-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/go: -buildmode=pie does not build correct PIE binaries for ppc64le #28531
Comments
When you use As far as a gcc defaulting to PIE, we already have support when using |
I'm sorry there's some confusion here. This was reported to me through a bugzilla that even with -buildmode=pie a bad relocation is generated but I was mistaken above about whether stdlib is built with PIC in this case. In my experiments it seems to be. The reported failure is on RHEL8 which I don't have access to so I'm not sure yet where it is coming from. One related question is whether golang should recognize whether the gcc on the system sets -pie by default when invoking the linker and if so just build it as -buildmode=pie. I'm not sure if that's the right answer but just what was suggested. |
I don't think we should change the default of Perhaps we should have an easy way for a distro to change the default of |
@ianlancetaylor Is there a way to build a toolchain for ppc64le so that the default type of executable is always PIE through the use of existing environment variables or other options? Or is it more complicated than that? I tried to just change the default in cmd/go/internal/work/init.go as a test to see what would happen and got this:
|
There is no simple way today to force the gc toolchain to default to PIE. I'm not sure why changing |
This issue is also present on SUSE and openSUSE for ppc64le. With go1.10.5, the build stops at the following error:
By ensuring gcc does not use PIE by default, the build can complete, although this is not ideal. It would be a great improvement to have an environment variable and option to force the toolchain to default to PIE. |
@jfkw Now in 1.12 you should be able to use |
@ianlancetaylor seems not work for 1.12:
|
@daixiang0 This bug report is about a problem with ppc64le. You are using mips64le. |
@ianlancetaylor sorry for mistake, BTW any plan for mips to support pie build mode? |
@daixiang0 Sorry, I do not know of anyone working on adding support for PIE for MIPS. |
I believe the title is is misleading. -buildmode=pie works fine for most things on ppc64le. The problem happens when trying to build a toolchain that will generate all binaries as pie by default, including those that are part of the toolchain. This came about because of a request from a single user. No one has asked about this again, so if we want to close it that is fine with me. I retried the same experiment as I did back in November and got the same result. |
So now you have to add 'me too' to bugs? It his some web 2.0 thing? Anyway, the code is just broken. How do you suppose the code is position independent if the libraries included in the interpreter are not? |
If you have an example of a failure when using -buildmode=pie on ppc64le
please provide it.
I'm not sure what libraries you are referring to, my understanding is that
if it is Go code built using -buildmode=pie it will be built as position
independent, and C or C++ code built for ppc64le should be position
independent by default.
…On Thu, Oct 17, 2019 at 11:07 AM Michal Suchánek ***@***.***> wrote:
So now you have to add 'me too' to bugs? It his some web 2.0 thing?
Anyway, the code is just broken.
How do you suppose the code is position independent if the libraries
included in the interpreter are not?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#28531?email_source=notifications&email_token=ACH7BDCEUEUQKTT56QRZISTQPCEV5A5CNFSM4GA2TLN2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEBQULNY#issuecomment-543245751>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACH7BDGW7BMX7JJBJW54FBDQPCEV5ANCNFSM4GA2TLNQ>
.
|
Apparently not. Some distributions choose to set this default which breaks go completely. |
I'm very sorry. I didn't notice that an earlier comment was made regarding this topic related to SUSE. If I change the default in init.go, I still get the errors that some files are stale. I cannot reproduce the problem identified earlier on SUSE using go 1.10.5. Were there any env variables used during the build? What distro was it. |
In openSUSE there is a package gcc-PIE which sets the gcc defaults options to PIC and PIE (since Leap 15.0 which is the oldest version still developed). They can still be overridden on the commandline or the package may opt to not install these defaults. Not using the PIE options was what was done in openSUSE to build go and go packages on ppc64le. |
@laboger I don't know why setting |
@hramrach Please be polite when making comments, and bear in mind the Gopher Code of Conduct (https://golang.org/conduct). In particular, be patient and be charitable. Thanks. |
What the R_PPC64_ADDR16_HA suggests is you generate direct references which are filled in as immediates in the code which are only 16bit and you need to generate indirect jumps or loads to be able to link non-trivial ppc binaries referencing code or data more than +-32kb away. |
@ianlancetaylor Currently, the openSUSE ppc64le go package builds by not installing the gcc-PIE package. I will do some testing in openSUSE ppc64le using the |
I suspect this is a bootstrap issue to some extent. You cannot build pie binaries if your stdlib is not PIC. You probably need to rebuild twice, once to build PIC stdlib injecting the PIC flag somewhere, and second time to build the PIE binaries. |
@hramrach If I understand you correctly, then the go tool should consistently do the right thing. Using |
that's not possible in the case when you are trying to build a pie compiler and all you have is non-PIE compiler with non-PIC stdlib. The new compiler will use the old stdlib which is not suitable. So you first need to build a compiler with PIC stdlib which does not default to PIE and then fully PIE compiler. Assuming the code generation works and correct relocations are generated. |
Yes, if I use -x I can see it uses -buildmode=pie on the final link of the executable for hello. |
@hramrach I'm sorry, I'm not sure what you mean. When you say "stdlib", what are you referring to? When you say "interpreter", do you mean the ELF interpreter, also known as the dynamic linker? |
sorry, I meant compiler. Looks like interpreter is not standard part of go. |
@hramrach When you say "stdlib", what are you referring to? |
whatever comes with the compiler that might be linked into binaries. |
Assuming you mean the Go compiler, then, as I explained at #28531 (comment), the Go standard library will be rebuilt, if necessary, with the options required to support the requested build mode. This happens automatically and does not require any user intervention. The results are cached to avoid excess rebuilding. |
After I do a normal build, I can do this to make these binaries built as pie: go install -buildmode=pie cmd/go Does this help? |
I would like to find a solution for this in Go 1.15. There are several options but they all have build failures due to the cache. I would need some help from someone who knows more about how the build cache is supposed to work. |
It's not clear to me what the build cache is doing wrong. Can you provide more details? |
I tried various combinations to force binaries to pie but could get nothing to work. Back to original example above, if I try to force everything built for ppc64le to -buildmode=pie then I get the stale errors above. Since I'm not sure how the cache is supposed to work, I don't know why it is complaining. I thought I saw a comment somewhere that said the buildmode was not saved in the cache which could be related but I still don't understand how something would get into the cache at one point and then look stale later if the same build options were used throughout. Assuming we could get it to work using pie as default, then there could be other issues. One would be how this default gets set, and the fact that we now check gcc's default link mode and change it from pie to no-pie all the time. That would have to change, and maybe that should be the indicator as to when to set Go's default buildmode to pie? If gcc wants pie as default then Go's buildmode should default to pie. Otherwise we provide an environment variable, maybe one used at build time to say this toolchain defaults to pie? Another question is, does this mean everything defaults to pie, even binaries that would have been built as static? I believe static should still work fine on systems that expect pie as the default unless there is some other reason we don't want static in this environment. |
The "stale dependency" errors shown in #28531 (comment) aren't about the build cache. Those are coming from cmd/dist, and mean that the package installed by |
I thought the original suggestion was to set the default buildmode to pie and codegenArg to shared in init.go. Doing that gives the output shown above. Then I tried modifying lib.go to avoid the errors from loadInternal about runtime/cgo. That eliminates those errors but the rest of the error message is still there. I did spend some time looking at checkNotStale but I don't understand why go list is complaining that these packages are stale because I don't know how it decides that and looking at the code didn't help to figure that out. Even if I look at the go list help documentation, it doesn't say what causes something to be stale. Are you saying that the -gcflags and -ldflags passed to go list in this function should use flags for pie and shared instead of blank as the output shows? |
I'm sorry, I guess I don't understand what is going on. This issue started as a problem using Then there was the separate discussion of changing the toolchain to default to generating a PIE. I guess the suggestion of changing cmd/go/internal/work may have been wrong. What was the patch that you have tried? I don't it above; maybe I missed it. |
I'm trying to build a toolchain that generates pie binaries by default, including the binaries that are generated during the build. Then the goal would be to have some environment variable or other switch to indicate that it should be done that way. Sorry for the confusion. This has been requested by more than one user but I personally do not have any specific issues with reproducible directions on how to cause errors when we don't default to pie on systems that expect pie. Based on previous test failures we saw with this error message when building for pie, it is probably related to mixing pic and non-pic code which we may or may not be able to fix. (i.e., if linking in a C library that was not built for pic). I tried a change to cmd/go/internal/work to force buildmode=pie by default, but that causes the errors during the build about runtime/cgo and stale packages coming from checkNotStale in cmd/dist/build.go. I don't understand why go -list would say the package or binary is stale if it just built it and therefore should be newer than the source. What else would cause it to be considered stale. Here is an initial patch to set the default to pie and fix up the errors about runtime/cgo. I also added something to remove defaulting to no-pie to see if that made any difference but it doesn't. |
go version mips64le
mipsle
|
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?latest
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?ppc64le
What did you do?
Tried to run binaries built as PIE.
What did you expect to see?
Correct execution
What did you see instead?
Error messages like this:
./main.exe: error while loading shared libraries: R_PPC64_ADDR16_HA re10f2f8fa4 for symbol `' out of range
2018/09/05 09:53:14 Failed: exit status 127
on newer distros.
The problem is related to issues #27510 and #21954 and can still be reproduced on many distros by passing -pie as a linker option.
The solution to the above issues was to use -buildmode=pie but that doesn't correct all problems. When linking a program with -pie on ppc64le then all code should be built as PIC. When some code is not PIC there could be relocations created like R_PPC64_ADDR16_HA which will fail with the above error if the relocated addresses are too big. On some distros/kernels we get lucky and no failures occur if the addresses stay small enough but on newer distros the runtime relocation errors can occur.
When using -buildmode=pie the -shared option is set to force the compiles to be built as PIC but it still links in stdlib which was not built as PIC. Likewise any library linked in should be PIC. When all the code is has been built as PIC then this relocation would not be generated and the PIE should work.
One further question is whether all code should be PIC if the gcc being used for the link passes -pie by default and stop setting -no-pie.
The text was updated successfully, but these errors were encountered: