diff options
author | Alan Modra <amodra@gmail.com> | 2024-12-11 17:02:00 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2024-12-13 15:21:45 +1030 |
commit | a21e2f0c20565216fbc560225ba15d8c5c1e1aa8 (patch) | |
tree | 977aa6d4394a27b7a1b0a33a9aca1c4c69c8641d | |
parent | 2cd1fe362711bb7221826cb5e1d791bffc04fc51 (diff) | |
download | gdb-a21e2f0c20565216fbc560225ba15d8c5c1e1aa8.zip gdb-a21e2f0c20565216fbc560225ba15d8c5c1e1aa8.tar.gz gdb-a21e2f0c20565216fbc560225ba15d8c5c1e1aa8.tar.bz2 |
xcoff reading dynamic relocs
This adds a sanity check to relocation symbol indices, and tidies code
a little.
The patch does result in a couple of testsuite failures
rs6000-aix7.2 +FAIL: TLS relocations (32-bit)
rs6000-aix7.2 +FAIL: TLS relocations (64-bit)
That seems reasonable to me, because prior to this patch l_symndx was
being set to -1 and -2 for .tdata and .tbss symbols resulting in a
buffer overflow when accessing the syms array.
bfd/
* xcofflink.c (_bfd_xcoff_canonicalize_dynamic_reloc): Prevent
symbol array overflow on invalid relocation symbol index.
Tidy code for relocs against standard sections.
(xcoff_create_ldrel): Remove cast.
include/
* coff/xcoff.h (struct internal_ldrel): Make l_symndx uint32_t.
Make l_rtype and l_rsecnm int16_t.
-rw-r--r-- | bfd/xcofflink.c | 41 | ||||
-rw-r--r-- | include/coff/xcoff.h | 6 |
2 files changed, 20 insertions, 27 deletions
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index 49ac8ef..b75fb42 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -439,30 +439,13 @@ _bfd_xcoff_canonicalize_dynamic_reloc (bfd *abfd, bfd_xcoff_swap_ldrel_in (abfd, elrel, &ldrel); - if (ldrel.l_symndx >= 3) - relbuf->sym_ptr_ptr = syms + (ldrel.l_symndx - 3); - else + if (ldrel.l_symndx == -1u) + relbuf->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; + else if (ldrel.l_symndx < 3) { - const char *name; - asection *sec; - - switch (ldrel.l_symndx) - { - case 0: - name = ".text"; - break; - case 1: - name = ".data"; - break; - case 2: - name = ".bss"; - break; - default: - abort (); - break; - } - - sec = bfd_get_section_by_name (abfd, name); + static const char stdsec[3][8] = { ".text", ".data", ".bss" }; + const char *name = stdsec[ldrel.l_symndx]; + asection *sec = bfd_get_section_by_name (abfd, name); if (sec == NULL) { bfd_set_error (bfd_error_bad_value); @@ -471,6 +454,16 @@ _bfd_xcoff_canonicalize_dynamic_reloc (bfd *abfd, relbuf->sym_ptr_ptr = sec->symbol_ptr_ptr; } + else if (ldrel.l_symndx - 3 < ldhdr.l_nsyms) + relbuf->sym_ptr_ptr = syms + (ldrel.l_symndx - 3); + else + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB: warning: illegal symbol index %lu in relocs"), + abfd, (unsigned long) ldrel.l_symndx); + relbuf->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; + } relbuf->address = ldrel.l_vaddr; relbuf->addend = 0; @@ -5097,7 +5090,7 @@ xcoff_create_ldrel (bfd *output_bfd, struct xcoff_final_link_info *flinfo, ldrel.l_symndx = h->ldindx; } else - ldrel.l_symndx = -(bfd_size_type) 1; + ldrel.l_symndx = -1; ldrel.l_rtype = (irel->r_size << 8) | irel->r_type; ldrel.l_rsecnm = output_section->target_index; diff --git a/include/coff/xcoff.h b/include/coff/xcoff.h index 104660f..82d82eb 100644 --- a/include/coff/xcoff.h +++ b/include/coff/xcoff.h @@ -298,13 +298,13 @@ struct internal_ldrel bfd_vma l_vaddr; /* The symbol table index in the .loader section symbol table. */ - bfd_size_type l_symndx; + uint32_t l_symndx; /* The relocation type and size. */ - short l_rtype; + int16_t l_rtype; /* The section number this relocation applies to. */ - short l_rsecnm; + int16_t l_rsecnm; }; /* An entry in the XCOFF linker hash table. */ |