Message ID | 554D276D.9040205@mentor.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Nathan, On 8 May 2015 at 23:15, Nathan Lynch <Nathan_Lynch@mentor.com> wrote: > On 05/08/2015 11:08 AM, Stefan Agner wrote: >> On 2015-05-08 17:27, Nathan Lynch wrote: >>> On 05/08/2015 06:13 AM, Stefan Agner wrote: >>>> Also, I used the BFD linker by adding LD=${CROSS_COMPILE}ld.bfd to the >>>> build command. Interestingly thought, I had the same issue when using >>>> gold linker... >>> >>> When I try this, ld.gold is used regardless. >>> >>> You can tell by doing and checking for a NT_GNU_GOLD_VERSION note: >>> >>> $ readelf -n arch/arm/vdso/vdso.so.raw >>> >>> Displaying notes found at file offset 0x000001bc with length 0x00000040: >>> Owner Data size Description >>> GNU 0x00000009 NT_GNU_GOLD_VERSION (gold version) >>> GNU 0x00000014 NT_GNU_BUILD_ID (unique build >>> ID bitstring) >>> Build ID: f025409550acb7f955c61d95691291da078e6688 >> >> Hm, you are right. When deleting moving ld.bfd to ld, which makes the >> BFD linker as default, compiling works flawless. >> >> However, so far LD=${CROSS_COMPILE}ld.bfc seems to work for other build >> objects, at least those do not have this note. For instance time.o does >> not return anything: >> >> $ readelf -n arch/arm/kernel/time.o > > This is just an object file that hasn't been linked, but your general > point stands -- LD is honored by other parts of the build. > > I suppose this implies that the build only chokes on --pic-veneer when linking the VDSO, and nowhere else? >> So it seems to be a vdso.so.raw specific problem not using the specified >> linker...? > > Yes, since it's produced by an invocation of $(CC) which is expected > to call the linker implicitly, and this is how the toolchain's default > linker ends up getting used even when you set LD on the command line. > > If I'm not mistaken, implicitly performing a link through the compiler > seems to be 1) conventional for all VDSOs, not just ARM's, but 2) unusual > for other parts of the kernel build. > > I suppose it's possible to make arch/arm/vdso/Makefile honor LD, but it > would basically entail a rewrite. In the meantime, using -fuse-ld=bfd > may suffice: > > diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile > index 8aa791051029..da0ce897edde 100644 > --- a/arch/arm/vdso/Makefile > +++ b/arch/arm/vdso/Makefile > @@ -43,6 +43,7 @@ quiet_cmd_vdsold = VDSO $@ > cmd_vdsold = $(CC) $(c_flags) -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) \ > $(call cc-ldoption, -Wl$(comma)--build-id) \ > -Wl,-Bsymbolic -Wl,-z,max-page-size=4096 \ > + $(call cc-option, -fuse-ld=bfd) \ > -Wl,-z,common-page-size=4096 -o $@ > > quiet_cmd_vdsomunge = MUNGE $@ > > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Fri, May 08, 2015 at 04:15:25PM -0500, Nathan Lynch wrote: > I suppose it's possible to make arch/arm/vdso/Makefile honor LD, but it > would basically entail a rewrite. In the meantime, using -fuse-ld=bfd > may suffice: > > diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile > index 8aa791051029..da0ce897edde 100644 > --- a/arch/arm/vdso/Makefile > +++ b/arch/arm/vdso/Makefile > @@ -43,6 +43,7 @@ quiet_cmd_vdsold = VDSO $@ > cmd_vdsold = $(CC) $(c_flags) -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) \ > $(call cc-ldoption, -Wl$(comma)--build-id) \ > -Wl,-Bsymbolic -Wl,-z,max-page-size=4096 \ > + $(call cc-option, -fuse-ld=bfd) \ > -Wl,-z,common-page-size=4096 -o $@ Would it make more sense to have something like: VDSO_LDFLAGS := -Wl,-Bsymbolic -Wl,-z,max-page-size=4096 \ -Wl,-z,common-page-size=4096 \ $(call cc-ldoption, -Wl$(comma)--build-id) \ $(call cc-option, -fuse-ld=bfd) and then have: cmd_vdsold = $(CC) $(c_flags) $(VDSO_LDFLAGS) \ -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@ Also, do we want to use cc-option or cc-ldoption (this question becomes obvious when you arrange the Makefile as I have above...)? cc-option doesn't result in the linker actually being run, where as cc-ldoption does.
On 2015-05-08 23:15, Nathan Lynch wrote: > On 05/08/2015 11:08 AM, Stefan Agner wrote: >> On 2015-05-08 17:27, Nathan Lynch wrote: >>> On 05/08/2015 06:13 AM, Stefan Agner wrote: >>>> Also, I used the BFD linker by adding LD=${CROSS_COMPILE}ld.bfd to the >>>> build command. Interestingly thought, I had the same issue when using >>>> gold linker... >>> >>> When I try this, ld.gold is used regardless. >>> >>> You can tell by doing and checking for a NT_GNU_GOLD_VERSION note: >>> >>> $ readelf -n arch/arm/vdso/vdso.so.raw >>> >>> Displaying notes found at file offset 0x000001bc with length 0x00000040: >>> Owner Data size Description >>> GNU 0x00000009 NT_GNU_GOLD_VERSION (gold version) >>> GNU 0x00000014 NT_GNU_BUILD_ID (unique build >>> ID bitstring) >>> Build ID: f025409550acb7f955c61d95691291da078e6688 >> >> Hm, you are right. When deleting moving ld.bfd to ld, which makes the >> BFD linker as default, compiling works flawless. >> >> However, so far LD=${CROSS_COMPILE}ld.bfc seems to work for other build >> objects, at least those do not have this note. For instance time.o does >> not return anything: >> >> $ readelf -n arch/arm/kernel/time.o > > This is just an object file that hasn't been linked, but your general > point stands -- LD is honored by other parts of the build. > > >> So it seems to be a vdso.so.raw specific problem not using the specified >> linker...? > > Yes, since it's produced by an invocation of $(CC) which is expected > to call the linker implicitly, and this is how the toolchain's default > linker ends up getting used even when you set LD on the command line. > > If I'm not mistaken, implicitly performing a link through the compiler > seems to be 1) conventional for all VDSOs, not just ARM's, but 2) unusual > for other parts of the kernel build. > > I suppose it's possible to make arch/arm/vdso/Makefile honor LD, but it > would basically entail a rewrite. In the meantime, using -fuse-ld=bfd > may suffice: > > diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile > index 8aa791051029..da0ce897edde 100644 > --- a/arch/arm/vdso/Makefile > +++ b/arch/arm/vdso/Makefile > @@ -43,6 +43,7 @@ quiet_cmd_vdsold = VDSO $@ > cmd_vdsold = $(CC) $(c_flags) -Wl,-T $(filter %.lds,$^) > $(filter %.o,$^) \ > $(call cc-ldoption, -Wl$(comma)--build-id) \ > -Wl,-Bsymbolic -Wl,-z,max-page-size=4096 \ > + $(call cc-option, -fuse-ld=bfd) \ > -Wl,-z,common-page-size=4096 -o $@ > > quiet_cmd_vdsomunge = MUNGE $@ Thanks Nathan, your solution looks reasonable. I figured that the option is available since GCC 4.8, so it should work probably for most toolchains which try to make use of gold linker as default. Unfortunately, I hit another problem with the configuration on my build host. With your patch applied, I get: collect2: fatal error: cannot find 'ld' compilation terminated. make[2]: *** [arch/arm/vdso/vdso.so.raw] Error 1 make[1]: *** [arch/arm/vdso] Error 2 make[1]: *** Waiting for unfinished jobs.... OpenEmbedded distinguish between three toolchains for the target: - Native (on the target) - Host (on the host which builds the whole image, usually x86_64) - SDK (on a third architecture for application development, usually x86 or x86_64, the toolchain which I published the link to) I use x86_64 as host and SDK architecture, nevertheless it seems that the toolchains are configured differently. The Host toolchain (the one which shows the error above) uses "--enable-gold=default" when configuring binutils. With that option, ld.bfd is still being built, but ld is by default gold, without any additional doing (cp/ln -f..). Currently it seems to me that this difference triggers a problem with -fuse-ld=bfd. However, I don't think that this problem invalidates your proposed solution. -- Stefan
On 2015-05-09 14:41, Stefan Agner wrote: > On 2015-05-08 23:15, Nathan Lynch wrote: >> On 05/08/2015 11:08 AM, Stefan Agner wrote: >>> On 2015-05-08 17:27, Nathan Lynch wrote: >>>> On 05/08/2015 06:13 AM, Stefan Agner wrote: >>>>> Also, I used the BFD linker by adding LD=${CROSS_COMPILE}ld.bfd to the >>>>> build command. Interestingly thought, I had the same issue when using >>>>> gold linker... >>>> >>>> When I try this, ld.gold is used regardless. >>>> >>>> You can tell by doing and checking for a NT_GNU_GOLD_VERSION note: >>>> >>>> $ readelf -n arch/arm/vdso/vdso.so.raw >>>> >>>> Displaying notes found at file offset 0x000001bc with length 0x00000040: >>>> Owner Data size Description >>>> GNU 0x00000009 NT_GNU_GOLD_VERSION (gold version) >>>> GNU 0x00000014 NT_GNU_BUILD_ID (unique build >>>> ID bitstring) >>>> Build ID: f025409550acb7f955c61d95691291da078e6688 >>> >>> Hm, you are right. When deleting moving ld.bfd to ld, which makes the >>> BFD linker as default, compiling works flawless. >>> >>> However, so far LD=${CROSS_COMPILE}ld.bfc seems to work for other build >>> objects, at least those do not have this note. For instance time.o does >>> not return anything: >>> >>> $ readelf -n arch/arm/kernel/time.o >> >> This is just an object file that hasn't been linked, but your general >> point stands -- LD is honored by other parts of the build. >> >> >>> So it seems to be a vdso.so.raw specific problem not using the specified >>> linker...? >> >> Yes, since it's produced by an invocation of $(CC) which is expected >> to call the linker implicitly, and this is how the toolchain's default >> linker ends up getting used even when you set LD on the command line. >> >> If I'm not mistaken, implicitly performing a link through the compiler >> seems to be 1) conventional for all VDSOs, not just ARM's, but 2) unusual >> for other parts of the kernel build. >> >> I suppose it's possible to make arch/arm/vdso/Makefile honor LD, but it >> would basically entail a rewrite. In the meantime, using -fuse-ld=bfd >> may suffice: >> >> diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile >> index 8aa791051029..da0ce897edde 100644 >> --- a/arch/arm/vdso/Makefile >> +++ b/arch/arm/vdso/Makefile >> @@ -43,6 +43,7 @@ quiet_cmd_vdsold = VDSO $@ >> cmd_vdsold = $(CC) $(c_flags) -Wl,-T $(filter %.lds,$^) >> $(filter %.o,$^) \ >> $(call cc-ldoption, -Wl$(comma)--build-id) \ >> -Wl,-Bsymbolic -Wl,-z,max-page-size=4096 \ >> + $(call cc-option, -fuse-ld=bfd) \ >> -Wl,-z,common-page-size=4096 -o $@ >> >> quiet_cmd_vdsomunge = MUNGE $@ > > > Thanks Nathan, your solution looks reasonable. I figured that the option > is available since GCC 4.8, so it should work probably for most > toolchains which try to make use of gold linker as default. > > Unfortunately, I hit another problem with the configuration on my build > host. With your patch applied, I get: > collect2: fatal error: cannot find 'ld' > compilation terminated. > make[2]: *** [arch/arm/vdso/vdso.so.raw] Error 1 > make[1]: *** [arch/arm/vdso] Error 2 > make[1]: *** Waiting for unfinished jobs.... Sorry for the noise, it turns out when using no paths in CROSS_COMPILE and instead add the location of the toolchain to PATH properly, this second issue is fixed. -- Stefan
On 05/09/2015 03:31 AM, Ard Biesheuvel wrote: > Hi Nathan, > > On 8 May 2015 at 23:15, Nathan Lynch <Nathan_Lynch@mentor.com> wrote: >> On 05/08/2015 11:08 AM, Stefan Agner wrote: >>> On 2015-05-08 17:27, Nathan Lynch wrote: >>>> On 05/08/2015 06:13 AM, Stefan Agner wrote: >>>>> Also, I used the BFD linker by adding LD=${CROSS_COMPILE}ld.bfd to the >>>>> build command. Interestingly thought, I had the same issue when using >>>>> gold linker... >>>> >>>> When I try this, ld.gold is used regardless. >>>> >>>> You can tell by doing and checking for a NT_GNU_GOLD_VERSION note: >>>> >>>> $ readelf -n arch/arm/vdso/vdso.so.raw >>>> >>>> Displaying notes found at file offset 0x000001bc with length 0x00000040: >>>> Owner Data size Description >>>> GNU 0x00000009 NT_GNU_GOLD_VERSION (gold version) >>>> GNU 0x00000014 NT_GNU_BUILD_ID (unique build >>>> ID bitstring) >>>> Build ID: f025409550acb7f955c61d95691291da078e6688 >>> >>> Hm, you are right. When deleting moving ld.bfd to ld, which makes the >>> BFD linker as default, compiling works flawless. >>> >>> However, so far LD=${CROSS_COMPILE}ld.bfc seems to work for other build >>> objects, at least those do not have this note. For instance time.o does >>> not return anything: >>> >>> $ readelf -n arch/arm/kernel/time.o >> >> This is just an object file that hasn't been linked, but your general >> point stands -- LD is honored by other parts of the build. >> >> > > I suppose this implies that the build only chokes on --pic-veneer when > linking the VDSO, and nowhere else? No, --pic-veneer isn't the problem for the VDSO; for better or worse LDFLAGS is ignored for the VDSO build.
On 05/09/2015 08:25 AM, Stefan Agner wrote: > On 2015-05-09 14:41, Stefan Agner wrote: >> On 2015-05-08 23:15, Nathan Lynch wrote: >>> On 05/08/2015 11:08 AM, Stefan Agner wrote: >>>> On 2015-05-08 17:27, Nathan Lynch wrote: >>>>> On 05/08/2015 06:13 AM, Stefan Agner wrote: >>>>>> Also, I used the BFD linker by adding LD=${CROSS_COMPILE}ld.bfd to the >>>>>> build command. Interestingly thought, I had the same issue when using >>>>>> gold linker... >>>>> >>>>> When I try this, ld.gold is used regardless. >>>>> >>>>> You can tell by doing and checking for a NT_GNU_GOLD_VERSION note: >>>>> >>>>> $ readelf -n arch/arm/vdso/vdso.so.raw >>>>> >>>>> Displaying notes found at file offset 0x000001bc with length 0x00000040: >>>>> Owner Data size Description >>>>> GNU 0x00000009 NT_GNU_GOLD_VERSION (gold version) >>>>> GNU 0x00000014 NT_GNU_BUILD_ID (unique build >>>>> ID bitstring) >>>>> Build ID: f025409550acb7f955c61d95691291da078e6688 >>>> >>>> Hm, you are right. When deleting moving ld.bfd to ld, which makes the >>>> BFD linker as default, compiling works flawless. >>>> >>>> However, so far LD=${CROSS_COMPILE}ld.bfc seems to work for other build >>>> objects, at least those do not have this note. For instance time.o does >>>> not return anything: >>>> >>>> $ readelf -n arch/arm/kernel/time.o >>> >>> This is just an object file that hasn't been linked, but your general >>> point stands -- LD is honored by other parts of the build. >>> >>> >>>> So it seems to be a vdso.so.raw specific problem not using the specified >>>> linker...? >>> >>> Yes, since it's produced by an invocation of $(CC) which is expected >>> to call the linker implicitly, and this is how the toolchain's default >>> linker ends up getting used even when you set LD on the command line. >>> >>> If I'm not mistaken, implicitly performing a link through the compiler >>> seems to be 1) conventional for all VDSOs, not just ARM's, but 2) unusual >>> for other parts of the kernel build. >>> >>> I suppose it's possible to make arch/arm/vdso/Makefile honor LD, but it >>> would basically entail a rewrite. In the meantime, using -fuse-ld=bfd >>> may suffice: >>> >>> diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile >>> index 8aa791051029..da0ce897edde 100644 >>> --- a/arch/arm/vdso/Makefile >>> +++ b/arch/arm/vdso/Makefile >>> @@ -43,6 +43,7 @@ quiet_cmd_vdsold = VDSO $@ >>> cmd_vdsold = $(CC) $(c_flags) -Wl,-T $(filter %.lds,$^) >>> $(filter %.o,$^) \ >>> $(call cc-ldoption, -Wl$(comma)--build-id) \ >>> -Wl,-Bsymbolic -Wl,-z,max-page-size=4096 \ >>> + $(call cc-option, -fuse-ld=bfd) \ >>> -Wl,-z,common-page-size=4096 -o $@ >>> >>> quiet_cmd_vdsomunge = MUNGE $@ >> >> >> Thanks Nathan, your solution looks reasonable. I figured that the option >> is available since GCC 4.8, so it should work probably for most >> toolchains which try to make use of gold linker as default. >> >> Unfortunately, I hit another problem with the configuration on my build >> host. With your patch applied, I get: >> collect2: fatal error: cannot find 'ld' >> compilation terminated. >> make[2]: *** [arch/arm/vdso/vdso.so.raw] Error 1 >> make[1]: *** [arch/arm/vdso] Error 2 >> make[1]: *** Waiting for unfinished jobs.... > > Sorry for the noise, it turns out when using no paths in CROSS_COMPILE > and instead add the location of the toolchain to PATH properly, this > second issue is fixed. I should have mentioned that this is the tradeoff with using -fuse-ld... the requested linker needs to be in $PATH. So, you lose if: 1. You're using e.g. CROSS_COMPILE=/usr/local/bin/arm-linux-gnu-gcc; 2. /usr/local/bin isn't in PATH; 3. Your toolchain is configured to use gold by default; 4. And you enable CONFIG_VDSO. I am okay with accepting this as a limitation if Russell is.
Sorry for the delay in following up on this. On 05/09/2015 04:26 AM, Russell King - ARM Linux wrote: > On Fri, May 08, 2015 at 04:15:25PM -0500, Nathan Lynch wrote: >> I suppose it's possible to make arch/arm/vdso/Makefile honor LD, but it >> would basically entail a rewrite. In the meantime, using -fuse-ld=bfd >> may suffice: >> >> diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile >> index 8aa791051029..da0ce897edde 100644 >> --- a/arch/arm/vdso/Makefile >> +++ b/arch/arm/vdso/Makefile >> @@ -43,6 +43,7 @@ quiet_cmd_vdsold = VDSO $@ >> cmd_vdsold = $(CC) $(c_flags) -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) \ >> $(call cc-ldoption, -Wl$(comma)--build-id) \ >> -Wl,-Bsymbolic -Wl,-z,max-page-size=4096 \ >> + $(call cc-option, -fuse-ld=bfd) \ >> -Wl,-z,common-page-size=4096 -o $@ > > Would it make more sense to have something like: > > VDSO_LDFLAGS := -Wl,-Bsymbolic -Wl,-z,max-page-size=4096 \ > -Wl,-z,common-page-size=4096 \ > $(call cc-ldoption, -Wl$(comma)--build-id) \ > $(call cc-option, -fuse-ld=bfd) > > and then have: > > cmd_vdsold = $(CC) $(c_flags) $(VDSO_LDFLAGS) \ > -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@ Yes, I can see value in grouping linker directives into one variable; there are a few in ccflags-y that could be moved to VDSO_LDFLAGS as well. > Also, do we want to use cc-option or cc-ldoption (this question becomes > obvious when you arrange the Makefile as I have above...)? cc-option > doesn't result in the linker actually being run, where as cc-ldoption > does. It's a corner case, but cc-option and cc-ldoption result in different failure modes when gold is the default linker and the bfd linker is not in $PATH: With $(call cc-option, -fuse-ld=bfd): VDSO arch/arm/vdso/vdso.so.raw collect2: fatal error: cannot find 'ld' With $(call cc-ldoption, -fuse-ld=bfd): VDSO arch/arm/vdso/vdso.so.raw HOSTCC arch/arm/vdso/vdsomunge MUNGE arch/arm/vdso/vdso.so.dbg OBJCOPY arch/arm/vdso/vdso.so BFD: arch/arm/vdso/vdso.so: Not enough room for program headers, try linking with -N That is, since using cc-ldoption invokes the linker, and the bfd linker isn't found, -fuse-ld=bfd is omitted from the command and gold gets run, resulting in the same symptom as the report that started this thread. I think the first one gives more of a clue as to what the user can do to remedy the situation, so that's what I'd slightly prefer.
diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile index 8aa791051029..da0ce897edde 100644 --- a/arch/arm/vdso/Makefile +++ b/arch/arm/vdso/Makefile @@ -43,6 +43,7 @@ quiet_cmd_vdsold = VDSO $@ cmd_vdsold = $(CC) $(c_flags) -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) \ $(call cc-ldoption, -Wl$(comma)--build-id) \ -Wl,-Bsymbolic -Wl,-z,max-page-size=4096 \ + $(call cc-option, -fuse-ld=bfd) \ -Wl,-z,common-page-size=4096 -o $@ quiet_cmd_vdsomunge = MUNGE $@