This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH]: msp430, bfd/elf32-msp430.c fix adjust local symbols after relaxation
- From: Dmitry Diky <ddiky at alarity dot com>
- To: binutils at sourceware dot org
- Date: Thu, 1 Sep 2005 15:26:18 +0400
- Subject: [PATCH]: msp430, bfd/elf32-msp430.c fix adjust local symbols after relaxation
- Reply-to: ddiky at alarity dot com
Fellows,
This patch fixes a problem with relaxation when local symbol referenced from
other sections.
For example:
.text
nop
jump .L1 ; <- relaxable insn
nop
.L1: ; before relaxation this symbol is referenced as .text+0x6
; after - .text+0x4
ret
.section .newsection ; (not necessary loadable)
.word .L1 ; .text+0x6 before relax and .text+0x4 after
Without the patch below all locals referenced from other sections after
relaxations have wrong values.
Dmitry.
2005-09-01 Dmitry Diky <diwil@spec.ru>
* elf32-msp430.c (msp430_elf_relax_delete_bytes): Do not adjust
local symbols and move it to
(msp430_elf_relax_adjust_locals): New function - walk over the
sections in the bfd and adjust relocations as necessary.
Index: elf32-msp430.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-msp430.c,v
retrieving revision 1.12
diff -c -3 -p -r1.12 elf32-msp430.c
*** elf32-msp430.c 12 Aug 2005 11:45:26 -0000 1.12
--- elf32-msp430.c 1 Sep 2005 11:24:52 -0000
*************** msp430_elf_symbol_address_p (bfd * abfd,
*** 830,835 ****
--- 830,865 ----
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
*************** msp430_elf_relax_delete_bytes (bfd * abf
*** 848,853 ****
--- 878,884 ----
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);
*************** msp430_elf_relax_delete_bytes (bfd * abf
*** 872,890 ****
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;
-
/* Get the new reloc address. */
if ((irel->r_offset > addr && irel->r_offset < toaddr))
irel->r_offset -= count;
-
- /* Adjust symbols referenced by .sec+0xXX */
- if (irel->r_addend > addr && irel->r_addend < toaddr
- && lsym->st_shndx == sec_shndx)
- irel->r_addend -= count;
}
/* Adjust the local symbols defined in this section. */
symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
isym = (Elf_Internal_Sym *) symtab_hdr->contents;
--- 903,916 ----
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;
}
+ 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;