* 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
* Re: RFC: binutils PATCH: Set e_type to ET_EXEC for -pie -Ttext-segment=
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
0 siblings, 1 reply; 8+ messages in thread
From: H. Peter Anvin @ 2013-12-10 19:08 UTC (permalink / raw)
To: H.J. Lu; +Cc: Binutils, Jiri Kosina, LKML, Josh Boyer
On 12/10/2013 04:20 AM, H.J. Lu wrote:
> 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.
>
OK, so this is fundamentally an issue with the gcc wrapper... there
isn't a way to get the relocatable crt files without telling the linker
to link PIE (except perhaps using some -Wl option, maybe "-Wl,-no-pie"?)
Either way, if the *only* goal is to get the file above a certain point,
like 4 GiB, then there is no reason not to randomize upward.
-hpa
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFC: binutils PATCH: Set e_type to ET_EXEC for -pie -Ttext-segment=
2013-12-10 19:08 ` H. Peter Anvin
@ 2013-12-10 19:15 ` H.J. Lu
2013-12-10 19:26 ` H. Peter Anvin
0 siblings, 1 reply; 8+ messages in thread
From: H.J. Lu @ 2013-12-10 19:15 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: Binutils, Jiri Kosina, LKML, Josh Boyer
On Tue, Dec 10, 2013 at 11:08 AM, H. Peter Anvin <hpa@zytor.com> wrote:
> On 12/10/2013 04:20 AM, H.J. Lu wrote:
>> 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.
>>
>
> OK, so this is fundamentally an issue with the gcc wrapper... there
> isn't a way to get the relocatable crt files without telling the linker
> to link PIE (except perhaps using some -Wl option, maybe "-Wl,-no-pie"?)
>
> Either way, if the *only* goal is to get the file above a certain point,
> like 4 GiB, then there is no reason not to randomize upward.
>
I agree that kernel should load ET_DYN binary anywhere. I will
change linker to set type to ET_EXEC if p_vaddr != 0.
--
H.J.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFC: binutils PATCH: Set e_type to ET_EXEC for -pie -Ttext-segment=
2013-12-10 19:15 ` H.J. Lu
@ 2013-12-10 19:26 ` H. Peter Anvin
0 siblings, 0 replies; 8+ messages in thread
From: H. Peter Anvin @ 2013-12-10 19:26 UTC (permalink / raw)
To: H.J. Lu; +Cc: Binutils, Jiri Kosina, LKML, Josh Boyer
On 12/10/2013 11:15 AM, H.J. Lu wrote:
>>
>> Either way, if the *only* goal is to get the file above a certain point,
>> like 4 GiB, then there is no reason not to randomize upward.
>
> I agree that kernel should load ET_DYN binary anywhere. I will
> change linker to set type to ET_EXEC if p_vaddr != 0.
>
I didn't say "anywhere". I said "at or above the p_vaddr".
-hpa
^ 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* Re: 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
2013-12-10 22:47 ` H.J. Lu
0 siblings, 1 reply; 8+ messages in thread
From: Alan Modra @ 2013-12-10 22:36 UTC (permalink / raw)
To: H.J. Lu; +Cc: LKML, Binutils
On Mon, Dec 09, 2013 at 07:10:23PM -0800, H.J. Lu wrote:
> 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.
Well, I suppose it's a hack to use ET_DYN for executables in the first
place, so one more hack in the linker hardly matters. Why not just
patch the kernel though? The kernel can look at the first PT_LOAD
header just as easily as the linker, and it's the kernel that is doing
the loading after all.
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFC: binutils PATCH: Set e_type to ET_EXEC for -pie -Ttext-segment=
2013-12-10 22:36 ` Alan Modra
@ 2013-12-10 22:47 ` H.J. Lu
2013-12-12 15:42 ` H.J. Lu
0 siblings, 1 reply; 8+ messages in thread
From: H.J. Lu @ 2013-12-10 22:47 UTC (permalink / raw)
To: LKML, Binutils
On Tue, Dec 10, 2013 at 2:36 PM, Alan Modra <amodra@gmail.com> wrote:
> On Mon, Dec 09, 2013 at 07:10:23PM -0800, H.J. Lu wrote:
>> 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.
>
> Well, I suppose it's a hack to use ET_DYN for executables in the first
> place, so one more hack in the linker hardly matters. Why not just
> patch the kernel though? The kernel can look at the first PT_LOAD
> header just as easily as the linker, and it's the kernel that is doing
> the loading after all.
>
Kernel should have some freedom on where to load ET_DYN object.
But when -Ttext-segment= is used, programmer expects the
executable will be loaded at the specified address. Setting
ET_EXEC will guarantee that it will be loaded at that address.
--
H.J.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFC: binutils PATCH: Set e_type to ET_EXEC for -pie -Ttext-segment=
2013-12-10 22:47 ` H.J. Lu
@ 2013-12-12 15:42 ` H.J. Lu
0 siblings, 0 replies; 8+ messages in thread
From: H.J. Lu @ 2013-12-12 15:42 UTC (permalink / raw)
To: LKML, Binutils
On Tue, Dec 10, 2013 at 2:47 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Dec 10, 2013 at 2:36 PM, Alan Modra <amodra@gmail.com> wrote:
>> On Mon, Dec 09, 2013 at 07:10:23PM -0800, H.J. Lu wrote:
>>> 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.
>>
>> Well, I suppose it's a hack to use ET_DYN for executables in the first
>> place, so one more hack in the linker hardly matters. Why not just
>> patch the kernel though? The kernel can look at the first PT_LOAD
>> header just as easily as the linker, and it's the kernel that is doing
>> the loading after all.
>>
>
> Kernel should have some freedom on where to load ET_DYN object.
> But when -Ttext-segment= is used, programmer expects the
> executable will be loaded at the specified address. Setting
> ET_EXEC will guarantee that it will be loaded at that address.
>
I checked it in with 2 testcases.
--
H.J.
^ permalink raw reply [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.