mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
ld/
* ld.texinfo (INSERT): Describe. * ldgram.y (ldgram_in_script, ldgram_had_equals): Delete. (INSERT_K, AFTER, BEFORE): Add as tokens. (ifile_p1): Handle INSERT statements. (saved_script_handle, force_make_executable): Move to.. * ldmain.c: ..here. (previous_script_handle): New global var. * ldmain.h (saved_script_handle, force_make_executable): Declare. (previous_script_handle): Likewise. * ldlex.l (INSERT_K, AFTER, BEFORE): Add tokens. * lexsup.c (parge_args <-T>): Set previous_script_handle. * ldlang.c (lang_for_each_statement_worker): Handle insert statement. (map_input_to_output_sections, print_statement): Likewise. (lang_size_sections_1, lang_do_assignments_1): Likewise. (insert_os_after): New function, extracted from.. (lang_insert_orphan): ..here. (process_insert_statements): New function. (lang_process): Call it. (lang_add_insert): New function. * ldlang.h (lang_insert_statement_enum): New. (lang_insert_statement_type): New. (lang_statement_union_type): Add insert_statement. (lang_add_insert): Declare. ld/testsuite/ * ld-spu/ovl.lnk: Delete overlay. * ld-spu/ovl1.lnk: New file. * ld-spu/ovl2.lnk: New file. * ld-spu/ovl.d: Update. * ld-spu/ovl2.d: Update.
This commit is contained in:
parent
5ca3b13d65
commit
53d25da64b
26
ld/ChangeLog
26
ld/ChangeLog
@ -1,3 +1,29 @@
|
||||
2008-01-25 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* ld.texinfo (INSERT): Describe.
|
||||
* ldgram.y (ldgram_in_script, ldgram_had_equals): Delete.
|
||||
(INSERT_K, AFTER, BEFORE): Add as tokens.
|
||||
(ifile_p1): Handle INSERT statements.
|
||||
(saved_script_handle, force_make_executable): Move to..
|
||||
* ldmain.c: ..here.
|
||||
(previous_script_handle): New global var.
|
||||
* ldmain.h (saved_script_handle, force_make_executable): Declare.
|
||||
(previous_script_handle): Likewise.
|
||||
* ldlex.l (INSERT_K, AFTER, BEFORE): Add tokens.
|
||||
* lexsup.c (parge_args <-T>): Set previous_script_handle.
|
||||
* ldlang.c (lang_for_each_statement_worker): Handle insert statement.
|
||||
(map_input_to_output_sections, print_statement): Likewise.
|
||||
(lang_size_sections_1, lang_do_assignments_1): Likewise.
|
||||
(insert_os_after): New function, extracted from..
|
||||
(lang_insert_orphan): ..here.
|
||||
(process_insert_statements): New function.
|
||||
(lang_process): Call it.
|
||||
(lang_add_insert): New function.
|
||||
* ldlang.h (lang_insert_statement_enum): New.
|
||||
(lang_insert_statement_type): New.
|
||||
(lang_statement_union_type): Add insert_statement.
|
||||
(lang_add_insert): Declare.
|
||||
|
||||
2008-01-18 Bob Wilson <bob.wilson@acm.org>
|
||||
|
||||
* scripttempl/elfxtensa.sc: Merge ENTRY and .note.gnu.build-id
|
||||
|
@ -297,10 +297,11 @@ augments the main linker script used for the link (either the default
|
||||
linker script or the one specified by using @samp{-T}). This feature
|
||||
permits the linker to link against a file which appears to be an object
|
||||
or an archive, but actually merely defines some symbol values, or uses
|
||||
@code{INPUT} or @code{GROUP} to load other objects. Note that
|
||||
specifying a script in this way merely augments the main linker script;
|
||||
use the @samp{-T} option to replace the default linker script entirely.
|
||||
@xref{Scripts}.
|
||||
@code{INPUT} or @code{GROUP} to load other objects. Specifying a
|
||||
script in this way merely augments the main linker script, with the
|
||||
extra commands placed after the main script; use the @samp{-T} option
|
||||
to replace the default linker script entirely, but note the effect of
|
||||
the @code{INSERT} command. @xref{Scripts}.
|
||||
|
||||
For options whose names are a single letter,
|
||||
option arguments must either follow the option letter without intervening
|
||||
@ -2903,6 +2904,35 @@ This command has the same effect as the @samp{--no-define-common}
|
||||
command-line option: to make @code{ld} omit the assignment of addresses
|
||||
to common symbols even for a non-relocatable output file.
|
||||
|
||||
@item INSERT [ AFTER | BEFORE ] @var{output_section}
|
||||
@kindex INSERT
|
||||
@cindex insert user script into default script
|
||||
This command is typically used in a script specified by @samp{-T} to
|
||||
augment the default @code{SECTIONS} with, for example, overlays. It
|
||||
inserts all prior linker script statements after (or before)
|
||||
@var{output_section}, and also causes @samp{-T} to not override the
|
||||
default linker script. The exact insertion point is as for orphan
|
||||
sections. @xref{Location Counter}. The insertion happens after the
|
||||
linker has mapped input sections to output sections. Prior to the
|
||||
insertion, since @samp{-T} scripts are parsed before the default
|
||||
linker script, statements in the @samp{-T} script occur before the
|
||||
default linker script statements in the internal linker representation
|
||||
of the script. In particular, input section assignments will be made
|
||||
to @samp{-T} output sections before those in the default script. Here
|
||||
is an example of how a @samp{-T} script using @code{INSERT} might look:
|
||||
|
||||
@smallexample
|
||||
SECTIONS
|
||||
@{
|
||||
OVERLAY :
|
||||
@{
|
||||
.ov1 @{ ov1*(.text) @}
|
||||
.ov2 @{ ov2*(.text) @}
|
||||
@}
|
||||
@}
|
||||
INSERT AFTER .text;
|
||||
@end smallexample
|
||||
|
||||
@item NOCROSSREFS(@var{section} @var{section} @dots{})
|
||||
@kindex NOCROSSREFS(@var{sections})
|
||||
@cindex cross references
|
||||
|
12
ld/ldgram.y
12
ld/ldgram.y
@ -49,11 +49,6 @@
|
||||
static enum section_type sectype;
|
||||
static lang_memory_region_type *region;
|
||||
|
||||
FILE *saved_script_handle = NULL;
|
||||
bfd_boolean force_make_executable = FALSE;
|
||||
|
||||
bfd_boolean ldgram_in_script = FALSE;
|
||||
bfd_boolean ldgram_had_equals = FALSE;
|
||||
bfd_boolean ldgram_had_keep = FALSE;
|
||||
char *ldgram_vers_current_lang = NULL;
|
||||
|
||||
@ -127,7 +122,8 @@ static int error_index;
|
||||
%token END
|
||||
%left <token> '('
|
||||
%token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE
|
||||
%token SECTIONS PHDRS DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
|
||||
%token SECTIONS PHDRS INSERT_K AFTER BEFORE
|
||||
%token DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
|
||||
%token SORT_BY_NAME SORT_BY_ALIGNMENT
|
||||
%token '{' '}'
|
||||
%token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
|
||||
@ -352,6 +348,10 @@ ifile_p1:
|
||||
lang_add_nocrossref ($3);
|
||||
}
|
||||
| EXTERN '(' extern_name_list ')'
|
||||
| INSERT_K AFTER NAME
|
||||
{ lang_add_insert ($3, 0); }
|
||||
| INSERT_K BEFORE NAME
|
||||
{ lang_add_insert ($3, 1); }
|
||||
;
|
||||
|
||||
input_list:
|
||||
|
307
ld/ldlang.c
307
ld/ldlang.c
@ -845,6 +845,7 @@ lang_for_each_statement_worker (void (*func) (lang_statement_union_type *),
|
||||
case lang_padding_statement_enum:
|
||||
case lang_address_statement_enum:
|
||||
case lang_fill_statement_enum:
|
||||
case lang_insert_statement_enum:
|
||||
break;
|
||||
default:
|
||||
FAIL ();
|
||||
@ -1451,6 +1452,73 @@ output_prev_sec_find (lang_output_section_statement_type *os)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Look for a suitable place for a new output section statement. The
|
||||
idea is to skip over anything that might be inside a SECTIONS {}
|
||||
statement in a script, before we find another output section
|
||||
statement. Assignments to "dot" before an output section statement
|
||||
are assumed to belong to it. An exception to this rule is made for
|
||||
the first assignment to dot, otherwise we might put an orphan
|
||||
before . = . + SIZEOF_HEADERS or similar assignments that set the
|
||||
initial address. */
|
||||
|
||||
static lang_statement_union_type **
|
||||
insert_os_after (lang_output_section_statement_type *after)
|
||||
{
|
||||
lang_statement_union_type **where;
|
||||
lang_statement_union_type **assign = NULL;
|
||||
bfd_boolean ignore_first;
|
||||
|
||||
ignore_first
|
||||
= after == &lang_output_section_statement.head->output_section_statement;
|
||||
|
||||
for (where = &after->header.next;
|
||||
*where != NULL;
|
||||
where = &(*where)->header.next)
|
||||
{
|
||||
switch ((*where)->header.type)
|
||||
{
|
||||
case lang_assignment_statement_enum:
|
||||
if (assign == NULL)
|
||||
{
|
||||
lang_assignment_statement_type *ass;
|
||||
|
||||
ass = &(*where)->assignment_statement;
|
||||
if (ass->exp->type.node_class != etree_assert
|
||||
&& ass->exp->assign.dst[0] == '.'
|
||||
&& ass->exp->assign.dst[1] == 0
|
||||
&& !ignore_first)
|
||||
assign = where;
|
||||
}
|
||||
ignore_first = FALSE;
|
||||
continue;
|
||||
case lang_wild_statement_enum:
|
||||
case lang_input_section_enum:
|
||||
case lang_object_symbols_statement_enum:
|
||||
case lang_fill_statement_enum:
|
||||
case lang_data_statement_enum:
|
||||
case lang_reloc_statement_enum:
|
||||
case lang_padding_statement_enum:
|
||||
case lang_constructors_statement_enum:
|
||||
assign = NULL;
|
||||
continue;
|
||||
case lang_output_section_statement_enum:
|
||||
if (assign != NULL)
|
||||
where = assign;
|
||||
break;
|
||||
case lang_input_statement_enum:
|
||||
case lang_address_statement_enum:
|
||||
case lang_target_statement_enum:
|
||||
case lang_output_statement_enum:
|
||||
case lang_group_statement_enum:
|
||||
case lang_insert_statement_enum:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return where;
|
||||
}
|
||||
|
||||
lang_output_section_statement_type *
|
||||
lang_insert_orphan (asection *s,
|
||||
const char *secname,
|
||||
@ -1606,64 +1674,7 @@ lang_insert_orphan (asection *s,
|
||||
|
||||
if (place->stmt == NULL)
|
||||
{
|
||||
lang_statement_union_type **where;
|
||||
lang_statement_union_type **assign = NULL;
|
||||
bfd_boolean ignore_first;
|
||||
|
||||
/* Look for a suitable place for the new statement list.
|
||||
The idea is to skip over anything that might be inside
|
||||
a SECTIONS {} statement in a script, before we find
|
||||
another output_section_statement. Assignments to "dot"
|
||||
before an output section statement are assumed to
|
||||
belong to it. An exception to this rule is made for
|
||||
the first assignment to dot, otherwise we might put an
|
||||
orphan before . = . + SIZEOF_HEADERS or similar
|
||||
assignments that set the initial address. */
|
||||
|
||||
ignore_first = after == (&lang_output_section_statement.head
|
||||
->output_section_statement);
|
||||
for (where = &after->header.next;
|
||||
*where != NULL;
|
||||
where = &(*where)->header.next)
|
||||
{
|
||||
switch ((*where)->header.type)
|
||||
{
|
||||
case lang_assignment_statement_enum:
|
||||
if (assign == NULL)
|
||||
{
|
||||
lang_assignment_statement_type *ass;
|
||||
ass = &(*where)->assignment_statement;
|
||||
if (ass->exp->type.node_class != etree_assert
|
||||
&& ass->exp->assign.dst[0] == '.'
|
||||
&& ass->exp->assign.dst[1] == 0
|
||||
&& !ignore_first)
|
||||
assign = where;
|
||||
}
|
||||
ignore_first = FALSE;
|
||||
continue;
|
||||
case lang_wild_statement_enum:
|
||||
case lang_input_section_enum:
|
||||
case lang_object_symbols_statement_enum:
|
||||
case lang_fill_statement_enum:
|
||||
case lang_data_statement_enum:
|
||||
case lang_reloc_statement_enum:
|
||||
case lang_padding_statement_enum:
|
||||
case lang_constructors_statement_enum:
|
||||
assign = NULL;
|
||||
continue;
|
||||
case lang_output_section_statement_enum:
|
||||
if (assign != NULL)
|
||||
where = assign;
|
||||
break;
|
||||
case lang_input_statement_enum:
|
||||
case lang_address_statement_enum:
|
||||
case lang_target_statement_enum:
|
||||
case lang_output_statement_enum:
|
||||
case lang_group_statement_enum:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
lang_statement_union_type **where = insert_os_after (after);
|
||||
|
||||
*add.tail = *where;
|
||||
*where = add.head;
|
||||
@ -3312,6 +3323,154 @@ map_input_to_output_sections
|
||||
aos->addr_tree = s->address_statement.address;
|
||||
}
|
||||
break;
|
||||
case lang_insert_statement_enum:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* An insert statement snips out all the linker statements from the
|
||||
start of the list and places them after the output section
|
||||
statement specified by the insert. This operation is complicated
|
||||
by the fact that we keep a doubly linked list of output section
|
||||
statements as well as the singly linked list of all statements. */
|
||||
|
||||
static void
|
||||
process_insert_statements (void)
|
||||
{
|
||||
lang_statement_union_type **s;
|
||||
lang_output_section_statement_type *first_os = NULL;
|
||||
lang_output_section_statement_type *last_os = NULL;
|
||||
|
||||
/* "start of list" is actually the statement immediately after
|
||||
the special abs_section output statement, so that it isn't
|
||||
reordered. */
|
||||
s = &lang_output_section_statement.head;
|
||||
while (*(s = &(*s)->header.next) != NULL)
|
||||
{
|
||||
if ((*s)->header.type == lang_output_section_statement_enum)
|
||||
{
|
||||
/* Keep pointers to the first and last output section
|
||||
statement in the sequence we may be about to move. */
|
||||
last_os = &(*s)->output_section_statement;
|
||||
if (first_os == NULL)
|
||||
first_os = last_os;
|
||||
}
|
||||
else if ((*s)->header.type == lang_insert_statement_enum)
|
||||
{
|
||||
lang_insert_statement_type *i = &(*s)->insert_statement;
|
||||
lang_output_section_statement_type *where;
|
||||
lang_output_section_statement_type *os;
|
||||
lang_statement_union_type **ptr;
|
||||
lang_statement_union_type *first;
|
||||
|
||||
where = lang_output_section_find (i->where);
|
||||
if (where != NULL && i->is_before)
|
||||
{
|
||||
do
|
||||
where = where->prev;
|
||||
while (where != NULL && where->constraint == -1);
|
||||
}
|
||||
if (where == NULL)
|
||||
{
|
||||
einfo (_("%X%P: %s not found for insert\n"), i->where);
|
||||
continue;
|
||||
}
|
||||
/* You can't insert into the list you are moving. */
|
||||
for (os = first_os; os != NULL; os = os->next)
|
||||
if (os == where || os == last_os)
|
||||
break;
|
||||
if (os == where)
|
||||
{
|
||||
einfo (_("%X%P: %s not found for insert\n"), i->where);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Deal with reordering the output section statement list. */
|
||||
if (last_os != NULL)
|
||||
{
|
||||
asection *first_sec, *last_sec;
|
||||
|
||||
/* Snip out the output sections we are moving. */
|
||||
first_os->prev->next = last_os->next;
|
||||
if (last_os->next == NULL)
|
||||
lang_output_section_statement.tail
|
||||
= (union lang_statement_union **) &first_os->prev->next;
|
||||
else
|
||||
last_os->next->prev = first_os->prev;
|
||||
/* Add them in at the new position. */
|
||||
last_os->next = where->next;
|
||||
if (where->next == NULL)
|
||||
lang_output_section_statement.tail
|
||||
= (union lang_statement_union **) &last_os->next;
|
||||
else
|
||||
where->next->prev = last_os;
|
||||
first_os->prev = where;
|
||||
where->next = first_os;
|
||||
|
||||
/* Move the bfd sections in the same way. */
|
||||
first_sec = NULL;
|
||||
last_sec = NULL;
|
||||
for (os = first_os; os != NULL; os = os->next)
|
||||
{
|
||||
if (os->bfd_section != NULL
|
||||
&& os->bfd_section->owner != NULL)
|
||||
{
|
||||
last_sec = os->bfd_section;
|
||||
if (first_sec == NULL)
|
||||
first_sec = last_sec;
|
||||
}
|
||||
if (os == last_os)
|
||||
break;
|
||||
}
|
||||
if (last_sec != NULL)
|
||||
{
|
||||
asection *sec = where->bfd_section;
|
||||
if (sec == NULL)
|
||||
sec = output_prev_sec_find (where);
|
||||
|
||||
/* The place we want to insert must come after the
|
||||
sections we are moving. So if we find no
|
||||
section or if the section is the same as our
|
||||
last section, then no move is needed. */
|
||||
if (sec != NULL && sec != last_sec)
|
||||
{
|
||||
/* Trim them off. */
|
||||
if (first_sec->prev != NULL)
|
||||
first_sec->prev->next = last_sec->next;
|
||||
else
|
||||
output_bfd->sections = last_sec->next;
|
||||
if (last_sec->next != NULL)
|
||||
last_sec->next->prev = first_sec->prev;
|
||||
else
|
||||
output_bfd->section_last = first_sec->prev;
|
||||
/* Add back. */
|
||||
last_sec->next = sec->next;
|
||||
if (sec->next != NULL)
|
||||
sec->next->prev = last_sec;
|
||||
else
|
||||
output_bfd->section_last = last_sec;
|
||||
first_sec->prev = sec;
|
||||
sec->next = first_sec;
|
||||
}
|
||||
}
|
||||
|
||||
first_os = NULL;
|
||||
last_os = NULL;
|
||||
}
|
||||
|
||||
ptr = insert_os_after (where);
|
||||
/* Snip everything after the abs_section output statement we
|
||||
know is at the start of the list, up to and including
|
||||
the insert statement we are currently processing. */
|
||||
first = lang_output_section_statement.head->header.next;
|
||||
lang_output_section_statement.head->header.next = (*s)->header.next;
|
||||
/* Add them back where they belong. */
|
||||
*s = *ptr;
|
||||
if (*s == NULL)
|
||||
statement_list.tail = s;
|
||||
*ptr = first;
|
||||
s = &lang_output_section_statement.head;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3954,6 +4113,11 @@ print_statement (lang_statement_union_type *s,
|
||||
case lang_group_statement_enum:
|
||||
print_group (&s->group_statement, os);
|
||||
break;
|
||||
case lang_insert_statement_enum:
|
||||
minfo ("INSERT %s %s\n",
|
||||
s->insert_statement.is_before ? "BEFORE" : "AFTER",
|
||||
s->insert_statement.where);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4734,13 +4898,16 @@ lang_size_sections_1
|
||||
fill, dot, relax, check_regions);
|
||||
break;
|
||||
|
||||
default:
|
||||
FAIL ();
|
||||
case lang_insert_statement_enum:
|
||||
break;
|
||||
|
||||
/* We can only get here when relaxing is turned on. */
|
||||
case lang_address_statement_enum:
|
||||
break;
|
||||
|
||||
default:
|
||||
FAIL ();
|
||||
break;
|
||||
}
|
||||
prev = &s->header.next;
|
||||
}
|
||||
@ -4999,12 +5166,15 @@ lang_do_assignments_1 (lang_statement_union_type *s,
|
||||
current_os, fill, dot);
|
||||
break;
|
||||
|
||||
default:
|
||||
FAIL ();
|
||||
case lang_insert_statement_enum:
|
||||
break;
|
||||
|
||||
case lang_address_statement_enum:
|
||||
break;
|
||||
|
||||
default:
|
||||
FAIL ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return dot;
|
||||
@ -5853,6 +6023,8 @@ lang_process (void)
|
||||
to the correct output sections. */
|
||||
map_input_to_output_sections (statement_list.head, NULL, NULL);
|
||||
|
||||
process_insert_statements ();
|
||||
|
||||
/* Find any sections not attached explicitly and handle them. */
|
||||
lang_place_orphans ();
|
||||
|
||||
@ -6269,6 +6441,17 @@ lang_add_output_format (const char *format,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lang_add_insert (const char *where, int is_before)
|
||||
{
|
||||
lang_insert_statement_type *new;
|
||||
|
||||
new = new_stat (lang_insert_statement, stat_ptr);
|
||||
new->where = where;
|
||||
new->is_before = is_before;
|
||||
saved_script_handle = previous_script_handle;
|
||||
}
|
||||
|
||||
/* Enter a group. This creates a new lang_group_statement, and sets
|
||||
stat_ptr to build new statements within the group. */
|
||||
|
||||
|
11
ld/ldlang.h
11
ld/ldlang.h
@ -79,6 +79,7 @@ typedef struct lang_statement_header_struct
|
||||
lang_output_statement_enum,
|
||||
lang_padding_statement_enum,
|
||||
lang_group_statement_enum,
|
||||
lang_insert_statement_enum,
|
||||
lang_constructors_statement_enum
|
||||
} type;
|
||||
} lang_statement_header_type;
|
||||
@ -352,6 +353,13 @@ typedef struct
|
||||
lang_statement_list_type children;
|
||||
} lang_group_statement_type;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
lang_statement_header_type header;
|
||||
const char *where;
|
||||
bfd_boolean is_before;
|
||||
} lang_insert_statement_type;
|
||||
|
||||
typedef union lang_statement_union
|
||||
{
|
||||
lang_statement_header_type header;
|
||||
@ -370,6 +378,7 @@ typedef union lang_statement_union
|
||||
lang_fill_statement_type fill_statement;
|
||||
lang_padding_statement_type padding_statement;
|
||||
lang_group_statement_type group_statement;
|
||||
lang_insert_statement_type insert_statement;
|
||||
} lang_statement_union_type;
|
||||
|
||||
/* This structure holds information about a program header, from the
|
||||
@ -565,6 +574,8 @@ extern void lang_size_sections
|
||||
(bfd_boolean *, bfd_boolean);
|
||||
extern void one_lang_size_sections_pass
|
||||
(bfd_boolean *, bfd_boolean);
|
||||
extern void lang_add_insert
|
||||
(const char *, int);
|
||||
extern void lang_enter_group
|
||||
(void);
|
||||
extern void lang_leave_group
|
||||
|
@ -274,6 +274,9 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
|
||||
<BOTH,SCRIPT>"FORCE_COMMON_ALLOCATION" { RTOKEN(FORCE_COMMON_ALLOCATION);}
|
||||
<BOTH,SCRIPT>"INHIBIT_COMMON_ALLOCATION" { RTOKEN(INHIBIT_COMMON_ALLOCATION);}
|
||||
<BOTH,SCRIPT>"SECTIONS" { RTOKEN(SECTIONS);}
|
||||
<BOTH,SCRIPT>"INSERT" { RTOKEN(INSERT_K);}
|
||||
<BOTH,SCRIPT>"AFTER" { RTOKEN(AFTER);}
|
||||
<BOTH,SCRIPT>"BEFORE" { RTOKEN(BEFORE);}
|
||||
<BOTH,SCRIPT>"FILL" { RTOKEN(FILL);}
|
||||
<BOTH,SCRIPT>"STARTUP" { RTOKEN(STARTUP);}
|
||||
<BOTH,SCRIPT>"OUTPUT_FORMAT" { RTOKEN(OUTPUT_FORMAT);}
|
||||
|
@ -60,6 +60,10 @@ extern void *sbrk ();
|
||||
|
||||
/* EXPORTS */
|
||||
|
||||
FILE *saved_script_handle = NULL;
|
||||
FILE *previous_script_handle = NULL;
|
||||
bfd_boolean force_make_executable = FALSE;
|
||||
|
||||
char *default_target;
|
||||
const char *output_filename = "a.out";
|
||||
|
||||
|
@ -26,6 +26,9 @@ extern char *program_name;
|
||||
extern const char *ld_sysroot;
|
||||
extern char *ld_canon_sysroot;
|
||||
extern int ld_canon_sysroot_len;
|
||||
extern FILE *saved_script_handle;
|
||||
extern FILE *previous_script_handle;
|
||||
extern bfd_boolean force_make_executable;
|
||||
extern bfd *output_bfd;
|
||||
extern char *default_target;
|
||||
extern bfd_boolean trace_files;
|
||||
|
@ -1166,9 +1166,11 @@ parse_args (unsigned argc, char **argv)
|
||||
trace_files = TRUE;
|
||||
break;
|
||||
case 'T':
|
||||
previous_script_handle = saved_script_handle;
|
||||
ldfile_open_command_file (optarg);
|
||||
parser_input = input_script;
|
||||
yyparse ();
|
||||
previous_script_handle = NULL;
|
||||
break;
|
||||
case OPTION_DEFAULT_SCRIPT:
|
||||
command_line.default_script = optarg;
|
||||
|
@ -1,3 +1,11 @@
|
||||
2008-01-25 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* ld-spu/ovl.lnk: Delete overlay.
|
||||
* ld-spu/ovl1.lnk: New file.
|
||||
* ld-spu/ovl2.lnk: New file.
|
||||
* ld-spu/ovl.d: Update.
|
||||
* ld-spu/ovl2.d: Update.
|
||||
|
||||
2008-01-23 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
* ld-gc/gc.c: Make sure used_func is not inlined.
|
||||
|
@ -1,5 +1,5 @@
|
||||
#source: ovl.s
|
||||
#ld: -N -T ovl.lnk --emit-relocs
|
||||
#ld: -N -T ovl1.lnk -T ovl.lnk --emit-relocs
|
||||
#objdump: -D -r
|
||||
|
||||
.*elf32-spu
|
||||
|
@ -2,13 +2,6 @@ SECTIONS
|
||||
{
|
||||
. = SIZEOF_HEADERS;
|
||||
.text : { *(.text) *(.stub) }
|
||||
|
||||
OVERLAY 0x400 :
|
||||
{
|
||||
.ov_a1 { *(.ov_a1) }
|
||||
.ov_a2 { *(.ov_a2) }
|
||||
}
|
||||
|
||||
.data : { *(.data) *(.ovtab) }
|
||||
.bss : { *(.bss) }
|
||||
}
|
||||
|
9
ld/testsuite/ld-spu/ovl1.lnk
Normal file
9
ld/testsuite/ld-spu/ovl1.lnk
Normal file
@ -0,0 +1,9 @@
|
||||
SECTIONS
|
||||
{
|
||||
OVERLAY 0x400 :
|
||||
{
|
||||
.ov_a1 { *(.ov_a1) }
|
||||
.ov_a2 { *(.ov_a2) }
|
||||
}
|
||||
}
|
||||
INSERT AFTER .text;
|
@ -1,5 +1,5 @@
|
||||
#source: ovl2.s
|
||||
#ld: -N -T ovl.lnk --emit-relocs
|
||||
#ld: -N -T ovl2.lnk -T ovl.lnk --emit-relocs
|
||||
#objdump: -D -r
|
||||
|
||||
.*elf32-spu
|
||||
|
10
ld/testsuite/ld-spu/ovl2.lnk
Normal file
10
ld/testsuite/ld-spu/ovl2.lnk
Normal file
@ -0,0 +1,10 @@
|
||||
SECTIONS
|
||||
{
|
||||
OVERLAY 0x400 :
|
||||
{
|
||||
.ov_a1 { *(.ov_a1) }
|
||||
.ov_a2 { *(.ov_a2) }
|
||||
.empty { empty.o?(.text) }
|
||||
}
|
||||
}
|
||||
INSERT BEFORE .data;
|
Loading…
Reference in New Issue
Block a user