Decorated symbols in import libs (BUG 30421)
PR 30421 * cofflink.c (_decoration_hash_newfunc): New function. (_bfd_coff_link_hash_table_init): Call it. * libcoff-in.h (struct coff_link_hash_table): Add decoration_hash field. (struct decoration_hash_entry): Declare. (_decoration_hash_newfunc): Prototype. * libcoff.h: Regenerate. * emultempl/pe.em (set_decoration): New function. (pe_fixup_stdcalls): Call the new function. * emultempl/pep.em (set_decoration): New function. (pep_fixup_stdcalls): Call the new function. * pe-dll.c (make_one): Check for decoated symbols.
This commit is contained in:
@@ -1,3 +1,14 @@
|
||||
2023-05-17 Luca Bacci <luca.bacci@outlook.com>
|
||||
|
||||
PR 30421
|
||||
* cofflink.c (_decoration_hash_newfunc): New function.
|
||||
(_bfd_coff_link_hash_table_init): Call it.
|
||||
* libcoff-in.h (struct coff_link_hash_table): Add decoration_hash
|
||||
field.
|
||||
(struct decoration_hash_entry): Declare.
|
||||
(_decoration_hash_newfunc): Prototype.
|
||||
* libcoff.h: Regenerate.
|
||||
|
||||
2023-05-16 Oleg Tolmatcev <oleg.tolmatcev@gmail.com>
|
||||
|
||||
* libcoff-in.h (struct coff_tdata): Add section_by_index and
|
||||
|
||||
+33
-1
@@ -89,6 +89,34 @@ _bfd_coff_link_hash_newfunc (struct bfd_hash_entry *entry,
|
||||
return (struct bfd_hash_entry *) ret;
|
||||
}
|
||||
|
||||
struct bfd_hash_entry *
|
||||
_decoration_hash_newfunc (struct bfd_hash_entry *entry,
|
||||
struct bfd_hash_table *table,
|
||||
const char *string)
|
||||
{
|
||||
struct decoration_hash_entry *ret = (struct decoration_hash_entry *) entry;
|
||||
|
||||
/* Allocate the structure if it has not already been allocated by a
|
||||
subclass. */
|
||||
if (ret == NULL)
|
||||
{
|
||||
ret = (struct decoration_hash_entry *)
|
||||
bfd_hash_allocate (table, sizeof (struct decoration_hash_entry));
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Call the allocation method of the superclass. */
|
||||
ret = (struct decoration_hash_entry *)
|
||||
_bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string);
|
||||
if (ret != NULL)
|
||||
{
|
||||
ret->decorated_link = NULL;
|
||||
}
|
||||
|
||||
return (struct bfd_hash_entry *) ret;
|
||||
}
|
||||
|
||||
/* Initialize a COFF linker hash table. */
|
||||
|
||||
bool
|
||||
@@ -100,7 +128,11 @@ _bfd_coff_link_hash_table_init (struct coff_link_hash_table *table,
|
||||
unsigned int entsize)
|
||||
{
|
||||
memset (&table->stab_info, 0, sizeof (table->stab_info));
|
||||
return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
|
||||
|
||||
return bfd_hash_table_init (&table->decoration_hash,
|
||||
_decoration_hash_newfunc,
|
||||
sizeof (struct decoration_hash_entry))
|
||||
&&_bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
|
||||
}
|
||||
|
||||
/* Create a COFF linker hash table. */
|
||||
|
||||
@@ -290,6 +290,9 @@ struct coff_link_hash_table
|
||||
struct bfd_link_hash_table root;
|
||||
/* A pointer to information used to link stabs in sections. */
|
||||
struct stab_info stab_info;
|
||||
/* Hash table that maps undecorated names to their respective
|
||||
* decorated coff_link_hash_entry as found in fixup_stdcalls */
|
||||
struct bfd_hash_table decoration_hash;
|
||||
};
|
||||
|
||||
struct coff_reloc_cookie
|
||||
@@ -321,6 +324,12 @@ struct coff_reloc_cookie
|
||||
|
||||
#define coff_hash_table(p) ((struct coff_link_hash_table *) ((p)->hash))
|
||||
|
||||
struct decoration_hash_entry
|
||||
{
|
||||
struct bfd_hash_entry root;
|
||||
struct bfd_link_hash_entry *decorated_link;
|
||||
};
|
||||
|
||||
/* Functions in coffgen.c. */
|
||||
extern bfd_cleanup coff_object_p
|
||||
(bfd *);
|
||||
@@ -568,6 +577,8 @@ struct coff_section_alignment_entry
|
||||
unsigned int alignment_power;
|
||||
};
|
||||
|
||||
extern struct bfd_hash_entry *_decoration_hash_newfunc
|
||||
(struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
|
||||
extern struct bfd_hash_entry *_bfd_coff_link_hash_newfunc
|
||||
(struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
|
||||
extern bool _bfd_coff_link_hash_table_init
|
||||
|
||||
@@ -294,6 +294,9 @@ struct coff_link_hash_table
|
||||
struct bfd_link_hash_table root;
|
||||
/* A pointer to information used to link stabs in sections. */
|
||||
struct stab_info stab_info;
|
||||
/* Hash table that maps undecorated names to their respective
|
||||
* decorated coff_link_hash_entry as found in fixup_stdcalls */
|
||||
struct bfd_hash_table decoration_hash;
|
||||
};
|
||||
|
||||
struct coff_reloc_cookie
|
||||
@@ -325,6 +328,12 @@ struct coff_reloc_cookie
|
||||
|
||||
#define coff_hash_table(p) ((struct coff_link_hash_table *) ((p)->hash))
|
||||
|
||||
struct decoration_hash_entry
|
||||
{
|
||||
struct bfd_hash_entry root;
|
||||
struct bfd_link_hash_entry *decorated_link;
|
||||
};
|
||||
|
||||
/* Functions in coffgen.c. */
|
||||
extern bfd_cleanup coff_object_p
|
||||
(bfd *);
|
||||
@@ -572,6 +581,8 @@ struct coff_section_alignment_entry
|
||||
unsigned int alignment_power;
|
||||
};
|
||||
|
||||
extern struct bfd_hash_entry *_decoration_hash_newfunc
|
||||
(struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
|
||||
extern struct bfd_hash_entry *_bfd_coff_link_hash_newfunc
|
||||
(struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
|
||||
extern bool _bfd_coff_link_hash_table_init
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
2023-05-17 Luca Bacci <luca.bacci@outlook.com>
|
||||
|
||||
PR 30421
|
||||
* emultempl/pe.em (set_decoration): New function.
|
||||
(pe_fixup_stdcalls): Call the new function.
|
||||
* emultempl/pep.em (set_decoration): New function.
|
||||
(pep_fixup_stdcalls): Call the new function.
|
||||
* pe-dll.c (make_one): Check for decoated symbols.
|
||||
|
||||
2023-05-16 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 30359
|
||||
|
||||
+28
-1
@@ -1188,6 +1188,30 @@ change_undef (struct bfd_link_hash_entry * undef,
|
||||
lang_add_gc_name (sym->root.string);
|
||||
}
|
||||
|
||||
static void
|
||||
set_decoration (const char *undecorated_name,
|
||||
struct bfd_link_hash_entry * decoration)
|
||||
{
|
||||
static bool gave_warning_message = false;
|
||||
struct decoration_hash_entry *entry;
|
||||
|
||||
if (is_underscoring () && undecorated_name[0] == '_')
|
||||
undecorated_name++;
|
||||
|
||||
entry = (struct decoration_hash_entry *)
|
||||
bfd_hash_lookup (&(coff_hash_table (&link_info)->decoration_hash),
|
||||
undecorated_name, true /* create */, false /* copy */);
|
||||
|
||||
if (entry->decorated_link != NULL && !gave_warning_message)
|
||||
{
|
||||
einfo (_("%P: warning: overwriting decorated name %s with %s\n"),
|
||||
entry->decorated_link->root.string, undecorated_name);
|
||||
gave_warning_message = true;
|
||||
}
|
||||
|
||||
entry->decorated_link = decoration;
|
||||
}
|
||||
|
||||
static void
|
||||
pe_fixup_stdcalls (void)
|
||||
{
|
||||
@@ -1231,7 +1255,10 @@ pe_fixup_stdcalls (void)
|
||||
bfd_link_hash_traverse (link_info.hash, pe_undef_cdecl_match,
|
||||
(char *) name);
|
||||
if (pe_undef_found_sym)
|
||||
change_undef (undef, pe_undef_found_sym);
|
||||
{
|
||||
change_undef (undef, pe_undef_found_sym);
|
||||
set_decoration (undef->root.string, pe_undef_found_sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1119,6 +1119,30 @@ pep_undef_cdecl_match (struct bfd_link_hash_entry *h, void *inf)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
set_decoration (const char *undecorated_name,
|
||||
struct bfd_link_hash_entry * decoration)
|
||||
{
|
||||
static bool gave_warning_message = false;
|
||||
struct decoration_hash_entry *entry;
|
||||
|
||||
if (is_underscoring () && undecorated_name[0] == '_')
|
||||
undecorated_name++;
|
||||
|
||||
entry = (struct decoration_hash_entry *)
|
||||
bfd_hash_lookup (&(coff_hash_table (&link_info)->decoration_hash),
|
||||
undecorated_name, true /* create */, false /* copy */);
|
||||
|
||||
if (entry->decorated_link != NULL && !gave_warning_message)
|
||||
{
|
||||
einfo (_("%P: warning: overwriting decorated name %s with %s\n"),
|
||||
entry->decorated_link->root.string, undecorated_name);
|
||||
gave_warning_message = true;
|
||||
}
|
||||
|
||||
entry->decorated_link = decoration;
|
||||
}
|
||||
|
||||
static void
|
||||
pep_fixup_stdcalls (void)
|
||||
{
|
||||
@@ -1180,6 +1204,7 @@ pep_fixup_stdcalls (void)
|
||||
undef->type = bfd_link_hash_defined;
|
||||
undef->u.def.value = sym->u.def.value;
|
||||
undef->u.def.section = sym->u.def.section;
|
||||
set_decoration (undef->root.string, sym);
|
||||
|
||||
if (pep_enable_stdcall_fixup == -1)
|
||||
{
|
||||
|
||||
+32
-7
@@ -2321,6 +2321,31 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
|
||||
bfd *abfd;
|
||||
const unsigned char *jmp_bytes = NULL;
|
||||
int jmp_byte_count = 0;
|
||||
const char *internal_name = exp->internal_name;
|
||||
|
||||
if (!exp->flag_noname)
|
||||
{
|
||||
/* Check for a decorated symbol name */
|
||||
struct decoration_hash_entry *entry;
|
||||
|
||||
entry = (struct decoration_hash_entry *)
|
||||
bfd_hash_lookup (&(coff_hash_table (&link_info)->decoration_hash),
|
||||
internal_name, false, false);
|
||||
if (entry)
|
||||
{
|
||||
if (entry->decorated_link)
|
||||
{
|
||||
internal_name = entry->decorated_link->root.string;
|
||||
|
||||
if (pe_details->underscored && internal_name[0] == '_')
|
||||
internal_name++;
|
||||
}
|
||||
else
|
||||
{
|
||||
einfo (_("%P: error: NULL decorated name for %s\n"), internal_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Include the jump stub section only if it is needed. A jump
|
||||
stub is needed if the symbol being imported <sym> is a function
|
||||
@@ -2382,13 +2407,13 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
|
||||
id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
|
||||
id6 = quick_section (abfd, ".idata$6", SEC_HAS_CONTENTS, 2);
|
||||
|
||||
if (*exp->internal_name == '@')
|
||||
if (*internal_name == '@')
|
||||
{
|
||||
quick_symbol (abfd, U ("_head_"), dll_symname, "", UNDSEC,
|
||||
BSF_GLOBAL, 0);
|
||||
if (include_jmp_stub)
|
||||
quick_symbol (abfd, "", exp->internal_name, "", tx, BSF_GLOBAL, 0);
|
||||
quick_symbol (abfd, "__imp_", exp->internal_name, "", id5,
|
||||
quick_symbol (abfd, "", internal_name, "", tx, BSF_GLOBAL, 0);
|
||||
quick_symbol (abfd, "__imp_", internal_name, "", id5,
|
||||
BSF_GLOBAL, 0);
|
||||
/* Fastcall applies only to functions,
|
||||
so no need for auto-import symbol. */
|
||||
@@ -2398,18 +2423,18 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
|
||||
quick_symbol (abfd, U ("_head_"), dll_symname, "", UNDSEC,
|
||||
BSF_GLOBAL, 0);
|
||||
if (include_jmp_stub)
|
||||
quick_symbol (abfd, U (""), exp->internal_name, "", tx,
|
||||
quick_symbol (abfd, U (""), internal_name, "", tx,
|
||||
BSF_GLOBAL, 0);
|
||||
quick_symbol (abfd, "__imp_", U (""), exp->internal_name, id5,
|
||||
quick_symbol (abfd, "__imp_", U (""), internal_name, id5,
|
||||
BSF_GLOBAL, 0);
|
||||
/* Symbol to reference ord/name of imported
|
||||
data symbol, used to implement auto-import. */
|
||||
if (exp->flag_data)
|
||||
quick_symbol (abfd, "__nm_", U (""), exp->internal_name, id6,
|
||||
quick_symbol (abfd, "__nm_", U (""), internal_name, id6,
|
||||
BSF_GLOBAL,0);
|
||||
}
|
||||
if (pe_dll_compat_implib)
|
||||
quick_symbol (abfd, "___imp_", exp->internal_name, "", id5,
|
||||
quick_symbol (abfd, "___imp_", internal_name, "", id5,
|
||||
BSF_GLOBAL, 0);
|
||||
|
||||
if (include_jmp_stub)
|
||||
|
||||
Reference in New Issue
Block a user