All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: RFC: binutils PATCH: Set e_type to ET_EXEC for -pie -Ttext-segment=
@ 2013-12-10 12:20 H.J. Lu
  2013-12-10 19:08 ` H. Peter Anvin
  0 siblings, 1 reply; 8+ messages in thread
From: H.J. Lu @ 2013-12-10 12:20 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Binutils, Jiri Kosina, LKML, Josh Boyer

On Mon, Dec 9, 2013 at 8:57 PM, H. Peter Anvin <hpa@zytor.com> wrote:
> Where do the _32 and _32S relocations come from?  Are we mixing multiple things inside -pie?

They come from crt1.o and crtbegin.o.  -pie uses Scrt1.o and crtbeginS.o.

> "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>On Mon, Dec 9, 2013 at 7:23 PM, H. Peter Anvin <hpa@zytor.com> wrote:
>>> On 12/09/2013 07:05 PM, H.J. Lu wrote:
>>>>>
>>>>> I see.  Maybe linker can set ET_EXEC if vaddr is non-zero.
>>>>>
>>>>
>>>> Linker sets e_type in ELF header to ET_DYN for -pie
>>-Ttext-segment=0xXXX.
>>>> When I added -Ttext-segment=0xXXX, one goal was to load
>>>> small model executable above 4GB on Linux/x86-64, which
>>>> was done with -pie -Ttext-segment=0xXXX.  But -pie sets
>>>> e_type in ELF header to ET_DYN and kernel may ignore
>>>> p_vaddr in ELF header to load ET_DYN binary at a random
>>>> address.  This patch changes ld to set e_type in ELF header
>>>> to ET_EXEC if the first PT_LOAD segment has non-zero
>>>> p_vaddr.  If this is unacceptable as generic ELF change,
>>>> I can make it specific to x86.
>>>>
>>>
>>> Why not just drop the -pie from the command line?  I would expect
>>-pie
>>> to set ET_DYN, but if you want to load at a specific address one
>>would
>>> expect to use -Ttext-segment=... and *not* -pie.
>>>
>>
>>No.  We must keep -pie.  Without -pie, we can't set -Ttext-segment=
>>to above 4GB:
>>
>>[hjl@gnu-6 tmp]$ gcc  a.c -Wl,-Ttext-segment=0x7ff000000
>>/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/crt1.o: In
>>function `_start':
>>(.text+0x12): relocation truncated to fit: R_X86_64_32S against symbol
>>`__libc_csu_fini' defined in .text section in
>>/usr/lib64/libc_nonshared.a(elf-init.oS)
>>/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/crt1.o: In
>>function `_start':
>>(.text+0x19): relocation truncated to fit: R_X86_64_32S against symbol
>>`__libc_csu_init' defined in .text section in
>>/usr/lib64/libc_nonshared.a(elf-init.oS)
>>/usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/crt1.o: In
>>function `_start':
>>(.text+0x20): relocation truncated to fit: R_X86_64_32S against symbol
>>`main' defined in .text section in /tmp/ccV9AIMR.o
>>/usr/lib/gcc/x86_64-redhat-linux/4.8.2/crtbegin.o: In function
>>`deregister_tm_clones':
>>crtstuff.c:(.text+0x1): relocation truncated to fit: R_X86_64_32
>>against symbol `__TMC_END__' defined in .data section in a.out
>>crtstuff.c:(.text+0x8): relocation truncated to fit: R_X86_64_32S
>>against `.tm_clone_table'
>>crtstuff.c:(.text+0x23): relocation truncated to fit: R_X86_64_32
>>against `.tm_clone_table'
>>/usr/lib/gcc/x86_64-redhat-linux/4.8.2/crtbegin.o: In function
>>`register_tm_clones':
>>crtstuff.c:(.text+0x31): relocation truncated to fit: R_X86_64_32
>>against symbol `__TMC_END__' defined in .data section in a.out
>>crtstuff.c:(.text+0x38): relocation truncated to fit: R_X86_64_32S
>>against `.tm_clone_table'
>>crtstuff.c:(.text+0x63): relocation truncated to fit: R_X86_64_32
>>against `.tm_clone_table'
>>/usr/lib/gcc/x86_64-redhat-linux/4.8.2/crtbegin.o: In function
>>`frame_dummy':
>>crtstuff.c:(.text+0xa6): relocation truncated to fit: R_X86_64_32
>>against `.jcr'
>>/tmp/ccV9AIMR.o: In function `main':
>>a.c:(.text+0x5): additional relocation overflows omitted from the
>>output
>>collect2: error: ld returned 1 exit status
>>[hjl@gnu-6 tmp]$ gcc -fpie -pie  a.c -Wl,-Ttext-segment=0x7ff000000
>>[hjl@gnu-6 tmp]$
>>
>

-- 
H.J.

^ permalink raw reply	[flat|nested] 8+ messages in thread
* RFC: binutils PATCH: Set e_type to ET_EXEC for -pie -Ttext-segment=
@ 2013-12-10  3:10 H.J. Lu
  2013-12-10 22:36 ` Alan Modra
  0 siblings, 1 reply; 8+ messages in thread
From: H.J. Lu @ 2013-12-10  3:10 UTC (permalink / raw)
  To: LKML, Binutils

My original post was rejected by LKML.  Resend.

On Mon, Dec 9, 2013 at 4:41 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Mon, Dec 9, 2013 at 4:37 PM, H. Peter Anvin <hpa@zytor.com> wrote:
>> On 12/09/2013 03:53 PM, H.J. Lu wrote:
>>>>>
>>>>> x86-64 small model is limited to 4GB in size.  You can't build
>>>>> a dynamic executable in small model larger than 4GB.
>>>>>
>>>>> There are medium and large models.  But they are slower than
>>>>> small models as well as small models in PIE.  Also there are
>>>>> no glibc run-times for medium and large models.
>>>>>
>>>> Compiling for the small PIC model shouldn't automatically mean
>>>> generating a PIE (ET_DYN) executable, though (and if those are
>>>> inherently linked, that is a fundamental bug IMNSHO.)
>>>
>>> PIE uses PIC. But GCC has -fPIE and -fPIC.  They aren't
>>> the same.   You build PIE with
>>>
>>> 1. Compile with -fPIE.
>>> 2. Link with -pie.
>>>
>>
>> I'm talking about the memory model ("small PIC model").  I don't see why
>> it should be encapsulated in a PIE (ET_DYN) container if the user
>> doesn't want it to be relocatable.
>>
>
> I see.  Maybe linker can set ET_EXEC if vaddr is non-zero.
>

Hi,

Linker sets e_type in ELF header to ET_DYN for -pie -Ttext-segment=0xXXX.
When I added -Ttext-segment=0xXXX, one goal was to load
small model executable above 4GB on Linux/x86-64, which
was done with -pie -Ttext-segment=0xXXX.  But -pie sets
e_type in ELF header to ET_DYN and kernel may ignore
p_vaddr in ELF header to load ET_DYN binary at a random
address.  This patch changes ld to set e_type in ELF header
to ET_EXEC if the first PT_LOAD segment has non-zero
p_vaddr.  If this is unacceptable as generic ELF change,
I can make it specific to x86.

Thanks.


--
H.J.
--
diff --git a/bfd/elf.c b/bfd/elf.c
index 8df38ee..5862460 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -5152,6 +5152,27 @@ assign_file_positions_except_relocs (bfd *abfd,
         return FALSE;
     }

+      if (link_info != NULL
+      && link_info->executable
+      && link_info->shared)
+    {
+      Elf_Internal_Phdr *segment;
+      unsigned int i;
+      unsigned int num_segments = elf_elfheader (abfd)->e_phnum;
+      bfd_vma p_vaddr = 0;
+      for (i = 0, segment = elf_tdata (abfd)->phdr;
+           i < num_segments;
+           i++, segment++)
+        if (segment->p_type == PT_LOAD)
+          {
+        p_vaddr = segment->p_vaddr;
+        break;
+          }
+
+      if (p_vaddr)
+        i_ehdrp->e_type = ET_EXEC;
+    }
+
       /* Write out the program headers.  */
       alloc = elf_program_header_size (abfd) / bed->s->sizeof_phdr;
       if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0


-- 
H.J.

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-12-12 15:42 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-10 12:20 RFC: binutils PATCH: Set e_type to ET_EXEC for -pie -Ttext-segment= H.J. Lu
2013-12-10 19:08 ` H. Peter Anvin
2013-12-10 19:15   ` H.J. Lu
2013-12-10 19:26     ` H. Peter Anvin
  -- strict thread matches above, loose matches on Subject: below --
2013-12-10  3:10 H.J. Lu
2013-12-10 22:36 ` Alan Modra
2013-12-10 22:47   ` H.J. Lu
2013-12-12 15:42     ` H.J. Lu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.