This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
ld output_section_statment related tidy
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils <binutils at sourceware dot org>
- Date: Sun, 7 Sep 2008 13:34:33 +0930
- Subject: ld output_section_statment related tidy
- References: <48B41673.4020106@linux.intel.com> <48B41919.6080800@redhat.com> <48B42354.50306@linux.intel.com> <48B42A54.4020809@redhat.com> <48B42B90.9070709@linux.intel.com> <48B43034.9070204@redhat.com> <48B43287.7030808@linux.intel.com> <20080826191933.GA7838@caradoc.them.org> <6dc9ffc80808261245y30d8b0e8u8c5cdaffada33aac@mail.gmail.com> <20080827002101.GA4989@bubble.grove.modra.org>
This patch started off as one to allow INSERT to add a new output
section statement before or after an existing output statement with
the same section name, but ended up just being a cleanup. The
trouble with allowing an INSERT of the same output section name is
simply that we'd need to allow duplicate output section statements of
the same name, which we don't support currently. That isn't a
particularly difficult thing to do, but I think it would be safer to
leave that change until we've branched.
* 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.
Index: ld/NEWS
===================================================================
RCS file: /cvs/src/src/ld/NEWS,v
retrieving revision 1.85
diff -u -p -r1.85 NEWS
--- ld/NEWS 7 Jun 2008 11:35:46 -0000 1.85
+++ ld/NEWS 6 Sep 2008 00:04:49 -0000
@@ -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:
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.291
diff -u -p -r1.291 ldlang.c
--- ld/ldlang.c 21 Aug 2008 13:10:54 -0000 1.291
+++ ld/ldlang.c 6 Sep 2008 00:04:53 -0000
@@ -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));
- 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));
+ create, 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 (
{
/* 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 (
&& 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 (
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_sectio
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 (con
{
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 (con
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;
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.78
diff -u -p -r1.78 ldlang.h
--- ld/ldlang.h 17 Aug 2008 03:12:50 -0000 1.78
+++ ld/ldlang.h 6 Sep 2008 00:04:54 -0000
@@ -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_a
(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
Index: ld/emultempl/beos.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/beos.em,v
retrieving revision 1.39
diff -u -p -r1.39 beos.em
--- ld/emultempl/beos.em 15 Feb 2008 03:35:53 -0000 1.39
+++ ld/emultempl/beos.em 6 Sep 2008 00:04:55 -0000
@@ -697,7 +697,7 @@ gld${EMULATION_NAME}_place_orphan (asect
output_secname = xstrdup (secname);
ps = strchr (output_secname + 1, '\$');
*ps = 0;
- os = lang_output_section_statement_lookup (output_secname);
+ os = lang_output_section_statement_lookup (output_secname, 0, TRUE);
/* Find the '\$' wild statement for this section. We currently require the
linker script to explicitly mention "*(.foo\$)".
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.191
diff -u -p -r1.191 elf32.em
--- ld/emultempl/elf32.em 8 Aug 2008 08:06:16 -0000 1.191
+++ ld/emultempl/elf32.em 6 Sep 2008 00:04:56 -0000
@@ -1583,7 +1583,7 @@ output_rel_find (asection *sec, int isdy
lookup != NULL;
lookup = lookup->next)
{
- if (lookup->constraint != -1
+ if (lookup->constraint >= 0
&& CONST_STRNEQ (lookup->name, ".rel"))
{
int lookrela = lookup->name[4] == 'a';
Index: ld/emultempl/sunos.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/sunos.em,v
retrieving revision 1.30
diff -u -p -r1.30 sunos.em
--- ld/emultempl/sunos.em 15 Feb 2008 03:35:53 -0000 1.30
+++ ld/emultempl/sunos.em 6 Sep 2008 00:04:56 -0000
@@ -698,7 +698,7 @@ gld${EMULATION_NAME}_before_allocation (
/* Set the .text section to start at 0x20, not 0x2020. FIXME:
This is too magical. */
- os = lang_output_section_statement_lookup (".text");
+ os = lang_output_section_statement_lookup (".text", 0, TRUE);
if (os->addr_tree == NULL)
os->addr_tree = exp_intop (0x20);
}
--
Alan Modra
Australia Development Lab, IBM