From ec33885937c311707a20bac4207422abde93511e Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sat, 10 Nov 2001 00:23:35 +0000 Subject: * elf32-arm.h (elf32_arm_final_link_relocate): Don't copy STN_UNDEF relocs into shared libs. * elf32-cris.c (cris_elf_relocate_section): Likewise. * elf32-i370.c (i370_elf_relocate_section): Likewise. * elf32-m68k.c (elf_m68k_relocate_section): Likewise. * elf32-mips.c (mips_elf_calculate_relocation): Likewise. * elf32-ppc.c (ppc_elf_relocate_section): Likewise. * elf32-sh.c (sh_elf_relocate_section): Likewise. * elf32-sparc.c (elf32_sparc_relocate_section): Likewise. * elf64-alpha.c (elf64_alpha_relocate_section): Likewise. * elf64-s390.c (elf_s390_relocate_section): Likewise. * elf64-sparc.c (sparc64_elf_relocate_section): Likewise. * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise. * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise. * elf.c (bfd_section_from_r_symndx): New function. * elf-bfd.h (LOCAL_SYM_CACHE_SIZE): Define. (struct sym_sec_cache): New. (bfd_section_from_r_symndx): Declare. (struct bfd_elf_section_data): Change local_dynrel type to PTR. * elflink.h (elf_link_input_bfd): Don't test for removed linkonce relocs when relocatable. Don't zero entire reloc, just zero the addend and sym. * elf32-i386.c (struct elf_i386_link_hash_table): Add sym_sec. (elf_i386_link_hash_table_create): Init it. (elf_i386_check_relocs): Track dynamic relocs needed for local syms on a per-section basis as we do for globals. (elf_i386_gc_sweep_hook): Update for local_dynrel change. Remove dead code. (allocate_dynrelocs): Warning fix. (elf_i386_size_dynamic_sections): Don't allocate relocs when section has been discarded. (elf_i386_relocate_section): Don't copy STN_UNDEF relocs into shared libs. * elf32-hppa.c: Likewise. * elf32-s390.c: Likewise. * elf64-ppc.c: Likewise. * elf64-s390.c: Likewise. --- bfd/elf.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'bfd/elf.c') diff --git a/bfd/elf.c b/bfd/elf.c index 8c1694e..7bffecd 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1747,6 +1747,62 @@ bfd_section_from_shdr (abfd, shindex) return true; } +/* Return the section for the local symbol specified by ABFD, R_SYMNDX. + Return SEC for sections that have no elf section, and NULL on error. */ + +asection * +bfd_section_from_r_symndx (abfd, cache, sec, r_symndx) + bfd *abfd; + struct sym_sec_cache *cache; + asection *sec; + unsigned long r_symndx; +{ + unsigned char esym_shndx[2]; + unsigned int isym_shndx; + Elf_Internal_Shdr *symtab_hdr; + file_ptr pos; + bfd_size_type amt; + unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE; + + if (cache->abfd == abfd && cache->indx[ent] == r_symndx) + return cache->sec[ent]; + + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + pos = symtab_hdr->sh_offset; + if (get_elf_backend_data (abfd)->s->sizeof_sym + == sizeof (Elf64_External_Sym)) + { + pos += r_symndx * sizeof (Elf64_External_Sym); + pos += offsetof (Elf64_External_Sym, st_shndx); + } + else + { + pos += r_symndx * sizeof (Elf32_External_Sym); + pos += offsetof (Elf32_External_Sym, st_shndx); + } + amt = sizeof (esym_shndx); + if (bfd_seek (abfd, pos, SEEK_SET) != 0 + || bfd_bread ((PTR) esym_shndx, amt, abfd) != amt) + return NULL; + isym_shndx = H_GET_16 (abfd, esym_shndx); + + if (cache->abfd != abfd) + { + memset (cache->indx, -1, sizeof (cache->indx)); + cache->abfd = abfd; + } + cache->indx[ent] = r_symndx; + cache->sec[ent] = sec; + if (isym_shndx > 0 && isym_shndx < SHN_LORESERVE) + { + asection *s; + s = bfd_section_from_elf_index (abfd, isym_shndx); + if (s != NULL) + cache->sec[ent] = s; + } + return cache->sec[ent]; +} + /* Given an ELF section number, retrieve the corresponding BFD section. */ -- cgit v1.1