mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-28 23:39:35 +08:00
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:

committed by
Nick Clifton

parent
3819af136d
commit
7ef3addbe1
@ -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>
|
2017-08-23 Alexander Fedotov <alexander.fedotov@nxp.com>
|
||||||
Edmar Wienskoski <edmar.wienskoski@nxp.com
|
Edmar Wienskoski <edmar.wienskoski@nxp.com
|
||||||
|
|
||||||
|
@ -676,6 +676,8 @@ static bfd_boolean warn_interrupt_nops = TRUE;
|
|||||||
#define OPTION_MCPU 'c'
|
#define OPTION_MCPU 'c'
|
||||||
#define OPTION_MOVE_DATA 'd'
|
#define OPTION_MOVE_DATA 'd'
|
||||||
static bfd_boolean move_data = FALSE;
|
static bfd_boolean move_data = FALSE;
|
||||||
|
#define OPTION_DATA_REGION 'r'
|
||||||
|
static bfd_boolean upper_data_region_in_use = FALSE;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -1448,6 +1450,12 @@ md_parse_option (int c, const char * arg)
|
|||||||
case OPTION_MOVE_DATA:
|
case OPTION_MOVE_DATA:
|
||||||
move_data = TRUE;
|
move_data = TRUE;
|
||||||
return 1;
|
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;
|
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
|
/* Note - data assigned to the .either.data section may end up being
|
||||||
placed in the .upper.data section if the .lower.data section is
|
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
|
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");
|
(void) symbol_find_or_make ("__crt0_move_highdata");
|
||||||
|
|
||||||
/* See note about .either.data above. */
|
/* See note about .either.data above. */
|
||||||
if (strncmp (name, ".upper.bss", 10) == 0
|
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");
|
(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_NO_WARN_INTR_NOPS},
|
||||||
{"my", no_argument, NULL, OPTION_WARN_INTR_NOPS},
|
{"my", no_argument, NULL, OPTION_WARN_INTR_NOPS},
|
||||||
{"md", no_argument, NULL, OPTION_MOVE_DATA},
|
{"md", no_argument, NULL, OPTION_MOVE_DATA},
|
||||||
|
{"mdata-region", required_argument, NULL, OPTION_DATA_REGION},
|
||||||
{NULL, no_argument, NULL, 0}
|
{NULL, no_argument, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1601,6 +1615,9 @@ md_show_usage (FILE * stream)
|
|||||||
_(" -my - warn about missing NOPs after changing interrupts (default)\n"));
|
_(" -my - warn about missing NOPs after changing interrupts (default)\n"));
|
||||||
fprintf (stream,
|
fprintf (stream,
|
||||||
_(" -md - Force copying of data from ROM to RAM at startup\n"));
|
_(" -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 *
|
symbolS *
|
||||||
|
@ -107,6 +107,19 @@ disables warnings about missing NOP instructions.
|
|||||||
mark the object file as one that requires data to copied from ROM to
|
mark the object file as one that requires data to copied from ROM to
|
||||||
RAM at execution startup. Disabled by default.
|
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
|
@end table
|
||||||
|
|
||||||
@node MSP430 Syntax
|
@node MSP430 Syntax
|
||||||
|
6
gas/testsuite/gas/msp430/high-data-bss-sym.d
Normal file
6
gas/testsuite/gas/msp430/high-data-bss-sym.d
Normal 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
|
19
gas/testsuite/gas/msp430/high-data-bss-sym.s
Normal file
19
gas/testsuite/gas/msp430/high-data-bss-sym.s
Normal 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
|
@ -24,4 +24,6 @@ if [expr [istarget "msp430-*-*"]] then {
|
|||||||
run_dump_test "bad"
|
run_dump_test "bad"
|
||||||
run_dump_test "errata_warns"
|
run_dump_test "errata_warns"
|
||||||
run_dump_test "errata_fixes"
|
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" } }
|
||||||
}
|
}
|
||||||
|
33
ld/ChangeLog
33
ld/ChangeLog
@ -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>
|
2017-08-26 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
PR ld/21997
|
PR ld/21997
|
||||||
|
@ -32,6 +32,7 @@ fragment <<EOF
|
|||||||
#include "bfdlink.h"
|
#include "bfdlink.h"
|
||||||
|
|
||||||
#include "ld.h"
|
#include "ld.h"
|
||||||
|
#include "getopt.h"
|
||||||
#include "ldmain.h"
|
#include "ldmain.h"
|
||||||
#include "ldmisc.h"
|
#include "ldmisc.h"
|
||||||
#include "ldexp.h"
|
#include "ldexp.h"
|
||||||
@ -39,6 +40,29 @@ fragment <<EOF
|
|||||||
#include "ldfile.h"
|
#include "ldfile.h"
|
||||||
#include "ldemul.h"
|
#include "ldemul.h"
|
||||||
#include "libiberty.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
|
EOF
|
||||||
|
|
||||||
@ -124,6 +148,32 @@ fi
|
|||||||
if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
|
if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
|
||||||
fragment <<EOF
|
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
|
/* Helper function for place_orphan that computes the size
|
||||||
of sections already mapped to the given statement. */
|
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_constructors_statement_enum:
|
||||||
case lang_assignment_statement_enum:
|
case lang_assignment_statement_enum:
|
||||||
|
case lang_padding_statement_enum:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lang_wild_statement_enum:
|
case lang_wild_statement_enum:
|
||||||
amount += scan_children (l->wild_statement.children.head);
|
amount += scan_children (l->wild_statement.children.head);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case lang_data_statement_enum:
|
||||||
|
amount += data_statement_size (&l->data_statement);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf (stderr, "msp430 orphan placer: unhandled lang type %d\n", l->header.type);
|
fprintf (stderr, "msp430 orphan placer: unhandled lang type %d\n", l->header.type);
|
||||||
break;
|
break;
|
||||||
@ -174,7 +229,6 @@ gld${EMULATION_NAME}_place_orphan (asection * s,
|
|||||||
char * buf = NULL;
|
char * buf = NULL;
|
||||||
lang_output_section_statement_type * lower;
|
lang_output_section_statement_type * lower;
|
||||||
lang_output_section_statement_type * upper;
|
lang_output_section_statement_type * upper;
|
||||||
lang_output_section_statement_type * os;
|
|
||||||
|
|
||||||
if ((s->flags & SEC_ALLOC) == 0)
|
if ((s->flags & SEC_ALLOC) == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -211,71 +265,580 @@ gld${EMULATION_NAME}_place_orphan (asection * s,
|
|||||||
/* Find the corresponding lower and upper sections. */
|
/* Find the corresponding lower and upper sections. */
|
||||||
lower = lang_output_section_find (lower_name);
|
lower = lang_output_section_find (lower_name);
|
||||||
upper = lang_output_section_find (upper_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 && upper == NULL)
|
||||||
|
{
|
||||||
|
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)
|
if (lower == NULL)
|
||||||
{
|
{
|
||||||
os = upper;
|
einfo ("%P: error: no section named %s in linker script\n", name);
|
||||||
if (upper == NULL)
|
|
||||||
{
|
|
||||||
einfo ("%P: error: no section named %s or %s in linker script\n", lower_name, upper_name);
|
|
||||||
goto end;
|
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);
|
/* Always place orphaned sections in lower. Optimal placement of either
|
||||||
|
sections is performed later, once section sizes have been finalized. */
|
||||||
/* Also check forwards for other statements assigned to the same region. */
|
lang_add_section (& lower->children, s, NULL, lower);
|
||||||
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);
|
|
||||||
end:
|
end:
|
||||||
free (upper_name);
|
free (upper_name);
|
||||||
free (lower_name);
|
free (lower_name);
|
||||||
if (buf)
|
if (buf)
|
||||||
free (buf);
|
free (buf);
|
||||||
return os;
|
return lower;
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fragment <<EOF
|
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 =
|
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
|
||||||
{
|
{
|
||||||
${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse},
|
${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse},
|
||||||
${LDEMUL_SYSLIB-syslib_default},
|
${LDEMUL_SYSLIB-syslib_default},
|
||||||
${LDEMUL_HLL-hll_default},
|
${LDEMUL_HLL-hll_default},
|
||||||
${LDEMUL_AFTER_PARSE-after_parse_default},
|
${LDEMUL_AFTER_PARSE-after_parse_default},
|
||||||
${LDEMUL_AFTER_OPEN-after_open_default},
|
msp430_elf_after_open,
|
||||||
${LDEMUL_AFTER_ALLOCATION-after_allocation_default},
|
msp430_elf_after_allocation,
|
||||||
${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
|
${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
|
||||||
${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
|
${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
|
||||||
${LDEMUL_BEFORE_ALLOCATION-before_allocation_default},
|
${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_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan},
|
||||||
${LDEMUL_SET_SYMBOLS-NULL},
|
${LDEMUL_SET_SYMBOLS-NULL},
|
||||||
${LDEMUL_PARSE_ARGS-NULL},
|
${LDEMUL_PARSE_ARGS-NULL},
|
||||||
${LDEMUL_ADD_OPTIONS-NULL},
|
gld${EMULATION_NAME}_add_options,
|
||||||
${LDEMUL_HANDLE_OPTION-NULL},
|
gld${EMULATION_NAME}_handle_option,
|
||||||
${LDEMUL_UNRECOGNIZED_FILE-NULL},
|
${LDEMUL_UNRECOGNIZED_FILE-NULL},
|
||||||
${LDEMUL_LIST_OPTIONS-NULL},
|
gld${EMULATION_NAME}_list_options,
|
||||||
${LDEMUL_RECOGNIZED_FILE-NULL},
|
${LDEMUL_RECOGNIZED_FILE-NULL},
|
||||||
${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
|
${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
|
||||||
${LDEMUL_NEW_VERS_PATTERN-NULL},
|
${LDEMUL_NEW_VERS_PATTERN-NULL},
|
||||||
|
@ -7260,6 +7260,29 @@ Denotes a portion of RAM located above @samp{.bss} section.
|
|||||||
The last two sections are used by gcc.
|
The last two sections are used by gcc.
|
||||||
@end table
|
@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
|
@ifclear GENERIC
|
||||||
@lowersections
|
@lowersections
|
||||||
@end ifclear
|
@end ifclear
|
||||||
|
3
ld/testsuite/ld-msp430-elf/main-bss-lower.d
Normal file
3
ld/testsuite/ld-msp430-elf/main-bss-lower.d
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#...
|
||||||
|
Disassembly of section .lower.bss:
|
||||||
|
#pass
|
3
ld/testsuite/ld-msp430-elf/main-bss-upper.d
Normal file
3
ld/testsuite/ld-msp430-elf/main-bss-upper.d
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#...
|
||||||
|
Disassembly of section .upper.bss:
|
||||||
|
#pass
|
3
ld/testsuite/ld-msp430-elf/main-const-lower.d
Normal file
3
ld/testsuite/ld-msp430-elf/main-const-lower.d
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#...
|
||||||
|
Disassembly of section .lower.rodata:
|
||||||
|
#pass
|
3
ld/testsuite/ld-msp430-elf/main-const-upper.d
Normal file
3
ld/testsuite/ld-msp430-elf/main-const-upper.d
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#...
|
||||||
|
Disassembly of section .upper.rodata:
|
||||||
|
#pass
|
3
ld/testsuite/ld-msp430-elf/main-text-lower.d
Normal file
3
ld/testsuite/ld-msp430-elf/main-text-lower.d
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#...
|
||||||
|
Disassembly of section .lower.text:
|
||||||
|
#pass
|
6
ld/testsuite/ld-msp430-elf/main-text-upper.d
Normal file
6
ld/testsuite/ld-msp430-elf/main-text-upper.d
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
.*: file format.*msp430.*
|
||||||
|
|
||||||
|
|
||||||
|
Disassembly of section .upper.text:
|
||||||
|
#...
|
3
ld/testsuite/ld-msp430-elf/main-var-lower.d
Normal file
3
ld/testsuite/ld-msp430-elf/main-var-lower.d
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#...
|
||||||
|
Disassembly of section .lower.data:
|
||||||
|
#pass
|
3
ld/testsuite/ld-msp430-elf/main-var-upper.d
Normal file
3
ld/testsuite/ld-msp430-elf/main-var-upper.d
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#...
|
||||||
|
Disassembly of section .upper.data:
|
||||||
|
#pass
|
78
ld/testsuite/ld-msp430-elf/main-with-data-bss-unique-sec.s
Normal file
78
ld/testsuite/ld-msp430-elf/main-with-data-bss-unique-sec.s
Normal 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
|
74
ld/testsuite/ld-msp430-elf/main-with-data-bss.s
Normal file
74
ld/testsuite/ld-msp430-elf/main-with-data-bss.s
Normal 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
|
@ -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
|
59
ld/testsuite/ld-msp430-elf/main-with-text-rodata.s
Normal file
59
ld/testsuite/ld-msp430-elf/main-with-text-rodata.s
Normal 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
|
141
ld/testsuite/ld-msp430-elf/msp430-elf.exp
Normal file
141
ld/testsuite/ld-msp430-elf/msp430-elf.exp
Normal 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
|
54
ld/testsuite/ld-msp430-elf/msp430-no-lower.ld
Normal file
54
ld/testsuite/ld-msp430-elf/msp430-no-lower.ld
Normal 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.*)
|
||||||
|
}
|
||||||
|
}
|
49
ld/testsuite/ld-msp430-elf/msp430-tiny-ram.ld
Normal file
49
ld/testsuite/ld-msp430-elf/msp430-tiny-ram.ld
Normal 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
|
||||||
|
}
|
48
ld/testsuite/ld-msp430-elf/msp430-tiny-rom.ld
Normal file
48
ld/testsuite/ld-msp430-elf/msp430-tiny-rom.ld
Normal 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
|
||||||
|
}
|
78
ld/testsuite/ld-msp430-elf/msp430.ld
Normal file
78
ld/testsuite/ld-msp430-elf/msp430.ld
Normal 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.*)
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user