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]

Re: [x32] Allow R_X86_64_64


On Fri, Aug 12, 2011 at 10:53 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Fri, Aug 12, 2011 at 8:52 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Fri, Aug 12, 2011 at 8:17 AM, Jan Beulich <JBeulich@novell.com> wrote:
>>>>>> On 12.08.11 at 16:47, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>>> On Fri, Aug 12, 2011 at 7:42 AM, Jan Beulich <JBeulich@novell.com> wrote:
>>>>>>>> On 12.08.11 at 16:02, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>>>>> On Fri, Aug 12, 2011 at 6:59 AM, Jan Beulich <JBeulich@novell.com> wrote:
>>>>>>>>>> On 12.08.11 at 15:22, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>>>>>>> On Fri, Aug 12, 2011 at 6:17 AM, Jan Beulich <JBeulich@novell.com> wrote:
>>>>>>>>>>>> On 12.08.11 at 14:09, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>>>>>>>>> On Fri, Aug 12, 2011 at 12:30 AM, Jan Beulich <JBeulich@novell.com> wrote:
>>>>>>>>>>>>>> On 12.08.11 at 06:37, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>>>>>>>>>>> On Mon, Aug 1, 2011 at 3:15 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>
>>>>>>>>>>>>> It turns out that x32 needs R_X86_64_64. ?One major reason is
>>>>>>>>>>>>> the displacement range of x32 is -2G to +2G. ?It isn't a problem
>>>>>>>>>>>>> for compiler since only small model is required for x32.
>>>>>>>>>>>>>
>>>>>>>>>>>>> However, to address 0 to 4G directly in assembly code, we have
>>>>>>>>>>>>> to use R_X86_64_64 with movabs. ?I am checking the follow patch
>>>>>>>>>>>>> into x32 psABI to allow R_X86_64_64.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> X32 ?Linker should treats R_X86_64_64 as R_X86_64_32
>>>>>>>>>>>> zero-extended to 64bit for output. ?I will update x32 psABI with
>>>>>>>>>>>
>>>>>>>>>>> I'm sorry to say that, but the situation about x32 seems to be
>>>>>>>>>>> getting worse with each change you do, every time again
>>>>>>>>>>> revolving around mixing up ABI specification and a particular
>>>>>>>>>>> implementation thereof.
>>>>>>>>>>>
>>>>>>>>>>> Here, if you need something zero-extended (though I can't see
>>>>>>>>>>> why you would), then you should use a new relocation type. As
>>>>>>>>>>> pointed out before, there are valid possible uses of R_X86_64_64
>>>>>>>>>>> that would require the semantics of x86-64.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> When does x32 need the semantics of x86-64 for R_X86_64_64?
>>>>>>>>>
>>>>>>>>> When referencing an assembler or linker defined constant that
>>>>>>>>> exceeds 32-bit in width. Given that this is a 64-bit architecture
>>>>>>>>> with 32-bit addresses, at least I would expect such to work.
>>>>>>>>>
>>>>>>>>
>>>>>>>> Yes, it should work just fine for x32 by zero-extending 32bit
>>>>>>>> address to 64bit.
>>>>>>>
>>>>>>> For a constant that has more than 32 significant bits???
>>>>>>>
>>>>>>
>>>>>> Can you give me an example in assembly code?
>>>>>
>>>>> Something like
>>>>>
>>>>> ? ? ? ?.equ ? ?sym, 0x1234567890
>>>>> ? ? ? ?.global sym
>>>>>
>>>>
>>>> "sym" is truncated to 32bit:
>>>
>>> Yes, because of your tying of the ABI to ELF32.
>>
>> X32 uses ELF32 and won't change.
>>
>>>> Symbol table '.symtab' contains 5 entries:
>>>> ? ?Num: ? ?Value ?Size Type ? ?Bind ? Vis ? ? ?Ndx Name
>>>> ? ? ?0: 00000000 ? ? 0 NOTYPE ?LOCAL ?DEFAULT ?UND
>>>> ? ? ?1: 00000000 ? ? 0 SECTION LOCAL ?DEFAULT ? ?1
>>>> ? ? ?2: 00000000 ? ? 0 SECTION LOCAL ?DEFAULT ? ?2
>>>> ? ? ?3: 00000000 ? ? 0 SECTION LOCAL ?DEFAULT ? ?3
>>>> ? ? ?4: 34567890 ? ? 0 NOTYPE ?GLOBAL DEFAULT ?ABS sym
>>>>
>>>> However, one can write
>>>>
>>>> .quad main + 0x8000000
>>>
>>> And I suppose that wouldn't work either with your R_X86_64_64
>>> implied zero-extension...
>>>
>>
>
> I will add R_X86_64_64 support to x32 dynamic linker. ?I will
> also add R_X86_64_RELATIVE64 to x32 dynamic linker.
>
> For R_X86_64_64 relocation, if addend is 0, linker will
> turn it to R_X86_64_32 and zero-extends it to 64bit. Otherwise,
> linker will generate R_X86_64_RELATIVE64 if it is a relocation
> against a local symbol or keep R_X86_64_64 for relocations
> against external symbols. We need R_X86_64_RELATIVE64
> since R_X86_64_RELATIVE only updates 32bit destination.
>
>
> --
> H.J.
> ---
> diff --git a/object-files.tex b/object-files.tex
> index 7f0fd14..d2be264 100644
> --- a/object-files.tex
> +++ b/object-files.tex
> @@ -483,10 +483,13 @@ or \texttt{Elf32_Rel} relocation.
> ? ? ? \texttt{R_X86_64_TLSDESC_CALL} & 35 & none & ?\\
> ? ? ? \texttt{R_X86_64_TLSDESC} & 36 & \textit{word64}$\times 2$ & \\
> ? ? ? \texttt{R_X86_64_IRELATIVE} & 37 & \textit{wordclass} &
> \texttt{indirect (B + A)}\\
> + ? ? ?\texttt{R_X86_64_RELATIVE64} $^{\dagger\dagger}$ & 38 &
> \textit{word64} & \texttt{B + A} \\
> ?% ? ? ?\texttt{R_X86_64_GOT64} & 16 & \textit{word64} & \texttt{G + A} \\
> ?% ? ? ?\texttt{R_X86_64_PLT64} & 17 & \textit{word64} & \texttt{L + A - P} \\
> ? ? ?\cline{1-4}
> ? ? \multicolumn{3}{l}{\small $^\dagger$ This relocation is used only
> for LP64.}\\
> + ? ?\multicolumn{3}{l}{\small $^{\dagger\dagger}$ This relocation only
> + ? ?appears in X32 executable files or shared objects.}\\
> ? ? \end{tabular}
> ? \end{center}
> ?\Hrule
>

I checked the enclosed linker change. I also enclosed the glibc change
to handle R_X86_64_RELATIVE64 and R_X86_64_64 for x32.


-- 
H.J.
bfd/

2011-08-12  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/13082
	* elf64-x86-64.c (x86_64_elf_howto_table): Add R_X86_64_RELATIVE64.
	(elf_x86_64_relocate_section): Treat R_X86_64_64 like R_X86_64_32
	and zero-extend it to 64bit if addend is zero for x32.  Generate
	R_X86_64_RELATIVE64 for x32.

include/elf/

2011-08-12  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/13082
	* x86-64.h (R_X86_64_RELATIVE64): New.

ld/testsuite/

2011-08-12  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/13082
	* ld-x86-64/pr13082-1.s: New.
	* ld-x86-64/pr13082-1a.d: Likewise.
	* ld-x86-64/pr13082-1b.d: Likewise.
	* ld-x86-64/pr13082-2.s: Likewise.
	* ld-x86-64/pr13082-2a.d: Likewise.
	* ld-x86-64/pr13082-2b.d: Likewise.
	* ld-x86-64/pr13082-3.s: Likewise.
	* ld-x86-64/pr13082-3a.d: Likewise.
	* ld-x86-64/pr13082-3b.d: Likewise.
	* ld-x86-64/pr13082-4.s: Likewise.
	* ld-x86-64/pr13082-4a.d: Likewise.
	* ld-x86-64/pr13082-4b.d: Likewise.
	* ld-x86-64/pr13082-5.s: Likewise.
	* ld-x86-64/pr13082-5a.d: Likewise.
	* ld-x86-64/pr13082-5b.d: Likewise.
	* ld-x86-64/pr13082-6.s: Likewise.
	* ld-x86-64/pr13082-6a.d: Likewise.
	* ld-x86-64/pr13082-6b.d: Likewise.

	* ld-x86-64/x86-64.exp: Run pr13082-[1-6][ab].

diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 7b92097..238c7bd 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -164,6 +164,9 @@ static reloc_howto_type x86_64_elf_howto_table[] =
   HOWTO(R_X86_64_IRELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
 	bfd_elf_generic_reloc, "R_X86_64_IRELATIVE", FALSE, MINUS_ONE,
 	MINUS_ONE, FALSE),
+  HOWTO(R_X86_64_RELATIVE64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+	bfd_elf_generic_reloc, "R_X86_64_RELATIVE64", FALSE, MINUS_ONE,
+	MINUS_ONE, FALSE),
 
   /* We have a gap in the reloc numbers here.
      R_X86_64_standard counts the number up to this point, and
@@ -3083,6 +3086,16 @@ elf_x86_64_relocate_section (bfd *output_bfd,
       if (info->relocatable)
 	continue;
 
+      if (rel->r_addend == 0
+	  && r_type == R_X86_64_64
+	  && !ABI_64_P (output_bfd))
+	{
+	  /* For x32, treat R_X86_64_64 like R_X86_64_32 and zero-extend
+	     it to 64bit if addend is zero.  */
+	  r_type = R_X86_64_32;
+	  memset (contents + rel->r_offset + 4, 0, 4);
+	}
+
       /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
 	 it here if it is defined in a non-shared object.  */
       if (h != NULL
@@ -3597,6 +3610,14 @@ elf_x86_64_relocate_section (bfd *output_bfd,
 		      outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
 		      outrel.r_addend = relocation + rel->r_addend;
 		    }
+		  else if (r_type == R_X86_64_64
+			   && !ABI_64_P (output_bfd))
+		    {
+		      relocate = TRUE;
+		      outrel.r_info = htab->r_info (0,
+						    R_X86_64_RELATIVE64);
+		      outrel.r_addend = relocation + rel->r_addend;
+		    }
 		  else
 		    {
 		      long sindx;
diff --git a/include/elf/x86-64.h b/include/elf/x86-64.h
index 56254d2..9022f84 100644
--- a/include/elf/x86-64.h
+++ b/include/elf/x86-64.h
@@ -72,6 +72,7 @@ START_RELOC_NUMBERS (elf_x86_64_reloc_type)
 						 descriptor.  */
      RELOC_NUMBER (R_X86_64_TLSDESC, 36)      /* 2x64-bit TLS descriptor.  */
      RELOC_NUMBER (R_X86_64_IRELATIVE, 37)    /* Adjust indirectly by program base */
+     RELOC_NUMBER (R_X86_64_RELATIVE64, 38)   /* 64bit adjust by program base */
      RELOC_NUMBER (R_X86_64_GNU_VTINHERIT, 250)       /* GNU C++ hack  */
      RELOC_NUMBER (R_X86_64_GNU_VTENTRY, 251)         /* GNU C++ hack  */
 END_RELOC_NUMBERS (R_X86_64_max)
diff --git a/ld/testsuite/ld-x86-64/pr13082-1.s b/ld/testsuite/ld-x86-64/pr13082-1.s
new file mode 100644
index 0000000..6c03e98
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-1.s
@@ -0,0 +1,10 @@
+	.text
+	.globl _start
+_start:
+	lea	.Ljmp(%rip), %rax
+.L1:
+	jmp	*(%rax)
+	.section	.data.rel.ro.local,"aw",@progbits
+	.align	8
+.Ljmp:
+	.quad .L1
diff --git a/ld/testsuite/ld-x86-64/pr13082-1a.d b/ld/testsuite/ld-x86-64/pr13082-1a.d
new file mode 100644
index 0000000..f0e98ff
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-1a.d
@@ -0,0 +1,9 @@
+#source: pr13082-1.s
+#name: PR ld/13082-1 (a)
+#as: --x32
+#ld: -shared -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE64 +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr13082-1b.d b/ld/testsuite/ld-x86-64/pr13082-1b.d
new file mode 100644
index 0000000..f10481f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-1b.d
@@ -0,0 +1,9 @@
+#source: pr13082-1.s
+#name: PR ld/13082-1 (b)
+#as: --x32
+#ld: -pie -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE64 +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr13082-2.s b/ld/testsuite/ld-x86-64/pr13082-2.s
new file mode 100644
index 0000000..d1847a6
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-2.s
@@ -0,0 +1,9 @@
+	.text
+	.globl _start
+_start:
+	lea	.Ljmp(%rip), %rax
+	jmp	*(%rax)
+	.section	.data.rel.ro.local,"aw",@progbits
+	.align	8
+.Ljmp:
+	.quad _start
diff --git a/ld/testsuite/ld-x86-64/pr13082-2a.d b/ld/testsuite/ld-x86-64/pr13082-2a.d
new file mode 100644
index 0000000..aed33c2
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-2a.d
@@ -0,0 +1,9 @@
+#source: pr13082-2.s
+#name: PR ld/13082-2 (a)
+#as: --x32
+#ld: -shared -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +[0-9a-f]+ +_start \+ 0
diff --git a/ld/testsuite/ld-x86-64/pr13082-2b.d b/ld/testsuite/ld-x86-64/pr13082-2b.d
new file mode 100644
index 0000000..b000e85
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-2b.d
@@ -0,0 +1,9 @@
+#source: pr13082-2.s
+#name: PR ld/13082-2 (b)
+#as: --x32
+#ld: -pie -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr13082-3.s b/ld/testsuite/ld-x86-64/pr13082-3.s
new file mode 100644
index 0000000..b76eb0f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-3.s
@@ -0,0 +1,10 @@
+	.text
+	.globl _start
+_start:
+	lea	.Ljmp(%rip), %rax
+	jmp	*(%rax)
+	.section	.data.rel.ro.local,"aw",@progbits
+	.weak func
+	.align	8
+.Ljmp:
+	.quad func
diff --git a/ld/testsuite/ld-x86-64/pr13082-3a.d b/ld/testsuite/ld-x86-64/pr13082-3a.d
new file mode 100644
index 0000000..bf176f9
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-3a.d
@@ -0,0 +1,9 @@
+#source: pr13082-3.s
+#name: PR ld/13082-3 (a)
+#as: --x32
+#ld: -shared -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +[0-9a-f]+ +func \+ 0
diff --git a/ld/testsuite/ld-x86-64/pr13082-3b.d b/ld/testsuite/ld-x86-64/pr13082-3b.d
new file mode 100644
index 0000000..12efaf0
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-3b.d
@@ -0,0 +1,9 @@
+#source: pr13082-3.s
+#name: PR ld/13082-3 (b)
+#as: --x32
+#ld: -pie -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +[0-9a-f]+ +func \+ 0
diff --git a/ld/testsuite/ld-x86-64/pr13082-4.s b/ld/testsuite/ld-x86-64/pr13082-4.s
new file mode 100644
index 0000000..ed8506d
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-4.s
@@ -0,0 +1,10 @@
+	.text
+	.globl _start
+_start:
+	lea	.Ljmp(%rip), %rax
+	jmp	*(%rax)
+	.section	.data.rel.ro.local,"aw",@progbits
+	.weak func
+	.align	8
+.Ljmp:
+	.quad func + 1
diff --git a/ld/testsuite/ld-x86-64/pr13082-4a.d b/ld/testsuite/ld-x86-64/pr13082-4a.d
new file mode 100644
index 0000000..bb2c573
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-4a.d
@@ -0,0 +1,9 @@
+#source: pr13082-4.s
+#name: PR ld/13082-4 (a)
+#as: --x32
+#ld: -shared -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_64 +[0-9a-f]+ +func \+ 1
diff --git a/ld/testsuite/ld-x86-64/pr13082-4b.d b/ld/testsuite/ld-x86-64/pr13082-4b.d
new file mode 100644
index 0000000..cb4d90a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-4b.d
@@ -0,0 +1,9 @@
+#source: pr13082-4.s
+#name: PR ld/13082-4 (b)
+#as: --x32
+#ld: -pie -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_64 +[0-9a-f]+ +func \+ 1
diff --git a/ld/testsuite/ld-x86-64/pr13082-5.s b/ld/testsuite/ld-x86-64/pr13082-5.s
new file mode 100644
index 0000000..9757fcb
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-5.s
@@ -0,0 +1,12 @@
+	.text
+	.globl _start
+	.globl ifunc
+	.type ifunc, @gnu_indirect_function
+_start:
+	lea	.Ljmp(%rip), %rax
+ifunc:
+	jmp	*(%rax)
+	.section	.data.rel.ro.local,"aw",@progbits
+	.align	8
+.Ljmp:
+	.quad ifunc
diff --git a/ld/testsuite/ld-x86-64/pr13082-5a.d b/ld/testsuite/ld-x86-64/pr13082-5a.d
new file mode 100644
index 0000000..e5b0c11
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-5a.d
@@ -0,0 +1,14 @@
+#source: pr13082-5.s
+#name: PR ld/13082-5 (a)
+#as: --x32
+#ld: -shared -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +ifunc\(\)+ +ifunc \+ 0
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +ifunc\(\)+ +ifunc \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_JUMP_SLOT +ifunc\(\)+ +ifunc \+ 0
diff --git a/ld/testsuite/ld-x86-64/pr13082-5b.d b/ld/testsuite/ld-x86-64/pr13082-5b.d
new file mode 100644
index 0000000..1c5a5e7
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-5b.d
@@ -0,0 +1,13 @@
+#source: pr13082-5.s
+#name: PR ld/13082-5 (b)
+#as: --x32
+#ld: -pie -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr13082-6.s b/ld/testsuite/ld-x86-64/pr13082-6.s
new file mode 100644
index 0000000..eb88fb6
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-6.s
@@ -0,0 +1,11 @@
+	.text
+	.globl _start
+	.type ifunc, @gnu_indirect_function
+_start:
+	lea	.Ljmp(%rip), %rax
+ifunc:
+	jmp	*(%rax)
+	.section	.data.rel.ro.local,"aw",@progbits
+	.align	8
+.Ljmp:
+	.quad ifunc
diff --git a/ld/testsuite/ld-x86-64/pr13082-6a.d b/ld/testsuite/ld-x86-64/pr13082-6a.d
new file mode 100644
index 0000000..9a1a655
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-6a.d
@@ -0,0 +1,13 @@
+#source: pr13082-6.s
+#name: PR ld/13082-6 (a)
+#as: --x32
+#ld: -shared -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr13082-6b.d b/ld/testsuite/ld-x86-64/pr13082-6b.d
new file mode 100644
index 0000000..792c348
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr13082-6b.d
@@ -0,0 +1,13 @@
+#source: pr13082-6.s
+#name: PR ld/13082-6 (b)
+#as: --x32
+#ld: -pie -melf32_x86_64
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_IRELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 2b8721c..77b081b 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -213,6 +213,18 @@ run_dump_test "ia32-3"
 run_dump_test "lp64-1"
 run_dump_test "lp64-2"
 run_dump_test "lp64-3"
+run_dump_test "pr13082-1a"
+run_dump_test "pr13082-1b"
+run_dump_test "pr13082-2a"
+run_dump_test "pr13082-2b"
+run_dump_test "pr13082-3a"
+run_dump_test "pr13082-3b"
+run_dump_test "pr13082-4a"
+run_dump_test "pr13082-4b"
+run_dump_test "pr13082-5a"
+run_dump_test "pr13082-5b"
+run_dump_test "pr13082-6a"
+run_dump_test "pr13082-6b"
 
 # Must be native with the C compiler
 if { [isnative] && [which $CC] != 0 } {
commit 3c876e080bd7a98f378794288f49a0fb4bf3026b
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Aug 12 12:54:37 2011 -0700

    Handle R_X86_64_RELATIVE64 and R_X86_64_64 for x32.

diff --git a/ChangeLog.x32 b/ChangeLog.x32
index b7c3a69..ffb797b 100644
--- a/ChangeLog.x32
+++ b/ChangeLog.x32
@@ -1,3 +1,10 @@
+2011-08-12  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* elf/elf.h (R_X86_64_RELATIVE64): New.
+
+	* sysdeps/x86_64/dl-machine.h (elf_machine_rela): Handle
+	R_X86_64_RELATIVE64 and R_X86_64_64 for x32.
+
 2011-07-24  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* configure.in: Check size of long.
diff --git a/elf/elf.h b/elf/elf.h
index ca5abbf..0f87b4e 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -2712,8 +2712,9 @@ typedef Elf32_Addr Elf32_Conflict;
 					   descriptor.  */
 #define R_X86_64_TLSDESC        36	/* TLS descriptor.  */
 #define R_X86_64_IRELATIVE	37	/* Adjust indirectly by program base */
+#define R_X86_64_RELATIVE64	38	/* 64bit adjust by program base */
 
-#define R_X86_64_NUM		38
+#define R_X86_64_NUM		39
 
 
 /* AM33 relocations.  */
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index dbeb078..74a8109 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -286,6 +286,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
     }
   else
 # endif
+# if !defined RTLD_BOOTSTRAP && !defined __LP64__
+  if (__builtin_expect (r_type == R_X86_64_RELATIVE64, 0))
+    *((Elf64_Addr *) (uintptr_t) reloc_addr)
+      = (Elf64_Addr) map->l_addr + reloc->r_addend;
+  else
+# endif
   if (__builtin_expect (r_type == R_X86_64_NONE, 0))
     return;
   else
@@ -404,11 +410,14 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
 # endif
 
 # ifndef RTLD_BOOTSTRAP
-#  ifdef __LP64__
 	case R_X86_64_64:
+#  ifdef __LP64__
 	  *reloc_addr = value + reloc->r_addend;
-	  break;
+#  else
+	  *((Elf64_Addr *) (uintptr_t) reloc_addr)
+	    = (Elf64_Addr) value + reloc->r_addend;
 #  endif
+	  break;
 	case R_X86_64_32:
 	  value += reloc->r_addend;
 	  *(unsigned int *) reloc_addr = value;

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