/* Routines to help build PEI-format DLLs (Win32 etc)
- Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Written by DJ Delorie <dj@cygnus.com>
This file is part of GLD, the Gnu Linker.
static bfd_vma image_base;
static bfd *filler_bfd;
-static struct sec *edata_s, *reloc_s;
+static struct bfd_section *edata_s, *reloc_s;
static unsigned char *edata_d, *reloc_d;
static size_t edata_sz, reloc_sz;
static int runtime_pseudo_relocs_created = 0;
defined, since we can't export symbols we don't have. */
static bfd_vma *exported_symbol_offsets;
-static struct sec **exported_symbol_sections;
+static struct bfd_section **exported_symbol_sections;
static int export_table_size;
static int count_exported;
static int count_exported_byname;
libname = lbasename (abfd->my_archive->filename);
/* We should not re-export imported stuff. */
- if (strncmp (n, "_imp__", 6) == 0)
+ if (strncmp (n, "_imp_", 5) == 0)
return 0;
for (i = 0; i < d->num_exports; i++)
int i, j;
struct bfd_link_hash_entry *blhe;
bfd *b;
- struct sec *s;
+ struct bfd_section *s;
def_file_export *e = 0;
if (!pe_def_file)
s = bfd_get_section_by_name (b, ".drectve");
if (s)
{
- int size = bfd_get_section_size_before_reloc (s);
+ long size = s->size;
char *buf = xmalloc (size);
bfd_get_section_contents (b, s, buf, 0, size);
/* If we are not building a DLL, when there are no exports
we do not build an export table at all. */
if (!pe_dll_export_everything && pe_def_file->num_exports == 0
- && !info->shared)
+ && info->executable)
return;
/* Now, maybe export everything else the default way. */
e = pe_def_file->exports;
exported_symbol_offsets = xmalloc (NE * sizeof (bfd_vma));
- exported_symbol_sections = xmalloc (NE * sizeof (struct sec *));
+ exported_symbol_sections = xmalloc (NE * sizeof (struct bfd_section *));
- memset (exported_symbol_sections, 0, NE * sizeof (struct sec *));
+ memset (exported_symbol_sections, 0, NE * sizeof (struct bfd_section *));
max_ordinal = 0;
min_ordinal = 65536;
count_exported = 0;
{
int s, hint;
unsigned char *edirectory;
- unsigned long *eaddresses;
- unsigned long *enameptrs;
- unsigned short *eordinals;
+ unsigned char *eaddresses;
+ unsigned char *enameptrs;
+ unsigned char *eordinals;
unsigned char *enamestr;
time_t now;
/* Note use of array pointer math here. */
edirectory = edata_d;
- eaddresses = (unsigned long *) (edata_d + 40);
- enameptrs = eaddresses + export_table_size;
- eordinals = (unsigned short *) (enameptrs + count_exported_byname);
- enamestr = (char *) (eordinals + count_exported_byname);
+ eaddresses = edata_d + 40;
+ enameptrs = eaddresses + 4 * export_table_size;
+ eordinals = enameptrs + 4 * count_exported_byname;
+ enamestr = eordinals + 2 * count_exported_byname;
#define ERVA(ptr) (((unsigned char *)(ptr) - edata_d) \
+ edata_s->output_section->vma - image_base)
hint = 0;
for (s = 0; s < NE; s++)
{
- if (pe_def_file->exports[s].ordinal != -1)
+ struct bfd_section *ssec = exported_symbol_sections[s];
+ if (ssec && pe_def_file->exports[s].ordinal != -1)
{
- struct sec *ssec = exported_symbol_sections[s];
unsigned long srva = (exported_symbol_offsets[s]
+ ssec->output_section->vma
+ ssec->output_offset);
int ord = pe_def_file->exports[s].ordinal;
bfd_put_32 (abfd, srva - image_base,
- (void *) (eaddresses + ord - min_ordinal));
+ eaddresses + 4 * (ord - min_ordinal));
if (!pe_def_file->exports[s].flag_noname)
{
char *ename = pe_def_file->exports[s].name;
- bfd_put_32 (abfd, ERVA (enamestr), (void *) enameptrs);
- enameptrs++;
+ bfd_put_32 (abfd, ERVA (enamestr), enameptrs);
+ enameptrs += 4;
strcpy (enamestr, ename);
enamestr += strlen (enamestr) + 1;
- bfd_put_16 (abfd, ord - min_ordinal, (void *) eordinals);
- eordinals++;
+ bfd_put_16 (abfd, ord - min_ordinal, eordinals);
+ eordinals += 2;
pe_def_file->exports[s].hint = hint++;
}
}
}
-static struct sec *current_sec;
+static struct bfd_section *current_sec;
void
pe_walk_relocs_of_symbol (struct bfd_link_info *info,
for (i = 0; i < nrelocs; i++)
{
- struct symbol_cache_entry *sym = *relocs[i]->sym_ptr_ptr;
+ struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
if (!strcmp (name, sym->name))
cb (relocs[i], s);
unsigned long page_ptr, page_count;
int bi;
bfd *b;
- struct sec *s;
+ struct bfd_section *s;
total_relocs = 0;
for (b = info->input_bfds; b; b = b->link_next)
{
if (pe_dll_extra_pe_debug)
{
- struct symbol_cache_entry *sym = *relocs[i]->sym_ptr_ptr;
+ struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
printf ("rel: %s\n", sym->name);
}
if (!relocs[i]->howto->pc_relative
&& relocs[i]->howto->type != pe_details->imagebase_reloc)
{
bfd_vma sym_vma;
- struct symbol_cache_entry *sym = *relocs[i]->sym_ptr_ptr;
+ struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
sym_vma = (relocs[i]->addend
+ sym->value
total_relocs++;
break;
case BITS_AND_SHIFT (24, 2):
- if (relocs[i]->howto->type == 5)
+ /* FIXME: 0 is ARM_26D, it is defined in bfd/coff-arm.c
+ Those ARM_xxx definitions should go in proper
+ header someday. */
+ if (relocs[i]->howto->type == 0
+ /* Older GNU linkers used 5 instead of 0 for this reloc. */
+ || relocs[i]->howto->type == 5)
/* This is an ARM_26D reloc, which is an ARM_26 reloc
that has already been fully processed during a
previous link stage, so ignore it here. */
if (page_ptr != (unsigned long) -1)
bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4);
- while (reloc_sz < reloc_s->_raw_size)
+ while (reloc_sz < reloc_s->size)
reloc_d[reloc_sz++] = 0;
}
static char *fixup_name = NULL;
static size_t buffer_len = 0;
- struct symbol_cache_entry *sym = *rel->sym_ptr_ptr;
+ struct bfd_symbol *sym = *rel->sym_ptr_ptr;
bfd *abfd = bfd_asymbol_bfd (sym);
struct bfd_link_hash_entry *bh;
pe_create_import_fixup (arelent *rel, asection *s, int addend)
{
char buf[300];
- struct symbol_cache_entry *sym = *rel->sym_ptr_ptr;
+ struct bfd_symbol *sym = *rel->sym_ptr_ptr;
struct bfd_link_hash_entry *name_thunk_sym;
const char *name = sym->name;
char *fixup_name = make_import_fixup_mark (rel);
/* If we ever use autoimport, we have to cast text section writable. */
config.text_read_only = FALSE;
+ output_bfd->flags &= ~WP_TEXT;
}
if (addend == 0 || link_info.pei386_runtime_pseudo_reloc)
char *internal = def->exports[i].internal_name;
bfd *n;
+ /* Don't add PRIVATE entries to import lib. */
+ if (pe_def_file->exports[i].flag_private)
+ continue;
def->exports[i].internal_name = def->exports[i].name;
n = make_one (def->exports + i, outarch);
n->next = head;
/* Initialization with start > end guarantees that is_data
will not be set by mistake, and avoids compiler warning. */
unsigned long data_start = 1;
- unsigned long data_end = 0;
- unsigned long bss_start = 1;
- unsigned long bss_end = 0;
+ unsigned long data_end = 0;
+ unsigned long rdata_start = 1;
+ unsigned long rdata_end = 0;
+ unsigned long bss_start = 1;
+ unsigned long bss_end = 0;
/* No, I can't use bfd here. kernel32.dll puts its export table in
the middle of the .rdata section. */
data_start = vaddr;
data_end = vaddr + vsize;
+ if (pe_dll_extra_pe_debug)
+ printf ("%s %s: 0x%08lx-0x%08lx (0x%08lx)\n",
+ __FUNCTION__, sec_name, vaddr, vaddr + vsize, flags);
+ }
+ else if (strcmp(sec_name,".rdata") == 0)
+ {
+ rdata_start = vaddr;
+ rdata_end = vaddr + vsize;
+
if (pe_dll_extra_pe_debug)
printf ("%s %s: 0x%08lx-0x%08lx (0x%08lx)\n",
__FUNCTION__, sec_name, vaddr, vaddr + vsize, flags);
exported in buggy auto-import releases. */
if (strncmp (erva + name_rva, "_nm_", 4) != 0)
{
- /* is_data is true if the address is in the data or bss segment. */
+ /* is_data is true if the address is in the data, rdata or bss
+ segment. */
is_data =
(func_rva >= data_start && func_rva < data_end)
+ || (func_rva >= rdata_start && func_rva < rdata_end)
|| (func_rva >= bss_start && func_rva < bss_end);
imp = def_file_add_import (pe_def_file, erva + name_rva,
fill_edata (abfd, info);
- if (info->shared)
+ if (info->shared && !info->pie)
pe_data (abfd)->dll = 1;
edata_s->contents = edata_d;