[Bug driver/88262] gcc uses crt1.o in place of Scrt1.o when the main function is in a PIC shared lib
stephen.kim at oracle dot com
gcc-bugzilla@gcc.gnu.org
Thu Dec 20 03:28:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88262
--- Comment #16 from Stephen Kim <stephen.kim at oracle dot com> ---
(In reply to Andrew Pinski from comment #15)
> Let's start over. crt1.o in glibc should support calling main that is
> located in the shared library.
> If it does not then there is a bug there.
>
Sorry. I got notice this comment a bit late.
Firstly, the glibc commit I posted was not correct. It seems like this commit:
6cd380dd366d728da9f579eeb9f7f4c47f48e474
It does not. Nonetheless, a glibc maintainer, Siddhesh Poyarekar, told me that
it is NOT a glibc bug. I am not a glibc expert, so I did not find a reason that
I should not believe Siddhesh regarding glibc.
> Can you explain why you think crt1.o is broken that it can't be used for
> that purpose?
>
If I manually link with Scrt1.0, it works. I firstly used -Wl,-v option to see
what options are passed to Gold. Then, I just change crt1.o with Scrt1.o, which
works. Running the generate executable does not cause a segmentation fault as
the address of main is correctly found in the _start function. However, I am
not sure whether we could call it "broken crt1.o." The glibc maintainer and
also Ian Lance Taylor--the Gold developer--believed that Scrt1.o should be
given.
> Also you pointed to a commit which you said changed the behavior in glibc
> but the commit you pointed to only changes dates and nothing more. Can you
> point to the commit which changed the behavior in glibc which caused this
> not to work any more?
>
I am not a glibc expert, so I am not sure about the details. I found three
commits that updated start.S probably with regard to my issue.
Here is the commit message:
AArch64: use movz/movk instead of literal pools in start.S
eXecute-Only Memory (XOM) is a protection mechanism against some ROP
attacks. XOM sets the code as executable and unreadable, so the access
to any data, like literal pools, in the code section causes the fault
with XOM. The compiler can disable literal pools for C source files,
but not for assembly files, so I use movz/movk instead of literal pools
in start.S for XOM.
I add MOVL macro with movz/movk instructions like movl pseudo-instruction
in armasm, and use the macro instead of literal pools.
* sysdeps/aarch64/start.S: Use MOVL instead of literal pools.
* sysdeps/aarch64/sysdep.h (MOVL): Add MOVL macro.
Since then, there have been multiple commits that change start.S regarding the
problem:
commit 3d1d79283e6de4f7c434cb67fb53a4fd28359669
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date: Tue Dec 19 18:43:04 2017 +0000
aarch64: fix static pie enabled libc when main is in a shared library
In the static pie enabled libc, crt1.o uses the same position independent
code as rcrt1.o and crt1.o is used instead of Scrt1.o when -no-pie
executables are linked. When main is not defined in the executable, but
in a shared library crt1.o is currently broken, it assumes main is local.
(glibc has a test for this but i missed it in my previous testing.)
To make both rcrt1.o and crt1.o happy with the same code, a wrapper is
introduced around main: with this crt1.o works with extern main symbol
while rcrt1.o does not depend on GOT relocations. (The change only
affects static pie enabled libc. Further simplification of start.S is
possible in the future by using the same approach for Scrt1.o too.)
* aarch64/start.S (_start): Use __wrap_main.
(__wrap_main): New local symbol.
commit 14d886edbd3d80b771e1c42fbd9217f9074de9c6
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date: Fri Nov 17 10:45:32 2017 +0000
aarch64: fix start code for static pie
There are three flavors of the crt startup code:
1) crt1.o used for non-pie,
2) Scrt1.o used for dynamic linked pie (dynamic linker relocates),
3) rcrt1.o used for static linked pie (self relocation is needed)
In the --enable-static-pie case crt1.o is built with -DPIC and in case
of static linking it interposes _dl_relocate_static_pie in libc to
avoid self relocation.
Scrt1.o is built with -DPIC -DSHARED and it relies on GOT entries that
the static linker cannot relax and thus need relocation before the
start code is executed, so rcrt1.o needs separate implementation.
This implementation does not work for .text > 4G position independent
executables, which is fine since the toolchain does not support
-mcmodel=large with -fPIE.
Tests pass with ld/22269 and ld/22263 binutils bugs fixed.
* sysdeps/aarch64/start.S (_start): Handle PIC && !SHARED case.
commit 6cd380dd366d728da9f579eeb9f7f4c47f48e474 (thecommit2)
Author: Wang Boshi <wangboshi@huawei.com>
Date: Fri Sep 15 17:53:23 2017 +0100
AArch64: use movz/movk instead of literal pools in start.S
eXecute-Only Memory (XOM) is a protection mechanism against some ROP
attacks. XOM sets the code as executable and unreadable, so the access
to any data, like literal pools, in the code section causes the fault
with XOM. The compiler can disable literal pools for C source files,
but not for assembly files, so I use movz/movk instead of literal pools
in start.S for XOM.
I add MOVL macro with movz/movk instructions like movl pseudo-instruction
in armasm, and use the macro instead of literal pools.
* sysdeps/aarch64/start.S: Use MOVL instead of literal pools.
* sysdeps/aarch64/sysdep.h (MOVL): Add MOVL macro.
> We can forward from there with those two.
More information about the Gcc-bugs
mailing list