2009-01-26 Kai Tietz <kai.tietz@onevision.com>
* pe-dll.c (tmp_seq2): New static variable. (make_singleton_name_imp): New. (make_import_fixup_entry): Use for v2 the _imp_<name> symbol and avoid duplicate import table generation for same symbol. (pe_create_runtime_relocator_reference): Make reference for 64-bit 8 bytes.
This commit is contained in:
parent
54d972a37e
commit
9382254dc7
|
@ -1,3 +1,12 @@
|
||||||
|
2009-01-26 Kai Tietz <kai.tietz@onevision.com>
|
||||||
|
|
||||||
|
* pe-dll.c (tmp_seq2): New static variable.
|
||||||
|
(make_singleton_name_imp): New.
|
||||||
|
(make_import_fixup_entry): Use for v2 the _imp_<name> symbol and
|
||||||
|
avoid duplicate import table generation for same symbol.
|
||||||
|
(pe_create_runtime_relocator_reference): Make reference for
|
||||||
|
64-bit 8 bytes.
|
||||||
|
|
||||||
2009-01-21 Alan Modra <amodra@bigpond.net.au>
|
2009-01-21 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* emultempl/spuelf.em (params): Init new field.
|
* emultempl/spuelf.em (params): Init new field.
|
||||||
|
|
88
ld/pe-dll.c
88
ld/pe-dll.c
|
@ -1656,6 +1656,7 @@ pe_dll_generate_def_file (const char *pe_out_def_filename)
|
||||||
static asymbol **symtab;
|
static asymbol **symtab;
|
||||||
static int symptr;
|
static int symptr;
|
||||||
static int tmp_seq;
|
static int tmp_seq;
|
||||||
|
static int tmp_seq2;
|
||||||
static const char *dll_filename;
|
static const char *dll_filename;
|
||||||
static char *dll_symname;
|
static char *dll_symname;
|
||||||
|
|
||||||
|
@ -2170,6 +2171,47 @@ make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub)
|
||||||
return abfd;
|
return abfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bfd *
|
||||||
|
make_singleton_name_imp (const char *import, bfd *parent)
|
||||||
|
{
|
||||||
|
/* Name thunks go to idata$4. */
|
||||||
|
asection *id5;
|
||||||
|
unsigned char *d5;
|
||||||
|
char *oname;
|
||||||
|
bfd *abfd;
|
||||||
|
|
||||||
|
oname = xmalloc (20);
|
||||||
|
sprintf (oname, "nmimp%06d.o", tmp_seq2);
|
||||||
|
tmp_seq2++;
|
||||||
|
|
||||||
|
abfd = bfd_create (oname, parent);
|
||||||
|
bfd_find_target (pe_details->object_target, abfd);
|
||||||
|
bfd_make_writable (abfd);
|
||||||
|
|
||||||
|
bfd_set_format (abfd, bfd_object);
|
||||||
|
bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
|
||||||
|
|
||||||
|
symptr = 0;
|
||||||
|
symtab = xmalloc (3 * sizeof (asymbol *));
|
||||||
|
id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
|
||||||
|
quick_symbol (abfd, U ("_imp_"), import, "", id5, BSF_GLOBAL, 0);
|
||||||
|
|
||||||
|
/* We need space for the real thunk and for the null terminator. */
|
||||||
|
bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE * 2);
|
||||||
|
d5 = xmalloc (PE_IDATA5_SIZE * 2);
|
||||||
|
id5->contents = d5;
|
||||||
|
memset (d5, 0, PE_IDATA5_SIZE * 2);
|
||||||
|
quick_reloc (abfd, 0, BFD_RELOC_RVA, 2);
|
||||||
|
save_relocs (id5);
|
||||||
|
|
||||||
|
bfd_set_symtab (abfd, symtab, symptr);
|
||||||
|
|
||||||
|
bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA4_SIZE * 2);
|
||||||
|
|
||||||
|
bfd_make_readable (abfd);
|
||||||
|
return abfd;
|
||||||
|
}
|
||||||
|
|
||||||
static bfd *
|
static bfd *
|
||||||
make_singleton_name_thunk (const char *import, bfd *parent)
|
make_singleton_name_thunk (const char *import, bfd *parent)
|
||||||
{
|
{
|
||||||
|
@ -2288,7 +2330,12 @@ make_import_fixup_entry (const char *name,
|
||||||
|
|
||||||
quick_symbol (abfd, U ("_nm_thnk_"), name, "", UNDSEC, BSF_GLOBAL, 0);
|
quick_symbol (abfd, U ("_nm_thnk_"), name, "", UNDSEC, BSF_GLOBAL, 0);
|
||||||
quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
|
quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
|
||||||
quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
|
/* For relocator v2 we have to use the .idata$5 element and not
|
||||||
|
fixup_name. */
|
||||||
|
if (link_info.pei386_runtime_pseudo_reloc == 2)
|
||||||
|
quick_symbol (abfd, U ("_imp_"), name, "", UNDSEC, BSF_GLOBAL, 0);
|
||||||
|
else
|
||||||
|
quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
|
||||||
|
|
||||||
bfd_set_section_size (abfd, id2, 20);
|
bfd_set_section_size (abfd, id2, 20);
|
||||||
d2 = xmalloc (20);
|
d2 = xmalloc (20);
|
||||||
|
@ -2422,8 +2469,8 @@ pe_create_runtime_relocator_reference (bfd *parent)
|
||||||
quick_symbol (abfd, "", U ("_pei386_runtime_relocator"), "", UNDSEC,
|
quick_symbol (abfd, "", U ("_pei386_runtime_relocator"), "", UNDSEC,
|
||||||
BSF_NO_FLAGS, 0);
|
BSF_NO_FLAGS, 0);
|
||||||
|
|
||||||
bfd_set_section_size (abfd, extern_rt_rel, 4);
|
bfd_set_section_size (abfd, extern_rt_rel, PE_IDATA5_SIZE);
|
||||||
extern_rt_rel_d = xmalloc (4);
|
extern_rt_rel_d = xmalloc (PE_IDATA5_SIZE);
|
||||||
extern_rt_rel->contents = extern_rt_rel_d;
|
extern_rt_rel->contents = extern_rt_rel_d;
|
||||||
|
|
||||||
quick_reloc (abfd, 0, BFD_RELOC_RVA, 1);
|
quick_reloc (abfd, 0, BFD_RELOC_RVA, 1);
|
||||||
|
@ -2431,7 +2478,7 @@ pe_create_runtime_relocator_reference (bfd *parent)
|
||||||
|
|
||||||
bfd_set_symtab (abfd, symtab, symptr);
|
bfd_set_symtab (abfd, symtab, symptr);
|
||||||
|
|
||||||
bfd_set_section_contents (abfd, extern_rt_rel, extern_rt_rel_d, 0, 4);
|
bfd_set_section_contents (abfd, extern_rt_rel, extern_rt_rel_d, 0, PE_IDATA5_SIZE);
|
||||||
|
|
||||||
bfd_make_readable (abfd);
|
bfd_make_readable (abfd);
|
||||||
return abfd;
|
return abfd;
|
||||||
|
@ -2443,25 +2490,48 @@ pe_create_import_fixup (arelent *rel, asection *s, bfd_vma addend)
|
||||||
char buf[300];
|
char buf[300];
|
||||||
struct bfd_symbol *sym = *rel->sym_ptr_ptr;
|
struct bfd_symbol *sym = *rel->sym_ptr_ptr;
|
||||||
struct bfd_link_hash_entry *name_thunk_sym;
|
struct bfd_link_hash_entry *name_thunk_sym;
|
||||||
|
struct bfd_link_hash_entry *name_imp_sym;
|
||||||
const char *name = sym->name;
|
const char *name = sym->name;
|
||||||
char *fixup_name = make_import_fixup_mark (rel);
|
char *fixup_name = make_import_fixup_mark (rel);
|
||||||
bfd *b;
|
bfd *b;
|
||||||
|
int need_import_table = 1;
|
||||||
|
|
||||||
|
sprintf (buf, U ("_imp_%s"), name);
|
||||||
|
name_imp_sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);
|
||||||
|
|
||||||
sprintf (buf, U ("_nm_thnk_%s"), name);
|
sprintf (buf, U ("_nm_thnk_%s"), name);
|
||||||
|
|
||||||
name_thunk_sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);
|
name_thunk_sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);
|
||||||
|
|
||||||
if (!name_thunk_sym || name_thunk_sym->type != bfd_link_hash_defined)
|
/* For version 2 pseudo relocation we don't need to add an import
|
||||||
|
if the import symbol is already present. */
|
||||||
|
if (link_info.pei386_runtime_pseudo_reloc == 2
|
||||||
|
&& name_imp_sym
|
||||||
|
&& name_imp_sym->type == bfd_link_hash_defined)
|
||||||
|
need_import_table = 0;
|
||||||
|
|
||||||
|
if (need_import_table == 1
|
||||||
|
&& (!name_thunk_sym || name_thunk_sym->type != bfd_link_hash_defined))
|
||||||
{
|
{
|
||||||
bfd *b = make_singleton_name_thunk (name, link_info.output_bfd);
|
bfd *b = make_singleton_name_thunk (name, link_info.output_bfd);
|
||||||
add_bfd_to_link (b, b->filename, &link_info);
|
add_bfd_to_link (b, b->filename, &link_info);
|
||||||
|
|
||||||
/* If we ever use autoimport, we have to cast text section writable. */
|
/* If we ever use autoimport, we have to cast text section writable.
|
||||||
config.text_read_only = FALSE;
|
But not for version 2. */
|
||||||
link_info.output_bfd->flags &= ~WP_TEXT;
|
if (link_info.pei386_runtime_pseudo_reloc != 2)
|
||||||
|
{
|
||||||
|
config.text_read_only = FALSE;
|
||||||
|
link_info.output_bfd->flags &= ~WP_TEXT;
|
||||||
|
}
|
||||||
|
if (link_info.pei386_runtime_pseudo_reloc == 2)
|
||||||
|
{
|
||||||
|
b = make_singleton_name_imp (name, link_info.output_bfd);
|
||||||
|
add_bfd_to_link (b, b->filename, &link_info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addend == 0 || link_info.pei386_runtime_pseudo_reloc)
|
if ((addend == 0 || link_info.pei386_runtime_pseudo_reloc)
|
||||||
|
&& need_import_table == 1)
|
||||||
{
|
{
|
||||||
extern char * pe_data_import_dll;
|
extern char * pe_data_import_dll;
|
||||||
char * dll_symname = pe_data_import_dll ? pe_data_import_dll : "unknown";
|
char * dll_symname = pe_data_import_dll ? pe_data_import_dll : "unknown";
|
||||||
|
|
Loading…
Reference in New Issue