[PATCH 1/4][MSP430] Add feature to add lower/either/upper prefixes to section names
Jozef Lawrynowicz
jozef.l@somniumtech.com
Wed Jul 19 17:16:00 GMT 2017
This patch adds a feature to the linker which adds a lower/either/upper
prefix to code/data sections, depending on the option passed to --code-
region or --data-region. GCC propagates the parameters passed to -mcode-
region and -mdata-region to these linker options. The benefit of this
feature is that precompiled objects or libraries can now be shuffled
around by the linker placement algorithm. For example, simple C++
programs do not build for some devices with small ROM/RAM. Previously,
C++ libraries would take up many kB and would all be placed in lower
memory, but when the sections from the libraries are shuffled between
the regions there is enough space available to successfully link these
programs.
The added tests pass when built with todays GCC trunk and binutils master.
-------------- next part --------------
From 50594250137c8250e9545037cc643fc91cd3d568 Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <jozef.l@somniumtech.com>
Date: Mon, 10 Jul 2017 13:14:53 +0000
Subject: [PATCH 1/4] MSP430: Add feature to add lower/either/upper prefixes to
section names
---
ld/emultempl/msp430.em | 276 ++++++++++++++++++++-
ld/ld.texinfo | 23 ++
ld/testsuite/ld-msp430-elf/main-bss-lower.d | 3 +
ld/testsuite/ld-msp430-elf/main-bss-upper.d | 3 +
ld/testsuite/ld-msp430-elf/main-const-lower.d | 3 +
ld/testsuite/ld-msp430-elf/main-const-upper.d | 3 +
ld/testsuite/ld-msp430-elf/main-text-lower.d | 3 +
ld/testsuite/ld-msp430-elf/main-text-upper.d | 6 +
ld/testsuite/ld-msp430-elf/main-var-lower.d | 3 +
ld/testsuite/ld-msp430-elf/main-var-upper.d | 3 +
.../ld-msp430-elf/main-with-data-bss-unique-sec.s | 78 ++++++
ld/testsuite/ld-msp430-elf/main-with-data-bss.s | 74 ++++++
.../main-with-text-rodata-unique-sec.s | 59 +++++
ld/testsuite/ld-msp430-elf/main-with-text-rodata.s | 59 +++++
ld/testsuite/ld-msp430-elf/msp430-elf.exp | 112 +++++++++
ld/testsuite/ld-msp430-elf/msp430-no-lower.ld | 54 ++++
ld/testsuite/ld-msp430-elf/msp430.ld | 78 ++++++
17 files changed, 836 insertions(+), 4 deletions(-)
create mode 100644 ld/testsuite/ld-msp430-elf/main-bss-lower.d
create mode 100644 ld/testsuite/ld-msp430-elf/main-bss-upper.d
create mode 100644 ld/testsuite/ld-msp430-elf/main-const-lower.d
create mode 100644 ld/testsuite/ld-msp430-elf/main-const-upper.d
create mode 100644 ld/testsuite/ld-msp430-elf/main-text-lower.d
create mode 100644 ld/testsuite/ld-msp430-elf/main-text-upper.d
create mode 100644 ld/testsuite/ld-msp430-elf/main-var-lower.d
create mode 100644 ld/testsuite/ld-msp430-elf/main-var-upper.d
create mode 100644 ld/testsuite/ld-msp430-elf/main-with-data-bss-unique-sec.s
create mode 100644 ld/testsuite/ld-msp430-elf/main-with-data-bss.s
create mode 100644 ld/testsuite/ld-msp430-elf/main-with-text-rodata-unique-sec.s
create mode 100644 ld/testsuite/ld-msp430-elf/main-with-text-rodata.s
create mode 100644 ld/testsuite/ld-msp430-elf/msp430-elf.exp
create mode 100644 ld/testsuite/ld-msp430-elf/msp430-no-lower.ld
create mode 100644 ld/testsuite/ld-msp430-elf/msp430.ld
diff --git a/ld/emultempl/msp430.em b/ld/emultempl/msp430.em
index 949fea0..04f8a2b 100644
--- a/ld/emultempl/msp430.em
+++ b/ld/emultempl/msp430.em
@@ -39,6 +39,21 @@ fragment <<EOF
#include "ldfile.h"
#include "ldemul.h"
#include "libiberty.h"
+#include <ldgram.h>
+
+enum regions
+{
+ REGION_NONE = 0,
+ REGION_LOWER,
+ REGION_UPPER,
+ REGION_EITHER = 3,
+};
+
+static int data_region = REGION_NONE;
+static int code_region = REGION_NONE;
+static bfd_boolean disable_sec_transformation = FALSE;
+
+#define MAX_PREFIX_LENGTH 7
EOF
@@ -268,13 +283,266 @@ fi
fragment <<EOF
+static bfd_boolean
+change_output_section (lang_statement_union_type ** head,
+ asection *s,
+ lang_output_section_statement_type * new_output_section)
+{
+ asection *is;
+ lang_statement_union_type * prev = NULL;
+ lang_statement_union_type * curr;
+ curr = *head;
+ while (curr != NULL)
+ {
+ switch (curr->header.type)
+ {
+ case lang_input_section_enum:
+ is = curr->input_section.section;
+ if (is == s)
+ {
+ s->output_section = NULL;
+ lang_add_section (& (new_output_section->children), s, NULL,
+ new_output_section);
+ /* Remove the section from the old output section. */
+ if (prev == NULL)
+ *head = curr->header.next;
+ else
+ prev->header.next = curr->header.next;
+ return TRUE;
+ }
+ break;
+ case lang_wild_statement_enum:
+ if (change_output_section (&(curr->wild_statement.children.head),
+ s, new_output_section))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ prev = curr;
+ curr = curr->header.next;
+ }
+ return FALSE;
+}
+
+static void
+move_prefixed_section (asection *s, char *new_name,
+ lang_output_section_statement_type * new_output_sec)
+{
+ s->name = new_name;
+ if (s->output_section == NULL)
+ lang_add_section (& (new_output_sec->children), s, NULL, new_output_sec);
+ else
+ {
+ lang_output_section_statement_type * curr_output_sec
+ = lang_output_section_find (s->output_section->name);
+ change_output_section (&(curr_output_sec->children.head), s,
+ new_output_sec);
+ }
+}
+
+static void
+add_region_prefix (bfd *abfd, asection *s,
+ __attribute__ ((unused)) void *unused)
+{
+ const char *curr_name = bfd_get_section_name (abfd, s);
+ char * base_name;
+ char * new_input_sec_name = NULL;
+ char * new_output_sec_name = NULL;
+ int region = REGION_NONE;
+ if (strncmp (curr_name, ".text", 5) == 0)
+ {
+ region = code_region;
+ base_name = concat (".text", NULL);
+ }
+ else if (strncmp (curr_name, ".data", 5) == 0)
+ {
+ region = data_region;
+ base_name = concat (".data", NULL);
+ }
+ else if (strncmp (curr_name, ".bss", 4) == 0)
+ {
+ region = data_region;
+ base_name = concat (".bss", NULL);
+ }
+ else if (strncmp (curr_name, ".rodata", 7) == 0)
+ {
+ region = data_region;
+ base_name = concat (".rodata", NULL);
+ }
+ else
+ return;
+
+ switch (region)
+ {
+ case REGION_NONE:
+ break;
+ case REGION_UPPER:
+ new_input_sec_name = concat (".upper", curr_name, NULL);
+ new_output_sec_name = concat (".upper", base_name, NULL);
+ lang_output_section_statement_type * upper
+ = lang_output_section_find (new_output_sec_name);
+ if (upper != NULL)
+ {
+ move_prefixed_section (s, new_input_sec_name, upper);
+ }
+ else
+ einfo ("%P: error: no section named %s in linker script\n",
+ new_output_sec_name);
+ break;
+ case REGION_LOWER:
+ new_input_sec_name = concat (".lower", curr_name, NULL);
+ new_output_sec_name = concat (".lower", base_name, NULL);
+ lang_output_section_statement_type * lower
+ = lang_output_section_find (new_output_sec_name);
+ if (lower != NULL)
+ {
+ move_prefixed_section (s, new_input_sec_name, lower);
+ }
+ else
+ einfo ("%P: error: no section named %s in linker script\n",
+ new_output_sec_name);
+ break;
+ case REGION_EITHER:
+ s->name = concat (".either", curr_name, NULL);
+ break;
+ default:
+ /* Unreachable. */
+ FAIL ();
+ break;
+ }
+ free (base_name);
+ if (new_input_sec_name)
+ {
+ free (new_input_sec_name);
+ free (new_output_sec_name);
+ }
+}
+
+static void
+msp430_elf_after_open (void)
+{
+ gld${EMULATION_NAME}_after_open ();
+ /* If neither --code-region or --data-region have been passed, do not
+ transform sections names. */
+ if ((code_region == REGION_NONE && data_region == REGION_NONE)
+ || disable_sec_transformation)
+ return;
+ bfd *abfd;
+ for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
+ {
+ bfd_map_over_sections (abfd, add_region_prefix, NULL);
+ }
+}
+
+#define OPTION_CODE_REGION 321
+#define OPTION_DATA_REGION (OPTION_CODE_REGION + 1)
+#define OPTION_DISABLE_TRANS (OPTION_CODE_REGION + 2)
+
+static void
+gld${EMULATION_NAME}_add_options
+ (int ns, char **shortopts, int nl, struct option **longopts,
+ int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
+{
+ static const char xtra_short[] = { };
+
+ static const struct option xtra_long[] = {
+ { "code-region", required_argument, NULL, OPTION_CODE_REGION },
+ { "data-region", required_argument, NULL, OPTION_DATA_REGION },
+ { "disable-sec-transformation", no_argument, NULL,
+ OPTION_DISABLE_TRANS },
+ { NULL, no_argument, NULL, 0 }
+ };
+
+ *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short));
+ memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short));
+ *longopts = (struct option *)
+ xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
+ memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
+}
+
+static void
+gld${EMULATION_NAME}_list_options (FILE * file)
+{
+ fprintf (file, _("\
+ --code-region={either,lower,upper,none}\n\
+ \tTransform .text* sections to {either,lower,upper,none}.text* sections.\n\
+ --data-region={either,lower,upper,none}\n\
+ \tTransform .data*, .rodata* and .bss* sections to\n\
+ {either,lower,upper,none}.{bss,data,rodata}* sections\n\
+ --disable-sec-transformation\n\
+ \tDisable transformation of .{text,data,bss,rodata}* sections to\n\
+ \tadd the {either,lower,upper,none} prefixes\n"));
+}
+
+static bfd_boolean
+gld${EMULATION_NAME}_handle_option (int optc)
+{
+ switch (optc)
+ {
+ case OPTION_CODE_REGION:
+ if (strcmp (optarg, "upper") == 0)
+ code_region = REGION_UPPER;
+ else if (strcmp (optarg, "lower") == 0)
+ code_region = REGION_LOWER;
+ else if (strcmp (optarg, "either") == 0)
+ code_region = REGION_EITHER;
+ else if (strcmp (optarg, "none") == 0)
+ code_region = REGION_NONE;
+ else if (strlen (optarg) == 0)
+ {
+ einfo (_("%P: --code-region requires an argument: \
+ {upper,lower,either,none}\n"));
+ return FALSE;
+ }
+ else
+ {
+ einfo (_("%P: error: unrecognized argument to --code-region= option: \
+ \"%s\"\n"), optarg);
+ return FALSE;
+ }
+ break;
+
+ case OPTION_DATA_REGION:
+ if (strcmp (optarg, "upper") == 0)
+ data_region = REGION_UPPER;
+ else if (strcmp (optarg, "lower") == 0)
+ data_region = REGION_LOWER;
+ else if (strcmp (optarg, "either") == 0)
+ data_region = REGION_EITHER;
+ else if (strcmp (optarg, "none") == 0)
+ data_region = REGION_NONE;
+ else if (strlen (optarg) == 0)
+ {
+ einfo (_("%P: --data-region requires an argument: \
+ {upper,lower,either,none}\n"));
+ return FALSE;
+ }
+ else
+ {
+ einfo (_("%P: error: unrecognized argument to --data-region= option: \
+ \"%s\"\n"), optarg);
+ return FALSE;
+ }
+ break;
+
+ case OPTION_DISABLE_TRANS:
+ disable_sec_transformation = TRUE;
+ break;
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
{
${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse},
${LDEMUL_SYSLIB-syslib_default},
${LDEMUL_HLL-hll_default},
${LDEMUL_AFTER_PARSE-after_parse_default},
- ${LDEMUL_AFTER_OPEN-after_open_default},
+ msp430_elf_after_open,
${LDEMUL_AFTER_ALLOCATION-after_allocation_default},
${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
@@ -288,10 +556,10 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan},
${LDEMUL_SET_SYMBOLS-NULL},
${LDEMUL_PARSE_ARGS-NULL},
- ${LDEMUL_ADD_OPTIONS-NULL},
- ${LDEMUL_HANDLE_OPTION-NULL},
+ gld${EMULATION_NAME}_add_options,
+ gld${EMULATION_NAME}_handle_option,
${LDEMUL_UNRECOGNIZED_FILE-NULL},
- ${LDEMUL_LIST_OPTIONS-NULL},
+ gld${EMULATION_NAME}_list_options,
${LDEMUL_RECOGNIZED_FILE-NULL},
${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
${LDEMUL_NEW_VERS_PATTERN-NULL},
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 987816f..53ccd6a4 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -7252,6 +7252,29 @@ Denotes a portion of RAM located above @samp{.bss} section.
The last two sections are used by gcc.
@end table
+@table @option
+@cindex MSP430 Options
+@kindex --code-region
+@item --code-region=[either,lower,upper,none]
+This will transform .text* sections to [either,lower,upper].text* sections. The
+argument passed to GCC for -mcode-region is propagated to the linker
+using this option.
+
+@kindex --data-region
+@item --data-region=[either,lower,upper,none]
+This will transform .data*, .bss* and .rodata* sections to
+[either,lower,upper].[data,bss,rodata]* sections. The argument passed to GCC
+for -mdata-region is propagated to the linker using this option.
+
+@kindex --disable-sec-transformation
+@item --disable-sec-transformation
+Prevent the transformation of sections as specified by the @code{--code-region}
+and @code{--data-region} options.
+This is useful if you are compiling and linking using a single call to the GCC
+wrapper, and want to compile the source files using -m[code,data]-region but
+not transform the sections for prebuilt libraries and objects.
+@end table
+
@ifclear GENERIC
@lowersections
@end ifclear
diff --git a/ld/testsuite/ld-msp430-elf/main-bss-lower.d b/ld/testsuite/ld-msp430-elf/main-bss-lower.d
new file mode 100644
index 0000000..6007420
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/main-bss-lower.d
@@ -0,0 +1,3 @@
+#...
+Disassembly of section .lower.bss:
+#pass
diff --git a/ld/testsuite/ld-msp430-elf/main-bss-upper.d b/ld/testsuite/ld-msp430-elf/main-bss-upper.d
new file mode 100644
index 0000000..2f6376a7
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/main-bss-upper.d
@@ -0,0 +1,3 @@
+#...
+Disassembly of section .upper.bss:
+#pass
diff --git a/ld/testsuite/ld-msp430-elf/main-const-lower.d b/ld/testsuite/ld-msp430-elf/main-const-lower.d
new file mode 100644
index 0000000..8549961
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/main-const-lower.d
@@ -0,0 +1,3 @@
+#...
+Disassembly of section .lower.rodata:
+#pass
diff --git a/ld/testsuite/ld-msp430-elf/main-const-upper.d b/ld/testsuite/ld-msp430-elf/main-const-upper.d
new file mode 100644
index 0000000..c84d649
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/main-const-upper.d
@@ -0,0 +1,3 @@
+#...
+Disassembly of section .upper.rodata:
+#pass
diff --git a/ld/testsuite/ld-msp430-elf/main-text-lower.d b/ld/testsuite/ld-msp430-elf/main-text-lower.d
new file mode 100644
index 0000000..446a305
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/main-text-lower.d
@@ -0,0 +1,3 @@
+#...
+Disassembly of section .lower.text:
+#pass
diff --git a/ld/testsuite/ld-msp430-elf/main-text-upper.d b/ld/testsuite/ld-msp430-elf/main-text-upper.d
new file mode 100644
index 0000000..f7ae6af
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/main-text-upper.d
@@ -0,0 +1,6 @@
+
+.*: file format.*msp430.*
+
+
+Disassembly of section .upper.text:
+#...
diff --git a/ld/testsuite/ld-msp430-elf/main-var-lower.d b/ld/testsuite/ld-msp430-elf/main-var-lower.d
new file mode 100644
index 0000000..f520cf5
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/main-var-lower.d
@@ -0,0 +1,3 @@
+#...
+Disassembly of section .lower.data:
+#pass
diff --git a/ld/testsuite/ld-msp430-elf/main-var-upper.d b/ld/testsuite/ld-msp430-elf/main-var-upper.d
new file mode 100644
index 0000000..fc3d712
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/main-var-upper.d
@@ -0,0 +1,3 @@
+#...
+Disassembly of section .upper.data:
+#pass
diff --git a/ld/testsuite/ld-msp430-elf/main-with-data-bss-unique-sec.s b/ld/testsuite/ld-msp430-elf/main-with-data-bss-unique-sec.s
new file mode 100644
index 0000000..7774804
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/main-with-data-bss-unique-sec.s
@@ -0,0 +1,78 @@
+ .file "main-with-data-bss.c"
+ .global glob_var_array
+ .section .data.glob_var_array,"aw",@progbits
+ .balign 2
+ .type glob_var_array, @object
+ .size glob_var_array, 20
+glob_var_array:
+ .short 0
+ .short 1
+ .short 2
+ .short 3
+ .short 4
+ .short 5
+ .short 6
+ .short 7
+ .short 8
+ .short 9
+ .section .bss.glob_bss_array,"aw",@nobits
+ .balign 2
+ .type glob_bss_array, @object
+ .size glob_bss_array, 20
+glob_bss_array:
+ .zero 20
+ .section .text.main,"ax",@progbits
+ .balign 2
+ .global main
+ .type main, @function
+main:
+; start of function
+; framesize_regs: 0
+; framesize_locals: 2
+; framesize_outgoing: 0
+; framesize: 2
+; elim ap -> fp 2
+; elim fp -> sp 2
+; saved regs:(none)
+ ; start of prologue
+ SUB.W #2, R1
+ ; end of prologue
+ MOV.W #0, @R1
+ BR #.L2
+.L7:
+ MOV.W @R1, R12
+ ADD.W R12, R12
+ ADD.W #glob_var_array, R12
+ MOV.W @R12, R13
+ MOV.W R13, R12
+ ADD.W R12, R12
+ ADD.W R13, R12
+ rpt #2 { rlax.w R12
+ SUB.W R13, R12
+ CMP.W #110, R12 { JNE .L3
+.L4:
+ BR #.L4
+.L3:
+ MOV.W @R1, R12
+ ADD.W R12, R12
+ ADD.W #glob_bss_array, R12
+ MOV.W @R12, R13
+ MOV.W R13, R12
+ ADD.W R12, R12
+ ADD.W R13, R12
+ rpt #2 { rlax.w R12
+ SUB.W R13, R12
+ CMP.W #110, R12 { JNE .L5
+.L6:
+ BR #.L6
+.L5:
+ ADD.W #1, @R1
+.L2:
+ MOV.B #9, R12
+ CMP.W @R1, R12 { JGE .L7
+ MOV.B #0, R12
+ ; start of epilogue
+ .refsym __crt0_call_exit
+ ADD.W #2, R1
+ RET
+ .size main, .-main
diff --git a/ld/testsuite/ld-msp430-elf/main-with-data-bss.s b/ld/testsuite/ld-msp430-elf/main-with-data-bss.s
new file mode 100644
index 0000000..a406b64
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/main-with-data-bss.s
@@ -0,0 +1,74 @@
+ .file "main-with-data-bss.c"
+ .global glob_var_array
+.data
+ .balign 2
+ .type glob_var_array, @object
+ .size glob_var_array, 20
+glob_var_array:
+ .short 0
+ .short 1
+ .short 2
+ .short 3
+ .short 4
+ .short 5
+ .short 6
+ .short 7
+ .short 8
+ .short 9
+ .local glob_bss_array
+ .comm glob_bss_array,20,2
+.text
+ .balign 2
+ .global main
+ .type main, @function
+main:
+; start of function
+; framesize_regs: 0
+; framesize_locals: 2
+; framesize_outgoing: 0
+; framesize: 2
+; elim ap -> fp 2
+; elim fp -> sp 2
+; saved regs:(none)
+ ; start of prologue
+ SUB.W #2, R1
+ ; end of prologue
+ MOV.W #0, @R1
+ BR #.L2
+.L7:
+ MOV.W @R1, R12
+ ADD.W R12, R12
+ ADD.W #glob_var_array, R12
+ MOV.W @R12, R13
+ MOV.W R13, R12
+ ADD.W R12, R12
+ ADD.W R13, R12
+ rpt #2 { rlax.w R12
+ SUB.W R13, R12
+ CMP.W #110, R12 { JNE .L3
+.L4:
+ BR #.L4
+.L3:
+ MOV.W @R1, R12
+ ADD.W R12, R12
+ ADD.W #glob_bss_array, R12
+ MOV.W @R12, R13
+ MOV.W R13, R12
+ ADD.W R12, R12
+ ADD.W R13, R12
+ rpt #2 { rlax.w R12
+ SUB.W R13, R12
+ CMP.W #110, R12 { JNE .L5
+.L6:
+ BR #.L6
+.L5:
+ ADD.W #1, @R1
+.L2:
+ MOV.B #9, R12
+ CMP.W @R1, R12 { JGE .L7
+ MOV.B #0, R12
+ ; start of epilogue
+ .refsym __crt0_call_exit
+ ADD.W #2, R1
+ RET
+ .size main, .-main
diff --git a/ld/testsuite/ld-msp430-elf/main-with-text-rodata-unique-sec.s b/ld/testsuite/ld-msp430-elf/main-with-text-rodata-unique-sec.s
new file mode 100644
index 0000000..398cf74
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/main-with-text-rodata-unique-sec.s
@@ -0,0 +1,59 @@
+ .file "main-with-text-rodata.c"
+ .global glob_const_array
+ .section .rodata.glob_const_array,"a",@progbits
+ .balign 2
+ .type glob_const_array, @object
+ .size glob_const_array, 20
+glob_const_array:
+ .short 0
+ .short 1
+ .short 2
+ .short 3
+ .short 4
+ .short 5
+ .short 6
+ .short 7
+ .short 8
+ .short 9
+ .section .text.main,"ax",@progbits
+ .balign 2
+ .global main
+ .type main, @function
+main:
+; start of function
+; framesize_regs: 0
+; framesize_locals: 2
+; framesize_outgoing: 0
+; framesize: 2
+; elim ap -> fp 2
+; elim fp -> sp 2
+; saved regs:(none)
+ ; start of prologue
+ SUB.W #2, R1
+ ; end of prologue
+ MOV.W #0, @R1
+ BR #.L2
+.L5:
+ MOV.W @R1, R12
+ ADD.W R12, R12
+ ADD.W #glob_const_array, R12
+ MOV.W @R12, R13
+ MOV.W R13, R12
+ ADD.W R12, R12
+ ADD.W R13, R12
+ rpt #2 { rlax.w R12
+ SUB.W R13, R12
+ CMP.W #110, R12 { JNE .L3
+.L4:
+ BR #.L4
+.L3:
+ ADD.W #1, @R1
+.L2:
+ MOV.B #9, R12
+ CMP.W @R1, R12 { JGE .L5
+ MOV.B #0, R12
+ ; start of epilogue
+ .refsym __crt0_call_exit
+ ADD.W #2, R1
+ RET
+ .size main, .-main
diff --git a/ld/testsuite/ld-msp430-elf/main-with-text-rodata.s b/ld/testsuite/ld-msp430-elf/main-with-text-rodata.s
new file mode 100644
index 0000000..225b5d4
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/main-with-text-rodata.s
@@ -0,0 +1,59 @@
+ .file "main-with-text-rodata.c"
+ .global glob_const_array
+ .section .rodata
+ .balign 2
+ .type glob_const_array, @object
+ .size glob_const_array, 20
+glob_const_array:
+ .short 0
+ .short 1
+ .short 2
+ .short 3
+ .short 4
+ .short 5
+ .short 6
+ .short 7
+ .short 8
+ .short 9
+.text
+ .balign 2
+ .global main
+ .type main, @function
+main:
+; start of function
+; framesize_regs: 0
+; framesize_locals: 2
+; framesize_outgoing: 0
+; framesize: 2
+; elim ap -> fp 2
+; elim fp -> sp 2
+; saved regs:(none)
+ ; start of prologue
+ SUB.W #2, R1
+ ; end of prologue
+ MOV.W #0, @R1
+ BR #.L2
+.L5:
+ MOV.W @R1, R12
+ ADD.W R12, R12
+ ADD.W #glob_const_array, R12
+ MOV.W @R12, R13
+ MOV.W R13, R12
+ ADD.W R12, R12
+ ADD.W R13, R12
+ rpt #2 { rlax.w R12
+ SUB.W R13, R12
+ CMP.W #110, R12 { JNE .L3
+.L4:
+ BR #.L4
+.L3:
+ ADD.W #1, @R1
+.L2:
+ MOV.B #9, R12
+ CMP.W @R1, R12 { JGE .L5
+ MOV.B #0, R12
+ ; start of epilogue
+ .refsym __crt0_call_exit
+ ADD.W #2, R1
+ RET
+ .size main, .-main
diff --git a/ld/testsuite/ld-msp430-elf/msp430-elf.exp b/ld/testsuite/ld-msp430-elf/msp430-elf.exp
new file mode 100644
index 0000000..bed2ed8
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/msp430-elf.exp
@@ -0,0 +1,112 @@
+# Expect script for various MSP430 ELF tests.
+# Copyright (C) 2002-2015 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+if { ![istarget "msp430*elf*"] } {
+ return
+}
+
+# List contains test-items with 3 items followed by 2 lists and one more item:
+# 0:name 1:ld early options 2:ld late options 3:assembler options
+# 4:filenames of assembler files 5: action and options. 6: name of output file
+
+# Actions:
+# objdump: Apply objdump options on result. Compare with regex (last arg).
+# nm: Apply nm options on result. Compare with regex (last arg).
+# readelf: Apply readelf options on result. Compare with regex (last arg).
+
+set msp430regionprefixtests {
+ {"Move main() to .upper.text" "-T msp430.ld --code-region=upper"
+ "" "" {main-with-text-rodata.s} {{objdump -d main-text-upper.d}} "main-upper"}
+ {"Move main() to .upper.text. No .lower.text in ld script" "-T msp430-no-lower.ld --code-region=upper"
+ "" "" {main-with-text-rodata.s} {{objdump -d main-text-upper.d}} "main-upper"}
+ {"Move main() to .lower.text" "-T msp430.ld --code-region=lower"
+ "" "" {main-with-text-rodata.s} {{objdump -d main-text-lower.d}} "main-lower"}
+ {"Move \"either\" main() to .lower.text" "-T msp430.ld --code-region=either"
+ "" "" {main-with-text-rodata.s} {{objdump -d main-text-lower.d}} "main-either"}
+
+ {"Move glob_var to .upper.data" "-T msp430.ld --data-region=upper"
+ "" "" {main-with-data-bss.s} {{objdump -D main-var-upper.d}} "main-var-upper"}
+ {"Move glob_var to .upper.data. No .lower.data in ld script" "-T msp430-no-lower.ld --data-region=upper"
+ "" "" {main-with-data-bss.s} {{objdump -D main-var-upper.d}} "main-var-upper"}
+ {"Move glob_var to .lower.data" "-T msp430.ld --data-region=lower"
+ "" "" {main-with-data-bss.s} {{objdump -D main-var-lower.d}} "main-var-lower"}
+ {"Move \"either\" glob_var to .lower.data" "-T msp430.ld --data-region=lower"
+ "" "" {main-with-data-bss.s} {{objdump -D main-var-lower.d}} "main-var-lower"}
+
+ {"Move glob_zero to .upper.bss" "-T msp430.ld --data-region=upper"
+ "" "" {main-with-data-bss.s} {{objdump -D main-bss-upper.d}} "main-bss-upper"}
+ {"Move glob_zero to .upper.bss. No .lower.bss in ld script." "-T msp430-no-lower.ld --data-region=upper"
+ "" "" {main-with-data-bss.s} {{objdump -D main-bss-upper.d}} "main-bss-upper"}
+ {"Move glob_zero to .lower.bss" "-T msp430.ld --data-region=lower"
+ "" "" {main-with-data-bss.s} {{objdump -D main-bss-lower.d}} "main-bss-lower"}
+ {"Move \"either\" glob_zero to .lower.bss" "-T msp430.ld --data-region=lower"
+ "" "" {main-with-data-bss.s} {{objdump -D main-bss-lower.d}} "main-bss-lower"}
+
+ {"Move glob_const to .upper.rodata" "-T msp430.ld --data-region=upper"
+ "" "" {main-with-text-rodata.s} {{objdump -D main-const-upper.d}} "main-const-upper"}
+ {"Move glob_const to .upper.rodata. No .lower.rodata in ld script." "-T msp430-no-lower.ld --data-region=upper"
+ "" "" {main-with-text-rodata.s} {{objdump -D main-const-upper.d}} "main-const-upper"}
+ {"Move glob_const to .lower.rodata" "-T msp430.ld --data-region=lower"
+ "" "" {main-with-text-rodata.s} {{objdump -D main-const-lower.d}} "main-const-lower"}
+ {"Move \"either\" glob_const to .lower.rodata" "-T msp430.ld --data-region=lower"
+ "" "" {main-with-text-rodata.s} {{objdump -D main-const-lower.d}} "main-const-lower"}
+}
+
+set msp430regionprefixuniquesectiontests {
+ {"Move main() to .upper.text, with -ffunction/data-sections" "-T msp430.ld --code-region=upper"
+ "" "" {main-with-text-rodata-unique-sec.s} {{objdump -d main-text-upper.d}} "main-upper"}
+ {"Move main() to .upper.text. No .lower.text in ld script, with -ffunction/data-sections" "-T msp430-no-lower.ld --code-region=upper"
+ "" "" {main-with-text-rodata-unique-sec.s} {{objdump -d main-text-upper.d}} "main-upper"}
+ {"Move main() to .lower.text, with -ffunction/data-sections" "-T msp430.ld --code-region=lower"
+ "" "" {main-with-text-rodata-unique-sec.s} {{objdump -d main-text-lower.d}} "main-lower"}
+ {"Move \"either\" main() to .lower.text, with -ffunction/data-sections" "-T msp430.ld --code-region=either"
+ "" "" {main-with-text-rodata-unique-sec.s} {{objdump -d main-text-lower.d}} "main-either"}
+
+ {"Move glob_var to .upper.data, with -ffunction/data-sections" "-T msp430.ld --data-region=upper"
+ "" "" {main-with-data-bss-unique-sec.s} {{objdump -D main-var-upper.d}} "main-var-upper"}
+ {"Move glob_var to .upper.data. No .lower.data in ld script, with -ffunction/data-sections" "-T msp430-no-lower.ld --data-region=upper"
+ "" "" {main-with-data-bss-unique-sec.s} {{objdump -D main-var-upper.d}} "main-var-upper"}
+ {"Move glob_var to .lower.data, with -ffunction/data-sections" "-T msp430.ld --data-region=lower"
+ "" "" {main-with-data-bss-unique-sec.s} {{objdump -D main-var-lower.d}} "main-var-lower"}
+ {"Move \"either\" glob_var to .lower.data, with -ffunction/data-sections" "-T msp430.ld --data-region=lower"
+ "" "" {main-with-data-bss-unique-sec.s} {{objdump -D main-var-lower.d}} "main-var-lower"}
+
+ {"Move glob_zero to .upper.bss, with -ffunction/data-sections" "-T msp430.ld --data-region=upper"
+ "" "" {main-with-data-bss-unique-sec.s} {{objdump -D main-bss-upper.d}} "main-bss-upper"}
+ {"Move glob_zero to .upper.bss. No .lower.bss in ld script., with -ffunction/data-sections" "-T msp430-no-lower.ld --data-region=upper"
+ "" "" {main-with-data-bss-unique-sec.s} {{objdump -D main-bss-upper.d}} "main-bss-upper"}
+ {"Move glob_zero to .lower.bss, with -ffunction/data-sections" "-T msp430.ld --data-region=lower"
+ "" "" {main-with-data-bss-unique-sec.s} {{objdump -D main-bss-lower.d}} "main-bss-lower"}
+ {"Move \"either\" glob_zero to .lower.bss, with -ffunction/data-sections" "-T msp430.ld --data-region=lower"
+ "" "" {main-with-data-bss-unique-sec.s} {{objdump -D main-bss-lower.d}} "main-bss-lower"}
+
+ {"Move glob_const to .upper.rodata, with -ffunction/data-sections" "-T msp430.ld --data-region=upper"
+ "" "" {main-with-text-rodata-unique-sec.s} {{objdump -D main-const-upper.d}} "main-const-upper"}
+ {"Move glob_const to .upper.rodata. No .lower.rodata in ld script., with -ffunction/data-sections" "-T msp430-no-lower.ld --data-region=upper"
+ "" "" {main-with-text-rodata-unique-sec.s} {{objdump -D main-const-upper.d}} "main-const-upper"}
+ {"Move glob_const to .lower.rodata, with -ffunction/data-sections" "-T msp430.ld --data-region=lower"
+ "" "" {main-with-text-rodata-unique-sec.s} {{objdump -D main-const-lower.d}} "main-const-lower"}
+ {"Move \"either\" glob_const to .lower.rodata, with -ffunction/data-sections" "-T msp430.ld --data-region=lower"
+ "" "" {main-with-text-rodata-unique-sec.s} {{objdump -D main-const-lower.d}} "main-const-lower"}
+}
+
+run_ld_link_tests $msp430regionprefixtests
+run_ld_link_tests $msp430regionprefixuniquesectiontests
diff --git a/ld/testsuite/ld-msp430-elf/msp430-no-lower.ld b/ld/testsuite/ld-msp430-elf/msp430-no-lower.ld
new file mode 100644
index 0000000..f9a2847
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/msp430-no-lower.ld
@@ -0,0 +1,54 @@
+/* Script for ld testsuite */
+OUTPUT_ARCH(msp430)
+ENTRY(_start)
+
+SECTIONS
+{
+ .text :
+ {
+ PROVIDE (_start = .);
+ . = ALIGN(2);
+ *(.text .stub .text.* .gnu.linkonce.t.* .text:*)
+ }
+
+ .rodata :
+ {
+ *(.rodata.* .rodata)
+ }
+
+ .data :
+ {
+ . = ALIGN(2);
+ *(.data.* .data)
+ }
+
+ .bss :
+ {
+ . = ALIGN(2);
+ *(.bss.* .bss)
+ }
+
+ .upper.text :
+ {
+ . = ALIGN(2);
+ *(.upper.text.* .upper.text)
+ }
+
+ .upper.rodata :
+ {
+ . = ALIGN(2);
+ *(.upper.rodata .upper.rodata.*)
+ }
+
+ .upper.data :
+ {
+ . = ALIGN(2);
+ *(.upper.data .upper.data.*)
+ }
+
+ .upper.bss :
+ {
+ . = ALIGN(2);
+ *(.upper.bss .upper.bss.*)
+ }
+}
diff --git a/ld/testsuite/ld-msp430-elf/msp430.ld b/ld/testsuite/ld-msp430-elf/msp430.ld
new file mode 100644
index 0000000..9c30836
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/msp430.ld
@@ -0,0 +1,78 @@
+/* Script for ld testsuite */
+OUTPUT_ARCH(msp430)
+ENTRY(_start)
+
+SECTIONS
+{
+ .lower.data :
+ {
+ . = ALIGN(2);
+ *(.lower.data .lower.data.*)
+ }
+
+ .lower.bss :
+ {
+ . = ALIGN(2);
+ *(.lower.bss .lower.bss.*)
+ }
+
+ .lower.text :
+ {
+ PROVIDE (_start = .);
+ . = ALIGN(2);
+ *(.lower.text.* .lower.text)
+ }
+
+ .lower.rodata :
+ {
+ . = ALIGN(2);
+ *(.lower.rodata .lower.rodata.*)
+ }
+
+ .text :
+ {
+ . = ALIGN(2);
+ *(.text .stub .text.* .gnu.linkonce.t.* .text:*)
+ }
+
+ .rodata :
+ {
+ *(.rodata.* .rodata)
+ }
+
+ .data :
+ {
+ . = ALIGN(2);
+ *(.data.* .data)
+ }
+
+ .bss :
+ {
+ . = ALIGN(2);
+ *(.bss.* .bss)
+ }
+
+ .upper.text :
+ {
+ . = ALIGN(2);
+ *(.upper.text.* .upper.text)
+ }
+
+ .upper.rodata :
+ {
+ . = ALIGN(2);
+ *(.upper.rodata .upper.rodata.*)
+ }
+
+ .upper.data :
+ {
+ . = ALIGN(2);
+ *(.upper.data .upper.data.*)
+ }
+
+ .upper.bss :
+ {
+ . = ALIGN(2);
+ *(.upper.bss .upper.bss.*)
+ }
+}
--
1.8.3.1
More information about the Binutils
mailing list