On Mon, Aug 17, 2015 at 10:42:56PM -0400, Rich Felker wrote: > On Mon, Aug 17, 2015 at 02:19:34PM -0700, H.J. Lu wrote: > > On Tue, Jun 23, 2015 at 9:18 PM, Rich Felker <dal...@libc.org> wrote: > > > For background on the static PIE model I'm working with, see the > > > following post to the GCC list: > > > > > > https://gcc.gnu.org/ml/gcc/2015-06/msg00008.html > > > > > > So far, I've been prototyping static PIE support by having GCC pass > > > the following options to ld instead of -static -pie: > > > > > > -static -shared -Bsymbolic > > > > > > This partly works, but since ld does not know it's producing a main > > > executable, it misses important details, including the ability to link > > > initial-exec and local-exec model TLS code correctly, as well as > > > various linking optimizations. So I think the right way forward is > > > making ld accept -static and -pie together to do the right thing. > > > > > > In elflink.c, _bfd_elf_link_create_dynamic_sections assumes that > > > executables should always have a .interp section. > > > bfd_elf_size_dynamic_sections asserts this assumption again, and the > > > individual elf??-*.c files also do so in *_elf_size_dynamic_sections > > > where they set a default interpreter. (Is this even useful? Most of > > > the names are out of touch with reality, and GCC always passes an > > > explicit -dynamic-linker anyway, so I think this code should just be > > > removed.) > > > > > > Now I have a working prototype by changing the info->executable > > > condition to info->executable && info->dynamic, and having lexsup.c > > > store the value of input_flags.dynamic in link_info.dynamic after > > > processing the command line, but I'm not sure if this is the right > > > approach. > > > > It is OK to use -static/-Bstatic/-non_shared with -shared and -pie. > > I think you want --no-dynamic-linker. > > I see two overall approaches to making the option to omit .interp: > > 1. In elflink.c, make the creation of the .interp section conditional > on a new field in link_info. > > 2. In ld code (ldlang.c? elf32.em?), check the command line option and > remove the .interp section before it can be processed. > > I think option 1 is a lot cleaner, but it's also going to be a lot > more invasive, because every single target arch (elf32-*.c and > elf64-*.c) has its own ASSERT that the .interp section exists. These > would also need to be updated to either check the new field in > link_info, or to replace the ASSERT with a conditional. > > Before I spend a lot of time implementing one or the other, do you > have any feelings on which way would be appropriate?
I went ahead and did option 1 modulo all the target code except sh which is where I'm testing it. My work-in-progress patch is attached. This is obviously not ready to submit but I would appreciate any feedback that's possible at this stage. Rich
--- binutils-2.25.1.orig/bfd/elf32-sh.c +++ binutils-2.25.1/bfd/elf32-sh.c @@ -3344,7 +3344,7 @@ if (htab->root.dynamic_sections_created) { /* Set the contents of the .interp section to the interpreter. */ - if (info->executable) + if (info->executable && !info->nointerp) { s = bfd_get_linker_section (dynobj, ".interp"); BFD_ASSERT (s != NULL); --- binutils-2.25.1.orig/bfd/elflink.c +++ binutils-2.25.1/bfd/elflink.c @@ -206,7 +206,7 @@ /* A dynamically linked executable has a .interp section, but a shared library does not. */ - if (info->executable) + if (info->executable && !info->nointerp) { s = bfd_make_section_anyway_with_flags (abfd, ".interp", flags | SEC_READONLY); @@ -5620,7 +5620,7 @@ bfd_boolean all_defined; *sinterpptr = bfd_get_linker_section (dynobj, ".interp"); - BFD_ASSERT (*sinterpptr != NULL || !info->executable); + BFD_ASSERT (*sinterpptr != NULL || !info->executable || info->nointerp); if (soname != NULL) { --- binutils-2.25.1.orig/include/bfdlink.h +++ binutils-2.25.1/include/bfdlink.h @@ -426,6 +426,9 @@ /* TRUE if BND prefix in PLT entries is always generated. */ unsigned int bndplt: 1; + /* TRUE if generation of .interp/PT_INTERP should be suppressed. */ + unsigned int nointerp: 1; + /* Char that may appear as the first char of a symbol, but should be skipped (like symbol_leading_char) when looking up symbols in wrap_hash. Used by PowerPC Linux for 'dot' symbols. */ --- binutils-2.25.1.orig/ld/ldlex.h +++ binutils-2.25.1/ld/ldlex.h @@ -33,6 +33,7 @@ OPTION_DEFSYM, OPTION_DEMANGLE, OPTION_DYNAMIC_LINKER, + OPTION_NO_DYNAMIC_LINKER, OPTION_SYSROOT, OPTION_EB, OPTION_EL, --- binutils-2.25.1.orig/ld/lexsup.c +++ binutils-2.25.1/ld/lexsup.c @@ -138,6 +138,9 @@ { {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER}, 'I', N_("PROGRAM"), N_("Set PROGRAM as the dynamic linker to use"), TWO_DASHES }, + { {"no-dynamic-linker", no_argument, NULL, OPTION_NO_DYNAMIC_LINKER}, + '\0', NULL, N_("Produce an executable with no program interpreter header"), + TWO_DASHES }, { {"library", required_argument, NULL, 'l'}, 'l', N_("LIBNAME"), N_("Search for library LIBNAME"), TWO_DASHES }, { {"library-path", required_argument, NULL, 'L'}, @@ -747,6 +750,11 @@ case 'I': /* Used on Solaris. */ case OPTION_DYNAMIC_LINKER: command_line.interpreter = optarg; + link_info.nointerp = 0; + break; + case OPTION_NO_DYNAMIC_LINKER: + command_line.interpreter = NULL; + link_info.nointerp = 1; break; case OPTION_SYSROOT: /* Already handled in ldmain.c. */