aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog24
-rw-r--r--ld/NEWS6
-rw-r--r--ld/emultempl/elf32.em32
-rwxr-xr-xld/genscripts.sh44
-rw-r--r--ld/ld.texinfo6
-rw-r--r--ld/ldint.texinfo22
-rw-r--r--ld/ldmain.c2
-rw-r--r--ld/lexsup.c6
-rw-r--r--ld/scripttempl/elf.sc27
9 files changed, 157 insertions, 12 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index b4a1302..c29a986 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,27 @@
+2001-08-23 Jakub Jelinek <jakub@redhat.com>
+
+ * emultempl/elf32.em (place_orphan): Place orphan .rel* sections
+ into .rel.dyn resp. .rela.dyn if combreloc.
+ (get_script): If .x linker script is equal to .xn, only put it
+ once into the binary.
+ Add .xc and .xsc scripts.
+ (parse_args): Handle -z combreloc and -z nocombreloc.
+ * scripttempl/elf.sc (.rela.sbss): Fix a typo.
+ For .xc and .xsc scripts put all .rel* or .rela* input sections
+ but .rel*.plt and PLT-like sections into .rel.dyn resp. .rela.dyn.
+ * genscripts.sh (GENERATE_COMBRELOC_SCRIPT): Set if SCRIPT_NAME
+ is elf.
+ Strip trailing whitespace from script.
+ Generate .xc and .xsc scripts if requested.
+ * ldmain.c (main): Initialize link_info.combreloc and
+ link_info.spare_dynamic_tags.
+ * lexsup.c (OPTION_SPARE_DYNAMIC_TAGS): Define.
+ (ld_options): Add --spare-dynamic-tags option.
+ (parse_args): Likewise.
+ * ld.texinfo: Document -z combreloc and -z nocombreloc.
+ * ldint.texinfo: Document .xc and .xsc linker scripts.
+ * NEWS: Add notes about -z combreloc and SHF_MERGE.
+
2001-08-22 H.J. Lu <hjl@gnu.org>
* emulparams/elf32fr30.sh: Add a newline.
diff --git a/ld/NEWS b/ld/NEWS
index f1e7ece..27dc891 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,11 @@
-*- text -*-
+* Support for -z combreloc in the ELF linker, which puts dynamic
+ relocations against the same symbol together, so that dynamic linker
+ can use an one-entry symbol lookup cache.
+
+* Support for ELF SHF_MERGE section merging, by Jakub Jelinek.
+
* Support for AMD x86-64 architecture, by Jan Hubicka, SuSE Labs.
* Support added for eliminating duplicate DWARF2 debug information by
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 93dc739..0e5cd99 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1135,7 +1135,25 @@ gld${EMULATION_NAME}_place_orphan (file, s)
else if (strncmp (secname, ".rel", 4) == 0
&& (hold_rel.os != NULL
|| (hold_rel.os = output_rel_find ()) != NULL))
- place = &hold_rel;
+ {
+ if (! link_info.relocateable && link_info.combreloc)
+ {
+ if (strncmp (secname, ".rela", 5) == 0)
+ os = lang_output_section_find (".rela.dyn");
+ else
+ os = lang_output_section_find (".rel.dyn");
+
+ if (os != NULL
+ && os->bfd_section != NULL
+ && ((s->flags ^ os->bfd_section->flags)
+ & (SEC_LOAD | SEC_ALLOC)) == 0)
+ {
+ lang_add_section (&os->children, s, os, file);
+ return true;
+ }
+ }
+ place = &hold_rel;
+ }
else if ((s->flags & (SEC_CODE | SEC_READONLY)) == SEC_READONLY
&& HAVE_SECTION (hold_rodata, ".rodata"))
place = &hold_rodata;
@@ -1332,14 +1350,18 @@ echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}
sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
+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_SHLIB_SCRIPT" ; then
+echo ' ; else if (link_info.shared && link_info.combreloc) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xsc >> e${EMULATION_NAME}.c
echo ' ; else if (link_info.shared) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c
fi
-
+echo ' ; else if (link_info.combreloc) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xc >> e${EMULATION_NAME}.c
echo ' ; else return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
echo '; }' >> e${EMULATION_NAME}.c
@@ -1492,6 +1514,10 @@ cat >>e${EMULATION_NAME}.c <<EOF
}
else if (strcmp (optarg, "defs") == 0)
link_info.no_undefined = true;
+ else if (strcmp (optarg, "combreloc") == 0)
+ link_info.combreloc = true;
+ else if (strcmp (optarg, "nocombreloc") == 0)
+ link_info.combreloc = false;
/* What about the other Solaris -z options? FIXME. */
break;
EOF
diff --git a/ld/genscripts.sh b/ld/genscripts.sh
index d3ab768..f169132 100755
--- a/ld/genscripts.sh
+++ b/ld/genscripts.sh
@@ -84,6 +84,17 @@ LIB_SEARCH_DIRS=`echo ${LIB_PATH} | tr ':' ' ' | sed -e 's/\([^ ][^ ]*\)/SEARCH_
# A .xs script is for generating a shared library with the --shared
# flag; it is only generated if $GENERATE_SHLIB_SCRIPT is set by the
# emulation parameters.
+# A .xc script is for linking with -z combreloc; it is only generated if
+# $GENERATE_COMBRELOC_SCRIPT is set by the emulation parameters or
+# $SCRIPT_NAME is "elf".
+# A .xsc script is for linking with --shared -z combreloc; it is generated
+# if $GENERATE_COMBRELOC_SCRIPT is set by the emulation parameters or
+# $SCRIPT_NAME is "elf" and $GENERATE_SHLIB_SCRIPT is set by the emulation
+# parameters too.
+
+if [ "x$SCRIPT_NAME" = "xelf" ]; then
+ GENERATE_COMBRELOC_SCRIPT=yes
+fi
SEGMENT_SIZE=${SEGMENT_SIZE-${TARGET_PAGE_SIZE}}
@@ -101,34 +112,45 @@ DATA_ALIGNMENT=${DATA_ALIGNMENT_r}
DEFAULT_DATA_ALIGNMENT="ALIGN(${SEGMENT_SIZE})"
( . ${srcdir}/emulparams/${EMULATION_NAME}.sh
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
-) | sed -e '/^ *$/d' > ldscripts/${EMULATION_NAME}.xr
+) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xr
LD_FLAG=u
DATA_ALIGNMENT=${DATA_ALIGNMENT_u}
CONSTRUCTING=" "
( . ${srcdir}/emulparams/${EMULATION_NAME}.sh
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
-) | sed -e '/^ *$/d' > ldscripts/${EMULATION_NAME}.xu
+) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xu
LD_FLAG=
DATA_ALIGNMENT=${DATA_ALIGNMENT_}
RELOCATING=" "
( . ${srcdir}/emulparams/${EMULATION_NAME}.sh
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
-) | sed -e '/^ *$/d' > ldscripts/${EMULATION_NAME}.x
+) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.x
LD_FLAG=n
DATA_ALIGNMENT=${DATA_ALIGNMENT_n}
TEXT_START_ADDR=${NONPAGED_TEXT_START_ADDR-${TEXT_START_ADDR}}
( . ${srcdir}/emulparams/${EMULATION_NAME}.sh
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
-) | sed -e '/^ *$/d' > ldscripts/${EMULATION_NAME}.xn
+) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xn
LD_FLAG=N
DATA_ALIGNMENT=${DATA_ALIGNMENT_N}
( . ${srcdir}/emulparams/${EMULATION_NAME}.sh
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
-) | sed -e '/^ *$/d' > ldscripts/${EMULATION_NAME}.xbn
+) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xbn
+
+if test -n "$GENERATE_COMBRELOC_SCRIPT"; then
+ DATA_ALIGNMENT=${DATA_ALIGNMENT_c-${DATA_ALIGNMENT_}}
+ LD_FLAG=c
+ COMBRELOC=ldscripts/${EMULATION_NAME}.xc.tmp
+ ( . ${srcdir}/emulparams/${EMULATION_NAME}.sh
+ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xc
+ rm -f ${COMBRELOC}
+ COMBRELOC=
+fi
if test -n "$GENERATE_SHLIB_SCRIPT"; then
LD_FLAG=shared
@@ -137,7 +159,17 @@ if test -n "$GENERATE_SHLIB_SCRIPT"; then
# Note that TEXT_START_ADDR is set to NONPAGED_TEXT_START_ADDR.
( . ${srcdir}/emulparams/${EMULATION_NAME}.sh
. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
- ) | sed -e '/^ *$/d' > ldscripts/${EMULATION_NAME}.xs
+ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xs
+ if test -n "$GENERATE_COMBRELOC_SCRIPT"; then
+ LD_FLAG=cshared
+ DATA_ALIGNMENT=${DATA_ALIGNMENT_sc-${DATA_ALIGNMENT}}
+ COMBRELOC=ldscripts/${EMULATION_NAME}.xc.tmp
+ ( . ${srcdir}/emulparams/${EMULATION_NAME}.sh
+ . ${srcdir}/scripttempl/${SCRIPT_NAME}.sc
+ ) | sed -e '/^ *$/d;s/[ ]*$//' > ldscripts/${EMULATION_NAME}.xsc
+ rm -f ${COMBRELOC}
+ COMBRELOC=
+ fi
fi
for i in $EMULATION_LIBPATH ; do
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 95785e0..5bc0a30 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -840,7 +840,8 @@ for Solaris compatibility.
@item -z @var{keyword}
The recognized keywords are @code{initfirst}, @code{interpose},
@code{loadfltr}, @code{nodefaultlib}, @code{nodelete}, @code{nodlopen},
-@code{nodump}, @code{now} and @code{origin}. The other keywords are
+@code{nodump}, @code{now}, @code{origin}, @code{combreloc} and
+@code{nocombreloc}. The other keywords are
ignored for Solaris compatibility. @code{initfirst} marks the object
to be initialized first at runtime before any other objects.
@code{interpose} marks the object that its symbol table interposes
@@ -854,6 +855,9 @@ of this object will ignore any default library search paths.
@code{now} marks the object with the non-lazy runtime binding.
@code{origin} marks the object may contain $ORIGIN.
@code{defs} disallows undefined symbols.
+@code{combreloc} combines multiple reloc sections and sorts them
+to make dynamic symbol lookup caching possible.
+@code{nocombreloc} disables multiple reloc sections combining.
@kindex -(
@cindex groups of archives
diff --git a/ld/ldint.texinfo b/ld/ldint.texinfo
index 47a9817..489750a 100644
--- a/ld/ldint.texinfo
+++ b/ld/ldint.texinfo
@@ -239,7 +239,7 @@ If @code{SCRIPT_NAME} is set to @var{script}, @code{genscripts.sh} will
invoke @file{scripttempl/@var{script}.sc}.
The @file{genscripts.sh} script will invoke the @file{scripttempl}
-script 5 or 6 times. Each time it will set the shell variable
+script 5 to 8 times. Each time it will set the shell variable
@code{LD_FLAG} to a different value. When the linker is run, the
options used will direct it to select a particular script. (Script
selection is controlled by the @code{get_script} emulation entry point;
@@ -278,6 +278,22 @@ this value if @code{GENERATE_SHLIB_SCRIPT} is defined in the
this script at the appropriate time, normally when the linker is invoked
with the @code{-shared} option. The output has an extension of
@file{.xs}.
+@item c
+The @file{scripttempl} script is only invoked with @code{LD_FLAG} set to
+this value if @code{GENERATE_COMBRELOC_SCRIPT} is defined in the
+@file{emulparams} file or if @code{SCRIPT_NAME} is @code{elf}. The
+@file{emultempl} script must arrange to use this script at the appropriate
+time, normally when the linker is invoked with the @code{-z combreloc}
+option. The output has an extension of
+@file{.xc}.
+@item cshared
+The @file{scripttempl} script is only invoked with @code{LD_FLAG} set to
+this value if @code{GENERATE_COMBRELOC_SCRIPT} is defined in the
+@file{emulparams} file or if @code{SCRIPT_NAME} is @code{elf} and
+@code{GENERATE_SHLIB_SCRIPT} is defined in the @file{emulparms} file.
+The @file{emultempl} script must arrange to use this script at the
+appropriate time, normally when the linker is invoked with the @code{-shared
+-z combreloc} option. The output has an extension of @file{.xsc}.
@end table
Besides the shell variables set by the @file{emulparams} script, and the
@@ -301,6 +317,10 @@ page aligned, or to @samp{.} when generating the @code{-N} script.
@item CREATE_SHLIB
This will be set to a non-empty string when generating a @code{-shared}
script.
+
+@item COMBRELOC
+This will be set to a non-empty string when generating @code{-z combreloc}
+scripts to a temporary file name which can be used during script generation.
@end table
The conventional way to write a @file{scripttempl} script is to first
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 0ec7891..b7114f9 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -244,6 +244,8 @@ main (argc, argv)
link_info.flags = (bfd_vma) 0;
link_info.flags_1 = (bfd_vma) 0;
link_info.pei386_auto_import = false;
+ link_info.combreloc = false;
+ link_info.spare_dynamic_tags = 5;
ldfile_add_arch ("");
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 7e23a7d..5183b86 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -131,6 +131,7 @@ int parsing_defsym = 0;
#define OPTION_TARGET_HELP (OPTION_UNIQUE + 1)
#define OPTION_ALLOW_SHLIB_UNDEFINED (OPTION_TARGET_HELP + 1)
#define OPTION_DISCARD_NONE (OPTION_ALLOW_SHLIB_UNDEFINED + 1)
+#define OPTION_SPARE_DYNAMIC_TAGS (OPTION_DISCARD_NONE + 1)
/* The long options. This structure is used for both the option
parsing and the help text. */
@@ -347,6 +348,8 @@ static const struct ld_option ld_options[] =
'\0', NULL, N_("Sort common symbols by size"), TWO_DASHES },
{ {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
'\0', NULL, NULL, NO_HELP },
+ { {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_DYNAMIC_TAGS},
+ '\0', N_("COUNT"), N_("How many tags to reserve in .dynamic section"), TWO_DASHES },
{ {"split-by-file", optional_argument, NULL, OPTION_SPLIT_BY_FILE},
'\0', N_("[=SIZE]"), N_("Split output sections every SIZE octets"), TWO_DASHES },
{ {"split-by-reloc", optional_argument, NULL, OPTION_SPLIT_BY_RELOC},
@@ -1073,6 +1076,9 @@ the GNU General Public License. This program has absolutely no warranty.\n"));
case 'y':
add_ysym (optarg);
break;
+ case OPTION_SPARE_DYNAMIC_TAGS:
+ link_info.spare_dynamic_tags = strtoul (optarg, NULL, 0);
+ break;
case OPTION_SPLIT_BY_RELOC:
if (optarg != NULL)
config.split_by_reloc = strtoul (optarg, NULL, 0);
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
index 84630bd..8ccf803 100644
--- a/ld/scripttempl/elf.sc
+++ b/ld/scripttempl/elf.sc
@@ -145,6 +145,13 @@ SECTIONS
.gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) }
.gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) }
+EOF
+if [ "x$COMBRELOC" = x ]; then
+ COMBRELOCCAT=cat
+else
+ COMBRELOCCAT="cat > $COMBRELOC"
+fi
+eval $COMBRELOCCAT <<EOF
.rel.init ${RELOCATING-0} : { *(.rel.init) }
.rela.init ${RELOCATING-0} : { *(.rela.init) }
.rel.text ${RELOCATING-0} :
@@ -215,7 +222,7 @@ SECTIONS
{
*(.rela.sbss)
${RELOCATING+*(.rela.sbss.*)}
- ${RELOCATING+*(.rel.gnu.linkonce.sb.*)}
+ ${RELOCATING+*(.rela.gnu.linkonce.sb.*)}
}
.rel.sdata2 ${RELOCATING-0} :
{
@@ -253,6 +260,24 @@ SECTIONS
${RELOCATING+*(.rela.bss.*)}
${RELOCATING+*(.rela.gnu.linkonce.b.*)}
}
+EOF
+if [ -n "$COMBRELOC" ]; then
+cat <<EOF
+ .rel.dyn :
+ {
+EOF
+sed -e '/^[ ]*[{}][ ]*$/d;/:[ ]*$/d;/\.rela\./d;s/^.*: { *\(.*\)}$/ \1/' $COMBRELOC
+cat <<EOF
+ }
+ .rela.dyn :
+ {
+EOF
+sed -e '/^[ ]*[{}][ ]*$/d;/:[ ]*$/d;/\.rel\./d;s/^.*: { *\(.*\)}/ \1/' $COMBRELOC
+cat <<EOF
+ }
+EOF
+fi
+cat <<EOF
.rel.plt ${RELOCATING-0} : { *(.rel.plt) }
.rela.plt ${RELOCATING-0} : { *(.rela.plt) }
${OTHER_PLT_RELOC_SECTIONS}