Bug 29592 - [2.39 Regression][bisected] Exec stack warning causes go programs with cgo to fail to link on mips
Summary: [2.39 Regression][bisected] Exec stack warning causes go programs with cgo to...
Status: UNCONFIRMED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.39
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL: https://github.com/golang/go/issues/5...
Keywords:
Depends on:
Blocks:
 
Reported: 2022-09-21 05:06 UTC by matoro
Modified: 2022-10-17 01:08 UTC (History)
3 users (show)

See Also:
Host: mips64-unknown-linux-gnu
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description matoro 2022-09-21 05:06:19 UTC
65daf5bed68f3e792e80f7c9a12871fd71da32a2 is the first bad commit
commit 65daf5bed68f3e792e80f7c9a12871fd71da32a2
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed Apr 20 13:37:51 2022 +0100

    Add linker warning for when it creates an executable stack.

       PR 29072

On mips, since this commit, all linking prints the following warning:

/usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../mips64-unknown-linux-gnu/bin/ld: warning: /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../lib64/Scrt1.o: requires executable stack (because the .note.GNU-stack section is executable)

This seems to be harmless most of the time.  However this commit also seems to have made it impossible to link golang programs (including golang itself) when cgo is enabled (which is the default unless explicitly disabled with CGO_ENABLED=0).  The linker will print the following error thousands of times, one for every single local symbol:

+ ./cmd/dist/dist bootstrap -a
Building Go toolchain1 using /usr/lib/go-bootstrap.
Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.
Building Go toolchain2 using go_bootstrap and Go toolchain1.
Building Go toolchain3 using go_bootstrap and Go toolchain2.
Building packages and commands for linux/mips64.
# cmd/trace
/var/tmp/portage/dev-lang/go-1.19.1/work/go/pkg/tool/linux_mips64/link: running mips64-unknown-linux-gnu-gcc failed: exit status 1
/var/tmp/portage/dev-lang/go-1.19.1/temp/go-link-3757955373/go.o: in function `internal/cpu.Initialize':
/usr/lib/go/src/internal/cpu/cpu.go:123:(.text+0x14): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:124:(.text+0x30): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/var/tmp/portage/dev-lang/go-1.19.1/temp/go-link-3757955373/go.o: in function `internal/cpu.Initialize':
/usr/lib/go/src/internal/cpu/cpu_mips64x.go:22:(.text+0x40): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/var/tmp/portage/dev-lang/go-1.19.1/temp/go-link-3757955373/go.o: in function `internal/cpu.doinit':
/usr/lib/go/src/internal/cpu/cpu_mips64x.go:23:(.text+0x54): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu_mips64x.go:23:(.text+0x64): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu_mips64x.go:22:(.text+0x78): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu_mips64x.go:22:(.text+0x84): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu_mips64x.go:22:(.text+0x90): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu_mips64x.go:22:(.text+0xa4): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu_mips64x.go:22:(.text+0xb8): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu_mips64x.go:22:(.text+0xc4): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu_mips64x.go:27:(.text+0xcc): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu_mips64x.go:27:(.text+0xe4): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/var/tmp/portage/dev-lang/go-1.19.1/temp/go-link-3757955373/go.o: in function `internal/cpu.Initialize':
/usr/lib/go/src/internal/cpu/cpu.go:125:(.text+0x100): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/var/tmp/portage/dev-lang/go-1.19.1/temp/go-link-3757955373/go.o: in function `internal/cpu.processOptions':
/usr/lib/go/src/internal/cpu/cpu.go:148:(.text+0x130): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:180:(.text+0x34c): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:187:(.text+0x368): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:175:(.text+0x384): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:175:(.text+0x38c): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:175:(.text+0x3a4): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:175:(.text+0x3bc): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:175:(.text+0x3c4): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:175:(.text+0x3dc): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:175:(.text+0x3f4): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:175:(.text+0x3fc): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:175:(.text+0x414): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:175:(.text+0x41c): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:163:(.text+0x43c): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:163:(.text+0x444): relocation R_MIPS_HI16 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:163:(.text+0x45c): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC
/usr/lib/go/src/internal/cpu/cpu.go:163:(.text+0x474): relocation R_MIPS_26 against `a local symbol' cannot be used when making a shared object; recompile with -fPIC


And so on for a huge length, eventually erroring.  There is one final warning at the end:

/usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../mips64-unknown-linux-gnu/bin/ld: warning: creating DT_TEXTREL in a PIE

Linking C programs, other than the execstack warning, still works even after this commit; only golang programs are affected.
Comment 1 Nick Clifton 2022-09-21 10:13:12 UTC
(In reply to matoro from comment #0)
Hi Matoro,

> On mips, since this commit, all linking prints the following warning:
> 
> /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../mips64-unknown-
> linux-gnu/bin/ld: warning:
> /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../lib64/Scrt1.o:
> requires executable stack (because the .note.GNU-stack section is executable)

This was supposed to have been fixed by commit ed1c7ad8e31a2cfca1d8c8c898ee7cde6ae340ca  
Do you have that commit in your sources ?


 
> /var/tmp/portage/dev-lang/go-1.19.1/temp/go-link-3757955373/go.o: in
> function `internal/cpu.Initialize':
> /usr/lib/go/src/internal/cpu/cpu.go:123:(.text+0x14): relocation R_MIPS_26
> against `a local symbol' cannot be used when making a shared object;
> recompile with -fPIC

Are you sure that it was that commit which triggered this problem ?

The commit only added code to generate the new warning messages, it did not - or at least should not - affect the linking process in any other way.

Also - is the warning correct ?  Is the -fPIC option missing from the compilation command line ?  Or is the linker mistaken when it complains about attempting to create a shared object ?  (IE is it supposed to be creating a static executable rather than a dynamic executable ?)

Cheers
  Nick
Comment 2 matoro 2022-09-21 14:51:40 UTC
(In reply to Nick Clifton from comment #1)
> (In reply to matoro from comment #0)
> Hi Matoro,
> 
> > On mips, since this commit, all linking prints the following warning:
> > 
> > /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../mips64-unknown-
> > linux-gnu/bin/ld: warning:
> > /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../lib64/Scrt1.o:
> > requires executable stack (because the .note.GNU-stack section is executable)
> 
> This was supposed to have been fixed by commit
> ed1c7ad8e31a2cfca1d8c8c898ee7cde6ae340ca  
> Do you have that commit in your sources ?
> 
> 
>  
> > /var/tmp/portage/dev-lang/go-1.19.1/temp/go-link-3757955373/go.o: in
> > function `internal/cpu.Initialize':
> > /usr/lib/go/src/internal/cpu/cpu.go:123:(.text+0x14): relocation R_MIPS_26
> > against `a local symbol' cannot be used when making a shared object;
> > recompile with -fPIC
> 
> Are you sure that it was that commit which triggered this problem ?
> 
> The commit only added code to generate the new warning messages, it did not
> - or at least should not - affect the linking process in any other way.
> 
> Also - is the warning correct ?  Is the -fPIC option missing from the
> compilation command line ?  Or is the linker mistaken when it complains
> about attempting to create a shared object ?  (IE is it supposed to be
> creating a static executable rather than a dynamic executable ?)
> 
> Cheers
>   Nick

Hi Nick, thank you for taking a look at this.  I checked and found that the distro (Gentoo) is actually explicitly passing --enable-warn-execstack, so any change to the defaults doesn't help:  https://github.com/gentoo/gentoo/blob/master/sys-devel/binutils/binutils-9999.ebuild#L251

I tested  at that commit and when --enable-warn-execstack is passed, the issue is still present.  What I don't understand is why toggling this warning on or off changes the behavior of the linker - shouldn't it just be a purely informational warning?
Comment 3 matoro 2022-09-21 14:55:01 UTC
The warning itself is correct.  In golang, CGO_ENABLED=1 (the default) creates a dynamic exe, while CGO_ENABLED=0 produces a static one.

However the -fPIC part is not accurate.  Golang has its own assembly emitter, it doesn't use gcc or any compiler for codegen.  It only uses ld for linking.
Comment 4 matoro 2022-09-21 15:21:04 UTC
OK, just tested, removing --enable-warn-execstack does resolve the problem.  But that also confirms that toggling that flag is not purely informational, it has an effect on the linker behavior and causes previously-working scenarios to stop working.
Comment 5 Nick Clifton 2022-09-22 11:25:28 UTC
(In reply to matoro from comment #3)
> The warning itself is correct.  In golang, CGO_ENABLED=1 (the default)
> creates a dynamic exe, while CGO_ENABLED=0 produces a static one.
> 
> However the -fPIC part is not accurate.  Golang has its own assembly
> emitter, it doesn't use gcc or any compiler for codegen.  It only uses ld
> for linking.

So possibly the golang assembler is generating the wrong relocations when CGO_ENABLED is set to 0.  (ie it should be producing relocations suitable for generating static executables, but instead it is generating relocations suitable for dynamic executables).


(In reply to matoro from comment #4)
> OK, just tested, removing --enable-warn-execstack does resolve the problem. 
> But that also confirms that toggling that flag is not purely informational,
> it has an effect on the linker behavior and causes previously-working
> scenarios to stop working.

Right - we definitely need to investigate this.  Is there any chance that you can create a small test case that reproduces the problem ?  Ideally one that just involves the linker and does not need a Go toolchain.
Comment 6 matoro 2022-09-22 17:11:52 UTC
*It's the other way around - CGO_ENABLED=1 is the default, creates a dynamic binary, and that is the scenario where it is not working.  It works with CGO_ENABLED=0, which creates a static binary, but that is a non-default workaround.

I captured this by stopping the golang link command, and taking a snapshot of its temporary link directory while frozen.  What confused me was that the object code was *exactly the same* in both the good and bad directories!  Then I compared the scripts with the linker invocations that I got out of pgrep and saw that they were different.  The linker is getting invoked differently depending on whether the execstack warning is enabled or not.

Without --enable-warn-execstack:
/usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../mips64-unknown-linux-gnu/bin/ld -plugin /usr/libexec/gcc/mips64-unknown-linux-gnu/12.2.0/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/mips64-unknown-linux-gnu/12.2.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccYpZeDT.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --eh-frame-hdr -EB -export-dynamic -dynamic-linker /lib64/ld.so.1 -melf64btsmip -o go-sqlite3.test -s /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../lib64/crt1.o /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../lib64/crti.o /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/crtbegin.o -L/usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0 -L/usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../lib64 -L/lib64/../lib64 -L/usr/lib64/../lib64 -L/usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../mips64-unknown-linux-gnu/lib -L/usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../.. -L/lib64 -L/usr/lib64 --compress-debug-sections=zlib /tmp/go-link-good/go.o /tmp/go-link-good/000000.o /tmp/go-link-good/000001.o /tmp/go-link-good/000002.o /tmp/go-link-good/000003.o /tmp/go-link-good/000004.o /tmp/go-link-good/000005.o /tmp/go-link-good/000006.o /tmp/go-link-good/000007.o /tmp/go-link-good/000008.o /tmp/go-link-good/000009.o /tmp/go-link-good/000010.o /tmp/go-link-good/000011.o /tmp/go-link-good/000012.o /tmp/go-link-good/000013.o /tmp/go-link-good/000014.o /tmp/go-link-good/000015.o /tmp/go-link-good/000016.o /tmp/go-link-good/000017.o /tmp/go-link-good/000018.o /tmp/go-link-good/000019.o /tmp/go-link-good/000020.o /tmp/go-link-good/000021.o /tmp/go-link-good/000022.o -ldl -lpthread -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/crtend.o /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../lib64/crtn.o

With --enable-warn-execstack:
/usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../mips64-unknown-linux-gnu/bin/ld -plugin /usr/libexec/gcc/mips64-unknown-linux-gnu/12.2.0/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/mips64-unknown-linux-gnu/12.2.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccexkDVx.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --eh-frame-hdr -EB -export-dynamic -dynamic-linker /lib64/ld.so.1 -melf64btsmip -pie -o go-sqlite3.test -s /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../lib64/Scrt1.o /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../lib64/crti.o /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/crtbeginS.o -L/usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0 -L/usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../lib64 -L/lib64/../lib64 -L/usr/lib64/../lib64 -L/usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../mips64-unknown-linux-gnu/lib -L/usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../.. -L/lib64 -L/usr/lib64 /tmp/go-link-bad/go.o /tmp/go-link-bad/000000.o /tmp/go-link-bad/000001.o /tmp/go-link-bad/000002.o /tmp/go-link-bad/000003.o /tmp/go-link-bad/000004.o /tmp/go-link-bad/000005.o /tmp/go-link-bad/000006.o /tmp/go-link-bad/000007.o /tmp/go-link-bad/000008.o /tmp/go-link-bad/000009.o /tmp/go-link-bad/000010.o /tmp/go-link-bad/000011.o /tmp/go-link-bad/000012.o /tmp/go-link-bad/000013.o /tmp/go-link-bad/000014.o /tmp/go-link-bad/000015.o /tmp/go-link-bad/000016.o /tmp/go-link-bad/000017.o /tmp/go-link-bad/000018.o /tmp/go-link-bad/000019.o /tmp/go-link-bad/000020.o /tmp/go-link-bad/000021.o /tmp/go-link-bad/000022.o -ldl -lpthread -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/crtendS.o /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../lib64/crtn.o


Diff:

7c7
< -plugin-opt=-fresolution=/tmp/ccYpZeDT.res
---
> -plugin-opt=-fresolution=/tmp/ccexkDVx.res
18a19
> -pie
22c23
< /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../lib64/crt1.o
---
> /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/../../../../lib64/Scrt1.o
24c25
< /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/crtbegin.o
---
> /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/crtbeginS.o
33,57c34,57
< --compress-debug-sections=zlib
< /tmp/go-link-good/go.o
< /tmp/go-link-good/000000.o
< /tmp/go-link-good/000001.o
< /tmp/go-link-good/000002.o
< /tmp/go-link-good/000003.o
< /tmp/go-link-good/000004.o
< /tmp/go-link-good/000005.o
< /tmp/go-link-good/000006.o
< /tmp/go-link-good/000007.o
< /tmp/go-link-good/000008.o
< /tmp/go-link-good/000009.o
< /tmp/go-link-good/000010.o
< /tmp/go-link-good/000011.o
< /tmp/go-link-good/000012.o
< /tmp/go-link-good/000013.o
< /tmp/go-link-good/000014.o
< /tmp/go-link-good/000015.o
< /tmp/go-link-good/000016.o
< /tmp/go-link-good/000017.o
< /tmp/go-link-good/000018.o
< /tmp/go-link-good/000019.o
< /tmp/go-link-good/000020.o
< /tmp/go-link-good/000021.o
< /tmp/go-link-good/000022.o
---
> /tmp/go-link-bad/go.o
> /tmp/go-link-bad/000000.o
> /tmp/go-link-bad/000001.o
> /tmp/go-link-bad/000002.o
> /tmp/go-link-bad/000003.o
> /tmp/go-link-bad/000004.o
> /tmp/go-link-bad/000005.o
> /tmp/go-link-bad/000006.o
> /tmp/go-link-bad/000007.o
> /tmp/go-link-bad/000008.o
> /tmp/go-link-bad/000009.o
> /tmp/go-link-bad/000010.o
> /tmp/go-link-bad/000011.o
> /tmp/go-link-bad/000012.o
> /tmp/go-link-bad/000013.o
> /tmp/go-link-bad/000014.o
> /tmp/go-link-bad/000015.o
> /tmp/go-link-bad/000016.o
> /tmp/go-link-bad/000017.o
> /tmp/go-link-bad/000018.o
> /tmp/go-link-bad/000019.o
> /tmp/go-link-bad/000020.o
> /tmp/go-link-bad/000021.o
> /tmp/go-link-bad/000022.o
71c71
< /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/crtend.o
---
> /usr/lib/gcc/mips64-unknown-linux-gnu/12.2.0/crtendS.o


You can see that after the change, it seems to be enabling PIE in the bad scenario, when it presumably should not.
Comment 7 Nick Clifton 2022-09-26 15:33:05 UTC
(In reply to matoro from comment #6)
Hi Matoro,

 
> Then I compared the scripts with the linker invocations that I got out of
> pgrep and saw that they were different.  The linker is getting invoked
> differently depending on whether the execstack warning is enabled or not.

OK - so does that mean that the bug is inside whatever is constructing the linker
command line ?

You said that Gentoo is adding --enable-warn-execstack. How does it do this ?  Could whatever method it is using also be the source of the mis-constructed linker command line ?

 
> With --enable-warn-execstack:

I might be missing something here, but I do not actually see --enable-warn-execstack on the command line that you listed.

> -melf64btsmip -pie -o go-sqlite3.test -s
  
It looks to me like the -pie option is also added here...

Cheers
  Nick
Comment 8 matoro 2022-09-26 15:56:58 UTC
(In reply to Nick Clifton from comment #7)
> (In reply to matoro from comment #6)
> Hi Matoro,
> 
>  
> > Then I compared the scripts with the linker invocations that I got out of
> > pgrep and saw that they were different.  The linker is getting invoked
> > differently depending on whether the execstack warning is enabled or not.
> 
> OK - so does that mean that the bug is inside whatever is constructing the
> linker
> command line ?
> 
> You said that Gentoo is adding --enable-warn-execstack. How does it do this
> ?  Could whatever method it is using also be the source of the
> mis-constructed linker command line ?
> 
>  
> > With --enable-warn-execstack:
> 
> I might be missing something here, but I do not actually see
> --enable-warn-execstack on the command line that you listed.
> 
> > -melf64btsmip -pie -o go-sqlite3.test -s
>   
> It looks to me like the -pie option is also added here...
> 
> Cheers
>   Nick

--enable-warn-execstack is the flag you yourself added to default-enable this feature at binutils build-time in ba951afb99912da01a6e8434126b8fac7aa75107.

To test this, I am toggling this flag on/off and rebuilding binutils.  When it's toggled on, it always enables the warning, and -pie gets added to link invocations from ld.  When toggled off, it defers to the target-specific rules, which you already used to disable the warning on mips, and -pie does NOT get added to link invocations.

As for what actually invokes the linker, I believe it is the usual gcc -> collect2 -> ld chain.  I will check and see if these command lines are different also.
Comment 9 Nick Clifton 2022-09-27 08:09:32 UTC
(In reply to matoro from comment #8)

Sorry - what I meant was that the problem is not with the code that implements the execstack warning, but rather the fact that when CGO_ENABLED=1 is used, the GO compiler is changing its behaviour and trying to link a dynamic executable rather than a static one.  

As part of this change different startup files are selected, and in particular /usr/lib64/Scrt1.o is being linked in, rather than /usr/lib64/crt1.o.  This is a problem because /usr/lib64/Scrt1.o is marked as requiring an executable stack and so the warning is triggered.  But - this warning has not caused all the other linking problems.  It is the fact that the linker is now being asked to create a dynamic executable from object files that were built for static linkage that causes the problems.

So the real question is *why* does CGO_ENABLED=1 change the type of executable that is being created ?
Comment 10 Sam James 2022-10-17 00:53:18 UTC
wrt the configure flag issue: could we change this so it only affects arches which support non-exec stacks, etc?

i.e. If there's an exception granted to disable the warning by default, don't override it with the configure option.
Comment 11 matoro 2022-10-17 01:08:47 UTC
(In reply to Nick Clifton from comment #9)
> (In reply to matoro from comment #8)
> 
> Sorry - what I meant was that the problem is not with the code that
> implements the execstack warning, but rather the fact that when
> CGO_ENABLED=1 is used, the GO compiler is changing its behaviour and trying
> to link a dynamic executable rather than a static one.  
> 
> As part of this change different startup files are selected, and in
> particular /usr/lib64/Scrt1.o is being linked in, rather than
> /usr/lib64/crt1.o.  This is a problem because /usr/lib64/Scrt1.o is marked
> as requiring an executable stack and so the warning is triggered.  But -
> this warning has not caused all the other linking problems.  It is the fact
> that the linker is now being asked to create a dynamic executable from
> object files that were built for static linkage that causes the problems.
> 
> So the real question is *why* does CGO_ENABLED=1 change the type of
> executable that is being created ?

Sorry I missed this question.  CGO_ENABLED will toggle between dynamic and static executables.  By default, with CGO_ENABLED=1, go will generate dynamic binaries.  Setting CGO_ENABLED=0 will create static binaries.