summaryrefslogtreecommitdiff
path: root/ld/pe-dll.c
diff options
context:
space:
mode:
authorKai Tietz <kai.tietz@onevision.com>2009-11-15 07:52:42 +0000
committerKai Tietz <kai.tietz@onevision.com>2009-11-15 07:52:42 +0000
commit2fde9dd8ea56f8a1c4963ef69b9d824f7c84f1ac (patch)
tree3ef1f037c098483805e1ab62156e5bc2241c54d5 /ld/pe-dll.c
parent62b00dfcba17ee2ec3344712c0a96ba3f3a2ccdc (diff)
downloadbinutils-redhat-2fde9dd8ea56f8a1c4963ef69b9d824f7c84f1ac.tar.gz
2009-11-15 Kai Tietz <kai.tietz@onevision.com>
* pe-dll.c (pe_undef_alias_cdecl_match): New function. (pe_find_cdecl_alias_match): New function. (pe_process_import_defs): Add matching for import symbols declared as cdecl for fastcall/stdcall. * emultempl/pe.em (pe_undef_cdecl_match): Treat fastcall symbols, too. (pe_fixup_stdcalls): Likewise. (gld_XXX_after_open): Redo scanning for imported fastcall/stdcall symbols as cdecl one. * emultempl/pep.em (pep_undef_cdecl_match): Treat fastcall symbols, too. (pep_fixup_stdcalls): Likewise. (gld_XXX_after_open): Redo scanning for imported fastcall/stdcall symbols as cdecl one. 2009-11-15 Kai Tietz <kai.tietz@onevision.com> * ld-pe/direct2_client.c: New file. * ld-pe/direct2_dll.c: Likewise. * ld-pe/direct2_dll.def: Likewise. * ld-pe/pe-run2.exp: Likewise.
Diffstat (limited to 'ld/pe-dll.c')
-rw-r--r--ld/pe-dll.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index dbf1b5e467..beeb580f20 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -2761,6 +2761,37 @@ pe_dll_generate_implib (def_file *def, const char *impfilename, struct bfd_link_
}
}
+static struct bfd_link_hash_entry *found_sym;
+
+static bfd_boolean
+pe_undef_alias_cdecl_match (struct bfd_link_hash_entry *h, void *inf)
+{
+ int sl;
+ char *string = inf;
+ const char *hs = h->root.string;
+
+ sl = strlen (string);
+ if (h->type == bfd_link_hash_undefined
+ && ((*hs == '@' && *string == '_'
+ && strncmp (hs + 1, string + 1, sl - 1) == 0)
+ || strncmp (hs, string, sl) == 0)
+ && h->root.string[sl] == '@')
+ {
+ found_sym = h;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static struct bfd_link_hash_entry *
+pe_find_cdecl_alias_match (char *name)
+{
+ found_sym = 0;
+ bfd_link_hash_traverse (link_info.hash, pe_undef_alias_cdecl_match,
+ (char *) name);
+ return found_sym;
+}
+
static void
add_bfd_to_link (bfd *abfd, const char *name, struct bfd_link_info *link_info)
{
@@ -2808,6 +2839,9 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *link_info)
size_t len = strlen (pe_def_file->imports[i].internal_name);
char *name = xmalloc (len + 2 + 6);
bfd_boolean include_jmp_stub = FALSE;
+ bfd_boolean is_cdecl = FALSE;
+ if (!lead_at && strchr (pe_def_file->imports[i].internal_name, '@') == NULL)
+ is_cdecl = TRUE;
if (lead_at)
sprintf (name, "%s",
@@ -2836,6 +2870,14 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *link_info)
else
include_jmp_stub = TRUE;
+ if (is_cdecl && !blhe)
+ {
+ sprintf (name, "%s%s",U (""),
+ pe_def_file->imports[i].internal_name);
+ blhe = pe_find_cdecl_alias_match (name);
+ include_jmp_stub = TRUE;
+ }
+
free (name);
if (blhe && blhe->type == bfd_link_hash_undefined)