/* Routines to help build PEI-format DLLs (Win32 etc)
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009 Free Software Foundation, Inc.
+ 2008, 2009, 2010 Free Software Foundation, Inc.
Written by DJ Delorie <dj@cygnus.com>
This file is part of the GNU Binutils.
int pe_dll_extra_pe_debug = 0;
int pe_use_nul_prefixed_import_tables = 0;
int pe_use_coff_long_section_names = -1;
+int pe_leading_underscore = -1;
/* Static variables and types. */
#define PE_ARCH_arm_epoc 5
#define PE_ARCH_arm_wince 6
-static const pe_details_type pe_detail_list[] =
+/* Don't make it constant as underscore mode gets possibly overriden
+ by target or -(no-)leading-underscore option. */
+static pe_details_type pe_detail_list[] =
{
{
#ifdef pe_use_x86_64
if (strcmp (pe_detail_list[i].target_name, target) == 0
|| strcmp (pe_detail_list[i].object_target, target) == 0)
{
+ int u = pe_leading_underscore; /* Underscoring mode. -1 for use default. */
+ if (u == -1)
+ bfd_get_target_info (target, NULL, NULL, &u, NULL);
+ if (u != -1)
+ pe_detail_list[i].underscored = (u != 0 ? TRUE : FALSE);
pe_details = pe_detail_list + i;
return;
}
for (bi = 0, b = info->input_bfds; b; bi++, b = b->link_next)
{
arelent **relocs;
- int relsize, nrelocs, i;
+ int relsize, nrelocs;
for (s = b->sections; s; s = s->next)
{
if (sym->flags == BSF_WEAK)
{
struct bfd_link_hash_entry *blhe
- = bfd_link_hash_lookup (info->hash, sym->name,
+ = bfd_wrapped_link_hash_lookup (abfd, info, sym->name,
FALSE, FALSE, FALSE);
- if (!blhe || blhe->type != bfd_link_hash_defined)
- continue;
+ if (blhe && blhe->type == bfd_link_hash_undefweak)
+ {
+ /* Check aux sym and see if it is defined or not. */
+ struct coff_link_hash_entry *h, *h2;
+ h = (struct coff_link_hash_entry *)blhe;
+ if (h->symbol_class != C_NT_WEAK || h->numaux != 1)
+ continue;
+ h2 = h->auxbfd->tdata.coff_obj_data->sym_hashes
+ [h->aux->x_sym.x_tagndx.l];
+ /* We don't want a base reloc if the aux sym is not
+ found, undefined, or if it is the constant ABS
+ zero default value. (We broaden that slightly by
+ not testing the value, just the section; there's
+ no reason we'd want a reference to any absolute
+ address to get relocated during rebasing). */
+ if (!h2 || h2->root.type == bfd_link_hash_undefined
+ || h2->root.u.def.section == &bfd_abs_section)
+ continue;
+ }
+ else if (!blhe || blhe->type != bfd_link_hash_defined)
+ continue;
}
sym_vma = (relocs[i]->addend
bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
symptr = 0;
- symtab = xmalloc (11 * sizeof (asymbol *));
- tx = quick_section (abfd, ".text", SEC_CODE|SEC_HAS_CONTENTS, 2);
+ symtab = xmalloc (12 * sizeof (asymbol *));
+
+ tx = quick_section (abfd, ".text", SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY, 2);
id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
#ifdef pe_use_x86_64
quick_reloc (abfd, 2, BFD_RELOC_32_PCREL, 2);
#else
+ /* Mark this object as SAFESEH compatible. */
+ quick_symbol (abfd, "", "@feat.00", "", bfd_abs_section_ptr,
+ BSF_LOCAL, 1);
quick_reloc (abfd, 2, BFD_RELOC_32, 2);
#endif
break;
static bfd *
make_import_fixup_entry (const char *name,
const char *fixup_name,
- const char *dll_symname,
+ const char *symname,
bfd *parent)
{
asection *id2;
id2 = quick_section (abfd, ".idata$2", SEC_HAS_CONTENTS, 2);
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 (""), symname, "_iname", 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)
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);
+ b = make_singleton_name_thunk (name, link_info.output_bfd);
add_bfd_to_link (b, b->filename, &link_info);
/* If we ever use autoimport, we have to cast text section writable.
&& need_import_table == 1)
{
extern char * pe_data_import_dll;
- char * dll_symname = pe_data_import_dll ? pe_data_import_dll : "unknown";
+ char * symname = pe_data_import_dll ? pe_data_import_dll : "unknown";
- b = make_import_fixup_entry (name, fixup_name, dll_symname,
+ b = make_import_fixup_entry (name, fixup_name, symname,
link_info.output_bfd);
add_bfd_to_link (b, b->filename, &link_info);
}
}
static void
-add_bfd_to_link (bfd *abfd, const char *name, struct bfd_link_info *link_info)
+add_bfd_to_link (bfd *abfd, const char *name, struct bfd_link_info *linfo)
{
lang_input_statement_type *fake_file;
fake_file->the_bfd = abfd;
ldlang_add_file (fake_file);
- if (!bfd_link_add_symbols (abfd, link_info))
+ if (!bfd_link_add_symbols (abfd, linfo))
einfo ("%Xaddsym %s: %E\n", name);
}
void
-pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *link_info)
+pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *linfo)
{
def_file_module *module;
sprintf (name, "%s%s",U (""),
pe_def_file->imports[i].internal_name);
- blhe = bfd_link_hash_lookup (link_info->hash, name,
+ blhe = bfd_link_hash_lookup (linfo->hash, name,
FALSE, FALSE, FALSE);
/* Include the jump stub for <sym> only if the <sym>
sprintf (name, "%s%s%s", "__imp_", U (""),
pe_def_file->imports[i].internal_name);
- blhe = bfd_link_hash_lookup (link_info->hash, name,
+ blhe = bfd_link_hash_lookup (linfo->hash, name,
FALSE, FALSE, FALSE);
}
else
if (!do_this_dll)
{
bfd *ar_head = make_head (output_bfd);
- add_bfd_to_link (ar_head, ar_head->filename, link_info);
+ add_bfd_to_link (ar_head, ar_head->filename, linfo);
do_this_dll = 1;
}
exp.internal_name = pe_def_file->imports[i].internal_name;
exp.flag_data = pe_def_file->imports[i].data;
exp.flag_noname = exp.name ? 0 : 1;
one = make_one (&exp, output_bfd, (! exp.flag_data) && include_jmp_stub);
- add_bfd_to_link (one, one->filename, link_info);
+ add_bfd_to_link (one, one->filename, linfo);
}
}
if (do_this_dll)
{
bfd *ar_tail = make_tail (output_bfd);
- add_bfd_to_link (ar_tail, ar_tail->filename, link_info);
+ add_bfd_to_link (ar_tail, ar_tail->filename, linfo);
}
free (dll_symname);
unsigned char *expdata;
char *erva;
bfd_vma name_rvas, ordinals, nexp, ordbase;
- const char *dll_name;
+ const char *dllname;
/* Initialization with start > end guarantees that is_data
will not be set by mistake, and avoids compiler warning. */
bfd_vma data_start = 1;
/* Use internal dll name instead of filename
to enable symbolic dll linking. */
- dll_name = erva + pe_as32 (expdata + 12);
+ dllname = erva + pe_as32 (expdata + 12);
/* Check to see if the dll has already been added to
the definition list and if so return without error.
This avoids multiple symbol definitions. */
- if (def_get_module (pe_def_file, dll_name))
+ if (def_get_module (pe_def_file, dllname))
{
if (pe_dll_extra_pe_debug)
- printf ("%s is already loaded\n", dll_name);
+ printf ("%s is already loaded\n", dllname);
return TRUE;
}
|| (func_rva >= bss_start && func_rva < bss_end);
imp = def_file_add_import (pe_def_file, erva + name_rva,
- dll_name, i, 0, NULL);
+ dllname, i, 0, NULL);
/* Mark symbol type. */
imp->data = is_data;
if (pe_dll_extra_pe_debug)
printf ("%s dll-name: %s sym: %s addr: 0x%lx %s\n",
- __FUNCTION__, dll_name, erva + name_rva,
+ __FUNCTION__, dllname, erva + name_rva,
(unsigned long) func_rva, is_data ? "(data)" : "");
}
}