1999-05-03 09:29:11 +02:00
|
|
|
/* Routines to help build PEI-format DLLs (Win32 etc)
|
2008-02-15 04:35:53 +01:00
|
|
|
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
|
2012-02-11 20:25:12 +01:00
|
|
|
2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
1999-05-03 09:29:11 +02:00
|
|
|
Written by DJ Delorie <dj@cygnus.com>
|
|
|
|
|
2007-07-06 16:09:45 +02:00
|
|
|
This file is part of the GNU Binutils.
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2007-07-06 16:09:45 +02:00
|
|
|
This program is free software; you can redistribute it and/or modify
|
1999-05-03 09:29:11 +02:00
|
|
|
it under the terms of the GNU General Public License as published by
|
2007-07-06 16:09:45 +02:00
|
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2007-07-06 16:09:45 +02:00
|
|
|
This program is distributed in the hope that it will be useful,
|
1999-05-03 09:29:11 +02:00
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2007-07-06 16:09:45 +02:00
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
|
|
|
MA 02110-1301, USA. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
#include "sysdep.h"
|
2007-04-26 16:47:00 +02:00
|
|
|
#include "bfd.h"
|
1999-05-03 09:29:11 +02:00
|
|
|
#include "bfdlink.h"
|
|
|
|
#include "libiberty.h"
|
2011-02-28 19:34:52 +01:00
|
|
|
#include "filenames.h"
|
2001-09-19 07:33:36 +02:00
|
|
|
#include "safe-ctype.h"
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#include "ld.h"
|
|
|
|
#include "ldexp.h"
|
|
|
|
#include "ldlang.h"
|
|
|
|
#include "ldwrite.h"
|
|
|
|
#include "ldmisc.h"
|
2002-10-30 04:57:39 +01:00
|
|
|
#include <ldgram.h>
|
1999-05-03 09:29:11 +02:00
|
|
|
#include "ldmain.h"
|
2000-07-11 05:42:41 +02:00
|
|
|
#include "ldfile.h"
|
1999-05-03 09:29:11 +02:00
|
|
|
#include "ldemul.h"
|
|
|
|
#include "coff/internal.h"
|
|
|
|
#include "../bfd/libcoff.h"
|
|
|
|
#include "deffile.h"
|
2006-09-20 13:35:11 +02:00
|
|
|
|
|
|
|
#ifdef pe_use_x86_64
|
|
|
|
|
|
|
|
#define PE_IDATA4_SIZE 8
|
|
|
|
#define PE_IDATA5_SIZE 8
|
|
|
|
#include "pep-dll.h"
|
|
|
|
#undef AOUTSZ
|
|
|
|
#define AOUTSZ PEPAOUTSZ
|
|
|
|
#define PEAOUTHDR PEPAOUTHDR
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
1999-09-12 17:27:48 +02:00
|
|
|
#include "pe-dll.h"
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2006-09-20 13:35:11 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef PE_IDATA4_SIZE
|
|
|
|
#define PE_IDATA4_SIZE 4
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef PE_IDATA5_SIZE
|
|
|
|
#define PE_IDATA5_SIZE 4
|
|
|
|
#endif
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* This file turns a regular Windows PE image into a DLL. Because of
|
|
|
|
the complexity of this operation, it has been broken down into a
|
|
|
|
number of separate modules which are all called by the main function
|
|
|
|
at the end of this file. This function is not re-entrant and is
|
|
|
|
normally only called once, so static variables are used to reduce
|
|
|
|
the number of parameters and return values required.
|
2002-05-03 15:48:55 +02:00
|
|
|
|
2006-09-20 13:35:11 +02:00
|
|
|
See also: ld/emultempl/pe.em and ld/emultempl/pep.em. */
|
2001-09-14 16:19:05 +02:00
|
|
|
|
|
|
|
/* Auto-import feature by Paul Sokolovsky
|
|
|
|
|
|
|
|
Quick facts:
|
|
|
|
|
|
|
|
1. With this feature on, DLL clients can import variables from DLL
|
|
|
|
without any concern from their side (for example, without any source
|
|
|
|
code modifications).
|
|
|
|
|
|
|
|
2. This is done completely in bounds of the PE specification (to be fair,
|
2003-01-02 04:53:53 +01:00
|
|
|
there's a place where it pokes nose out of, but in practice it works).
|
2001-09-14 16:19:05 +02:00
|
|
|
So, resulting module can be used with any other PE compiler/linker.
|
|
|
|
|
|
|
|
3. Auto-import is fully compatible with standard import method and they
|
|
|
|
can be mixed together.
|
|
|
|
|
|
|
|
4. Overheads: space: 8 bytes per imported symbol, plus 20 for each
|
|
|
|
reference to it; load time: negligible; virtual/physical memory: should be
|
|
|
|
less than effect of DLL relocation, and I sincerely hope it doesn't affect
|
|
|
|
DLL sharability (too much).
|
|
|
|
|
|
|
|
Idea
|
|
|
|
|
|
|
|
The obvious and only way to get rid of dllimport insanity is to make client
|
|
|
|
access variable directly in the DLL, bypassing extra dereference. I.e.,
|
2003-01-02 04:53:53 +01:00
|
|
|
whenever client contains something like
|
2001-09-14 16:19:05 +02:00
|
|
|
|
|
|
|
mov dll_var,%eax,
|
|
|
|
|
|
|
|
address of dll_var in the command should be relocated to point into loaded
|
|
|
|
DLL. The aim is to make OS loader do so, and than make ld help with that.
|
|
|
|
Import section of PE made following way: there's a vector of structures
|
|
|
|
each describing imports from particular DLL. Each such structure points
|
2003-01-02 04:53:53 +01:00
|
|
|
to two other parallel vectors: one holding imported names, and one which
|
2001-09-14 16:19:05 +02:00
|
|
|
will hold address of corresponding imported name. So, the solution is
|
|
|
|
de-vectorize these structures, making import locations be sparse and
|
|
|
|
pointing directly into code. Before continuing, it is worth a note that,
|
|
|
|
while authors strives to make PE act ELF-like, there're some other people
|
|
|
|
make ELF act PE-like: elfvector, ;-) .
|
|
|
|
|
|
|
|
Implementation
|
|
|
|
|
|
|
|
For each reference of data symbol to be imported from DLL (to set of which
|
|
|
|
belong symbols with name <sym>, if __imp_<sym> is found in implib), the
|
|
|
|
import fixup entry is generated. That entry is of type
|
2006-05-11 10:48:58 +02:00
|
|
|
IMAGE_IMPORT_DESCRIPTOR and stored in .idata$2 subsection. Each
|
2001-09-14 16:19:05 +02:00
|
|
|
fixup entry contains pointer to symbol's address within .text section
|
|
|
|
(marked with __fuN_<sym> symbol, where N is integer), pointer to DLL name
|
|
|
|
(so, DLL name is referenced by multiple entries), and pointer to symbol
|
|
|
|
name thunk. Symbol name thunk is singleton vector (__nm_th_<symbol>)
|
|
|
|
pointing to IMAGE_IMPORT_BY_NAME structure (__nm_<symbol>) directly
|
2006-10-03 12:06:26 +02:00
|
|
|
containing imported name. Here comes that "on the edge" problem mentioned
|
2001-09-14 16:19:05 +02:00
|
|
|
above: PE specification rambles that name vector (OriginalFirstThunk)
|
|
|
|
should run in parallel with addresses vector (FirstThunk), i.e. that they
|
|
|
|
should have same number of elements and terminated with zero. We violate
|
2003-01-02 04:53:53 +01:00
|
|
|
this, since FirstThunk points directly into machine code. But in practice,
|
2001-09-14 16:19:05 +02:00
|
|
|
OS loader implemented the sane way: it goes thru OriginalFirstThunk and
|
|
|
|
puts addresses to FirstThunk, not something else. It once again should be
|
|
|
|
noted that dll and symbol name structures are reused across fixup entries
|
|
|
|
and should be there anyway to support standard import stuff, so sustained
|
|
|
|
overhead is 20 bytes per reference. Other question is whether having several
|
|
|
|
IMAGE_IMPORT_DESCRIPTORS for the same DLL is possible. Answer is yes, it is
|
|
|
|
done even by native compiler/linker (libth32's functions are in fact reside
|
|
|
|
in windows9x kernel32.dll, so if you use it, you have two
|
|
|
|
IMAGE_IMPORT_DESCRIPTORS for kernel32.dll). Yet other question is whether
|
|
|
|
referencing the same PE structures several times is valid. The answer is why
|
2003-01-02 04:53:53 +01:00
|
|
|
not, prohibiting that (detecting violation) would require more work on
|
2001-09-14 16:19:05 +02:00
|
|
|
behalf of loader than not doing it.
|
|
|
|
|
2006-09-20 13:35:11 +02:00
|
|
|
See also: ld/emultempl/pe.em and ld/emultempl/pep.em. */
|
2001-08-03 01:12:02 +02:00
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
static void add_bfd_to_link (bfd *, const char *, struct bfd_link_info *);
|
2001-08-03 01:12:02 +02:00
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* For emultempl/pe.em. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
def_file * pe_def_file = 0;
|
1999-05-03 09:29:11 +02:00
|
|
|
int pe_dll_export_everything = 0;
|
2009-10-16 17:15:39 +02:00
|
|
|
int pe_dll_exclude_all_symbols = 0;
|
1999-05-03 09:29:11 +02:00
|
|
|
int pe_dll_do_default_excludes = 1;
|
|
|
|
int pe_dll_kill_ats = 0;
|
|
|
|
int pe_dll_stdcall_aliases = 0;
|
2000-01-05 00:44:03 +01:00
|
|
|
int pe_dll_warn_dup_exports = 0;
|
|
|
|
int pe_dll_compat_implib = 0;
|
2001-08-03 01:12:02 +02:00
|
|
|
int pe_dll_extra_pe_debug = 0;
|
2009-01-08 14:28:48 +01:00
|
|
|
int pe_use_nul_prefixed_import_tables = 0;
|
2009-02-18 19:23:08 +01:00
|
|
|
int pe_use_coff_long_section_names = -1;
|
2010-04-05 11:04:09 +02:00
|
|
|
int pe_leading_underscore = -1;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Static variables and types. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
static bfd_vma image_base;
|
|
|
|
static bfd *filler_bfd;
|
2003-10-19 Andrew Cagney <cagney@redhat.com>
* targets.c: Replace "struct sec" with "struct bfd_section"
* syms.c, sparclynx.c, section.c, opncls.c: Ditto.
* libcoff-in.h, libbfd-in.h, elfxx-target.h: Ditto.
* elf.c, coffgen.c, bfd.c, bfd-in.h, aoutf1.h: Ditto.
* aout-tic30.c, aout-target.h:
* bfd-in2.h, libcoff.h, libbfd.h: Regenerate.
Index: binutils/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* coffgrok.h (coff_section): Replace 'struct sec" with "struct
bfd_section".
Index: gdb/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* symtab.c: Replace "struct sec" with "struct bfd_section".
* objfiles.c, linespec.c, blockframe.c, block.c: Ditto.
Index: ld/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* pe-dll.c: Replace "struct sec" with "struct bfd_section".
Index: sim/common/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* sim-base.h: Replace "struct sec" with "struct bfd_section".
2003-10-20 16:38:46 +02:00
|
|
|
static struct bfd_section *edata_s, *reloc_s;
|
1999-05-03 09:29:11 +02:00
|
|
|
static unsigned char *edata_d, *reloc_d;
|
1999-09-12 17:27:48 +02:00
|
|
|
static size_t edata_sz, reloc_sz;
|
2002-11-14 19:03:17 +01:00
|
|
|
static int runtime_pseudo_relocs_created = 0;
|
2008-11-14 16:13:05 +01:00
|
|
|
static int runtime_pseudp_reloc_v2_init = 0;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
typedef struct
|
2006-06-23 13:20:15 +02:00
|
|
|
{
|
2006-11-01 01:48:25 +01:00
|
|
|
const char *name;
|
2006-06-23 13:20:15 +02:00
|
|
|
int len;
|
|
|
|
}
|
|
|
|
autofilter_entry_type;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
|
|
|
typedef struct
|
2006-06-23 13:20:15 +02:00
|
|
|
{
|
2006-11-01 01:48:25 +01:00
|
|
|
const char *target_name;
|
|
|
|
const char *object_target;
|
2006-06-23 13:20:15 +02:00
|
|
|
unsigned int imagebase_reloc;
|
|
|
|
int pe_arch;
|
|
|
|
int bfd_arch;
|
|
|
|
bfd_boolean underscored;
|
2010-05-15 16:20:06 +02:00
|
|
|
const autofilter_entry_type* autofilter_symbollist;
|
2006-06-23 13:20:15 +02:00
|
|
|
}
|
|
|
|
pe_details_type;
|
|
|
|
|
2006-11-01 01:48:25 +01:00
|
|
|
static const autofilter_entry_type autofilter_symbollist_generic[] =
|
2006-06-23 13:20:15 +02:00
|
|
|
{
|
2008-07-09 05:18:15 +02:00
|
|
|
{ STRING_COMMA_LEN ("_NULL_IMPORT_DESCRIPTOR") },
|
2006-06-23 13:20:15 +02:00
|
|
|
/* Entry point symbols. */
|
2006-09-16 20:12:17 +02:00
|
|
|
{ STRING_COMMA_LEN ("DllMain") },
|
|
|
|
{ STRING_COMMA_LEN ("DllMainCRTStartup") },
|
|
|
|
{ STRING_COMMA_LEN ("_DllMainCRTStartup") },
|
2006-06-23 13:20:15 +02:00
|
|
|
/* Runtime pseudo-reloc. */
|
2006-09-16 20:12:17 +02:00
|
|
|
{ STRING_COMMA_LEN ("_pei386_runtime_relocator") },
|
|
|
|
{ STRING_COMMA_LEN ("do_pseudo_reloc") },
|
2007-10-25 23:01:55 +02:00
|
|
|
{ NULL, 0 }
|
2006-06-23 13:20:15 +02:00
|
|
|
};
|
|
|
|
|
2006-11-01 01:48:25 +01:00
|
|
|
static const autofilter_entry_type autofilter_symbollist_i386[] =
|
2006-06-23 13:20:15 +02:00
|
|
|
{
|
2008-07-09 05:18:15 +02:00
|
|
|
{ STRING_COMMA_LEN ("_NULL_IMPORT_DESCRIPTOR") },
|
2006-06-23 13:20:15 +02:00
|
|
|
/* Entry point symbols, and entry hooks. */
|
2006-09-16 20:12:17 +02:00
|
|
|
{ STRING_COMMA_LEN ("cygwin_crt0") },
|
2007-08-06 16:32:08 +02:00
|
|
|
#ifdef pe_use_x86_64
|
|
|
|
{ STRING_COMMA_LEN ("DllMain") },
|
|
|
|
{ STRING_COMMA_LEN ("DllEntryPoint") },
|
|
|
|
{ STRING_COMMA_LEN ("DllMainCRTStartup") },
|
|
|
|
{ STRING_COMMA_LEN ("_cygwin_dll_entry") },
|
|
|
|
{ STRING_COMMA_LEN ("_cygwin_crt0_common") },
|
|
|
|
{ STRING_COMMA_LEN ("_cygwin_noncygwin_dll_entry") },
|
|
|
|
#else
|
2006-09-16 20:12:17 +02:00
|
|
|
{ STRING_COMMA_LEN ("DllMain@12") },
|
|
|
|
{ STRING_COMMA_LEN ("DllEntryPoint@0") },
|
|
|
|
{ STRING_COMMA_LEN ("DllMainCRTStartup@12") },
|
|
|
|
{ STRING_COMMA_LEN ("_cygwin_dll_entry@12") },
|
|
|
|
{ STRING_COMMA_LEN ("_cygwin_crt0_common@8") },
|
|
|
|
{ STRING_COMMA_LEN ("_cygwin_noncygwin_dll_entry@12") },
|
|
|
|
{ STRING_COMMA_LEN ("cygwin_attach_dll") },
|
2010-05-15 16:20:06 +02:00
|
|
|
#endif
|
2006-09-16 20:12:17 +02:00
|
|
|
{ STRING_COMMA_LEN ("cygwin_premain0") },
|
|
|
|
{ STRING_COMMA_LEN ("cygwin_premain1") },
|
|
|
|
{ STRING_COMMA_LEN ("cygwin_premain2") },
|
|
|
|
{ STRING_COMMA_LEN ("cygwin_premain3") },
|
2006-06-23 13:20:15 +02:00
|
|
|
/* Runtime pseudo-reloc. */
|
2006-09-16 20:12:17 +02:00
|
|
|
{ STRING_COMMA_LEN ("_pei386_runtime_relocator") },
|
|
|
|
{ STRING_COMMA_LEN ("do_pseudo_reloc") },
|
2006-06-23 13:20:15 +02:00
|
|
|
/* Global vars that should not be exported. */
|
2006-09-16 20:12:17 +02:00
|
|
|
{ STRING_COMMA_LEN ("impure_ptr") },
|
|
|
|
{ STRING_COMMA_LEN ("_impure_ptr") },
|
|
|
|
{ STRING_COMMA_LEN ("_fmode") },
|
|
|
|
{ STRING_COMMA_LEN ("environ") },
|
2007-10-25 23:01:55 +02:00
|
|
|
{ NULL, 0 }
|
2006-06-23 13:20:15 +02:00
|
|
|
};
|
2001-08-03 01:12:02 +02:00
|
|
|
|
2006-06-23 13:20:15 +02:00
|
|
|
#define PE_ARCH_i386 1
|
|
|
|
#define PE_ARCH_sh 2
|
|
|
|
#define PE_ARCH_mips 3
|
|
|
|
#define PE_ARCH_arm 4
|
2001-09-14 16:19:05 +02:00
|
|
|
#define PE_ARCH_arm_epoc 5
|
2006-08-21 10:12:46 +02:00
|
|
|
#define PE_ARCH_arm_wince 6
|
1999-05-11 23:06:50 +02:00
|
|
|
|
2010-04-05 11:04:09 +02:00
|
|
|
/* 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[] =
|
2001-09-14 16:19:05 +02:00
|
|
|
{
|
1999-05-11 23:06:50 +02:00
|
|
|
{
|
2006-09-20 13:35:11 +02:00
|
|
|
#ifdef pe_use_x86_64
|
|
|
|
"pei-x86-64",
|
|
|
|
"pe-x86-64",
|
|
|
|
3 /* R_IMAGEBASE */,
|
|
|
|
#else
|
1999-05-11 23:06:50 +02:00
|
|
|
"pei-i386",
|
|
|
|
"pe-i386",
|
|
|
|
7 /* R_IMAGEBASE */,
|
2006-09-20 13:35:11 +02:00
|
|
|
#endif
|
1999-05-11 23:06:50 +02:00
|
|
|
PE_ARCH_i386,
|
|
|
|
bfd_arch_i386,
|
2010-05-15 21:50:44 +02:00
|
|
|
#ifdef pe_use_x86_64
|
|
|
|
FALSE,
|
|
|
|
#else
|
2006-06-23 13:20:15 +02:00
|
|
|
TRUE,
|
2010-05-15 21:50:44 +02:00
|
|
|
#endif
|
2006-06-23 13:20:15 +02:00
|
|
|
autofilter_symbollist_i386
|
1999-05-11 23:06:50 +02:00
|
|
|
},
|
2000-02-24 18:53:12 +01:00
|
|
|
{
|
|
|
|
"pei-shl",
|
|
|
|
"pe-shl",
|
|
|
|
16 /* R_SH_IMAGEBASE */,
|
|
|
|
PE_ARCH_sh,
|
|
|
|
bfd_arch_sh,
|
2006-06-23 13:20:15 +02:00
|
|
|
TRUE,
|
|
|
|
autofilter_symbollist_generic
|
2000-02-24 18:53:12 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"pei-mips",
|
|
|
|
"pe-mips",
|
|
|
|
34 /* MIPS_R_RVA */,
|
|
|
|
PE_ARCH_mips,
|
|
|
|
bfd_arch_mips,
|
2006-06-23 13:20:15 +02:00
|
|
|
FALSE,
|
|
|
|
autofilter_symbollist_generic
|
2000-02-24 18:53:12 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"pei-arm-little",
|
|
|
|
"pe-arm-little",
|
|
|
|
11 /* ARM_RVA32 */,
|
|
|
|
PE_ARCH_arm,
|
|
|
|
bfd_arch_arm,
|
2006-06-23 13:20:15 +02:00
|
|
|
TRUE,
|
|
|
|
autofilter_symbollist_generic
|
2000-02-24 18:53:12 +01:00
|
|
|
},
|
2001-09-14 16:19:05 +02:00
|
|
|
{
|
|
|
|
"epoc-pei-arm-little",
|
|
|
|
"epoc-pe-arm-little",
|
|
|
|
11 /* ARM_RVA32 */,
|
|
|
|
PE_ARCH_arm_epoc,
|
|
|
|
bfd_arch_arm,
|
2006-06-23 13:20:15 +02:00
|
|
|
FALSE,
|
|
|
|
autofilter_symbollist_generic
|
2001-09-14 16:19:05 +02:00
|
|
|
},
|
2006-08-21 10:12:46 +02:00
|
|
|
{
|
|
|
|
"pei-arm-wince-little",
|
|
|
|
"pe-arm-wince-little",
|
|
|
|
2, /* ARM_RVA32 on Windows CE, see bfd/coff-arm.c. */
|
|
|
|
PE_ARCH_arm_wince,
|
|
|
|
bfd_arch_arm,
|
|
|
|
FALSE,
|
|
|
|
autofilter_symbollist_generic
|
|
|
|
},
|
2006-06-23 13:20:15 +02:00
|
|
|
{ NULL, NULL, 0, 0, 0, FALSE, NULL }
|
1999-05-11 23:06:50 +02:00
|
|
|
};
|
|
|
|
|
2006-11-01 01:48:25 +01:00
|
|
|
static const pe_details_type *pe_details;
|
1999-05-11 23:06:50 +02:00
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Do not specify library suffix explicitly, to allow for dllized versions. */
|
2006-11-01 01:48:25 +01:00
|
|
|
static const autofilter_entry_type autofilter_liblist[] =
|
2001-09-14 16:19:05 +02:00
|
|
|
{
|
2006-09-16 20:12:17 +02:00
|
|
|
{ STRING_COMMA_LEN ("libcegcc") },
|
|
|
|
{ STRING_COMMA_LEN ("libcygwin") },
|
|
|
|
{ STRING_COMMA_LEN ("libgcc") },
|
2009-01-03 18:43:45 +01:00
|
|
|
{ STRING_COMMA_LEN ("libgcc_s") },
|
2006-09-16 20:12:17 +02:00
|
|
|
{ STRING_COMMA_LEN ("libstdc++") },
|
|
|
|
{ STRING_COMMA_LEN ("libmingw32") },
|
|
|
|
{ STRING_COMMA_LEN ("libmingwex") },
|
|
|
|
{ STRING_COMMA_LEN ("libg2c") },
|
|
|
|
{ STRING_COMMA_LEN ("libsupc++") },
|
|
|
|
{ STRING_COMMA_LEN ("libobjc") },
|
|
|
|
{ STRING_COMMA_LEN ("libgcj") },
|
2007-10-25 23:01:55 +02:00
|
|
|
{ NULL, 0 }
|
2001-08-03 01:12:02 +02:00
|
|
|
};
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2009-01-03 18:43:45 +01:00
|
|
|
/* Regardless of the suffix issue mentioned above, we must ensure that
|
|
|
|
we do not falsely match on a leading substring, such as when libtool
|
|
|
|
builds libstdc++ as a DLL using libsupc++convenience.a as an intermediate.
|
|
|
|
This routine ensures that the leading part of the name matches and that
|
|
|
|
it is followed by only an optional version suffix and a file extension,
|
|
|
|
returning zero if so or -1 if not. */
|
|
|
|
static int libnamencmp (const char *libname, const autofilter_entry_type *afptr)
|
|
|
|
{
|
2011-02-28 19:34:52 +01:00
|
|
|
if (filename_ncmp (libname, afptr->name, afptr->len))
|
2009-01-03 18:43:45 +01:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
libname += afptr->len;
|
|
|
|
|
|
|
|
/* Be liberal in interpreting what counts as a version suffix; we
|
|
|
|
accept anything that has a dash to separate it from the name and
|
|
|
|
begins with a digit. */
|
|
|
|
if (libname[0] == '-')
|
|
|
|
{
|
|
|
|
if (!ISDIGIT (*++libname))
|
|
|
|
return -1;
|
|
|
|
/* Ensure the filename has an extension. */
|
|
|
|
while (*++libname != '.')
|
|
|
|
if (!*libname)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else if (libname[0] != '.')
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-11-01 01:48:25 +01:00
|
|
|
static const autofilter_entry_type autofilter_objlist[] =
|
2001-09-14 16:19:05 +02:00
|
|
|
{
|
2006-09-16 20:12:17 +02:00
|
|
|
{ STRING_COMMA_LEN ("crt0.o") },
|
|
|
|
{ STRING_COMMA_LEN ("crt1.o") },
|
|
|
|
{ STRING_COMMA_LEN ("crt2.o") },
|
|
|
|
{ STRING_COMMA_LEN ("dllcrt1.o") },
|
|
|
|
{ STRING_COMMA_LEN ("dllcrt2.o") },
|
|
|
|
{ STRING_COMMA_LEN ("gcrt0.o") },
|
|
|
|
{ STRING_COMMA_LEN ("gcrt1.o") },
|
|
|
|
{ STRING_COMMA_LEN ("gcrt2.o") },
|
|
|
|
{ STRING_COMMA_LEN ("crtbegin.o") },
|
|
|
|
{ STRING_COMMA_LEN ("crtend.o") },
|
2007-10-25 23:01:55 +02:00
|
|
|
{ NULL, 0 }
|
2001-08-03 01:12:02 +02:00
|
|
|
};
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2006-11-01 01:48:25 +01:00
|
|
|
static const autofilter_entry_type autofilter_symbolprefixlist[] =
|
2001-09-14 16:19:05 +02:00
|
|
|
{
|
2006-10-03 12:06:26 +02:00
|
|
|
/* _imp_ is treated specially, as it is always underscored. */
|
|
|
|
/* { STRING_COMMA_LEN ("_imp_") }, */
|
|
|
|
/* Don't export some c++ symbols. */
|
2006-09-16 20:12:17 +02:00
|
|
|
{ STRING_COMMA_LEN ("__rtti_") },
|
2006-10-03 12:06:26 +02:00
|
|
|
{ STRING_COMMA_LEN ("__builtin_") },
|
2002-10-07 18:36:11 +02:00
|
|
|
/* Don't re-export auto-imported symbols. */
|
2010-04-28 17:24:22 +02:00
|
|
|
{ STRING_COMMA_LEN ("__nm_") },
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Don't export symbols specifying internal DLL layout. */
|
2006-09-16 20:12:17 +02:00
|
|
|
{ STRING_COMMA_LEN ("_head_") },
|
2008-07-09 05:18:15 +02:00
|
|
|
{ STRING_COMMA_LEN ("_IMPORT_DESCRIPTOR_") },
|
|
|
|
/* Don't export section labels or artificial symbols
|
|
|
|
(eg ".weak.foo". */
|
|
|
|
{ STRING_COMMA_LEN (".") },
|
2007-10-25 23:01:55 +02:00
|
|
|
{ NULL, 0 }
|
2001-08-03 01:12:02 +02:00
|
|
|
};
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2006-11-01 01:48:25 +01:00
|
|
|
static const autofilter_entry_type autofilter_symbolsuffixlist[] =
|
2001-09-14 16:19:05 +02:00
|
|
|
{
|
2006-09-16 20:12:17 +02:00
|
|
|
{ STRING_COMMA_LEN ("_iname") },
|
2008-07-09 05:18:15 +02:00
|
|
|
{ STRING_COMMA_LEN ("_NULL_THUNK_DATA") },
|
2007-10-25 23:01:55 +02:00
|
|
|
{ NULL, 0 }
|
2001-08-03 01:12:02 +02:00
|
|
|
};
|
|
|
|
|
1999-05-11 23:06:50 +02:00
|
|
|
#define U(str) (pe_details->underscored ? "_" str : str)
|
|
|
|
|
|
|
|
void
|
2003-06-28 07:28:54 +02:00
|
|
|
pe_dll_id_target (const char *target)
|
1999-05-11 23:06:50 +02:00
|
|
|
{
|
|
|
|
int i;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2000-10-09 03:37:11 +02:00
|
|
|
for (i = 0; pe_detail_list[i].target_name; i++)
|
2000-07-19 02:04:04 +02:00
|
|
|
if (strcmp (pe_detail_list[i].target_name, target) == 0
|
|
|
|
|| strcmp (pe_detail_list[i].object_target, target) == 0)
|
1999-05-11 23:06:50 +02:00
|
|
|
{
|
2010-04-05 11:04:09 +02:00
|
|
|
int u = pe_leading_underscore; /* Underscoring mode. -1 for use default. */
|
|
|
|
if (u == -1)
|
|
|
|
bfd_get_target_info (target, NULL, NULL, &u, NULL);
|
2010-05-15 21:50:44 +02:00
|
|
|
if (u == -1)
|
|
|
|
abort ();
|
|
|
|
pe_detail_list[i].underscored = (u != 0 ? TRUE : FALSE);
|
2000-10-09 03:37:11 +02:00
|
|
|
pe_details = pe_detail_list + i;
|
2010-05-15 21:50:44 +02:00
|
|
|
pe_leading_underscore = (u != 0 ? 1 : 0);
|
1999-05-11 23:06:50 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
einfo (_("%XUnsupported PEI architecture: %s\n"), target);
|
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
|
2002-05-03 15:48:55 +02:00
|
|
|
/* Helper functions for qsort. Relocs must be sorted so that we can write
|
2001-09-14 16:19:05 +02:00
|
|
|
them out by pages. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
bfd_vma vma;
|
|
|
|
char type;
|
|
|
|
short extra;
|
|
|
|
}
|
|
|
|
reloc_data_type;
|
1999-05-11 23:06:50 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
static int
|
2003-06-28 07:28:54 +02:00
|
|
|
reloc_sort (const void *va, const void *vb)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
2003-06-28 07:28:54 +02:00
|
|
|
bfd_vma a = ((const reloc_data_type *) va)->vma;
|
|
|
|
bfd_vma b = ((const reloc_data_type *) vb)->vma;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-11 23:06:50 +02:00
|
|
|
return (a > b) ? 1 : ((a < b) ? -1 : 0);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2003-06-28 07:28:54 +02:00
|
|
|
pe_export_sort (const void *va, const void *vb)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
2003-06-28 07:28:54 +02:00
|
|
|
const def_file_export *a = va;
|
|
|
|
const def_file_export *b = vb;
|
2009-10-23 13:40:17 +02:00
|
|
|
char *an = a->name;
|
|
|
|
char *bn = b->name;
|
|
|
|
if (a->its_name)
|
|
|
|
an = a->its_name;
|
|
|
|
if (b->its_name)
|
|
|
|
bn = b->its_name;
|
|
|
|
|
|
|
|
return strcmp (an, bn);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Read and process the .DEF file. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
/* These correspond to the entries in pe_def_file->exports[]. I use
|
|
|
|
exported_symbol_sections[i] to tag whether or not the symbol was
|
2000-09-29 15:21:41 +02:00
|
|
|
defined, since we can't export symbols we don't have. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
static bfd_vma *exported_symbol_offsets;
|
2003-10-19 Andrew Cagney <cagney@redhat.com>
* targets.c: Replace "struct sec" with "struct bfd_section"
* syms.c, sparclynx.c, section.c, opncls.c: Ditto.
* libcoff-in.h, libbfd-in.h, elfxx-target.h: Ditto.
* elf.c, coffgen.c, bfd.c, bfd-in.h, aoutf1.h: Ditto.
* aout-tic30.c, aout-target.h:
* bfd-in2.h, libcoff.h, libbfd.h: Regenerate.
Index: binutils/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* coffgrok.h (coff_section): Replace 'struct sec" with "struct
bfd_section".
Index: gdb/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* symtab.c: Replace "struct sec" with "struct bfd_section".
* objfiles.c, linespec.c, blockframe.c, block.c: Ditto.
Index: ld/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* pe-dll.c: Replace "struct sec" with "struct bfd_section".
Index: sim/common/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* sim-base.h: Replace "struct sec" with "struct bfd_section".
2003-10-20 16:38:46 +02:00
|
|
|
static struct bfd_section **exported_symbol_sections;
|
1999-05-03 09:29:11 +02:00
|
|
|
static int export_table_size;
|
|
|
|
static int count_exported;
|
|
|
|
static int count_exported_byname;
|
|
|
|
static int count_with_ordinals;
|
|
|
|
static const char *dll_name;
|
|
|
|
static int min_ordinal, max_ordinal;
|
|
|
|
static int *exported_symbols;
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
typedef struct exclude_list_struct
|
|
|
|
{
|
|
|
|
char *string;
|
|
|
|
struct exclude_list_struct *next;
|
2009-01-03 19:04:16 +01:00
|
|
|
exclude_type type;
|
2001-09-14 16:19:05 +02:00
|
|
|
}
|
|
|
|
exclude_list_struct;
|
2000-10-09 09:01:29 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
static struct exclude_list_struct *excludes = 0;
|
|
|
|
|
|
|
|
void
|
2009-01-03 19:04:16 +01:00
|
|
|
pe_dll_add_excludes (const char *new_excludes, const exclude_type type)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
char *local_copy;
|
|
|
|
char *exclude_string;
|
|
|
|
|
|
|
|
local_copy = xstrdup (new_excludes);
|
|
|
|
|
|
|
|
exclude_string = strtok (local_copy, ",:");
|
|
|
|
for (; exclude_string; exclude_string = strtok (NULL, ",:"))
|
|
|
|
{
|
|
|
|
struct exclude_list_struct *new_exclude;
|
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
new_exclude = xmalloc (sizeof (struct exclude_list_struct));
|
|
|
|
new_exclude->string = xmalloc (strlen (exclude_string) + 1);
|
1999-05-03 09:29:11 +02:00
|
|
|
strcpy (new_exclude->string, exclude_string);
|
2002-05-22 20:03:09 +02:00
|
|
|
new_exclude->type = type;
|
1999-05-03 09:29:11 +02:00
|
|
|
new_exclude->next = excludes;
|
|
|
|
excludes = new_exclude;
|
|
|
|
}
|
|
|
|
|
|
|
|
free (local_copy);
|
|
|
|
}
|
|
|
|
|
2006-10-03 12:06:26 +02:00
|
|
|
static bfd_boolean
|
|
|
|
is_import (const char* n)
|
|
|
|
{
|
2006-11-01 01:48:25 +01:00
|
|
|
return (CONST_STRNEQ (n, "__imp_"));
|
2006-10-03 12:06:26 +02:00
|
|
|
}
|
2002-05-22 20:03:09 +02:00
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* abfd is a bfd containing n (or NULL)
|
|
|
|
It can be used for contextual checks. */
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
static int
|
2003-06-28 07:28:54 +02:00
|
|
|
auto_export (bfd *abfd, def_file *d, const char *n)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
2012-02-11 20:25:12 +01:00
|
|
|
def_file_export key;
|
1999-05-03 09:29:11 +02:00
|
|
|
struct exclude_list_struct *ex;
|
2006-11-01 01:48:25 +01:00
|
|
|
const autofilter_entry_type *afptr;
|
2012-02-11 20:25:12 +01:00
|
|
|
const char * libname = NULL;
|
|
|
|
|
2002-05-22 20:03:09 +02:00
|
|
|
if (abfd && abfd->my_archive)
|
|
|
|
libname = lbasename (abfd->my_archive->filename);
|
2001-08-03 01:12:02 +02:00
|
|
|
|
2012-02-11 20:25:12 +01:00
|
|
|
key.name = key.its_name = (char *) n;
|
|
|
|
|
|
|
|
/* Return false if n is in the d->exports table. */
|
|
|
|
if (bsearch (&key, d->exports, d->num_exports,
|
|
|
|
sizeof (pe_def_file->exports[0]), pe_export_sort))
|
|
|
|
return 0;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (pe_dll_do_default_excludes)
|
|
|
|
{
|
2001-10-19 02:00:55 +02:00
|
|
|
const char * p;
|
2001-09-14 16:19:05 +02:00
|
|
|
int len;
|
|
|
|
|
2001-08-03 01:12:02 +02:00
|
|
|
if (pe_dll_extra_pe_debug)
|
2001-09-14 16:19:05 +02:00
|
|
|
printf ("considering exporting: %s, abfd=%p, abfd->my_arc=%p\n",
|
|
|
|
n, abfd, abfd->my_archive);
|
2001-08-03 01:12:02 +02:00
|
|
|
|
|
|
|
/* First of all, make context checks:
|
2003-06-28 07:28:54 +02:00
|
|
|
Don't export anything from standard libs. */
|
2002-05-25 22:39:25 +02:00
|
|
|
if (libname)
|
2001-08-03 01:12:02 +02:00
|
|
|
{
|
|
|
|
afptr = autofilter_liblist;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2001-08-03 01:12:02 +02:00
|
|
|
while (afptr->name)
|
|
|
|
{
|
2009-01-03 18:43:45 +01:00
|
|
|
if (libnamencmp (libname, afptr) == 0 )
|
2001-08-03 01:12:02 +02:00
|
|
|
return 0;
|
|
|
|
afptr++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Next, exclude symbols from certain startup objects. */
|
|
|
|
|
2001-10-19 16:25:51 +02:00
|
|
|
if (abfd && (p = lbasename (abfd->filename)))
|
2001-10-19 02:00:55 +02:00
|
|
|
{
|
2002-05-03 15:48:55 +02:00
|
|
|
afptr = autofilter_objlist;
|
|
|
|
while (afptr->name)
|
2001-10-19 16:25:51 +02:00
|
|
|
{
|
2002-05-03 15:48:55 +02:00
|
|
|
if (strcmp (p, afptr->name) == 0)
|
|
|
|
return 0;
|
2001-10-19 16:25:51 +02:00
|
|
|
afptr++;
|
2001-10-19 02:00:55 +02:00
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
}
|
2001-08-03 01:12:02 +02:00
|
|
|
|
|
|
|
/* Don't try to blindly exclude all symbols
|
|
|
|
that begin with '__'; this was tried and
|
2006-06-23 13:20:15 +02:00
|
|
|
it is too restrictive. Instead we have
|
|
|
|
a target specific list to use: */
|
2010-05-15 16:20:06 +02:00
|
|
|
afptr = pe_details->autofilter_symbollist;
|
2006-09-20 13:35:11 +02:00
|
|
|
|
2001-08-03 01:12:02 +02:00
|
|
|
while (afptr->name)
|
|
|
|
{
|
|
|
|
if (strcmp (n, afptr->name) == 0)
|
|
|
|
return 0;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2002-05-03 15:48:55 +02:00
|
|
|
afptr++;
|
2001-08-03 01:12:02 +02:00
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Next, exclude symbols starting with ... */
|
2001-08-03 01:12:02 +02:00
|
|
|
afptr = autofilter_symbolprefixlist;
|
|
|
|
while (afptr->name)
|
|
|
|
{
|
|
|
|
if (strncmp (n, afptr->name, afptr->len) == 0)
|
|
|
|
return 0;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2002-05-03 15:48:55 +02:00
|
|
|
afptr++;
|
2001-08-03 01:12:02 +02:00
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Finally, exclude symbols ending with ... */
|
|
|
|
len = strlen (n);
|
|
|
|
afptr = autofilter_symbolsuffixlist;
|
|
|
|
while (afptr->name)
|
|
|
|
{
|
2002-05-03 15:48:55 +02:00
|
|
|
if ((len >= afptr->len)
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Add 1 to insure match with trailing '\0'. */
|
2002-05-03 15:48:55 +02:00
|
|
|
&& strncmp (n + len - afptr->len, afptr->name,
|
|
|
|
afptr->len + 1) == 0)
|
2001-09-14 16:19:05 +02:00
|
|
|
return 0;
|
|
|
|
|
2002-05-03 15:48:55 +02:00
|
|
|
afptr++;
|
2001-09-14 16:19:05 +02:00
|
|
|
}
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
for (ex = excludes; ex; ex = ex->next)
|
2002-05-22 20:03:09 +02:00
|
|
|
{
|
2009-01-03 19:04:16 +01:00
|
|
|
if (ex->type == EXCLUDELIBS)
|
2002-05-22 20:03:09 +02:00
|
|
|
{
|
|
|
|
if (libname
|
2011-02-28 19:34:52 +01:00
|
|
|
&& ((filename_cmp (libname, ex->string) == 0)
|
2002-05-22 20:03:09 +02:00
|
|
|
|| (strcasecmp ("ALL", ex->string) == 0)))
|
|
|
|
return 0;
|
|
|
|
}
|
2009-01-03 19:04:16 +01:00
|
|
|
else if (ex->type == EXCLUDEFORIMPLIB)
|
|
|
|
{
|
2011-02-28 19:34:52 +01:00
|
|
|
if (filename_cmp (abfd->filename, ex->string) == 0)
|
2009-01-03 19:04:16 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2002-05-22 20:03:09 +02:00
|
|
|
else if (strcmp (n, ex->string) == 0)
|
2002-05-25 22:39:25 +02:00
|
|
|
return 0;
|
2002-05-22 20:03:09 +02:00
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-05-19 18:08:08 +02:00
|
|
|
process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
struct bfd_link_hash_entry *blhe;
|
|
|
|
bfd *b;
|
2003-10-19 Andrew Cagney <cagney@redhat.com>
* targets.c: Replace "struct sec" with "struct bfd_section"
* syms.c, sparclynx.c, section.c, opncls.c: Ditto.
* libcoff-in.h, libbfd-in.h, elfxx-target.h: Ditto.
* elf.c, coffgen.c, bfd.c, bfd-in.h, aoutf1.h: Ditto.
* aout-tic30.c, aout-target.h:
* bfd-in2.h, libcoff.h, libbfd.h: Regenerate.
Index: binutils/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* coffgrok.h (coff_section): Replace 'struct sec" with "struct
bfd_section".
Index: gdb/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* symtab.c: Replace "struct sec" with "struct bfd_section".
* objfiles.c, linespec.c, blockframe.c, block.c: Ditto.
Index: ld/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* pe-dll.c: Replace "struct sec" with "struct bfd_section".
Index: sim/common/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* sim-base.h: Replace "struct sec" with "struct bfd_section".
2003-10-20 16:38:46 +02:00
|
|
|
struct bfd_section *s;
|
2000-10-09 03:37:11 +02:00
|
|
|
def_file_export *e = 0;
|
2012-02-11 20:25:12 +01:00
|
|
|
bfd_boolean resort_needed;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
if (!pe_def_file)
|
|
|
|
pe_def_file = def_file_empty ();
|
|
|
|
|
|
|
|
/* First, run around to all the objects looking for the .drectve
|
2000-10-09 09:01:29 +02:00
|
|
|
sections, and push those into the def file too. */
|
1999-05-03 09:29:11 +02:00
|
|
|
for (b = info->input_bfds; b; b = b->link_next)
|
|
|
|
{
|
|
|
|
s = bfd_get_section_by_name (b, ".drectve");
|
|
|
|
if (s)
|
|
|
|
{
|
bfd/
* section.c (struct sec): Rename "_cooked_size" to "size".
Rename "_raw_size" to "rawsize".
(STD_SECTION): Adjust comments.
(bfd_set_section_size, bfd_get_section_contents): Use size.
(bfd_malloc_and_get_section): New function.
* bfd-in.h (bfd_section_size, bfd_get_section_size): Use size.
* coff-sh.c (sh_relax_section): Alloc coff_section_data struct early.
Correctly free reloc and contents memory.
* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Delete FIXME
and fake CIE now that we can shink section size to zero.
(_bfd_elf_write_section_eh_frame): Likewise..
* elf32-ppc.c (ppc_elf_relax_section): Delay reading section contents.
* elf-m10300.c (mn10300_elf_final_link_relocate): Don't use
_bfd_stab_section_offset. Use _bfd_elf_section_offset.
* stabs.c (_bfd_stab_section_offset_): Remove unused args and
unneeded indirection.
* elf.c (_bfd_elf_section_offset): .. and update call.
* libbfd-in.h (_bfd_stab_section_offset): Update prototype.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
Replace occurrences of "_raw_size" and "_cooked_size" in most places
with "size". Set new "rawsize" for stabs, eh_frame, and SEC_MERGE
sections. Use "rawsize", if non-zero, for bfd_get_section_contents
calls if the section might be a stabs, eh_frame, or SEC_MERGE section.
Similarly use "rawsize", if non-zero, in reloc functions to validate
reloc addresses. Use new bfd_malloc_and_get_section in most places
where bfd_get_section_contents was called. Expand all occurrences of
bfd_section_size and bfd_get_section_size. Rename "raw_size" var in
grok_prstatus and similar functions to "size".
* aix386-core.c (aix386_core_file_p): ..
* aix5ppc-core.c (xcoff64_core_p): ..
* aout-adobe.c (aout_adobe_callback, aout_adobe_write_object_contents,
aout_adobe_set_section_contents): ..
* aout-target.h (callback): ..
* aout-tic30.c (tic30_aout_callback, tic30_aout_final_link_relocate,
MY_bfd_final_link): ..
* aoutf1.h (sunos4_core_file_p): ..
* aoutx.h (some_aout_object_p, adjust_o_magic, adjust_z_magic,
adjust_n_magic, adjust_sizes_and_vmas, translate_from_native_sym_flags,
final_link, aout_link_input_section): ..
* binary.c (binary_object_p, binary_canonicalize_symtab,
binary_set_section_contents): ..
* bout.c (b_out_callback, b_out_write_object_contents,
b_out_set_section_contents, b_out_bfd_relax_section,
b_out_bfd_get_relocated_section_contents): ..
* cisco-core.c (cisco_core_file_validate): ..
* coff-alpha.c (alpha_ecoff_object_p,
alpha_ecoff_get_relocated_section_conten, alpha_relocate_section): ..
* coff-arm.c (coff_arm_relocate_section,
bfd_arm_allocate_interworking_sections): ..
* coff-h8300.c (h8300_reloc16_extra_cases,
h8300_bfd_link_add_symbols): ..
* coff-mips.c (mips_refhi_reloc, mips_gprel_reloc): ..
* coff-ppc.c (coff_ppc_relocate_section, ppc_allocate_toc_section,
ppc_bfd_coff_final_link): ..
* coff-rs6000.c (xcoff_reloc_type_br, xcoff_ppc_relocate_section): ..
* coff-sh.c (sh_relax_section, sh_relax_delete_bytes,
sh_align_loads, sh_coff_get_relocated_section_contents): ..
* coff64-rs6000.c (xcoff64_write_object_contents,
xcoff64_reloc_type_br, xcoff64_ppc_relocate_section): ..
* coffcode.h (coff_compute_section_file_positions,
coff_write_object_contents): ..
* coffgen.c (make_a_section_from_file, coff_write_symbols,
coff_section_symbol, build_debug_section): ..
* cofflink.c (coff_link_add_symbols, _bfd_coff_final_link,
process_embedded_commands, _bfd_coff_link_input_bfd,
_bfd_coff_write_global_sym): ..
* cpu-arm.c (bfd_arm_update_notes, bfd_arm_get_mach_from_notes): ..
* cpu-ns32k.c (do_ns32k_reloc, _bfd_ns32k_final_link_relocate): ..
* dwarf1.c (parse_line_table, _bfd_dwarf1_find_nearest_line): ..
* dwarf2.c (read_indirect_string, read_abbrevs, decode_line_info,
_bfd_dwarf2_find_nearest_line): ..
* ecoff.c (bfd_debug_section, ecoff_set_symbol_info,
ecoff_compute_section_file_positions,
_bfd_ecoff_write_object_contents, ecoff_indirect_link_order): ..
* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame,
_bfd_elf_discard_section_eh_frame_hdr,
_bfd_elf_maybe_strip_eh_frame_hdr, _bfd_elf_eh_frame_section_offset,
_bfd_elf_write_section_eh_frame,
_bfd_elf_write_section_eh_frame_hdr): ..
* elf-hppa.h (elf_hppa_sort_unwind): ..
* elf-m10200.c (mn10200_elf_relax_section,
mn10200_elf_relax_delete_bytes,
mn10200_elf_get_relocated_section_contents): ..
* elf-m10300.c (_bfd_mn10300_elf_create_got_section,
mn10300_elf_check_relocs, mn10300_elf_relax_section,
mn10300_elf_relax_delete_bytes,
mn10300_elf_get_relocated_section_contents,
_bfd_mn10300_elf_adjust_dynamic_symbol,
_bfd_mn10300_elf_discard_copies,
_bfd_mn10300_elf_size_dynamic_sections,
_bfd_mn10300_elf_finish_dynamic_sections): ..
* elf.c (_bfd_elf_print_private_bfd_data, bfd_elf_get_bfd_needed_list,
_bfd_elf_make_section_from_phdr, elf_fake_sections,
bfd_elf_set_group_contents, map_sections_to_segments,
elf_sort_sections, assign_file_positions_for_segments,
SECTION_SIZE, copy_private_bfd_data,
_bfd_elf_get_dynamic_reloc_upper_bound,
_bfd_elf_canonicalize_dynamic_reloc, elfcore_maybe_make_sect,
_bfd_elfcore_make_pseudosection, elfcore_grok_prstatus,
elfcore_grok_lwpstatus, elfcore_grok_win32pstatus,
elfcore_grok_note, elfcore_grok_nto_status, elfcore_grok_nto_gregs,
_bfd_elf_rel_local_sym, _bfd_elf_get_synthetic_symtab): ..
* elf32-arm.h (bfd_elf32_arm_allocate_interworking_sect,
bfd_elf32_arm_process_before_allocation,
elf32_arm_adjust_dynamic_symbol, allocate_dynrelocs,
elf32_arm_size_dynamic_sections, elf32_arm_finish_dynamic_sections,
elf32_arm_write_section): ..
* elf32-cris.c (cris_elf_grok_prstatus,
elf_cris_finish_dynamic_sections, cris_elf_gc_sweep_hook,
elf_cris_adjust_gotplt_to_got, elf_cris_adjust_dynamic_symbol,
cris_elf_check_relocs, elf_cris_size_dynamic_sections,
elf_cris_discard_excess_dso_dynamics,
elf_cris_discard_excess_program_dynamics): ..
* elf32-d30v.c (bfd_elf_d30v_reloc, bfd_elf_d30v_reloc_21): ..
* elf32-dlx.c (_bfd_dlx_elf_hi16_reloc): ..
* elf32-frv.c (_frvfdpic_add_dyn_reloc, _frvfdpic_add_rofixup,
_frv_create_got_section, _frvfdpic_assign_plt_entries,
elf32_frvfdpic_size_dynamic_sections,
elf32_frvfdpic_modify_segment_map,
elf32_frvfdpic_finish_dynamic_sections): ..
* elf32-h8300.c (elf32_h8_relax_section, elf32_h8_relax_delete_bytes,
elf32_h8_get_relocated_section_contents): ..
* elf32-hppa.c (hppa_build_one_stub, hppa_size_one_stub,
elf32_hppa_adjust_dynamic_symbol, allocate_plt_static,
allocate_dynrelocs, elf32_hppa_size_dynamic_sections, group_sections,
elf32_hppa_size_stubs, elf32_hppa_set_gp, elf32_hppa_build_stubs,
elf32_hppa_finish_dynamic_sections): ..
* elf32-i370.c (i370_elf_adjust_dynamic_symbol,
i370_elf_size_dynamic_sections, i370_elf_check_relocs,
i370_elf_finish_dynamic_sections): ..
* elf32-i386.c (elf_i386_grok_prstatus, elf_i386_adjust_dynamic_symbol,
allocate_dynrelocs, elf_i386_size_dynamic_sections,
elf_i386_relocate_section, elf_i386_finish_dynamic_sections): ..
* elf32-i860.c (i860_howto_pc26_reloc, i860_howto_pc16_reloc,
i860_howto_highadj_reloc, i860_howto_splitn_reloc): ..
* elf32-ip2k.c (ip2k_is_switch_table_128,
ip2k_relax_switch_table_128, ip2k_is_switch_table_256,
ip2k_relax_switch_table_256, ip2k_elf_relax_section,
adjust_all_relocations, ip2k_elf_relax_delete_bytes): ..
* elf32-m32r.c (m32r_elf_do_10_pcrel_reloc, m32r_elf_hi16_reloc,
m32r_elf_generic_reloc, m32r_elf_adjust_dynamic_symbol,
allocate_dynrelocs, m32r_elf_size_dynamic_sections,
m32r_elf_relocate_section, m32r_elf_finish_dynamic_sections,
m32r_elf_relax_section, m32r_elf_relax_delete_bytes,
m32r_elf_get_relocated_section_contents): ..
* elf32-m68hc11.c (m68hc11_elf_build_one_stub,
m68hc11_elf_size_one_stub, m68hc11_elf_relax_section,
m68hc11_elf_relax_delete_bytes): ..
* elf32-m68hc12.c (m68hc12_elf_build_one_stub,
m68hc12_elf_size_one_stub): ..
* elf32-m68hc1x.c (elf32_m68hc11_size_stubs,
elf32_m68hc11_build_stubs, m68hc11_elf_special_reloc): ..
* elf32-m68k.c (elf_m68k_check_relocs, elf_m68k_gc_sweep_hook,
elf_m68k_adjust_dynamic_symbol, elf_m68k_size_dynamic_sections,
elf_m68k_discard_copies, elf_m68k_finish_dynamic_sections): ..
* elf32-mips.c (gprel32_with_gp, mips16_gprel_reloc,
elf32_mips_grok_prstatus): ..
* elf32-or32.c (or32_elf_consth_reloc): ..
* elf32-ppc.c (ppc_elf_relax_section, ppc_elf_addr16_ha_reloc,
elf_create_pointer_linker_section, ppc_elf_create_linker_section,
ppc_elf_additional_program_headers, ppc_elf_adjust_dynamic_symbol,
allocate_dynrelocs, ppc_elf_size_dynamic_sections,
ppc_elf_finish_dynamic_sections, ppc_elf_grok_prstatus,
ppc_elf_final_write_processing): ..
* elf32-s390.c (s390_elf_ldisp_reloc, elf_s390_adjust_dynamic_symbol,
allocate_dynrelocs, elf_s390_size_dynamic_sections,
elf_s390_finish_dynamic_sections, elf_s390_grok_prstatus): ..
* elf32-sh.c (sh_elf_reloc_loop, sh_elf_relax_section,
sh_elf_relax_delete_bytes, sh_elf_align_loads,
sh_elf_adjust_dynamic_symbol, allocate_dynrelocs,
sh_elf_size_dynamic_sections, sh_elf_get_relocated_section_contents,
sh_elf_finish_dynamic_sections, elf32_shlin_grok_prstatus): ..
* elf32-sh64-com.c (sh64_address_in_cranges,
sh64_get_contents_type): ..
* elf32-sh64.c (sh64_find_section_for_address,
sh64_elf_final_write_processing): ..
* elf32-sparc.c (sparc_elf_wdisp16_reloc, sparc_elf_hix22_reloc,
sparc_elf_lox10_reloc, elf32_sparc_adjust_dynamic_symbol,
allocate_dynrelocs, elf32_sparc_size_dynamic_sections,
elf32_sparc_relocate_section, elf32_sparc_finish_dynamic_sections): ..
* elf32-v850.c (v850_elf_reloc, v850_elf_relax_section): ..
* elf32-vax.c (elf_vax_check_relocs, elf_vax_adjust_dynamic_symbol,
elf_vax_size_dynamic_sections, elf_vax_discard_copies,
elf_vax_instantiate_got_entries, elf_vax_relocate_section,
elf_vax_finish_dynamic_sections): ..
* elf32-xstormy16.c (xstormy16_elf_24_reloc,
xstormy16_elf_check_relocs, xstormy16_relax_plt_check,
xstormy16_elf_relax_section, xstormy16_elf_always_size_sections,
xstormy16_elf_finish_dynamic_sections): ..
* elf32-xtensa.c (xtensa_read_table_entries,
elf_xtensa_allocate_got_size, elf_xtensa_allocate_local_got_size,
elf_xtensa_size_dynamic_sections, elf_xtensa_do_reloc,
bfd_elf_xtensa_reloc, elf_xtensa_relocate_section,
elf_xtensa_combine_prop_entries, elf_xtensa_finish_dynamic_sections,
elf_xtensa_discard_info_for_section, elf_xtensa_grok_prstatus,
get_relocation_opcode, retrieve_contents, find_relaxable_sections,
collect_source_relocs, is_resolvable_asm_expansion, remove_literals,
relax_section, shrink_dynamic_reloc_sections, relax_property_section,
xtensa_callback_required_dependence): ..
* elf64-alpha.c (elf64_alpha_reloc_gpdisp, elf64_alpha_relax_section,
elf64_alpha_check_relocs, elf64_alpha_adjust_dynamic_symbol,
elf64_alpha_calc_got_offsets_for_symbol, elf64_alpha_calc_got_offsets,
elf64_alpha_size_plt_section, elf64_alpha_size_plt_section_1,
elf64_alpha_always_size_sections, elf64_alpha_calc_dynrel_sizes,
elf64_alpha_size_rela_got_section, elf64_alpha_size_rela_got_1,
elf64_alpha_size_dynamic_sections, elf64_alpha_emit_dynrel,
elf64_alpha_finish_dynamic_sections, elf64_alpha_final_link): ..
* elf64-hppa.c (allocate_dynrel_entries,
elf64_hppa_size_dynamic_sections,
elf64_hppa_finish_dynamic_sections): ..
* elf64-mips.c (mips_elf64_gprel32_reloc, mips16_gprel_reloc,
mips_elf64_canonicalize_dynamic_reloc, mips_elf64_slurp_reloc_table,
elf64_mips_grok_prstatus): ..
* elf64-mmix.c (mmix_elf_perform_relocation, mmix_elf_reloc,
mmix_elf_relocate_section, mmix_elf_final_link,
mmix_set_relaxable_size, _bfd_mmix_after_linker_allocation,
mmix_elf_relax_section, mmix_elf_get_section_contents): ..
* elf64-ppc.c (ppc64_elf_object_p, ppc64_elf_grok_prstatus,
ppc64_elf_check_relocs, ppc64_elf_func_desc_adjust,
ppc64_elf_adjust_dynamic_symbol, ppc64_elf_edit_opd,
allocate_dynrelocs, ppc64_elf_size_dynamic_sections,
ppc_build_one_stub, ppc_size_one_stub, ppc64_elf_next_toc_section,
toc_adjusting_stub_needed, group_sections, ppc64_elf_size_stubs,
ppc64_elf_build_stubs, ppc64_elf_relocate_section,
ppc64_elf_finish_dynamic_sections): ..
* elf64-s390.c (s390_elf_ldisp_reloc, elf_s390_adjust_dynamic_symbol,
allocate_dynrelocs, elf_s390_size_dynamic_sections,
elf_s390_finish_dynamic_sections): ..
* elf64-sh64.c (sh_elf64_get_relocated_section_contents,
sh_elf64_check_relocs, sh64_elf64_adjust_dynamic_symbol,
sh64_elf64_discard_copies, sh64_elf64_size_dynamic_sections,
sh64_elf64_finish_dynamic_sections): ..
* elf64-sparc.c (sparc64_elf_slurp_reloc_table, init_insn_reloc,
sparc64_elf_check_relocs, sparc64_elf_adjust_dynamic_symbol,
sparc64_elf_size_dynamic_sections, sparc64_elf_relocate_section,
sparc64_elf_finish_dynamic_symbol,
sparc64_elf_finish_dynamic_sections): ..
* elf64-x86-64.c (elf64_x86_64_grok_prstatus,
elf64_x86_64_adjust_dynamic_symbol, allocate_dynrelocs,
elf64_x86_64_size_dynamic_sections, elf64_x86_64_relocate_section,
elf64_x86_64_finish_dynamic_sections): ..
* elfarm-nabi.c (elf32_arm_nabi_grok_prstatus): ..
* elfcode.h (elf_slurp_reloc_table): ..
* elflink.c (_bfd_elf_create_got_section, elf_add_dt_needed_tag,
elf_finalize_dynstr, elf_link_add_object_symbols,
bfd_elf_size_dynamic_sections, elf_link_sort_relocs,
elf_link_input_bfd, bfd_elf_final_link, bfd_elf_discard_info): ..
* elfn32-mips.c (gprel32_with_gp, mips16_gprel_reloc,
elf32_mips_grok_prstatus): ..
* elfxx-ia64.c (elfNN_ia64_relax_section, allocate_dynrel_entries,
elfNN_ia64_size_dynamic_sections, elfNN_ia64_install_dyn_reloc,
elfNN_ia64_choose_gp, elfNN_ia64_final_link,
elfNN_ia64_finish_dynamic_sections): ..
* elfxx-mips.c (mips_elf_create_procedure_table,
mips_elf_check_mips16_stubs, _bfd_mips_elf_gprel16_with_gp,
_bfd_mips_elf_hi16_reloc, _bfd_mips_elf_generic_reloc,
mips_elf_global_got_index, mips_elf_multi_got,
mips_elf_create_compact_rel_section, mips_elf_calculate_relocation,
mips_elf_allocate_dynamic_relocations,
mips_elf_create_dynamic_relocation, _bfd_mips_elf_fake_sections,
_bfd_mips_relax_section, _bfd_mips_elf_adjust_dynamic_symbol,
_bfd_mips_elf_always_size_sections,
_bfd_mips_elf_size_dynamic_sections,
_bfd_mips_elf_finish_dynamic_symbol,
_bfd_mips_elf_finish_dynamic_sections,
_bfd_mips_elf_modify_segment_map, _bfd_mips_elf_discard_info,
_bfd_mips_elf_write_section, _bfd_mips_elf_set_section_contents,
_bfd_elf_mips_get_relocated_section_contents,
_bfd_mips_elf_final_link, _bfd_mips_elf_merge_private_bfd_data): ..
* hp300hpux.c (callback): ..
* hppabsd-core.c (make_bfd_asection): ..
* hpux-core.c (make_bfd_asection): ..
* i386linux.c (linux_link_create_dynamic_sections,
bfd_i386linux_size_dynamic_sections, linux_finish_dynamic_link): ..
* i386msdos.c (msdos_write_object_contents): ..
* i386os9k.c (os9k_callback, os9k_write_object_contents,
os9k_set_section_contents): ..
* ieee.c (parse_expression, ieee_slurp_external_symbols,
ieee_slurp_sections, ieee_slurp_debug, ieee_slurp_section_data,
ieee_write_section_part, do_with_relocs, do_as_repeat,
do_without_relocs, ieee_write_debug_part, init_for_output,
ieee_set_section_contents): ..
* ihex.c (ihex_scan, ihex_read_section, ihex_get_section_contents): ..
* irix-core.c (do_sections, make_bfd_asection): ..
* libaout.h (aout_section_merge_with_text_p): ..
* libbfd.c (_bfd_generic_get_section_contents,
_bfd_generic_get_section_contents_in_window): ..
* linker.c (default_indirect_link_order): ..
* lynx-core.c (make_bfd_asection): ..
* m68klinux.c (linux_link_create_dynamic_sections,
bfd_m68klinux_size_dynamic_sections, linux_finish_dynamic_link): ..
* mach-o.c (bfd_mach_o_make_bfd_section,
bfd_mach_o_scan_read_dylinker, bfd_mach_o_scan_read_dylib,
bfd_mach_o_scan_read_thread, bfd_mach_o_scan_read_symtab,
bfd_mach_o_scan_read_segment): ..
* merge.c (_bfd_add_merge_section, record_section, merge_strings,
_bfd_merge_sections): ..
* mmo.c (mmo_find_sec_w_addr, mmo_get_spec_section, mmo_get_loc,
mmo_map_set_sizes, mmo_canonicalize_symtab,
mmo_internal_write_section, mmo_write_object_contents): ..
* netbsd-core.c (netbsd_core_file_p): ..
* nlm32-alpha.c (nlm_alpha_read_reloc, nlm_alpha_write_import,
nlm_alpha_set_public_section): ..
* nlm32-ppc.c (nlm_powerpc_read_reloc, nlm_powerpc_write_reloc): ..
* nlm32-sparc.c (nlm_sparc_write_import): ..
* nlmcode.h (add_bfd_section, nlm_swap_auxiliary_headers_in,
nlm_compute_section_file_positions): ..
* oasys.c (oasys_object_p, oasys_slurp_section_data,
oasys_write_sections, oasys_write_data, oasys_set_section_contents): ..
* opncls.c (get_debug_link_info): ..
* osf-core.c (make_bfd_asection): ..
* pdp11.c (some_aout_object_p, adjust_o_magic, adjust_z_magic,
adjust_n_magic, adjust_sizes_and_vmas, squirt_out_relocs,
final_link, aout_link_input_section): ..
* peXXigen.c (_bfd_XXi_swap_sym_in, _bfd_XXi_swap_aouthdr_out,
pe_print_idata, pe_print_edata, pe_print_pdata, pe_print_reloc): ..
* pef.c (bfd_pef_make_bfd_section, bfd_pef_print_loader_section,
bfd_pef_scan_start_address, bfd_pef_parse_symbols): ..
* ppcboot.c (ppcboot_object_p, ppcboot_canonicalize_symtab): ..
* ptrace-core.c (ptrace_unix_core_file_p): ..
* reloc.c (bfd_perform_relocation, bfd_install_relocation,
_bfd_final_link_relocate, bfd_generic_relax_section,
bfd_generic_get_relocated_section_contents): ..
* reloc16.c (bfd_coff_reloc16_relax_section,
bfd_coff_reloc16_get_relocated_section_c): ..
* riscix.c (riscix_some_aout_object_p): ..
* rs6000-core.c (read_hdr, make_bfd_asection): ..
* sco5-core.c (make_bfd_asection): ..
* simple.c (bfd_simple_get_relocated_section_contents): ..
* som.c (som_object_setup, setup_sections, som_prep_headers,
som_write_fixups, som_begin_writing, bfd_section_from_som_symbol,
som_set_reloc_info, som_get_section_contents,
som_bfd_link_split_section): ..
* sparclinux.c (linux_link_create_dynamic_sections,
bfd_sparclinux_size_dynamic_sections, linux_finish_dynamic_link): ..
* srec.c (srec_scan, srec_read_section, srec_get_section_contents): ..
* stabs.c (_bfd_link_section_stabs, _bfd_discard_section_stabs,
_bfd_write_stab_strings, _bfd_stab_section_offset): ..
* sunos.c (sunos_read_dynamic_info, sunos_create_dynamic_sections,
bfd_sunos_size_dynamic_sections, sunos_scan_std_relocs,
sunos_scan_ext_relocs, sunos_scan_dynamic_symbol,
sunos_write_dynamic_symbol, sunos_check_dynamic_reloc,
sunos_finish_dynamic_link): ..
* syms.c (_bfd_stab_section_find_nearest_line): ..
* tekhex.c (first_phase, tekhex_set_section_contents,
tekhex_write_object_contents): ..
* trad-core.c (trad_unix_core_file_p): ..
* versados.c (process_esd, process_otr, process_otr): ..
* vms-gsd.c (_bfd_vms_slurp_gsd, _bfd_vms_write_gsd): ..
* vms-misc.c (add_new_contents): ..
* vms-tir.c (check_section, new_section, _bfd_vms_write_tir): ..
* vms.c (vms_set_section_contents): ..
* xcofflink.c (xcoff_get_section_contents, xcoff_link_add_symbols,
xcoff_sweep, bfd_xcoff_size_dynamic_sections, xcoff_build_ldsyms,
_bfd_xcoff_bfd_final_link, xcoff_link_input_bfd): ..
* xsym.c (bfd_sym_scan): .. See above.
binutils/
* objcopy.c (copy_section): Don't set _cooked_size.
include/
* bfdlink.h (struct bfd_link_order): Update comment.
ld/
* ldlang.c (print_output_section_statement): Don't print size before
relaxation.
(IGNORE_SECTION): Remove bfd arg. Update all callers.
* ldexp.c (fold_name): .. See below.
* ldlang.c (section_already_linked, print_output_section_statement,
print_input_section, insert_pad, size_input_section,
lang_check_section_addresses, lang_size_sections_1,
lang_size_sections, lang_do_assignments_1, lang_set_startof,
lang_one_common, lang_reset_memory_regions, lang_process,
lang_abs_symbol_at_end_of, lang_do_version_exports_section): ..
* ldwrite.c (build_link_order, clone_section, ds, split_sections): ..
* pe-dll.c (process_def_file, generate_reloc): ..
* emultempl/elf32.em (gld${EMULATION_NAME}_find_statement_assignment,
gld${EMULATION_NAME}_before_allocation): ..
* emultempl/mmix-elfnmmo.em (mmix_after_allocation): ..
* emultempl/sh64elf.em (sh64_elf_${EMULATION_NAME}_before_allocation,
sh64_elf_${EMULATION_NAME}_after_allocation): ..
* emultempl/sunos.em (gld${EMULATION_NAME}_before_allocation): ..
* emultempl/xtensaelf.em (ld_assign_relative_paged_dot,
ld_local_file_relocations_fit, ld_xtensa_insert_page_offsets): Use
"size" instead of "_raw_size" and "_cooked_size". Expand
bfd_section_size macro invocations.
2004-06-24 06:46:28 +02:00
|
|
|
long size = s->size;
|
1999-05-03 09:29:11 +02:00
|
|
|
char *buf = xmalloc (size);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_get_section_contents (b, s, buf, 0, size);
|
|
|
|
def_file_add_directive (pe_def_file, buf, size);
|
|
|
|
free (buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-19 18:08:08 +02:00
|
|
|
/* Process aligned common symbol information from the
|
|
|
|
.drectve sections now; common symbol allocation is
|
|
|
|
done before final link, so it will be too late to
|
|
|
|
process them in process_embedded_commands() called
|
|
|
|
from _bfd_coff_link_input_bfd(). */
|
|
|
|
if (pe_def_file->aligncomms)
|
|
|
|
{
|
|
|
|
def_file_aligncomm *ac = pe_def_file->aligncomms;
|
|
|
|
while (ac)
|
|
|
|
{
|
|
|
|
struct coff_link_hash_entry *sym_hash;
|
|
|
|
sym_hash = coff_link_hash_lookup (coff_hash_table (info),
|
|
|
|
ac->symbol_name, FALSE, FALSE, FALSE);
|
|
|
|
if (sym_hash && sym_hash->root.type == bfd_link_hash_common
|
|
|
|
&& sym_hash->root.u.c.p->alignment_power < (unsigned) ac->alignment)
|
|
|
|
{
|
|
|
|
sym_hash->root.u.c.p->alignment_power = (unsigned) ac->alignment;
|
|
|
|
}
|
|
|
|
ac = ac->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-16 17:15:39 +02:00
|
|
|
/* If we are building an executable and there is nothing
|
|
|
|
to export, we do not build an export table at all. */
|
|
|
|
if (info->executable && pe_def_file->num_exports == 0
|
|
|
|
&& (!pe_dll_export_everything || pe_dll_exclude_all_symbols))
|
2003-04-02 19:39:24 +02:00
|
|
|
return;
|
|
|
|
|
2000-10-09 09:01:29 +02:00
|
|
|
/* Now, maybe export everything else the default way. */
|
2009-10-16 17:15:39 +02:00
|
|
|
if ((pe_dll_export_everything || pe_def_file->num_exports == 0)
|
|
|
|
&& !pe_dll_exclude_all_symbols)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
for (b = info->input_bfds; b; b = b->link_next)
|
|
|
|
{
|
|
|
|
asymbol **symbols;
|
2008-08-17 05:12:50 +02:00
|
|
|
int nsyms;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2008-08-17 05:12:50 +02:00
|
|
|
if (!bfd_generic_link_read_symbols (b))
|
|
|
|
{
|
|
|
|
einfo (_("%B%F: could not read symbols: %E\n"), b);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
symbols = bfd_get_outsymbols (b);
|
|
|
|
nsyms = bfd_get_symcount (b);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
for (j = 0; j < nsyms; j++)
|
|
|
|
{
|
2000-10-09 03:37:11 +02:00
|
|
|
/* We should export symbols which are either global or not
|
2003-06-28 07:28:54 +02:00
|
|
|
anything at all. (.bss data is the latter)
|
|
|
|
We should not export undefined symbols. */
|
2012-05-05 05:05:32 +02:00
|
|
|
bfd_boolean would_export
|
|
|
|
= (symbols[j]->section != bfd_und_section_ptr
|
|
|
|
&& ((symbols[j]->flags & BSF_GLOBAL)
|
|
|
|
|| (symbols[j]->flags == 0)));
|
2011-09-16 03:15:20 +02:00
|
|
|
if (link_info.version_info && would_export)
|
|
|
|
would_export
|
|
|
|
= !bfd_hide_sym_by_version (link_info.version_info,
|
|
|
|
symbols[j]->name);
|
2009-05-04 14:09:30 +02:00
|
|
|
if (would_export)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
const char *sn = symbols[j]->name;
|
2001-08-03 01:12:02 +02:00
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* We should not re-export imported stuff. */
|
2001-08-03 01:12:02 +02:00
|
|
|
{
|
2006-11-01 01:48:25 +01:00
|
|
|
char *name;
|
2006-10-03 12:06:26 +02:00
|
|
|
if (is_import (sn))
|
|
|
|
continue;
|
|
|
|
|
2006-11-01 01:48:25 +01:00
|
|
|
name = xmalloc (strlen ("__imp_") + strlen (sn) + 1);
|
2006-10-03 12:06:26 +02:00
|
|
|
sprintf (name, "%s%s", "__imp_", sn);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2001-08-03 01:12:02 +02:00
|
|
|
blhe = bfd_link_hash_lookup (info->hash, name,
|
2002-11-30 09:39:46 +01:00
|
|
|
FALSE, FALSE, FALSE);
|
2001-08-03 01:12:02 +02:00
|
|
|
free (name);
|
|
|
|
|
2002-05-03 15:48:55 +02:00
|
|
|
if (blhe && blhe->type == bfd_link_hash_defined)
|
2001-08-03 01:12:02 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2006-10-03 12:06:26 +02:00
|
|
|
if (pe_details->underscored && *sn == '_')
|
1999-05-03 09:29:11 +02:00
|
|
|
sn++;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2001-08-03 01:12:02 +02:00
|
|
|
if (auto_export (b, pe_def_file, sn))
|
|
|
|
{
|
2011-04-13 14:53:36 +02:00
|
|
|
int is_dup = 0;
|
2001-08-03 01:12:02 +02:00
|
|
|
def_file_export *p;
|
2012-02-11 20:25:12 +01:00
|
|
|
|
2011-04-13 14:53:36 +02:00
|
|
|
p = def_file_add_export (pe_def_file, sn, 0, -1,
|
|
|
|
NULL, &is_dup);
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Fill data flag properly, from dlltool.c. */
|
2011-04-13 14:53:36 +02:00
|
|
|
if (!is_dup)
|
|
|
|
p->flag_data = !(symbols[j]->flags & BSF_FUNCTION);
|
2001-08-03 01:12:02 +02:00
|
|
|
}
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef NE
|
|
|
|
#define NE pe_def_file->num_exports
|
|
|
|
|
2009-05-17 07:10:21 +02:00
|
|
|
/* Don't create an empty export table. */
|
|
|
|
if (NE == 0)
|
|
|
|
return;
|
|
|
|
|
2012-02-11 20:25:12 +01:00
|
|
|
resort_needed = FALSE;
|
|
|
|
|
2000-10-09 09:01:29 +02:00
|
|
|
/* Canonicalize the export list. */
|
1999-05-03 09:29:11 +02:00
|
|
|
if (pe_dll_kill_ats)
|
|
|
|
{
|
|
|
|
for (i = 0; i < NE; i++)
|
|
|
|
{
|
|
|
|
if (strchr (pe_def_file->exports[i].name, '@'))
|
|
|
|
{
|
2000-10-09 09:01:29 +02:00
|
|
|
/* This will preserve internal_name, which may have been
|
2003-06-28 07:28:54 +02:00
|
|
|
pointing to the same memory as name, or might not
|
|
|
|
have. */
|
|
|
|
int lead_at = (*pe_def_file->exports[i].name == '@');
|
2002-11-06 20:36:20 +01:00
|
|
|
char *tmp = xstrdup (pe_def_file->exports[i].name + lead_at);
|
2006-01-31 23:08:14 +01:00
|
|
|
char *tmp_at = strchr (tmp, '@');
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2006-01-31 23:08:14 +01:00
|
|
|
if (tmp_at)
|
|
|
|
*tmp_at = 0;
|
|
|
|
else
|
|
|
|
einfo (_("%XCannot export %s: invalid export name\n"),
|
|
|
|
pe_def_file->exports[i].name);
|
1999-05-03 09:29:11 +02:00
|
|
|
pe_def_file->exports[i].name = tmp;
|
2012-02-11 20:25:12 +01:00
|
|
|
resort_needed = TRUE;
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-11 20:25:12 +01:00
|
|
|
/* Re-sort the exports table as we have possibly changed the order
|
|
|
|
by removing leading @. */
|
|
|
|
if (resort_needed)
|
|
|
|
qsort (pe_def_file->exports, NE, sizeof (pe_def_file->exports[0]),
|
|
|
|
pe_export_sort);
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (pe_dll_stdcall_aliases)
|
|
|
|
{
|
|
|
|
for (i = 0; i < NE; i++)
|
|
|
|
{
|
2006-10-03 12:06:26 +02:00
|
|
|
if (is_import (pe_def_file->exports[i].name))
|
|
|
|
continue;
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (strchr (pe_def_file->exports[i].name, '@'))
|
|
|
|
{
|
2011-04-13 14:53:36 +02:00
|
|
|
int is_dup = 1;
|
2003-06-28 07:28:54 +02:00
|
|
|
int lead_at = (*pe_def_file->exports[i].name == '@');
|
2002-11-06 20:36:20 +01:00
|
|
|
char *tmp = xstrdup (pe_def_file->exports[i].name + lead_at);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
*(strchr (tmp, '@')) = 0;
|
2001-08-03 01:12:02 +02:00
|
|
|
if (auto_export (NULL, pe_def_file, tmp))
|
1999-05-03 09:29:11 +02:00
|
|
|
def_file_add_export (pe_def_file, tmp,
|
2001-08-03 01:12:02 +02:00
|
|
|
pe_def_file->exports[i].internal_name,
|
2011-04-13 14:53:36 +02:00
|
|
|
-1, NULL, &is_dup);
|
|
|
|
if (is_dup)
|
|
|
|
free (tmp);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-10-09 09:01:29 +02:00
|
|
|
/* Convenience, but watch out for it changing. */
|
|
|
|
e = pe_def_file->exports;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
for (i = 0, j = 0; i < NE; i++)
|
|
|
|
{
|
|
|
|
if (i > 0 && strcmp (e[i].name, e[i - 1].name) == 0)
|
|
|
|
{
|
2000-01-05 00:44:03 +01:00
|
|
|
/* This is a duplicate. */
|
1999-05-03 09:29:11 +02:00
|
|
|
if (e[j - 1].ordinal != -1
|
|
|
|
&& e[i].ordinal != -1
|
|
|
|
&& e[j - 1].ordinal != e[i].ordinal)
|
|
|
|
{
|
2000-01-05 00:44:03 +01:00
|
|
|
if (pe_dll_warn_dup_exports)
|
|
|
|
/* xgettext:c-format */
|
2000-10-02 16:39:46 +02:00
|
|
|
einfo (_("%XError, duplicate EXPORT with ordinals: %s (%d vs %d)\n"),
|
2000-01-05 00:44:03 +01:00
|
|
|
e[j - 1].name, e[j - 1].ordinal, e[i].ordinal);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2000-01-05 00:44:03 +01:00
|
|
|
if (pe_dll_warn_dup_exports)
|
|
|
|
/* xgettext:c-format */
|
|
|
|
einfo (_("Warning, duplicate EXPORT: %s\n"),
|
|
|
|
e[j - 1].name);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2000-10-02 16:39:46 +02:00
|
|
|
if (e[i].ordinal != -1)
|
1999-05-03 09:29:11 +02:00
|
|
|
e[j - 1].ordinal = e[i].ordinal;
|
|
|
|
e[j - 1].flag_private |= e[i].flag_private;
|
|
|
|
e[j - 1].flag_constant |= e[i].flag_constant;
|
|
|
|
e[j - 1].flag_noname |= e[i].flag_noname;
|
|
|
|
e[j - 1].flag_data |= e[i].flag_data;
|
2012-02-19 22:18:08 +01:00
|
|
|
if (e[i].name)
|
|
|
|
free (e[i].name);
|
|
|
|
if (e[i].internal_name)
|
|
|
|
free (e[i].internal_name);
|
|
|
|
if (e[i].its_name)
|
|
|
|
free (e[i].its_name);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (i != j)
|
|
|
|
e[j] = e[i];
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pe_def_file->num_exports = j; /* == NE */
|
|
|
|
|
2012-02-19 22:18:08 +01:00
|
|
|
exported_symbol_offsets = xmalloc (NE * sizeof (bfd_vma));
|
|
|
|
exported_symbol_sections = xmalloc (NE * sizeof (struct bfd_section *));
|
|
|
|
|
|
|
|
memset (exported_symbol_sections, 0, NE * sizeof (struct bfd_section *));
|
|
|
|
max_ordinal = 0;
|
|
|
|
min_ordinal = 65536;
|
|
|
|
count_exported = 0;
|
|
|
|
count_exported_byname = 0;
|
|
|
|
count_with_ordinals = 0;
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
for (i = 0; i < NE; i++)
|
|
|
|
{
|
2003-06-28 07:28:54 +02:00
|
|
|
char *name;
|
|
|
|
name = xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2);
|
2002-11-06 20:36:20 +01:00
|
|
|
if (pe_details->underscored
|
|
|
|
&& (*pe_def_file->exports[i].internal_name != '@'))
|
1999-05-11 23:06:50 +02:00
|
|
|
{
|
|
|
|
*name = '_';
|
|
|
|
strcpy (name + 1, pe_def_file->exports[i].internal_name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
strcpy (name, pe_def_file->exports[i].internal_name);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
blhe = bfd_link_hash_lookup (info->hash,
|
|
|
|
name,
|
2002-11-30 09:39:46 +01:00
|
|
|
FALSE, FALSE, TRUE);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
1999-09-29 02:31:40 +02:00
|
|
|
if (blhe
|
2000-10-09 03:37:11 +02:00
|
|
|
&& (blhe->type == bfd_link_hash_defined
|
1999-09-29 02:31:40 +02:00
|
|
|
|| (blhe->type == bfd_link_hash_common)))
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
count_exported++;
|
|
|
|
if (!pe_def_file->exports[i].flag_noname)
|
|
|
|
count_exported_byname++;
|
1999-09-29 02:31:40 +02:00
|
|
|
|
|
|
|
/* Only fill in the sections. The actual offsets are computed
|
|
|
|
in fill_exported_offsets() after common symbols are laid
|
|
|
|
out. */
|
2000-10-09 03:37:11 +02:00
|
|
|
if (blhe->type == bfd_link_hash_defined)
|
1999-09-29 02:31:40 +02:00
|
|
|
exported_symbol_sections[i] = blhe->u.def.section;
|
|
|
|
else
|
|
|
|
exported_symbol_sections[i] = blhe->u.c.p->section;
|
2000-09-29 15:21:41 +02:00
|
|
|
|
2010-06-09 20:17:10 +02:00
|
|
|
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;
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
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++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (blhe && blhe->type == bfd_link_hash_undefined)
|
|
|
|
{
|
|
|
|
/* xgettext:c-format */
|
|
|
|
einfo (_("%XCannot export %s: symbol not defined\n"),
|
|
|
|
pe_def_file->exports[i].internal_name);
|
|
|
|
}
|
|
|
|
else if (blhe)
|
|
|
|
{
|
|
|
|
/* xgettext:c-format */
|
|
|
|
einfo (_("%XCannot export %s: symbol wrong type (%d vs %d)\n"),
|
|
|
|
pe_def_file->exports[i].internal_name,
|
|
|
|
blhe->type, bfd_link_hash_defined);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* xgettext:c-format */
|
|
|
|
einfo (_("%XCannot export %s: symbol not found\n"),
|
|
|
|
pe_def_file->exports[i].internal_name);
|
|
|
|
}
|
|
|
|
free (name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Build the bfd that will contain .edata and .reloc sections. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
static void
|
2003-06-28 07:28:54 +02:00
|
|
|
build_filler_bfd (int include_edata)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
lang_input_statement_type *filler_file;
|
|
|
|
filler_file = lang_add_input_file ("dll stuff",
|
|
|
|
lang_input_file_is_fake_enum,
|
|
|
|
NULL);
|
2008-02-15 04:35:53 +01:00
|
|
|
filler_file->the_bfd = filler_bfd = bfd_create ("dll stuff",
|
|
|
|
link_info.output_bfd);
|
1999-05-03 09:29:11 +02:00
|
|
|
if (filler_bfd == NULL
|
|
|
|
|| !bfd_set_arch_mach (filler_bfd,
|
2008-02-15 04:35:53 +01:00
|
|
|
bfd_get_arch (link_info.output_bfd),
|
|
|
|
bfd_get_mach (link_info.output_bfd)))
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
2005-12-08 12:38:25 +01:00
|
|
|
einfo ("%X%P: can not create BFD: %E\n");
|
1999-05-03 09:29:11 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
1999-05-11 23:06:50 +02:00
|
|
|
if (include_edata)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
1999-05-11 23:06:50 +02:00
|
|
|
edata_s = bfd_make_section_old_way (filler_bfd, ".edata");
|
|
|
|
if (edata_s == NULL
|
|
|
|
|| !bfd_set_section_flags (filler_bfd, edata_s,
|
|
|
|
(SEC_HAS_CONTENTS
|
|
|
|
| SEC_ALLOC
|
|
|
|
| SEC_LOAD
|
|
|
|
| SEC_KEEP
|
|
|
|
| SEC_IN_MEMORY)))
|
|
|
|
{
|
|
|
|
einfo ("%X%P: can not create .edata section: %E\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
bfd_set_section_size (filler_bfd, edata_s, edata_sz);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
reloc_s = bfd_make_section_old_way (filler_bfd, ".reloc");
|
|
|
|
if (reloc_s == NULL
|
|
|
|
|| !bfd_set_section_flags (filler_bfd, reloc_s,
|
|
|
|
(SEC_HAS_CONTENTS
|
|
|
|
| SEC_ALLOC
|
|
|
|
| SEC_LOAD
|
|
|
|
| SEC_KEEP
|
|
|
|
| SEC_IN_MEMORY)))
|
|
|
|
{
|
|
|
|
einfo ("%X%P: can not create .reloc section: %E\n");
|
|
|
|
return;
|
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_set_section_size (filler_bfd, reloc_s, 0);
|
|
|
|
|
|
|
|
ldlang_add_file (filler_file);
|
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Gather all the exported symbols and build the .edata section. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
static void
|
2003-06-28 07:28:54 +02:00
|
|
|
generate_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
int i, next_ordinal;
|
|
|
|
int name_table_size = 0;
|
|
|
|
const char *dlnp;
|
|
|
|
|
|
|
|
/* First, we need to know how many exported symbols there are,
|
2000-09-29 15:21:41 +02:00
|
|
|
and what the range of ordinals is. */
|
1999-05-03 09:29:11 +02:00
|
|
|
if (pe_def_file->name)
|
2001-09-14 16:19:05 +02:00
|
|
|
dll_name = pe_def_file->name;
|
1999-05-03 09:29:11 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
dll_name = abfd->filename;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
for (dlnp = dll_name; *dlnp; dlnp++)
|
2001-09-14 16:19:05 +02:00
|
|
|
if (*dlnp == '\\' || *dlnp == '/' || *dlnp == ':')
|
|
|
|
dll_name = dlnp + 1;
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (count_with_ordinals && max_ordinal > count_exported)
|
|
|
|
{
|
|
|
|
if (min_ordinal > max_ordinal - count_exported + 1)
|
|
|
|
min_ordinal = max_ordinal - count_exported + 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
min_ordinal = 1;
|
|
|
|
max_ordinal = count_exported;
|
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
export_table_size = max_ordinal - min_ordinal + 1;
|
2003-06-28 07:28:54 +02:00
|
|
|
exported_symbols = xmalloc (export_table_size * sizeof (int));
|
1999-05-03 09:29:11 +02:00
|
|
|
for (i = 0; i < export_table_size; i++)
|
|
|
|
exported_symbols[i] = -1;
|
|
|
|
|
2000-10-09 09:01:29 +02:00
|
|
|
/* Now we need to assign ordinals to those that don't have them. */
|
1999-05-03 09:29:11 +02:00
|
|
|
for (i = 0; i < NE; i++)
|
|
|
|
{
|
2006-01-31 23:08:14 +01:00
|
|
|
if (exported_symbol_sections[i] ||
|
|
|
|
pe_def_file->exports[i].flag_forward)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
if (pe_def_file->exports[i].ordinal != -1)
|
|
|
|
{
|
|
|
|
int ei = pe_def_file->exports[i].ordinal - min_ordinal;
|
|
|
|
int pi = exported_symbols[ei];
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (pi != -1)
|
|
|
|
{
|
|
|
|
/* xgettext:c-format */
|
2000-10-02 16:39:46 +02:00
|
|
|
einfo (_("%XError, ordinal used twice: %d (%s vs %s)\n"),
|
1999-05-03 09:29:11 +02:00
|
|
|
pe_def_file->exports[i].ordinal,
|
|
|
|
pe_def_file->exports[i].name,
|
|
|
|
pe_def_file->exports[pi].name);
|
|
|
|
}
|
|
|
|
exported_symbols[ei] = i;
|
|
|
|
}
|
2009-10-23 13:40:17 +02:00
|
|
|
if (pe_def_file->exports[i].its_name)
|
|
|
|
name_table_size += strlen (pe_def_file->exports[i].its_name) + 1;
|
|
|
|
else
|
|
|
|
name_table_size += strlen (pe_def_file->exports[i].name) + 1;
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
2006-01-31 23:08:14 +01:00
|
|
|
|
|
|
|
/* Reserve space for the forward name. */
|
|
|
|
if (pe_def_file->exports[i].flag_forward)
|
|
|
|
{
|
|
|
|
name_table_size += strlen (pe_def_file->exports[i].internal_name) + 1;
|
|
|
|
}
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
next_ordinal = min_ordinal;
|
|
|
|
for (i = 0; i < NE; i++)
|
2006-01-31 23:08:14 +01:00
|
|
|
if ((exported_symbol_sections[i] ||
|
|
|
|
pe_def_file->exports[i].flag_forward) &&
|
|
|
|
pe_def_file->exports[i].ordinal == -1)
|
|
|
|
{
|
|
|
|
while (exported_symbols[next_ordinal - min_ordinal] != -1)
|
|
|
|
next_ordinal++;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2006-01-31 23:08:14 +01:00
|
|
|
exported_symbols[next_ordinal - min_ordinal] = i;
|
|
|
|
pe_def_file->exports[i].ordinal = next_ordinal;
|
|
|
|
}
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2000-10-09 09:01:29 +02:00
|
|
|
/* OK, now we can allocate some memory. */
|
2001-09-14 16:19:05 +02:00
|
|
|
edata_sz = (40 /* directory */
|
|
|
|
+ 4 * export_table_size /* addresses */
|
1999-05-03 09:29:11 +02:00
|
|
|
+ 4 * count_exported_byname /* name ptrs */
|
|
|
|
+ 2 * count_exported_byname /* ordinals */
|
|
|
|
+ name_table_size + strlen (dll_name) + 1);
|
|
|
|
}
|
|
|
|
|
1999-09-29 02:31:40 +02:00
|
|
|
/* Fill the exported symbol offsets. The preliminary work has already
|
2009-05-19 18:08:08 +02:00
|
|
|
been done in process_def_file_and_drectve(). */
|
1999-09-29 02:31:40 +02:00
|
|
|
|
|
|
|
static void
|
2003-06-28 07:28:54 +02:00
|
|
|
fill_exported_offsets (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
1999-09-29 02:31:40 +02:00
|
|
|
{
|
2000-03-01 21:54:37 +01:00
|
|
|
int i;
|
1999-09-29 02:31:40 +02:00
|
|
|
struct bfd_link_hash_entry *blhe;
|
2000-09-29 15:21:41 +02:00
|
|
|
|
1999-09-29 02:31:40 +02:00
|
|
|
for (i = 0; i < pe_def_file->num_exports; i++)
|
|
|
|
{
|
2003-06-28 07:28:54 +02:00
|
|
|
char *name;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
name = xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2);
|
2002-11-06 20:36:20 +01:00
|
|
|
if (pe_details->underscored
|
2003-06-28 07:28:54 +02:00
|
|
|
&& *pe_def_file->exports[i].internal_name != '@')
|
1999-09-29 02:31:40 +02:00
|
|
|
{
|
|
|
|
*name = '_';
|
|
|
|
strcpy (name + 1, pe_def_file->exports[i].internal_name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
strcpy (name, pe_def_file->exports[i].internal_name);
|
|
|
|
|
|
|
|
blhe = bfd_link_hash_lookup (info->hash,
|
|
|
|
name,
|
2002-11-30 09:39:46 +01:00
|
|
|
FALSE, FALSE, TRUE);
|
1999-09-29 02:31:40 +02:00
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
if (blhe && blhe->type == bfd_link_hash_defined)
|
2001-09-14 16:19:05 +02:00
|
|
|
exported_symbol_offsets[i] = blhe->u.def.value;
|
|
|
|
|
1999-09-29 02:31:40 +02:00
|
|
|
free (name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
static void
|
2003-06-28 07:28:54 +02:00
|
|
|
fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
2003-06-02 10:43:37 +02:00
|
|
|
int s, hint;
|
1999-05-03 09:29:11 +02:00
|
|
|
unsigned char *edirectory;
|
2004-04-29 15:05:49 +02:00
|
|
|
unsigned char *eaddresses;
|
|
|
|
unsigned char *enameptrs;
|
|
|
|
unsigned char *eordinals;
|
2005-02-23 13:30:48 +01:00
|
|
|
char *enamestr;
|
1999-05-03 09:29:11 +02:00
|
|
|
time_t now;
|
|
|
|
|
|
|
|
time (&now);
|
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
edata_d = xmalloc (edata_sz);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2000-10-09 09:01:29 +02:00
|
|
|
/* Note use of array pointer math here. */
|
1999-05-03 09:29:11 +02:00
|
|
|
edirectory = edata_d;
|
2010-06-27 06:07:55 +02:00
|
|
|
eaddresses = edirectory + 40;
|
2004-04-29 15:05:49 +02:00
|
|
|
enameptrs = eaddresses + 4 * export_table_size;
|
|
|
|
eordinals = enameptrs + 4 * count_exported_byname;
|
2005-02-23 13:30:48 +01:00
|
|
|
enamestr = (char *) eordinals + 2 * count_exported_byname;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
#define ERVA(ptr) (((unsigned char *)(ptr) - edata_d) \
|
|
|
|
+ edata_s->output_section->vma - image_base)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2000-10-04 00:07:17 +02:00
|
|
|
memset (edata_d, 0, edata_sz);
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_put_32 (abfd, now, edata_d + 4);
|
|
|
|
if (pe_def_file->version_major != -1)
|
|
|
|
{
|
|
|
|
bfd_put_16 (abfd, pe_def_file->version_major, edata_d + 8);
|
|
|
|
bfd_put_16 (abfd, pe_def_file->version_minor, edata_d + 10);
|
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_put_32 (abfd, ERVA (enamestr), edata_d + 12);
|
|
|
|
strcpy (enamestr, dll_name);
|
|
|
|
enamestr += strlen (enamestr) + 1;
|
|
|
|
bfd_put_32 (abfd, min_ordinal, edata_d + 16);
|
|
|
|
bfd_put_32 (abfd, export_table_size, edata_d + 20);
|
|
|
|
bfd_put_32 (abfd, count_exported_byname, edata_d + 24);
|
|
|
|
bfd_put_32 (abfd, ERVA (eaddresses), edata_d + 28);
|
|
|
|
bfd_put_32 (abfd, ERVA (enameptrs), edata_d + 32);
|
|
|
|
bfd_put_32 (abfd, ERVA (eordinals), edata_d + 36);
|
|
|
|
|
1999-09-29 02:31:40 +02:00
|
|
|
fill_exported_offsets (abfd, info);
|
|
|
|
|
2003-06-02 10:43:37 +02:00
|
|
|
/* Ok, now for the filling in part.
|
|
|
|
Scan alphabetically - ie the ordering in the exports[] table,
|
|
|
|
rather than by ordinal - the ordering in the exported_symbol[]
|
|
|
|
table. See dlltool.c and:
|
|
|
|
http://sources.redhat.com/ml/binutils/2003-04/msg00379.html
|
2003-06-28 07:28:54 +02:00
|
|
|
for more information. */
|
1999-05-03 09:29:11 +02:00
|
|
|
hint = 0;
|
2003-06-02 10:43:37 +02:00
|
|
|
for (s = 0; s < NE; s++)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
2004-02-25 22:00:32 +01:00
|
|
|
struct bfd_section *ssec = exported_symbol_sections[s];
|
2006-01-31 23:08:14 +01:00
|
|
|
if (pe_def_file->exports[s].ordinal != -1 &&
|
|
|
|
(pe_def_file->exports[s].flag_forward || ssec != NULL))
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
2000-09-28 22:53:40 +02:00
|
|
|
int ord = pe_def_file->exports[s].ordinal;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2006-01-31 23:08:14 +01:00
|
|
|
if (pe_def_file->exports[s].flag_forward)
|
|
|
|
{
|
|
|
|
bfd_put_32 (abfd, ERVA (enamestr),
|
|
|
|
eaddresses + 4 * (ord - min_ordinal));
|
|
|
|
|
|
|
|
strcpy (enamestr, pe_def_file->exports[s].internal_name);
|
|
|
|
enamestr += strlen (pe_def_file->exports[s].internal_name) + 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-05-27 10:34:26 +02:00
|
|
|
bfd_vma srva = (exported_symbol_offsets[s]
|
2006-01-31 23:08:14 +01:00
|
|
|
+ ssec->output_section->vma
|
|
|
|
+ ssec->output_offset);
|
|
|
|
|
|
|
|
bfd_put_32 (abfd, srva - image_base,
|
|
|
|
eaddresses + 4 * (ord - min_ordinal));
|
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (!pe_def_file->exports[s].flag_noname)
|
|
|
|
{
|
|
|
|
char *ename = pe_def_file->exports[s].name;
|
2009-10-23 13:40:17 +02:00
|
|
|
if (pe_def_file->exports[s].its_name)
|
|
|
|
ename = pe_def_file->exports[s].its_name;
|
2003-06-02 10:43:37 +02:00
|
|
|
|
2004-04-29 15:05:49 +02:00
|
|
|
bfd_put_32 (abfd, ERVA (enamestr), enameptrs);
|
|
|
|
enameptrs += 4;
|
1999-05-03 09:29:11 +02:00
|
|
|
strcpy (enamestr, ename);
|
|
|
|
enamestr += strlen (enamestr) + 1;
|
2004-04-29 15:05:49 +02:00
|
|
|
bfd_put_16 (abfd, ord - min_ordinal, eordinals);
|
|
|
|
eordinals += 2;
|
1999-05-03 09:29:11 +02:00
|
|
|
pe_def_file->exports[s].hint = hint++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-08-03 01:12:02 +02:00
|
|
|
|
2003-10-19 Andrew Cagney <cagney@redhat.com>
* targets.c: Replace "struct sec" with "struct bfd_section"
* syms.c, sparclynx.c, section.c, opncls.c: Ditto.
* libcoff-in.h, libbfd-in.h, elfxx-target.h: Ditto.
* elf.c, coffgen.c, bfd.c, bfd-in.h, aoutf1.h: Ditto.
* aout-tic30.c, aout-target.h:
* bfd-in2.h, libcoff.h, libbfd.h: Regenerate.
Index: binutils/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* coffgrok.h (coff_section): Replace 'struct sec" with "struct
bfd_section".
Index: gdb/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* symtab.c: Replace "struct sec" with "struct bfd_section".
* objfiles.c, linespec.c, blockframe.c, block.c: Ditto.
Index: ld/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* pe-dll.c: Replace "struct sec" with "struct bfd_section".
Index: sim/common/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* sim-base.h: Replace "struct sec" with "struct bfd_section".
2003-10-20 16:38:46 +02:00
|
|
|
static struct bfd_section *current_sec;
|
2001-08-03 01:12:02 +02:00
|
|
|
|
|
|
|
void
|
2003-06-28 07:28:54 +02:00
|
|
|
pe_walk_relocs_of_symbol (struct bfd_link_info *info,
|
|
|
|
const char *name,
|
|
|
|
int (*cb) (arelent *, asection *))
|
2001-08-03 01:12:02 +02:00
|
|
|
{
|
|
|
|
bfd *b;
|
2001-09-12 17:58:10 +02:00
|
|
|
asection *s;
|
2001-08-03 01:12:02 +02:00
|
|
|
|
|
|
|
for (b = info->input_bfds; b; b = b->link_next)
|
|
|
|
{
|
2001-09-14 16:19:05 +02:00
|
|
|
asymbol **symbols;
|
|
|
|
|
2008-08-17 05:12:50 +02:00
|
|
|
if (!bfd_generic_link_read_symbols (b))
|
|
|
|
{
|
|
|
|
einfo (_("%B%F: could not read symbols: %E\n"), b);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
symbols = bfd_get_outsymbols (b);
|
2001-08-03 01:12:02 +02:00
|
|
|
|
|
|
|
for (s = b->sections; s; s = s->next)
|
|
|
|
{
|
2001-09-14 16:19:05 +02:00
|
|
|
arelent **relocs;
|
|
|
|
int relsize, nrelocs, i;
|
2001-08-03 01:12:02 +02:00
|
|
|
int flags = bfd_get_section_flags (b, s);
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Skip discarded linkonce sections. */
|
2001-08-03 01:12:02 +02:00
|
|
|
if (flags & SEC_LINK_ONCE
|
|
|
|
&& s->output_section == bfd_abs_section_ptr)
|
|
|
|
continue;
|
|
|
|
|
2001-09-12 17:58:10 +02:00
|
|
|
current_sec = s;
|
2001-08-03 01:12:02 +02:00
|
|
|
|
|
|
|
relsize = bfd_get_reloc_upper_bound (b, s);
|
2003-06-28 07:28:54 +02:00
|
|
|
relocs = xmalloc (relsize);
|
2001-08-03 01:12:02 +02:00
|
|
|
nrelocs = bfd_canonicalize_reloc (b, s, relocs, symbols);
|
|
|
|
|
|
|
|
for (i = 0; i < nrelocs; i++)
|
|
|
|
{
|
Index: sim/frv/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* traps.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
Index: sim/d10v/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* simops.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
Index: sim/common/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* sim-trace.c, sim-base.h: Replace "struct symbol_cache_entry"
with "struct bfd_symbol".
Index: ld/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* emultempl/pe.em, pe-dll.c: Replace "struct symbol_cache_entry"
with "struct bfd_symbol".
Index: bfd/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* syms.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
* vms.h, targets.c, section.c, reloc.c, peicode.h: Ditto.
* mipsbsd.c, elf.c, linker.c, elf-bfd.h, ecoff.c: Ditto.
* cpu-z8k.c, cpu-ns32k.c, cpu-h8500.c, bfd.c, bfd-in.h: Ditto.
* bfd-in2.h: Re-generate.
2003-10-31 06:32:46 +01:00
|
|
|
struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
|
|
|
if (!strcmp (name, sym->name))
|
|
|
|
cb (relocs[i], s);
|
2001-08-03 01:12:02 +02:00
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2001-08-03 01:12:02 +02:00
|
|
|
free (relocs);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2001-08-03 01:12:02 +02:00
|
|
|
/* Warning: the allocated symbols are remembered in BFD and reused
|
|
|
|
later, so don't free them! */
|
|
|
|
/* free (symbols); */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Gather all the relocations and build the .reloc section. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
static void
|
2003-06-28 07:28:54 +02:00
|
|
|
generate_reloc (bfd *abfd, struct bfd_link_info *info)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
|
2000-10-09 09:01:29 +02:00
|
|
|
/* For .reloc stuff. */
|
1999-05-11 23:06:50 +02:00
|
|
|
reloc_data_type *reloc_data;
|
1999-05-03 09:29:11 +02:00
|
|
|
int total_relocs = 0;
|
|
|
|
int i;
|
2008-05-27 10:34:26 +02:00
|
|
|
bfd_vma sec_page = (bfd_vma) -1;
|
|
|
|
bfd_vma page_ptr, page_count;
|
1999-05-03 09:29:11 +02:00
|
|
|
int bi;
|
|
|
|
bfd *b;
|
2003-10-19 Andrew Cagney <cagney@redhat.com>
* targets.c: Replace "struct sec" with "struct bfd_section"
* syms.c, sparclynx.c, section.c, opncls.c: Ditto.
* libcoff-in.h, libbfd-in.h, elfxx-target.h: Ditto.
* elf.c, coffgen.c, bfd.c, bfd-in.h, aoutf1.h: Ditto.
* aout-tic30.c, aout-target.h:
* bfd-in2.h, libcoff.h, libbfd.h: Regenerate.
Index: binutils/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* coffgrok.h (coff_section): Replace 'struct sec" with "struct
bfd_section".
Index: gdb/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* symtab.c: Replace "struct sec" with "struct bfd_section".
* objfiles.c, linespec.c, blockframe.c, block.c: Ditto.
Index: ld/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* pe-dll.c: Replace "struct sec" with "struct bfd_section".
Index: sim/common/ChangeLog
2003-10-19 Andrew Cagney <cagney@redhat.com>
* sim-base.h: Replace "struct sec" with "struct bfd_section".
2003-10-20 16:38:46 +02:00
|
|
|
struct bfd_section *s;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
total_relocs = 0;
|
|
|
|
for (b = info->input_bfds; b; b = b->link_next)
|
|
|
|
for (s = b->sections; s; s = s->next)
|
|
|
|
total_relocs += s->reloc_count;
|
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
reloc_data = xmalloc (total_relocs * sizeof (reloc_data_type));
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
total_relocs = 0;
|
|
|
|
bi = 0;
|
|
|
|
for (bi = 0, b = info->input_bfds; b; bi++, b = b->link_next)
|
|
|
|
{
|
|
|
|
arelent **relocs;
|
2009-12-11 14:42:17 +01:00
|
|
|
int relsize, nrelocs;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
for (s = b->sections; s; s = s->next)
|
|
|
|
{
|
2008-05-27 10:34:26 +02:00
|
|
|
bfd_vma sec_vma = s->output_section->vma + s->output_offset;
|
1999-05-03 09:29:11 +02:00
|
|
|
asymbol **symbols;
|
|
|
|
|
2000-10-09 09:01:29 +02:00
|
|
|
/* If it's not loaded, we don't need to relocate it this way. */
|
1999-05-03 09:29:11 +02:00
|
|
|
if (!(s->output_section->flags & SEC_LOAD))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* I don't know why there would be a reloc for these, but I've
|
2000-10-09 09:01:29 +02:00
|
|
|
seen it happen - DJ */
|
2012-05-05 05:05:32 +02:00
|
|
|
if (s->output_section == bfd_abs_section_ptr)
|
1999-05-03 09:29:11 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (s->output_section->vma == 0)
|
|
|
|
{
|
2000-10-09 09:01:29 +02:00
|
|
|
/* Huh? Shouldn't happen, but punt if it does. */
|
1999-05-03 09:29:11 +02:00
|
|
|
einfo ("DJ: zero vma section reloc detected: `%s' #%d f=%d\n",
|
|
|
|
s->output_section->name, s->output_section->index,
|
|
|
|
s->output_section->flags);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2008-08-17 05:12:50 +02:00
|
|
|
if (!bfd_generic_link_read_symbols (b))
|
|
|
|
{
|
|
|
|
einfo (_("%B%F: could not read symbols: %E\n"), b);
|
|
|
|
return;
|
|
|
|
}
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2008-08-17 05:12:50 +02:00
|
|
|
symbols = bfd_get_outsymbols (b);
|
1999-05-03 09:29:11 +02:00
|
|
|
relsize = bfd_get_reloc_upper_bound (b, s);
|
2003-06-28 07:28:54 +02:00
|
|
|
relocs = xmalloc (relsize);
|
1999-05-03 09:29:11 +02:00
|
|
|
nrelocs = bfd_canonicalize_reloc (b, s, relocs, symbols);
|
|
|
|
|
|
|
|
for (i = 0; i < nrelocs; i++)
|
|
|
|
{
|
2001-08-03 01:12:02 +02:00
|
|
|
if (pe_dll_extra_pe_debug)
|
2002-05-03 15:48:55 +02:00
|
|
|
{
|
Index: sim/frv/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* traps.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
Index: sim/d10v/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* simops.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
Index: sim/common/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* sim-trace.c, sim-base.h: Replace "struct symbol_cache_entry"
with "struct bfd_symbol".
Index: ld/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* emultempl/pe.em, pe-dll.c: Replace "struct symbol_cache_entry"
with "struct bfd_symbol".
Index: bfd/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* syms.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
* vms.h, targets.c, section.c, reloc.c, peicode.h: Ditto.
* mipsbsd.c, elf.c, linker.c, elf-bfd.h, ecoff.c: Ditto.
* cpu-z8k.c, cpu-ns32k.c, cpu-h8500.c, bfd.c, bfd-in.h: Ditto.
* bfd-in2.h: Re-generate.
2003-10-31 06:32:46 +01:00
|
|
|
struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
|
2002-05-03 15:48:55 +02:00
|
|
|
printf ("rel: %s\n", sym->name);
|
2001-08-03 01:12:02 +02:00
|
|
|
}
|
1999-05-03 09:29:11 +02:00
|
|
|
if (!relocs[i]->howto->pc_relative
|
1999-05-11 23:06:50 +02:00
|
|
|
&& relocs[i]->howto->type != pe_details->imagebase_reloc)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
Index: sim/frv/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* traps.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
Index: sim/d10v/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* simops.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
Index: sim/common/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* sim-trace.c, sim-base.h: Replace "struct symbol_cache_entry"
with "struct bfd_symbol".
Index: ld/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* emultempl/pe.em, pe-dll.c: Replace "struct symbol_cache_entry"
with "struct bfd_symbol".
Index: bfd/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* syms.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
* vms.h, targets.c, section.c, reloc.c, peicode.h: Ditto.
* mipsbsd.c, elf.c, linker.c, elf-bfd.h, ecoff.c: Ditto.
* cpu-z8k.c, cpu-ns32k.c, cpu-h8500.c, bfd.c, bfd-in.h: Ditto.
* bfd-in2.h: Re-generate.
2003-10-31 06:32:46 +01:00
|
|
|
struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2010-05-15 16:20:06 +02:00
|
|
|
/* Don't create relocs for undefined weak symbols. */
|
2008-07-31 09:27:52 +02:00
|
|
|
if (sym->flags == BSF_WEAK)
|
|
|
|
{
|
|
|
|
struct bfd_link_hash_entry *blhe
|
2009-12-17 20:51:35 +01:00
|
|
|
= bfd_wrapped_link_hash_lookup (abfd, info, sym->name,
|
2008-07-31 09:27:52 +02:00
|
|
|
FALSE, FALSE, FALSE);
|
2009-12-17 20:51:35 +01:00
|
|
|
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
|
2012-05-05 05:05:32 +02:00
|
|
|
|| h2->root.u.def.section == bfd_abs_section_ptr)
|
2009-12-17 20:51:35 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (!blhe || blhe->type != bfd_link_hash_defined)
|
|
|
|
continue;
|
2008-07-31 09:27:52 +02:00
|
|
|
}
|
2011-10-13 04:34:36 +02:00
|
|
|
/* Nor for Dwarf FDE references to discarded sections. */
|
|
|
|
else if (bfd_is_abs_section (sym->section->output_section))
|
|
|
|
{
|
|
|
|
/* We only ignore relocs from .eh_frame sections, as
|
|
|
|
they are discarded by the final link rather than
|
|
|
|
resolved against the kept section. */
|
|
|
|
if (!strcmp (s->name, ".eh_frame"))
|
|
|
|
continue;
|
|
|
|
}
|
2008-07-31 09:27:52 +02:00
|
|
|
|
1999-05-11 23:06:50 +02:00
|
|
|
reloc_data[total_relocs].vma = sec_vma + relocs[i]->address;
|
2000-09-29 15:21:41 +02:00
|
|
|
|
2000-02-24 18:53:12 +01:00
|
|
|
#define BITS_AND_SHIFT(bits, shift) (bits * 1000 | shift)
|
2000-09-29 15:21:41 +02:00
|
|
|
|
2000-02-24 18:53:12 +01:00
|
|
|
switch BITS_AND_SHIFT (relocs[i]->howto->bitsize,
|
|
|
|
relocs[i]->howto->rightshift)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
2006-09-20 13:35:11 +02:00
|
|
|
#ifdef pe_use_x86_64
|
|
|
|
case BITS_AND_SHIFT (64, 0):
|
|
|
|
reloc_data[total_relocs].type = 10;
|
|
|
|
total_relocs++;
|
|
|
|
break;
|
|
|
|
#endif
|
2000-02-24 18:53:12 +01:00
|
|
|
case BITS_AND_SHIFT (32, 0):
|
1999-05-11 23:06:50 +02:00
|
|
|
reloc_data[total_relocs].type = 3;
|
|
|
|
total_relocs++;
|
1999-05-03 09:29:11 +02:00
|
|
|
break;
|
2000-02-24 18:53:12 +01:00
|
|
|
case BITS_AND_SHIFT (16, 0):
|
|
|
|
reloc_data[total_relocs].type = 2;
|
|
|
|
total_relocs++;
|
|
|
|
break;
|
|
|
|
case BITS_AND_SHIFT (16, 16):
|
|
|
|
reloc_data[total_relocs].type = 4;
|
2000-10-09 09:01:29 +02:00
|
|
|
/* FIXME: we can't know the symbol's right value
|
|
|
|
yet, but we probably can safely assume that
|
|
|
|
CE will relocate us in 64k blocks, so leaving
|
|
|
|
it zero is safe. */
|
2000-02-24 18:53:12 +01:00
|
|
|
reloc_data[total_relocs].extra = 0;
|
|
|
|
total_relocs++;
|
|
|
|
break;
|
|
|
|
case BITS_AND_SHIFT (26, 2):
|
|
|
|
reloc_data[total_relocs].type = 5;
|
|
|
|
total_relocs++;
|
|
|
|
break;
|
2003-06-17 14:05:33 +02:00
|
|
|
case BITS_AND_SHIFT (24, 2):
|
2003-12-05 12:30:18 +01:00
|
|
|
/* 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)
|
2003-06-17 14:05:33 +02:00
|
|
|
/* 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. */
|
|
|
|
break;
|
|
|
|
/* Fall through. */
|
1999-05-03 09:29:11 +02:00
|
|
|
default:
|
|
|
|
/* xgettext:c-format */
|
|
|
|
einfo (_("%XError: %d-bit reloc in dll\n"),
|
|
|
|
relocs[i]->howto->bitsize);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free (relocs);
|
2000-10-09 09:01:29 +02:00
|
|
|
/* Warning: the allocated symbols are remembered in BFD and
|
|
|
|
reused later, so don't free them! */
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* At this point, we have total_relocs relocation addresses in
|
|
|
|
reloc_addresses, which are all suitable for the .reloc section.
|
2000-09-29 15:21:41 +02:00
|
|
|
We must now create the new sections. */
|
1999-05-11 23:06:50 +02:00
|
|
|
qsort (reloc_data, total_relocs, sizeof (*reloc_data), reloc_sort);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
for (i = 0; i < total_relocs; i++)
|
|
|
|
{
|
2008-05-27 10:34:26 +02:00
|
|
|
bfd_vma this_page = (reloc_data[i].vma >> 12);
|
2000-09-29 15:21:41 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (this_page != sec_page)
|
|
|
|
{
|
2001-09-14 16:19:05 +02:00
|
|
|
reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align. */
|
1999-05-03 09:29:11 +02:00
|
|
|
reloc_sz += 8;
|
|
|
|
sec_page = this_page;
|
|
|
|
}
|
2000-09-29 15:21:41 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
reloc_sz += 2;
|
2000-09-29 15:21:41 +02:00
|
|
|
|
2000-02-24 18:53:12 +01:00
|
|
|
if (reloc_data[i].type == 4)
|
|
|
|
reloc_sz += 2;
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
2002-05-03 15:48:55 +02:00
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align. */
|
2003-06-28 07:28:54 +02:00
|
|
|
reloc_d = xmalloc (reloc_sz);
|
2008-05-27 10:34:26 +02:00
|
|
|
sec_page = (bfd_vma) -1;
|
1999-05-03 09:29:11 +02:00
|
|
|
reloc_sz = 0;
|
2008-05-27 10:34:26 +02:00
|
|
|
page_ptr = (bfd_vma) -1;
|
1999-05-03 09:29:11 +02:00
|
|
|
page_count = 0;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
for (i = 0; i < total_relocs; i++)
|
|
|
|
{
|
2008-05-27 10:34:26 +02:00
|
|
|
bfd_vma rva = reloc_data[i].vma - image_base;
|
|
|
|
bfd_vma this_page = (rva & ~0xfff);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (this_page != sec_page)
|
|
|
|
{
|
|
|
|
while (reloc_sz & 3)
|
|
|
|
reloc_d[reloc_sz++] = 0;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2008-05-27 10:34:26 +02:00
|
|
|
if (page_ptr != (bfd_vma) -1)
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_put_32 (abfd, this_page, reloc_d + reloc_sz);
|
|
|
|
page_ptr = reloc_sz;
|
|
|
|
reloc_sz += 8;
|
|
|
|
sec_page = this_page;
|
|
|
|
page_count = 0;
|
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2000-10-09 03:37:11 +02:00
|
|
|
bfd_put_16 (abfd, (rva & 0xfff) + (reloc_data[i].type << 12),
|
1999-05-11 23:06:50 +02:00
|
|
|
reloc_d + reloc_sz);
|
1999-05-03 09:29:11 +02:00
|
|
|
reloc_sz += 2;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-11 23:06:50 +02:00
|
|
|
if (reloc_data[i].type == 4)
|
|
|
|
{
|
|
|
|
bfd_put_16 (abfd, reloc_data[i].extra, reloc_d + reloc_sz);
|
|
|
|
reloc_sz += 2;
|
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
page_count++;
|
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
while (reloc_sz & 3)
|
|
|
|
reloc_d[reloc_sz++] = 0;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2008-05-27 10:34:26 +02:00
|
|
|
if (page_ptr != (bfd_vma) -1)
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
bfd/
* section.c (struct sec): Rename "_cooked_size" to "size".
Rename "_raw_size" to "rawsize".
(STD_SECTION): Adjust comments.
(bfd_set_section_size, bfd_get_section_contents): Use size.
(bfd_malloc_and_get_section): New function.
* bfd-in.h (bfd_section_size, bfd_get_section_size): Use size.
* coff-sh.c (sh_relax_section): Alloc coff_section_data struct early.
Correctly free reloc and contents memory.
* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Delete FIXME
and fake CIE now that we can shink section size to zero.
(_bfd_elf_write_section_eh_frame): Likewise..
* elf32-ppc.c (ppc_elf_relax_section): Delay reading section contents.
* elf-m10300.c (mn10300_elf_final_link_relocate): Don't use
_bfd_stab_section_offset. Use _bfd_elf_section_offset.
* stabs.c (_bfd_stab_section_offset_): Remove unused args and
unneeded indirection.
* elf.c (_bfd_elf_section_offset): .. and update call.
* libbfd-in.h (_bfd_stab_section_offset): Update prototype.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
Replace occurrences of "_raw_size" and "_cooked_size" in most places
with "size". Set new "rawsize" for stabs, eh_frame, and SEC_MERGE
sections. Use "rawsize", if non-zero, for bfd_get_section_contents
calls if the section might be a stabs, eh_frame, or SEC_MERGE section.
Similarly use "rawsize", if non-zero, in reloc functions to validate
reloc addresses. Use new bfd_malloc_and_get_section in most places
where bfd_get_section_contents was called. Expand all occurrences of
bfd_section_size and bfd_get_section_size. Rename "raw_size" var in
grok_prstatus and similar functions to "size".
* aix386-core.c (aix386_core_file_p): ..
* aix5ppc-core.c (xcoff64_core_p): ..
* aout-adobe.c (aout_adobe_callback, aout_adobe_write_object_contents,
aout_adobe_set_section_contents): ..
* aout-target.h (callback): ..
* aout-tic30.c (tic30_aout_callback, tic30_aout_final_link_relocate,
MY_bfd_final_link): ..
* aoutf1.h (sunos4_core_file_p): ..
* aoutx.h (some_aout_object_p, adjust_o_magic, adjust_z_magic,
adjust_n_magic, adjust_sizes_and_vmas, translate_from_native_sym_flags,
final_link, aout_link_input_section): ..
* binary.c (binary_object_p, binary_canonicalize_symtab,
binary_set_section_contents): ..
* bout.c (b_out_callback, b_out_write_object_contents,
b_out_set_section_contents, b_out_bfd_relax_section,
b_out_bfd_get_relocated_section_contents): ..
* cisco-core.c (cisco_core_file_validate): ..
* coff-alpha.c (alpha_ecoff_object_p,
alpha_ecoff_get_relocated_section_conten, alpha_relocate_section): ..
* coff-arm.c (coff_arm_relocate_section,
bfd_arm_allocate_interworking_sections): ..
* coff-h8300.c (h8300_reloc16_extra_cases,
h8300_bfd_link_add_symbols): ..
* coff-mips.c (mips_refhi_reloc, mips_gprel_reloc): ..
* coff-ppc.c (coff_ppc_relocate_section, ppc_allocate_toc_section,
ppc_bfd_coff_final_link): ..
* coff-rs6000.c (xcoff_reloc_type_br, xcoff_ppc_relocate_section): ..
* coff-sh.c (sh_relax_section, sh_relax_delete_bytes,
sh_align_loads, sh_coff_get_relocated_section_contents): ..
* coff64-rs6000.c (xcoff64_write_object_contents,
xcoff64_reloc_type_br, xcoff64_ppc_relocate_section): ..
* coffcode.h (coff_compute_section_file_positions,
coff_write_object_contents): ..
* coffgen.c (make_a_section_from_file, coff_write_symbols,
coff_section_symbol, build_debug_section): ..
* cofflink.c (coff_link_add_symbols, _bfd_coff_final_link,
process_embedded_commands, _bfd_coff_link_input_bfd,
_bfd_coff_write_global_sym): ..
* cpu-arm.c (bfd_arm_update_notes, bfd_arm_get_mach_from_notes): ..
* cpu-ns32k.c (do_ns32k_reloc, _bfd_ns32k_final_link_relocate): ..
* dwarf1.c (parse_line_table, _bfd_dwarf1_find_nearest_line): ..
* dwarf2.c (read_indirect_string, read_abbrevs, decode_line_info,
_bfd_dwarf2_find_nearest_line): ..
* ecoff.c (bfd_debug_section, ecoff_set_symbol_info,
ecoff_compute_section_file_positions,
_bfd_ecoff_write_object_contents, ecoff_indirect_link_order): ..
* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame,
_bfd_elf_discard_section_eh_frame_hdr,
_bfd_elf_maybe_strip_eh_frame_hdr, _bfd_elf_eh_frame_section_offset,
_bfd_elf_write_section_eh_frame,
_bfd_elf_write_section_eh_frame_hdr): ..
* elf-hppa.h (elf_hppa_sort_unwind): ..
* elf-m10200.c (mn10200_elf_relax_section,
mn10200_elf_relax_delete_bytes,
mn10200_elf_get_relocated_section_contents): ..
* elf-m10300.c (_bfd_mn10300_elf_create_got_section,
mn10300_elf_check_relocs, mn10300_elf_relax_section,
mn10300_elf_relax_delete_bytes,
mn10300_elf_get_relocated_section_contents,
_bfd_mn10300_elf_adjust_dynamic_symbol,
_bfd_mn10300_elf_discard_copies,
_bfd_mn10300_elf_size_dynamic_sections,
_bfd_mn10300_elf_finish_dynamic_sections): ..
* elf.c (_bfd_elf_print_private_bfd_data, bfd_elf_get_bfd_needed_list,
_bfd_elf_make_section_from_phdr, elf_fake_sections,
bfd_elf_set_group_contents, map_sections_to_segments,
elf_sort_sections, assign_file_positions_for_segments,
SECTION_SIZE, copy_private_bfd_data,
_bfd_elf_get_dynamic_reloc_upper_bound,
_bfd_elf_canonicalize_dynamic_reloc, elfcore_maybe_make_sect,
_bfd_elfcore_make_pseudosection, elfcore_grok_prstatus,
elfcore_grok_lwpstatus, elfcore_grok_win32pstatus,
elfcore_grok_note, elfcore_grok_nto_status, elfcore_grok_nto_gregs,
_bfd_elf_rel_local_sym, _bfd_elf_get_synthetic_symtab): ..
* elf32-arm.h (bfd_elf32_arm_allocate_interworking_sect,
bfd_elf32_arm_process_before_allocation,
elf32_arm_adjust_dynamic_symbol, allocate_dynrelocs,
elf32_arm_size_dynamic_sections, elf32_arm_finish_dynamic_sections,
elf32_arm_write_section): ..
* elf32-cris.c (cris_elf_grok_prstatus,
elf_cris_finish_dynamic_sections, cris_elf_gc_sweep_hook,
elf_cris_adjust_gotplt_to_got, elf_cris_adjust_dynamic_symbol,
cris_elf_check_relocs, elf_cris_size_dynamic_sections,
elf_cris_discard_excess_dso_dynamics,
elf_cris_discard_excess_program_dynamics): ..
* elf32-d30v.c (bfd_elf_d30v_reloc, bfd_elf_d30v_reloc_21): ..
* elf32-dlx.c (_bfd_dlx_elf_hi16_reloc): ..
* elf32-frv.c (_frvfdpic_add_dyn_reloc, _frvfdpic_add_rofixup,
_frv_create_got_section, _frvfdpic_assign_plt_entries,
elf32_frvfdpic_size_dynamic_sections,
elf32_frvfdpic_modify_segment_map,
elf32_frvfdpic_finish_dynamic_sections): ..
* elf32-h8300.c (elf32_h8_relax_section, elf32_h8_relax_delete_bytes,
elf32_h8_get_relocated_section_contents): ..
* elf32-hppa.c (hppa_build_one_stub, hppa_size_one_stub,
elf32_hppa_adjust_dynamic_symbol, allocate_plt_static,
allocate_dynrelocs, elf32_hppa_size_dynamic_sections, group_sections,
elf32_hppa_size_stubs, elf32_hppa_set_gp, elf32_hppa_build_stubs,
elf32_hppa_finish_dynamic_sections): ..
* elf32-i370.c (i370_elf_adjust_dynamic_symbol,
i370_elf_size_dynamic_sections, i370_elf_check_relocs,
i370_elf_finish_dynamic_sections): ..
* elf32-i386.c (elf_i386_grok_prstatus, elf_i386_adjust_dynamic_symbol,
allocate_dynrelocs, elf_i386_size_dynamic_sections,
elf_i386_relocate_section, elf_i386_finish_dynamic_sections): ..
* elf32-i860.c (i860_howto_pc26_reloc, i860_howto_pc16_reloc,
i860_howto_highadj_reloc, i860_howto_splitn_reloc): ..
* elf32-ip2k.c (ip2k_is_switch_table_128,
ip2k_relax_switch_table_128, ip2k_is_switch_table_256,
ip2k_relax_switch_table_256, ip2k_elf_relax_section,
adjust_all_relocations, ip2k_elf_relax_delete_bytes): ..
* elf32-m32r.c (m32r_elf_do_10_pcrel_reloc, m32r_elf_hi16_reloc,
m32r_elf_generic_reloc, m32r_elf_adjust_dynamic_symbol,
allocate_dynrelocs, m32r_elf_size_dynamic_sections,
m32r_elf_relocate_section, m32r_elf_finish_dynamic_sections,
m32r_elf_relax_section, m32r_elf_relax_delete_bytes,
m32r_elf_get_relocated_section_contents): ..
* elf32-m68hc11.c (m68hc11_elf_build_one_stub,
m68hc11_elf_size_one_stub, m68hc11_elf_relax_section,
m68hc11_elf_relax_delete_bytes): ..
* elf32-m68hc12.c (m68hc12_elf_build_one_stub,
m68hc12_elf_size_one_stub): ..
* elf32-m68hc1x.c (elf32_m68hc11_size_stubs,
elf32_m68hc11_build_stubs, m68hc11_elf_special_reloc): ..
* elf32-m68k.c (elf_m68k_check_relocs, elf_m68k_gc_sweep_hook,
elf_m68k_adjust_dynamic_symbol, elf_m68k_size_dynamic_sections,
elf_m68k_discard_copies, elf_m68k_finish_dynamic_sections): ..
* elf32-mips.c (gprel32_with_gp, mips16_gprel_reloc,
elf32_mips_grok_prstatus): ..
* elf32-or32.c (or32_elf_consth_reloc): ..
* elf32-ppc.c (ppc_elf_relax_section, ppc_elf_addr16_ha_reloc,
elf_create_pointer_linker_section, ppc_elf_create_linker_section,
ppc_elf_additional_program_headers, ppc_elf_adjust_dynamic_symbol,
allocate_dynrelocs, ppc_elf_size_dynamic_sections,
ppc_elf_finish_dynamic_sections, ppc_elf_grok_prstatus,
ppc_elf_final_write_processing): ..
* elf32-s390.c (s390_elf_ldisp_reloc, elf_s390_adjust_dynamic_symbol,
allocate_dynrelocs, elf_s390_size_dynamic_sections,
elf_s390_finish_dynamic_sections, elf_s390_grok_prstatus): ..
* elf32-sh.c (sh_elf_reloc_loop, sh_elf_relax_section,
sh_elf_relax_delete_bytes, sh_elf_align_loads,
sh_elf_adjust_dynamic_symbol, allocate_dynrelocs,
sh_elf_size_dynamic_sections, sh_elf_get_relocated_section_contents,
sh_elf_finish_dynamic_sections, elf32_shlin_grok_prstatus): ..
* elf32-sh64-com.c (sh64_address_in_cranges,
sh64_get_contents_type): ..
* elf32-sh64.c (sh64_find_section_for_address,
sh64_elf_final_write_processing): ..
* elf32-sparc.c (sparc_elf_wdisp16_reloc, sparc_elf_hix22_reloc,
sparc_elf_lox10_reloc, elf32_sparc_adjust_dynamic_symbol,
allocate_dynrelocs, elf32_sparc_size_dynamic_sections,
elf32_sparc_relocate_section, elf32_sparc_finish_dynamic_sections): ..
* elf32-v850.c (v850_elf_reloc, v850_elf_relax_section): ..
* elf32-vax.c (elf_vax_check_relocs, elf_vax_adjust_dynamic_symbol,
elf_vax_size_dynamic_sections, elf_vax_discard_copies,
elf_vax_instantiate_got_entries, elf_vax_relocate_section,
elf_vax_finish_dynamic_sections): ..
* elf32-xstormy16.c (xstormy16_elf_24_reloc,
xstormy16_elf_check_relocs, xstormy16_relax_plt_check,
xstormy16_elf_relax_section, xstormy16_elf_always_size_sections,
xstormy16_elf_finish_dynamic_sections): ..
* elf32-xtensa.c (xtensa_read_table_entries,
elf_xtensa_allocate_got_size, elf_xtensa_allocate_local_got_size,
elf_xtensa_size_dynamic_sections, elf_xtensa_do_reloc,
bfd_elf_xtensa_reloc, elf_xtensa_relocate_section,
elf_xtensa_combine_prop_entries, elf_xtensa_finish_dynamic_sections,
elf_xtensa_discard_info_for_section, elf_xtensa_grok_prstatus,
get_relocation_opcode, retrieve_contents, find_relaxable_sections,
collect_source_relocs, is_resolvable_asm_expansion, remove_literals,
relax_section, shrink_dynamic_reloc_sections, relax_property_section,
xtensa_callback_required_dependence): ..
* elf64-alpha.c (elf64_alpha_reloc_gpdisp, elf64_alpha_relax_section,
elf64_alpha_check_relocs, elf64_alpha_adjust_dynamic_symbol,
elf64_alpha_calc_got_offsets_for_symbol, elf64_alpha_calc_got_offsets,
elf64_alpha_size_plt_section, elf64_alpha_size_plt_section_1,
elf64_alpha_always_size_sections, elf64_alpha_calc_dynrel_sizes,
elf64_alpha_size_rela_got_section, elf64_alpha_size_rela_got_1,
elf64_alpha_size_dynamic_sections, elf64_alpha_emit_dynrel,
elf64_alpha_finish_dynamic_sections, elf64_alpha_final_link): ..
* elf64-hppa.c (allocate_dynrel_entries,
elf64_hppa_size_dynamic_sections,
elf64_hppa_finish_dynamic_sections): ..
* elf64-mips.c (mips_elf64_gprel32_reloc, mips16_gprel_reloc,
mips_elf64_canonicalize_dynamic_reloc, mips_elf64_slurp_reloc_table,
elf64_mips_grok_prstatus): ..
* elf64-mmix.c (mmix_elf_perform_relocation, mmix_elf_reloc,
mmix_elf_relocate_section, mmix_elf_final_link,
mmix_set_relaxable_size, _bfd_mmix_after_linker_allocation,
mmix_elf_relax_section, mmix_elf_get_section_contents): ..
* elf64-ppc.c (ppc64_elf_object_p, ppc64_elf_grok_prstatus,
ppc64_elf_check_relocs, ppc64_elf_func_desc_adjust,
ppc64_elf_adjust_dynamic_symbol, ppc64_elf_edit_opd,
allocate_dynrelocs, ppc64_elf_size_dynamic_sections,
ppc_build_one_stub, ppc_size_one_stub, ppc64_elf_next_toc_section,
toc_adjusting_stub_needed, group_sections, ppc64_elf_size_stubs,
ppc64_elf_build_stubs, ppc64_elf_relocate_section,
ppc64_elf_finish_dynamic_sections): ..
* elf64-s390.c (s390_elf_ldisp_reloc, elf_s390_adjust_dynamic_symbol,
allocate_dynrelocs, elf_s390_size_dynamic_sections,
elf_s390_finish_dynamic_sections): ..
* elf64-sh64.c (sh_elf64_get_relocated_section_contents,
sh_elf64_check_relocs, sh64_elf64_adjust_dynamic_symbol,
sh64_elf64_discard_copies, sh64_elf64_size_dynamic_sections,
sh64_elf64_finish_dynamic_sections): ..
* elf64-sparc.c (sparc64_elf_slurp_reloc_table, init_insn_reloc,
sparc64_elf_check_relocs, sparc64_elf_adjust_dynamic_symbol,
sparc64_elf_size_dynamic_sections, sparc64_elf_relocate_section,
sparc64_elf_finish_dynamic_symbol,
sparc64_elf_finish_dynamic_sections): ..
* elf64-x86-64.c (elf64_x86_64_grok_prstatus,
elf64_x86_64_adjust_dynamic_symbol, allocate_dynrelocs,
elf64_x86_64_size_dynamic_sections, elf64_x86_64_relocate_section,
elf64_x86_64_finish_dynamic_sections): ..
* elfarm-nabi.c (elf32_arm_nabi_grok_prstatus): ..
* elfcode.h (elf_slurp_reloc_table): ..
* elflink.c (_bfd_elf_create_got_section, elf_add_dt_needed_tag,
elf_finalize_dynstr, elf_link_add_object_symbols,
bfd_elf_size_dynamic_sections, elf_link_sort_relocs,
elf_link_input_bfd, bfd_elf_final_link, bfd_elf_discard_info): ..
* elfn32-mips.c (gprel32_with_gp, mips16_gprel_reloc,
elf32_mips_grok_prstatus): ..
* elfxx-ia64.c (elfNN_ia64_relax_section, allocate_dynrel_entries,
elfNN_ia64_size_dynamic_sections, elfNN_ia64_install_dyn_reloc,
elfNN_ia64_choose_gp, elfNN_ia64_final_link,
elfNN_ia64_finish_dynamic_sections): ..
* elfxx-mips.c (mips_elf_create_procedure_table,
mips_elf_check_mips16_stubs, _bfd_mips_elf_gprel16_with_gp,
_bfd_mips_elf_hi16_reloc, _bfd_mips_elf_generic_reloc,
mips_elf_global_got_index, mips_elf_multi_got,
mips_elf_create_compact_rel_section, mips_elf_calculate_relocation,
mips_elf_allocate_dynamic_relocations,
mips_elf_create_dynamic_relocation, _bfd_mips_elf_fake_sections,
_bfd_mips_relax_section, _bfd_mips_elf_adjust_dynamic_symbol,
_bfd_mips_elf_always_size_sections,
_bfd_mips_elf_size_dynamic_sections,
_bfd_mips_elf_finish_dynamic_symbol,
_bfd_mips_elf_finish_dynamic_sections,
_bfd_mips_elf_modify_segment_map, _bfd_mips_elf_discard_info,
_bfd_mips_elf_write_section, _bfd_mips_elf_set_section_contents,
_bfd_elf_mips_get_relocated_section_contents,
_bfd_mips_elf_final_link, _bfd_mips_elf_merge_private_bfd_data): ..
* hp300hpux.c (callback): ..
* hppabsd-core.c (make_bfd_asection): ..
* hpux-core.c (make_bfd_asection): ..
* i386linux.c (linux_link_create_dynamic_sections,
bfd_i386linux_size_dynamic_sections, linux_finish_dynamic_link): ..
* i386msdos.c (msdos_write_object_contents): ..
* i386os9k.c (os9k_callback, os9k_write_object_contents,
os9k_set_section_contents): ..
* ieee.c (parse_expression, ieee_slurp_external_symbols,
ieee_slurp_sections, ieee_slurp_debug, ieee_slurp_section_data,
ieee_write_section_part, do_with_relocs, do_as_repeat,
do_without_relocs, ieee_write_debug_part, init_for_output,
ieee_set_section_contents): ..
* ihex.c (ihex_scan, ihex_read_section, ihex_get_section_contents): ..
* irix-core.c (do_sections, make_bfd_asection): ..
* libaout.h (aout_section_merge_with_text_p): ..
* libbfd.c (_bfd_generic_get_section_contents,
_bfd_generic_get_section_contents_in_window): ..
* linker.c (default_indirect_link_order): ..
* lynx-core.c (make_bfd_asection): ..
* m68klinux.c (linux_link_create_dynamic_sections,
bfd_m68klinux_size_dynamic_sections, linux_finish_dynamic_link): ..
* mach-o.c (bfd_mach_o_make_bfd_section,
bfd_mach_o_scan_read_dylinker, bfd_mach_o_scan_read_dylib,
bfd_mach_o_scan_read_thread, bfd_mach_o_scan_read_symtab,
bfd_mach_o_scan_read_segment): ..
* merge.c (_bfd_add_merge_section, record_section, merge_strings,
_bfd_merge_sections): ..
* mmo.c (mmo_find_sec_w_addr, mmo_get_spec_section, mmo_get_loc,
mmo_map_set_sizes, mmo_canonicalize_symtab,
mmo_internal_write_section, mmo_write_object_contents): ..
* netbsd-core.c (netbsd_core_file_p): ..
* nlm32-alpha.c (nlm_alpha_read_reloc, nlm_alpha_write_import,
nlm_alpha_set_public_section): ..
* nlm32-ppc.c (nlm_powerpc_read_reloc, nlm_powerpc_write_reloc): ..
* nlm32-sparc.c (nlm_sparc_write_import): ..
* nlmcode.h (add_bfd_section, nlm_swap_auxiliary_headers_in,
nlm_compute_section_file_positions): ..
* oasys.c (oasys_object_p, oasys_slurp_section_data,
oasys_write_sections, oasys_write_data, oasys_set_section_contents): ..
* opncls.c (get_debug_link_info): ..
* osf-core.c (make_bfd_asection): ..
* pdp11.c (some_aout_object_p, adjust_o_magic, adjust_z_magic,
adjust_n_magic, adjust_sizes_and_vmas, squirt_out_relocs,
final_link, aout_link_input_section): ..
* peXXigen.c (_bfd_XXi_swap_sym_in, _bfd_XXi_swap_aouthdr_out,
pe_print_idata, pe_print_edata, pe_print_pdata, pe_print_reloc): ..
* pef.c (bfd_pef_make_bfd_section, bfd_pef_print_loader_section,
bfd_pef_scan_start_address, bfd_pef_parse_symbols): ..
* ppcboot.c (ppcboot_object_p, ppcboot_canonicalize_symtab): ..
* ptrace-core.c (ptrace_unix_core_file_p): ..
* reloc.c (bfd_perform_relocation, bfd_install_relocation,
_bfd_final_link_relocate, bfd_generic_relax_section,
bfd_generic_get_relocated_section_contents): ..
* reloc16.c (bfd_coff_reloc16_relax_section,
bfd_coff_reloc16_get_relocated_section_c): ..
* riscix.c (riscix_some_aout_object_p): ..
* rs6000-core.c (read_hdr, make_bfd_asection): ..
* sco5-core.c (make_bfd_asection): ..
* simple.c (bfd_simple_get_relocated_section_contents): ..
* som.c (som_object_setup, setup_sections, som_prep_headers,
som_write_fixups, som_begin_writing, bfd_section_from_som_symbol,
som_set_reloc_info, som_get_section_contents,
som_bfd_link_split_section): ..
* sparclinux.c (linux_link_create_dynamic_sections,
bfd_sparclinux_size_dynamic_sections, linux_finish_dynamic_link): ..
* srec.c (srec_scan, srec_read_section, srec_get_section_contents): ..
* stabs.c (_bfd_link_section_stabs, _bfd_discard_section_stabs,
_bfd_write_stab_strings, _bfd_stab_section_offset): ..
* sunos.c (sunos_read_dynamic_info, sunos_create_dynamic_sections,
bfd_sunos_size_dynamic_sections, sunos_scan_std_relocs,
sunos_scan_ext_relocs, sunos_scan_dynamic_symbol,
sunos_write_dynamic_symbol, sunos_check_dynamic_reloc,
sunos_finish_dynamic_link): ..
* syms.c (_bfd_stab_section_find_nearest_line): ..
* tekhex.c (first_phase, tekhex_set_section_contents,
tekhex_write_object_contents): ..
* trad-core.c (trad_unix_core_file_p): ..
* versados.c (process_esd, process_otr, process_otr): ..
* vms-gsd.c (_bfd_vms_slurp_gsd, _bfd_vms_write_gsd): ..
* vms-misc.c (add_new_contents): ..
* vms-tir.c (check_section, new_section, _bfd_vms_write_tir): ..
* vms.c (vms_set_section_contents): ..
* xcofflink.c (xcoff_get_section_contents, xcoff_link_add_symbols,
xcoff_sweep, bfd_xcoff_size_dynamic_sections, xcoff_build_ldsyms,
_bfd_xcoff_bfd_final_link, xcoff_link_input_bfd): ..
* xsym.c (bfd_sym_scan): .. See above.
binutils/
* objcopy.c (copy_section): Don't set _cooked_size.
include/
* bfdlink.h (struct bfd_link_order): Update comment.
ld/
* ldlang.c (print_output_section_statement): Don't print size before
relaxation.
(IGNORE_SECTION): Remove bfd arg. Update all callers.
* ldexp.c (fold_name): .. See below.
* ldlang.c (section_already_linked, print_output_section_statement,
print_input_section, insert_pad, size_input_section,
lang_check_section_addresses, lang_size_sections_1,
lang_size_sections, lang_do_assignments_1, lang_set_startof,
lang_one_common, lang_reset_memory_regions, lang_process,
lang_abs_symbol_at_end_of, lang_do_version_exports_section): ..
* ldwrite.c (build_link_order, clone_section, ds, split_sections): ..
* pe-dll.c (process_def_file, generate_reloc): ..
* emultempl/elf32.em (gld${EMULATION_NAME}_find_statement_assignment,
gld${EMULATION_NAME}_before_allocation): ..
* emultempl/mmix-elfnmmo.em (mmix_after_allocation): ..
* emultempl/sh64elf.em (sh64_elf_${EMULATION_NAME}_before_allocation,
sh64_elf_${EMULATION_NAME}_after_allocation): ..
* emultempl/sunos.em (gld${EMULATION_NAME}_before_allocation): ..
* emultempl/xtensaelf.em (ld_assign_relative_paged_dot,
ld_local_file_relocations_fit, ld_xtensa_insert_page_offsets): Use
"size" instead of "_raw_size" and "_cooked_size". Expand
bfd_section_size macro invocations.
2004-06-24 06:46:28 +02:00
|
|
|
while (reloc_sz < reloc_s->size)
|
1999-05-03 09:29:11 +02:00
|
|
|
reloc_d[reloc_sz++] = 0;
|
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Given the exiting def_file structure, print out a .DEF file that
|
|
|
|
corresponds to it. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
static void
|
2003-06-28 07:28:54 +02:00
|
|
|
quoteput (char *s, FILE *f, int needs_quotes)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
char *cp;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
for (cp = s; *cp; cp++)
|
|
|
|
if (*cp == '\''
|
|
|
|
|| *cp == '"'
|
|
|
|
|| *cp == '\\'
|
2001-09-19 07:33:36 +02:00
|
|
|
|| ISSPACE (*cp)
|
1999-05-03 09:29:11 +02:00
|
|
|
|| *cp == ','
|
|
|
|
|| *cp == ';')
|
|
|
|
needs_quotes = 1;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (needs_quotes)
|
|
|
|
{
|
|
|
|
putc ('"', f);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
while (*s)
|
|
|
|
{
|
|
|
|
if (*s == '"' || *s == '\\')
|
|
|
|
putc ('\\', f);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
putc (*s, f);
|
|
|
|
s++;
|
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
putc ('"', f);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fputs (s, f);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-06-28 07:28:54 +02:00
|
|
|
pe_dll_generate_def_file (const char *pe_out_def_filename)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
FILE *out = fopen (pe_out_def_filename, "w");
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (out == NULL)
|
2001-09-14 16:19:05 +02:00
|
|
|
/* xgettext:c-format */
|
|
|
|
einfo (_("%s: Can't open output def file %s\n"),
|
|
|
|
program_name, pe_out_def_filename);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
if (pe_def_file)
|
|
|
|
{
|
|
|
|
if (pe_def_file->name)
|
|
|
|
{
|
|
|
|
if (pe_def_file->is_dll)
|
|
|
|
fprintf (out, "LIBRARY ");
|
|
|
|
else
|
|
|
|
fprintf (out, "NAME ");
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
quoteput (pe_def_file->name, out, 1);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2008-02-15 04:35:53 +01:00
|
|
|
if (pe_data (link_info.output_bfd)->pe_opthdr.ImageBase)
|
2008-05-09 13:56:31 +02:00
|
|
|
{
|
|
|
|
fprintf (out, " BASE=0x");
|
|
|
|
fprintf_vma (out, ((bfd_vma) pe_data (link_info.output_bfd)->pe_opthdr.ImageBase));
|
|
|
|
}
|
1999-05-03 09:29:11 +02:00
|
|
|
fprintf (out, "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pe_def_file->description)
|
|
|
|
{
|
|
|
|
fprintf (out, "DESCRIPTION ");
|
|
|
|
quoteput (pe_def_file->description, out, 1);
|
|
|
|
fprintf (out, "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pe_def_file->version_minor != -1)
|
|
|
|
fprintf (out, "VERSION %d.%d\n", pe_def_file->version_major,
|
|
|
|
pe_def_file->version_minor);
|
|
|
|
else if (pe_def_file->version_major != -1)
|
|
|
|
fprintf (out, "VERSION %d\n", pe_def_file->version_major);
|
|
|
|
|
|
|
|
if (pe_def_file->stack_reserve != -1 || pe_def_file->heap_reserve != -1)
|
|
|
|
fprintf (out, "\n");
|
|
|
|
|
|
|
|
if (pe_def_file->stack_commit != -1)
|
|
|
|
fprintf (out, "STACKSIZE 0x%x,0x%x\n",
|
|
|
|
pe_def_file->stack_reserve, pe_def_file->stack_commit);
|
|
|
|
else if (pe_def_file->stack_reserve != -1)
|
|
|
|
fprintf (out, "STACKSIZE 0x%x\n", pe_def_file->stack_reserve);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (pe_def_file->heap_commit != -1)
|
|
|
|
fprintf (out, "HEAPSIZE 0x%x,0x%x\n",
|
|
|
|
pe_def_file->heap_reserve, pe_def_file->heap_commit);
|
|
|
|
else if (pe_def_file->heap_reserve != -1)
|
|
|
|
fprintf (out, "HEAPSIZE 0x%x\n", pe_def_file->heap_reserve);
|
|
|
|
|
|
|
|
if (pe_def_file->num_section_defs > 0)
|
|
|
|
{
|
|
|
|
fprintf (out, "\nSECTIONS\n\n");
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
for (i = 0; i < pe_def_file->num_section_defs; i++)
|
|
|
|
{
|
|
|
|
fprintf (out, " ");
|
|
|
|
quoteput (pe_def_file->section_defs[i].name, out, 0);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (pe_def_file->section_defs[i].class)
|
|
|
|
{
|
|
|
|
fprintf (out, " CLASS ");
|
|
|
|
quoteput (pe_def_file->section_defs[i].class, out, 0);
|
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (pe_def_file->section_defs[i].flag_read)
|
|
|
|
fprintf (out, " READ");
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (pe_def_file->section_defs[i].flag_write)
|
|
|
|
fprintf (out, " WRITE");
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (pe_def_file->section_defs[i].flag_execute)
|
|
|
|
fprintf (out, " EXECUTE");
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (pe_def_file->section_defs[i].flag_shared)
|
|
|
|
fprintf (out, " SHARED");
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
fprintf (out, "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pe_def_file->num_exports > 0)
|
|
|
|
{
|
2001-08-03 01:12:02 +02:00
|
|
|
fprintf (out, "EXPORTS\n");
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
for (i = 0; i < pe_def_file->num_exports; i++)
|
|
|
|
{
|
|
|
|
def_file_export *e = pe_def_file->exports + i;
|
|
|
|
fprintf (out, " ");
|
|
|
|
quoteput (e->name, out, 0);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (e->internal_name && strcmp (e->internal_name, e->name))
|
|
|
|
{
|
|
|
|
fprintf (out, " = ");
|
|
|
|
quoteput (e->internal_name, out, 0);
|
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (e->ordinal != -1)
|
|
|
|
fprintf (out, " @%d", e->ordinal);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (e->flag_private)
|
|
|
|
fprintf (out, " PRIVATE");
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (e->flag_constant)
|
|
|
|
fprintf (out, " CONSTANT");
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (e->flag_noname)
|
|
|
|
fprintf (out, " NONAME");
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (e->flag_data)
|
|
|
|
fprintf (out, " DATA");
|
|
|
|
|
|
|
|
fprintf (out, "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pe_def_file->num_imports > 0)
|
|
|
|
{
|
|
|
|
fprintf (out, "\nIMPORTS\n\n");
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
for (i = 0; i < pe_def_file->num_imports; i++)
|
|
|
|
{
|
|
|
|
def_file_import *im = pe_def_file->imports + i;
|
|
|
|
fprintf (out, " ");
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (im->internal_name
|
|
|
|
&& (!im->name || strcmp (im->internal_name, im->name)))
|
|
|
|
{
|
|
|
|
quoteput (im->internal_name, out, 0);
|
|
|
|
fprintf (out, " = ");
|
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
quoteput (im->module->name, out, 0);
|
|
|
|
fprintf (out, ".");
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (im->name)
|
|
|
|
quoteput (im->name, out, 0);
|
|
|
|
else
|
|
|
|
fprintf (out, "%d", im->ordinal);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2009-10-23 13:40:17 +02:00
|
|
|
if (im->its_name)
|
|
|
|
{
|
|
|
|
fprintf (out, " == ");
|
|
|
|
quoteput (im->its_name, out, 0);
|
|
|
|
}
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
fprintf (out, "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fprintf (out, _("; no contents available\n"));
|
|
|
|
|
|
|
|
if (fclose (out) == EOF)
|
2001-09-14 16:19:05 +02:00
|
|
|
/* xgettext:c-format */
|
|
|
|
einfo (_("%P: Error closing file `%s'\n"), pe_out_def_filename);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Generate the import library. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
static asymbol **symtab;
|
|
|
|
static int symptr;
|
|
|
|
static int tmp_seq;
|
2009-01-26 11:29:11 +01:00
|
|
|
static int tmp_seq2;
|
1999-05-03 09:29:11 +02:00
|
|
|
static const char *dll_filename;
|
|
|
|
static char *dll_symname;
|
|
|
|
|
2012-05-05 05:05:32 +02:00
|
|
|
#define UNDSEC bfd_und_section_ptr
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
static asection *
|
2003-06-28 07:28:54 +02:00
|
|
|
quick_section (bfd *abfd, const char *name, int flags, int align)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
asection *sec;
|
|
|
|
asymbol *sym;
|
|
|
|
|
|
|
|
sec = bfd_make_section_old_way (abfd, name);
|
2000-10-09 09:01:29 +02:00
|
|
|
bfd_set_section_flags (abfd, sec, flags | SEC_ALLOC | SEC_LOAD | SEC_KEEP);
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_set_section_alignment (abfd, sec, align);
|
2000-10-09 09:01:29 +02:00
|
|
|
/* Remember to undo this before trying to link internally! */
|
1999-05-03 09:29:11 +02:00
|
|
|
sec->output_section = sec;
|
|
|
|
|
|
|
|
sym = bfd_make_empty_symbol (abfd);
|
|
|
|
symtab[symptr++] = sym;
|
|
|
|
sym->name = sec->name;
|
|
|
|
sym->section = sec;
|
|
|
|
sym->flags = BSF_LOCAL;
|
|
|
|
sym->value = 0;
|
|
|
|
|
|
|
|
return sec;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2003-06-28 07:28:54 +02:00
|
|
|
quick_symbol (bfd *abfd,
|
|
|
|
const char *n1,
|
|
|
|
const char *n2,
|
|
|
|
const char *n3,
|
|
|
|
asection *sec,
|
|
|
|
int flags,
|
|
|
|
int addr)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
asymbol *sym;
|
2003-06-28 07:28:54 +02:00
|
|
|
char *name = xmalloc (strlen (n1) + strlen (n2) + strlen (n3) + 1);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
strcpy (name, n1);
|
|
|
|
strcat (name, n2);
|
|
|
|
strcat (name, n3);
|
|
|
|
sym = bfd_make_empty_symbol (abfd);
|
|
|
|
sym->name = name;
|
|
|
|
sym->section = sec;
|
|
|
|
sym->flags = flags;
|
|
|
|
sym->value = addr;
|
|
|
|
symtab[symptr++] = sym;
|
|
|
|
}
|
|
|
|
|
|
|
|
static arelent *reltab = 0;
|
|
|
|
static int relcount = 0, relsize = 0;
|
|
|
|
|
|
|
|
static void
|
2008-05-09 13:56:31 +02:00
|
|
|
quick_reloc (bfd *abfd, bfd_size_type address, int which_howto, int symidx)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
2003-06-28 07:28:54 +02:00
|
|
|
if (relcount >= relsize - 1)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
relsize += 10;
|
|
|
|
if (reltab)
|
2003-06-28 07:28:54 +02:00
|
|
|
reltab = xrealloc (reltab, relsize * sizeof (arelent));
|
1999-05-03 09:29:11 +02:00
|
|
|
else
|
2003-06-28 07:28:54 +02:00
|
|
|
reltab = xmalloc (relsize * sizeof (arelent));
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
reltab[relcount].address = address;
|
|
|
|
reltab[relcount].addend = 0;
|
|
|
|
reltab[relcount].howto = bfd_reloc_type_lookup (abfd, which_howto);
|
|
|
|
reltab[relcount].sym_ptr_ptr = symtab + symidx;
|
|
|
|
relcount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
save_relocs (asection *sec)
|
|
|
|
{
|
|
|
|
int i;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
sec->relocation = reltab;
|
|
|
|
sec->reloc_count = relcount;
|
2003-06-28 07:28:54 +02:00
|
|
|
sec->orelocation = xmalloc ((relcount + 1) * sizeof (arelent *));
|
2000-10-09 03:37:11 +02:00
|
|
|
for (i = 0; i < relcount; i++)
|
1999-05-03 09:29:11 +02:00
|
|
|
sec->orelocation[i] = sec->relocation + i;
|
|
|
|
sec->orelocation[relcount] = 0;
|
|
|
|
sec->flags |= SEC_RELOC;
|
|
|
|
reltab = 0;
|
|
|
|
relcount = relsize = 0;
|
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* .section .idata$2
|
|
|
|
.global __head_my_dll
|
|
|
|
__head_my_dll:
|
|
|
|
.rva hname
|
|
|
|
.long 0
|
|
|
|
.long 0
|
|
|
|
.rva __my_dll_iname
|
|
|
|
.rva fthunk
|
2002-05-03 15:48:55 +02:00
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
.section .idata$5
|
|
|
|
.long 0
|
|
|
|
fthunk:
|
2002-05-03 15:48:55 +02:00
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
.section .idata$4
|
|
|
|
.long 0
|
|
|
|
hname: */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
static bfd *
|
2003-06-28 07:28:54 +02:00
|
|
|
make_head (bfd *parent)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
asection *id2, *id5, *id4;
|
|
|
|
unsigned char *d2, *d5, *d4;
|
|
|
|
char *oname;
|
|
|
|
bfd *abfd;
|
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
oname = xmalloc (20);
|
1999-05-03 09:29:11 +02:00
|
|
|
sprintf (oname, "d%06d.o", tmp_seq);
|
|
|
|
tmp_seq++;
|
|
|
|
|
|
|
|
abfd = bfd_create (oname, parent);
|
1999-05-11 23:06:50 +02:00
|
|
|
bfd_find_target (pe_details->object_target, abfd);
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_make_writable (abfd);
|
|
|
|
|
|
|
|
bfd_set_format (abfd, bfd_object);
|
1999-05-11 23:06:50 +02:00
|
|
|
bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
symptr = 0;
|
2003-06-28 07:28:54 +02:00
|
|
|
symtab = xmalloc (6 * sizeof (asymbol *));
|
1999-05-03 09:29:11 +02:00
|
|
|
id2 = quick_section (abfd, ".idata$2", SEC_HAS_CONTENTS, 2);
|
|
|
|
id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
|
|
|
|
id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
|
2000-10-09 03:37:11 +02:00
|
|
|
quick_symbol (abfd, U ("_head_"), dll_symname, "", id2, BSF_GLOBAL, 0);
|
|
|
|
quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
|
1999-05-11 23:06:50 +02:00
|
|
|
|
|
|
|
/* OK, pay attention here. I got confused myself looking back at
|
|
|
|
it. We create a four-byte section to mark the beginning of the
|
|
|
|
list, and we include an offset of 4 in the section, so that the
|
|
|
|
pointer to the list points to the *end* of this section, which is
|
2000-09-29 15:21:41 +02:00
|
|
|
the start of the list of sections from other objects. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
bfd_set_section_size (abfd, id2, 20);
|
2003-06-28 07:28:54 +02:00
|
|
|
d2 = xmalloc (20);
|
1999-05-03 09:29:11 +02:00
|
|
|
id2->contents = d2;
|
|
|
|
memset (d2, 0, 20);
|
2009-01-08 14:28:48 +01:00
|
|
|
if (pe_use_nul_prefixed_import_tables)
|
|
|
|
d2[0] = d2[16] = PE_IDATA5_SIZE; /* Reloc addend. */
|
1999-05-03 09:29:11 +02:00
|
|
|
quick_reloc (abfd, 0, BFD_RELOC_RVA, 2);
|
|
|
|
quick_reloc (abfd, 12, BFD_RELOC_RVA, 4);
|
|
|
|
quick_reloc (abfd, 16, BFD_RELOC_RVA, 1);
|
|
|
|
save_relocs (id2);
|
|
|
|
|
2009-01-08 14:28:48 +01:00
|
|
|
if (pe_use_nul_prefixed_import_tables)
|
|
|
|
bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE);
|
|
|
|
else
|
|
|
|
bfd_set_section_size (abfd, id5, 0);
|
2006-09-20 13:35:11 +02:00
|
|
|
d5 = xmalloc (PE_IDATA5_SIZE);
|
1999-05-03 09:29:11 +02:00
|
|
|
id5->contents = d5;
|
2006-09-20 13:35:11 +02:00
|
|
|
memset (d5, 0, PE_IDATA5_SIZE);
|
2009-01-08 14:28:48 +01:00
|
|
|
if (pe_use_nul_prefixed_import_tables)
|
|
|
|
bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE);
|
|
|
|
else
|
|
|
|
bfd_set_section_size (abfd, id4, 0);
|
2006-09-20 13:35:11 +02:00
|
|
|
d4 = xmalloc (PE_IDATA4_SIZE);
|
1999-05-03 09:29:11 +02:00
|
|
|
id4->contents = d4;
|
2006-09-20 13:35:11 +02:00
|
|
|
memset (d4, 0, PE_IDATA4_SIZE);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
bfd_set_symtab (abfd, symtab, symptr);
|
|
|
|
|
|
|
|
bfd_set_section_contents (abfd, id2, d2, 0, 20);
|
2009-01-08 14:28:48 +01:00
|
|
|
if (pe_use_nul_prefixed_import_tables)
|
|
|
|
{
|
|
|
|
bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA5_SIZE);
|
|
|
|
bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bfd_set_section_contents (abfd, id5, d5, 0, 0);
|
|
|
|
bfd_set_section_contents (abfd, id4, d4, 0, 0);
|
|
|
|
}
|
2000-09-29 15:21:41 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_make_readable (abfd);
|
|
|
|
return abfd;
|
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* .section .idata$4
|
|
|
|
.long 0
|
2006-09-20 13:35:11 +02:00
|
|
|
[.long 0] for PE+
|
2001-09-14 16:19:05 +02:00
|
|
|
.section .idata$5
|
|
|
|
.long 0
|
2006-09-20 13:35:11 +02:00
|
|
|
[.long 0] for PE+
|
2001-09-14 16:19:05 +02:00
|
|
|
.section idata$7
|
|
|
|
.global __my_dll_iname
|
|
|
|
__my_dll_iname:
|
|
|
|
.asciz "my.dll" */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
static bfd *
|
2003-06-28 07:28:54 +02:00
|
|
|
make_tail (bfd *parent)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
asection *id4, *id5, *id7;
|
|
|
|
unsigned char *d4, *d5, *d7;
|
|
|
|
int len;
|
|
|
|
char *oname;
|
|
|
|
bfd *abfd;
|
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
oname = xmalloc (20);
|
1999-05-03 09:29:11 +02:00
|
|
|
sprintf (oname, "d%06d.o", tmp_seq);
|
|
|
|
tmp_seq++;
|
|
|
|
|
|
|
|
abfd = bfd_create (oname, parent);
|
1999-05-11 23:06:50 +02:00
|
|
|
bfd_find_target (pe_details->object_target, abfd);
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_make_writable (abfd);
|
|
|
|
|
|
|
|
bfd_set_format (abfd, bfd_object);
|
1999-05-11 23:06:50 +02:00
|
|
|
bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
symptr = 0;
|
2003-06-28 07:28:54 +02:00
|
|
|
symtab = xmalloc (5 * sizeof (asymbol *));
|
1999-05-03 09:29:11 +02:00
|
|
|
id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
|
|
|
|
id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
|
|
|
|
id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
|
2000-10-09 03:37:11 +02:00
|
|
|
quick_symbol (abfd, U (""), dll_symname, "_iname", id7, BSF_GLOBAL, 0);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2006-09-20 13:35:11 +02:00
|
|
|
bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE);
|
|
|
|
d4 = xmalloc (PE_IDATA4_SIZE);
|
1999-05-03 09:29:11 +02:00
|
|
|
id4->contents = d4;
|
2006-09-20 13:35:11 +02:00
|
|
|
memset (d4, 0, PE_IDATA4_SIZE);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2006-09-20 13:35:11 +02:00
|
|
|
bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE);
|
|
|
|
d5 = xmalloc (PE_IDATA5_SIZE);
|
1999-05-03 09:29:11 +02:00
|
|
|
id5->contents = d5;
|
2006-09-20 13:35:11 +02:00
|
|
|
memset (d5, 0, PE_IDATA5_SIZE);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2000-10-09 03:37:11 +02:00
|
|
|
len = strlen (dll_filename) + 1;
|
1999-05-03 09:29:11 +02:00
|
|
|
if (len & 1)
|
2000-10-09 03:37:11 +02:00
|
|
|
len++;
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_set_section_size (abfd, id7, len);
|
2003-06-28 07:28:54 +02:00
|
|
|
d7 = xmalloc (len);
|
1999-05-03 09:29:11 +02:00
|
|
|
id7->contents = d7;
|
2005-02-23 13:30:48 +01:00
|
|
|
strcpy ((char *) d7, dll_filename);
|
2006-11-01 01:48:25 +01:00
|
|
|
/* If len was odd, the above
|
|
|
|
strcpy leaves behind an undefined byte. That is harmless,
|
|
|
|
but we set it to 0 just so the binary dumps are pretty. */
|
|
|
|
d7[len - 1] = 0;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
bfd_set_symtab (abfd, symtab, symptr);
|
|
|
|
|
2006-09-20 13:35:11 +02:00
|
|
|
bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE);
|
|
|
|
bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA5_SIZE);
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_set_section_contents (abfd, id7, d7, 0, len);
|
|
|
|
|
|
|
|
bfd_make_readable (abfd);
|
|
|
|
return abfd;
|
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* .text
|
|
|
|
.global _function
|
|
|
|
.global ___imp_function
|
|
|
|
.global __imp__function
|
|
|
|
_function:
|
|
|
|
jmp *__imp__function:
|
2002-05-03 15:48:55 +02:00
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
.section idata$7
|
|
|
|
.long __head_my_dll
|
2002-05-03 15:48:55 +02:00
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
.section .idata$5
|
|
|
|
___imp_function:
|
|
|
|
__imp__function:
|
|
|
|
iat?
|
|
|
|
.section .idata$4
|
|
|
|
iat?
|
|
|
|
.section .idata$6
|
|
|
|
ID<ordinal>:
|
|
|
|
.short <hint>
|
|
|
|
.asciz "function" xlate? (add underscore, kill at) */
|
|
|
|
|
2006-11-01 01:48:25 +01:00
|
|
|
static const unsigned char jmp_ix86_bytes[] =
|
2001-09-14 16:19:05 +02:00
|
|
|
{
|
1999-05-03 09:29:11 +02:00
|
|
|
0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
|
|
|
|
};
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* _function:
|
|
|
|
mov.l ip+8,r0
|
|
|
|
mov.l @r0,r0
|
|
|
|
jmp @r0
|
|
|
|
nop
|
|
|
|
.dw __imp_function */
|
2000-02-24 18:53:12 +01:00
|
|
|
|
2006-11-01 01:48:25 +01:00
|
|
|
static const unsigned char jmp_sh_bytes[] =
|
2001-09-14 16:19:05 +02:00
|
|
|
{
|
2000-02-24 18:53:12 +01:00
|
|
|
0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
|
|
};
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* _function:
|
|
|
|
lui $t0,<high:__imp_function>
|
|
|
|
lw $t0,<low:__imp_function>
|
|
|
|
jr $t0
|
|
|
|
nop */
|
2000-02-24 18:53:12 +01:00
|
|
|
|
2006-11-01 01:48:25 +01:00
|
|
|
static const unsigned char jmp_mips_bytes[] =
|
2001-09-14 16:19:05 +02:00
|
|
|
{
|
2000-02-24 18:53:12 +01:00
|
|
|
0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d,
|
|
|
|
0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
|
|
|
|
};
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2006-11-01 01:48:25 +01:00
|
|
|
static const unsigned char jmp_arm_bytes[] =
|
2006-05-11 10:48:58 +02:00
|
|
|
{
|
|
|
|
0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
|
|
|
|
0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
|
|
|
|
0, 0, 0, 0
|
|
|
|
};
|
|
|
|
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
static bfd *
|
2007-01-19 16:40:55 +01:00
|
|
|
make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
asection *tx, *id7, *id5, *id4, *id6;
|
2000-10-10 05:28:01 +02:00
|
|
|
unsigned char *td = NULL, *d7, *d5, *d4, *d6 = NULL;
|
1999-05-03 09:29:11 +02:00
|
|
|
int len;
|
|
|
|
char *oname;
|
|
|
|
bfd *abfd;
|
2006-11-01 01:48:25 +01:00
|
|
|
const unsigned char *jmp_bytes = NULL;
|
2000-03-01 21:54:37 +01:00
|
|
|
int jmp_byte_count = 0;
|
1999-05-11 23:06:50 +02:00
|
|
|
|
2007-01-19 16:40:55 +01:00
|
|
|
/* Include the jump stub section only if it is needed. A jump
|
|
|
|
stub is needed if the symbol being imported <sym> is a function
|
|
|
|
symbol and there is at least one undefined reference to that
|
|
|
|
symbol. In other words, if all the import references to <sym> are
|
|
|
|
explicitly through _declspec(dllimport) then the jump stub is not
|
|
|
|
needed. */
|
|
|
|
if (include_jmp_stub)
|
1999-05-11 23:06:50 +02:00
|
|
|
{
|
2007-01-19 16:40:55 +01:00
|
|
|
switch (pe_details->pe_arch)
|
|
|
|
{
|
|
|
|
case PE_ARCH_i386:
|
|
|
|
jmp_bytes = jmp_ix86_bytes;
|
|
|
|
jmp_byte_count = sizeof (jmp_ix86_bytes);
|
|
|
|
break;
|
|
|
|
case PE_ARCH_sh:
|
|
|
|
jmp_bytes = jmp_sh_bytes;
|
|
|
|
jmp_byte_count = sizeof (jmp_sh_bytes);
|
|
|
|
break;
|
|
|
|
case PE_ARCH_mips:
|
|
|
|
jmp_bytes = jmp_mips_bytes;
|
|
|
|
jmp_byte_count = sizeof (jmp_mips_bytes);
|
|
|
|
break;
|
|
|
|
case PE_ARCH_arm:
|
|
|
|
case PE_ARCH_arm_epoc:
|
|
|
|
case PE_ARCH_arm_wince:
|
|
|
|
jmp_bytes = jmp_arm_bytes;
|
|
|
|
jmp_byte_count = sizeof (jmp_arm_bytes);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort ();
|
|
|
|
}
|
1999-05-11 23:06:50 +02:00
|
|
|
}
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
oname = xmalloc (20);
|
1999-05-03 09:29:11 +02:00
|
|
|
sprintf (oname, "d%06d.o", tmp_seq);
|
|
|
|
tmp_seq++;
|
|
|
|
|
|
|
|
abfd = bfd_create (oname, parent);
|
1999-05-11 23:06:50 +02:00
|
|
|
bfd_find_target (pe_details->object_target, abfd);
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_make_writable (abfd);
|
|
|
|
|
|
|
|
bfd_set_format (abfd, bfd_object);
|
1999-05-11 23:06:50 +02:00
|
|
|
bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
symptr = 0;
|
2010-03-18 11:51:31 +01:00
|
|
|
symtab = xmalloc (12 * sizeof (asymbol *));
|
|
|
|
|
|
|
|
tx = quick_section (abfd, ".text", SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY, 2);
|
1999-05-03 09:29:11 +02:00
|
|
|
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);
|
|
|
|
id6 = quick_section (abfd, ".idata$6", SEC_HAS_CONTENTS, 2);
|
2002-11-30 09:39:46 +01:00
|
|
|
|
2002-11-06 20:36:20 +01:00
|
|
|
if (*exp->internal_name == '@')
|
|
|
|
{
|
2003-06-28 07:28:54 +02:00
|
|
|
quick_symbol (abfd, U ("_head_"), dll_symname, "", UNDSEC,
|
|
|
|
BSF_GLOBAL, 0);
|
2007-01-19 16:40:55 +01:00
|
|
|
if (include_jmp_stub)
|
2003-10-02 13:18:13 +02:00
|
|
|
quick_symbol (abfd, "", exp->internal_name, "", tx, BSF_GLOBAL, 0);
|
2006-10-03 12:06:26 +02:00
|
|
|
quick_symbol (abfd, "__imp_", exp->internal_name, "", id5,
|
2003-06-28 07:28:54 +02:00
|
|
|
BSF_GLOBAL, 0);
|
2002-11-06 20:36:20 +01:00
|
|
|
/* Fastcall applies only to functions,
|
|
|
|
so no need for auto-import symbol. */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-10-02 13:18:13 +02:00
|
|
|
quick_symbol (abfd, U ("_head_"), dll_symname, "", UNDSEC,
|
|
|
|
BSF_GLOBAL, 0);
|
2007-01-19 16:40:55 +01:00
|
|
|
if (include_jmp_stub)
|
2003-06-28 07:28:54 +02:00
|
|
|
quick_symbol (abfd, U (""), exp->internal_name, "", tx,
|
|
|
|
BSF_GLOBAL, 0);
|
2006-10-03 12:06:26 +02:00
|
|
|
quick_symbol (abfd, "__imp_", U (""), exp->internal_name, id5,
|
2003-06-28 07:28:54 +02:00
|
|
|
BSF_GLOBAL, 0);
|
2002-11-06 20:36:20 +01:00
|
|
|
/* Symbol to reference ord/name of imported
|
2003-06-28 07:28:54 +02:00
|
|
|
data symbol, used to implement auto-import. */
|
2002-11-06 20:36:20 +01:00
|
|
|
if (exp->flag_data)
|
2010-04-28 17:24:22 +02:00
|
|
|
quick_symbol (abfd, "__nm_", U (""), exp->internal_name, id6,
|
2003-06-28 07:28:54 +02:00
|
|
|
BSF_GLOBAL,0);
|
2002-11-06 20:36:20 +01:00
|
|
|
}
|
2000-01-05 00:44:03 +01:00
|
|
|
if (pe_dll_compat_implib)
|
2010-04-28 17:24:22 +02:00
|
|
|
quick_symbol (abfd, "___imp_", exp->internal_name, "", id5,
|
2003-06-28 07:28:54 +02:00
|
|
|
BSF_GLOBAL, 0);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2007-01-19 16:40:55 +01:00
|
|
|
if (include_jmp_stub)
|
2001-09-14 16:19:05 +02:00
|
|
|
{
|
|
|
|
bfd_set_section_size (abfd, tx, jmp_byte_count);
|
2003-06-28 07:28:54 +02:00
|
|
|
td = xmalloc (jmp_byte_count);
|
2001-09-14 16:19:05 +02:00
|
|
|
tx->contents = td;
|
|
|
|
memcpy (td, jmp_bytes, jmp_byte_count);
|
|
|
|
|
|
|
|
switch (pe_details->pe_arch)
|
|
|
|
{
|
|
|
|
case PE_ARCH_i386:
|
2007-03-16 16:13:21 +01:00
|
|
|
#ifdef pe_use_x86_64
|
|
|
|
quick_reloc (abfd, 2, BFD_RELOC_32_PCREL, 2);
|
|
|
|
#else
|
2010-03-18 11:51:31 +01:00
|
|
|
/* Mark this object as SAFESEH compatible. */
|
|
|
|
quick_symbol (abfd, "", "@feat.00", "", bfd_abs_section_ptr,
|
|
|
|
BSF_LOCAL, 1);
|
2007-03-16 16:13:21 +01:00
|
|
|
quick_reloc (abfd, 2, BFD_RELOC_32, 2);
|
|
|
|
#endif
|
2001-09-14 16:19:05 +02:00
|
|
|
break;
|
|
|
|
case PE_ARCH_sh:
|
|
|
|
quick_reloc (abfd, 8, BFD_RELOC_32, 2);
|
|
|
|
break;
|
|
|
|
case PE_ARCH_mips:
|
|
|
|
quick_reloc (abfd, 0, BFD_RELOC_HI16_S, 2);
|
|
|
|
quick_reloc (abfd, 0, BFD_RELOC_LO16, 0); /* MIPS_R_PAIR */
|
|
|
|
quick_reloc (abfd, 4, BFD_RELOC_LO16, 2);
|
|
|
|
break;
|
2006-05-11 10:48:58 +02:00
|
|
|
case PE_ARCH_arm:
|
2006-08-21 10:12:46 +02:00
|
|
|
case PE_ARCH_arm_epoc:
|
|
|
|
case PE_ARCH_arm_wince:
|
2006-05-11 10:48:58 +02:00
|
|
|
quick_reloc (abfd, 8, BFD_RELOC_32, 2);
|
|
|
|
break;
|
2001-09-14 16:19:05 +02:00
|
|
|
default:
|
|
|
|
abort ();
|
|
|
|
}
|
|
|
|
save_relocs (tx);
|
|
|
|
}
|
2007-01-19 16:40:55 +01:00
|
|
|
else
|
|
|
|
bfd_set_section_size (abfd, tx, 0);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
bfd_set_section_size (abfd, id7, 4);
|
2003-06-28 07:28:54 +02:00
|
|
|
d7 = xmalloc (4);
|
1999-05-03 09:29:11 +02:00
|
|
|
id7->contents = d7;
|
|
|
|
memset (d7, 0, 4);
|
2003-10-02 13:18:13 +02:00
|
|
|
quick_reloc (abfd, 0, BFD_RELOC_RVA, 5);
|
1999-05-03 09:29:11 +02:00
|
|
|
save_relocs (id7);
|
|
|
|
|
2006-09-20 13:35:11 +02:00
|
|
|
bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE);
|
|
|
|
d5 = xmalloc (PE_IDATA5_SIZE);
|
1999-05-03 09:29:11 +02:00
|
|
|
id5->contents = d5;
|
2006-09-20 13:35:11 +02:00
|
|
|
memset (d5, 0, PE_IDATA5_SIZE);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (exp->flag_noname)
|
|
|
|
{
|
|
|
|
d5[0] = exp->ordinal;
|
|
|
|
d5[1] = exp->ordinal >> 8;
|
2006-09-20 13:35:11 +02:00
|
|
|
d5[PE_IDATA5_SIZE - 1] = 0x80;
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
quick_reloc (abfd, 0, BFD_RELOC_RVA, 4);
|
|
|
|
save_relocs (id5);
|
|
|
|
}
|
|
|
|
|
2006-09-20 13:35:11 +02:00
|
|
|
bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE);
|
|
|
|
d4 = xmalloc (PE_IDATA4_SIZE);
|
1999-05-03 09:29:11 +02:00
|
|
|
id4->contents = d4;
|
2006-09-20 13:35:11 +02:00
|
|
|
memset (d4, 0, PE_IDATA4_SIZE);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (exp->flag_noname)
|
|
|
|
{
|
2000-10-04 00:07:17 +02:00
|
|
|
d4[0] = exp->ordinal;
|
|
|
|
d4[1] = exp->ordinal >> 8;
|
2006-09-20 13:35:11 +02:00
|
|
|
d4[PE_IDATA4_SIZE - 1] = 0x80;
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
quick_reloc (abfd, 0, BFD_RELOC_RVA, 4);
|
|
|
|
save_relocs (id4);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (exp->flag_noname)
|
|
|
|
{
|
|
|
|
len = 0;
|
|
|
|
bfd_set_section_size (abfd, id6, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-11-01 01:48:25 +01:00
|
|
|
/* { short, asciz } */
|
2009-10-23 13:40:17 +02:00
|
|
|
if (exp->its_name)
|
|
|
|
len = 2 + strlen (exp->its_name) + 1;
|
|
|
|
else
|
|
|
|
len = 2 + strlen (exp->name) + 1;
|
1999-05-03 09:29:11 +02:00
|
|
|
if (len & 1)
|
|
|
|
len++;
|
|
|
|
bfd_set_section_size (abfd, id6, len);
|
2003-06-28 07:28:54 +02:00
|
|
|
d6 = xmalloc (len);
|
1999-05-03 09:29:11 +02:00
|
|
|
id6->contents = d6;
|
|
|
|
memset (d6, 0, len);
|
|
|
|
d6[0] = exp->hint & 0xff;
|
|
|
|
d6[1] = exp->hint >> 8;
|
2009-10-23 13:40:17 +02:00
|
|
|
if (exp->its_name)
|
|
|
|
strcpy ((char*) d6 + 2, exp->its_name);
|
|
|
|
else
|
|
|
|
strcpy ((char *) d6 + 2, exp->name);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bfd_set_symtab (abfd, symtab, symptr);
|
|
|
|
|
2007-01-19 16:40:55 +01:00
|
|
|
if (include_jmp_stub)
|
|
|
|
bfd_set_section_contents (abfd, tx, td, 0, jmp_byte_count);
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_set_section_contents (abfd, id7, d7, 0, 4);
|
2006-09-20 13:35:11 +02:00
|
|
|
bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA5_SIZE);
|
|
|
|
bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE);
|
1999-05-03 09:29:11 +02:00
|
|
|
if (!exp->flag_noname)
|
|
|
|
bfd_set_section_contents (abfd, id6, d6, 0, len);
|
|
|
|
|
|
|
|
bfd_make_readable (abfd);
|
|
|
|
return abfd;
|
|
|
|
}
|
|
|
|
|
2009-01-26 11:29:11 +01:00
|
|
|
static bfd *
|
|
|
|
make_singleton_name_imp (const char *import, bfd *parent)
|
|
|
|
{
|
|
|
|
/* Name thunks go to idata$4. */
|
|
|
|
asection *id5;
|
|
|
|
unsigned char *d5;
|
|
|
|
char *oname;
|
|
|
|
bfd *abfd;
|
|
|
|
|
|
|
|
oname = xmalloc (20);
|
|
|
|
sprintf (oname, "nmimp%06d.o", tmp_seq2);
|
|
|
|
tmp_seq2++;
|
|
|
|
|
|
|
|
abfd = bfd_create (oname, parent);
|
|
|
|
bfd_find_target (pe_details->object_target, abfd);
|
|
|
|
bfd_make_writable (abfd);
|
|
|
|
|
|
|
|
bfd_set_format (abfd, bfd_object);
|
|
|
|
bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
|
|
|
|
|
|
|
|
symptr = 0;
|
|
|
|
symtab = xmalloc (3 * sizeof (asymbol *));
|
|
|
|
id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
|
2010-04-28 17:24:22 +02:00
|
|
|
quick_symbol (abfd, "__imp_", import, "", id5, BSF_GLOBAL, 0);
|
2009-01-26 11:29:11 +01:00
|
|
|
|
|
|
|
/* We need space for the real thunk and for the null terminator. */
|
|
|
|
bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE * 2);
|
|
|
|
d5 = xmalloc (PE_IDATA5_SIZE * 2);
|
|
|
|
id5->contents = d5;
|
|
|
|
memset (d5, 0, PE_IDATA5_SIZE * 2);
|
|
|
|
quick_reloc (abfd, 0, BFD_RELOC_RVA, 2);
|
|
|
|
save_relocs (id5);
|
|
|
|
|
|
|
|
bfd_set_symtab (abfd, symtab, symptr);
|
|
|
|
|
|
|
|
bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA4_SIZE * 2);
|
|
|
|
|
|
|
|
bfd_make_readable (abfd);
|
|
|
|
return abfd;
|
|
|
|
}
|
|
|
|
|
2001-08-03 01:12:02 +02:00
|
|
|
static bfd *
|
2003-06-28 07:28:54 +02:00
|
|
|
make_singleton_name_thunk (const char *import, bfd *parent)
|
2001-08-03 01:12:02 +02:00
|
|
|
{
|
2001-09-14 16:19:05 +02:00
|
|
|
/* Name thunks go to idata$4. */
|
2001-08-03 01:12:02 +02:00
|
|
|
asection *id4;
|
|
|
|
unsigned char *d4;
|
|
|
|
char *oname;
|
|
|
|
bfd *abfd;
|
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
oname = xmalloc (20);
|
2001-08-03 01:12:02 +02:00
|
|
|
sprintf (oname, "nmth%06d.o", tmp_seq);
|
|
|
|
tmp_seq++;
|
|
|
|
|
|
|
|
abfd = bfd_create (oname, parent);
|
|
|
|
bfd_find_target (pe_details->object_target, abfd);
|
|
|
|
bfd_make_writable (abfd);
|
|
|
|
|
|
|
|
bfd_set_format (abfd, bfd_object);
|
|
|
|
bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
|
|
|
|
|
|
|
|
symptr = 0;
|
2003-06-28 07:28:54 +02:00
|
|
|
symtab = xmalloc (3 * sizeof (asymbol *));
|
2001-08-03 01:12:02 +02:00
|
|
|
id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
|
2010-04-28 17:24:22 +02:00
|
|
|
quick_symbol (abfd, "__nm_thnk_", import, "", id4, BSF_GLOBAL, 0);
|
|
|
|
quick_symbol (abfd, "__nm_", import, "", UNDSEC, BSF_GLOBAL, 0);
|
2001-08-03 01:12:02 +02:00
|
|
|
|
2006-10-29 18:14:37 +01:00
|
|
|
/* We need space for the real thunk and for the null terminator. */
|
|
|
|
bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE * 2);
|
|
|
|
d4 = xmalloc (PE_IDATA4_SIZE * 2);
|
2001-08-03 01:12:02 +02:00
|
|
|
id4->contents = d4;
|
2006-10-29 18:14:37 +01:00
|
|
|
memset (d4, 0, PE_IDATA4_SIZE * 2);
|
2001-08-03 01:12:02 +02:00
|
|
|
quick_reloc (abfd, 0, BFD_RELOC_RVA, 2);
|
|
|
|
save_relocs (id4);
|
|
|
|
|
|
|
|
bfd_set_symtab (abfd, symtab, symptr);
|
|
|
|
|
2006-10-29 18:14:37 +01:00
|
|
|
bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE * 2);
|
2001-08-03 01:12:02 +02:00
|
|
|
|
|
|
|
bfd_make_readable (abfd);
|
|
|
|
return abfd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
2003-06-28 07:28:54 +02:00
|
|
|
make_import_fixup_mark (arelent *rel)
|
2001-08-03 01:12:02 +02:00
|
|
|
{
|
2001-09-14 16:19:05 +02:00
|
|
|
/* We convert reloc to symbol, for later reference. */
|
2001-08-03 01:12:02 +02:00
|
|
|
static int counter;
|
|
|
|
static char *fixup_name = NULL;
|
2001-09-18 12:10:21 +02:00
|
|
|
static size_t buffer_len = 0;
|
2002-05-03 15:48:55 +02:00
|
|
|
|
Index: sim/frv/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* traps.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
Index: sim/d10v/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* simops.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
Index: sim/common/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* sim-trace.c, sim-base.h: Replace "struct symbol_cache_entry"
with "struct bfd_symbol".
Index: ld/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* emultempl/pe.em, pe-dll.c: Replace "struct symbol_cache_entry"
with "struct bfd_symbol".
Index: bfd/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* syms.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
* vms.h, targets.c, section.c, reloc.c, peicode.h: Ditto.
* mipsbsd.c, elf.c, linker.c, elf-bfd.h, ecoff.c: Ditto.
* cpu-z8k.c, cpu-ns32k.c, cpu-h8500.c, bfd.c, bfd-in.h: Ditto.
* bfd-in2.h: Re-generate.
2003-10-31 06:32:46 +01:00
|
|
|
struct bfd_symbol *sym = *rel->sym_ptr_ptr;
|
2002-05-03 15:48:55 +02:00
|
|
|
|
2001-08-03 01:12:02 +02:00
|
|
|
bfd *abfd = bfd_asymbol_bfd (sym);
|
2002-10-11 10:59:24 +02:00
|
|
|
struct bfd_link_hash_entry *bh;
|
2001-08-03 01:12:02 +02:00
|
|
|
|
|
|
|
if (!fixup_name)
|
|
|
|
{
|
2003-06-28 07:28:54 +02:00
|
|
|
fixup_name = xmalloc (384);
|
2001-08-03 01:12:02 +02:00
|
|
|
buffer_len = 384;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strlen (sym->name) + 25 > buffer_len)
|
2002-05-03 15:48:55 +02:00
|
|
|
/* Assume 25 chars for "__fu" + counter + "_". If counter is
|
2001-08-03 01:12:02 +02:00
|
|
|
bigger than 20 digits long, we've got worse problems than
|
2001-09-14 16:19:05 +02:00
|
|
|
overflowing this buffer... */
|
2001-08-03 01:12:02 +02:00
|
|
|
{
|
|
|
|
free (fixup_name);
|
2003-01-28 12:39:43 +01:00
|
|
|
/* New buffer size is length of symbol, plus 25, but
|
|
|
|
then rounded up to the nearest multiple of 128. */
|
2001-08-03 01:12:02 +02:00
|
|
|
buffer_len = ((strlen (sym->name) + 25) + 127) & ~127;
|
2003-06-28 07:28:54 +02:00
|
|
|
fixup_name = xmalloc (buffer_len);
|
2001-08-03 01:12:02 +02:00
|
|
|
}
|
2002-05-03 15:48:55 +02:00
|
|
|
|
2001-08-03 01:12:02 +02:00
|
|
|
sprintf (fixup_name, "__fu%d_%s", counter++, sym->name);
|
|
|
|
|
2002-10-11 10:59:24 +02:00
|
|
|
bh = NULL;
|
2002-05-03 15:48:55 +02:00
|
|
|
bfd_coff_link_add_one_symbol (&link_info, abfd, fixup_name, BSF_GLOBAL,
|
2001-08-03 01:12:02 +02:00
|
|
|
current_sec, /* sym->section, */
|
2002-11-30 09:39:46 +01:00
|
|
|
rel->address, NULL, TRUE, FALSE, &bh);
|
2002-10-11 10:59:24 +02:00
|
|
|
|
2001-08-03 01:12:02 +02:00
|
|
|
return fixup_name;
|
|
|
|
}
|
|
|
|
|
2006-05-11 10:48:58 +02:00
|
|
|
/* .section .idata$2
|
2001-09-14 16:19:05 +02:00
|
|
|
.rva __nm_thnk_SYM (singleton thunk with name of func)
|
|
|
|
.long 0
|
|
|
|
.long 0
|
|
|
|
.rva __my_dll_iname (name of dll)
|
|
|
|
.rva __fuNN_SYM (pointer to reference (address) in text) */
|
2001-08-03 01:12:02 +02:00
|
|
|
|
|
|
|
static bfd *
|
2003-06-28 07:28:54 +02:00
|
|
|
make_import_fixup_entry (const char *name,
|
|
|
|
const char *fixup_name,
|
2009-12-11 14:42:17 +01:00
|
|
|
const char *symname,
|
2003-06-28 07:28:54 +02:00
|
|
|
bfd *parent)
|
2001-08-03 01:12:02 +02:00
|
|
|
{
|
2006-05-11 10:48:58 +02:00
|
|
|
asection *id2;
|
|
|
|
unsigned char *d2;
|
2001-08-03 01:12:02 +02:00
|
|
|
char *oname;
|
|
|
|
bfd *abfd;
|
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
oname = xmalloc (20);
|
2001-08-03 01:12:02 +02:00
|
|
|
sprintf (oname, "fu%06d.o", tmp_seq);
|
|
|
|
tmp_seq++;
|
|
|
|
|
|
|
|
abfd = bfd_create (oname, parent);
|
|
|
|
bfd_find_target (pe_details->object_target, abfd);
|
|
|
|
bfd_make_writable (abfd);
|
|
|
|
|
|
|
|
bfd_set_format (abfd, bfd_object);
|
|
|
|
bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
|
|
|
|
|
|
|
|
symptr = 0;
|
2003-06-28 07:28:54 +02:00
|
|
|
symtab = xmalloc (6 * sizeof (asymbol *));
|
2006-05-11 10:48:58 +02:00
|
|
|
id2 = quick_section (abfd, ".idata$2", SEC_HAS_CONTENTS, 2);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2010-04-28 17:24:22 +02:00
|
|
|
quick_symbol (abfd, "__nm_thnk_", name, "", UNDSEC, BSF_GLOBAL, 0);
|
2009-12-11 14:42:17 +01:00
|
|
|
quick_symbol (abfd, U (""), symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
|
2010-05-15 16:20:06 +02:00
|
|
|
/* For relocator v2 we have to use the .idata$5 element and not
|
2009-01-26 11:29:11 +01:00
|
|
|
fixup_name. */
|
|
|
|
if (link_info.pei386_runtime_pseudo_reloc == 2)
|
2010-04-28 17:24:22 +02:00
|
|
|
quick_symbol (abfd, "__imp_", name, "", UNDSEC, BSF_GLOBAL, 0);
|
2009-01-26 11:29:11 +01:00
|
|
|
else
|
|
|
|
quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
|
2001-08-03 01:12:02 +02:00
|
|
|
|
2006-05-11 10:48:58 +02:00
|
|
|
bfd_set_section_size (abfd, id2, 20);
|
|
|
|
d2 = xmalloc (20);
|
|
|
|
id2->contents = d2;
|
|
|
|
memset (d2, 0, 20);
|
2001-08-03 01:12:02 +02:00
|
|
|
|
|
|
|
quick_reloc (abfd, 0, BFD_RELOC_RVA, 1);
|
|
|
|
quick_reloc (abfd, 12, BFD_RELOC_RVA, 2);
|
|
|
|
quick_reloc (abfd, 16, BFD_RELOC_RVA, 3);
|
2006-05-11 10:48:58 +02:00
|
|
|
save_relocs (id2);
|
2001-08-03 01:12:02 +02:00
|
|
|
|
|
|
|
bfd_set_symtab (abfd, symtab, symptr);
|
|
|
|
|
2006-05-11 10:48:58 +02:00
|
|
|
bfd_set_section_contents (abfd, id2, d2, 0, 20);
|
2001-08-03 01:12:02 +02:00
|
|
|
|
|
|
|
bfd_make_readable (abfd);
|
|
|
|
return abfd;
|
|
|
|
}
|
|
|
|
|
2002-11-14 19:03:17 +01:00
|
|
|
/* .section .rdata_runtime_pseudo_reloc
|
|
|
|
.long addend
|
|
|
|
.rva __fuNN_SYM (pointer to reference (address) in text) */
|
|
|
|
|
|
|
|
static bfd *
|
2003-06-28 07:28:54 +02:00
|
|
|
make_runtime_pseudo_reloc (const char *name ATTRIBUTE_UNUSED,
|
|
|
|
const char *fixup_name,
|
2008-11-14 16:13:05 +01:00
|
|
|
bfd_vma addend ATTRIBUTE_UNUSED,
|
|
|
|
bfd_vma bitsize,
|
2003-06-28 07:28:54 +02:00
|
|
|
bfd *parent)
|
2002-11-14 19:03:17 +01:00
|
|
|
{
|
|
|
|
asection *rt_rel;
|
|
|
|
unsigned char *rt_rel_d;
|
|
|
|
char *oname;
|
|
|
|
bfd *abfd;
|
2003-06-28 07:28:54 +02:00
|
|
|
oname = xmalloc (20);
|
2002-11-14 19:03:17 +01:00
|
|
|
sprintf (oname, "rtr%06d.o", tmp_seq);
|
|
|
|
tmp_seq++;
|
|
|
|
|
|
|
|
abfd = bfd_create (oname, parent);
|
|
|
|
bfd_find_target (pe_details->object_target, abfd);
|
|
|
|
bfd_make_writable (abfd);
|
|
|
|
|
|
|
|
bfd_set_format (abfd, bfd_object);
|
|
|
|
bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
|
|
|
|
|
|
|
|
symptr = 0;
|
2008-12-02 10:33:12 +01:00
|
|
|
if (link_info.pei386_runtime_pseudo_reloc == 2)
|
|
|
|
{
|
|
|
|
symtab = xmalloc ((runtime_pseudp_reloc_v2_init ? 3 : 6) * sizeof (asymbol *));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
symtab = xmalloc (2 * sizeof (asymbol *));
|
|
|
|
}
|
2003-06-28 07:28:54 +02:00
|
|
|
rt_rel = quick_section (abfd, ".rdata_runtime_pseudo_reloc",
|
|
|
|
SEC_HAS_CONTENTS, 2);
|
2002-11-14 19:03:17 +01:00
|
|
|
|
|
|
|
quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
|
|
|
|
|
2008-11-14 16:13:05 +01:00
|
|
|
if (link_info.pei386_runtime_pseudo_reloc == 2)
|
|
|
|
{
|
|
|
|
size_t size = 12;
|
|
|
|
if (! runtime_pseudp_reloc_v2_init)
|
|
|
|
{
|
|
|
|
size += 12;
|
|
|
|
runtime_pseudp_reloc_v2_init = 1;
|
|
|
|
}
|
2010-04-28 17:24:22 +02:00
|
|
|
quick_symbol (abfd, "__imp_", name, "", UNDSEC, BSF_GLOBAL, 0);
|
2008-11-14 16:13:05 +01:00
|
|
|
|
|
|
|
bfd_set_section_size (abfd, rt_rel, size);
|
|
|
|
rt_rel_d = xmalloc (size);
|
|
|
|
rt_rel->contents = rt_rel_d;
|
|
|
|
memset (rt_rel_d, 0, size);
|
|
|
|
quick_reloc (abfd, size - 8, BFD_RELOC_RVA, 1);
|
|
|
|
quick_reloc (abfd, size - 12, BFD_RELOC_RVA, 2);
|
|
|
|
bfd_put_32 (abfd, bitsize, rt_rel_d + (size - 4));
|
|
|
|
if (size != 12)
|
|
|
|
bfd_put_32 (abfd, 1, rt_rel_d + 8);
|
|
|
|
save_relocs (rt_rel);
|
|
|
|
|
|
|
|
bfd_set_symtab (abfd, symtab, symptr);
|
|
|
|
|
|
|
|
bfd_set_section_contents (abfd, rt_rel, rt_rel_d, 0, size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bfd_set_section_size (abfd, rt_rel, 8);
|
|
|
|
rt_rel_d = xmalloc (8);
|
|
|
|
rt_rel->contents = rt_rel_d;
|
|
|
|
memset (rt_rel_d, 0, 8);
|
2002-11-14 19:03:17 +01:00
|
|
|
|
2008-11-14 16:13:05 +01:00
|
|
|
bfd_put_32 (abfd, addend, rt_rel_d);
|
|
|
|
quick_reloc (abfd, 4, BFD_RELOC_RVA, 1);
|
2002-11-14 19:03:17 +01:00
|
|
|
|
2008-11-14 16:13:05 +01:00
|
|
|
save_relocs (rt_rel);
|
2002-11-14 19:03:17 +01:00
|
|
|
|
2008-11-14 16:13:05 +01:00
|
|
|
bfd_set_symtab (abfd, symtab, symptr);
|
2002-11-14 19:03:17 +01:00
|
|
|
|
2008-11-14 16:13:05 +01:00
|
|
|
bfd_set_section_contents (abfd, rt_rel, rt_rel_d, 0, 8);
|
|
|
|
}
|
2002-11-14 19:03:17 +01:00
|
|
|
bfd_make_readable (abfd);
|
|
|
|
return abfd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* .section .rdata
|
2003-01-28 12:39:43 +01:00
|
|
|
.rva __pei386_runtime_relocator */
|
2002-11-14 19:03:17 +01:00
|
|
|
|
|
|
|
static bfd *
|
2003-06-28 07:28:54 +02:00
|
|
|
pe_create_runtime_relocator_reference (bfd *parent)
|
2002-11-14 19:03:17 +01:00
|
|
|
{
|
|
|
|
asection *extern_rt_rel;
|
|
|
|
unsigned char *extern_rt_rel_d;
|
|
|
|
char *oname;
|
|
|
|
bfd *abfd;
|
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
oname = xmalloc (20);
|
2002-11-14 19:03:17 +01:00
|
|
|
sprintf (oname, "ertr%06d.o", tmp_seq);
|
|
|
|
tmp_seq++;
|
|
|
|
|
|
|
|
abfd = bfd_create (oname, parent);
|
|
|
|
bfd_find_target (pe_details->object_target, abfd);
|
|
|
|
bfd_make_writable (abfd);
|
|
|
|
|
|
|
|
bfd_set_format (abfd, bfd_object);
|
|
|
|
bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
|
|
|
|
|
|
|
|
symptr = 0;
|
2003-06-28 07:28:54 +02:00
|
|
|
symtab = xmalloc (2 * sizeof (asymbol *));
|
2002-11-14 19:03:17 +01:00
|
|
|
extern_rt_rel = quick_section (abfd, ".rdata", SEC_HAS_CONTENTS, 2);
|
|
|
|
|
2006-10-03 12:06:26 +02:00
|
|
|
quick_symbol (abfd, "", U ("_pei386_runtime_relocator"), "", UNDSEC,
|
2003-06-28 07:28:54 +02:00
|
|
|
BSF_NO_FLAGS, 0);
|
2002-11-14 19:03:17 +01:00
|
|
|
|
2009-01-26 11:29:11 +01:00
|
|
|
bfd_set_section_size (abfd, extern_rt_rel, PE_IDATA5_SIZE);
|
|
|
|
extern_rt_rel_d = xmalloc (PE_IDATA5_SIZE);
|
2002-11-14 19:03:17 +01:00
|
|
|
extern_rt_rel->contents = extern_rt_rel_d;
|
|
|
|
|
|
|
|
quick_reloc (abfd, 0, BFD_RELOC_RVA, 1);
|
|
|
|
save_relocs (extern_rt_rel);
|
|
|
|
|
|
|
|
bfd_set_symtab (abfd, symtab, symptr);
|
|
|
|
|
2009-01-26 11:29:11 +01:00
|
|
|
bfd_set_section_contents (abfd, extern_rt_rel, extern_rt_rel_d, 0, PE_IDATA5_SIZE);
|
2002-11-14 19:03:17 +01:00
|
|
|
|
|
|
|
bfd_make_readable (abfd);
|
|
|
|
return abfd;
|
|
|
|
}
|
|
|
|
|
2001-08-03 01:12:02 +02:00
|
|
|
void
|
2008-11-14 16:13:05 +01:00
|
|
|
pe_create_import_fixup (arelent *rel, asection *s, bfd_vma addend)
|
2001-08-03 01:12:02 +02:00
|
|
|
{
|
|
|
|
char buf[300];
|
Index: sim/frv/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* traps.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
Index: sim/d10v/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* simops.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
Index: sim/common/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* sim-trace.c, sim-base.h: Replace "struct symbol_cache_entry"
with "struct bfd_symbol".
Index: ld/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* emultempl/pe.em, pe-dll.c: Replace "struct symbol_cache_entry"
with "struct bfd_symbol".
Index: bfd/ChangeLog
2003-10-30 Andrew Cagney <cagney@redhat.com>
* syms.c: Replace "struct symbol_cache_entry" with "struct
bfd_symbol".
* vms.h, targets.c, section.c, reloc.c, peicode.h: Ditto.
* mipsbsd.c, elf.c, linker.c, elf-bfd.h, ecoff.c: Ditto.
* cpu-z8k.c, cpu-ns32k.c, cpu-h8500.c, bfd.c, bfd-in.h: Ditto.
* bfd-in2.h: Re-generate.
2003-10-31 06:32:46 +01:00
|
|
|
struct bfd_symbol *sym = *rel->sym_ptr_ptr;
|
2001-08-03 01:12:02 +02:00
|
|
|
struct bfd_link_hash_entry *name_thunk_sym;
|
2009-01-26 11:29:11 +01:00
|
|
|
struct bfd_link_hash_entry *name_imp_sym;
|
2001-09-18 12:10:21 +02:00
|
|
|
const char *name = sym->name;
|
2001-08-03 01:12:02 +02:00
|
|
|
char *fixup_name = make_import_fixup_mark (rel);
|
2002-11-14 19:03:17 +01:00
|
|
|
bfd *b;
|
2009-01-26 11:29:11 +01:00
|
|
|
int need_import_table = 1;
|
|
|
|
|
2010-04-28 17:24:22 +02:00
|
|
|
sprintf (buf, "__imp_%s", name);
|
2009-01-26 11:29:11 +01:00
|
|
|
name_imp_sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);
|
2001-08-03 01:12:02 +02:00
|
|
|
|
2010-04-28 17:24:22 +02:00
|
|
|
sprintf (buf, "__nm_thnk_%s", name);
|
2001-08-03 01:12:02 +02:00
|
|
|
|
|
|
|
name_thunk_sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);
|
|
|
|
|
2009-01-26 11:29:11 +01:00
|
|
|
/* For version 2 pseudo relocation we don't need to add an import
|
|
|
|
if the import symbol is already present. */
|
|
|
|
if (link_info.pei386_runtime_pseudo_reloc == 2
|
|
|
|
&& name_imp_sym
|
|
|
|
&& name_imp_sym->type == bfd_link_hash_defined)
|
|
|
|
need_import_table = 0;
|
|
|
|
|
|
|
|
if (need_import_table == 1
|
|
|
|
&& (!name_thunk_sym || name_thunk_sym->type != bfd_link_hash_defined))
|
2001-08-03 01:12:02 +02:00
|
|
|
{
|
2009-12-11 14:42:17 +01:00
|
|
|
b = make_singleton_name_thunk (name, link_info.output_bfd);
|
2001-08-03 01:12:02 +02:00
|
|
|
add_bfd_to_link (b, b->filename, &link_info);
|
|
|
|
|
2009-01-26 11:29:11 +01:00
|
|
|
/* If we ever use autoimport, we have to cast text section writable.
|
|
|
|
But not for version 2. */
|
|
|
|
if (link_info.pei386_runtime_pseudo_reloc != 2)
|
|
|
|
{
|
|
|
|
config.text_read_only = FALSE;
|
|
|
|
link_info.output_bfd->flags &= ~WP_TEXT;
|
|
|
|
}
|
|
|
|
if (link_info.pei386_runtime_pseudo_reloc == 2)
|
|
|
|
{
|
|
|
|
b = make_singleton_name_imp (name, link_info.output_bfd);
|
|
|
|
add_bfd_to_link (b, b->filename, &link_info);
|
|
|
|
}
|
2001-08-03 01:12:02 +02:00
|
|
|
}
|
|
|
|
|
2009-01-26 11:29:11 +01:00
|
|
|
if ((addend == 0 || link_info.pei386_runtime_pseudo_reloc)
|
|
|
|
&& need_import_table == 1)
|
2002-11-14 19:03:17 +01:00
|
|
|
{
|
|
|
|
extern char * pe_data_import_dll;
|
2009-12-11 14:42:17 +01:00
|
|
|
char * symname = pe_data_import_dll ? pe_data_import_dll : "unknown";
|
2001-09-24 20:21:24 +02:00
|
|
|
|
2009-12-11 14:42:17 +01:00
|
|
|
b = make_import_fixup_entry (name, fixup_name, symname,
|
2008-02-15 04:35:53 +01:00
|
|
|
link_info.output_bfd);
|
2002-11-14 19:03:17 +01:00
|
|
|
add_bfd_to_link (b, b->filename, &link_info);
|
|
|
|
}
|
|
|
|
|
2008-11-14 16:13:05 +01:00
|
|
|
if ((link_info.pei386_runtime_pseudo_reloc != 0 && addend != 0)
|
|
|
|
|| link_info.pei386_runtime_pseudo_reloc == 2)
|
|
|
|
{
|
|
|
|
if (pe_dll_extra_pe_debug)
|
|
|
|
printf ("creating runtime pseudo-reloc entry for %s (addend=%d)\n",
|
|
|
|
fixup_name, (int) addend);
|
|
|
|
|
|
|
|
b = make_runtime_pseudo_reloc (name, fixup_name, addend, rel->howto->bitsize,
|
|
|
|
link_info.output_bfd);
|
|
|
|
add_bfd_to_link (b, b->filename, &link_info);
|
|
|
|
|
|
|
|
if (runtime_pseudo_relocs_created == 0)
|
|
|
|
{
|
|
|
|
b = pe_create_runtime_relocator_reference (link_info.output_bfd);
|
|
|
|
add_bfd_to_link (b, b->filename, &link_info);
|
|
|
|
}
|
|
|
|
runtime_pseudo_relocs_created++;
|
|
|
|
}
|
|
|
|
else if (addend != 0)
|
|
|
|
{
|
|
|
|
einfo (_("%C: variable '%T' can't be auto-imported. Please read the documentation for ld's --enable-auto-import for details.\n"),
|
|
|
|
s->owner, s, rel->address, sym->name);
|
|
|
|
einfo ("%X");
|
|
|
|
}
|
2001-08-03 01:12:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
void
|
2009-01-03 19:04:16 +01:00
|
|
|
pe_dll_generate_implib (def_file *def, const char *impfilename, struct bfd_link_info *info)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
bfd *ar_head;
|
|
|
|
bfd *ar_tail;
|
|
|
|
bfd *outarch;
|
2009-01-03 19:04:16 +01:00
|
|
|
bfd *ibfd;
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd *head = 0;
|
|
|
|
|
2000-01-05 00:30:51 +01:00
|
|
|
dll_filename = (def->name) ? def->name : dll_name;
|
1999-05-03 09:29:11 +02:00
|
|
|
dll_symname = xstrdup (dll_filename);
|
2000-10-09 03:37:11 +02:00
|
|
|
for (i = 0; dll_symname[i]; i++)
|
2001-09-19 07:33:36 +02:00
|
|
|
if (!ISALNUM (dll_symname[i]))
|
1999-05-03 09:29:11 +02:00
|
|
|
dll_symname[i] = '_';
|
|
|
|
|
2005-03-02 10:03:58 +01:00
|
|
|
unlink_if_ordinary (impfilename);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
outarch = bfd_openw (impfilename, 0);
|
|
|
|
|
|
|
|
if (!outarch)
|
|
|
|
{
|
|
|
|
/* xgettext:c-format */
|
|
|
|
einfo (_("%XCan't open .lib file: %s\n"), impfilename);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-07-13 15:20:27 +02:00
|
|
|
if (verbose)
|
|
|
|
/* xgettext:c-format */
|
|
|
|
info_msg (_("Creating library file: %s\n"), impfilename);
|
2009-01-26 11:29:11 +01:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_set_format (outarch, bfd_archive);
|
|
|
|
outarch->has_armap = 1;
|
|
|
|
|
2000-09-29 15:21:41 +02:00
|
|
|
/* Work out a reasonable size of things to put onto one line. */
|
1999-05-03 09:29:11 +02:00
|
|
|
ar_head = make_head (outarch);
|
|
|
|
|
2009-01-03 19:04:16 +01:00
|
|
|
/* Iterate the input BFDs, looking for exclude-modules-for-implib. */
|
|
|
|
for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link_next)
|
|
|
|
{
|
|
|
|
/* Iterate the exclude list. */
|
|
|
|
struct exclude_list_struct *ex;
|
|
|
|
char found;
|
|
|
|
for (ex = excludes, found = 0; ex && !found; ex = ex->next)
|
|
|
|
{
|
|
|
|
if (ex->type != EXCLUDEFORIMPLIB)
|
|
|
|
continue;
|
2011-02-28 19:34:52 +01:00
|
|
|
found = (filename_cmp (ex->string, ibfd->filename) == 0);
|
2009-01-03 19:04:16 +01:00
|
|
|
}
|
|
|
|
/* 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
|
|
|
|
it into the archive member chain. */
|
|
|
|
if (found)
|
|
|
|
{
|
2009-01-26 11:29:11 +01:00
|
|
|
bfd *newbfd = bfd_openr (ibfd->my_archive
|
2009-01-03 19:04:16 +01:00
|
|
|
? ibfd->my_archive->filename : ibfd->filename, NULL);
|
|
|
|
if (!newbfd)
|
|
|
|
{
|
|
|
|
einfo (_("%Xbfd_openr %s: %E\n"), ibfd->filename);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (ibfd->my_archive)
|
|
|
|
{
|
|
|
|
/* Must now iterate through archive until we find the
|
|
|
|
required member. A minor shame that we'll open the
|
|
|
|
archive once per member that we require from it, and
|
|
|
|
leak those archive bfds rather than reuse them. */
|
|
|
|
bfd *arbfd = newbfd;
|
|
|
|
if (!bfd_check_format_matches (arbfd, bfd_archive, NULL))
|
|
|
|
{
|
2009-01-26 11:29:11 +01:00
|
|
|
einfo (_("%X%s(%s): can't find member in non-archive file"),
|
2009-01-03 19:04:16 +01:00
|
|
|
ibfd->my_archive->filename, ibfd->filename);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
newbfd = NULL;
|
|
|
|
while ((newbfd = bfd_openr_next_archived_file (arbfd, newbfd)) != 0)
|
|
|
|
{
|
2011-02-28 19:34:52 +01:00
|
|
|
if (filename_cmp (newbfd->filename, ibfd->filename) == 0)
|
2009-01-03 19:04:16 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!newbfd)
|
|
|
|
{
|
2009-01-26 11:29:11 +01:00
|
|
|
einfo (_("%X%s(%s): can't find member in archive"),
|
2009-01-03 19:04:16 +01:00
|
|
|
ibfd->my_archive->filename, ibfd->filename);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
newbfd->archive_next = head;
|
|
|
|
head = newbfd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-10-09 03:37:11 +02:00
|
|
|
for (i = 0; i < def->num_exports; i++)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
2000-10-09 09:01:29 +02:00
|
|
|
/* The import library doesn't know about the internal name. */
|
1999-05-03 09:29:11 +02:00
|
|
|
char *internal = def->exports[i].internal_name;
|
|
|
|
bfd *n;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2009-01-26 11:29:11 +01:00
|
|
|
/* Don't add PRIVATE entries to import lib. */
|
2004-03-08 12:33:59 +01:00
|
|
|
if (pe_def_file->exports[i].flag_private)
|
|
|
|
continue;
|
1999-05-03 09:29:11 +02:00
|
|
|
def->exports[i].internal_name = def->exports[i].name;
|
2007-01-19 16:40:55 +01:00
|
|
|
n = make_one (def->exports + i, outarch,
|
|
|
|
! (def->exports + i)->flag_data);
|
2007-06-27 13:54:10 +02:00
|
|
|
n->archive_next = head;
|
1999-05-03 09:29:11 +02:00
|
|
|
head = n;
|
|
|
|
def->exports[i].internal_name = internal;
|
|
|
|
}
|
|
|
|
|
1999-05-11 23:06:50 +02:00
|
|
|
ar_tail = make_tail (outarch);
|
|
|
|
|
|
|
|
if (ar_head == NULL || ar_tail == NULL)
|
|
|
|
return;
|
|
|
|
|
2000-10-09 09:01:29 +02:00
|
|
|
/* Now stick them all into the archive. */
|
2007-06-27 13:54:10 +02:00
|
|
|
ar_head->archive_next = head;
|
|
|
|
ar_tail->archive_next = ar_head;
|
1999-05-03 09:29:11 +02:00
|
|
|
head = ar_tail;
|
|
|
|
|
|
|
|
if (! bfd_set_archive_head (outarch, head))
|
2005-12-08 12:38:25 +01:00
|
|
|
einfo ("%Xbfd_set_archive_head: %E\n");
|
2000-09-29 15:21:41 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
if (! bfd_close (outarch))
|
2005-12-08 12:38:25 +01:00
|
|
|
einfo ("%Xbfd_close %s: %E\n", impfilename);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
while (head != NULL)
|
|
|
|
{
|
2007-06-27 13:54:10 +02:00
|
|
|
bfd *n = head->archive_next;
|
1999-05-03 09:29:11 +02:00
|
|
|
bfd_close (head);
|
|
|
|
head = n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-14 20:00:03 +01:00
|
|
|
static int undef_count = 0;
|
|
|
|
|
|
|
|
struct key_value
|
|
|
|
{
|
|
|
|
char *key;
|
|
|
|
const char *oname;
|
|
|
|
};
|
|
|
|
|
2012-05-07 12:52:00 +02:00
|
|
|
static struct key_value *udef_table;
|
2012-03-14 20:00:03 +01:00
|
|
|
|
|
|
|
static int undef_sort_cmp (const void *l1, const void *r1)
|
|
|
|
{
|
|
|
|
const struct key_value *l = l1;
|
|
|
|
const struct key_value *r = r1;
|
|
|
|
|
|
|
|
return strcmp (l->key, r->key);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct bfd_link_hash_entry *
|
|
|
|
pe_find_cdecl_alias_match (struct bfd_link_info *linfo, char *name)
|
|
|
|
{
|
|
|
|
struct bfd_link_hash_entry *h = NULL;
|
|
|
|
struct key_value *kv;
|
|
|
|
struct key_value key;
|
|
|
|
char *at, *lname = (char *) alloca (strlen (name) + 3);
|
|
|
|
|
|
|
|
strcpy (lname, name);
|
|
|
|
|
|
|
|
at = strchr (lname + (lname[0] == '@'), '@');
|
|
|
|
if (at)
|
|
|
|
at[1] = 0;
|
|
|
|
|
|
|
|
key.key = lname;
|
|
|
|
kv = bsearch (&key, udef_table, undef_count, sizeof (struct key_value),
|
|
|
|
undef_sort_cmp);
|
|
|
|
|
|
|
|
if (kv)
|
|
|
|
{
|
|
|
|
h = bfd_link_hash_lookup (linfo->hash, kv->oname, FALSE, FALSE, FALSE);
|
|
|
|
if (h->type == bfd_link_hash_undefined)
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
if (lname[0] == '?')
|
|
|
|
return NULL;
|
|
|
|
if (at || lname[0] == '@')
|
|
|
|
{
|
|
|
|
if (lname[0] == '@')
|
|
|
|
{
|
|
|
|
if (pe_details->underscored)
|
|
|
|
lname[0] = '_';
|
|
|
|
else
|
|
|
|
strcpy (lname, lname + 1);
|
|
|
|
key.key = lname;
|
|
|
|
kv = bsearch (&key, udef_table, undef_count,
|
|
|
|
sizeof (struct key_value), undef_sort_cmp);
|
|
|
|
if (kv)
|
|
|
|
{
|
|
|
|
h = bfd_link_hash_lookup (linfo->hash, kv->oname, FALSE, FALSE, FALSE);
|
|
|
|
if (h->type == bfd_link_hash_undefined)
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (at)
|
|
|
|
*strchr (lname, '@') = 0;
|
|
|
|
key.key = lname;
|
|
|
|
kv = bsearch (&key, udef_table, undef_count,
|
|
|
|
sizeof (struct key_value), undef_sort_cmp);
|
|
|
|
if (kv)
|
|
|
|
{
|
|
|
|
h = bfd_link_hash_lookup (linfo->hash, kv->oname, FALSE, FALSE, FALSE);
|
|
|
|
if (h->type == bfd_link_hash_undefined)
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
strcat (lname, "@");
|
|
|
|
key.key = lname;
|
|
|
|
kv = bsearch (&key, udef_table, undef_count,
|
|
|
|
sizeof (struct key_value), undef_sort_cmp);
|
|
|
|
|
|
|
|
if (kv)
|
|
|
|
{
|
|
|
|
h = bfd_link_hash_lookup (linfo->hash, kv->oname, FALSE, FALSE, FALSE);
|
|
|
|
if (h->type == bfd_link_hash_undefined)
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lname[0] == '_' && pe_details->underscored)
|
|
|
|
lname[0] = '@';
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memmove (lname + 1, lname, strlen (lname) + 1);
|
|
|
|
lname[0] = '@';
|
|
|
|
}
|
|
|
|
key.key = lname;
|
|
|
|
|
|
|
|
kv = bsearch (&key, udef_table, undef_count,
|
|
|
|
sizeof (struct key_value), undef_sort_cmp);
|
|
|
|
|
|
|
|
if (kv)
|
|
|
|
{
|
|
|
|
h = bfd_link_hash_lookup (linfo->hash, kv->oname, FALSE, FALSE, FALSE);
|
|
|
|
if (h->type == bfd_link_hash_undefined)
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-11-15 08:52:45 +01:00
|
|
|
|
|
|
|
static bfd_boolean
|
2012-03-14 20:00:03 +01:00
|
|
|
pe_undef_count (struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
|
|
|
|
void *inf ATTRIBUTE_UNUSED)
|
2009-11-15 08:52:45 +01:00
|
|
|
{
|
2012-03-14 20:00:03 +01:00
|
|
|
if (h->type == bfd_link_hash_undefined)
|
|
|
|
undef_count++;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bfd_boolean
|
|
|
|
pe_undef_fill (struct bfd_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
if (h->type == bfd_link_hash_undefined)
|
2009-11-15 08:52:45 +01:00
|
|
|
{
|
2012-03-14 20:00:03 +01:00
|
|
|
char *at;
|
|
|
|
|
|
|
|
udef_table[undef_count].key = xstrdup (h->root.string);
|
|
|
|
at = strchr (udef_table[undef_count].key
|
|
|
|
+ (udef_table[undef_count].key[0] == '@'), '@');
|
|
|
|
if (at)
|
|
|
|
at[1] = 0;
|
|
|
|
udef_table[undef_count].oname = h->root.string;
|
|
|
|
undef_count++;
|
2009-11-15 08:52:45 +01:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2012-03-14 20:00:03 +01:00
|
|
|
static void
|
|
|
|
pe_create_undef_table (void)
|
2009-11-15 08:52:45 +01:00
|
|
|
{
|
2012-03-14 20:00:03 +01:00
|
|
|
undef_count = 0;
|
|
|
|
|
|
|
|
/* count undefined symbols */
|
|
|
|
|
|
|
|
bfd_link_hash_traverse (link_info.hash, pe_undef_count, "");
|
|
|
|
|
|
|
|
/* create and fill the corresponding table */
|
|
|
|
udef_table = xmalloc (undef_count * sizeof (struct key_value));
|
|
|
|
|
|
|
|
undef_count = 0;
|
|
|
|
bfd_link_hash_traverse (link_info.hash, pe_undef_fill, "");
|
|
|
|
|
|
|
|
/* sort items */
|
|
|
|
qsort (udef_table, undef_count, sizeof (struct key_value), undef_sort_cmp);
|
2009-11-15 08:52:45 +01:00
|
|
|
}
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
static void
|
2009-12-11 14:42:17 +01:00
|
|
|
add_bfd_to_link (bfd *abfd, const char *name, struct bfd_link_info *linfo)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
lang_input_statement_type *fake_file;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
fake_file = lang_add_input_file (name,
|
|
|
|
lang_input_file_is_fake_enum,
|
|
|
|
NULL);
|
|
|
|
fake_file->the_bfd = abfd;
|
|
|
|
ldlang_add_file (fake_file);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2009-12-11 14:42:17 +01:00
|
|
|
if (!bfd_link_add_symbols (abfd, linfo))
|
2005-12-08 12:38:25 +01:00
|
|
|
einfo ("%Xaddsym %s: %E\n", name);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2009-12-11 14:42:17 +01:00
|
|
|
pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *linfo)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
2012-02-19 22:18:08 +01:00
|
|
|
int i, j;
|
1999-05-03 09:29:11 +02:00
|
|
|
def_file_module *module;
|
2012-02-19 22:18:08 +01:00
|
|
|
def_file_import *imp;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2000-10-09 03:37:11 +02:00
|
|
|
pe_dll_id_target (bfd_get_target (output_bfd));
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
if (!pe_def_file)
|
|
|
|
return;
|
|
|
|
|
2012-02-19 22:18:08 +01:00
|
|
|
imp = pe_def_file->imports;
|
|
|
|
|
2012-03-14 20:00:03 +01:00
|
|
|
pe_create_undef_table ();
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
for (module = pe_def_file->modules; module; module = module->next)
|
|
|
|
{
|
2012-02-19 22:18:08 +01:00
|
|
|
int do_this_dll = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < pe_def_file->num_imports && imp[i].module != module; i++)
|
|
|
|
;
|
|
|
|
if (i >= pe_def_file->num_imports)
|
|
|
|
continue;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
dll_filename = module->name;
|
|
|
|
dll_symname = xstrdup (module->name);
|
2012-02-19 22:18:08 +01:00
|
|
|
for (j = 0; dll_symname[j]; j++)
|
|
|
|
if (!ISALNUM (dll_symname[j]))
|
|
|
|
dll_symname[j] = '_';
|
|
|
|
|
|
|
|
for (; i < pe_def_file->num_imports && imp[i].module == module; i++)
|
|
|
|
{
|
|
|
|
def_file_export exp;
|
|
|
|
struct bfd_link_hash_entry *blhe;
|
|
|
|
int lead_at = (*imp[i].internal_name == '@');
|
|
|
|
/* See if we need this import. */
|
|
|
|
size_t len = strlen (imp[i].internal_name);
|
|
|
|
char *name = xmalloc (len + 2 + 6);
|
|
|
|
bfd_boolean include_jmp_stub = FALSE;
|
|
|
|
bfd_boolean is_cdecl = FALSE;
|
2012-03-14 20:00:03 +01:00
|
|
|
bfd_boolean is_undef = FALSE;
|
|
|
|
|
2012-02-19 22:18:08 +01:00
|
|
|
if (!lead_at && strchr (imp[i].internal_name, '@') == NULL)
|
|
|
|
is_cdecl = TRUE;
|
|
|
|
|
|
|
|
if (lead_at)
|
|
|
|
sprintf (name, "%s", imp[i].internal_name);
|
|
|
|
else
|
|
|
|
sprintf (name, "%s%s",U (""), imp[i].internal_name);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2012-02-19 22:18:08 +01:00
|
|
|
blhe = bfd_link_hash_lookup (linfo->hash, name,
|
|
|
|
FALSE, FALSE, FALSE);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2012-02-19 22:18:08 +01:00
|
|
|
/* Include the jump stub for <sym> only if the <sym>
|
|
|
|
is undefined. */
|
|
|
|
if (!blhe || (blhe && blhe->type != bfd_link_hash_undefined))
|
|
|
|
{
|
|
|
|
if (lead_at)
|
|
|
|
sprintf (name, "%s%s", "__imp_", imp[i].internal_name);
|
|
|
|
else
|
|
|
|
sprintf (name, "%s%s%s", "__imp_", U (""),
|
|
|
|
imp[i].internal_name);
|
|
|
|
|
|
|
|
blhe = bfd_link_hash_lookup (linfo->hash, name,
|
|
|
|
FALSE, FALSE, FALSE);
|
2012-03-14 20:00:03 +01:00
|
|
|
if (blhe)
|
|
|
|
is_undef = (blhe->type == bfd_link_hash_undefined);
|
2012-02-19 22:18:08 +01:00
|
|
|
}
|
|
|
|
else
|
2012-03-14 20:00:03 +01:00
|
|
|
{
|
|
|
|
include_jmp_stub = TRUE;
|
|
|
|
is_undef = (blhe->type == bfd_link_hash_undefined);
|
|
|
|
}
|
2012-02-19 22:18:08 +01:00
|
|
|
|
2012-03-14 20:00:03 +01:00
|
|
|
if (is_cdecl && (!blhe || (blhe && blhe->type != bfd_link_hash_undefined)))
|
2012-02-19 22:18:08 +01:00
|
|
|
{
|
|
|
|
sprintf (name, "%s%s",U (""), imp[i].internal_name);
|
2012-03-14 20:00:03 +01:00
|
|
|
blhe = pe_find_cdecl_alias_match (linfo, name);
|
2007-01-19 16:40:55 +01:00
|
|
|
include_jmp_stub = TRUE;
|
2012-03-14 20:00:03 +01:00
|
|
|
if (blhe)
|
|
|
|
is_undef = (blhe->type == bfd_link_hash_undefined);
|
2012-02-19 22:18:08 +01:00
|
|
|
}
|
2007-01-19 16:40:55 +01:00
|
|
|
|
2012-02-19 22:18:08 +01:00
|
|
|
free (name);
|
|
|
|
|
2012-03-14 20:00:03 +01:00
|
|
|
if (is_undef)
|
2012-02-19 22:18:08 +01:00
|
|
|
{
|
|
|
|
bfd *one;
|
|
|
|
/* We do. */
|
|
|
|
if (!do_this_dll)
|
|
|
|
{
|
|
|
|
bfd *ar_head = make_head (output_bfd);
|
|
|
|
add_bfd_to_link (ar_head, ar_head->filename, linfo);
|
|
|
|
do_this_dll = 1;
|
|
|
|
}
|
|
|
|
exp.internal_name = imp[i].internal_name;
|
|
|
|
exp.name = imp[i].name;
|
|
|
|
exp.its_name = imp[i].its_name;
|
|
|
|
exp.ordinal = imp[i].ordinal;
|
|
|
|
exp.hint = exp.ordinal >= 0 ? exp.ordinal : 0;
|
|
|
|
exp.flag_private = 0;
|
|
|
|
exp.flag_constant = 0;
|
|
|
|
exp.flag_data = imp[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, linfo);
|
|
|
|
}
|
|
|
|
}
|
1999-05-03 09:29:11 +02:00
|
|
|
if (do_this_dll)
|
|
|
|
{
|
|
|
|
bfd *ar_tail = make_tail (output_bfd);
|
2009-12-11 14:42:17 +01:00
|
|
|
add_bfd_to_link (ar_tail, ar_tail->filename, linfo);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
free (dll_symname);
|
|
|
|
}
|
2012-03-14 20:00:03 +01:00
|
|
|
|
|
|
|
while (undef_count)
|
|
|
|
{
|
|
|
|
--undef_count;
|
|
|
|
free (udef_table[undef_count].key);
|
|
|
|
}
|
|
|
|
free (udef_table);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* We were handed a *.DLL file. Parse it and turn it into a set of
|
2002-11-30 09:39:46 +01:00
|
|
|
IMPORTS directives in the def file. Return TRUE if the file was
|
|
|
|
handled, FALSE if not. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
static unsigned int
|
2003-06-28 07:28:54 +02:00
|
|
|
pe_get16 (bfd *abfd, int where)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
unsigned char b[2];
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2001-09-18 12:10:21 +02:00
|
|
|
bfd_seek (abfd, (file_ptr) where, SEEK_SET);
|
|
|
|
bfd_bread (b, (bfd_size_type) 2, abfd);
|
2000-10-09 03:37:11 +02:00
|
|
|
return b[0] + (b[1] << 8);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int
|
2003-06-28 07:28:54 +02:00
|
|
|
pe_get32 (bfd *abfd, int where)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
unsigned char b[4];
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2001-09-18 12:10:21 +02:00
|
|
|
bfd_seek (abfd, (file_ptr) where, SEEK_SET);
|
|
|
|
bfd_bread (b, (bfd_size_type) 4, abfd);
|
2000-10-09 03:37:11 +02:00
|
|
|
return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int
|
2003-06-28 07:28:54 +02:00
|
|
|
pe_as32 (void *ptr)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
unsigned char *b = ptr;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2000-10-09 03:37:11 +02:00
|
|
|
return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
2002-11-30 09:39:46 +01:00
|
|
|
bfd_boolean
|
2003-06-28 07:28:54 +02:00
|
|
|
pe_implied_import_dll (const char *filename)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
bfd *dll;
|
2008-05-27 10:34:26 +02:00
|
|
|
bfd_vma pe_header_offset, opthdr_ofs, num_entries, i;
|
|
|
|
bfd_vma export_rva, export_size, nsections, secptr, expptr;
|
|
|
|
bfd_vma exp_funcbase;
|
2005-02-23 13:30:48 +01:00
|
|
|
unsigned char *expdata;
|
|
|
|
char *erva;
|
2010-06-27 06:07:55 +02:00
|
|
|
bfd_vma name_rvas, nexp;
|
2009-12-11 14:42:17 +01:00
|
|
|
const char *dllname;
|
2002-12-16 19:02:16 +01:00
|
|
|
/* Initialization with start > end guarantees that is_data
|
|
|
|
will not be set by mistake, and avoids compiler warning. */
|
2008-05-27 10:34:26 +02:00
|
|
|
bfd_vma data_start = 1;
|
|
|
|
bfd_vma data_end = 0;
|
|
|
|
bfd_vma rdata_start = 1;
|
|
|
|
bfd_vma rdata_end = 0;
|
|
|
|
bfd_vma bss_start = 1;
|
|
|
|
bfd_vma bss_end = 0;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
/* No, I can't use bfd here. kernel32.dll puts its export table in
|
2000-09-29 15:21:41 +02:00
|
|
|
the middle of the .rdata section. */
|
1999-05-11 23:06:50 +02:00
|
|
|
dll = bfd_openr (filename, pe_details->target_name);
|
1999-05-03 09:29:11 +02:00
|
|
|
if (!dll)
|
|
|
|
{
|
2005-12-08 12:38:25 +01:00
|
|
|
einfo ("%Xopen %s: %E\n", filename);
|
2002-11-30 09:39:46 +01:00
|
|
|
return FALSE;
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2000-10-09 09:01:29 +02:00
|
|
|
/* PEI dlls seem to be bfd_objects. */
|
1999-05-03 09:29:11 +02:00
|
|
|
if (!bfd_check_format (dll, bfd_object))
|
|
|
|
{
|
|
|
|
einfo ("%X%s: this doesn't appear to be a DLL\n", filename);
|
2002-11-30 09:39:46 +01:00
|
|
|
return FALSE;
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
2009-11-27 10:00:36 +01:00
|
|
|
/* Get pe_header, optional header and numbers of directory entries. */
|
1999-05-03 09:29:11 +02:00
|
|
|
pe_header_offset = pe_get32 (dll, 0x3c);
|
|
|
|
opthdr_ofs = pe_header_offset + 4 + 20;
|
2006-09-20 13:35:11 +02:00
|
|
|
#ifdef pe_use_x86_64
|
|
|
|
num_entries = pe_get32 (dll, opthdr_ofs + 92 + 4 * 4); /* & NumberOfRvaAndSizes. */
|
|
|
|
#else
|
1999-05-03 09:29:11 +02:00
|
|
|
num_entries = pe_get32 (dll, opthdr_ofs + 92);
|
2006-09-20 13:35:11 +02:00
|
|
|
#endif
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2009-11-27 10:00:36 +01:00
|
|
|
/* No import or export directory entry. */
|
|
|
|
if (num_entries < 1)
|
2002-11-30 09:39:46 +01:00
|
|
|
return FALSE;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2006-09-20 13:35:11 +02:00
|
|
|
#ifdef pe_use_x86_64
|
|
|
|
export_rva = pe_get32 (dll, opthdr_ofs + 96 + 4 * 4);
|
|
|
|
export_size = pe_get32 (dll, opthdr_ofs + 100 + 4 * 4);
|
|
|
|
#else
|
1999-05-03 09:29:11 +02:00
|
|
|
export_rva = pe_get32 (dll, opthdr_ofs + 96);
|
|
|
|
export_size = pe_get32 (dll, opthdr_ofs + 100);
|
2006-09-20 13:35:11 +02:00
|
|
|
#endif
|
2009-01-26 11:29:11 +01:00
|
|
|
|
2009-11-27 10:00:36 +01:00
|
|
|
/* No export table - nothing to export. */
|
|
|
|
if (export_size == 0)
|
|
|
|
return FALSE;
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
nsections = pe_get16 (dll, pe_header_offset + 4 + 2);
|
|
|
|
secptr = (pe_header_offset + 4 + 20 +
|
|
|
|
pe_get16 (dll, pe_header_offset + 4 + 16));
|
|
|
|
expptr = 0;
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
/* Get the rva and size of the export section. */
|
2000-10-09 03:37:11 +02:00
|
|
|
for (i = 0; i < nsections; i++)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
char sname[8];
|
2008-05-27 10:34:26 +02:00
|
|
|
bfd_vma secptr1 = secptr + 40 * i;
|
|
|
|
bfd_vma vaddr = pe_get32 (dll, secptr1 + 12);
|
|
|
|
bfd_vma vsize = pe_get32 (dll, secptr1 + 16);
|
|
|
|
bfd_vma fptr = pe_get32 (dll, secptr1 + 20);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2001-09-18 12:10:21 +02:00
|
|
|
bfd_seek (dll, (file_ptr) secptr1, SEEK_SET);
|
|
|
|
bfd_bread (sname, (bfd_size_type) 8, dll);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2000-10-09 03:37:11 +02:00
|
|
|
if (vaddr <= export_rva && vaddr + vsize > export_rva)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
|
|
|
expptr = fptr + (export_rva - vaddr);
|
|
|
|
if (export_rva + export_size > vaddr + vsize)
|
|
|
|
export_size = vsize - (export_rva - vaddr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-16 19:02:16 +01:00
|
|
|
/* Scan sections and store the base and size of the
|
2003-06-28 07:28:54 +02:00
|
|
|
data and bss segments in data/base_start/end. */
|
2002-12-16 19:02:16 +01:00
|
|
|
for (i = 0; i < nsections; i++)
|
|
|
|
{
|
2008-05-27 10:34:26 +02:00
|
|
|
bfd_vma secptr1 = secptr + 40 * i;
|
|
|
|
bfd_vma vsize = pe_get32 (dll, secptr1 + 8);
|
|
|
|
bfd_vma vaddr = pe_get32 (dll, secptr1 + 12);
|
|
|
|
bfd_vma flags = pe_get32 (dll, secptr1 + 36);
|
2002-12-16 19:02:16 +01:00
|
|
|
char sec_name[9];
|
|
|
|
|
|
|
|
sec_name[8] = '\0';
|
|
|
|
bfd_seek (dll, (file_ptr) secptr1 + 0, SEEK_SET);
|
|
|
|
bfd_bread (sec_name, (bfd_size_type) 8, dll);
|
|
|
|
|
|
|
|
if (strcmp(sec_name,".data") == 0)
|
|
|
|
{
|
|
|
|
data_start = vaddr;
|
|
|
|
data_end = vaddr + vsize;
|
|
|
|
|
2003-10-14 08:26:31 +02:00
|
|
|
if (pe_dll_extra_pe_debug)
|
|
|
|
printf ("%s %s: 0x%08lx-0x%08lx (0x%08lx)\n",
|
2008-05-27 10:34:26 +02:00
|
|
|
__FUNCTION__, sec_name, (unsigned long) vaddr,
|
|
|
|
(unsigned long) (vaddr + vsize), (unsigned long) flags);
|
2003-10-14 08:26:31 +02:00
|
|
|
}
|
|
|
|
else if (strcmp(sec_name,".rdata") == 0)
|
|
|
|
{
|
|
|
|
rdata_start = vaddr;
|
|
|
|
rdata_end = vaddr + vsize;
|
|
|
|
|
2002-12-16 19:02:16 +01:00
|
|
|
if (pe_dll_extra_pe_debug)
|
|
|
|
printf ("%s %s: 0x%08lx-0x%08lx (0x%08lx)\n",
|
2008-05-27 10:34:26 +02:00
|
|
|
__FUNCTION__, sec_name, (unsigned long) vaddr,
|
|
|
|
(unsigned long) (vaddr + vsize), (unsigned long) flags);
|
2003-06-28 07:28:54 +02:00
|
|
|
}
|
2002-12-16 19:02:16 +01:00
|
|
|
else if (strcmp (sec_name,".bss") == 0)
|
|
|
|
{
|
|
|
|
bss_start = vaddr;
|
|
|
|
bss_end = vaddr + vsize;
|
|
|
|
|
|
|
|
if (pe_dll_extra_pe_debug)
|
|
|
|
printf ("%s %s: 0x%08lx-0x%08lx (0x%08lx)\n",
|
2008-05-27 10:34:26 +02:00
|
|
|
__FUNCTION__, sec_name, (unsigned long) vaddr,
|
|
|
|
(unsigned long) (vaddr + vsize), (unsigned long) flags);
|
2002-12-16 19:02:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
expdata = xmalloc (export_size);
|
2001-09-18 12:10:21 +02:00
|
|
|
bfd_seek (dll, (file_ptr) expptr, SEEK_SET);
|
|
|
|
bfd_bread (expdata, (bfd_size_type) export_size, dll);
|
2005-02-23 13:30:48 +01:00
|
|
|
erva = (char *) expdata - export_rva;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
if (pe_def_file == 0)
|
2000-10-09 03:37:11 +02:00
|
|
|
pe_def_file = def_file_empty ();
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2000-10-09 03:37:11 +02:00
|
|
|
nexp = pe_as32 (expdata + 24);
|
|
|
|
name_rvas = pe_as32 (expdata + 32);
|
2002-12-16 19:02:16 +01:00
|
|
|
exp_funcbase = pe_as32 (expdata + 28);
|
2001-09-14 16:19:05 +02:00
|
|
|
|
2002-12-16 19:02:16 +01:00
|
|
|
/* Use internal dll name instead of filename
|
|
|
|
to enable symbolic dll linking. */
|
2009-12-11 14:42:17 +01:00
|
|
|
dllname = erva + pe_as32 (expdata + 12);
|
2002-12-16 19:02:16 +01:00
|
|
|
|
2003-01-28 12:39:43 +01:00
|
|
|
/* 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. */
|
2009-12-11 14:42:17 +01:00
|
|
|
if (def_get_module (pe_def_file, dllname))
|
2003-01-28 12:39:43 +01:00
|
|
|
{
|
|
|
|
if (pe_dll_extra_pe_debug)
|
2009-12-11 14:42:17 +01:00
|
|
|
printf ("%s is already loaded\n", dllname);
|
2003-01-28 12:39:43 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2002-12-16 19:02:16 +01:00
|
|
|
/* Iterate through the list of symbols. */
|
2000-10-09 03:37:11 +02:00
|
|
|
for (i = 0; i < nexp; i++)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
2002-12-16 19:02:16 +01:00
|
|
|
/* Pointer to the names vector. */
|
2008-05-27 10:34:26 +02:00
|
|
|
bfd_vma name_rva = pe_as32 (erva + name_rvas + i * 4);
|
1999-05-03 09:29:11 +02:00
|
|
|
def_file_import *imp;
|
2003-06-28 07:28:54 +02:00
|
|
|
/* Pointer to the function address vector. */
|
2008-05-27 10:34:26 +02:00
|
|
|
bfd_vma func_rva = pe_as32 (erva + exp_funcbase + i * 4);
|
2002-12-16 19:02:16 +01:00
|
|
|
int is_data = 0;
|
|
|
|
|
|
|
|
/* Skip unwanted symbols, which are
|
|
|
|
exported in buggy auto-import releases. */
|
2010-04-28 17:24:22 +02:00
|
|
|
if (! CONST_STRNEQ (erva + name_rva, "__nm_"))
|
2002-12-16 19:02:16 +01:00
|
|
|
{
|
2011-04-13 14:53:36 +02:00
|
|
|
int is_dup = 0;
|
2003-10-14 08:26:31 +02:00
|
|
|
/* is_data is true if the address is in the data, rdata or bss
|
|
|
|
segment. */
|
2002-12-16 19:02:16 +01:00
|
|
|
is_data =
|
|
|
|
(func_rva >= data_start && func_rva < data_end)
|
2003-10-14 08:26:31 +02:00
|
|
|
|| (func_rva >= rdata_start && func_rva < rdata_end)
|
2002-12-16 19:02:16 +01:00
|
|
|
|| (func_rva >= bss_start && func_rva < bss_end);
|
|
|
|
|
|
|
|
imp = def_file_add_import (pe_def_file, erva + name_rva,
|
2012-02-19 22:18:08 +01:00
|
|
|
dllname, i, NULL, NULL, &is_dup);
|
2003-01-02 04:53:53 +01:00
|
|
|
/* Mark symbol type. */
|
2011-04-13 14:53:36 +02:00
|
|
|
if (!is_dup)
|
|
|
|
imp->data = is_data;
|
2003-06-28 07:28:54 +02:00
|
|
|
|
2002-12-16 19:02:16 +01:00
|
|
|
if (pe_dll_extra_pe_debug)
|
|
|
|
printf ("%s dll-name: %s sym: %s addr: 0x%lx %s\n",
|
2009-12-11 14:42:17 +01:00
|
|
|
__FUNCTION__, dllname, erva + name_rva,
|
2008-05-27 10:34:26 +02:00
|
|
|
(unsigned long) func_rva, is_data ? "(data)" : "");
|
2002-12-16 19:02:16 +01:00
|
|
|
}
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
2002-11-30 09:39:46 +01:00
|
|
|
return TRUE;
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
2009-02-18 19:23:08 +01:00
|
|
|
void
|
|
|
|
pe_output_file_set_long_section_names (bfd *abfd)
|
|
|
|
{
|
|
|
|
if (pe_use_coff_long_section_names < 0)
|
|
|
|
return;
|
|
|
|
if (!bfd_coff_set_long_section_names (abfd, pe_use_coff_long_section_names))
|
|
|
|
einfo (_("%XError: can't use long section names on this arch\n"));
|
|
|
|
}
|
|
|
|
|
2001-09-14 16:19:05 +02:00
|
|
|
/* These are the main functions, called from the emulation. The first
|
|
|
|
is called after the bfds are read, so we can guess at how much space
|
|
|
|
we need. The second is called after everything is placed, so we
|
|
|
|
can put the right values in place. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
void
|
2003-06-28 07:28:54 +02:00
|
|
|
pe_dll_build_sections (bfd *abfd, struct bfd_link_info *info)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
1999-05-11 23:06:50 +02:00
|
|
|
pe_dll_id_target (bfd_get_target (abfd));
|
2009-02-18 19:23:08 +01:00
|
|
|
pe_output_file_set_long_section_names (abfd);
|
2009-05-19 18:08:08 +02:00
|
|
|
process_def_file_and_drectve (abfd, info);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
2003-06-28 07:28:54 +02:00
|
|
|
if (pe_def_file->num_exports == 0 && !info->shared)
|
2003-04-02 19:39:24 +02:00
|
|
|
return;
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
generate_edata (abfd, info);
|
1999-05-11 23:06:50 +02:00
|
|
|
build_filler_bfd (1);
|
2009-02-18 19:23:08 +01:00
|
|
|
pe_output_file_set_long_section_names (filler_bfd);
|
1999-05-11 23:06:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-06-28 07:28:54 +02:00
|
|
|
pe_exe_build_sections (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
|
1999-05-11 23:06:50 +02:00
|
|
|
{
|
|
|
|
pe_dll_id_target (bfd_get_target (abfd));
|
2009-02-18 19:23:08 +01:00
|
|
|
pe_output_file_set_long_section_names (abfd);
|
1999-05-11 23:06:50 +02:00
|
|
|
build_filler_bfd (0);
|
2009-02-18 19:23:08 +01:00
|
|
|
pe_output_file_set_long_section_names (filler_bfd);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-06-28 07:28:54 +02:00
|
|
|
pe_dll_fill_sections (bfd *abfd, struct bfd_link_info *info)
|
1999-05-03 09:29:11 +02:00
|
|
|
{
|
1999-05-11 23:06:50 +02:00
|
|
|
pe_dll_id_target (bfd_get_target (abfd));
|
2009-02-18 19:23:08 +01:00
|
|
|
pe_output_file_set_long_section_names (abfd);
|
1999-05-03 09:29:11 +02:00
|
|
|
image_base = pe_data (abfd)->pe_opthdr.ImageBase;
|
|
|
|
|
|
|
|
generate_reloc (abfd, info);
|
|
|
|
if (reloc_sz > 0)
|
|
|
|
{
|
|
|
|
bfd_set_section_size (filler_bfd, reloc_s, reloc_sz);
|
|
|
|
|
|
|
|
/* Resize the sections. */
|
2005-08-10 18:46:30 +02:00
|
|
|
lang_reset_memory_regions ();
|
* ld.h (lang_phase_type): Move to..
* ldexp.h: ..here. Add lang_mark_phase_enum.
(node_type): Remove etree_undef and etree_unspec.
(exp_data_seg): Delete.
(struct ldexp_control, expld): New.
(invalid, exp_mark_used_section): Delete.
(exp_fold_tree, exp_get_vma, exp_get_value_int, exp_get_fill,
exp_get_abs_int): Update prototypes.
* ldexp.c (assigning_to_dot): Delete.
(expld): Define.
(make_abs): Operate directly on expld.result. Update all callers.
(new_abs): Likewise. Return void.
(new_rel_from_abs): Rename from new_rel_from_section.
(new_rel, new_rel_from_abs): Operate on expld.result and return void.
Update all callers.
(fold_unary): Operate on expld.result and return void. Remove
"current_section", "allocation_done", "dot", "dotp" and "mark_used"
params. Update all callers.
(fold_binary, fold_trinary, fold_name, exp_fold_tree_1): Likewise.
(fold_unary <ALIGN_K>): Ensure alignment is absolute.
(fold_unary <ABSOLUTE>): Use make_abs.
(fold_unary <DATA_SEGMENT_END>): Evaluate mark_phase as for
allocating_phase.
(fold_binary <DATA_SEGMENT_ALIGN, DATA_SEGMENT_RELRO_END, >): Ditto.
(fold_binary <'%','/'>): Don't error if marking.
(fold_name <SIZEOF_HEADERS>): Don't call bfd_sizeof_headers when
marking.
(fold_name <NAME>): Remove FIXME; -R is handled correctly. Don't
error when marking.
(fold_name <ADDR, LOADADDR, SIZEOF>): Don't set SEC_KEEP.
(exp_fold_tree_1): Don't error when marking.
(exp_fold_tree_1 <etree_rel>): Evaluate in all phases except first.
(exp_fold_tree_1 <etree_assign to dot>): Don't check for NULL
current section, instead check for NULL dotp.
(exp_fold_tree_1 <etree_provide>): Don't evaluate the assignment
source unless the symbol is referenced and undefined.
(exp_fold_tree): Remove "allocation_done" and "dot" params. Save
params to expld.
(exp_fold_tree_no_dot): Remove "current_section", "allocation_done
and "mark_used" params. Save params to expld. Update all callers.
(exp_assop): Do without temp var.
(exp_print_tree <etree_undef>): Delete code.
(exp_get_vma): Remove "allocation_done" param. Correct error return.
(exp_get_fill, exp_get_abs_int): Likewise.
(exp_get_value_int): Remove "allocation_done" param.
(exp_mark_used_section): Delete.
* ldgram.y (fill_exp): Update exp_get_fill call.
(origin_spec, length_spec): Update exp_get_vma call.
* ldlang.c (lang_init): Don't bother clearing lang_statement_iteration.
(lang_mark_used_section_1, lang_mark_used_section): Delete.
(strip_excluded_output_sections): Call one_lang_size_sections_pass in
marking mode. Merge old lang_mark_used_section code. Correct handling
of output sections with excluded input sections and data statements.
Don't drop non-zero sized sections. Don't zap os->bfd_section.
Do set SEC_EXCLUDE when appropriate.
(print_output_section_statement): Update for changed ldexp.c
interface.
(print_assignment, lang_size_sections_1): Likewise.
(lang_do_assignments_1, lang_enter_output_section_statement): Likewise.
(lang_new_phdr, lang_record_phdrs): Likewise.
(lang_size_sections): Likewise.
(insert_pad): Use following statement if it is a pad, rather than
creating a new one.
(lang_size_sections_1 <lang_output_section_statement_enum>): Do
process ignored output section to set vma and lma, but don't
update dot for these sections. Don't error if marking.
(lang_size_sections_1 <lang_assignment_statement_enum>): Don't
update dot for ignored sections.
(lang_size_sections_1 <lang_data_statement_enum>): Don't mark absolute
section with SEC_ALLOC.
(one_lang_size_sections_pass): New function.
(lang_size_sections): Remove first five params. Set expld.phase on
entry and exit. Use one_lang_size_sections_pass.
(lang_do_assignments): Remove all params. Update all callers.
(lang_reset_memory_regions): Clear os->processed for all output
section statements.
* ldlang.h (lang_do_assignments): Update prototype.
(lang_size_sections): Likewise.
(one_lang_size_sections_pass): Declare.
* pe-dll.c (pe_dll_fill_sections, pe_exe_fill_sections): Update
lang_size_sections and lang_do_assignments calls.
* emultempl/elf32.em (layout_sections_again): Likewise.
* emultempl/ppc64elf.em (ppc_before_allocation): Use
one_lang_size_sections_pass.
2005-06-09 04:05:47 +02:00
|
|
|
lang_size_sections (NULL, TRUE);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
/* Redo special stuff. */
|
|
|
|
ldemul_after_allocation ();
|
|
|
|
|
|
|
|
/* Do the assignments again. */
|
2011-05-03 16:56:14 +02:00
|
|
|
lang_do_assignments (lang_final_phase_enum);
|
1999-05-03 09:29:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fill_edata (abfd, info);
|
|
|
|
|
2004-09-30 19:19:19 +02:00
|
|
|
if (info->shared && !info->pie)
|
2003-04-02 19:39:24 +02:00
|
|
|
pe_data (abfd)->dll = 1;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
edata_s->contents = edata_d;
|
|
|
|
reloc_s->contents = reloc_d;
|
|
|
|
}
|
1999-05-11 23:06:50 +02:00
|
|
|
|
|
|
|
void
|
2003-06-28 07:28:54 +02:00
|
|
|
pe_exe_fill_sections (bfd *abfd, struct bfd_link_info *info)
|
1999-05-11 23:06:50 +02:00
|
|
|
{
|
|
|
|
pe_dll_id_target (bfd_get_target (abfd));
|
2009-02-18 19:23:08 +01:00
|
|
|
pe_output_file_set_long_section_names (abfd);
|
1999-05-11 23:06:50 +02:00
|
|
|
image_base = pe_data (abfd)->pe_opthdr.ImageBase;
|
|
|
|
|
|
|
|
generate_reloc (abfd, info);
|
|
|
|
if (reloc_sz > 0)
|
|
|
|
{
|
|
|
|
bfd_set_section_size (filler_bfd, reloc_s, reloc_sz);
|
|
|
|
|
|
|
|
/* Resize the sections. */
|
2005-08-10 18:46:30 +02:00
|
|
|
lang_reset_memory_regions ();
|
* ld.h (lang_phase_type): Move to..
* ldexp.h: ..here. Add lang_mark_phase_enum.
(node_type): Remove etree_undef and etree_unspec.
(exp_data_seg): Delete.
(struct ldexp_control, expld): New.
(invalid, exp_mark_used_section): Delete.
(exp_fold_tree, exp_get_vma, exp_get_value_int, exp_get_fill,
exp_get_abs_int): Update prototypes.
* ldexp.c (assigning_to_dot): Delete.
(expld): Define.
(make_abs): Operate directly on expld.result. Update all callers.
(new_abs): Likewise. Return void.
(new_rel_from_abs): Rename from new_rel_from_section.
(new_rel, new_rel_from_abs): Operate on expld.result and return void.
Update all callers.
(fold_unary): Operate on expld.result and return void. Remove
"current_section", "allocation_done", "dot", "dotp" and "mark_used"
params. Update all callers.
(fold_binary, fold_trinary, fold_name, exp_fold_tree_1): Likewise.
(fold_unary <ALIGN_K>): Ensure alignment is absolute.
(fold_unary <ABSOLUTE>): Use make_abs.
(fold_unary <DATA_SEGMENT_END>): Evaluate mark_phase as for
allocating_phase.
(fold_binary <DATA_SEGMENT_ALIGN, DATA_SEGMENT_RELRO_END, >): Ditto.
(fold_binary <'%','/'>): Don't error if marking.
(fold_name <SIZEOF_HEADERS>): Don't call bfd_sizeof_headers when
marking.
(fold_name <NAME>): Remove FIXME; -R is handled correctly. Don't
error when marking.
(fold_name <ADDR, LOADADDR, SIZEOF>): Don't set SEC_KEEP.
(exp_fold_tree_1): Don't error when marking.
(exp_fold_tree_1 <etree_rel>): Evaluate in all phases except first.
(exp_fold_tree_1 <etree_assign to dot>): Don't check for NULL
current section, instead check for NULL dotp.
(exp_fold_tree_1 <etree_provide>): Don't evaluate the assignment
source unless the symbol is referenced and undefined.
(exp_fold_tree): Remove "allocation_done" and "dot" params. Save
params to expld.
(exp_fold_tree_no_dot): Remove "current_section", "allocation_done
and "mark_used" params. Save params to expld. Update all callers.
(exp_assop): Do without temp var.
(exp_print_tree <etree_undef>): Delete code.
(exp_get_vma): Remove "allocation_done" param. Correct error return.
(exp_get_fill, exp_get_abs_int): Likewise.
(exp_get_value_int): Remove "allocation_done" param.
(exp_mark_used_section): Delete.
* ldgram.y (fill_exp): Update exp_get_fill call.
(origin_spec, length_spec): Update exp_get_vma call.
* ldlang.c (lang_init): Don't bother clearing lang_statement_iteration.
(lang_mark_used_section_1, lang_mark_used_section): Delete.
(strip_excluded_output_sections): Call one_lang_size_sections_pass in
marking mode. Merge old lang_mark_used_section code. Correct handling
of output sections with excluded input sections and data statements.
Don't drop non-zero sized sections. Don't zap os->bfd_section.
Do set SEC_EXCLUDE when appropriate.
(print_output_section_statement): Update for changed ldexp.c
interface.
(print_assignment, lang_size_sections_1): Likewise.
(lang_do_assignments_1, lang_enter_output_section_statement): Likewise.
(lang_new_phdr, lang_record_phdrs): Likewise.
(lang_size_sections): Likewise.
(insert_pad): Use following statement if it is a pad, rather than
creating a new one.
(lang_size_sections_1 <lang_output_section_statement_enum>): Do
process ignored output section to set vma and lma, but don't
update dot for these sections. Don't error if marking.
(lang_size_sections_1 <lang_assignment_statement_enum>): Don't
update dot for ignored sections.
(lang_size_sections_1 <lang_data_statement_enum>): Don't mark absolute
section with SEC_ALLOC.
(one_lang_size_sections_pass): New function.
(lang_size_sections): Remove first five params. Set expld.phase on
entry and exit. Use one_lang_size_sections_pass.
(lang_do_assignments): Remove all params. Update all callers.
(lang_reset_memory_regions): Clear os->processed for all output
section statements.
* ldlang.h (lang_do_assignments): Update prototype.
(lang_size_sections): Likewise.
(one_lang_size_sections_pass): Declare.
* pe-dll.c (pe_dll_fill_sections, pe_exe_fill_sections): Update
lang_size_sections and lang_do_assignments calls.
* emultempl/elf32.em (layout_sections_again): Likewise.
* emultempl/ppc64elf.em (ppc_before_allocation): Use
one_lang_size_sections_pass.
2005-06-09 04:05:47 +02:00
|
|
|
lang_size_sections (NULL, TRUE);
|
1999-05-11 23:06:50 +02:00
|
|
|
|
|
|
|
/* Redo special stuff. */
|
|
|
|
ldemul_after_allocation ();
|
|
|
|
|
|
|
|
/* Do the assignments again. */
|
2011-05-03 16:56:14 +02:00
|
|
|
lang_do_assignments (lang_final_phase_enum);
|
1999-05-11 23:06:50 +02:00
|
|
|
}
|
|
|
|
reloc_s->contents = reloc_d;
|
|
|
|
}
|
2006-12-18 23:38:53 +01:00
|
|
|
|
|
|
|
bfd_boolean
|
|
|
|
pe_bfd_is_dll (bfd *abfd)
|
|
|
|
{
|
|
|
|
return (bfd_get_format (abfd) == bfd_object
|
|
|
|
&& obj_pe (abfd)
|
|
|
|
&& pe_data (abfd)->dll);
|
|
|
|
}
|