Message ID | 20170929213203.GG2482@gmail.com |
---|---|
State | New, archived |
Headers |
Received: (qmail 6392 invoked by alias); 29 Sep 2017 21:32:13 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: <libc-alpha.sourceware.org> List-Unsubscribe: <mailto:libc-alpha-unsubscribe-##L=##H@sourceware.org> List-Subscribe: <mailto:libc-alpha-subscribe@sourceware.org> List-Archive: <http://sourceware.org/ml/libc-alpha/> List-Post: <mailto:libc-alpha@sourceware.org> List-Help: <mailto:libc-alpha-help@sourceware.org>, <http://sourceware.org/ml/#faqs> Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 6138 invoked by uid 89); 29 Sep 2017 21:32:12 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.7 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-it0-f50.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition:user-agent; bh=B+mcH079JyHQSVSFI2myFWIWbnZkHZZrvXyHJF+pZOE=; b=PBjb+eDJRYX9spT0fEgXy+WNCgcNNijbAwP8vvshRm6rqSWoZPJpa8SFdVUxR/lHR4 cSG/vJFlCD88CtF30HlEBvZXoQo09hb5tIvTDCeUgKUMUoFZzGZJtVboN/vXmH37enjG mO0J6UPxGGFvnUBKrjTjV1jspD0Zsx8aSvJ8vap3Ifdd3WM3/SGi2CfF0KW/ofwT86by zvah7fVKpGyXmM+iORahTHPzjvo/J+mTtd73zaoxhOo71+NDkWFf5EYZ36z7TwABOJul ajakj4470vnaL8O8LrhutXL2ERWg81i7HdT1+S4GoHMJdm8o9rDJXrwD7D0J3FhYCjJ+ DI1Q== X-Gm-Message-State: AMCzsaXTtbgu+23+Ti+8DFrvUF3GHS8bbahC0sZlAnf7rsWSwzlNZe3d OSC6EoghOOfI1F6rXW7fhejcJ6hC X-Google-Smtp-Source: AOwi7QDb7IpoZtJjb2fzXUKIOsZwtqa6LjaSgRvXwyxfNnapVpdn18ZLvgDKEmFDzEsYSQQqp21CAA== X-Received: by 10.36.1.12 with SMTP id 12mr2314414itk.84.1506720730027; Fri, 29 Sep 2017 14:32:10 -0700 (PDT) Date: Fri, 29 Sep 2017 14:32:03 -0700 From: "H.J. Lu" <hjl.tools@gmail.com> To: GNU C Library <libc-alpha@sourceware.org> Subject: [PATCH] aarch64: Check PIC instead of SHARED in start.S Message-ID: <20170929213203.GG2482@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.9.0 (2017-09-02) |
Commit Message
H.J. Lu
Sept. 29, 2017, 9:32 p.m. UTC
Since start.o may be compiled as PIC, we should check PIC instead of SHARED. OK for master? * sysdeps/aarch64/start.S (_start): Check PIC instead of SHARED. --- sysdeps/aarch64/start.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Comments
On 29/09/17 22:32, H.J. Lu wrote: > Since start.o may be compiled as PIC, we should check PIC instead of > SHARED. > > OK for master? > i believe that the compile/link tests worked.. ..but i still don't understand how the GOT entries of the startup code get initialized in PIE executable at runtime. > > * sysdeps/aarch64/start.S (_start): Check PIC instead of SHARED. > --- > sysdeps/aarch64/start.S | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/sysdeps/aarch64/start.S b/sysdeps/aarch64/start.S > index c20433ad73..7a946506f2 100644 > --- a/sysdeps/aarch64/start.S > +++ b/sysdeps/aarch64/start.S > @@ -60,7 +60,7 @@ _start: > /* Setup stack limit in argument register */ > mov x6, sp > > -#ifdef SHARED > +#ifdef PIC > adrp x0, :got:main > ldr PTR_REG (0), [x0, #:got_lo12:main] > >
On 10/2/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: > On 29/09/17 22:32, H.J. Lu wrote: >> Since start.o may be compiled as PIC, we should check PIC instead of >> SHARED. >> >> OK for master? >> > > i believe that the compile/link tests worked.. Does static PIE of hjl/pie/static branch run on arm and aarch64? > ..but i still don't understand how the GOT entries > of the startup code get initialized in PIE executable > at runtime. You just avoid GOT entries in start.S for static PIE by using PC relative relocations.
On 02/10/17 12:20, H.J. Lu wrote: > On 10/2/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >> On 29/09/17 22:32, H.J. Lu wrote: >>> Since start.o may be compiled as PIC, we should check PIC instead of >>> SHARED. >>> >>> OK for master? >>> >> >> i believe that the compile/link tests worked.. > > Does static PIE of hjl/pie/static branch run on arm and aarch64? > no, if i build with --enable-static-pie the install step fails when the static linked sln runs. there are relative relocs against the func ptrs that are loaded from GOT in the startup code, but execution fails even before those are used because there are R*_JUMP_SLOT and R*_GLOB_DAT relocs which are not processed correctly. in particular in if (__pthread_initialize_minimal != NULL) __pthread_initialize_minimal (); the symbol value loaded from GOT is non-NULL even though there is no pthread linked in, that is probably a linker bug. >> ..but i still don't understand how the GOT entries >> of the startup code get initialized in PIE executable >> at runtime. > > You just avoid GOT entries in start.S for static PIE by using > PC relative relocations. > i don't see how can you do that when you have to pass absolute addresses as arguments to __libc_start_main and the base address is not yet computed.
On 10/3/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: > On 02/10/17 12:20, H.J. Lu wrote: >> On 10/2/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >>> On 29/09/17 22:32, H.J. Lu wrote: >>>> Since start.o may be compiled as PIC, we should check PIC instead of >>>> SHARED. >>>> >>>> OK for master? >>>> >>> >>> i believe that the compile/link tests worked.. >> >> Does static PIE of hjl/pie/static branch run on arm and aarch64? >> > > no, if i build with --enable-static-pie the install step > fails when the static linked sln runs. > > there are relative relocs against the func ptrs that are > loaded from GOT in the startup code, but execution fails > even before those are used because there are R*_JUMP_SLOT > and R*_GLOB_DAT relocs which are not processed correctly. > > in particular in > if (__pthread_initialize_minimal != NULL) > __pthread_initialize_minimal (); > the symbol value loaded from GOT is non-NULL even though > there is no pthread linked in, that is probably a linker bug. > >>> ..but i still don't understand how the GOT entries >>> of the startup code get initialized in PIE executable >>> at runtime. >> >> You just avoid GOT entries in start.S for static PIE by using >> PC relative relocations. >> > > i don't see how can you do that when you have to pass > absolute addresses as arguments to __libc_start_main > and the base address is not yet computed. Does ARM support PC relative relocation for local function address? All functions are local in static PIE. In i386/start.S, there are /* Load PIC register. */ call 1f addl $_GLOBAL_OFFSET_TABLE_, %ebx /* Push address of our own entry points to .fini and .init. */ leal __libc_csu_fini@GOTOFF(%ebx), %eax pushl %eax leal __libc_csu_init@GOTOFF(%ebx), %eax pushl %eax pushl %ecx /* Push second argument: argv. */ pushl %esi /* Push first argument: argc. */ # ifdef SHARED pushl main@GOT(%ebx) # else /* Avoid relocation in static PIE since _start is called before it is relocated. */ leal main@GOTOFF(%ebx), %eax pushl %eax # endif GOTOFF can be resolved by linker to avoid dynamic relocations. [hjl@gnu-efi-2 gcc]$ cat x.c extern void foo (void) __attribute__ ((visibility("hidden"))); extern void bar (void*); void xxx (void) { bar (foo); } [hjl@gnu-efi-2 gcc]$ cat x.s .arch armv8-a .file "x.c" .text .align 2 .align 3 .global xxx .type xxx, %function xxx: adrp x0, foo add x0, x0, :lo12:foo b bar .size xxx, .-xxx .hidden foo .ident "GCC: (GNU) 8.0.0 20171002 (experimental)" .section .note.GNU-stack,"",@progbits [hjl@gnu-efi-2 gcc]$ Does this need GOT?
On 03/10/17 11:52, H.J. Lu wrote: > On 10/3/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >> On 02/10/17 12:20, H.J. Lu wrote: >>> On 10/2/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >>>> On 29/09/17 22:32, H.J. Lu wrote: >>>>> Since start.o may be compiled as PIC, we should check PIC instead of >>>>> SHARED. >>>>> >>>>> OK for master? >>>>> >>>> >>>> i believe that the compile/link tests worked.. >>> >>> Does static PIE of hjl/pie/static branch run on arm and aarch64? >>> >> >> no, if i build with --enable-static-pie the install step >> fails when the static linked sln runs. >> >> there are relative relocs against the func ptrs that are >> loaded from GOT in the startup code, but execution fails >> even before those are used because there are R*_JUMP_SLOT >> and R*_GLOB_DAT relocs which are not processed correctly. >> >> in particular in >> if (__pthread_initialize_minimal != NULL) >> __pthread_initialize_minimal (); >> the symbol value loaded from GOT is non-NULL even though >> there is no pthread linked in, that is probably a linker bug. >> >>>> ..but i still don't understand how the GOT entries >>>> of the startup code get initialized in PIE executable >>>> at runtime. >>> >>> You just avoid GOT entries in start.S for static PIE by using >>> PC relative relocations. >>> >> >> i don't see how can you do that when you have to pass >> absolute addresses as arguments to __libc_start_main >> and the base address is not yet computed. > > Does ARM support PC relative relocation for local function address? > All functions are local in static PIE. In i386/start.S, there are > > /* Load PIC register. */ > call 1f > addl $_GLOBAL_OFFSET_TABLE_, %ebx > > /* Push address of our own entry points to .fini and .init. */ > leal __libc_csu_fini@GOTOFF(%ebx), %eax > pushl %eax > leal __libc_csu_init@GOTOFF(%ebx), %eax > pushl %eax > > pushl %ecx /* Push second argument: argv. */ > pushl %esi /* Push first argument: argc. */ > > # ifdef SHARED > pushl main@GOT(%ebx) > # else > /* Avoid relocation in static PIE since _start is called before > it is relocated. */ > leal main@GOTOFF(%ebx), %eax > pushl %eax > # endif > > GOTOFF can be resolved by linker to avoid dynamic relocations. > > [hjl@gnu-efi-2 gcc]$ cat x.c > extern void foo (void) __attribute__ ((visibility("hidden"))); > extern void bar (void*); > > void > xxx (void) > { > bar (foo); > } > [hjl@gnu-efi-2 gcc]$ cat x.s > .arch armv8-a > .file "x.c" > .text > .align 2 > .align 3 > .global xxx > .type xxx, %function > xxx: > adrp x0, foo > add x0, x0, :lo12:foo > b bar > .size xxx, .-xxx > .hidden foo > .ident "GCC: (GNU) 8.0.0 20171002 (experimental)" > .section .note.GNU-stack,"",@progbits > [hjl@gnu-efi-2 gcc]$ > > Does this need GOT? > ok, this works (for binaries < 4G), but i assumed the symbols can come from external module (in case of non-static linking) and thus crt1.o will need GOT entries anyway, but now i see that all of __libc_csu_init, __libc_csu_fini and main will be in the same module as crt1.o i can update start.S, but i wonder if there might be code where main is not in the executable for some reason, but comes from a shared lib.
On 10/3/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: > On 03/10/17 11:52, H.J. Lu wrote: >> On 10/3/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >>> On 02/10/17 12:20, H.J. Lu wrote: >>>> On 10/2/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >>>>> On 29/09/17 22:32, H.J. Lu wrote: >>>>>> Since start.o may be compiled as PIC, we should check PIC instead of >>>>>> SHARED. >>>>>> >>>>>> OK for master? >>>>>> >>>>> >>>>> i believe that the compile/link tests worked.. >>>> >>>> Does static PIE of hjl/pie/static branch run on arm and aarch64? >>>> >>> >>> no, if i build with --enable-static-pie the install step >>> fails when the static linked sln runs. >>> >>> there are relative relocs against the func ptrs that are >>> loaded from GOT in the startup code, but execution fails >>> even before those are used because there are R*_JUMP_SLOT >>> and R*_GLOB_DAT relocs which are not processed correctly. >>> >>> in particular in >>> if (__pthread_initialize_minimal != NULL) >>> __pthread_initialize_minimal (); >>> the symbol value loaded from GOT is non-NULL even though >>> there is no pthread linked in, that is probably a linker bug. >>> >>>>> ..but i still don't understand how the GOT entries >>>>> of the startup code get initialized in PIE executable >>>>> at runtime. >>>> >>>> You just avoid GOT entries in start.S for static PIE by using >>>> PC relative relocations. >>>> >>> >>> i don't see how can you do that when you have to pass >>> absolute addresses as arguments to __libc_start_main >>> and the base address is not yet computed. >> >> Does ARM support PC relative relocation for local function address? >> All functions are local in static PIE. In i386/start.S, there are >> >> /* Load PIC register. */ >> call 1f >> addl $_GLOBAL_OFFSET_TABLE_, %ebx >> >> /* Push address of our own entry points to .fini and .init. */ >> leal __libc_csu_fini@GOTOFF(%ebx), %eax >> pushl %eax >> leal __libc_csu_init@GOTOFF(%ebx), %eax >> pushl %eax >> >> pushl %ecx /* Push second argument: argv. */ >> pushl %esi /* Push first argument: argc. */ >> >> # ifdef SHARED >> pushl main@GOT(%ebx) >> # else >> /* Avoid relocation in static PIE since _start is called before >> it is relocated. */ >> leal main@GOTOFF(%ebx), %eax >> pushl %eax >> # endif >> >> GOTOFF can be resolved by linker to avoid dynamic relocations. >> >> [hjl@gnu-efi-2 gcc]$ cat x.c >> extern void foo (void) __attribute__ ((visibility("hidden"))); >> extern void bar (void*); >> >> void >> xxx (void) >> { >> bar (foo); >> } >> [hjl@gnu-efi-2 gcc]$ cat x.s >> .arch armv8-a >> .file "x.c" >> .text >> .align 2 >> .align 3 >> .global xxx >> .type xxx, %function >> xxx: >> adrp x0, foo >> add x0, x0, :lo12:foo >> b bar >> .size xxx, .-xxx >> .hidden foo >> .ident "GCC: (GNU) 8.0.0 20171002 (experimental)" >> .section .note.GNU-stack,"",@progbits >> [hjl@gnu-efi-2 gcc]$ >> >> Does this need GOT? >> > > ok, this works (for binaries < 4G), but i assumed the symbols > can come from external module (in case of non-static linking) > and thus crt1.o will need GOT entries anyway, but now i see > that all of __libc_csu_init, __libc_csu_fini and main will > be in the same module as crt1.o > > i can update start.S, but i wonder if there might be code > where main is not in the executable for some reason, but > comes from a shared lib. > That won't happen with static PIE :-).
On 03/10/17 13:00, H.J. Lu wrote: > On 10/3/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >> ok, this works (for binaries < 4G), but i assumed the symbols >> can come from external module (in case of non-static linking) >> and thus crt1.o will need GOT entries anyway, but now i see >> that all of __libc_csu_init, __libc_csu_fini and main will >> be in the same module as crt1.o >> >> i can update start.S, but i wonder if there might be code >> where main is not in the executable for some reason, but >> comes from a shared lib. >> > > That won't happen with static PIE :-). > yes but now crt1.o is used for both static and non-static linking and if i change start.S it will observably change abi for the non-static case (i think it probably does not matter in practice, but somebody might think otherwise).
On 10/3/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: > On 03/10/17 13:00, H.J. Lu wrote: >> On 10/3/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >>> ok, this works (for binaries < 4G), but i assumed the symbols >>> can come from external module (in case of non-static linking) >>> and thus crt1.o will need GOT entries anyway, but now i see >>> that all of __libc_csu_init, __libc_csu_fini and main will >>> be in the same module as crt1.o >>> >>> i can update start.S, but i wonder if there might be code >>> where main is not in the executable for some reason, but >>> comes from a shared lib. >>> >> >> That won't happen with static PIE :-). >> > > yes but now crt1.o is used for both static and non-static > linking and if i change start.S it will observably change > abi for the non-static case (i think it probably does not > matter in practice, but somebody might think otherwise). > Can you modify your start.S with #if defined PIC && !defined SHARED pass local_main to __libc_start_main local_main: tail call to main via PLT
On 03/10/17 15:31, H.J. Lu wrote: > On 10/3/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >> On 03/10/17 13:00, H.J. Lu wrote: >>> On 10/3/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >>>> ok, this works (for binaries < 4G), but i assumed the symbols >>>> can come from external module (in case of non-static linking) >>>> and thus crt1.o will need GOT entries anyway, but now i see >>>> that all of __libc_csu_init, __libc_csu_fini and main will >>>> be in the same module as crt1.o >>>> >>>> i can update start.S, but i wonder if there might be code >>>> where main is not in the executable for some reason, but >>>> comes from a shared lib. >>>> >>> >>> That won't happen with static PIE :-). >>> >> >> yes but now crt1.o is used for both static and non-static >> linking and if i change start.S it will observably change >> abi for the non-static case (i think it probably does not >> matter in practice, but somebody might think otherwise). >> > > Can you modify your start.S with > > #if defined PIC && !defined SHARED > > pass local_main to __libc_start_main > > local_main: > tail call to main via PLT > good, so this problem can be solved too (i'm not sure if it is worth solving though)
On 03/10/17 11:39, Szabolcs Nagy wrote: > On 02/10/17 12:20, H.J. Lu wrote: >> On 10/2/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >>> On 29/09/17 22:32, H.J. Lu wrote: >>>> Since start.o may be compiled as PIC, we should check PIC instead of >>>> SHARED. >>>> >>>> OK for master? >>>> >>> >>> i believe that the compile/link tests worked.. >> >> Does static PIE of hjl/pie/static branch run on arm and aarch64? >> > > no, if i build with --enable-static-pie the install step > fails when the static linked sln runs. > > there are relative relocs against the func ptrs that are > loaded from GOT in the startup code, but execution fails > even before those are used because there are R*_JUMP_SLOT > and R*_GLOB_DAT relocs which are not processed correctly. > > in particular in > if (__pthread_initialize_minimal != NULL) > __pthread_initialize_minimal (); > the symbol value loaded from GOT is non-NULL even though > there is no pthread linked in, that is probably a linker bug. > it seems weak extern symbol is accessed via got and at link time that is not relaxed to 0 with -static -pie and the got entry is not initialized to 0 either. as far as i can see the startup code and weak symbols are the remaining issues on aarch64 for static pie.
On 10/3/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: > On 03/10/17 11:39, Szabolcs Nagy wrote: >> On 02/10/17 12:20, H.J. Lu wrote: >>> On 10/2/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >>>> On 29/09/17 22:32, H.J. Lu wrote: >>>>> Since start.o may be compiled as PIC, we should check PIC instead of >>>>> SHARED. >>>>> >>>>> OK for master? >>>>> >>>> >>>> i believe that the compile/link tests worked.. >>> >>> Does static PIE of hjl/pie/static branch run on arm and aarch64? >>> >> >> no, if i build with --enable-static-pie the install step >> fails when the static linked sln runs. >> >> there are relative relocs against the func ptrs that are >> loaded from GOT in the startup code, but execution fails >> even before those are used because there are R*_JUMP_SLOT >> and R*_GLOB_DAT relocs which are not processed correctly. >> >> in particular in >> if (__pthread_initialize_minimal != NULL) >> __pthread_initialize_minimal (); >> the symbol value loaded from GOT is non-NULL even though >> there is no pthread linked in, that is probably a linker bug. >> > > it seems weak extern symbol is accessed via got and at > link time that is not relaxed to 0 with -static -pie > and the got entry is not initialized to 0 either. Please try the current hjl/pie/static branch. I added Pcrt1.o to to create static PIE. There is no weak extern symbol anymore. As long as there is no dynamic relocation before _dl_relocate_static_pie relocates static PIE, it should work. > as far as i can see the startup code and weak symbols > are the remaining issues on aarch64 for static pie. > >
On 03/10/17 16:31, Szabolcs Nagy wrote: > On 03/10/17 11:39, Szabolcs Nagy wrote: >> On 02/10/17 12:20, H.J. Lu wrote: >>> On 10/2/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >>>> On 29/09/17 22:32, H.J. Lu wrote: >>>>> Since start.o may be compiled as PIC, we should check PIC instead of >>>>> SHARED. >>>>> >>>>> OK for master? >>>>> >>>> >>>> i believe that the compile/link tests worked.. >>> >>> Does static PIE of hjl/pie/static branch run on arm and aarch64? >>> >> >> no, if i build with --enable-static-pie the install step >> fails when the static linked sln runs. >> >> there are relative relocs against the func ptrs that are >> loaded from GOT in the startup code, but execution fails >> even before those are used because there are R*_JUMP_SLOT >> and R*_GLOB_DAT relocs which are not processed correctly. >> >> in particular in >> if (__pthread_initialize_minimal != NULL) >> __pthread_initialize_minimal (); >> the symbol value loaded from GOT is non-NULL even though >> there is no pthread linked in, that is probably a linker bug. >> > > it seems weak extern symbol is accessed via got and at > link time that is not relaxed to 0 with -static -pie > and the got entry is not initialized to 0 either. aarch64 dl-machine.h has struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ElfW(Addr) value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value; x86_64 has struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); ElfW(Addr) value = (sym == NULL ? 0 : (ElfW(Addr)) sym_map->l_addr + sym->st_value); sym_map is always == BOOTSTRAP_MAP in case of static pie, so tye sym_map == NULL check is not true on aarch64 case for weak undef symbols. so either targets need to be fixed to not use sym_map check for detecting undef weak (powerpc32, powerpc64, aarch64, i386, arm, sh, sparc32, sparc64) or RESOLVE_MAP should not be unconditionally set to BOOTSTRAP_MAP in _dl_relocate_static_pie (since that is not true for undef symbols)
On 04/10/17 10:05, H.J. Lu wrote: > On 10/3/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >> >> it seems weak extern symbol is accessed via got and at >> link time that is not relaxed to 0 with -static -pie >> and the got entry is not initialized to 0 either. > > Please try the current hjl/pie/static branch. I added Pcrt1.o to > to create static PIE. There is no weak extern symbol anymore. > As long as there is no dynamic relocation before > _dl_relocate_static_pie relocates static PIE, it should work. > i still get weak undefined symbols (pthread stuff when linking without -lpthread) how Pcrt1.o is supposed to work? it seems it is built the same way as crt1.o? (i'd expect Pcrt1 to mean "static pie link with pie libc.a", and crt1.o to mean "link executable that will be relocated by a dynamic linker")
On 10/6/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: > On 04/10/17 10:05, H.J. Lu wrote: >> On 10/3/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >>> >>> it seems weak extern symbol is accessed via got and at >>> link time that is not relaxed to 0 with -static -pie >>> and the got entry is not initialized to 0 either. >> >> Please try the current hjl/pie/static branch. I added Pcrt1.o to >> to create static PIE. There is no weak extern symbol anymore. >> As long as there is no dynamic relocation before >> _dl_relocate_static_pie relocates static PIE, it should work. >> > > i still get weak undefined symbols (pthread stuff when linking > without -lpthread) All weak undefined symbols in static executable should be resolved to zero at link-time, PIE nor non-PIE. See /* Is a undefined weak symbol which is resolved to 0. Reference to an undefined weak symbol is resolved to 0 when building executable if it isn't dynamic and 1. Has non-GOT/non-PLT relocations in text section. Or 2. Has no GOT/PLT relocation. Local undefined weak symbol is always resolved to 0. */ #define UNDEFINED_WEAK_RESOLVED_TO_ZERO(INFO, EH) \ ((EH)->elf.root.type == bfd_link_hash_undefweak \ && (SYMBOL_REFERENCES_LOCAL_P ((INFO), &(EH)->elf) \ || (bfd_link_executable (INFO) \ && (!(EH)->has_got_reloc \ || (EH)->has_non_got_reloc)))) in elfxx-x86.h. Also see: https://sourceware.org/bugzilla/show_bug.cgi?id=19636 > how Pcrt1.o is supposed to work? it seems it is built the same > way as crt1.o? (i'd expect Pcrt1 to mean "static pie link with > pie libc.a", and crt1.o to mean "link executable that will be > relocated by a dynamic linker") That is correct: [hjl@gnu-efi-2 glibc]$ readelf -sW csu/Pcrt1.o | grep _dl_relocate_static_pie [hjl@gnu-efi-2 glibc]$ readelf -sW csu/crt1.o | grep _dl_relocate_static_pie 24: 0000000000000038 4 FUNC GLOBAL HIDDEN 2 _dl_relocate_static_pie [hjl@gnu-efi-2 glibc]$ When Pcrt1.o is used, the real _dl_relocate_static_pie in libc.a will be used for static PIE. Otherwise, you will get a dummy _dl_relocate_static_pie in crt1.o for non-PIE static and dynamic executables.
On 10/6/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: > On 03/10/17 16:31, Szabolcs Nagy wrote: >> On 03/10/17 11:39, Szabolcs Nagy wrote: >>> On 02/10/17 12:20, H.J. Lu wrote: >>>> On 10/2/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >>>>> On 29/09/17 22:32, H.J. Lu wrote: >>>>>> Since start.o may be compiled as PIC, we should check PIC instead of >>>>>> SHARED. >>>>>> >>>>>> OK for master? >>>>>> >>>>> >>>>> i believe that the compile/link tests worked.. >>>> >>>> Does static PIE of hjl/pie/static branch run on arm and aarch64? >>>> >>> >>> no, if i build with --enable-static-pie the install step >>> fails when the static linked sln runs. >>> >>> there are relative relocs against the func ptrs that are >>> loaded from GOT in the startup code, but execution fails >>> even before those are used because there are R*_JUMP_SLOT >>> and R*_GLOB_DAT relocs which are not processed correctly. >>> >>> in particular in >>> if (__pthread_initialize_minimal != NULL) >>> __pthread_initialize_minimal (); >>> the symbol value loaded from GOT is non-NULL even though >>> there is no pthread linked in, that is probably a linker bug. >>> >> >> it seems weak extern symbol is accessed via got and at >> link time that is not relaxed to 0 with -static -pie >> and the got entry is not initialized to 0 either. > > aarch64 dl-machine.h has > > struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); > ElfW(Addr) value = sym_map == NULL ? 0 : sym_map->l_addr + > sym->st_value; > > x86_64 has > > struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); > ElfW(Addr) value = (sym == NULL ? 0 > : (ElfW(Addr)) sym_map->l_addr + sym->st_value); > > sym_map is always == BOOTSTRAP_MAP in case of static pie, so > tye sym_map == NULL check is not true on aarch64 case for weak > undef symbols. > > so either targets need to be fixed to not use sym_map check > for detecting undef weak (powerpc32, powerpc64, aarch64, > i386, arm, sh, sparc32, sparc64) or RESOLVE_MAP should not > be unconditionally set to BOOTSTRAP_MAP in _dl_relocate_static_pie > (since that is not true for undef symbols) > It shouldn't matter. All undefined weak symbols should be resolved to 0 in static PIE by linker. See: https://sourceware.org/bugzilla/show_bug.cgi?id=22269
On 06/10/17 13:34, H.J. Lu wrote: > On 10/6/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >> On 03/10/17 16:31, Szabolcs Nagy wrote: >>> On 03/10/17 11:39, Szabolcs Nagy wrote: >>>> On 02/10/17 12:20, H.J. Lu wrote: >>>>> On 10/2/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >>>>>> On 29/09/17 22:32, H.J. Lu wrote: >>>>>>> Since start.o may be compiled as PIC, we should check PIC instead of >>>>>>> SHARED. >>>>>>> >>>>>>> OK for master? >>>>>>> >>>>>> >>>>>> i believe that the compile/link tests worked.. >>>>> >>>>> Does static PIE of hjl/pie/static branch run on arm and aarch64? >>>>> >>>> >>>> no, if i build with --enable-static-pie the install step >>>> fails when the static linked sln runs. >>>> >>>> there are relative relocs against the func ptrs that are >>>> loaded from GOT in the startup code, but execution fails >>>> even before those are used because there are R*_JUMP_SLOT >>>> and R*_GLOB_DAT relocs which are not processed correctly. >>>> >>>> in particular in >>>> if (__pthread_initialize_minimal != NULL) >>>> __pthread_initialize_minimal (); >>>> the symbol value loaded from GOT is non-NULL even though >>>> there is no pthread linked in, that is probably a linker bug. >>>> >>> >>> it seems weak extern symbol is accessed via got and at >>> link time that is not relaxed to 0 with -static -pie >>> and the got entry is not initialized to 0 either. >> >> aarch64 dl-machine.h has >> >> struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); >> ElfW(Addr) value = sym_map == NULL ? 0 : sym_map->l_addr + >> sym->st_value; >> >> x86_64 has >> >> struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); >> ElfW(Addr) value = (sym == NULL ? 0 >> : (ElfW(Addr)) sym_map->l_addr + sym->st_value); >> >> sym_map is always == BOOTSTRAP_MAP in case of static pie, so >> tye sym_map == NULL check is not true on aarch64 case for weak >> undef symbols. >> >> so either targets need to be fixed to not use sym_map check >> for detecting undef weak (powerpc32, powerpc64, aarch64, >> i386, arm, sh, sparc32, sparc64) or RESOLVE_MAP should not >> be unconditionally set to BOOTSTRAP_MAP in _dl_relocate_static_pie >> (since that is not true for undef symbols) >> > > It shouldn't matter. All undefined weak symbols should be resolved > to 0 in static PIE by linker. See: > > https://sourceware.org/bugzilla/show_bug.cgi?id=22269 > ok, thanks for the bug report, but i prefer to also fix the dynamic linker to try set abs/got/jumpslot relocs for weak undef syms to 0, so it can work with earlier binutils.
On 10/6/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: > On 06/10/17 13:34, H.J. Lu wrote: >> On 10/6/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >>> On 03/10/17 16:31, Szabolcs Nagy wrote: >>>> On 03/10/17 11:39, Szabolcs Nagy wrote: >>>>> On 02/10/17 12:20, H.J. Lu wrote: >>>>>> On 10/2/17, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: >>>>>>> On 29/09/17 22:32, H.J. Lu wrote: >>>>>>>> Since start.o may be compiled as PIC, we should check PIC instead >>>>>>>> of >>>>>>>> SHARED. >>>>>>>> >>>>>>>> OK for master? >>>>>>>> >>>>>>> >>>>>>> i believe that the compile/link tests worked.. >>>>>> >>>>>> Does static PIE of hjl/pie/static branch run on arm and aarch64? >>>>>> >>>>> >>>>> no, if i build with --enable-static-pie the install step >>>>> fails when the static linked sln runs. >>>>> >>>>> there are relative relocs against the func ptrs that are >>>>> loaded from GOT in the startup code, but execution fails >>>>> even before those are used because there are R*_JUMP_SLOT >>>>> and R*_GLOB_DAT relocs which are not processed correctly. >>>>> >>>>> in particular in >>>>> if (__pthread_initialize_minimal != NULL) >>>>> __pthread_initialize_minimal (); >>>>> the symbol value loaded from GOT is non-NULL even though >>>>> there is no pthread linked in, that is probably a linker bug. >>>>> >>>> >>>> it seems weak extern symbol is accessed via got and at >>>> link time that is not relaxed to 0 with -static -pie >>>> and the got entry is not initialized to 0 either. >>> >>> aarch64 dl-machine.h has >>> >>> struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); >>> ElfW(Addr) value = sym_map == NULL ? 0 : sym_map->l_addr + >>> sym->st_value; >>> >>> x86_64 has >>> >>> struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); >>> ElfW(Addr) value = (sym == NULL ? 0 >>> : (ElfW(Addr)) sym_map->l_addr + sym->st_value); >>> >>> sym_map is always == BOOTSTRAP_MAP in case of static pie, so >>> tye sym_map == NULL check is not true on aarch64 case for weak >>> undef symbols. >>> >>> so either targets need to be fixed to not use sym_map check >>> for detecting undef weak (powerpc32, powerpc64, aarch64, >>> i386, arm, sh, sparc32, sparc64) or RESOLVE_MAP should not >>> be unconditionally set to BOOTSTRAP_MAP in _dl_relocate_static_pie >>> (since that is not true for undef symbols) >>> >> >> It shouldn't matter. All undefined weak symbols should be resolved >> to 0 in static PIE by linker. See: >> >> https://sourceware.org/bugzilla/show_bug.cgi?id=22269 >> > > ok, thanks for the bug report, but i prefer to also > fix the dynamic linker to try set abs/got/jumpslot Sure. > relocs for weak undef syms to 0, so it can work with > earlier binutils. > > Please try binutils users/hjl/pr22269 branch. aarch64 may need to check UNDEFINED_WEAK_RESOLVED_TO_ZERO in more places.
diff --git a/sysdeps/aarch64/start.S b/sysdeps/aarch64/start.S index c20433ad73..7a946506f2 100644 --- a/sysdeps/aarch64/start.S +++ b/sysdeps/aarch64/start.S @@ -60,7 +60,7 @@ _start: /* Setup stack limit in argument register */ mov x6, sp -#ifdef SHARED +#ifdef PIC adrp x0, :got:main ldr PTR_REG (0), [x0, #:got_lo12:main]