This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH]: msp430, bfd/elf32-msp430.c fix adjust local symbols after relaxation


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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]