Reapply change from r210245. In binutils 2.17, the code in question has

moved from ld/emultempl/elf32.em to ld/ldlang.c, so apply approximately
the same change as upstream, which has description:

* 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.

Taken from upstream git commit 7e01d69a19a8fd079887f26853c8565da15ff340,
with permission to use it under GPLv2 from the author.
This commit is contained in:
Dimitry Andric 2010-10-21 19:27:27 +00:00
parent dfd2f2d4bb
commit dc9aea6cc4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/binutils-2.17/; revision=214159
2 changed files with 39 additions and 56 deletions

View File

@ -1525,6 +1525,7 @@ gld_${EMULATION_NAME}_place_orphan (asection *s)
char *dollar = NULL;
lang_output_section_statement_type *os;
lang_statement_list_type add_child;
lang_statement_union_type **pl;
secname = bfd_get_section_name (s->owner, s);
@ -1644,47 +1645,29 @@ gld_${EMULATION_NAME}_place_orphan (asection *s)
os = lang_insert_orphan (s, secname, after, place, address, &add_child);
}
{
lang_statement_union_type **pl = &os->children.head;
/* 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 (dollar != NULL)
{
bfd_boolean found_dollar;
if ((*pl)->header.type != lang_input_section_enum)
continue;
/* 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;
ls = &(*pl)->input_section;
if ((*pl)->header.type != lang_input_section_enum)
continue;
lname = bfd_get_section_name (ls->section->owner, ls->section);
if (strchr (lname, '\$') != NULL
&& (dollar == NULL || strcmp (orig_secname, lname) < 0))
break;
}
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;
}
}
}
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 TRUE;
}

View File

@ -1349,8 +1349,26 @@ lang_insert_orphan (asection *s,
lang_list_init (stat_ptr);
}
if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
address = exp_intop (0);
load_base = NULL;
if (after != NULL && after->load_base != NULL)
{
etree_type *lma_from_vma;
lma_from_vma = exp_binop ('-', after->load_base,
exp_nameop (ADDR, after->name));
load_base = exp_binop ('+', lma_from_vma,
exp_nameop (ADDR, secname));
}
os_tail = ((lang_output_section_statement_type **)
lang_output_section_statement.tail);
os = lang_enter_output_section_statement (secname, address, 0, NULL, NULL,
load_base, 0);
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. */
@ -1373,24 +1391,6 @@ lang_insert_orphan (asection *s,
}
}
if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
address = exp_intop (0);
load_base = NULL;
if (after != NULL && after->load_base != NULL)
{
etree_type *lma_from_vma;
lma_from_vma = exp_binop ('-', after->load_base,
exp_nameop (ADDR, after->name));
load_base = exp_binop ('+', lma_from_vma,
exp_nameop (ADDR, secname));
}
os_tail = ((lang_output_section_statement_type **)
lang_output_section_statement.tail);
os = lang_enter_output_section_statement (secname, address, 0, NULL, NULL,
load_base, 0);
if (add_child == NULL)
add_child = &os->children;
lang_add_section (add_child, s, os);