Harden PowerPC64 OPD handling against fuzzers
PowerPC64 ELFv1 object files should have at most one .opd section, and
OPD handling in elf64-ppc.c makes use of this fact by caching some
.opd section info in the per-object bfd.tdata. This was done to avoid
another word in the target specific section data. Of course, fuzzers
don't respect the ABI, and even non-malicious users can accidentally
create multiple .opd sections. So it is better to avoid possible
buffer overflows and other confusion when OPD handling for a second
.opd section references data for the first .opd section, by keeping
the data per-section.
The patch also fixes a memory leak, and a corner case where I think we
could hit an assertion in opd_entry_value or read out of bounds in
ppc64_elf_branch_reloc doing a final link producing non-ppc64 output.
(It's a really rare corner case because not only would you need to be
linking ppc64 objects to non-ppc64 output, you'd also need a branch
reloc symbol to be defined in a .opd section of a non-ppc64 input.)
* elf64-ppc.c (is_ppc64_elf): Move earlier in file.
(ppc64_elf_branch_reloc): Check symbol bfd before accessing
ppc64 elf specific data structures.
(struct ppc64_elf_obj_tdata): Move opd union..
(struct _ppc64_elf_section_data): ..to here.
(ppc64_elf_before_check_relocs): Allow for opd sec_type
already set to sec_opd.
(ppc64_elf_check_relocs): Only set sec_type to sec_toc when
unset. Error for unexpected toc relocs.
(opd_entry_value): Return -1 when non-ppc64 rather than
asserting. Check and set sec_type too. Adjust for changed
location of contents and relocs.
(ppc64_elf_relocate_section): Adjust for changed location of
cached .opd relocs.
(ppc64_elf_free_cached_info): New function.
(bfd_elf64_bfd_free_cached_info): Define.