fix string table generation for XCOFF64 .debug section
authorCl?ment Chigot <clement.chigot@atos.net>
Thu, 22 Apr 2021 14:31:02 +0000 (15:31 +0100)
committerNick Clifton <nickc@redhat.com>
Thu, 22 Apr 2021 14:31:02 +0000 (15:31 +0100)
bfd * hash.c (struct bfd_strtab_hash): Remove xcoff field.
Add length_field_size field.
(_bfd_stringtab_init): Change prototype.
Adapt to new length_field_size.
(_bfd_xcoff_stringtab_init): Likewise.
(_bfd_stringtab_add): Likewise.
(_bfd_stringtab_emit): Likewise.
* libbfd-in.h (_bfd_xcoff_stringtab_init):
Change prototype.
* libbfd.h: Regenerate.
* xcofflink.c (_bfd_xcoff_bfd_link_hash_table_create):
Call _bfd_xcoff_stringtab_init with isxcoff64 value.

bfd/ChangeLog
bfd/hash.c
bfd/libbfd-in.h
bfd/libbfd.h
bfd/xcofflink.c

index abb9d5f34d766f4cfcb926d2ae2d775b9e202ca7..6361656fac167daa6d7d649c327e83e53ce2b4f8 100644 (file)
@@ -1,3 +1,18 @@
+2021-04-22  Clément Chigot  <clement.chigot@atos.net>
+
+       * hash.c (struct bfd_strtab_hash): Remove xcoff field.
+       Add length_field_size field.
+       (_bfd_stringtab_init): Change prototype.
+       Adapt to new length_field_size.
+       (_bfd_xcoff_stringtab_init): Likewise.
+       (_bfd_stringtab_add): Likewise.
+       (_bfd_stringtab_emit): Likewise.
+       * libbfd-in.h (_bfd_xcoff_stringtab_init):
+       Change prototype.
+       * libbfd.h: Regenerate.
+       * xcofflink.c (_bfd_xcoff_bfd_link_hash_table_create):
+       Call _bfd_xcoff_stringtab_init with isxcoff64 value.
+
 2021-04-22  Clément Chigot  <clement.chigot@atos.net>
 
        * coff-rs6000.c (_bfd_xcoff_swap_aux_in): Add errors for
index 0093d63fd9a6ca0a18617258a35b561489b09e9f..06969fecd21bc5008f42c905827eed44e9e5f60a 100644 (file)
@@ -713,11 +713,12 @@ struct bfd_strtab_hash
   struct strtab_hash_entry *first;
   /* Last string in strtab.  */
   struct strtab_hash_entry *last;
-  /* Whether to precede strings with a two byte length, as in the
-     XCOFF .debug section.  */
-  bool xcoff;
+  /* Whether to precede strings with a two or four byte length,
+     as in the XCOFF .debug section.  */
+  char length_field_size;
 };
 
+
 /* Routine to create an entry in a strtab.  */
 
 static struct bfd_hash_entry *
@@ -777,7 +778,7 @@ _bfd_stringtab_init (void)
   table->size = 0;
   table->first = NULL;
   table->last = NULL;
-  table->xcoff = false;
+  table->length_field_size = 0;
 
   return table;
 }
@@ -787,13 +788,13 @@ _bfd_stringtab_init (void)
    string.  */
 
 struct bfd_strtab_hash *
-_bfd_xcoff_stringtab_init (void)
+_bfd_xcoff_stringtab_init (bool isxcoff64)
 {
   struct bfd_strtab_hash *ret;
 
   ret = _bfd_stringtab_init ();
   if (ret != NULL)
-    ret->xcoff = true;
+    ret->length_field_size = isxcoff64 ? 4 : 2;
   return ret;
 }
 
@@ -852,11 +853,8 @@ _bfd_stringtab_add (struct bfd_strtab_hash *tab,
     {
       entry->index = tab->size;
       tab->size += strlen (str) + 1;
-      if (tab->xcoff)
-       {
-         entry->index += 2;
-         tab->size += 2;
-       }
+      entry->index += tab->length_field_size;
+      tab->size += tab->length_field_size;
       if (tab->first == NULL)
        tab->first = entry;
       else
@@ -881,11 +879,8 @@ _bfd_stringtab_size (struct bfd_strtab_hash *tab)
 bool
 _bfd_stringtab_emit (bfd *abfd, struct bfd_strtab_hash *tab)
 {
-  bool xcoff;
   struct strtab_hash_entry *entry;
 
-  xcoff = tab->xcoff;
-
   for (entry = tab->first; entry != NULL; entry = entry->next)
     {
       const char *str;
@@ -894,7 +889,16 @@ _bfd_stringtab_emit (bfd *abfd, struct bfd_strtab_hash *tab)
       str = entry->root.string;
       len = strlen (str) + 1;
 
-      if (xcoff)
+      if (tab->length_field_size == 4)
+       {
+         bfd_byte buf[4];
+
+         /* The output length includes the null byte.  */
+         bfd_put_32 (abfd, (bfd_vma) len, buf);
+         if (bfd_bwrite ((void *) buf, (bfd_size_type) 4, abfd) != 4)
+           return false;
+       }
+      else if (tab->length_field_size == 2)
        {
          bfd_byte buf[2];
 
index ebcc27dcbdf1f5e65a9fabe3c67622e6deb96b1d..1ad1af8c002e4e239cb3008461c6eacf3073bbb8 100644 (file)
@@ -761,7 +761,7 @@ extern struct bfd_strtab_hash *_bfd_stringtab_init
 
 /* Create an XCOFF .debug section style string table.  */
 extern struct bfd_strtab_hash *_bfd_xcoff_stringtab_init
-  (void) ATTRIBUTE_HIDDEN;
+  (bool isxcoff64) ATTRIBUTE_HIDDEN;
 
 /* Free a string table.  */
 extern void _bfd_stringtab_free
index bee1a1f8e592e2b3d3f6fb410b3337bcc30aaa08..fba29998900214b9b787d9d67871d80c5f8ed3f7 100644 (file)
@@ -766,7 +766,7 @@ extern struct bfd_strtab_hash *_bfd_stringtab_init
 
 /* Create an XCOFF .debug section style string table.  */
 extern struct bfd_strtab_hash *_bfd_xcoff_stringtab_init
-  (void) ATTRIBUTE_HIDDEN;
+  (bool isxcoff64) ATTRIBUTE_HIDDEN;
 
 /* Free a string table.  */
 extern void _bfd_stringtab_free
index 1607cd57d448b9b20fe7ee5db7c177e3bfc731d7..e18efd4381a8d15e03a0d9b7f6de9b6434c0f6f2 100644 (file)
@@ -592,6 +592,7 @@ struct bfd_link_hash_table *
 _bfd_xcoff_bfd_link_hash_table_create (bfd *abfd)
 {
   struct xcoff_link_hash_table *ret;
+  bool isxcoff64 = false;
   size_t amt = sizeof (* ret);
 
   ret = bfd_zmalloc (amt);
@@ -604,7 +605,9 @@ _bfd_xcoff_bfd_link_hash_table_create (bfd *abfd)
       return NULL;
     }
 
-  ret->debug_strtab = _bfd_xcoff_stringtab_init ();
+  isxcoff64 = bfd_coff_debug_string_prefix_length (abfd) == 4;
+
+  ret->debug_strtab = _bfd_xcoff_stringtab_init (isxcoff64);
   ret->archive_info = htab_create (37, xcoff_archive_info_hash,
                                   xcoff_archive_info_eq, NULL);
   if (!ret->debug_strtab || !ret->archive_info)