1999-05-10 DJ Delorie <dj@cygnus.com>

* scripttempl/pe.sc: Specify the output arch, which Ian says is
	the Right Thing to do.
	* emultempl/pe.em: various changes to parameterize the
	target-specific information.
	(gld_i386pe_after_open): Detect and fix MS import libraries
	by renaming the member objects (which are all named the same).
	* pe-dll.c: various changes to parameterize the target-specific
	information.
	(generate_reloc): support relocs more generically to allow for
	expansion.
	(pe_exe_build_sections): new; used to add .relocs to .exes
	(pe_exe_fill_sections): ditto
This commit is contained in:
DJ Delorie 1999-05-11 21:06:50 +00:00
parent 09cda596de
commit c6c37250e9
4 changed files with 290 additions and 62 deletions

View File

@ -1,3 +1,20 @@
1999-05-10 DJ Delorie <dj@cygnus.com>
* scripttempl/pe.sc: Specify the output arch, which Ian says is
the Right Thing to do.
* emultempl/pe.em: various changes to parameterize the
target-specific information.
(gld_i386pe_after_open): Detect and fix MS import libraries
by renaming the member objects (which are all named the same).
* pe-dll.c: various changes to parameterize the target-specific
information.
(generate_reloc): support relocs more generically to allow for
expansion.
(pe_exe_build_sections): new; used to add .relocs to .exes
(pe_exe_fill_sections): ditto
1999-05-10 Catherine Moore <clm@cygnus.com>
* emultempl/pe.em (gld_${EMULATION_NAME}_after_open):

View File

@ -1,6 +1,7 @@
# This shell script emits a C file. -*- C -*-
# It does some substitutions.
cat >e${EMULATION_NAME}.c <<EOF
(echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-)
cat >>e${EMULATION_NAME}.c <<EOF
/* This file is part of GLD, the Gnu Linker.
Copyright 1995, 96, 97, 1998 Free Software Foundation, Inc.
@ -42,10 +43,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "ldfile.h"
#include "coff/internal.h"
#include "../bfd/libcoff.h"
#include "../bfd/libbfd.h"
#include "deffile.h"
#define TARGET_IS_${EMULATION_NAME}
#if defined(TARGET_IS_i386pe)
#define DLL_SUPPORT
#endif
#define PE_DEF_SUBSYSTEM 3
static void gld_${EMULATION_NAME}_set_symbols PARAMS ((void));
static void gld_${EMULATION_NAME}_after_open PARAMS ((void));
static void gld_${EMULATION_NAME}_before_parse PARAMS ((void));
@ -78,7 +86,7 @@ gld_${EMULATION_NAME}_before_parse()
{
output_filename = "a.exe";
ldfile_output_architecture = bfd_arch_${ARCH};
#ifdef TARGET_IS_i386pe
#ifdef DLL_SUPPORT
config.has_shared = 1;
#endif
}
@ -128,7 +136,7 @@ static struct option longopts[] =
{"stack", required_argument, NULL, OPTION_STACK},
{"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
{"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
#ifdef TARGET_IS_i386pe
#ifdef DLL_SUPPORT
/* getopt allows abbreviations, so we do this to stop it from treating -o
as an abbreviation for this option */
{"output-def", required_argument, NULL, OPTION_OUT_DEF},
@ -174,7 +182,7 @@ static definfo init[] =
D(MinorImageVersion,"__minor_image_version__", 0),
D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
D(Subsystem,"__subsystem__", 3),
D(Subsystem,"__subsystem__", PE_DEF_SUBSYSTEM),
D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x2000000),
D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
@ -202,7 +210,7 @@ gld_${EMULATION_NAME}_list_options (file)
fprintf (file, _(" --stack <size> Set size of the initial stack\n"));
fprintf (file, _(" --subsystem <name>[:<version>] Set required OS subsystem [& version]\n"));
fprintf (file, _(" --support-old-code Support interworking with old code\n"));
#ifdef TARGET_IS_i386pe
#ifdef DLL_SUPPORT
fprintf (file, _(" --add-stdcall-alias Export symbols with and without @nn\n"));
fprintf (file, _(" --disable-stdcall-fixup Don't link _sym to _sym@nn\n"));
fprintf (file, _(" --enable-stdcall-fixup Link _sym to _sym@nn without warnings\n"));
@ -410,6 +418,7 @@ gld_${EMULATION_NAME}_parse_args(argc, argv)
case OPTION_SUPPORT_OLD_CODE:
support_old_code = 1;
break;
#ifdef DLL_SUPPORT
case OPTION_OUT_DEF:
pe_out_def_filename = xstrdup (optarg);
break;
@ -417,9 +426,7 @@ gld_${EMULATION_NAME}_parse_args(argc, argv)
pe_dll_export_everything = 1;
break;
case OPTION_EXCLUDE_SYMBOLS:
#ifdef TARGET_IS_i386pe
pe_dll_add_excludes (optarg);
#endif
break;
case OPTION_KILL_ATS:
pe_dll_kill_ats = 1;
@ -436,6 +443,7 @@ gld_${EMULATION_NAME}_parse_args(argc, argv)
case OPTION_IMPLIB_FILENAME:
pe_implib_filename = xstrdup (optarg);
break;
#endif
}
return 1;
}
@ -617,7 +625,7 @@ gld_${EMULATION_NAME}_after_open ()
pe_data (output_bfd)->pe_opthdr = pe;
pe_data (output_bfd)->dll = init[DLLOFF].value;
#ifdef TARGET_IS_i386pe
#ifdef DLL_SUPPORT
if (pe_enable_stdcall_fixup) /* -1=warn or 1=disable */
pe_fixup_stdcalls ();
@ -636,6 +644,70 @@ gld_${EMULATION_NAME}_after_open ()
}
}
#endif
{
static int sequence = 0;
int is_ms_arch;
bfd *cur_arch = 0, *elt;
lang_input_statement_type *is2;
/* Careful - this is a shell script. Watch those dollar signs! */
/* Microsoft import libraries have every member named the same,
and not in the right order for us to link them correctly. We
must detect these and rename the members so that they'll link
correctly. There are three types of objects: the head, the
thunks, and the sentinel(s). The head is easy; it's the one
with idata2. We assume that the sentinels won't have relocs,
and the thunks will. It's easier than checking the symbol
table for external references. */
LANG_FOR_EACH_INPUT_STATEMENT (is)
{
if (is->the_bfd->my_archive)
{
bfd *arch = is->the_bfd->my_archive;
if (cur_arch != arch)
{
cur_arch = arch;
is_ms_arch = 1;
for (is2 = is;
is2 && is2->the_bfd->my_archive == arch;
is2 = (lang_input_statement_type *)is2->next)
{
if (strcmp (is->the_bfd->filename, is2->the_bfd->filename))
is_ms_arch = 0;
}
}
if (is_ms_arch)
{
int idata2 = 0, i, reloc_count=0;
asection *sec;
char *new_name, seq;
for (sec = is->the_bfd->sections; sec; sec = sec->next)
{
if (strcmp (sec->name, ".idata\$2") == 0)
idata2 = 1;
reloc_count += sec->reloc_count;
}
if (idata2) /* .idata2 is the TOC */
seq = 'a';
else if (reloc_count > 0) /* thunks */
seq = 'b';
else /* sentinel */
seq = 'c';
new_name = bfd_alloc (is->the_bfd,
strlen (is->the_bfd->filename)+2);
sprintf (new_name, "%s.%c", is->the_bfd->filename, seq);
is->the_bfd->filename = new_name;
new_name = bfd_alloc(is->the_bfd, strlen(is->filename)+2);
sprintf (new_name, "%s.%c", is->filename, seq);
is->filename = new_name;
}
}
}
}
}
static void
@ -701,7 +773,7 @@ static boolean
gld_${EMULATION_NAME}_unrecognized_file(entry)
lang_input_statement_type *entry;
{
#ifdef TARGET_IS_i386pe
#ifdef DLL_SUPPORT
const char *ext = entry->filename + strlen (entry->filename) - 4;
if (strcmp (ext, ".def") == 0 || strcmp (ext, ".DEF") == 0)
@ -786,7 +858,10 @@ static boolean
gld_${EMULATION_NAME}_recognized_file(entry)
lang_input_statement_type *entry;
{
#ifdef DLL_SUPPORT
#ifdef TARGET_IS_i386pe
pe_dll_id_target ("pei-i386");
#endif
if (bfd_get_format (entry->the_bfd) == bfd_object)
{
const char *ext = entry->filename + strlen (entry->filename) - 4;
@ -800,7 +875,7 @@ gld_${EMULATION_NAME}_recognized_file(entry)
static void
gld_${EMULATION_NAME}_finish ()
{
#ifdef TARGET_IS_i386pe
#ifdef DLL_SUPPORT
if (link_info.shared)
{
pe_dll_fill_sections (output_bfd, &link_info);

View File

@ -73,6 +73,48 @@ static struct sec *edata_s, *reloc_s;
static unsigned char *edata_d, *reloc_d;
static int edata_sz, reloc_sz;
typedef struct {
char *target_name;
char *object_target;
int imagebase_reloc;
int pe_arch;
int bfd_arch;
int underscored;
} pe_details_type;
#define PE_ARCH_i386 1
static pe_details_type pe_detail_list[] = {
{
"pei-i386",
"pe-i386",
7 /* R_IMAGEBASE */,
PE_ARCH_i386,
bfd_arch_i386,
1
},
{ 0 }
};
static pe_details_type *pe_details;
#define U(str) (pe_details->underscored ? "_" str : str)
void
pe_dll_id_target (target)
char *target;
{
int i;
for (i=0; pe_detail_list[i].target_name; i++)
if (strcmp (pe_detail_list[i].target_name, target) == 0)
{
pe_details = pe_detail_list+i;
return;
}
einfo (_("%XUnsupported PEI architecture: %s\n"), target);
exit (1);
}
/************************************************************************
Helper functions for qsort. Relocs must be sorted so that we can write
@ -80,13 +122,19 @@ static int edata_sz, reloc_sz;
************************************************************************/
typedef struct {
bfd_vma vma;
char type;
short extra;
} reloc_data_type;
static int
reloc_sort (va, vb)
const void *va, *vb;
{
bfd_vma a = *(bfd_vma *) va;
bfd_vma b = *(bfd_vma *) vb;
return (a > b) - (a < b);
bfd_vma a = ((reloc_data_type *) va)->vma;
bfd_vma b = ((reloc_data_type *) vb)->vma;
return (a > b) ? 1 : ((a < b) ? -1 : 0);
}
static int
@ -323,8 +371,13 @@ process_def_file (abfd, info)
for (i = 0; i < NE; i++)
{
char *name = (char *) xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2);
*name = '_';
strcpy (name + 1, pe_def_file->exports[i].internal_name);
if (pe_details->underscored)
{
*name = '_';
strcpy (name + 1, pe_def_file->exports[i].internal_name);
}
else
strcpy (name, pe_def_file->exports[i].internal_name);
blhe = bfd_link_hash_lookup (info->hash,
name,
@ -376,7 +429,8 @@ process_def_file (abfd, info)
************************************************************************/
static void
build_filler_bfd ()
build_filler_bfd (include_edata)
int include_edata;
{
lang_input_statement_type *filler_file;
filler_file = lang_add_input_file ("dll stuff",
@ -392,19 +446,22 @@ build_filler_bfd ()
return;
}
edata_s = bfd_make_section_old_way (filler_bfd, ".edata");
if (edata_s == NULL
|| !bfd_set_section_flags (filler_bfd, edata_s,
(SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_KEEP
| SEC_IN_MEMORY)))
if (include_edata)
{
einfo ("%X%P: can not create .edata section: %E\n");
return;
edata_s = bfd_make_section_old_way (filler_bfd, ".edata");
if (edata_s == NULL
|| !bfd_set_section_flags (filler_bfd, edata_s,
(SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_KEEP
| SEC_IN_MEMORY)))
{
einfo ("%X%P: can not create .edata section: %E\n");
return;
}
bfd_set_section_size (filler_bfd, edata_s, edata_sz);
}
bfd_set_section_size (filler_bfd, edata_s, edata_sz);
reloc_s = bfd_make_section_old_way (filler_bfd, ".reloc");
if (reloc_s == NULL
@ -598,7 +655,7 @@ generate_reloc (abfd, info)
{
/* for .reloc stuff */
bfd_vma *reloc_addresses;
reloc_data_type *reloc_data;
int total_relocs = 0;
int i;
unsigned long sec_page = (unsigned long) (-1);
@ -612,7 +669,7 @@ generate_reloc (abfd, info)
for (s = b->sections; s; s = s->next)
total_relocs += s->reloc_count;
reloc_addresses = (bfd_vma *) xmalloc (total_relocs * sizeof (bfd_vma));
reloc_data = (reloc_data_type *) xmalloc (total_relocs * sizeof (reloc_data_type));
total_relocs = 0;
bi = 0;
@ -656,12 +713,22 @@ generate_reloc (abfd, info)
for (i = 0; i < nrelocs; i++)
{
if (!relocs[i]->howto->pc_relative
&& relocs[i]->howto->type != R_IMAGEBASE)
&& relocs[i]->howto->type != pe_details->imagebase_reloc)
{
switch (relocs[i]->howto->bitsize)
bfd_vma sym_vma;
struct symbol_cache_entry *sym = *relocs[i]->sym_ptr_ptr;
sym_vma = (relocs[i]->addend
+ sym->value
+ sym->section->vma
+ sym->section->output_offset
+ sym->section->output_section->vma);
reloc_data[total_relocs].vma = sec_vma + relocs[i]->address;
switch (relocs[i]->howto->bitsize*1000
+ relocs[i]->howto->rightshift)
{
case 32:
reloc_addresses[total_relocs++] = sec_vma + relocs[i]->address;
case 32000:
reloc_data[total_relocs].type = 3;
total_relocs++;
break;
default:
/* xgettext:c-format */
@ -682,11 +749,11 @@ generate_reloc (abfd, info)
reloc_addresses, which are all suitable for the .reloc section.
We must now create the new sections. */
qsort (reloc_addresses, total_relocs, sizeof (bfd_vma), reloc_sort);
qsort (reloc_data, total_relocs, sizeof (*reloc_data), reloc_sort);
for (i = 0; i < total_relocs; i++)
{
unsigned long this_page = (reloc_addresses[i] >> 12);
unsigned long this_page = (reloc_data[i].vma >> 12);
if (this_page != sec_page)
{
reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align */
@ -705,7 +772,7 @@ generate_reloc (abfd, info)
page_count = 0;
for (i = 0; i < total_relocs; i++)
{
unsigned long rva = reloc_addresses[i] - image_base;
unsigned long rva = reloc_data[i].vma - image_base;
unsigned long this_page = (rva & ~0xfff);
if (this_page != sec_page)
{
@ -719,8 +786,14 @@ generate_reloc (abfd, info)
sec_page = this_page;
page_count = 0;
}
bfd_put_16 (abfd, (rva & 0xfff) + 0x3000, reloc_d + reloc_sz);
bfd_put_16 (abfd, (rva & 0xfff) + (reloc_data[i].type<<12),
reloc_d + reloc_sz);
reloc_sz += 2;
if (reloc_data[i].type == 4)
{
bfd_put_16 (abfd, reloc_data[i].extra, reloc_d + reloc_sz);
reloc_sz += 2;
}
page_count++;
}
while (reloc_sz & 3)
@ -1049,19 +1122,25 @@ make_head (parent)
tmp_seq++;
abfd = bfd_create (oname, parent);
bfd_find_target ("pe-i386", abfd);
bfd_find_target (pe_details->object_target, abfd);
bfd_make_writable (abfd);
bfd_set_format (abfd, bfd_object);
bfd_set_arch_mach (abfd, bfd_arch_i386, 0);
bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
symptr = 0;
symtab = (asymbol **) xmalloc (6 * sizeof (asymbol *));
id2 = quick_section (abfd, ".idata$2", SEC_HAS_CONTENTS, 2);
id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
quick_symbol (abfd, "__head_", dll_symname, "", id2, BSF_GLOBAL, 0);
quick_symbol (abfd, "_", dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
quick_symbol (abfd, U("_head_"), dll_symname, "", id2, BSF_GLOBAL, 0);
quick_symbol (abfd, U(""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
/* OK, pay attention here. I got confused myself looking back at
it. We create a four-byte section to mark the beginning of the
list, and we include an offset of 4 in the section, so that the
pointer to the list points to the *end* of this section, which is
the start of the list of sections from other objects. */
bfd_set_section_size (abfd, id2, 20);
d2 = (unsigned char *) xmalloc (20);
@ -1119,18 +1198,18 @@ make_tail (parent)
tmp_seq++;
abfd = bfd_create (oname, parent);
bfd_find_target ("pe-i386", abfd);
bfd_find_target (pe_details->object_target, abfd);
bfd_make_writable (abfd);
bfd_set_format (abfd, bfd_object);
bfd_set_arch_mach (abfd, bfd_arch_i386, 0);
bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
symptr = 0;
symtab = (asymbol **) xmalloc (5 * sizeof (asymbol *));
id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
quick_symbol (abfd, "_", dll_symname, "_iname", id7, BSF_GLOBAL, 0);
quick_symbol (abfd, U(""), dll_symname, "_iname", id7, BSF_GLOBAL, 0);
bfd_set_section_size (abfd, id4, 4);
d4 = (unsigned char *) xmalloc (4);
@ -1198,17 +1277,27 @@ make_one (exp, parent)
int len;
char *oname;
bfd *abfd;
unsigned char *jmp_bytes;
int jmp_byte_count;
switch (pe_details->pe_arch)
{
case PE_ARCH_i386:
jmp_bytes = jmp_ix86_bytes;
jmp_byte_count = sizeof (jmp_ix86_bytes);
break;
}
oname = (char *) xmalloc (20);
sprintf (oname, "d%06d.o", tmp_seq);
tmp_seq++;
abfd = bfd_create (oname, parent);
bfd_find_target ("pe-i386", abfd);
bfd_find_target (pe_details->object_target, abfd);
bfd_make_writable (abfd);
bfd_set_format (abfd, bfd_object);
bfd_set_arch_mach (abfd, bfd_arch_i386, 0);
bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
symptr = 0;
symtab = (asymbol **) xmalloc (10 * sizeof (asymbol *));
@ -1217,16 +1306,21 @@ make_one (exp, parent)
id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
id6 = quick_section (abfd, ".idata$6", SEC_HAS_CONTENTS, 2);
quick_symbol (abfd, "_", exp->internal_name, "", tx, BSF_GLOBAL, 0);
quick_symbol (abfd, "__head_", dll_symname, "", UNDSEC, BSF_GLOBAL, 0);
quick_symbol (abfd, "___imp_", exp->internal_name, "", id5, BSF_GLOBAL, 0);
quick_symbol (abfd, "__imp__", exp->internal_name, "", id5, BSF_GLOBAL, 0);
quick_symbol (abfd, U(""), exp->internal_name, "", tx, BSF_GLOBAL, 0);
quick_symbol (abfd, U("_head_"), dll_symname, "", UNDSEC, BSF_GLOBAL, 0);
quick_symbol (abfd, U("__imp_"), exp->internal_name, "", id5, BSF_GLOBAL, 0);
quick_symbol (abfd, U("_imp__"), exp->internal_name, "", id5, BSF_GLOBAL, 0);
bfd_set_section_size (abfd, tx, 8);
td = (unsigned char *) xmalloc (8);
bfd_set_section_size (abfd, tx, jmp_byte_count);
td = (unsigned char *) xmalloc (jmp_byte_count);
tx->contents = td;
memcpy (td, jmp_ix86_bytes, 8);
quick_reloc (abfd, 2, BFD_RELOC_32, 2);
memcpy (td, jmp_bytes, jmp_byte_count);
switch (pe_details->pe_arch)
{
case PE_ARCH_i386:
quick_reloc (abfd, 2, BFD_RELOC_32, 2);
break;
}
save_relocs (tx);
bfd_set_section_size (abfd, id7, 4);
@ -1289,7 +1383,7 @@ make_one (exp, parent)
bfd_set_symtab (abfd, symtab, symptr);
bfd_set_section_contents (abfd, tx, td, 0, 4);
bfd_set_section_contents (abfd, tx, td, 0, jmp_byte_count);
bfd_set_section_contents (abfd, id7, d7, 0, 4);
bfd_set_section_contents (abfd, id5, d5, 0, 4);
bfd_set_section_contents (abfd, id4, d4, 0, 4);
@ -1344,10 +1438,6 @@ pe_dll_generate_implib (def, impfilename)
/* Work out a reasonable size of things to put onto one line. */
ar_head = make_head (outarch);
ar_tail = make_tail (outarch);
if (ar_head == NULL || ar_tail == NULL)
return;
for (i = 0; i<def->num_exports; i++)
{
@ -1361,6 +1451,11 @@ pe_dll_generate_implib (def, impfilename)
def->exports[i].internal_name = internal;
}
ar_tail = make_tail (outarch);
if (ar_head == NULL || ar_tail == NULL)
return;
/* Now stick them all into the archive */
ar_head->next = head;
@ -1403,6 +1498,7 @@ pe_process_import_defs (output_bfd, link_info)
struct bfd_link_info *link_info;
{
def_file_module *module;
pe_dll_id_target(bfd_get_target (output_bfd));
if (!pe_def_file)
return;
@ -1427,7 +1523,7 @@ pe_process_import_defs (output_bfd, link_info)
/* see if we need this import */
char *name = (char *) xmalloc (strlen (pe_def_file->imports[i].internal_name) + 2);
sprintf (name, "_%s", pe_def_file->imports[i].internal_name);
sprintf (name, "%s%s", U(""), pe_def_file->imports[i].internal_name);
blhe = bfd_link_hash_lookup (link_info->hash, name,
false, false, false);
free (name);
@ -1527,7 +1623,7 @@ pe_implied_import_dll (filename)
/* No, I can't use bfd here. kernel32.dll puts its export table in
the middle of the .rdata section. */
dll = bfd_openr (filename, "pei-i386");
dll = bfd_openr (filename, pe_details->target_name);
if (!dll)
{
einfo ("%Xopen %s: %s\n", filename, bfd_errmsg (bfd_get_error ()));
@ -1611,10 +1707,20 @@ pe_dll_build_sections (abfd, info)
bfd *abfd;
struct bfd_link_info *info;
{
pe_dll_id_target (bfd_get_target (abfd));
process_def_file (abfd, info);
generate_edata (abfd, info);
build_filler_bfd ();
build_filler_bfd (1);
}
void
pe_exe_build_sections (abfd, info)
bfd *abfd;
struct bfd_link_info *info;
{
pe_dll_id_target (bfd_get_target (abfd));
build_filler_bfd (0);
}
void
@ -1622,6 +1728,7 @@ pe_dll_fill_sections (abfd, info)
bfd *abfd;
struct bfd_link_info *info;
{
pe_dll_id_target (bfd_get_target (abfd));
image_base = pe_data (abfd)->pe_opthdr.ImageBase;
generate_reloc (abfd, info);
@ -1649,3 +1756,31 @@ pe_dll_fill_sections (abfd, info)
edata_s->contents = edata_d;
reloc_s->contents = reloc_d;
}
void
pe_exe_fill_sections (abfd, info)
bfd *abfd;
struct bfd_link_info *info;
{
pe_dll_id_target (bfd_get_target (abfd));
image_base = pe_data (abfd)->pe_opthdr.ImageBase;
generate_reloc (abfd, info);
if (reloc_sz > 0)
{
bfd_set_section_size (filler_bfd, reloc_s, reloc_sz);
/* Resize the sections. */
lang_size_sections (stat_ptr->head, abs_output_section,
&stat_ptr->head, 0, (bfd_vma) 0, false);
/* Redo special stuff. */
ldemul_after_allocation ();
/* Do the assignments again. */
lang_do_assignments (stat_ptr->head,
abs_output_section,
(fill_type) 0, (bfd_vma) 0);
}
reloc_s->contents = reloc_d;
}

View File

@ -38,6 +38,7 @@ fi
cat <<EOF
${RELOCATING+OUTPUT_FORMAT(${OUTPUT_FORMAT})}
${RELOCATING-OUTPUT_FORMAT(${RELOCATEABLE_OUTPUT_FORMAT})}
${OUTPUT_ARCH+OUTPUT_ARCH(${OUTPUT_ARCH})}
${LIB_SEARCH_DIRS}