mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
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.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user