|
Message-ID: <20150601212615.GA23542@brightrain.aerifal.cx> Date: Mon, 1 Jun 2015 17:26:15 -0400 From: Rich Felker <dalias@...c.org> To: gcc@....gnu.org Cc: musl@...ts.openwall.com, binutils@...rceware.org Subject: Static PIE support in GCC A feature I've been interested in getting upstream in GCC for a while now is support for producing static-linked PIE executables for Linux. In the model I'm working with, static PIE executables are ET_DYN format with no PT_INTERP, and are intended to contain only relative type relocations (no symbol references). A custom crt1 start file named rcrt1.o is responsible for processing these relative relocations before passing execution to the libc entry point code. I have as part of musl libc an implementation of rcrt1.o (for all targets musl presently supports) that's working for this model. The way it works is completely analogous to what OpenBSD has done in their fork of GCC (see http://www.openbsd.org/papers/asiabsdcon2015-pie-slides.pdf), but aside from adopting the 'r' prefix for crt that they used, which I did for some level of consistency, my work on static PIE has been completely independent of the development of this feature in OpenBSD. While OpenBSD's motivations for static PIE seem to be purely security focused, I'm also interested in static PIE as a form of executable that can be used on NOMMU targets. My motivation for doing the relocations in the start file, rather than with an external program interpreter, is both to reduce runtime cost on very small systems, and to make deployment easier. For musl users, one of the main benefits of static linking is that the resulting binary can be run on systems without any additional runtime files installed. Unfortunately, producing static PIE binaries with GCC is not as simple as passing -static -pie when linking. The linker arguments I've been using to test this so far have been: -shared -Wl,-Bstatic -Wl,-Bsymbolic and adding the rcrt1.o to the beginning of the inputs. This looks like something of a hack, and on the GCC command line I would say it is, at least for -shared which is being used both to suppress the default crt1 file and to produce ET_DYN output without PT_INTERP. On the other hand,-Bstatic is just being used to suppress use of .so files to satisfy -l dependencies, and -Bsymbolic to produce relative relocations in the output instead of symbol references. Thankfully this gets a lot less ugly if you put it in the specs. Just replacing: #define LINK_PIE_SPEC "%{pie:-pie} " with: #define LINK_PIE_SPEC "%{pie:%{static:-shared -Bsymbolic;:-pie}} " causes -static -pie to invoke the linker in a manner which matches the desired static PIE model. Aside from this, a per-target addition to STARTFILE_SPEC is needed to make GCC choose rcrt1.o instead of Scrt1.o when -static is used with -pie, and to change the logic for crtbegin so that -pie's choice of crtbeginS.o overrides -static's crtbeginT.o, and likewise for crtend. Before proposing anything in the way of patches I'd like some feedback on whether this approach is acceptable for upstreaming in GCC. The obvious alternative to the LINK_PIE_SPEC change is making ld accept -static -pie and do "the right thing" on its side, but the startfile changes needed on the GCC side are the same either way. Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.