* emultempl/pe.em (struct orphan_save): Add os_tail.
	(place_orphan): Backport assorted fixes from elf32.em.
This commit is contained in:
Alan Modra
2004-10-12 23:44:57 +00:00
parent ac0fa625cd
commit 1af699f475
2 changed files with 139 additions and 97 deletions

View File

@ -1,3 +1,9 @@
2004-10-13 Alan Modra <amodra@bigpond.net.au>
PR 44
* emultempl/pe.em (struct orphan_save): Add os_tail.
(place_orphan): Backport assorted fixes from elf32.em.
2004-10-12 Bob Wilson <bob.wilson@acm.org>
* emultempl/xtensaelf.em: Use ISO C90 formatting.

View File

@ -1530,6 +1530,7 @@ struct orphan_save
lang_output_section_statement_type *os;
asection **section;
lang_statement_union_type **stmt;
lang_statement_union_type **os_tail;
};
static bfd_boolean
@ -1573,10 +1574,14 @@ gld_${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s
static struct orphan_save hold_rdata;
static struct orphan_save hold_data;
static struct orphan_save hold_bss;
static int count = 1;
char *outsecname;
lang_statement_list_type *old;
lang_statement_list_type add;
lang_statement_union_type **os_tail;
etree_type *address;
etree_type *load_base;
asection *sec;
/* Try to put the new output section in a reasonable place based
on the section name and section flags. */
@ -1596,41 +1601,42 @@ gld_${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s
&& (s->flags & SEC_READONLY) != 0
&& HAVE_SECTION (hold_rdata, ".rdata"))
place = &hold_rdata;
else if ((s->flags & SEC_READONLY) != 0
else if ((s->flags & SEC_CODE) != 0
&& (s->flags & SEC_READONLY) != 0
&& HAVE_SECTION (hold_text, ".text"))
place = &hold_text;
#undef HAVE_SECTION
/* Choose a unique name for the section. This will be needed if
the same section name appears in the input file with
different loadable or allocatable characteristics. */
/* Choose a unique name for the section. This will be needed if the
same section name appears in the input file with different
loadable or allocatable characteristics. But if the section
already exists but does not have any flags set, then it has been
created by the linker, probably as a result of a --section-start
command line switch. */
sec = bfd_get_section_by_name (output_bfd, hold_section_name);
if (sec != NULL
&& bfd_get_section_flags (output_bfd, sec) != 0)
{
outsecname = bfd_get_unique_section_name (output_bfd,
hold_section_name, &count);
if (outsecname == NULL)
einfo ("%F%P: place_orphan failed: %E\n");
}
else
outsecname = xstrdup (hold_section_name);
if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
{
unsigned int len;
char *newname;
unsigned int i;
len = strlen (outsecname);
newname = xmalloc (len + 5);
strcpy (newname, outsecname);
i = 0;
do
{
sprintf (newname + len, "%d", i);
++i;
}
while (bfd_get_section_by_name (output_bfd, newname) != NULL);
free (outsecname);
outsecname = newname;
}
/* Start building a list of statements for this section. */
old = stat_ptr;
/* If we have found an appropriate place for the output section
statements for this orphan, add them to our own private list,
inserting them later into the global statement list. */
if (place != NULL)
{
stat_ptr = &add;
lang_list_init (stat_ptr);
}
if (config.build_constructors)
{
@ -1662,10 +1668,21 @@ gld_${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s
exp_nameop (NAME, "__section_alignment__"));
}
load_base = NULL;
if (place != NULL && place->os->load_base != NULL)
{
etree_type *lma_from_vma;
lma_from_vma = exp_binop ('-', place->os->load_base,
exp_nameop (ADDR, place->os->name));
load_base = exp_binop ('+', lma_from_vma,
exp_nameop (ADDR, secname));
}
os_tail = lang_output_section_statement.tail;
os = lang_enter_output_section_statement (outsecname, address, 0,
(etree_type *) NULL,
(etree_type *) NULL,
(etree_type *) NULL, 0);
load_base, 0);
lang_add_section (&add_child, s, os, file);
@ -1741,11 +1758,15 @@ gld_${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s
read/write section before or amongst the read-only ones. */
if (add.head != NULL)
{
lang_statement_union_type *newly_added_os;
if (place->stmt == NULL)
{
/* Put the new statement list right at the head. */
*add.tail = place->os->header.next;
place->os->header.next = add.head;
place->os_tail = &place->os->next;
}
else
{
@ -1761,6 +1782,21 @@ gld_${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s
/* Save the end of this list. */
place->stmt = add.tail;
/* Do the same for the list of output section statements. */
newly_added_os = *os_tail;
*os_tail = NULL;
newly_added_os->output_section_statement.next = *place->os_tail;
*place->os_tail = newly_added_os;
place->os_tail = &newly_added_os->output_section_statement.next;
/* Fixing the global list pointer here is a little different.
We added to the list in lang_enter_output_section_statement,
trimmed off the new output_section_statment above when
assigning *os_tail = NULL, but possibly added it back in
the same place when assigning *place->os_tail. */
if (*os_tail == NULL)
lang_output_section_statement.tail = os_tail;
}
}
}