Improve MSP430 section placement.

ld	* emultempl/msp430.em (change_output_section): New function.
	(move_prefixed_section): New function.
	(add_region_prefix): New function.
	(msp430_elf_after_open): New function.
	(gld${EMULATION_NAME}_add_options): Implement.
	(gld${EMULATION_NAME}_list_options): Implement.
	(gld${EMULATION_NAME}_handle_option): Implement.
	* ld.texinfo: Document new options.
	* testsuite/ld-msp430-elf/main-bss-lower.d: New.
	* testsuite/ld-msp430-elf/main-bss-upper.d: New.
	* testsuite/ld-msp430-elf/main-const-lower.d: New.
	* testsuite/ld-msp430-elf/main-const-upper.d: New.
	* testsuite/ld-msp430-elf/main-text-lower.d: New.
	* testsuite/ld-msp430-elf/main-text-upper.d: New.
	* testsuite/ld-msp430-elf/main-var-lower.d: New.
	* testsuite/ld-msp430-elf/main-var-upper.d: New.
	* testsuite/ld-msp430-elf/main-with-data-bss-unique-sec.s: New.
	* testsuite/ld-msp430-elf/main-with-data-bss.s: New.
	* testsuite/ld-msp430-elf/main-with-text-rodata-unique-sec.s: New.
	* testsuite/ld-msp430-elf/main-with-text-rodata.s: New.
	* testsuite/ld-msp430-elf/msp430-elf.exp: New.
	* testsuite/ld-msp430-elf/msp430-no-lower.ld: New.
	* testsuite/ld-msp430-elf/msp430.ld: New.
	* emultempl/msp430.em (data_statement_size): New.
	(eval_upper_either_sections): New.
	(eval_lower_either_sections): New.
	(intermediate_relax_sections): New.
	(msp430_elf_after_allocation): New.
	* emultempl/msp430.em (gld${EMULATION_NAME}_place_orphan): Always
	place sections in the lower region.

gas	* config/tc-msp430.c (md_parse_option): Define high data and high
	bss symbols if -mdata-region is passed.
	Define -mdata-region open.
	* doc/c-msp430.texi: Document -mdata-region.
	* testsuite/gas/msp430/high-data-bss-sym.d: New test.
	* testsuite/gas/msp430/high-data-bss-sym.s: New.
	* testsuite/gas/msp430/msp430.exp: Add -mdata-region tests.
This commit is contained in:
Jozef Lawrynowicz 2017-08-29 17:18:43 +01:00 committed by Nick Clifton
parent 3819af136d
commit 7ef3addbe1
26 changed files with 1402 additions and 49 deletions

View File

@ -1,3 +1,13 @@
2017-08-29 Jozef Lawrynowicz <jozef.l@somniumtech.com>
* config/tc-msp430.c (md_parse_option): Define high data and high
bss symbols if -mdata-region is passed.
Define -mdata-region open.
* doc/c-msp430.texi: Document -mdata-region.
* testsuite/gas/msp430/high-data-bss-sym.d: New test.
* testsuite/gas/msp430/high-data-bss-sym.s: New.
* testsuite/gas/msp430/msp430.exp: Add -mdata-region tests.
2017-08-23 Alexander Fedotov <alexander.fedotov@nxp.com>
Edmar Wienskoski <edmar.wienskoski@nxp.com

View File

@ -676,6 +676,8 @@ static bfd_boolean warn_interrupt_nops = TRUE;
#define OPTION_MCPU 'c'
#define OPTION_MOVE_DATA 'd'
static bfd_boolean move_data = FALSE;
#define OPTION_DATA_REGION 'r'
static bfd_boolean upper_data_region_in_use = FALSE;
enum
{
@ -1448,6 +1450,12 @@ md_parse_option (int c, const char * arg)
case OPTION_MOVE_DATA:
move_data = TRUE;
return 1;
case OPTION_DATA_REGION:
if (strcmp (arg, "upper") == 0
|| strcmp (arg, "either") == 0)
upper_data_region_in_use = TRUE;
return 1;
}
return 0;
@ -1478,14 +1486,19 @@ msp430_make_init_symbols (const char * name)
/* Note - data assigned to the .either.data section may end up being
placed in the .upper.data section if the .lower.data section is
full. Hence the need to define the crt0 symbol. */
full. Hence the need to define the crt0 symbol.
The linker may create upper or either data sections, even when none exist
at the moment, so use the value of the data-region flag to determine if
the symbol is needed. */
if (strncmp (name, ".either.data", 12) == 0
|| strncmp (name, ".upper.data", 11) == 0)
|| strncmp (name, ".upper.data", 11) == 0
|| upper_data_region_in_use)
(void) symbol_find_or_make ("__crt0_move_highdata");
/* See note about .either.data above. */
if (strncmp (name, ".upper.bss", 10) == 0
|| strncmp (name, ".either.bss", 11) == 0)
|| strncmp (name, ".either.bss", 11) == 0
|| upper_data_region_in_use)
(void) symbol_find_or_make ("__crt0_init_highbss");
}
@ -1570,6 +1583,7 @@ struct option md_longopts[] =
{"mY", no_argument, NULL, OPTION_NO_WARN_INTR_NOPS},
{"my", no_argument, NULL, OPTION_WARN_INTR_NOPS},
{"md", no_argument, NULL, OPTION_MOVE_DATA},
{"mdata-region", required_argument, NULL, OPTION_DATA_REGION},
{NULL, no_argument, NULL, 0}
};
@ -1601,6 +1615,9 @@ md_show_usage (FILE * stream)
_(" -my - warn about missing NOPs after changing interrupts (default)\n"));
fprintf (stream,
_(" -md - Force copying of data from ROM to RAM at startup\n"));
fprintf (stream,
_(" -mdata-region={none|lower|upper|either} - select region data will be\n"
" placed in.\n"));
}
symbolS *

View File

@ -107,6 +107,19 @@ disables warnings about missing NOP instructions.
mark the object file as one that requires data to copied from ROM to
RAM at execution startup. Disabled by default.
@item -mdata-region=@var{region}
Select the region data will be placed in.
Region placement is performed by the compiler and linker. The only effect this
option will have on the assembler is that if @var{upper} or @var{either} is
selected, then the symbols to initialise high data and bss will be defined.
Valid @var{region} values are:
@table @code
@item none
@item lower
@item upper
@item either
@end table
@end table
@node MSP430 Syntax

View File

@ -0,0 +1,6 @@
#objdump: -t
#name: Check symbols to initialise high data and high bss have been defined
#...
.*__crt0_move_highdata.*
.*__crt0_init_highbss.*
#pass

View File

@ -0,0 +1,19 @@
.file "main.c"
.text
.balign 2
.global main
.type main, @function
main:
; start of function
; framesize_regs: 0
; framesize_locals: 0
; framesize_outgoing: 0
; framesize: 0
; elim ap -> fp 2
; elim fp -> sp 0
; saved regs:(none)
; start of prologue
; end of prologue
.L2:
BR #.L2
.size main, .-main

View File

@ -24,4 +24,6 @@ if [expr [istarget "msp430-*-*"]] then {
run_dump_test "bad"
run_dump_test "errata_warns"
run_dump_test "errata_fixes"
run_dump_test "high-data-bss-sym" { { as "-mdata-region=upper" } }
run_dump_test "high-data-bss-sym" { { as "-mdata-region=either" } }
}

View File

@ -1,3 +1,36 @@
2017-08-29 Jozef Lawrynowicz <jozef.l@somniumtech.com>
* emultempl/msp430.em (change_output_section): New function.
(move_prefixed_section): New function.
(add_region_prefix): New function.
(msp430_elf_after_open): New function.
(gld${EMULATION_NAME}_add_options): Implement.
(gld${EMULATION_NAME}_list_options): Implement.
(gld${EMULATION_NAME}_handle_option): Implement.
* ld.texinfo: Document new options.
* testsuite/ld-msp430-elf/main-bss-lower.d: New.
* testsuite/ld-msp430-elf/main-bss-upper.d: New.
* testsuite/ld-msp430-elf/main-const-lower.d: New.
* testsuite/ld-msp430-elf/main-const-upper.d: New.
* testsuite/ld-msp430-elf/main-text-lower.d: New.
* testsuite/ld-msp430-elf/main-text-upper.d: New.
* testsuite/ld-msp430-elf/main-var-lower.d: New.
* testsuite/ld-msp430-elf/main-var-upper.d: New.
* testsuite/ld-msp430-elf/main-with-data-bss-unique-sec.s: New.
* testsuite/ld-msp430-elf/main-with-data-bss.s: New.
* testsuite/ld-msp430-elf/main-with-text-rodata-unique-sec.s: New.
* testsuite/ld-msp430-elf/main-with-text-rodata.s: New.
* testsuite/ld-msp430-elf/msp430-elf.exp: New.
* testsuite/ld-msp430-elf/msp430-no-lower.ld: New.
* testsuite/ld-msp430-elf/msp430.ld: New.
* emultempl/msp430.em (data_statement_size): New.
(eval_upper_either_sections): New.
(eval_lower_either_sections): New.
(intermediate_relax_sections): New.
(msp430_elf_after_allocation): New.
* emultempl/msp430.em (gld${EMULATION_NAME}_place_orphan): Always
place sections in the lower region.
2017-08-26 H.J. Lu <hongjiu.lu@intel.com>
PR ld/21997

View File

@ -32,6 +32,7 @@ fragment <<EOF
#include "bfdlink.h"
#include "ld.h"
#include "getopt.h"
#include "ldmain.h"
#include "ldmisc.h"
#include "ldexp.h"
@ -39,6 +40,29 @@ 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,
};
enum either_placement_stage
{
LOWER_TO_UPPER,
UPPER_TO_LOWER,
};
enum { ROM, RAM };
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
@ -124,6 +148,32 @@ fi
if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
fragment <<EOF
static unsigned int
data_statement_size (lang_data_statement_type *d)
{
unsigned int size = 0;
switch (d->type)
{
case QUAD:
case SQUAD:
size = QUAD_SIZE;
break;
case LONG:
size = LONG_SIZE;
break;
case SHORT:
size = SHORT_SIZE;
break;
case BYTE:
size = BYTE_SIZE;
break;
default:
einfo ("%P: error: unhandled data_statement size\n");
FAIL ();
}
return size;
}
/* Helper function for place_orphan that computes the size
of sections already mapped to the given statement. */
@ -143,12 +193,17 @@ scan_children (lang_statement_union_type * l)
case lang_constructors_statement_enum:
case lang_assignment_statement_enum:
case lang_padding_statement_enum:
break;
case lang_wild_statement_enum:
amount += scan_children (l->wild_statement.children.head);
break;
case lang_data_statement_enum:
amount += data_statement_size (&l->data_statement);
break;
default:
fprintf (stderr, "msp430 orphan placer: unhandled lang type %d\n", l->header.type);
break;
@ -174,7 +229,6 @@ gld${EMULATION_NAME}_place_orphan (asection * s,
char * buf = NULL;
lang_output_section_statement_type * lower;
lang_output_section_statement_type * upper;
lang_output_section_statement_type * os;
if ((s->flags & SEC_ALLOC) == 0)
return NULL;
@ -211,71 +265,580 @@ gld${EMULATION_NAME}_place_orphan (asection * s,
/* Find the corresponding lower and upper sections. */
lower = lang_output_section_find (lower_name);
upper = lang_output_section_find (upper_name);
/* If the upper section does not exist, try again without the suffix. */
if (upper == NULL)
upper = lang_output_section_find (name);
if (lower == NULL)
if (lower == NULL && upper == NULL)
{
os = upper;
if (upper == NULL)
{
einfo ("%P: error: no section named %s or %s in linker script\n", lower_name, upper_name);
einfo ("%P: error: no section named %s or %s in linker script\n",
lower_name, upper_name);
goto end;
}
else if (lower == NULL)
{
lower = lang_output_section_find (name);
if (lower == NULL)
{
einfo ("%P: error: no section named %s in linker script\n", name);
goto end;
}
}
else if (upper == NULL)
os = lower;
else if (lower->region == NULL)
os = lower;
/* If the section is too big for the region containing
the lower section then do not even try to use it. */
else if (lower->region->length < s->size)
os = upper;
else
{
bfd_size_type amount = 0;
struct lang_output_section_statement_struct * p;
amount += scan_children (lower->children.head);
/* Also check forwards for other statements assigned to the same region. */
for (p = lower->next; p != NULL; p = p->next)
if (p->region == lower->region)
amount += scan_children (p->children.head);
/* Scan backwards as well. */
for (p = lower->prev; p != NULL; p = p->prev)
if (p->region == lower->region)
amount += scan_children (p->children.head);
if (amount + s->size >= lower->region->length)
os = upper;
else
os = lower;
}
lang_add_section (& os->children, s, NULL, os);
/* Always place orphaned sections in lower. Optimal placement of either
sections is performed later, once section sizes have been finalized. */
lang_add_section (& lower->children, s, NULL, lower);
end:
free (upper_name);
free (lower_name);
if (buf)
free (buf);
return os;
return lower;
}
EOF
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)
{
bfd *abfd;
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;
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;
}
static void
eval_upper_either_sections (bfd *abfd, asection *s, void *data)
{
char * base_sec_name;
const char * curr_name;
char * either_name;
int curr_region;
lang_output_section_statement_type * lower;
lang_output_section_statement_type * upper;
static bfd_size_type *lower_size = 0;
static bfd_size_type *upper_size = 0;
static bfd_size_type lower_size_rom = 0;
static bfd_size_type lower_size_ram = 0;
static bfd_size_type upper_size_rom = 0;
static bfd_size_type upper_size_ram = 0;
if ((s->flags & SEC_ALLOC) == 0)
return;
if (bfd_link_relocatable (&link_info))
return;
base_sec_name = (char *) data;
curr_name = bfd_get_section_name (abfd, s);
/* Only concerned with .either input sections in the upper output section. */
either_name = concat (".either", base_sec_name, NULL);
if (strncmp (curr_name, either_name, strlen (either_name)) != 0
|| strncmp (s->output_section->name, ".upper", 6) != 0)
goto end;
lower = lang_output_section_find (concat (".lower", base_sec_name, NULL));
upper = lang_output_section_find (concat (".upper", base_sec_name, NULL));
if (upper == NULL || upper->region == NULL)
goto end;
else if (lower == NULL)
lower = lang_output_section_find (base_sec_name);
if (lower == NULL || lower->region == NULL)
goto end;
if (strcmp (base_sec_name, ".text") == 0
|| strcmp (base_sec_name, ".rodata") == 0)
curr_region = ROM;
else
curr_region = RAM;
if (curr_region == ROM)
{
if (lower_size_rom == 0)
{
lower_size_rom = lower->region->current - lower->region->origin;
upper_size_rom = upper->region->current - upper->region->origin;
}
lower_size = &lower_size_rom;
upper_size = &upper_size_rom;
}
else if (curr_region == RAM)
{
if (lower_size_ram == 0)
{
lower_size_ram = lower->region->current - lower->region->origin;
upper_size_ram = upper->region->current - upper->region->origin;
}
lower_size = &lower_size_ram;
upper_size = &upper_size_ram;
}
/* Move sections in the upper region that would fit in the lower
region to the lower region. */
if (*lower_size + s->size < lower->region->length)
{
if (change_output_section (&(upper->children.head), s, lower))
{
*upper_size -= s->size;
*lower_size += s->size;
}
}
end:
free (either_name);
}
static void
eval_lower_either_sections (bfd *abfd, asection *s, void *data)
{
char * base_sec_name;
const char * curr_name;
char * either_name;
int curr_region;
lang_output_section_statement_type * output_sec;
lang_output_section_statement_type * lower;
lang_output_section_statement_type * upper;
static bfd_size_type *lower_size = 0;
static bfd_size_type lower_size_rom = 0;
static bfd_size_type lower_size_ram = 0;
if ((s->flags & SEC_ALLOC) == 0)
return;
if (bfd_link_relocatable (&link_info))
return;
base_sec_name = (char *) data;
curr_name = bfd_get_section_name (abfd, s);
/* Only concerned with .either input sections in the lower or "default"
output section i.e. not in the upper output section. */
either_name = concat (".either", base_sec_name, NULL);
if (strncmp (curr_name, either_name, strlen (either_name)) != 0
|| strncmp (s->output_section->name, ".upper", 6) == 0)
return;
if (strcmp (base_sec_name, ".text") == 0
|| strcmp (base_sec_name, ".rodata") == 0)
curr_region = ROM;
else
curr_region = RAM;
output_sec = lang_output_section_find (s->output_section->name);
/* If the output_section doesn't exist, this has already been reported in
place_orphan, so don't need to warn again. */
if (output_sec == NULL || output_sec->region == NULL)
goto end;
/* lower and output_sec might be the same, but in some cases an .either
section can end up in base_sec_name if it hasn't been placed by
place_orphan. */
lower = lang_output_section_find (concat (".lower", base_sec_name, NULL));
upper = lang_output_section_find (concat (".upper", base_sec_name, NULL));
if (upper == NULL)
goto end;
if (curr_region == ROM)
{
if (lower_size_rom == 0)
{
/* Get the size of other items in the lower region that aren't the
sections to be moved around. */
lower_size_rom
= (output_sec->region->current - output_sec->region->origin)
- scan_children (output_sec->children.head);
if (output_sec != lower && lower != NULL)
lower_size_rom -= scan_children (lower->children.head);
}
lower_size = &lower_size_rom;
}
else if (curr_region == RAM)
{
if (lower_size_ram == 0)
{
lower_size_ram
= (output_sec->region->current - output_sec->region->origin)
- scan_children (output_sec->children.head);
if (output_sec != lower && lower != NULL)
lower_size_ram -= scan_children (lower->children.head);
}
lower_size = &lower_size_ram;
}
/* Move sections that cause the lower region to overflow to the upper region. */
if (*lower_size + s->size > output_sec->region->length)
change_output_section (&(output_sec->children.head), s, upper);
else
*lower_size += s->size;
end:
free (either_name);
}
/* This function is similar to lang_relax_sections, but without the size
evaluation code that is always executed after relaxation. */
static void
intermediate_relax_sections (void)
{
int i = link_info.relax_pass;
/* The backend can use it to determine the current pass. */
link_info.relax_pass = 0;
while (i--)
{
bfd_boolean relax_again;
link_info.relax_trip = -1;
do
{
link_info.relax_trip++;
lang_do_assignments (lang_assigning_phase_enum);
lang_reset_memory_regions ();
relax_again = FALSE;
lang_size_sections (&relax_again, FALSE);
}
while (relax_again);
link_info.relax_pass++;
}
}
static void
msp430_elf_after_allocation (void)
{
int relax_count = 0;
int i;
/* Go over each section twice, once to place either sections that don't fit
in lower into upper, and then again to move any sections in upper that
fit in lower into lower. */
for (i = 0; i < 8; i++)
{
int placement_stage = (i < 4) ? LOWER_TO_UPPER : UPPER_TO_LOWER;
char * base_sec_name;
lang_output_section_statement_type * upper;
switch (i % 4)
{
case 0:
base_sec_name = concat (".text", NULL);
break;
case 1:
base_sec_name = concat (".data", NULL);
break;
case 2:
base_sec_name = concat (".bss", NULL);
break;
case 3:
base_sec_name = concat (".rodata", NULL);
break;
}
upper = lang_output_section_find (concat (".upper", base_sec_name, NULL));
if (upper != NULL)
{
/* Can't just use one iteration over the all the sections to make
both lower->upper and upper->lower transformations because the
iterator encounters upper sections before all lower sections have
been examined. */
bfd *abfd;
if (placement_stage == LOWER_TO_UPPER)
{
/* Perform relaxation and get the final size of sections
before trying to fit .either sections in the correct
ouput sections. */
if (relax_count == 0)
{
intermediate_relax_sections ();
relax_count++;
}
for (abfd = link_info.input_bfds; abfd != NULL;
abfd = abfd->link.next)
{
bfd_map_over_sections (abfd, eval_lower_either_sections,
base_sec_name);
}
}
else if (placement_stage == UPPER_TO_LOWER)
{
/* Relax again before moving upper->lower. */
if (relax_count == 1)
{
intermediate_relax_sections ();
relax_count++;
}
for (abfd = link_info.input_bfds; abfd != NULL;
abfd = abfd->link.next)
{
bfd_map_over_sections (abfd, eval_upper_either_sections,
base_sec_name);
}
}
}
free (base_sec_name);
}
gld${EMULATION_NAME}_after_allocation ();
}
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},
${LDEMUL_AFTER_ALLOCATION-after_allocation_default},
msp430_elf_after_open,
msp430_elf_after_allocation,
${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
${LDEMUL_BEFORE_ALLOCATION-before_allocation_default},
@ -288,10 +851,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},

View File

@ -7260,6 +7260,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

View File

@ -0,0 +1,3 @@
#...
Disassembly of section .lower.bss:
#pass

View File

@ -0,0 +1,3 @@
#...
Disassembly of section .upper.bss:
#pass

View File

@ -0,0 +1,3 @@
#...
Disassembly of section .lower.rodata:
#pass

View File

@ -0,0 +1,3 @@
#...
Disassembly of section .upper.rodata:
#pass

View File

@ -0,0 +1,3 @@
#...
Disassembly of section .lower.text:
#pass

View File

@ -0,0 +1,6 @@
.*: file format.*msp430.*
Disassembly of section .upper.text:
#...

View File

@ -0,0 +1,3 @@
#...
Disassembly of section .lower.data:
#pass

View File

@ -0,0 +1,3 @@
#...
Disassembly of section .upper.data:
#pass

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,141 @@
# 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"}
}
set msp430eithershuffletests {
{"Move \"either\" main() to .upper.text when it doesn\'t fit in .lower.text"
"-T msp430-tiny-rom.ld --code-region=either --data-region=either" "" "" {main-with-text-rodata.s}
{{objdump -d main-text-upper.d}} "either-to-upper-text"}
{"Move \"either\" glob_var_array to .upper.data when it doesn\'t fit in .lower.data"
"-T msp430-tiny-ram.ld --data-region=either" "" "" {main-with-data-bss.s}
{{objdump -D main-var-upper.d}} "either-to-upper-data"}
{"Move \"either\" glob_bss_array to .upper.bss when it doesn\'t fit in .lower.bss"
"-T msp430-tiny-ram.ld --data-region=either" "" "" {main-with-data-bss.s}
{{objdump -D main-bss-upper.d}} "either-to-upper-bss"}
{"Move \"either\" glob_const_array to .upper.rodata when it doesn\'t fit in .lower.rodata"
"-T msp430-tiny-rom.ld --code-region=either --data-region=either" "" "" {main-with-text-rodata.s}
{{objdump -D main-const-upper.d}} "either-to-upper-const"}
{"Move \"either\" main() to .upper.text when it doesn\'t fit in .lower.text, with -ffunction/data-sections"
"-T msp430-tiny-rom.ld --code-region=either --data-region=either" "" "" {main-with-text-rodata-unique-sec.s}
{{objdump -d main-text-upper.d}} "either-to-upper-text-unique-sec"}
{"Move \"either\" glob_var_array to .upper.data when it doesn\'t fit in .lower.data, with -ffunction/data-sections"
"-T msp430-tiny-ram.ld --data-region=either" "" "" {main-with-data-bss-unique-sec.s}
{{objdump -D main-var-upper.d}} "either-to-upper-data-unique-sec"}
{"Move \"either\" glob_bss_array to .upper.bss when it doesn\'t fit in .lower.bss, with -ffunction/data-sections"
"-T msp430-tiny-ram.ld --data-region=either" "" "" {main-with-data-bss-unique-sec.s}
{{objdump -D main-bss-upper.d}} "either-to-upper-bss-unique-sec"}
{"Move \"either\" glob_const_array to .upper.rodata when it doesn\'t fit in .lower.rodata, with -ffunction/data-sections"
"-T msp430-tiny-rom.ld --code-region=either --data-region=either" "" "" {main-with-text-rodata-unique-sec.s}
{{objdump -D main-const-upper.d}} "either-to-upper-const-unique-sec"}
}
run_ld_link_tests $msp430regionprefixtests
run_ld_link_tests $msp430regionprefixuniquesectiontests
run_ld_link_tests $msp430eithershuffletests

View File

@ -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.*)
}
}

View File

@ -0,0 +1,49 @@
/* Script for ld testsuite */
OUTPUT_ARCH(msp430)
ENTRY(_start)
MEMORY
{
RAM : ORIGIN = 0x0, LENGTH = 0x2
ROM : ORIGIN = 0x2, LENGTH = 0x1fe
HIFRAM : ORIGIN = 0x200, LENGTH = 0x1000
}
SECTIONS
{
.text :
{
PROVIDE (_start = .);
. = ALIGN(2);
*(.text .stub .text.* .gnu.linkonce.t.* .text:*)
} > ROM
.rodata :
{
*(.upper.rodata.* .rodata)
} > ROM
.data :
{
. = ALIGN(2);
*(.data.* .data)
} > RAM AT> ROM
.bss :
{
. = ALIGN(2);
*(.bss.* .bss)
} > RAM
.upper.data :
{
. = ALIGN(2);
*(.upper.data.* .upper.data)
} > HIFRAM AT> ROM
.upper.bss :
{
. = ALIGN(2);
*(.upper.bss.* .upper.bss)
} > HIFRAM
}

View File

@ -0,0 +1,48 @@
/* Script for ld testsuite */
OUTPUT_ARCH(msp430)
ENTRY(_start)
MEMORY
{
ROM : ORIGIN = 0x0, LENGTH = 0x2
RAM : ORIGIN = 0x2, LENGTH = 0x1fe
HIROM : ORIGIN = 0x200, LENGTH = 0x1000
}
SECTIONS
{
.text :
{
PROVIDE (_start = .);
. = ALIGN(2);
*(.text .stub .text.* .gnu.linkonce.t.* .text:*)
} > ROM
.rodata :
{
*(.rodata.* .rodata)
} > ROM
.data :
{
. = ALIGN(2);
*(.data.* .data)
} > RAM AT> ROM
.bss :
{
. = ALIGN(2);
*(.bss.* .bss)
} > RAM
.upper.text :
{
. = ALIGN(2);
*(.upper.text.* .upper.text)
} > HIROM
.upper.rodata :
{
*(.upper.rodata.* .upper.rodata)
} > HIROM
}

View File

@ -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.*)
}
}