From bdd2aaf69ea2e8c89f431bdf72516e2d6503891a Mon Sep 17 00:00:00 2001 From: Cl?ment Chigot Date: Thu, 22 Apr 2021 15:31:02 +0100 Subject: [PATCH] fix string table generation for XCOFF64 .debug section 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 | 15 +++++++++++++++ bfd/hash.c | 34 +++++++++++++++++++--------------- bfd/libbfd-in.h | 2 +- bfd/libbfd.h | 2 +- bfd/xcofflink.c | 5 ++++- 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index abb9d5f34d7..6361656fac1 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2021-04-22 Clément Chigot + + * 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 * coff-rs6000.c (_bfd_xcoff_swap_aux_in): Add errors for diff --git a/bfd/hash.c b/bfd/hash.c index 0093d63fd9a..06969fecd21 100644 --- a/bfd/hash.c +++ b/bfd/hash.c @@ -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]; diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index ebcc27dcbdf..1ad1af8c002 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -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 diff --git a/bfd/libbfd.h b/bfd/libbfd.h index bee1a1f8e59..fba29998900 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -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 diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index 1607cd57d44..e18efd4381a 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -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) -- 2.30.2