This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Fix linking of .gpdword on MIPS
- From: "H. J. Lu" <hjl at lucon dot org>
- To: binutils at sourceware dot org
- Date: Fri, 2 Mar 2007 19:20:02 -0800
- Subject: Re: Fix linking of .gpdword on MIPS
- References: <877iu4k03j.fsf@firetop.home> <20070227014036.GA9676@caradoc.them.org> <87mz309c9k.fsf@firetop.home> <20070227121051.GA5903@caradoc.them.org> <20070227230314.GL29005@bubble.grove.modra.org> <20070228012241.GB11623@lucon.org> <20070228013530.GN29005@bubble.grove.modra.org>
On Wed, Feb 28, 2007 at 12:05:30PM +1030, Alan Modra wrote:
> On Tue, Feb 27, 2007 at 05:22:41PM -0800, H. J. Lu wrote:
> > There are no regressions with my patch. But I don't know if there
> > are testcases to check ld -r and ld -emit-relocs for this specific
> > case.
>
> I don't think there is a testcase for this case in the testsuite.
> I'll approve your patch if you implement what I suggested in my last
> email.
>
Here is the updated patch with a testcase for -r and a testcase for
-emit-relocs. Currently, the -emit-relocs testcase fails. The problem
is the code in elflink.c:
/* This is a reloc against a local symbol. */
*rel_hash = NULL;
sym = isymbuf[r_symndx];
sec = finfo->sections[r_symndx];
if (ELF_ST_TYPE (sym.st_info) == STT_SECTION)
Check discarded section.
Why does it only check STT_SECTION symbols for discarded section?
Do we have testcases for it?
H.J.
-----
bfd/
2007-03-03 H.J. Lu <hongjiu.lu@intel.com>
PR ld/3958
* elf32-d10v.c (elf32_d10v_relocate_section): Use
elf_discarded_section to check if a relocation is against a
symbol from removed input section.
* elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
* elf32-i386.c (elf_i386_relocate_section): Likewise.
* elf32-ppc.c (ppc_elf_relocate_section): Likewise.
* elf32-s390.c (elf_s390_relocate_section): Likewise.
* elf32-sh.c (sh_elf_relocate_section): Likewise.
* elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
* elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
* elf64-s390.c (elf_s390_relocate_section): Likewise.
* elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
* elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise.
* elfxx-mips.c (mips_elf_calculate_relocation): Likewise.
* elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise.
* elflink.c (elf_link_input_bfd): Don't remove the symbol
reference from relocations against symbols from removed input
section.
ld/testsuite/
2007-03-03 H.J. Lu <hongjiu.lu@intel.com>
PR ld/3958
* ld-elf/linkonce1.d: New file.
* ld-elf/linkonce1a.s: Likewise.
* ld-elf/linkonce1b.s: Likewise.
* ld-elf/linkonce2.d: Likewise.
* ld-i386/pcrel16abs.d: Likewise.
* ld-i386/pcrel16abs.s: Likewise.
* ld-i386/i386.exp: Run "pcrel16abs".
--- binutils/bfd/elf32-d10v.c.abs 2006-11-02 19:36:06.000000000 -0800
+++ binutils/bfd/elf32-d10v.c 2007-03-02 17:59:22.000000000 -0800
@@ -469,12 +469,11 @@ elf32_d10v_relocate_section (bfd *output
unresolved_reloc, warned);
}
- if (r_symndx == 0)
+ if (sec && elf_discarded_section (sec))
{
- /* r_symndx will be zero only for relocs against symbols from
- removed linkonce sections, or sections discarded by a linker
- script. For these relocs, we just want the section contents
- zeroed. Avoid any special processing. */
+ /* For relocs against symbols from removed linkonce sections,
+ or sections discarded by a linker script, we just want the
+ section contents zeroed. Avoid any special processing. */
_bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
continue;
}
--- binutils/bfd/elf32-hppa.c.abs 2007-03-02 15:10:48.000000000 -0800
+++ binutils/bfd/elf32-hppa.c 2007-03-02 17:59:22.000000000 -0800
@@ -3939,11 +3939,12 @@ elf32_hppa_relocate_section (bfd *output
case R_PARISC_DPREL14R:
case R_PARISC_DPREL21L:
case R_PARISC_DIR32:
- /* r_symndx will be zero only for relocs against symbols
- from removed linkonce sections, or sections discarded by
- a linker script. */
- if (r_symndx == 0)
+ if (sym_sec && elf_discarded_section (sym_sec))
{
+ /* For relocs against symbols from removed linkonce
+ sections, or sections discarded by a linker script,
+ we just want the section contents zeroed. Avoid any
+ special processing. */
_bfd_clear_contents (elf_hppa_howto_table + r_type, input_bfd,
contents + rela->r_offset);
break;
--- binutils/bfd/elf32-i386.c.abs 2007-03-02 15:10:48.000000000 -0800
+++ binutils/bfd/elf32-i386.c 2007-03-02 17:59:22.000000000 -0800
@@ -2414,12 +2414,11 @@ elf_i386_relocate_section (bfd *output_b
unresolved_reloc, warned);
}
- if (r_symndx == 0)
+ if (sec && elf_discarded_section (sec))
{
- /* r_symndx will be zero only for relocs against symbols from
- removed linkonce sections, or sections discarded by a linker
- script. For these relocs, we just want the section contents
- zeroed. Avoid any special processing. */
+ /* For relocs against symbols from removed linkonce sections,
+ or sections discarded by a linker script, we just want the
+ section contents zeroed. Avoid any special processing. */
_bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
continue;
}
--- binutils/bfd/elf32-ppc.c.abs 2007-02-01 12:42:10.000000000 -0800
+++ binutils/bfd/elf32-ppc.c 2007-03-02 17:59:22.000000000 -0800
@@ -6225,12 +6225,13 @@ ppc_elf_relocate_section (bfd *output_bf
case R_PPC_ADDR14_BRNTAKEN:
case R_PPC_UADDR32:
case R_PPC_UADDR16:
- /* r_symndx will be zero only for relocs against symbols
- from removed linkonce sections, or sections discarded by
- a linker script. */
dodyn:
- if (r_symndx == 0)
+ if (sec && elf_discarded_section (sec))
{
+ /* For relocs against symbols from removed linkonce
+ sections, or sections discarded by a linker script, we
+ just want the section contents zeroed. Avoid any
+ special processing. */
_bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
break;
}
--- binutils/bfd/elf32-s390.c.abs 2006-11-02 19:36:07.000000000 -0800
+++ binutils/bfd/elf32-s390.c 2007-03-02 17:59:22.000000000 -0800
@@ -2540,11 +2540,12 @@ elf_s390_relocate_section (output_bfd, i
case R_390_PC16DBL:
case R_390_PC32DBL:
case R_390_PC32:
- /* r_symndx will be zero only for relocs against symbols
- from removed linkonce sections, or sections discarded by
- a linker script. */
- if (r_symndx == 0)
+ if (sec && elf_discarded_section (sec))
{
+ /* For relocs against symbols from removed linkonce
+ sections, or sections discarded by a linker script,
+ we just want the section contents zeroed. Avoid any
+ special processing. */
_bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
break;
}
--- binutils/bfd/elf32-sh.c.abs 2006-11-02 19:36:07.000000000 -0800
+++ binutils/bfd/elf32-sh.c 2007-03-02 17:59:22.000000000 -0800
@@ -3557,11 +3557,12 @@ sh_elf_relocate_section (bfd *output_bfd
case R_SH_IMM_MEDHI16_PCREL:
case R_SH_IMM_HI16_PCREL:
#endif
- /* r_symndx will be zero only for relocs against symbols
- from removed linkonce sections, or sections discarded by
- a linker script. */
- if (r_symndx == 0)
+ if (sec && elf_discarded_section (sec))
{
+ /* For relocs against symbols from removed linkonce
+ sections, or sections discarded by a linker script, we
+ just want the section contents zeroed. Avoid any
+ special processing. */
_bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
continue;
}
--- binutils/bfd/elf32-xtensa.c.abs 2007-03-02 11:46:35.000000000 -0800
+++ binutils/bfd/elf32-xtensa.c 2007-03-02 17:59:22.000000000 -0800
@@ -2241,12 +2241,11 @@ elf_xtensa_relocate_section (bfd *output
return FALSE;
}
- if (r_symndx == 0)
+ if (sec && elf_discarded_section (sec))
{
- /* r_symndx will be zero only for relocs against symbols from
- removed linkonce sections, or sections discarded by a linker
- script. For these relocs, we just want the section contents
- zeroed. Avoid any special processing. */
+ /* For relocs against symbols from removed linkonce sections,
+ or sections discarded by a linker script, we just want the
+ section contents zeroed. Avoid any special processing. */
_bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
continue;
}
--- binutils/bfd/elf64-ppc.c.abs 2007-03-01 14:53:13.000000000 -0800
+++ binutils/bfd/elf64-ppc.c 2007-03-02 17:59:22.000000000 -0800
@@ -10831,12 +10831,13 @@ ppc64_elf_relocate_section (bfd *output_
case R_PPC64_UADDR16:
case R_PPC64_UADDR32:
case R_PPC64_UADDR64:
- /* r_symndx will be zero only for relocs against symbols
- from removed linkonce sections, or sections discarded by
- a linker script. */
dodyn:
- if (r_symndx == 0)
+ if (sec && elf_discarded_section (sec))
{
+ /* For relocs against symbols from removed linkonce
+ sections, or sections discarded by a linker script,
+ we just want the section contents zeroed. Avoid any
+ special processing. */
_bfd_clear_contents (ppc64_elf_howto_table[r_type], input_bfd,
contents + rel->r_offset);
break;
--- binutils/bfd/elf64-s390.c.abs 2006-11-02 19:36:09.000000000 -0800
+++ binutils/bfd/elf64-s390.c 2007-03-02 17:59:22.000000000 -0800
@@ -2519,11 +2519,12 @@ elf_s390_relocate_section (output_bfd, i
case R_390_PC32:
case R_390_PC32DBL:
case R_390_PC64:
- /* r_symndx will be zero only for relocs against symbols
- from removed linkonce sections, or sections discarded by
- a linker script. */
- if (r_symndx == 0)
+ if (sec && elf_discarded_section (sec))
{
+ /* For relocs against symbols from removed linkonce
+ sections, or sections discarded by a linker script, we
+ just want the section contents zeroed. Avoid any
+ special processing. */
_bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
break;
}
--- binutils/bfd/elf64-x86-64.c.abs 2007-03-02 15:10:48.000000000 -0800
+++ binutils/bfd/elf64-x86-64.c 2007-03-02 17:59:22.000000000 -0800
@@ -2388,11 +2388,12 @@ elf64_x86_64_relocate_section (bfd *outp
/* FIXME: The ABI says the linker should make sure the value is
the same when it's zeroextended to 64 bit. */
- /* r_symndx will be zero only for relocs against symbols
- from removed linkonce sections, or sections discarded by
- a linker script. */
- if (r_symndx == 0)
+ if (sec && elf_discarded_section (sec))
{
+ /* For relocs against symbols from removed linkonce
+ sections, or sections discarded by a linker script, we
+ just want the section contents zeroed. Avoid any
+ special processing. */
_bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
break;
}
--- binutils/bfd/elflink.c.abs 2007-03-02 15:10:48.000000000 -0800
+++ binutils/bfd/elflink.c 2007-03-02 18:20:05.000000000 -0800
@@ -8479,14 +8479,19 @@ elf_link_input_bfd (struct elf_final_lin
}
}
- /* Remove the symbol reference from the reloc, but
- don't kill the reloc completely. This is so that
- a zero value will be written into the section,
- which may have non-zero contents put there by the
- assembler. Zero in things like an eh_frame fde
- pc_begin allows stack unwinders to recognize the
- fde as bogus. */
- rel->r_info &= r_type_mask;
+ /* We can't use relocation against STN_UNDEF to
+ indicate that a relocation entry is against a
+ symbol from a removed input section since it is
+ used for relocation against constant. See
+ PR 3958. We need to use elf_discarded_section
+ to check if a zero value should be be written
+ into the section, which may have non-zero
+ contents put there by the assembler. Zero
+ in things like an eh_frame fde pc_begin
+ allows stack unwinders to recognize the fde as
+ bogus. */
+ if (finfo->info->relocatable)
+ rel->r_info &= r_type_mask;
rel->r_addend = 0;
}
}
--- binutils/bfd/elfxx-ia64.c.abs 2007-03-02 15:10:48.000000000 -0800
+++ binutils/bfd/elfxx-ia64.c 2007-03-02 17:59:22.000000000 -0800
@@ -4752,10 +4752,10 @@ elfNN_ia64_relocate_section (output_bfd,
case R_IA64_LTV32LSB:
case R_IA64_LTV64MSB:
case R_IA64_LTV64LSB:
- /* r_symndx will be zero only for relocs against symbols
- from removed linkonce sections, or sections discarded by
- a linker script. */
- if (r_symndx == 0)
+ /* For relocs against symbols from removed linkonce sections,
+ or sections discarded by a linker script, we just want the
+ section contents zeroed. Avoid any special processing. */
+ if (sym_sec && elf_discarded_section (sym_sec))
value = 0;
r = elfNN_ia64_install_value (hit_addr, value, r_type);
--- binutils/bfd/elfxx-mips.c.abs 2007-03-01 14:53:14.000000000 -0800
+++ binutils/bfd/elfxx-mips.c 2007-03-02 17:59:22.000000000 -0800
@@ -4323,11 +4323,13 @@ mips_elf_calculate_relocation (bfd *abfd
input_section))
return bfd_reloc_undefined;
}
- else if (r_symndx == 0)
- /* r_symndx will be zero only for relocs against symbols
- from removed linkonce sections, or sections discarded by
- a linker script. */
- value = 0;
+ else if (sec && elf_discarded_section (sec))
+ {
+ /* For relocs against symbols from removed linkonce sections,
+ or sections discarded by a linker script, we just want the
+ section contents zeroed. Avoid any special processing. */
+ value = 0;
+ }
else
{
if (r_type != R_MIPS_REL32)
--- binutils/bfd/elfxx-sparc.c.abs 2006-11-02 19:36:09.000000000 -0800
+++ binutils/bfd/elfxx-sparc.c 2007-03-02 17:59:22.000000000 -0800
@@ -2752,11 +2752,12 @@ _bfd_sparc_elf_relocate_section (bfd *ou
case R_SPARC_L44:
case R_SPARC_UA64:
r_sparc_plt32:
- /* r_symndx will be zero only for relocs against symbols
- from removed linkonce sections, or sections discarded by
- a linker script. */
- if (r_symndx == 0)
+ if (sec && elf_discarded_section (sec))
{
+ /* For relocs against symbols from removed linkonce
+ sections, or sections discarded by a linker script, we
+ just want the section contents zeroed. Avoid any
+ special processing. */
_bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
break;
}
--- binutils/ld/testsuite/ld-elf/linkonce1.d.abs 2007-03-02 19:13:05.000000000 -0800
+++ binutils/ld/testsuite/ld-elf/linkonce1.d 2007-03-02 17:55:41.000000000 -0800
@@ -0,0 +1,12 @@
+#source: linkonce1a.s
+#source: linkonce1b.s
+#ld: -r
+#objdump: -r
+
+.*: file format .*
+
+RELOCATION RECORDS FOR \[.debug_frame\]:
+OFFSET[ ]+TYPE[ ]+VALUE[ ]*
+0+[ ]+R_[0-9A-Z_]+[ ]+\*ABS\*
+
+#pass
--- binutils/ld/testsuite/ld-elf/linkonce1a.s.abs 2007-03-02 19:13:01.000000000 -0800
+++ binutils/ld/testsuite/ld-elf/linkonce1a.s 2007-03-02 17:48:13.000000000 -0800
@@ -0,0 +1,3 @@
+ .section .gnu.linkonce.d.dummy,"aw"
+bar:
+ .long 0
--- binutils/ld/testsuite/ld-elf/linkonce1b.s.abs 2007-03-02 19:12:59.000000000 -0800
+++ binutils/ld/testsuite/ld-elf/linkonce1b.s 2007-03-02 17:48:02.000000000 -0800
@@ -0,0 +1,17 @@
+ .globl main
+ .globl start
+ .globl _start
+ .globl __start
+ .text
+main:
+start:
+_start:
+__start:
+ .long 0
+
+ .section .gnu.linkonce.d.dummy,"aw"
+ .long 0
+foo:
+ .long 0
+ .section .debug_frame,"",@progbits
+ .long foo
--- binutils/ld/testsuite/ld-elf/linkonce2.d.abs 2007-03-02 19:13:09.000000000 -0800
+++ binutils/ld/testsuite/ld-elf/linkonce2.d 2007-03-02 17:56:26.000000000 -0800
@@ -0,0 +1,12 @@
+#source: linkonce1a.s
+#source: linkonce1b.s
+#ld: -emit-relocs
+#objdump: -r
+
+.*: file format .*
+
+RELOCATION RECORDS FOR \[.debug_frame\]:
+OFFSET[ ]+TYPE[ ]+VALUE[ ]*
+0+[ ]+R_[0-9A-Z_]+[ ]+\*ABS\*
+
+#pass
--- binutils/ld/testsuite/ld-i386/i386.exp.abs 2007-03-02 15:10:48.000000000 -0800
+++ binutils/ld/testsuite/ld-i386/i386.exp 2007-03-02 17:59:22.000000000 -0800
@@ -113,4 +113,5 @@ run_ld_link_tests $i386tests
run_dump_test "abs"
run_dump_test "pcrel8"
run_dump_test "pcrel16"
+run_dump_test "pcrel16abs"
run_dump_test "alloc"
--- binutils/ld/testsuite/ld-i386/pcrel16abs.d.abs 2007-03-02 15:10:49.000000000 -0800
+++ binutils/ld/testsuite/ld-i386/pcrel16abs.d 2007-03-02 17:59:22.000000000 -0800
@@ -0,0 +1,12 @@
+#name: PCREL16 absolute reloc
+#as: --32
+#ld: -melf_i386 -Ttext 0xfffffff0
+#objdump: -drj.text -m i8086
+
+.*: +file format elf32-i386
+
+Disassembly of section .text:
+
+f+0 <_start>:
+f+0: e9 0d e0[ ]+jmp[ ]+ffffe000 <SEGMENT_SIZE\+0xfffee000>
+#pass
--- binutils/ld/testsuite/ld-i386/pcrel16abs.s.abs 2007-03-02 15:10:49.000000000 -0800
+++ binutils/ld/testsuite/ld-i386/pcrel16abs.s 2007-03-02 17:59:22.000000000 -0800
@@ -0,0 +1,6 @@
+SEGMENT_SIZE = 0x10000
+RVECTOR = 0x00010
+.code16
+ .globl _start
+_start:
+ jmp SEGMENT_SIZE-(0x1f00 +0xf0 +RVECTOR)