#12430 closed bug (fixed)
gcc 4 won't build a non-position-independent executable
Reported by: | simonsouth | Owned by: | korli |
---|---|---|---|
Priority: | normal | Milestone: | Unscheduled |
Component: | System | Version: | R1/Development |
Keywords: | Cc: | ||
Blocked By: | Blocking: | ||
Platform: | All |
Description
(This is the compile-side counterpart to #12427.)
On Haiku, executables are position-independent by default. However asking gcc (4.8.5) to build a non-position-independent executable with (for instance) the -fno-pie
flag fails with an error message like
/boot/system/(...)/bin/ld: /tmp//ccxbCP1i.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC /tmp//ccxbCP1i.o: error adding symbols: Bad value collect2: error: ld returned 1 exit status
This is because gcc is configured to always pass either the -r
or -shared
flag to the linker, and there is no easy way to override this. But not everything is relocatable or a shared object, and if the user specifically requests something different, that request should be honoured.
Consequently apps like GNU Emacs that rely on support for fixed-position executables cannot be built on Haiku right now.
Attachments (6)
Change History (22)
by , 9 years ago
Attachment: | 0001-gcc-Allow-the-user-to-build-non-PI-executables.patch added |
---|
comment:1 by , 9 years ago
patch: | 0 → 1 |
---|
by , 9 years ago
Attachment: | 0002-gcc-CC1_SPEC-LINK_SPEC-Wrap-lines-at-80-columns.patch added |
---|
Wrap CC1_SPEC and LINK_SPEC lines at 80 columns
by , 9 years ago
Attachment: | 0003-gcc-LINK_SPEC-Gently-refactor.patch added |
---|
Gently refactor LINK_SPEC: Consolidate sequences; use more compact notation
by , 9 years ago
Attachment: | 0004-binutils-ld-Set-ELF-interpreter-to-system-runtime_lo.patch added |
---|
Set ELF interpreter to "/system/runtime_loader"
comment:2 by , 9 years ago
Here is a set of patches that correct this issue.
The first patch modifies gcc's CC1_SPEC
and LINK_SPEC
strings to
- Include
-fno-PIC
and-fno-PIE
as command-line options that disable the generation of position-independent code (and remove the non-existent-no-fpic
option). - Use
-fPIC
by default in place of-fpic
to compile without restriction on the size of the global offset table (this matters only on m68k and ppc, and is already the default on ppc; users can still request this limit with-fpic
). - Pass
-shared
to the linker only if it was passed to gcc. - Output position-independent executables by default, and request them specifically with the
-pie
linker option, allowing undefined symbols in shared libraries and exporting all symbols to match the behaviour of shared-object "executables" today.
The remaining patches are optional but complete the implementation. In order, they
- Wrap the
CC1_SPEC
andLINK_SPEC
strings neatly at 80 columns. - Gently refactor the
LINK_SPEC
string for several platforms, consolidating sequences and using a more compact notation without any change in functionality. - Set the ELF interpreter on generated executables.
Now that gcc is outputting "real" PIEs and not shared objects masquerading as them, the linker includes an
INTERP
segment in the ELF header requesting a specific interpreter to launch the program. This final patch (against ld) changes the contents of this section from the UNIX-y default to something more accurate and distinctly Haiku.
With these patches applied
- The default behaviour of gcc is not changed. Position-independent executables are still generated by default, and these still participate in dynamic linking exactly as they do today.
- Pre-existing executables function just as they do currently and can still be used as link targets.
- Users can ask gcc to build a non-position-independent executable with the
-fno-pic
or-fno-pie
options, and the request will be honoured (and with the patch for #12427 applied, the generated executable will run). - gcc now says what it means: When it means to build a position-independent executable, it says so explicitly by passing the
-pie
option to the linker. No longer does it request a shared object that just happens to function like a PIE. - An INTERP segment is included in every executable that identifies it as built for Haiku with a pointer to
/system/runtime_loader
. This is ignored by runtime_loader today, but (aside from the vanity aspect) could be useful down the road to distinguish between 32- and 64-bit executables on x86_64, or to support seamless execution of BeOS and Haiku executables together.
by , 9 years ago
Attachment: | 0005-gcc-ppc-Remove-now-redundant-CC1_SPEC.patch added |
---|
Remove redundant CC1_SPEC from ppc
comment:3 by , 9 years ago
I realized in writing the above that with these changes, there is no longer a need for ppc to define its own CC1_SPEC.
I've added a fifth patch that removes this now-redundant code.
comment:4 by , 9 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:5 by , 9 years ago
Thanks for the patches. They look correct to me. I tested on x86 and x86_64, it runs well, though I got for both those warnings on kernel add-on link (the default address changes every time)
cross-tools-x86_64/lib/gcc/x86_64-unknown-haiku/4.8.5/../../../../x86_64-unknown-haiku/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000002cb0
When loading the addons, the kernel prints warnings:
ahci: unhandled pheader type 0x6 ahci: unhandled pheader type 0x3
I can handle the "unhandled pheader type" warnings in src/system/kernel/elf.cpp. The ld warning is probably related to the KernelAddOn rule in build/jam/KernelRules. Have you an idea for this one?
by , 9 years ago
Attachment: | 0006-Build-without-linker-warnings-about-missing-entry-sy.patch added |
---|
Build without linker warnings about missing entry symbols
comment:7 by , 9 years ago
Yes; this latest patch should clear up these warnings.
- From looking at the code it seems kernel add-ons are really meant to be built as shared objects (hence the lack of an apparent entry point), which just happened to be the default behaviour before. Adding
-shared
to the link options makes this explicit and clears up those warnings.
- The same warning was being issued by the BuildMBR rule, which was using the
-Xlinker
option incorrectly in an attempt to specify the entry point to the linker (the GCC manual actually warns about this misuse). A bit of reformatting fixes this as well.
comment:8 by , 9 years ago
Patch 6 looks good. I'll give it a check with GCC 2.95 first, then push the patchset.
On a side note, would it make sense to align GCC 2.95 behavior regarding -shared
?
comment:9 by , 9 years ago
Yes; probably all these changes should be applied to gcc 2.95 as well (less the options it doesn't support). I'll look at that shortly.
comment:12 by , 9 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
comment:13 by , 9 years ago
FYI, the change to the -shared flag being passed onto ld
has broken Haiku's TLS support when building gcc4 on Haiku.
As a result of the changes, gcc generates R_386_TLS_TPOFF32 relocations in the configure test for TLS, instead of previously R_386_TLS_DTPMOD32 & R_386_TLS_DTPOFF32. Currently, runtime_loader doesn't support R_386_TLS_TPOFF32 relocations. Due to the failed test, libstdc++.so generates different symbols (e.g. no std::__once_call
), which breaks apps that use TLS (WebPositive being one).
Example test:
__thread int a; int b; int main() { return a = b; }
My only change to gcc/config/i386/haiku.h: s/%{shared:-shared;/%{!r:-shared;/
which was enough to make TLS support work again, but obviously isn't ideal.
follow-up: 15 comment:14 by , 9 years ago
If you'd like to open a new ticket, Jessica, assign it to me and I will find a solution for this.
comment:15 by , 9 years ago
Replying to simonsouth:
If you'd like to open a new ticket, Jessica, assign it to me and I will find a solution for this.
See #12451.
comment:16 by , 9 years ago
Some commentary from pdziepak on IRC, that you might also find useful:
well, there is more to be done before we can say the we support position dependent executables currently kernel first loads runtime_loader and then runtime_loader loads the executable itself that's unusual order and will have to be changed because we need to guarantee that there is no address conflict between runtime_loader and the executable (well, we can guarantee that on x64 if we limit our support to memory model small, for instance, but the change is needed for 32bit anyway)
Change gcc configuration to allow non-PI executables to be created