diff options
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 27 | ||||
-rw-r--r-- | ld/emulparams/elf32_sparc.sh | 1 | ||||
-rw-r--r-- | ld/emulparams/elf32ppc.sh | 1 | ||||
-rw-r--r-- | ld/emulparams/elf64_ia64.sh | 1 | ||||
-rw-r--r-- | ld/emulparams/elf64_s390.sh | 1 | ||||
-rw-r--r-- | ld/emulparams/elf64_sparc.sh | 1 | ||||
-rw-r--r-- | ld/emulparams/elf64alpha.sh | 1 | ||||
-rw-r--r-- | ld/emulparams/elf64ppc.sh | 1 | ||||
-rw-r--r-- | ld/emulparams/elf_i386.sh | 1 | ||||
-rw-r--r-- | ld/emulparams/elf_s390.sh | 1 | ||||
-rw-r--r-- | ld/emulparams/elf_x86_64.sh | 1 | ||||
-rw-r--r-- | ld/emultempl/elf32.em | 24 | ||||
-rwxr-xr-x | ld/genscripts.sh | 25 | ||||
-rw-r--r-- | ld/ld.texinfo | 12 | ||||
-rw-r--r-- | ld/ldmain.c | 5 | ||||
-rw-r--r-- | ld/lexsup.c | 14 | ||||
-rw-r--r-- | ld/scripttempl/elf.sc | 3 |
17 files changed, 117 insertions, 3 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 52620ac..bfd7846 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,30 @@ +2003-05-30 Ulrich Drepper <drepper@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + * lexsup.c (OPTION_PIE): Define. + (ld_options): Add -pie and --pic-executable options. + (parse_args): Handle OPTION_PIE. + * ldmain.c (main): Initialize link_info.pie and + link_info.executable. + * genscripts.sh: Generate PIE scripts. + * ld.texinfo: Document -pie and --pic-executable options. + * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): + (gld${EMULATION_NAME}_place_orphan): Likewise. + (gld${EMULATION_NAME}_get_script): Include PIE scripts. + * scripttempl/elf.sc: In PIE scripts set . the same way as in + shared scripts. + * emulparams/elf_i386.sh (GENERATE_PIE_SCRIPT): Set to yes. + * emulparams/elf64_ia64.sh (GENERATE_PIE_SCRIPT): Likewise. + * emulparams/elf32ppc.sh (GENERATE_PIE_SCRIPT): Likewise. + * emulparams/elf64ppc.sh (GENERATE_PIE_SCRIPT): Likewise. + * emulparams/elf_x86_64.sh (GENERATE_PIE_SCRIPT): Likewise. + * emulparams/elf_s390.sh (GENERATE_PIE_SCRIPT): Likewise. + * emulparams/elf32_sparc.sh (GENERATE_PIE_SCRIPT): Likewise. + * emulparams/elf64_sparc.sh (GENERATE_PIE_SCRIPT): Likewise. + * emulparams/elf64alpha.sh (GENERATE_PIE_SCRIPT): Likewise. + * emulparams/elf64_s390.sh (GENERATE_PIE_SCRIPT): Likewise. + * emulparams/elf_i386.sh (GENERATE_PIE_SCRIPT): Likewise. + 2003-05-30 H.J. Lu <hongjiu.lu@intel.com> * genscripts.sh: Create tmpdir/libpath.exp. diff --git a/ld/emulparams/elf32_sparc.sh b/ld/emulparams/elf32_sparc.sh index 15a837d..af23252 100644 --- a/ld/emulparams/elf32_sparc.sh +++ b/ld/emulparams/elf32_sparc.sh @@ -10,4 +10,5 @@ MACHINE= TEMPLATE_NAME=elf32 DATA_PLT= GENERATE_SHLIB_SCRIPT=yes +GENERATE_PIE_SCRIPT=yes NO_SMALL_DATA=yes diff --git a/ld/emulparams/elf32ppc.sh b/ld/emulparams/elf32ppc.sh index d2d7041..ea05454 100644 --- a/ld/emulparams/elf32ppc.sh +++ b/ld/emulparams/elf32ppc.sh @@ -4,6 +4,7 @@ TEMPLATE_NAME=elf32 EXTRA_EM_FILE=ppc32elf GENERATE_SHLIB_SCRIPT=yes +GENERATE_PIE_SCRIPT=yes SCRIPT_NAME=elf OUTPUT_FORMAT="elf32-powerpc" TEXT_START_ADDR=0x01800000 diff --git a/ld/emulparams/elf64_ia64.sh b/ld/emulparams/elf64_ia64.sh index 817c50a..85ffe61 100644 --- a/ld/emulparams/elf64_ia64.sh +++ b/ld/emulparams/elf64_ia64.sh @@ -16,6 +16,7 @@ fi TEXT_START_ADDR="0x4000000000000000" DATA_ADDR="0x6000000000000000 + (. & (${MAXPAGESIZE} - 1))" GENERATE_SHLIB_SCRIPT=yes +GENERATE_PIE_SCRIPT=yes NOP=0x00300000010070000002000001000400 # a bundle full of nops OTHER_GOT_SECTIONS=" .IA_64.pltoff ${RELOCATING-0} : { *(.IA_64.pltoff) }" diff --git a/ld/emulparams/elf64_s390.sh b/ld/emulparams/elf64_s390.sh index e441b8a..233eb98 100644 --- a/ld/emulparams/elf64_s390.sh +++ b/ld/emulparams/elf64_s390.sh @@ -9,6 +9,7 @@ MACHINE= NOP=0x07070707 TEMPLATE_NAME=elf32 GENERATE_SHLIB_SCRIPT=yes +GENERATE_PIE_SCRIPT=yes # Treat a host that matches the target with the possible exception of "x" # in the name as if it were native. diff --git a/ld/emulparams/elf64_sparc.sh b/ld/emulparams/elf64_sparc.sh index ab3eec0..0c0f5d8 100644 --- a/ld/emulparams/elf64_sparc.sh +++ b/ld/emulparams/elf64_sparc.sh @@ -8,6 +8,7 @@ ARCH="sparc:v9" MACHINE= DATA_PLT= GENERATE_SHLIB_SCRIPT=yes +GENERATE_PIE_SCRIPT=yes NOP=0x01000000 NO_SMALL_DATA=yes diff --git a/ld/emulparams/elf64alpha.sh b/ld/emulparams/elf64alpha.sh index 2d16e9c..093c8df 100644 --- a/ld/emulparams/elf64alpha.sh +++ b/ld/emulparams/elf64alpha.sh @@ -11,6 +11,7 @@ NONPAGED_TEXT_START_ADDR="0x120000000" ARCH=alpha MACHINE= GENERATE_SHLIB_SCRIPT=yes +GENERATE_PIE_SCRIPT=yes DATA_PLT= # Note that the number is always big-endian, thus we have to # reverse the digit string. diff --git a/ld/emulparams/elf64ppc.sh b/ld/emulparams/elf64ppc.sh index 300b8d4..236b26b 100644 --- a/ld/emulparams/elf64ppc.sh +++ b/ld/emulparams/elf64ppc.sh @@ -2,6 +2,7 @@ TEMPLATE_NAME=elf32 EXTRA_EM_FILE=ppc64elf ELFSIZE=64 GENERATE_SHLIB_SCRIPT=yes +GENERATE_PIE_SCRIPT=yes SCRIPT_NAME=elf OUTPUT_FORMAT="elf64-powerpc" TEXT_START_ADDR=0x10000000 diff --git a/ld/emulparams/elf_i386.sh b/ld/emulparams/elf_i386.sh index f1b8522..2382286 100644 --- a/ld/emulparams/elf_i386.sh +++ b/ld/emulparams/elf_i386.sh @@ -9,4 +9,5 @@ MACHINE= NOP=0x90909090 TEMPLATE_NAME=elf32 GENERATE_SHLIB_SCRIPT=yes +GENERATE_PIE_SCRIPT=yes NO_SMALL_DATA=yes diff --git a/ld/emulparams/elf_s390.sh b/ld/emulparams/elf_s390.sh index 2804ace..3b51bb2 100644 --- a/ld/emulparams/elf_s390.sh +++ b/ld/emulparams/elf_s390.sh @@ -8,3 +8,4 @@ MACHINE= NOP=0x07070707 TEMPLATE_NAME=elf32 GENERATE_SHLIB_SCRIPT=yes +GENERATE_PIE_SCRIPT=yes diff --git a/ld/emulparams/elf_x86_64.sh b/ld/emulparams/elf_x86_64.sh index 61e8f29..6d37058 100644 --- a/ld/emulparams/elf_x86_64.sh +++ b/ld/emulparams/elf_x86_64.sh @@ -10,6 +10,7 @@ MACHINE= NOP=0x90909090 TEMPLATE_NAME=elf32 GENERATE_SHLIB_SCRIPT=yes +GENERATE_PIE_SCRIPT=yes NO_SMALL_DATA=yes if [ "x${host}" = "x${target}" ]; then diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 8d863ee..11668fd 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -643,7 +643,7 @@ gld${EMULATION_NAME}_after_open () struct bfd_link_needed_list *needed, *l; /* We only need to worry about this when doing a final link. */ - if (link_info.relocateable || link_info.shared) + if (link_info.relocateable || !link_info.executable) return; /* Get the list of files which appear in DT_NEEDED entries in @@ -1180,7 +1180,7 @@ gld${EMULATION_NAME}_place_orphan (file, s) /* If this is a final link, then always put .gnu.warning.SYMBOL sections into the .text section to get them out of the way. */ - if (! link_info.shared + if (link_info.executable && ! link_info.relocateable && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0 && hold_text.os != NULL) @@ -1474,6 +1474,14 @@ if cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then : ; echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c fi +if test -n "$GENERATE_PIE_SCRIPT" ; then +if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then +echo ' ; else if (link_info.pie && link_info.combreloc) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xdc >> e${EMULATION_NAME}.c +fi +echo ' ; else if (link_info.pie) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xd >> e${EMULATION_NAME}.c +fi if test -n "$GENERATE_SHLIB_SCRIPT" ; then if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then echo ' ; else if (link_info.shared && link_info.combreloc) return' >> e${EMULATION_NAME}.c @@ -1511,6 +1519,18 @@ cat >>e${EMULATION_NAME}.c <<EOF return "ldscripts/${EMULATION_NAME}.xn"; EOF fi +if test -n "$GENERATE_PIE_SCRIPT" ; then +if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then +cat >>e${EMULATION_NAME}.c <<EOF + else if (link_info.pie && link_info.combreloc) + return "ldscripts/${EMULATION_NAME}.xdc"; +EOF +fi +cat >>e${EMULATION_NAME}.c <<EOF + else if (link_info.pie) + return "ldscripts/${EMULATION_NAME}.xd"; +EOF +fi if test -n "$GENERATE_SHLIB_SCRIPT" ; then if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then cat >>e${EMULATION_NAME}.c <<EOF diff --git a/ld/genscripts.sh b/ld/genscripts.sh index fdfc37d..dce4136 100755 --- a/ld/genscripts.sh +++ b/ld/genscripts.sh @@ -236,6 +236,31 @@ if test -n "$GENERATE_SHLIB_SCRIPT"; then rm -f ${COMBRELOC} COMBRELOC= fi + unset CREATE_SHLIB +fi + +if test -n "$GENERATE_PIE_SCRIPT"; then + LD_FLAG=pie + DATA_ALIGNMENT=${DATA_ALIGNMENT_s-${DATA_ALIGNMENT_}} + CREATE_PIE=" " + # Note that TEXT_START_ADDR is set to NONPAGED_TEXT_START_ADDR. + ( + echo "/* Script for ld -pie: link position independent executable */" + . ${srcdir}/emulparams/${EMULATION_NAME}.sh + . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc + ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xd + if test -n "$GENERATE_COMBRELOC_SCRIPT"; then + LD_FLAG=cpie + DATA_ALIGNMENT=${DATA_ALIGNMENT_sc-${DATA_ALIGNMENT}} + COMBRELOC=ldscripts/${EMULATION_NAME}.xc.tmp + ( echo "/* Script for -pie -z combreloc: position independent executable, combine & sort relocs */" + . ${srcdir}/emulparams/${EMULATION_NAME}.sh + . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc + ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xdc + rm -f ${COMBRELOC} + COMBRELOC= + fi + unset CREATE_PIE fi case " $EMULATION_LIBPATH " in diff --git a/ld/ld.texinfo b/ld/ld.texinfo index cfebf09..d6e6220 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -1209,6 +1209,18 @@ command @code{OUTPUT_FORMAT} can also specify the output format, but this option overrides it. @xref{BFD}. @end ifclear +@kindex -pie +@kindex --pic-executable +@item -pie +@itemx --pic-executable +@cindex position independent executables +Create a position independent executable. This is currently only supported on +ELF platforms. Position independent executables are similar to shared +libraries in that they are relocated by the dynamic linker to the virtual +address OS chooses for them (which can varry between invocations), like +normal dynamically linked executables they can be executed and symbols +defined in the executable cannot be overridden by shared libraries. + @kindex -qmagic @item -qmagic This option is ignored for Linux compatibility. diff --git a/ld/ldmain.c b/ld/ldmain.c index 91818e0..08a0ec4 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -291,6 +291,8 @@ main (argc, argv) link_info.emitrelocations = FALSE; link_info.task_link = FALSE; link_info.shared = FALSE; + link_info.pie = FALSE; + link_info.executable = FALSE; link_info.symbolic = FALSE; link_info.export_dynamic = FALSE; link_info.static_link = FALSE; @@ -368,6 +370,9 @@ main (argc, argv) einfo (_("%P%F: -f may not be used without -shared\n")); } + if (! link_info.shared || link_info.pie) + link_info.executable = TRUE; + /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols). I don't see how else this can be handled, since in this case we must preserve all externally visible symbols. */ diff --git a/ld/lexsup.c b/ld/lexsup.c index b2f94f1..8c85807 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -138,6 +138,7 @@ int parsing_defsym = 0; #define OPTION_NO_STRIP_DISCARDED (OPTION_STRIP_DISCARDED + 1) #define OPTION_ACCEPT_UNKNOWN_INPUT_ARCH (OPTION_NO_STRIP_DISCARDED + 1) #define OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH (OPTION_ACCEPT_UNKNOWN_INPUT_ARCH + 1) +#define OPTION_PIE (OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH + 1) /* The long options. This structure is used for both the option parsing and the help text. */ @@ -370,6 +371,10 @@ static const struct ld_option ld_options[] = '\0', NULL, N_("Create a shared library"), ONE_DASH }, { {"Bshareable", no_argument, NULL, OPTION_SHARED }, /* FreeBSD. */ '\0', NULL, NULL, ONE_DASH }, + { {"pie", no_argument, NULL, OPTION_PIE}, + '\0', NULL, N_("Create a position independent executable"), ONE_DASH }, + { {"pic-executable", no_argument, NULL, OPTION_PIE}, + '\0', NULL, NULL, TWO_DASHES }, { {"sort-common", no_argument, NULL, OPTION_SORT_COMMON}, '\0', NULL, N_("Sort common symbols by size"), TWO_DASHES }, { {"sort_common", no_argument, NULL, OPTION_SORT_COMMON}, @@ -959,6 +964,15 @@ parse_args (argc, argv) else einfo (_("%P%F: -shared not supported\n")); break; + case OPTION_PIE: + if (config.has_shared) + { + link_info.shared = TRUE; + link_info.pie = TRUE; + } + else + einfo (_("%P%F: -pie not supported\n")); + break; case 'h': /* Used on Solaris. */ case OPTION_SONAME: command_line.soname = optarg; diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc index 42d7bda..d4ffcd6 100644 --- a/ld/scripttempl/elf.sc +++ b/ld/scripttempl/elf.sc @@ -180,8 +180,9 @@ ${RELOCATING- /* For some reason, the Solaris linker makes bad executables SECTIONS { /* Read-only sections, merged into text segment: */ - ${CREATE_SHLIB-${RELOCATING+. = ${TEXT_BASE_ADDRESS};}} + ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+. = ${TEXT_BASE_ADDRESS};}}} ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR:-0} + SIZEOF_HEADERS;}} + ${CREATE_PIE+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR:-0} + SIZEOF_HEADERS;}} ${CREATE_SHLIB-${INTERP}} ${INITIAL_READONLY_SECTIONS} ${TEXT_DYNAMIC+${DYNAMIC}} |