aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog19
-rw-r--r--ld/NEWS11
-rw-r--r--ld/emultempl/elf32.em2
-rw-r--r--ld/ldlang.c114
-rw-r--r--ld/ldlang.h10
5 files changed, 78 insertions, 78 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 8123c0a..2f49f6b 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,22 @@
+2008-09-07 Alan Modra <amodra@bigpond.net.au>
+
+ * ldlang.h (lang_output_section_find): Define.
+ (lang_output_section_statement_lookup): Update prototype.
+ * ldlang.c (lang_output_section_find,
+ lang_output_section_statement_lookup_1): Merge into..
+ (lang_output_section_statement_lookup): ..here. Update all callers.
+ (process_insert_statements): Set constraint negative
+ for output section statements we might be inserting. Make error
+ fatal on not finding insertion section.
+ (lang_output_section_find): Rather than comparing
+ output_section_statement.constraint against -1, test whether
+ it is postive.
+ (lang_output_section_statement_lookup_1): Likewise.
+ (output_prev_sec_find, strip_excluded_output_sections): Likewise.
+ (lang_record_phdrs): Likewise.
+ * emultempl/elf32.em (output_rel_find): Likewise.
+ * NEWS: Mention INSERT.
+
2008-08-26 Nick Clifton <nickc@redhat.com>
PR 6727
diff --git a/ld/NEWS b/ld/NEWS
index c7648a0..13eac98 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,6 +1,9 @@
-*- text -*-
+* Linker scripts support a new INSERT command that makes it easier to
+ augment the default script.
+
* Linker script input section filespecs may now specify a file within an
- archive by writing "archive:file".
+ archive by writing "archive:file".
* The --sort-common switch now has an optional argument which specifies the
direction of sorting.
@@ -8,9 +11,9 @@
* The M68K linker now supports multiple GOT generation schemes controlled via
the --got=<type> command line option.
-* The ARM EABI linker will now generate stubs for function calls to symbols that
- are too far away. The placement of the stubs is controlled by a new linker
- command line option: --stub-group-size=N.
+* The ARM EABI linker will now generate stubs for function calls to symbols
+ that are too far away. The placement of the stubs is controlled by a new
+ linker command line option: --stub-group-size=N.
Changes in 2.18:
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 955fc9f..be9d78d 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1583,7 +1583,7 @@ output_rel_find (asection *sec, int isdyn)
lookup != NULL;
lookup = lookup->next)
{
- if (lookup->constraint != -1
+ if (lookup->constraint >= 0
&& CONST_STRNEQ (lookup->name, ".rel"))
{
int lookrela = lookup->name[4] == 'a';
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 8d95254..b1b8806 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -1149,7 +1149,7 @@ lang_init (void)
first_file = lang_add_input_file (NULL, lang_input_file_is_marker_enum,
NULL);
abs_output_section =
- lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME);
+ lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME, 0, TRUE);
abs_output_section->bfd_section = bfd_abs_section_ptr;
@@ -1255,44 +1255,19 @@ lang_memory_default (asection *section)
}
lang_output_section_statement_type *
-lang_output_section_find (const char *const name)
+lang_output_section_statement_lookup (const char *const name,
+ int constraint,
+ bfd_boolean create)
{
struct out_section_hash_entry *entry;
- unsigned long hash;
entry = ((struct out_section_hash_entry *)
bfd_hash_lookup (&output_section_statement_table, name,
- FALSE, FALSE));
+ create, FALSE));
if (entry == NULL)
- return NULL;
-
- hash = entry->root.hash;
- do
{
- if (entry->s.output_section_statement.constraint != -1)
- return &entry->s.output_section_statement;
- entry = (struct out_section_hash_entry *) entry->root.next;
- }
- while (entry != NULL
- && entry->root.hash == hash
- && strcmp (name, entry->s.output_section_statement.name) == 0);
-
- return NULL;
-}
-
-static lang_output_section_statement_type *
-lang_output_section_statement_lookup_1 (const char *const name, int constraint)
-{
- struct out_section_hash_entry *entry;
- struct out_section_hash_entry *last_ent;
- unsigned long hash;
-
- entry = ((struct out_section_hash_entry *)
- bfd_hash_lookup (&output_section_statement_table, name,
- TRUE, FALSE));
- if (entry == NULL)
- {
- einfo (_("%P%F: failed creating section `%s': %E\n"), name);
+ if (create)
+ einfo (_("%P%F: failed creating section `%s': %E\n"), name);
return NULL;
}
@@ -1300,10 +1275,12 @@ lang_output_section_statement_lookup_1 (const char *const name, int constraint)
{
/* We have a section of this name, but it might not have the correct
constraint. */
- hash = entry->root.hash;
+ struct out_section_hash_entry *last_ent;
+ unsigned long hash = entry->root.hash;
+
do
{
- if (entry->s.output_section_statement.constraint != -1
+ if (entry->s.output_section_statement.constraint >= 0
&& (constraint == 0
|| (constraint == entry->s.output_section_statement.constraint
&& constraint != SPECIAL)))
@@ -1315,6 +1292,9 @@ lang_output_section_statement_lookup_1 (const char *const name, int constraint)
&& entry->root.hash == hash
&& strcmp (name, entry->s.output_section_statement.name) == 0);
+ if (!create)
+ return NULL;
+
entry
= ((struct out_section_hash_entry *)
output_section_statement_newfunc (NULL,
@@ -1334,12 +1314,6 @@ lang_output_section_statement_lookup_1 (const char *const name, int constraint)
return &entry->s.output_section_statement;
}
-lang_output_section_statement_type *
-lang_output_section_statement_lookup (const char *const name)
-{
- return lang_output_section_statement_lookup_1 (name, 0);
-}
-
/* A variant of lang_output_section_find used by place_orphan.
Returns the output statement that should precede a new output
statement for SEC. If an exact match is found on certain flags,
@@ -1502,7 +1476,7 @@ output_prev_sec_find (lang_output_section_statement_type *os)
for (lookup = os->prev; lookup != NULL; lookup = lookup->prev)
{
- if (lookup->constraint == -1)
+ if (lookup->constraint < 0)
continue;
if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL)
@@ -3378,7 +3352,7 @@ map_input_to_output_sections
{
lang_output_section_statement_type *aos
= (lang_output_section_statement_lookup
- (s->address_statement.section_name));
+ (s->address_statement.section_name, 0, TRUE));
if (aos->bfd_section == NULL)
init_os (aos, NULL, 0);
@@ -3403,6 +3377,7 @@ 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;
+ lang_output_section_statement_type *os;
/* "start of list" is actually the statement immediately after
the special abs_section output statement, so that it isn't
@@ -3415,6 +3390,12 @@ process_insert_statements (void)
/* 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;
+
+ /* Set constraint negative so that lang_output_section_find
+ won't match this output section statement. At this
+ stage in linking constraint has values in the range
+ [-1, ONLY_IN_RW]. */
+ last_os->constraint = -2 - last_os->constraint;
if (first_os == NULL)
first_os = last_os;
}
@@ -3422,7 +3403,6 @@ process_insert_statements (void)
{
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;
@@ -3431,21 +3411,12 @@ process_insert_statements (void)
{
do
where = where->prev;
- while (where != NULL && where->constraint == -1);
+ while (where != NULL && where->constraint < 0);
}
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;
+ einfo (_("%F%P: %s not found for insert\n"), i->where);
+ return;
}
/* Deal with reordering the output section statement list. */
@@ -3482,6 +3453,7 @@ process_insert_statements (void)
last_sec = NULL;
for (os = first_os; os != NULL; os = os->next)
{
+ os->constraint = -2 - os->constraint;
if (os->bfd_section != NULL
&& os->bfd_section->owner != NULL)
{
@@ -3542,6 +3514,14 @@ process_insert_statements (void)
s = &lang_output_section_statement.head;
}
}
+
+ /* Undo constraint twiddling. */
+ for (os = first_os; os != NULL; os = os->next)
+ {
+ os->constraint = -2 - os->constraint;
+ if (os == last_os)
+ break;
+ }
}
/* An output section might have been removed after its statement was
@@ -3569,7 +3549,7 @@ strip_excluded_output_sections (void)
asection *output_section;
bfd_boolean exclude;
- if (os->constraint == -1)
+ if (os->constraint < 0)
continue;
output_section = os->bfd_section;
@@ -5665,11 +5645,9 @@ lang_place_orphans (void)
|| command_line.force_common_definition)
{
if (default_common_section == NULL)
- {
- default_common_section =
- lang_output_section_statement_lookup (".bss");
-
- }
+ default_common_section
+ = lang_output_section_statement_lookup (".bss", 0,
+ TRUE);
lang_add_section (&default_common_section->children, s,
default_common_section);
}
@@ -5680,7 +5658,7 @@ lang_place_orphans (void)
{
lang_output_section_statement_type *os;
- os = lang_output_section_statement_lookup (s->name);
+ os = lang_output_section_statement_lookup (s->name, 0, TRUE);
lang_add_section (&os->children, s, os);
}
}
@@ -5827,12 +5805,10 @@ lang_enter_output_section_statement (const char *output_section_statement_name,
{
lang_output_section_statement_type *os;
- os = lang_output_section_statement_lookup_1 (output_section_statement_name,
- constraint);
+ os = lang_output_section_statement_lookup (output_section_statement_name,
+ constraint, TRUE);
current_section = os;
- /* Make next things chain into subchain of this. */
-
if (os->addr_tree == NULL)
{
os->addr_tree = address_exp;
@@ -5843,6 +5819,8 @@ lang_enter_output_section_statement (const char *output_section_statement_name,
else
os->flags = SEC_NEVER_LOAD;
os->block_value = 1;
+
+ /* Make next things chain into subchain of this. */
stat_ptr = &os->children;
os->subsection_alignment =
@@ -6639,7 +6617,7 @@ lang_record_phdrs (void)
{
lang_output_section_phdr_list *pl;
- if (os->constraint == -1)
+ if (os->constraint < 0)
continue;
pl = os->phdrs;
@@ -6720,7 +6698,7 @@ lang_record_phdrs (void)
{
lang_output_section_phdr_list *pl;
- if (os->constraint == -1
+ if (os->constraint < 0
|| os->bfd_section == NULL)
continue;
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 4846197..8b652a8 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -525,12 +525,13 @@ extern void lang_do_assignments
statement != (lang_input_statement_type *) NULL; \
statement = (lang_input_statement_type *) statement->next) \
+#define lang_output_section_find(NAME) \
+ lang_output_section_statement_lookup (NAME, 0, FALSE)
+
extern void lang_process
(void);
extern void ldlang_add_file
(lang_input_statement_type *);
-extern lang_output_section_statement_type *lang_output_section_find
- (const char * const);
extern lang_output_section_statement_type *lang_output_section_find_by_flags
(const asection *, lang_output_section_statement_type **,
lang_match_sec_type_func);
@@ -541,9 +542,8 @@ extern lang_input_statement_type *lang_add_input_file
(const char *, lang_input_file_enum_type, const char *);
extern void lang_add_keepsyms_file
(const char *);
-extern lang_output_section_statement_type *
- lang_output_section_statement_lookup
- (const char *const);
+extern lang_output_section_statement_type *lang_output_section_statement_lookup
+ (const char *const, int, bfd_boolean);
extern void ldlang_add_undef
(const char *const);
extern void lang_add_output_format