* 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> 2004-10-12 Bob Wilson <bob.wilson@acm.org>
* emultempl/xtensaelf.em: Use ISO C90 formatting. * emultempl/xtensaelf.em: Use ISO C90 formatting.

View File

@ -868,19 +868,19 @@ pe_find_data_imports (void)
for (undef = link_info.hash->undefs; undef; undef=undef->u.undef.next) for (undef = link_info.hash->undefs; undef; undef=undef->u.undef.next)
{ {
if (undef->type == bfd_link_hash_undefined) if (undef->type == bfd_link_hash_undefined)
{ {
/* C++ symbols are *long*. */ /* C++ symbols are *long*. */
char buf[4096]; char buf[4096];
if (pe_dll_extra_pe_debug) if (pe_dll_extra_pe_debug)
printf ("%s:%s\n", __FUNCTION__, undef->root.string); printf ("%s:%s\n", __FUNCTION__, undef->root.string);
sprintf (buf, "__imp_%s", undef->root.string); sprintf (buf, "__imp_%s", undef->root.string);
sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1); sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);
if (sym && sym->type == bfd_link_hash_defined) if (sym && sym->type == bfd_link_hash_defined)
{ {
bfd *b = sym->u.def.section->owner; bfd *b = sym->u.def.section->owner;
asymbol **symbols; asymbol **symbols;
int nsyms, symsize, i; int nsyms, symsize, i;
@ -918,8 +918,8 @@ pe_find_data_imports (void)
undef->root.string = sym->root.string; undef->root.string = sym->root.string;
undef->u.def.value = sym->u.def.value; undef->u.def.value = sym->u.def.value;
undef->u.def.section = sym->u.def.section; undef->u.def.section = sym->u.def.section;
} }
} }
} }
} }
@ -946,7 +946,7 @@ gld_${EMULATION_NAME}_after_open (void)
printf ("%s()\n", __FUNCTION__); printf ("%s()\n", __FUNCTION__);
for (sym = link_info.hash->undefs; sym; sym=sym->u.undef.next) for (sym = link_info.hash->undefs; sym; sym=sym->u.undef.next)
printf ("-%s\n", sym->root.string); printf ("-%s\n", sym->root.string);
bfd_hash_traverse (&link_info.hash->table, pr_sym, NULL); bfd_hash_traverse (&link_info.hash->table, pr_sym, NULL);
for (a = link_info.input_bfds; a; a = a->link_next) for (a = link_info.input_bfds; a; a = a->link_next)
@ -1151,7 +1151,7 @@ gld_${EMULATION_NAME}_after_open (void)
is3 && is3->the_bfd->my_archive == arch; is3 && is3->the_bfd->my_archive == arch;
is3 = (lang_input_statement_type *) is3->next) is3 = (lang_input_statement_type *) is3->next)
{ {
/* A MS dynamic import library can also contain static /* A MS dynamic import library can also contain static
members, so look for the first element with a .dll members, so look for the first element with a .dll
extension, and use that for the remainder of the extension, and use that for the remainder of the
comparisons. */ comparisons. */
@ -1478,8 +1478,8 @@ gld_${EMULATION_NAME}_finish (void)
if (asec) if (asec)
{ {
asec->flags &= ~SEC_CODE; asec->flags &= ~SEC_CODE;
asec->flags |= SEC_DATA; asec->flags |= SEC_DATA;
} }
} }
} }
@ -1530,6 +1530,7 @@ struct orphan_save
lang_output_section_statement_type *os; lang_output_section_statement_type *os;
asection **section; asection **section;
lang_statement_union_type **stmt; lang_statement_union_type **stmt;
lang_statement_union_type **os_tail;
}; };
static bfd_boolean 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_rdata;
static struct orphan_save hold_data; static struct orphan_save hold_data;
static struct orphan_save hold_bss; static struct orphan_save hold_bss;
static int count = 1;
char *outsecname; char *outsecname;
lang_statement_list_type *old; lang_statement_list_type *old;
lang_statement_list_type add; lang_statement_list_type add;
lang_statement_union_type **os_tail;
etree_type *address; etree_type *address;
etree_type *load_base;
asection *sec;
/* Try to put the new output section in a reasonable place based /* Try to put the new output section in a reasonable place based
on the section name and section flags. */ 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 && (s->flags & SEC_READONLY) != 0
&& HAVE_SECTION (hold_rdata, ".rdata")) && HAVE_SECTION (hold_rdata, ".rdata"))
place = &hold_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")) && HAVE_SECTION (hold_text, ".text"))
place = &hold_text; place = &hold_text;
#undef HAVE_SECTION #undef HAVE_SECTION
/* Choose a unique name for the section. This will be needed if /* Choose a unique name for the section. This will be needed if the
the same section name appears in the input file with same section name appears in the input file with different
different loadable or allocatable characteristics. */ loadable or allocatable characteristics. But if the section
outsecname = xstrdup (hold_section_name); already exists but does not have any flags set, then it has been
if (bfd_get_section_by_name (output_bfd, outsecname) != NULL) 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)
{ {
unsigned int len; outsecname = bfd_get_unique_section_name (output_bfd,
char *newname; hold_section_name, &count);
unsigned int i; if (outsecname == NULL)
einfo ("%F%P: place_orphan failed: %E\n");
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;
} }
else
outsecname = xstrdup (hold_section_name);
/* Start building a list of statements for this section. */ /* Start building a list of statements for this section. */
old = stat_ptr; old = stat_ptr;
stat_ptr = &add;
lang_list_init (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) 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__")); 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, os = lang_enter_output_section_statement (outsecname, address, 0,
(etree_type *) NULL, (etree_type *) NULL,
(etree_type *) NULL, (etree_type *) NULL,
(etree_type *) NULL, 0); load_base, 0);
lang_add_section (&add_child, s, os, file); lang_add_section (&add_child, s, os, file);
@ -1674,7 +1691,7 @@ gld_${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s
(struct lang_output_section_phdr_list *) NULL, NULL); (struct lang_output_section_phdr_list *) NULL, NULL);
if (config.build_constructors && *ps == '\0') if (config.build_constructors && *ps == '\0')
{ {
char *symname; char *symname;
/* lang_leave_ouput_section_statement resets stat_ptr. /* lang_leave_ouput_section_statement resets stat_ptr.
@ -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. */ read/write section before or amongst the read-only ones. */
if (add.head != NULL) if (add.head != NULL)
{ {
lang_statement_union_type *newly_added_os;
if (place->stmt == NULL) if (place->stmt == NULL)
{ {
/* Put the new statement list right at the head. */ /* Put the new statement list right at the head. */
*add.tail = place->os->header.next; *add.tail = place->os->header.next;
place->os->header.next = add.head; place->os->header.next = add.head;
place->os_tail = &place->os->next;
} }
else else
{ {
@ -1761,6 +1782,21 @@ gld_${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s
/* Save the end of this list. */ /* Save the end of this list. */
place->stmt = add.tail; 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;
} }
} }
} }
@ -1826,12 +1862,12 @@ gld_${EMULATION_NAME}_open_dynamic_archive
filename = entry->filename; filename = entry->filename;
string = (char *) xmalloc (strlen (search->name) string = (char *) xmalloc (strlen (search->name)
+ strlen (filename) + strlen (filename)
+ sizeof "/lib.a.dll" + sizeof "/lib.a.dll"
#ifdef DLL_SUPPORT #ifdef DLL_SUPPORT
+ (pe_dll_search_prefix ? strlen (pe_dll_search_prefix) : 0) + (pe_dll_search_prefix ? strlen (pe_dll_search_prefix) : 0)
#endif #endif
+ 1); + 1);
/* Try "libfoo.dll.a" first (preferred explicit import library for dll's. */ /* Try "libfoo.dll.a" first (preferred explicit import library for dll's. */
sprintf (string, "%s/lib%s.dll.a", search->name, filename); sprintf (string, "%s/lib%s.dll.a", search->name, filename);
@ -1841,7 +1877,7 @@ gld_${EMULATION_NAME}_open_dynamic_archive
/* Try "foo.dll.a" next (alternate explicit import library for dll's. */ /* Try "foo.dll.a" next (alternate explicit import library for dll's. */
sprintf (string, "%s/%s.dll.a", search->name, filename); sprintf (string, "%s/%s.dll.a", search->name, filename);
if (! ldfile_try_open_bfd (string, entry)) if (! ldfile_try_open_bfd (string, entry))
{ {
/* Try libfoo.a next. Normally, this would be interpreted as a static /* Try libfoo.a next. Normally, this would be interpreted as a static
library, but it *could* be an import library. For backwards compatibility, library, but it *could* be an import library. For backwards compatibility,
libfoo.a needs to ==precede== libfoo.dll and foo.dll in the search, libfoo.a needs to ==precede== libfoo.dll and foo.dll in the search,
@ -1851,50 +1887,50 @@ gld_${EMULATION_NAME}_open_dynamic_archive
-lfoo is not found) we will search for libfoo.a twice before -lfoo is not found) we will search for libfoo.a twice before
giving up -- once here, and once when searching for a "static" lib. giving up -- once here, and once when searching for a "static" lib.
for a "static" lib. */ for a "static" lib. */
/* Try "libfoo.a" (import lib, or static lib, but must /* Try "libfoo.a" (import lib, or static lib, but must
take precedence over dll's). */ take precedence over dll's). */
sprintf (string, "%s/lib%s.a", search->name, filename); sprintf (string, "%s/lib%s.a", search->name, filename);
if (! ldfile_try_open_bfd (string, entry)) if (! ldfile_try_open_bfd (string, entry))
{ {
#ifdef DLL_SUPPORT #ifdef DLL_SUPPORT
if (pe_dll_search_prefix) if (pe_dll_search_prefix)
{ {
/* Try "<prefix>foo.dll" (preferred dll name, if specified). */ /* Try "<prefix>foo.dll" (preferred dll name, if specified). */
sprintf (string, "%s/%s%s.dll", search->name, pe_dll_search_prefix, filename); sprintf (string, "%s/%s%s.dll", search->name, pe_dll_search_prefix, filename);
if (! ldfile_try_open_bfd (string, entry)) if (! ldfile_try_open_bfd (string, entry))
{ {
/* Try "libfoo.dll" (default preferred dll name). */ /* Try "libfoo.dll" (default preferred dll name). */
sprintf (string, "%s/lib%s.dll", search->name, filename); sprintf (string, "%s/lib%s.dll", search->name, filename);
if (! ldfile_try_open_bfd (string, entry)) if (! ldfile_try_open_bfd (string, entry))
{ {
/* Finally, try "foo.dll" (alternate dll name). */ /* Finally, try "foo.dll" (alternate dll name). */
sprintf (string, "%s/%s.dll", search->name, filename); sprintf (string, "%s/%s.dll", search->name, filename);
if (! ldfile_try_open_bfd (string, entry)) if (! ldfile_try_open_bfd (string, entry))
{ {
free (string); free (string);
return FALSE; return FALSE;
} }
} }
} }
} }
else /* pe_dll_search_prefix not specified. */ else /* pe_dll_search_prefix not specified. */
#endif #endif
{ {
/* Try "libfoo.dll" (preferred dll name). */ /* Try "libfoo.dll" (preferred dll name). */
sprintf (string, "%s/lib%s.dll", search->name, filename); sprintf (string, "%s/lib%s.dll", search->name, filename);
if (! ldfile_try_open_bfd (string, entry)) if (! ldfile_try_open_bfd (string, entry))
{ {
/* Finally, try "foo.dll" (alternate dll name). */ /* Finally, try "foo.dll" (alternate dll name). */
sprintf (string, "%s/%s.dll", search->name, filename); sprintf (string, "%s/%s.dll", search->name, filename);
if (! ldfile_try_open_bfd (string, entry)) if (! ldfile_try_open_bfd (string, entry))
{ {
free (string); free (string);
return FALSE; return FALSE;
} }
} }
} }
} }
} }
} }
entry->filename = string; entry->filename = string;
@ -1923,16 +1959,16 @@ cat >>e${EMULATION_NAME}.c <<EOF
if (link_info.relocatable && config.build_constructors) if (link_info.relocatable && config.build_constructors)
return return
EOF EOF
sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
echo ' ; else if (link_info.relocatable) return' >> e${EMULATION_NAME}.c echo ' ; else if (link_info.relocatable) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
echo ' ; else return' >> e${EMULATION_NAME}.c echo ' ; else return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
echo '; }' >> e${EMULATION_NAME}.c echo '; }' >> e${EMULATION_NAME}.c
cat >>e${EMULATION_NAME}.c <<EOF cat >>e${EMULATION_NAME}.c <<EOF