diff options
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 21 | ||||
-rw-r--r-- | ld/Makefile.am | 5 | ||||
-rw-r--r-- | ld/Makefile.in | 5 | ||||
-rw-r--r-- | ld/emulparams/elf32xtensa.sh | 1 | ||||
-rw-r--r-- | ld/emultempl/xtensaelf.em | 295 | ||||
-rw-r--r-- | ld/ld.texinfo | 69 | ||||
-rw-r--r-- | ld/scripttempl/elfxtensa.sc | 64 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | ld/testsuite/ld-xtensa/coalesce2.s | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-xtensa/lcall1.s | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-xtensa/lcall2.s | 3 |
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 |