diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 13 |
2 files changed, 18 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 93cd6c0..86cdde2 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2003-08-12 Alan Modra <amodra@bigpond.net.au> + + * elf64-ppc.c (ppc64_elf_next_input_section): Update comment. + (ppc64_elf_relocate_section): For zero sym R_PPC64_TOC relocs, + use the function sym from the previous reloc. + 2003-08-11 Jakub Jelinek <jakub@redhat.com> * elf32-i386.c (elf_i386_relocate_section): Make undefined symbols diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 4291f9b..c0f5b82 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -6608,7 +6608,8 @@ ppc64_elf_next_input_section (struct bfd_link_info *info, asection *isec) /* If a code section has a function that uses the TOC then we need to use the right TOC (obviously). Also, make sure that .opd gets - the correct TOC value. */ + the correct TOC value for R_PPC64_TOC relocs that don't have or + can't find their function symbol (shouldn't ever happen now). */ if (isec->has_gp_reloc || (isec->flags & SEC_CODE) == 0) { if (elf_gp (isec->owner) != 0) @@ -7327,6 +7328,16 @@ ppc64_elf_relocate_section (bfd *output_bfd, r_type = ELF64_R_TYPE (rel->r_info); r_symndx = ELF64_R_SYM (rel->r_info); + + /* For old style R_PPC64_TOC relocs with a zero symbol, use the + symbol of the previous ADDR64 reloc. The symbol gives us the + proper TOC base to use. */ + if (rel->r_info == ELF64_R_INFO (0, R_PPC64_TOC) + && rel != relocs + && ELF64_R_TYPE (rel[-1].r_info) == R_PPC64_ADDR64 + && is_opd) + r_symndx = ELF64_R_SYM (rel[-1].r_info); + sym = NULL; sec = NULL; h = NULL; |