* elfxx-ia64.c (is_unwind_section_name): Consider linkonce unwind
authorJakub Jelinek <jakub@redhat.com>
Fri, 11 May 2001 12:36:47 +0000 (12:36 +0000)
committerJakub Jelinek <jakub@redhat.com>
Fri, 11 May 2001 12:36:47 +0000 (12:36 +0000)
sections as well.
(elfNN_ia64_final_write_processing): Map .gnu.linkonce.ia64unw.FOO
to .gnu.linkonce.t.FOO text section.

* readelf.c (process_unwind): Print all unwind sections, not just
one.

* config/tc-ia64.c (special_linkonce_name): New.
(make_unw_section): Map .gnu.linkonce.t.FOO text section into
.gnu.linkonce.ia64unw{,i}.FOO.
(ia64_elf_section_type): Handle .gnu.linkonce.ia64unw{,i}.FOO.
(dot_endp): Add comment about it.

* elf/ia64.h (ELF_STRING_ia64_unwind_once): Define.
(ELF_STRING_ia64_unwind_info_once): Define.

* emulparams/elf64_ia64.sh (OTHER_READONLY_SECTIONS): Put
.gnu.linkonce.ia64unw{,i} sections into corresponding .IA_64.unwind*
output sections.
* emulparams/elf64_aix.sh (OTHER_READONLY_SECTIONS): Likewise.

bfd/ChangeLog
bfd/elfxx-ia64.c
binutils/ChangeLog
binutils/readelf.c
gas/ChangeLog
gas/config/tc-ia64.c
include/ChangeLog
include/elf/ia64.h
ld/ChangeLog
ld/emulparams/elf64_aix.sh
ld/emulparams/elf64_ia64.sh

index c2bb974371e283413a562196156f5d1a67f363b6..c97b46aacce0e60567abca219ad98a280e123ed3 100644 (file)
@@ -1,3 +1,10 @@
+2001-05-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * elfxx-ia64.c (is_unwind_section_name): Consider linkonce unwind
+       sections as well.
+       (elfNN_ia64_final_write_processing): Map .gnu.linkonce.ia64unw.FOO
+       to .gnu.linkonce.t.FOO text section.
+
 2001-05-11  Jakub Jelinek  <jakub@redhat.com>
 
        * merge.c (struct sec_merge_hash_entry): Add u.entsize and u.suffix
index 8d80e6e27dfc9725510e9043e51e60705f591fda..f0f64f654412425af84d3a28b1ac4803d499a91c 100644 (file)
@@ -921,12 +921,14 @@ static inline boolean
 is_unwind_section_name (name)
        const char *name;
 {
-  size_t len1, len2;
+  size_t len1, len2, len3;
 
   len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
   len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
-  return (strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
-         && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0);
+  len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1;
+  return ((strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
+          && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0)
+         || strncmp (name, ELF_STRING_ia64_unwind_once, len3) == 0);
 }
 
 /* Handle an IA-64 specific section when reading an object file.  This
@@ -1065,6 +1067,18 @@ elfNN_ia64_final_write_processing (abfd, linker)
                /* .IA_64.unwindFOO -> FOO */
                text_sect = bfd_get_section_by_name (abfd, sname);
            }
+         else if (sname
+                  && (len = sizeof (ELF_STRING_ia64_unwind_once) - 1,
+                      strncmp (sname, ELF_STRING_ia64_unwind_once, len)) == 0)
+           {
+             /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
+             size_t len2 = sizeof (".gnu.linkonce.t.") - 1;
+             char *once_name = alloca (len2 + strlen (sname) - len + 1);
+
+             memcpy (once_name, ".gnu.linkonce.t.", len2);
+             strcpy (once_name + len2, sname + len);
+             text_sect = bfd_get_section_by_name (abfd, once_name);
+           }
          else
            /* last resort: fall back on .text */
            text_sect = bfd_get_section_by_name (abfd, ".text");
index f2c82dc08dbef5ecd991c20b09c62be0a8c3fad1..311f8335de472db5cd3226c5713ab298170cd4f1 100644 (file)
@@ -1,3 +1,8 @@
+2001-05-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * readelf.c (process_unwind): Print all unwind sections, not just
+       one.
+
 2001-05-07  Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
 
        * readelf.c (process_unwind): Remove const specifier.
index fa583e441d3049d12e610391d413e9ddc7c7c85c..b7aecdebd9aa3163d47205760516d5b41732ec03 100644 (file)
@@ -3408,7 +3408,7 @@ process_unwind (file)
      FILE * file;
 {
   Elf32_Internal_Shdr *sec, *unwsec = NULL, *strsec;
-  unsigned long i, addr_size;
+  unsigned long i, addr_size, unwcount = 0, unwstart = 0;
   struct unw_aux_info aux;
 
   if (!do_unwind)
@@ -3437,40 +3437,100 @@ process_unwind (file)
                          aux.strtab, char *, "string table");
        }
       else if (sec->sh_type == SHT_IA_64_UNWIND)
-       unwsec = sec;
-      else if (strcmp (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info) == 0)
+       unwcount++;
+    }
+
+  if (!unwcount)
+    printf (_("\nThere are no unwind sections in this file.\n"));
+
+  while (unwcount-- > 0)
+    {
+      char *suffix;
+      size_t len, len2;
+
+      for (i = unwstart, sec = section_headers + unwstart;
+          i < elf_header.e_shnum; ++i, ++sec)
+       if (sec->sh_type == SHT_IA_64_UNWIND)
+         {
+           unwsec = sec;
+           break;
+         }
+
+      unwstart = i + 1;
+      len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
+
+      if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once,
+                  len) == 0)
+       {
+         /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO */
+         len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
+         suffix = SECTION_NAME (unwsec) + len;
+         for (i = 0, sec = section_headers; i < elf_header.e_shnum;
+              ++i, ++sec)
+           if (strncmp (SECTION_NAME (sec),
+                        ELF_STRING_ia64_unwind_info_once, len2) == 0
+               && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
+             break;
+       }
+      else
+       {
+         /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
+            .IA_64.unwind or BAR -> .IA_64.unwind_info */
+         len = sizeof (ELF_STRING_ia64_unwind) - 1;
+         len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
+         suffix = "";
+         if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind,
+                      len) == 0)
+           suffix = SECTION_NAME (unwsec) + len;
+         for (i = 0, sec = section_headers; i < elf_header.e_shnum;
+              ++i, ++sec)
+           if (strncmp (SECTION_NAME (sec),
+                        ELF_STRING_ia64_unwind_info, len2) == 0
+               && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
+             break;
+       }
+
+      if (i == elf_header.e_shnum)
+       {
+         printf (_("\nCould not find unwind info section for "));
+
+         if (string_table == NULL)
+           printf ("%d", unwsec->sh_name);
+         else
+           printf ("'%s'", SECTION_NAME (unwsec));
+       }
+      else
        {
          aux.info_size = sec->sh_size;
          aux.info_addr = sec->sh_addr;
          GET_DATA_ALLOC (sec->sh_offset, aux.info_size, aux.info,
                          char *, "unwind info");
-       }
-    }
 
-  if (unwsec)
-    {
-      printf (_("\nUnwind section "));
+         printf (_("\nUnwind section "));
 
-      if (string_table == NULL)
-       printf ("%d", unwsec->sh_name);
-      else
-       printf ("'%s'", SECTION_NAME (unwsec));
+         if (string_table == NULL)
+           printf ("%d", unwsec->sh_name);
+         else
+           printf ("'%s'", SECTION_NAME (unwsec));
 
-      printf (_(" at offset 0x%lx contains %lu entries:\n"),
-             unwsec->sh_offset, (unsigned long) (unwsec->sh_size / (3 * addr_size)));
+         printf (_(" at offset 0x%lx contains %lu entries:\n"),
+                 unwsec->sh_offset,
+                 (unsigned long) (unwsec->sh_size / (3 * addr_size)));
 
-      (void) slurp_ia64_unwind_table (file, & aux, unwsec);
+         (void) slurp_ia64_unwind_table (file, & aux, unwsec);
 
-      if (aux.table_len > 0)
-       dump_ia64_unwind (& aux);
+         if (aux.table_len > 0)
+           dump_ia64_unwind (& aux);
+
+         if (aux.table)
+           free ((char *) aux.table);
+         if (aux.info)
+           free ((char *) aux.info);
+         aux.table = NULL;
+         aux.info = NULL;
+       }
     }
-  else
-    printf (_("\nThere are no unwind sections in this file.\n"));
 
-  if (aux.table)
-    free ((char *) aux.table);
-  if (aux.info)
-    free ((char *) aux.info);
   if (aux.symtab)
     free (aux.symtab);
   if (aux.strtab)
index 1e6d8c8fd1baffb042e33ef2194013ea68d9f19d..21e5209456a8054d952b6b71394d622cbdedf8cf 100644 (file)
@@ -1,3 +1,11 @@
+2001-05-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * config/tc-ia64.c (special_linkonce_name): New.
+       (make_unw_section): Map .gnu.linkonce.t.FOO text section into
+       .gnu.linkonce.ia64unw{,i}.FOO.
+       (ia64_elf_section_type): Handle .gnu.linkonce.ia64unw{,i}.FOO.
+       (dot_endp): Add comment about it.
+
 2001-05-11  Nick Clifton  <nickc@cambridge.redhat.com>
 
        * config/tc-arm.c (arm_handle_align): When truncating an aligned 
index be4b7e5bd4d2bc4f679e44a568f88c500dbf9857..0a3dcc63e2667d1b850de6951f15ea45b4a5ad33 100644 (file)
@@ -526,6 +526,11 @@ static char special_section_name[][20] =
     {".IA_64.unwind"}, {".IA_64.unwind_info"}
   };
 
+static char *special_linkonce_name[] =
+  {
+    ".gnu.linkonce.ia64unw.", ".gnu.linkonce.ia64unwi."
+  };
+
 /* The best template for a particular sequence of up to three
    instructions:  */
 #define N      IA64_NUM_TYPES
@@ -852,11 +857,20 @@ static int generate_unwind_image PARAMS ((const char *));
 #define make_unw_section_name(special, text_name, result)                 \
   {                                                                       \
     char *_prefix = special_section_name[special];                        \
-    size_t _prefix_len = strlen (_prefix), _text_len = strlen (text_name); \
-    char *_result = alloca (_prefix_len + _text_len + 1);                 \
+    char *_suffix = text_name;                                            \
+    size_t _prefix_len, _suffix_len;                                      \
+    char *_result;                                                        \
+    if (strncmp (text_name, ".gnu.linkonce.t.",                                   \
+                sizeof (".gnu.linkonce.t.") - 1) == 0)                    \
+      {                                                                           \
+       _prefix = special_linkonce_name[special - SPECIAL_SECTION_UNWIND]; \
+       _suffix += sizeof (".gnu.linkonce.t.") - 1;                        \
+      }                                                                           \
+    _prefix_len = strlen (_prefix), _suffix_len = strlen (_suffix);       \
+    _result = alloca (_prefix_len + _suffix_len + 1);                     \
     memcpy(_result, _prefix, _prefix_len);                                \
-    memcpy(_result + _prefix_len, text_name, _text_len);                  \
-    _result[_prefix_len + _text_len] = '\0';                              \
+    memcpy(_result + _prefix_len, _suffix, _suffix_len);                  \
+    _result[_prefix_len + _suffix_len] = '\0';                            \
     result = _result;                                                     \
   }                                                                       \
 while (0)
@@ -913,10 +927,18 @@ ia64_elf_section_type (str, len)
   if (strncmp (str, ELF_STRING_ia64_unwind_info, len) == 0)
     return SHT_PROGBITS;
 
+  len = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
+  if (strncmp (str, ELF_STRING_ia64_unwind_info_once, len) == 0)
+    return SHT_PROGBITS;
+
   len = sizeof (ELF_STRING_ia64_unwind) - 1;
   if (strncmp (str, ELF_STRING_ia64_unwind, len) == 0)
     return SHT_IA_64_UNWIND;
 
+  len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
+  if (strncmp (str, ELF_STRING_ia64_unwind_once, len) == 0)
+    return SHT_IA_64_UNWIND;
+
   return -1;
 }
 
@@ -3820,6 +3842,8 @@ dot_endp (dummy)
     .text       .IA_64.unwind
     .text.foo   .IA_64.unwind.text.foo
     .foo        .IA_64.unwind.foo
+    .gnu.linkonce.t.foo
+               .gnu.linkonce.ia64unw.foo
     _info       .IA_64.unwind_info         gas issues error message (ditto)
     _infoFOO    .IA_64.unwind_infoFOO      gas issues error message (ditto)
 
index 1cf248342cbe2d3013d56d6535ff23cb2012808e..fee7f8901eba48dadb02abf397e3820f20563a2d 100644 (file)
@@ -1,3 +1,8 @@
+2001-05-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * elf/ia64.h (ELF_STRING_ia64_unwind_once): Define.
+       (ELF_STRING_ia64_unwind_info_once): Define.
+
 2001-05-07  Zack Weinberg  <zackw@stanford.edu>
 
        * demangle.h: Use PARAMS for all prototypes.
index ecd74b08f668080d976b4f268ef4dc77f97103fb..edfc7c5b532eb59c9006ef151f3ae2895e81df78 100644 (file)
@@ -47,6 +47,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #define ELF_STRING_ia64_pltoff         ".IA_64.pltoff"
 #define ELF_STRING_ia64_unwind         ".IA_64.unwind"
 #define ELF_STRING_ia64_unwind_info    ".IA_64.unwind_info"
+#define ELF_STRING_ia64_unwind_once    ".gnu.linkonce.ia64unw."
+#define ELF_STRING_ia64_unwind_info_once ".gnu.linkonce.ia64unwi."
 
 /* Bits in the sh_flags field of Elf64_Shdr:  */
 
index 3cd93912f20dcda1b914668d3d9a2cc3bd3369b6..8be1c30dcb5179de251062346f34d2ffe86f74ab 100644 (file)
@@ -1,3 +1,10 @@
+2001-05-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * emulparams/elf64_ia64.sh (OTHER_READONLY_SECTIONS): Put
+       .gnu.linkonce.ia64unw{,i} sections into corresponding .IA_64.unwind*
+       output sections.
+       * emulparams/elf64_aix.sh (OTHER_READONLY_SECTIONS): Likewise.
+
 2001-05-11  Jakub Jelinek  <jakub@redhat.com>
 
        * ldlang.c (lang_process): Call bfd_merge_sections.
index c0e73a9afd5c4bf970bd3b0a344c461323269e4f..057949b602b905f402faa8f37adbcc214952d8a4 100644 (file)
@@ -13,5 +13,5 @@ NOP=0x00300000010070000002000001000400  # a bundle full of nops
 OTHER_GOT_SYMBOLS='. = ALIGN (8); PROVIDE (__gp = . + 0x200000);'
 OTHER_GOT_SECTIONS='.IA_64.pltoff : { *(.IA_64.pltoff) }'
 OTHER_PLT_RELOC_SECTIONS='.rela.IA_64.pltoff : { *(.rela.IA_64.pltoff) }'
-OTHER_READONLY_SECTIONS='.opd : { *(.opd) }  .IA_64.unwind_info : { *(.IA_64.unwind_info*) }  .IA_64.unwind : { *(.IA_64.unwind*) }'
+OTHER_READONLY_SECTIONS='.opd : { *(.opd) }  .IA_64.unwind_info : { *(.IA_64.unwind_info*) *(.gnu.linkonce.ia64unwi.*) }  .IA_64.unwind : { *(.IA_64.unwind*) *(.gnu.linkonce.ia64unw.*) }'
 LIB_PATH=/usr/lib/ia64l64:/usr/lib:/usr/local/lib
index fff59924cb3c4e97a001b8dcc2571f76d498858e..845001bda0bf3b49603b0f8b4a57621806ef17f6 100644 (file)
@@ -12,4 +12,4 @@ GENERATE_SHLIB_SCRIPT=yes
 NOP=0x00300000010070000002000001000400  # a bundle full of nops
 OTHER_GOT_SECTIONS='.IA_64.pltoff : { *(.IA_64.pltoff) }'
 OTHER_PLT_RELOC_SECTIONS='.rela.IA_64.pltoff : { *(.rela.IA_64.pltoff) }'
-OTHER_READONLY_SECTIONS='.opd : { *(.opd) }  .IA_64.unwind_info : { *(.IA_64.unwind_info*) }  .IA_64.unwind : { *(.IA_64.unwind*) }'
+OTHER_READONLY_SECTIONS='.opd : { *(.opd) }  .IA_64.unwind_info : { *(.IA_64.unwind_info*) *(.gnu.linkonce.ia64unwi.*) }  .IA_64.unwind : { *(.IA_64.unwind*) *(.gnu.linkonce.ia64unw.*) }'