Post by Pan ruochenThe symbol ___start_ResData is not the start address of section
ResData. What's wrong?
This cures the problem with constructor symbols on pe targets. The
trouble was that pe.em (and pep.em) align output sections to a page
boundary, and the __start_<secname> symbol was added to the internal
linker script before the output section statement alignment.
While poking around in this area I noticed a few other problems.
a) The pe and pep place_orphan functions added non-dollar sections to
the beginning of the output section. That meant input sections are
reversed from their file order, which wouldn't ordinarily cause a
problem but it's not usual linker behaviour.
b) These functions improperly added their input section statements
into the output section statement child list without using the tail
pointer of the input list. This meant only one statement was added.
c) lang_insert_orphan can be called when an existing output section's
type or flags are incompatible with an orphan input section. In
this case, I think we ought to create a new output section, but I
don't do that in this patch. Instead I just ensure we don't
duplicate the symbols.
* ldlang.c (lang_insert_orphan): Add __start_<section> symbol
assignment inside output section statement. Ensure only one
set of symbols per output section.
* emultempl/pe.em (gld_${EMULATION_NAME}_place_orphan): Add non-
dollar sections before dollar sections. Correct add_child
list insertion.
* emultempl/pep.em (gld_${EMULATION_NAME}_place_orphan): Likewise.
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.306
diff -u -p -r1.306 ldlang.c
--- ld/ldlang.c 16 Apr 2009 23:07:00 -0000 1.306
+++ ld/ldlang.c 13 May 2009 00:16:36 -0000
@@ -1668,8 +1668,16 @@ lang_insert_orphan (asection *s,
push_stat_ptr (&add);
}
+ if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
+ address = exp_intop (0);
+
+ os_tail = ((lang_output_section_statement_type **)
+ lang_output_section_statement.tail);
+ os = lang_enter_output_section_statement (secname, address, 0, NULL, NULL,
+ NULL, constraint);
+
ps = NULL;
- if (config.build_constructors)
+ if (config.build_constructors && *os_tail == os)
{
/* If the name of the section is representable in C, then create
symbols to mark the start and the end of the section. */
@@ -1688,26 +1696,19 @@ lang_insert_orphan (asection *s,
exp_intop ((bfd_vma) 1 << s->alignment_power));
lang_add_assignment (exp_assop ('=', ".", e_align));
lang_add_assignment (exp_provide (symname,
- exp_nameop (NAME, "."),
+ exp_unop (ABSOLUTE,
+ exp_nameop (NAME, ".")),
FALSE));
}
}
- if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
- address = exp_intop (0);
-
- os_tail = ((lang_output_section_statement_type **)
- lang_output_section_statement.tail);
- os = lang_enter_output_section_statement (secname, address, 0, NULL, NULL,
- NULL, constraint);
-
if (add_child == NULL)
add_child = &os->children;
lang_add_section (add_child, s, os);
lang_leave_output_section_statement (0, "*default*", NULL, NULL);
- if (config.build_constructors && *ps == '\0')
+ if (ps != NULL && *ps == '\0')
{
char *symname;
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.148
diff -u -p -r1.148 pe.em
--- ld/emultempl/pe.em 2 Apr 2009 14:42:41 -0000 1.148
+++ ld/emultempl/pe.em 12 May 2009 23:19:34 -0000
@@ -1771,6 +1771,7 @@ gld_${EMULATION_NAME}_place_orphan (asec
char *dollar = NULL;
lang_output_section_statement_type *os;
lang_statement_list_type add_child;
+ lang_statement_union_type **pl;
/* Look through the script to see where to place this section. */
if (!link_info.relocatable
@@ -1876,47 +1877,29 @@ gld_${EMULATION_NAME}_place_orphan (asec
&add_child);
}
- {
- lang_statement_union_type **pl = &os->children.head;
-
- if (dollar != NULL)
- {
- bfd_boolean found_dollar;
-
- /* The section name has a '\$'. Sort it with the other '\$'
- sections. */
- found_dollar = FALSE;
- for ( ; *pl != NULL; pl = &(*pl)->header.next)
- {
- lang_input_section_type *ls;
- const char *lname;
+ /* If the section name has a '\$', sort it with the other '\$'
+ sections. */
+ for (pl = &os->children.head; *pl != NULL; pl = &(*pl)->header.next)
+ {
+ lang_input_section_type *ls;
+ const char *lname;
- if ((*pl)->header.type != lang_input_section_enum)
- continue;
+ if ((*pl)->header.type != lang_input_section_enum)
+ continue;
- ls = &(*pl)->input_section;
+ ls = &(*pl)->input_section;
- lname = bfd_get_section_name (ls->section->owner, ls->section);
- if (strchr (lname, '\$') == NULL)
- {
- if (found_dollar)
- break;
- }
- else
- {
- found_dollar = TRUE;
- if (strcmp (orig_secname, lname) < 0)
- break;
- }
- }
- }
+ lname = bfd_get_section_name (ls->section->owner, ls->section);
+ if (strchr (lname, '\$') != NULL
+ && (dollar == NULL || strcmp (orig_secname, lname) < 0))
+ break;
+ }
- if (add_child.head != NULL)
- {
- add_child.head->header.next = *pl;
- *pl = add_child.head;
- }
- }
+ if (add_child.head != NULL)
+ {
+ *add_child.tail = *pl;
+ *pl = add_child.head;
+ }
return os;
}
Index: ld/emultempl/pep.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pep.em,v
retrieving revision 1.25
diff -u -p -r1.25 pep.em
--- ld/emultempl/pep.em 2 Apr 2009 14:42:41 -0000 1.25
+++ ld/emultempl/pep.em 12 May 2009 23:19:35 -0000
@@ -1546,6 +1546,7 @@ gld_${EMULATION_NAME}_place_orphan (asec
char *dollar = NULL;
lang_output_section_statement_type *os;
lang_statement_list_type add_child;
+ lang_statement_union_type **pl;
/* Look through the script to see where to place this section. */
if (!link_info.relocatable
@@ -1651,47 +1652,29 @@ gld_${EMULATION_NAME}_place_orphan (asec
&add_child);
}
- {
- lang_statement_union_type **pl = &os->children.head;
-
- if (dollar != NULL)
- {
- bfd_boolean found_dollar;
-
- /* The section name has a '\$'. Sort it with the other '\$'
- sections. */
- found_dollar = FALSE;
- for ( ; *pl != NULL; pl = &(*pl)->header.next)
- {
- lang_input_section_type *ls;
- const char *lname;
+ /* If the section name has a '\$', sort it with the other '\$'
+ sections. */
+ for (pl = &os->children.head; *pl != NULL; pl = &(*pl)->header.next)
+ {
+ lang_input_section_type *ls;
+ const char *lname;
- if ((*pl)->header.type != lang_input_section_enum)
- continue;
+ if ((*pl)->header.type != lang_input_section_enum)
+ continue;
- ls = &(*pl)->input_section;
+ ls = &(*pl)->input_section;
- lname = bfd_get_section_name (ls->section->owner, ls->section);
- if (strchr (lname, '\$') == NULL)
- {
- if (found_dollar)
- break;
- }
- else
- {
- found_dollar = TRUE;
- if (strcmp (orig_secname, lname) < 0)
- break;
- }
- }
- }
+ lname = bfd_get_section_name (ls->section->owner, ls->section);
+ if (strchr (lname, '\$') != NULL
+ && (dollar == NULL || strcmp (orig_secname, lname) < 0))
+ break;
+ }
- if (add_child.head != NULL)
- {
- add_child.head->header.next = *pl;
- *pl = add_child.head;
- }
- }
+ if (add_child.head != NULL)
+ {
+ *add_child.tail = *pl;
+ *pl = add_child.head;
+ }
return os;
}
--
Alan Modra
Australia Development Lab, IBM