* elf64-mips.c (mips_elf64_howto_table_rela): Add support for
[deliverable/binutils-gdb.git] / bfd / elf-m10300.c
index a58be7b6b76405535dd3495ee262584ec8d52107..794d329fe80be3f7f24120dddece95d80cc9c3ae 100644 (file)
@@ -1,6 +1,6 @@
 /* Matsushita 10300 specific support for 32-bit ELF
    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007 Free Software Foundation, Inc.
+   2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -1493,7 +1493,7 @@ mn10300_elf_relocate_section (bfd *output_bfd,
                      /* _32 relocs in executables force _COPY relocs,
                         such that the address of the symbol ends up
                         being local.  */
-                     && !info->executable                    
+                     && !info->executable
                      && !SYMBOL_REFERENCES_LOCAL (info, hh)
                      && ((input_section->flags & SEC_ALLOC) != 0
                          /* DWARF will emit R_MN10300_32 relocations
@@ -2783,11 +2783,30 @@ mn10300_elf_relax_section (bfd *abfd,
          if ((sym_sec->flags & SEC_MERGE)
              && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
            {
-             symval = isym->st_value + irel->r_addend;
+             symval = isym->st_value;
+
+             /* GAS may reduce relocations against symbols in SEC_MERGE
+                sections to a relocation against the section symbol when
+                the original addend was zero.  When the reloc is against
+                a section symbol we should include the addend in the
+                offset passed to _bfd_merged_section_offset, since the
+                location of interest is the original symbol.  On the
+                other hand, an access to "sym+addend" where "sym" is not
+                a section symbol should not include the addend;  Such an
+                access is presumed to be an offset from "sym";  The
+                location of interest is just "sym".  */
+             if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
+               symval += irel->r_addend;
+
              symval = _bfd_merged_section_offset (abfd, & sym_sec,
                                                   elf_section_data (sym_sec)->sec_info,
                                                   symval);
-             symval += sym_sec->output_section->vma + sym_sec->output_offset - irel->r_addend;
+
+             if (ELF_ST_TYPE (isym->st_info) != STT_SECTION)
+               symval += irel->r_addend;
+
+             symval += sym_sec->output_section->vma
+               + sym_sec->output_offset - irel->r_addend;
            }
          else
            symval = (isym->st_value
This page took 0.026412 seconds and 4 git commands to generate.