/* Routines to help build PEI-format DLLs (Win32 etc)
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009, 2010 Free Software Foundation, Inc.
+ 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
Written by DJ Delorie <dj@cygnus.com>
This file is part of the GNU Binutils.
#include "bfd.h"
#include "bfdlink.h"
#include "libiberty.h"
+#include "filenames.h"
#include "safe-ctype.h"
#include <time.h>
#endif
PE_ARCH_i386,
bfd_arch_i386,
+#ifdef pe_use_x86_64
+ FALSE,
+#else
TRUE,
+#endif
autofilter_symbollist_i386
},
{
returning zero if so or -1 if not. */
static int libnamencmp (const char *libname, const autofilter_entry_type *afptr)
{
- if (strncmp (libname, afptr->name, afptr->len))
+ if (filename_ncmp (libname, afptr->name, afptr->len))
return -1;
libname += afptr->len;
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);
+ if (u == -1)
+ abort ();
+ pe_detail_list[i].underscored = (u != 0 ? TRUE : FALSE);
pe_details = pe_detail_list + i;
+ pe_leading_underscore = (u != 0 ? 1 : 0);
return;
}
einfo (_("%XUnsupported PEI architecture: %s\n"), target);
if (ex->type == EXCLUDELIBS)
{
if (libname
- && ((strcmp (libname, ex->string) == 0)
+ && ((filename_cmp (libname, ex->string) == 0)
|| (strcasecmp ("ALL", ex->string) == 0)))
return 0;
}
else if (ex->type == EXCLUDEFORIMPLIB)
{
- if (strcmp (abfd->filename, ex->string) == 0)
+ if (filename_cmp (abfd->filename, ex->string) == 0)
return 0;
}
else if (strcmp (n, ex->string) == 0)
bfd_boolean would_export = symbols[j]->section != &bfd_und_section
&& ((symbols[j]->flags & BSF_GLOBAL)
|| (symbols[j]->flags == 0));
- if (lang_elf_version_info && would_export)
- {
- bfd_boolean hide = 0;
- char ofs = pe_details->underscored && symbols[j]->name[0] == '_';
- (void) bfd_find_version_for_sym (lang_elf_version_info,
- symbols[j]->name + ofs, &hide);
- would_export = !hide;
- }
+ if (link_info.version_info && would_export)
+ would_export
+ = !bfd_hide_sym_by_version (link_info.version_info,
+ symbols[j]->name);
if (would_export)
{
const char *sn = symbols[j]->name;
if (auto_export (b, pe_def_file, sn))
{
+ int is_dup = 0;
def_file_export *p;
- p=def_file_add_export (pe_def_file, sn, 0, -1, NULL);
+ p = def_file_add_export (pe_def_file, sn, 0, -1,
+ NULL, &is_dup);
/* Fill data flag properly, from dlltool.c. */
- p->flag_data = !(symbols[j]->flags & BSF_FUNCTION);
+ if (!is_dup)
+ p->flag_data = !(symbols[j]->flags & BSF_FUNCTION);
}
}
}
if (strchr (pe_def_file->exports[i].name, '@'))
{
+ int is_dup = 1;
int lead_at = (*pe_def_file->exports[i].name == '@');
char *tmp = xstrdup (pe_def_file->exports[i].name + lead_at);
if (auto_export (NULL, pe_def_file, tmp))
def_file_add_export (pe_def_file, tmp,
pe_def_file->exports[i].internal_name,
- -1, NULL);
- else
- free (tmp);
+ -1, NULL, &is_dup);
+ if (is_dup)
+ free (tmp);
}
}
}
for (i = 0; i < NE; i++)
{
char *name;
-
- /* Check for forward exports */
- if (strchr (pe_def_file->exports[i].internal_name, '.'))
- {
- count_exported++;
- if (!pe_def_file->exports[i].flag_noname)
- count_exported_byname++;
-
- pe_def_file->exports[i].flag_forward = 1;
-
- if (pe_def_file->exports[i].ordinal != -1)
- {
- if (max_ordinal < pe_def_file->exports[i].ordinal)
- max_ordinal = pe_def_file->exports[i].ordinal;
- if (min_ordinal > pe_def_file->exports[i].ordinal)
- min_ordinal = pe_def_file->exports[i].ordinal;
- count_with_ordinals++;
- }
-
- continue;
- }
-
name = xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2);
if (pe_details->underscored
&& (*pe_def_file->exports[i].internal_name != '@'))
else
exported_symbol_sections[i] = blhe->u.c.p->section;
+ if (pe_def_file->exports[i].ordinal != -1)
+ {
+ if (max_ordinal < pe_def_file->exports[i].ordinal)
+ max_ordinal = pe_def_file->exports[i].ordinal;
+ if (min_ordinal > pe_def_file->exports[i].ordinal)
+ min_ordinal = pe_def_file->exports[i].ordinal;
+ count_with_ordinals++;
+ }
+ }
+ /* Check for forward exports. These are indicated in DEF files by an
+ export directive of the form NAME1 = MODULE-NAME.EXTERNAL-NAME
+ but we must take care not to be fooled when the user wants to export
+ a symbol that actually really has a dot in it, so we only check
+ for them here, after real defined symbols have already been matched. */
+ else if (strchr (pe_def_file->exports[i].internal_name, '.'))
+ {
+ count_exported++;
+ if (!pe_def_file->exports[i].flag_noname)
+ count_exported_byname++;
+
+ pe_def_file->exports[i].flag_forward = 1;
+
if (pe_def_file->exports[i].ordinal != -1)
{
if (max_ordinal < pe_def_file->exports[i].ordinal)
/* Note use of array pointer math here. */
edirectory = edata_d;
- eaddresses = edata_d + 40;
+ eaddresses = edirectory + 40;
enameptrs = eaddresses + 4 * export_table_size;
eordinals = enameptrs + 4 * count_exported_byname;
enamestr = (char *) eordinals + 2 * count_exported_byname;
for (b = info->input_bfds; b; b = b->link_next)
{
asymbol **symbols;
- int nsyms;
if (!bfd_generic_link_read_symbols (b))
{
}
symbols = bfd_get_outsymbols (b);
- nsyms = bfd_get_symcount (b);
for (s = b->sections; s; s = s->next)
{
{
bfd_vma sec_vma = s->output_section->vma + s->output_offset;
asymbol **symbols;
- int nsyms;
/* If it's not loaded, we don't need to relocate it this way. */
if (!(s->output_section->flags & SEC_LOAD))
}
symbols = bfd_get_outsymbols (b);
- nsyms = bfd_get_symcount (b);
relsize = bfd_get_reloc_upper_bound (b, s);
relocs = xmalloc (relsize);
nrelocs = bfd_canonicalize_reloc (b, s, relocs, symbols);
if (!relocs[i]->howto->pc_relative
&& relocs[i]->howto->type != pe_details->imagebase_reloc)
{
- bfd_vma sym_vma;
struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
/* Don't create relocs for undefined weak symbols. */
continue;
}
- 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;
#define BITS_AND_SHIFT(bits, shift) (bits * 1000 | shift)
{
if (ex->type != EXCLUDEFORIMPLIB)
continue;
- found = (strcmp (ex->string, ibfd->filename) == 0);
+ found = (filename_cmp (ex->string, ibfd->filename) == 0);
}
/* If it matched, we must open a fresh BFD for it (the original
input BFD is still needed for the DLL's final link) and add
newbfd = NULL;
while ((newbfd = bfd_openr_next_archived_file (arbfd, newbfd)) != 0)
{
- if (strcmp (newbfd->filename, ibfd->filename) == 0)
+ if (filename_cmp (newbfd->filename, ibfd->filename) == 0)
break;
}
if (!newbfd)
bfd_vma exp_funcbase;
unsigned char *expdata;
char *erva;
- bfd_vma name_rvas, ordinals, nexp, ordbase;
+ bfd_vma name_rvas, nexp;
const char *dllname;
/* Initialization with start > end guarantees that is_data
will not be set by mistake, and avoids compiler warning. */
nexp = pe_as32 (expdata + 24);
name_rvas = pe_as32 (expdata + 32);
- ordinals = pe_as32 (expdata + 36);
- ordbase = pe_as32 (expdata + 16);
exp_funcbase = pe_as32 (expdata + 28);
/* Use internal dll name instead of filename
exported in buggy auto-import releases. */
if (! CONST_STRNEQ (erva + name_rva, "__nm_"))
{
+ int is_dup = 0;
/* is_data is true if the address is in the data, rdata or bss
segment. */
is_data =
|| (func_rva >= bss_start && func_rva < bss_end);
imp = def_file_add_import (pe_def_file, erva + name_rva,
- dllname, i, 0, NULL);
+ dllname, i, 0, NULL, &is_dup);
/* Mark symbol type. */
- imp->data = is_data;
+ if (!is_dup)
+ imp->data = is_data;
if (pe_dll_extra_pe_debug)
printf ("%s dll-name: %s sym: %s addr: 0x%lx %s\n",
ldemul_after_allocation ();
/* Do the assignments again. */
- lang_do_assignments ();
+ lang_do_assignments (lang_final_phase_enum);
}
fill_edata (abfd, info);
ldemul_after_allocation ();
/* Do the assignments again. */
- lang_do_assignments ();
+ lang_do_assignments (lang_final_phase_enum);
}
reloc_s->contents = reloc_d;
}