aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog21
-rw-r--r--ld/Makefile.am5
-rw-r--r--ld/Makefile.in5
-rw-r--r--ld/emulparams/elf32xtensa.sh1
-rw-r--r--ld/emultempl/xtensaelf.em295
-rw-r--r--ld/ld.texinfo69
-rw-r--r--ld/scripttempl/elfxtensa.sc64
-rw-r--r--ld/testsuite/ChangeLog6
-rw-r--r--ld/testsuite/ld-xtensa/coalesce2.s1
-rw-r--r--ld/testsuite/ld-xtensa/lcall1.s4
-rw-r--r--ld/testsuite/ld-xtensa/lcall2.s3
11 files changed, 420 insertions, 54 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 21095bf..2b15726 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,24 @@
+2004-10-07 Bob Wilson <bob.wilson@acm.org>
+
+ * ld.texinfo (Xtensa): Describe new linker relaxation to optimize
+ assembler-generated longcall sequences. Describe new --size-opt
+ option.
+ * emulparams/elf32xtensa.sh (OTHER_SECTIONS): Add .xt.prop section.
+ * emultempl/xtensaelf.em (remove_section,
+ replace_insn_sec_with_prop_sec, replace_instruction_table_sections,
+ elf_xtensa_after_open): New.
+ (OPTION_OPT_SIZEOPT, OPTION_LITERAL_MOVEMENT,
+ OPTION_NO_LITERAL_MOVEMENT): Define.
+ (elf32xtensa_size_opt, elf32xtensa_no_literal_movement): New globals.
+ (PARSE_AND_LIST_LONGOPTS): Add size-opt and [no-]literal-movement.
+ (PARSE_AND_LIST_OPTIONS): Add --size-opt.
+ (PARSE_AND_LIST_ARGS_CASES): Handle OPTION_OPT_SIZEOPT,
+ OPTION_LITERAL_MOVEMENT, and OPTION_NO_LITERAL_MOVEMENT.
+ (LDEMUL_AFTER_OPEN): Set to elf_xtensa_after_open.
+ * scripttempl/elfxtensa.sc: Update with changes from elf.sc.
+ * Makefile.am (eelf32xtensa.c): Update dependencies.
+ * Makefile.in: Regenerate.
+
2004-10-07 Jeff Baker <jbaker@qnx.com>
* lexsup.c: Handle --warn-shared-textrel option.
diff --git a/ld/Makefile.am b/ld/Makefile.am
index 07246b9..5add7ff 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -609,8 +609,9 @@ eelf32vax.c: $(srcdir)/emulparams/elf32vax.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32vax "$(tdir_elf32vax)"
eelf32xtensa.c: $(srcdir)/emulparams/elf32xtensa.sh \
- $(srcdir)/emulparams/xtensa-config.sh \
- $(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/xtensaelf.em \
+ $(srcdir)/emulparams/xtensa-config.sh $(srcdir)/emultempl/elf32.em \
+ $(srcdir)/emultempl/xtensaelf.em $(INCDIR)/xtensa-config.h \
+ $(BFDDIR)/elf-bfd.h $(BFDDIR)/libbfd.h $(INCDIR)/elf/xtensa.h \
$(srcdir)/scripttempl/elfxtensa.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32xtensa "$(tdir_elf32xtensa)"
eelf32fr30.c: $(srcdir)/emulparams/elf32fr30.sh \
diff --git a/ld/Makefile.in b/ld/Makefile.in
index ce98c5b..10a3c9f 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -1346,8 +1346,9 @@ eelf32vax.c: $(srcdir)/emulparams/elf32vax.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32vax "$(tdir_elf32vax)"
eelf32xtensa.c: $(srcdir)/emulparams/elf32xtensa.sh \
- $(srcdir)/emulparams/xtensa-config.sh \
- $(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/xtensaelf.em \
+ $(srcdir)/emulparams/xtensa-config.sh $(srcdir)/emultempl/elf32.em \
+ $(srcdir)/emultempl/xtensaelf.em $(INCDIR)/xtensa-config.h \
+ $(BFDDIR)/elf-bfd.h $(BFDDIR)/libbfd.h $(INCDIR)/elf/xtensa.h \
$(srcdir)/scripttempl/elfxtensa.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32xtensa "$(tdir_elf32xtensa)"
eelf32fr30.c: $(srcdir)/emulparams/elf32fr30.sh \
diff --git a/ld/emulparams/elf32xtensa.sh b/ld/emulparams/elf32xtensa.sh
index 76f9da8..cf456c7 100644
--- a/ld/emulparams/elf32xtensa.sh
+++ b/ld/emulparams/elf32xtensa.sh
@@ -29,4 +29,5 @@ OTHER_READWRITE_SECTIONS="
OTHER_SECTIONS="
.xt.lit 0 : { *(.xt.lit${RELOCATING+ .xt.lit.* .gnu.linkonce.p.*}) }
.xt.insn 0 : { *(.xt.insn${RELOCATING+ .gnu.linkonce.x.*}) }
+ .xt.prop 0 : { *(.xt.prop${RELOCATING+ .gnu.linkonce.prop.*}) }
"
diff --git a/ld/emultempl/xtensaelf.em b/ld/emultempl/xtensaelf.em
index ffd4add..386bf8a 100644
--- a/ld/emultempl/xtensaelf.em
+++ b/ld/emultempl/xtensaelf.em
@@ -25,9 +25,17 @@
cat >>e${EMULATION_NAME}.c <<EOF
#include <xtensa-config.h>
+#include "../bfd/elf-bfd.h"
+#include "../bfd/libbfd.h"
+#include "elf/xtensa.h"
+#include "bfd.h"
static void xtensa_wild_group_interleave (lang_statement_union_type *);
static void xtensa_colocate_output_literals (lang_statement_union_type *);
+static void remove_section (bfd *, asection *);
+static bfd_boolean replace_insn_sec_with_prop_sec (bfd *, const char *,
+ const char *, char **);
+static void replace_instruction_table_sections (bfd *, asection *);
/* Flag for the emulation-specific "--no-relax" option. */
@@ -37,7 +45,7 @@ static bfd_boolean disable_relaxation = FALSE;
static bfd_vma xtensa_page_power = 12; /* 4K pages. */
/* To force a page break between literals and text, change
- xtensa_use_literal_pages to "true". */
+ xtensa_use_literal_pages to "TRUE". */
static bfd_boolean xtensa_use_literal_pages = FALSE;
#define EXTRA_VALIDATION 0
@@ -74,6 +82,266 @@ elf_xtensa_before_parse (void)
}
+void
+remove_section (abfd, os)
+ bfd *abfd;
+ asection *os;
+{
+ asection **spp;
+ for (spp = &abfd->sections; *spp; spp = &(*spp)->next)
+ if (*spp == os)
+ {
+ *spp = os->next;
+ os->owner->section_count--;
+ break;
+ }
+}
+
+
+bfd_boolean
+replace_insn_sec_with_prop_sec (abfd, insn_sec_name, prop_sec_name,
+ error_message)
+ bfd *abfd;
+ const char *insn_sec_name;
+ const char *prop_sec_name;
+ char **error_message;
+{
+ asection *insn_sec;
+ asection *prop_sec;
+ bfd_byte *prop_contents = NULL;
+ bfd_byte *insn_contents = NULL;
+ unsigned entry_count;
+ unsigned entry;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ unsigned reloc_count;
+
+ *error_message = "";
+ insn_sec = bfd_get_section_by_name (abfd, insn_sec_name);
+ if (insn_sec == NULL)
+ return TRUE;
+ entry_count = insn_sec->size / 8;
+
+ prop_sec = bfd_get_section_by_name (abfd, prop_sec_name);
+ if (prop_sec != NULL && insn_sec != NULL)
+ {
+ *error_message = _("file already has property tables");
+ return FALSE;
+ }
+
+ if (insn_sec->size != 0)
+ {
+ insn_contents = (bfd_byte *) bfd_malloc (insn_sec->size);
+ if (insn_contents == NULL)
+ {
+ *error_message = _("out of memory");
+ goto cleanup;
+ }
+ if (! bfd_get_section_contents (abfd, insn_sec, insn_contents,
+ (file_ptr) 0, insn_sec->size))
+ {
+ *error_message = _("failed to read section contents");
+ goto cleanup;
+ }
+ }
+
+ /* Create a Property table section and relocation section for it. */
+ prop_sec_name = strdup (prop_sec_name);
+ prop_sec = bfd_make_section (abfd, prop_sec_name);
+ if (prop_sec == NULL
+ || ! bfd_set_section_flags (abfd, prop_sec,
+ bfd_get_section_flags (abfd, insn_sec))
+ || ! bfd_set_section_alignment (abfd, prop_sec, 2))
+ {
+ *error_message = _("could not create new section");
+ goto cleanup;
+ }
+
+ if (! bfd_set_section_flags (abfd, prop_sec,
+ bfd_get_section_flags (abfd, insn_sec))
+ || ! bfd_set_section_alignment (abfd, prop_sec, 2))
+ {
+ *error_message = _("could not set new section properties");
+ goto cleanup;
+ }
+ prop_sec->size = entry_count * 12;
+ prop_contents = (bfd_byte *) bfd_zalloc (abfd, prop_sec->size);
+ elf_section_data (prop_sec)->this_hdr.contents = prop_contents;
+
+ /* The entry size and size must be set to allow the linker to compute
+ the number of relocations since it does not use reloc_count. */
+ elf_section_data (prop_sec)->rel_hdr.sh_entsize =
+ sizeof (Elf32_External_Rela);
+ elf_section_data (prop_sec)->rel_hdr.sh_size =
+ elf_section_data (insn_sec)->rel_hdr.sh_size;
+
+ if (prop_contents == NULL && prop_sec->size != 0)
+ {
+ *error_message = _("could not allocate section contents");
+ goto cleanup;
+ }
+
+ /* Read the relocations. */
+ reloc_count = insn_sec->reloc_count;
+ if (reloc_count != 0)
+ {
+ /* If there is already an internal_reloc, then save it so that the
+ read_relocs function freshly allocates a copy. */
+ Elf_Internal_Rela *saved_relocs = elf_section_data (insn_sec)->relocs;
+
+ elf_section_data (insn_sec)->relocs = NULL;
+ internal_relocs =
+ _bfd_elf_link_read_relocs (abfd, insn_sec, NULL, NULL, FALSE);
+ elf_section_data (insn_sec)->relocs = saved_relocs;
+
+ if (internal_relocs == NULL)
+ {
+ *error_message = _("out of memory");
+ goto cleanup;
+ }
+ }
+
+ /* Create a relocation section for the property section. */
+ if (internal_relocs != NULL)
+ {
+ elf_section_data (prop_sec)->relocs = internal_relocs;
+ prop_sec->reloc_count = reloc_count;
+ }
+
+ /* Now copy each insn table entry to the prop table entry with
+ appropriate flags. */
+ for (entry = 0; entry < entry_count; ++entry)
+ {
+ unsigned value;
+ unsigned flags = (XTENSA_PROP_INSN | XTENSA_PROP_INSN_NO_TRANSFORM
+ | XTENSA_PROP_INSN_NO_REORDER);
+ value = bfd_get_32 (abfd, insn_contents + entry * 8 + 0);
+ bfd_put_32 (abfd, value, prop_contents + entry * 12 + 0);
+ value = bfd_get_32 (abfd, insn_contents + entry * 8 + 4);
+ bfd_put_32 (abfd, value, prop_contents + entry * 12 + 4);
+ bfd_put_32 (abfd, flags, prop_contents + entry * 12 + 8);
+ }
+
+ /* Now copy all of the relocations. Change offsets for the
+ instruction table section to offsets in the property table
+ section. */
+ if (internal_relocs)
+ {
+ unsigned i;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ for (i = 0; i < reloc_count; i++)
+ {
+ Elf_Internal_Rela *rela;
+ unsigned r_offset;
+
+ rela = &internal_relocs[i];
+
+ /* If this relocation is to the .xt.insn section,
+ change the section number and the offset. */
+ r_offset = rela->r_offset;
+ r_offset += 4 * (r_offset / 8);
+ rela->r_offset = r_offset;
+ }
+ }
+
+ remove_section (abfd, insn_sec);
+
+ if (insn_contents)
+ free (insn_contents);
+
+ return TRUE;
+
+ cleanup:
+ if (prop_sec && prop_sec->owner)
+ remove_section (abfd, prop_sec);
+ if (insn_contents)
+ free (insn_contents);
+ if (internal_relocs)
+ free (internal_relocs);
+
+ return FALSE;
+}
+
+
+#define PROP_SEC_BASE_NAME ".xt.prop"
+#define INSN_SEC_BASE_NAME ".xt.insn"
+#define LINKONCE_SEC_OLD_TEXT_BASE_NAME ".gnu.linkonce.x."
+
+
+void
+replace_instruction_table_sections (abfd, sec)
+ bfd *abfd;
+ asection *sec;
+{
+ char *message = "";
+ const char *insn_sec_name = NULL;
+ char *prop_sec_name = NULL;
+ char *owned_prop_sec_name = NULL;
+ const char *sec_name;
+
+ sec_name = bfd_get_section_name (abfd, sec);
+ if (strcmp (sec_name, INSN_SEC_BASE_NAME) == 0)
+ {
+ insn_sec_name = INSN_SEC_BASE_NAME;
+ prop_sec_name = PROP_SEC_BASE_NAME;
+ }
+ else if (strncmp (sec_name, LINKONCE_SEC_OLD_TEXT_BASE_NAME,
+ strlen (LINKONCE_SEC_OLD_TEXT_BASE_NAME)) == 0)
+ {
+ insn_sec_name = sec_name;
+ owned_prop_sec_name = (char *) xmalloc (strlen (sec_name) + 20);
+ prop_sec_name = owned_prop_sec_name;
+ strcpy (prop_sec_name, ".gnu.linkonce.prop.t.");
+ strcat (prop_sec_name,
+ sec_name + strlen (LINKONCE_SEC_OLD_TEXT_BASE_NAME));
+ }
+ if (insn_sec_name != NULL)
+ {
+ if (! replace_insn_sec_with_prop_sec (abfd, insn_sec_name, prop_sec_name,
+ &message))
+ {
+ einfo (_("%P: warning: failed to convert %s table in %B (%s); subsequent disassembly may be incomplete\n"),
+ insn_sec_name, abfd, message);
+ }
+ }
+ if (owned_prop_sec_name)
+ free (owned_prop_sec_name);
+}
+
+
+/* This is called after all input sections have been opened to convert
+ instruction tables (.xt.insn, gnu.linkonce.x.*) tables into property
+ tables (.xt.prop) before any section placement. */
+
+static void
+elf_xtensa_after_open (void)
+{
+ bfd *abfd;
+
+ /* First call the ELF version. */
+ gld${EMULATION_NAME}_after_open ();
+
+ /* Now search the input files looking for instruction table sections. */
+ for (abfd = link_info.input_bfds;
+ abfd != NULL;
+ abfd = abfd->link_next)
+ {
+ asection *sec = abfd->sections;
+ asection *next_sec;
+
+ /* Do not use bfd_map_over_sections here since we are removing
+ sections as we iterate. */
+ while (sec != NULL)
+ {
+ next_sec = sec->next;
+ replace_instruction_table_sections (abfd, sec);
+ sec = next_sec;
+ }
+ }
+}
+
+
/* This is called after the sections have been attached to output
sections, but before any sizes or addresses have been set. */
@@ -443,7 +711,7 @@ ld_xtensa_move_section_after (xtensa_ld_iter *to, xtensa_ld_iter *current)
/* Can only be called with lang_statements that have lists. Returns
- false if the list is empty. */
+ FALSE if the list is empty. */
static bfd_boolean
iter_stack_empty (xtensa_ld_iter_stack **stack_p)
@@ -1443,30 +1711,49 @@ ld_xtensa_insert_page_offsets (bfd_vma dot,
EOF
-# Define some shell vars to insert bits of code into the standard elf
+# Define some shell vars to insert bits of code into the standard ELF
# parse_args and list_options functions.
#
PARSE_AND_LIST_PROLOGUE='
-#define OPTION_NO_RELAX 301
+#define OPTION_OPT_SIZEOPT (300)
+#define OPTION_NO_RELAX (OPTION_OPT_SIZEOPT + 1)
+#define OPTION_LITERAL_MOVEMENT (OPTION_NO_RELAX + 1)
+#define OPTION_NO_LITERAL_MOVEMENT (OPTION_LITERAL_MOVEMENT + 1)
+extern int elf32xtensa_size_opt;
+extern int elf32xtensa_no_literal_movement;
'
PARSE_AND_LIST_LONGOPTS='
+ { "size-opt", no_argument, NULL, OPTION_OPT_SIZEOPT},
{ "no-relax", no_argument, NULL, OPTION_NO_RELAX},
+ { "literal-movement", no_argument, NULL, OPTION_LITERAL_MOVEMENT},
+ { "no-literal-movement", no_argument, NULL, OPTION_NO_LITERAL_MOVEMENT},
'
PARSE_AND_LIST_OPTIONS='
+ fprintf (file, _(" --size-opt\t\tWhen relaxing longcalls, prefer size optimization\n\t\t\t over branch target alignment\n"));
fprintf (file, _(" --no-relax\t\tDo not relax branches or coalesce literals\n"));
'
PARSE_AND_LIST_ARGS_CASES='
+ case OPTION_OPT_SIZEOPT:
+ elf32xtensa_size_opt = 1;
+ break;
case OPTION_NO_RELAX:
disable_relaxation = TRUE;
break;
+ case OPTION_LITERAL_MOVEMENT:
+ elf32xtensa_no_literal_movement = 0;
+ break;
+ case OPTION_NO_LITERAL_MOVEMENT:
+ elf32xtensa_no_literal_movement = 1;
+ break;
'
# Replace some of the standard ELF functions with our own versions.
#
LDEMUL_BEFORE_PARSE=elf_xtensa_before_parse
+LDEMUL_AFTER_OPEN=elf_xtensa_after_open
LDEMUL_CHOOSE_TARGET=elf_xtensa_choose_target
LDEMUL_PLACE_ORPHAN=elf_xtensa_place_orphan
LDEMUL_BEFORE_ALLOCATION=elf_xtensa_before_allocation
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 420065b..bfd3464 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -5552,34 +5552,53 @@ interleaving might place the @code{.literal} sections from an initial
group of files followed by the @code{.text} sections of that group of
files. Then, the @code{.literal} sections from the rest of the files
and the @code{.text} sections from the rest of the files would follow.
-The non-interleaved order can still be specified as:
-@smallexample
-SECTIONS
-@{
- .text : @{
- *(.literal) *(.text)
- @}
-@}
-@end smallexample
-
-@cindex @code{--relax} on Xtensa
+@cindex @option{--relax} on Xtensa
@cindex relaxing on Xtensa
+Relaxation is enabled by default for the Xtensa version of @command{ld} and
+provides two important link-time optimizations. The first optimization
+is to combine identical literal values to reduce code size. A redundant
+literal will be removed and all the @code{L32R} instructions that use it
+will be changed to reference an identical literal, as long as the
+location of the replacement literal is within the offset range of all
+the @code{L32R} instructions. The second optimization is to remove
+unnecessary overhead from assembler-generated ``longcall'' sequences of
+@code{L32R}/@code{CALLX@var{n}} when the target functions are within
+range of direct @code{CALL@var{n}} instructions.
+
+For each of these cases where an indirect call sequence can be optimized
+to a direct call, the linker will change the @code{CALLX@var{n}}
+instruction to a @code{CALL@var{n}} instruction, remove the @code{L32R}
+instruction, and remove the literal referenced by the @code{L32R}
+instruction if it is not used for anything else. Removing the
+@code{L32R} instruction always reduces code size but can potentially
+hurt performance by changing the alignment of subsequent branch targets.
+By default, the linker will always preserve alignments, either by
+switching some instructions between 24-bit encodings and the equivalent
+density instructions or by inserting a no-op in place of the @code{L32R}
+instruction that was removed. If code size is more important than
+performance, the @option{--size-opt} option can be used to prevent the
+linker from widening density instructions or inserting no-ops, except in
+a few cases where no-ops are required for correctness.
+
+The following Xtensa-specific command-line options can be used to
+control the linker:
+
+@cindex Xtensa options
+@table @option
@kindex --no-relax
-The Xtensa version of @command{ld} enables the @option{--relax} option by
-default to attempt to reduce space in the output image by combining
-literals with identical values. It also provides the
-@option{--no-relax} option to disable this optimization. When enabled,
-the relaxation algorithm ensures that a literal will only be merged with
-another literal when the new merged literal location is within the
-offset range of all of its uses.
-
-The relaxation mechanism will also attempt to optimize
-assembler-generated ``longcall'' sequences of
-@code{L32R}/@code{CALLX@var{n}} when the target is known to fit into a
-@code{CALL@var{n}} instruction encoding. The current optimization
-converts the sequence into @code{NOP}/@code{CALL@var{n}} and removes the
-literal referenced by the @code{L32R} instruction.
+@item --no-relax
+Since the Xtensa version of @code{ld} enables the @option{--relax} option
+by default, the @option{--no-relax} option is provided to disable
+relaxation.
+
+@item --size-opt
+When optimizing indirect calls to direct calls, optimize for code size
+more than performance. With this option, the linker will not insert
+no-ops or widen density instructions to preserve branch target
+alignment. There may still be some cases where no-ops are required to
+preserve the correctness of the code.
+@end table
@ifclear GENERIC
@lowersections
diff --git a/ld/scripttempl/elfxtensa.sc b/ld/scripttempl/elfxtensa.sc
index f99d2ce..632cf6d 100644
--- a/ld/scripttempl/elfxtensa.sc
+++ b/ld/scripttempl/elfxtensa.sc
@@ -10,6 +10,8 @@
# OTHER_TEXT_SECTIONS - these get put in .text when relocating
# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ...
# (e.g., .PARISC.global)
+# OTHER_RELRO_SECTIONS - other than .data.rel.ro ...
+# (e.g. PPC32 .fixup, .got[12])
# OTHER_BSS_SECTIONS - other than .bss .sbss ...
# OTHER_SECTIONS - at the end
# EXECUTABLE_SYMBOLS - symbols that must be defined for an
@@ -67,17 +69,24 @@ test -z "$ENTRY" && ENTRY=_start
test -z "${ELFSIZE}" && ELFSIZE=32
test -z "${ALIGNMENT}" && ALIGNMENT="${ELFSIZE} / 8"
test "$LD_FLAG" = "N" && DATA_ADDR=.
-test -n "$CREATE_SHLIB" && test -n "$SHLIB_DATA_ADDR" && COMMONPAGESIZE=""
-test -z "$CREATE_SHLIB" && test -n "$DATA_ADDR" && COMMONPAGESIZE=""
+test -n "$CREATE_SHLIB$CREATE_PIE" && test -n "$SHLIB_DATA_ADDR" && COMMONPAGESIZE=""
+test -z "$CREATE_SHLIB$CREATE_PIE" && test -n "$DATA_ADDR" && COMMONPAGESIZE=""
DATA_SEGMENT_ALIGN="ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))"
+DATA_SEGMENT_RELRO_END=""
DATA_SEGMENT_END=""
if test -n "${COMMONPAGESIZE}"; then
DATA_SEGMENT_ALIGN="ALIGN (${SEGMENT_SIZE}) - ((${MAXPAGESIZE} - .) & (${MAXPAGESIZE} - 1)); . = DATA_SEGMENT_ALIGN (${MAXPAGESIZE}, ${COMMONPAGESIZE})"
DATA_SEGMENT_END=". = DATA_SEGMENT_END (.);"
+ DATA_SEGMENT_RELRO_END=". = DATA_SEGMENT_RELRO_END (.);"
fi
INTERP=".interp ${RELOCATING-0} : { *(.interp) }"
+if test -z "$GOT"; then
+ GOT=".got ${RELOCATING-0} : { *(.got) }"
+fi
DYNAMIC=".dynamic ${RELOCATING-0} : { *(.dynamic) }"
RODATA=".rodata ${RELOCATING-0} : { *(.rodata${RELOCATING+ .rodata.* .gnu.linkonce.r.*}) }"
+DATARELRO=".data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) }"
+STACKNOTE="/DISCARD/ : { *(.note.GNU-stack) }"
INIT_LIT=".init.literal 0 : { *(.init.literal) }"
INIT=".init 0 : { *(.init) }"
FINI_LIT=".fini.literal 0 : { *(.fini.literal) }"
@@ -111,6 +120,8 @@ if test -z "${NO_SMALL_DATA}"; then
.rela.sdata2 ${RELOCATING-0} : { *(.rela.sdata2${RELOCATING+ .rela.sdata2.* .rela.gnu.linkonce.s2.*}) }"
REL_SBSS2=".rel.sbss2 ${RELOCATING-0} : { *(.rel.sbss2${RELOCATING+ .rel.sbss2.* .rel.gnu.linkonce.sb2.*}) }
.rela.sbss2 ${RELOCATING-0} : { *(.rela.sbss2${RELOCATING+ .rela.sbss2.* .rela.gnu.linkonce.sb2.*}) }"
+else
+ NO_SMALL_DATA=" "
fi
CTOR=".ctors ${CONSTRUCTING-0} :
{
@@ -175,8 +186,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+PROVIDE (__executable_start = ${TEXT_START_ADDR}); . = ${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}}
@@ -203,6 +215,8 @@ eval $COMBRELOCCAT <<EOF
.rel.rodata ${RELOCATING-0} : { *(.rel.rodata${RELOCATING+ .rel.rodata.* .rel.gnu.linkonce.r.*}) }
.rela.rodata ${RELOCATING-0} : { *(.rela.rodata${RELOCATING+ .rela.rodata.* .rela.gnu.linkonce.r.*}) }
${OTHER_READONLY_RELOC_SECTIONS}
+ .rel.data.rel.ro ${RELOCATING-0} : { *(.rel.data.rel.ro${RELOCATING+*}) }
+ .rela.data.rel.ro ${RELOCATING-0} : { *(.rel.data.rel.ro${RELOCATING+*}) }
.rel.data ${RELOCATING-0} : { *(.rel.data${RELOCATING+ .rel.data.* .rel.gnu.linkonce.d.*}) }
.rela.data ${RELOCATING-0} : { *(.rela.data${RELOCATING+ .rela.data.* .rela.gnu.linkonce.d.*}) }
.rel.tdata ${RELOCATING-0} : { *(.rel.tdata${RELOCATING+ .rel.tdata.* .rel.gnu.linkonce.td.*}) }
@@ -257,7 +271,8 @@ cat <<EOF
${RELOCATING+${INIT_END}}
${RELOCATING+${TEXT_START_SYMBOLS}}
- *(.literal .text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*})
+ *(.literal .text .stub${RELOCATING+ .text.* .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*})
+ KEEP (*(.text.*personality*))
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
${RELOCATING+${OTHER_TEXT_SECTIONS}}
@@ -280,11 +295,22 @@ cat <<EOF
${CREATE_SHLIB-${SBSS2}}
${OTHER_READONLY_SECTIONS}
.eh_frame_hdr : { *(.eh_frame_hdr) }
+ .eh_frame ${RELOCATING-0} : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+ .gcc_except_table ${RELOCATING-0} : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
- ${CREATE_SHLIB-${RELOCATING+. = ${DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}
+ ${CREATE_SHLIB-${CREATE_PIE-${RELOCATING+. = ${DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}}
${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}
+ ${CREATE_PIE+${RELOCATING+. = ${SHLIB_DATA_ADDR-${DATA_SEGMENT_ALIGN}};}}
+
+ /* Exception handling */
+ .eh_frame ${RELOCATING-0} : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+ .gcc_except_table ${RELOCATING-0} : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
+
+ /* Thread Local Storage sections */
+ .tdata ${RELOCATING-0} : { *(.tdata${RELOCATING+ .tdata.* .gnu.linkonce.td.*}) }
+ .tbss ${RELOCATING-0} : { *(.tbss${RELOCATING+ .tbss.* .gnu.linkonce.tb.*})${RELOCATING+ *(.tcommon)} }
/* Ensure the __preinit_array_start label is properly aligned. We
could instead move the label definition inside the section, but
@@ -292,36 +318,39 @@ cat <<EOF
be empty, which isn't pretty. */
${RELOCATING+. = ALIGN(${ALIGNMENT});}
${RELOCATING+${CREATE_SHLIB-PROVIDE (__preinit_array_start = .);}}
- .preinit_array ${RELOCATING-0} : { *(.preinit_array) }
+ .preinit_array ${RELOCATING-0} : { KEEP (*(.preinit_array)) }
${RELOCATING+${CREATE_SHLIB-PROVIDE (__preinit_array_end = .);}}
${RELOCATING+${CREATE_SHLIB-PROVIDE (__init_array_start = .);}}
- .init_array ${RELOCATING-0} : { *(.init_array) }
+ .init_array ${RELOCATING-0} : { KEEP (*(.init_array)) }
${RELOCATING+${CREATE_SHLIB-PROVIDE (__init_array_end = .);}}
${RELOCATING+${CREATE_SHLIB-PROVIDE (__fini_array_start = .);}}
- .fini_array ${RELOCATING-0} : { *(.fini_array) }
+ .fini_array ${RELOCATING-0} : { KEEP (*(.fini_array)) }
${RELOCATING+${CREATE_SHLIB-PROVIDE (__fini_array_end = .);}}
+ ${RELOCATING+${CTOR}}
+ ${RELOCATING+${DTOR}}
+ .jcr ${RELOCATING-0} : { KEEP (*(.jcr)) }
+
+ ${RELOCATING+${DATARELRO}}
+ ${OTHER_RELRO_SECTIONS}
+ ${TEXT_DYNAMIC-${DYNAMIC}}
+ ${NO_SMALL_DATA+${GOT}}
+ ${RELOCATING+${DATA_SEGMENT_RELRO_END}}
+
.data ${RELOCATING-0} :
{
${RELOCATING+${DATA_START_SYMBOLS}}
*(.data${RELOCATING+ .data.* .gnu.linkonce.d.*})
+ KEEP (*(.gnu.linkonce.d.*personality*))
${CONSTRUCTING+SORT(CONSTRUCTORS)}
}
.data1 ${RELOCATING-0} : { *(.data1) }
- .tdata ${RELOCATING-0} : { *(.tdata${RELOCATING+ .tdata.* .gnu.linkonce.td.*}) }
- .tbss ${RELOCATING-0} : { *(.tbss${RELOCATING+ .tbss.* .gnu.linkonce.tb.*})${RELOCATING+ *(.tcommon)} }
- .eh_frame ${RELOCATING-0} : { KEEP (*(.eh_frame)) }
- .gcc_except_table ${RELOCATING-0} : { *(.gcc_except_table) }
${WRITABLE_RODATA+${RODATA}}
${OTHER_READWRITE_SECTIONS}
- ${TEXT_DYNAMIC-${DYNAMIC}}
- ${RELOCATING+${CTOR}}
- ${RELOCATING+${DTOR}}
- .jcr ${RELOCATING-0} : { KEEP (*(.jcr)) }
${RELOCATING+${OTHER_GOT_SYMBOLS}}
- .got ${RELOCATING-0} : { *(.got) }
+ ${NO_SMALL_DATA-${GOT}}
${OTHER_GOT_SECTIONS}
${CREATE_SHLIB+${SDATA2}}
${CREATE_SHLIB+${SBSS2}}
@@ -393,5 +422,6 @@ cat <<EOF
${STACK_ADDR+${STACK}}
${OTHER_SECTIONS}
${RELOCATING+${OTHER_END_SYMBOLS}}
+ ${RELOCATING+${STACKNOTE}}
}
EOF
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 7cba4a4..da6dc8a 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2004-10-07 Bob Wilson <bob.wilson@acm.org>
+
+ * ld-xtensa/lcall1.s: Use .literal directive.
+ * ld-xtensa/lcall2.s: Align function entry.
+ * ld-xtensa/coalesce2.s: Likewise.
+
2004-10-04 H.J. Lu <hongjiu.lu@intel.com>
* ld-scripts/sort.exp: New file for section sorting tests.
diff --git a/ld/testsuite/ld-xtensa/coalesce2.s b/ld/testsuite/ld-xtensa/coalesce2.s
index 962915c..7c9a83d 100644
--- a/ld/testsuite/ld-xtensa/coalesce2.s
+++ b/ld/testsuite/ld-xtensa/coalesce2.s
@@ -1,6 +1,7 @@
.text
.global foo
.global g_name
+ .align 4
foo:
entry a5,16
movi a5,20000
diff --git a/ld/testsuite/ld-xtensa/lcall1.s b/ld/testsuite/ld-xtensa/lcall1.s
index 1056c6a..3439319 100644
--- a/ld/testsuite/ld-xtensa/lcall1.s
+++ b/ld/testsuite/ld-xtensa/lcall1.s
@@ -2,9 +2,7 @@
.text
.align 4
label1:
- .begin literal
- .word 0xffffffff
- .end literal
+ .literal .Lunused, 0xffffffff
entry a5,16
.begin longcalls
call4 foo
diff --git a/ld/testsuite/ld-xtensa/lcall2.s b/ld/testsuite/ld-xtensa/lcall2.s
index f4784f0..d697096 100644
--- a/ld/testsuite/ld-xtensa/lcall2.s
+++ b/ld/testsuite/ld-xtensa/lcall2.s
@@ -1,4 +1,5 @@
-.global foo
+ .global foo
+ .align 4
foo:
entry a5,16
nop