if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ }
}
return TRUE;
return FALSE;
}
+/* Adjust all local symbols defined as '.section + 0xXXXX' (.section has sec_shndx)
+ referenced from current and other sections */
+static bfd_boolean
+msp430_elf_relax_adjust_locals(bfd * abfd, asection * sec, bfd_vma addr,
+ int count, unsigned int sec_shndx, bfd_vma toaddr)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *irelend;
+ Elf_Internal_Sym *isym;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+
+ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+ {
+ int sidx = ELF32_R_SYM(irel->r_info);
+ Elf_Internal_Sym *lsym = isym + sidx;
+
+ /* Adjust symbols referenced by .sec+0xXX */
+ if (irel->r_addend > addr && irel->r_addend < toaddr
+ && lsym->st_shndx == sec_shndx)
+ irel->r_addend -= count;
+ }
+
+ return TRUE;
+}
+
/* Delete some bytes from a section while relaxing. */
static bfd_boolean
struct elf_link_hash_entry **sym_hashes;
struct elf_link_hash_entry **end_hashes;
unsigned int symcount;
+ asection *p;
sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
sec->size -= count;
/* Adjust all the relocs. */
+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
- /* Get the new reloc address. */
- if ((irel->r_offset > addr && irel->r_offset < toaddr))
- irel->r_offset -= count;
+ {
+ /* Get the new reloc address. */
+ if ((irel->r_offset > addr && irel->r_offset < toaddr))
+ irel->r_offset -= count;
+ }
+ for (p = abfd->sections; p != NULL; p = p->next)
+ msp430_elf_relax_adjust_locals(abfd,p,addr,count,sec_shndx,toaddr);
+
/* Adjust the local symbols defined in this section. */
symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
isym = (Elf_Internal_Sym *) symtab_hdr->contents;