Mon Aug 21 17:49:28 1995 steve chamberlain <sac@slash.cygnus.com>
* bfd-in.h (bfd_link_subsystem): Turn enum into #defines. (bfd_link_pe_info_dval): New (bfd_link_stack_heap): Renamed and massaged into bfd_link_pe_info. * bfd-in2.h: rebuilt. * bfd.c (NT_subsystem, NT_stack_heap): Deleted. * coffcode.h (pe_value): New function. (fill_pe_header_info): New function. (coff_write_object_contents): Use new function. * cofflink.c (coff_final_link_info): Remove pe randomness. (dores_com): Update info in bfd_link_pe_info_dval. (process_embedded_commands): Use the bfd_link_pe_info_dval. (_bfd_coff_final_link): Remove PE stuff, initialize coff_data->link_info. * coffswap.h (coff_swap_[aout|filehdr]_out): Use indirect PE pointer. (coff_swap_scnhdr_out): Use real imagebase. * libcoff (coff_data_type.link_info): New field.
This commit is contained in:
parent
259d19c2be
commit
e9614321da
|
@ -1,3 +1,22 @@
|
|||
Mon Aug 21 17:49:28 1995 steve chamberlain <sac@slash.cygnus.com>
|
||||
|
||||
* bfd-in.h (bfd_link_subsystem): Turn enum into #defines.
|
||||
(bfd_link_pe_info_dval): New
|
||||
(bfd_link_stack_heap): Renamed and massaged into bfd_link_pe_info.
|
||||
* bfd-in2.h: rebuilt.
|
||||
* bfd.c (NT_subsystem, NT_stack_heap): Deleted.
|
||||
* coffcode.h (pe_value): New function.
|
||||
(fill_pe_header_info): New function.
|
||||
(coff_write_object_contents): Use new function.
|
||||
* cofflink.c (coff_final_link_info): Remove pe randomness.
|
||||
(dores_com): Update info in bfd_link_pe_info_dval.
|
||||
(process_embedded_commands): Use the bfd_link_pe_info_dval.
|
||||
(_bfd_coff_final_link): Remove PE stuff, initialize
|
||||
coff_data->link_info.
|
||||
* coffswap.h (coff_swap_[aout|filehdr]_out): Use indirect PE pointer.
|
||||
(coff_swap_scnhdr_out): Use real imagebase.
|
||||
* libcoff (coff_data_type.link_info): New field.
|
||||
|
||||
Mon Aug 21 11:10:32 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* linker.c (link_action): If an undefined reference follows an
|
||||
|
|
|
@ -20,7 +20,7 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* bfd.h -- The only header file required by users of the bfd library
|
||||
|
||||
|
@ -458,32 +458,46 @@ extern int bfd_stat PARAMS ((bfd *abfd, struct stat *));
|
|||
/* These are the different types of subsystems to be used when linking for
|
||||
Windows NT. This information is passed in as an input parameter (default
|
||||
is console) and ultimately ends up in the optional header data */
|
||||
enum bfd_link_subsystem
|
||||
{
|
||||
native, /* image doesn't require a subsystem */
|
||||
windows, /* image runs in the Windows GUI subsystem */
|
||||
console, /* image runs in the Windows CUI (character) subsystem */
|
||||
os2, /* image runs in the OS/2 character subsystem */
|
||||
posix /* image runs in the posix character subsystem */
|
||||
};
|
||||
|
||||
#define BFD_PE_NATIVE 1 /* image doesn't require a subsystem */
|
||||
#define BFD_PE_WINDOWS 2 /* image runs in the Windows GUI subsystem */
|
||||
#define BFD_PE_CONSOLE 3 /* image runs in the Windows CUI subsystem */
|
||||
#define BFD_PE_OS2 5 /* image runs in the OS/2 character subsystem */
|
||||
#define BFD_PE_POSIX 7 /* image runs in the posix character subsystem */
|
||||
|
||||
/* The NT optional header file allows input of the stack and heap reserve
|
||||
and commit size. This data may be input on the command line and will
|
||||
end up in the optional header. Default sizes are provided. */
|
||||
struct _bfd_link_stack_heap
|
||||
|
||||
typedef struct
|
||||
{
|
||||
boolean stack_defined;
|
||||
boolean heap_defined;
|
||||
bfd_vma stack_reserve;
|
||||
bfd_vma stack_commit;
|
||||
bfd_vma heap_reserve;
|
||||
bfd_vma heap_commit;
|
||||
};
|
||||
typedef struct _bfd_link_stack_heap bfd_link_stack_heap;
|
||||
boolean defined;
|
||||
bfd_vma value;
|
||||
} bfd_link_pe_info_dval ;
|
||||
|
||||
typedef struct _bfd_link_pe_info
|
||||
{
|
||||
bfd_link_pe_info_dval dll;
|
||||
bfd_link_pe_info_dval file_alignment;
|
||||
bfd_link_pe_info_dval heap_commit;
|
||||
bfd_link_pe_info_dval heap_reserve;
|
||||
bfd_link_pe_info_dval image_base;
|
||||
bfd_link_pe_info_dval major_image_version;
|
||||
bfd_link_pe_info_dval major_os_version;
|
||||
bfd_link_pe_info_dval major_subsystem_version;
|
||||
bfd_link_pe_info_dval minor_image_version;
|
||||
bfd_link_pe_info_dval minor_os_version;
|
||||
bfd_link_pe_info_dval minor_subsystem_version;
|
||||
bfd_link_pe_info_dval section_alignment;
|
||||
bfd_link_pe_info_dval stack_commit;
|
||||
bfd_link_pe_info_dval stack_reserve;
|
||||
bfd_link_pe_info_dval subsystem;
|
||||
} bfd_link_pe_info;
|
||||
|
||||
/* END OF PE STUFF */
|
||||
|
||||
extern enum bfd_link_subsystem NT_subsystem;
|
||||
extern bfd_link_stack_heap NT_stack_heap;
|
||||
|
||||
extern bfd_link_pe_info pe_info;
|
||||
|
||||
/* Cast from const char * to char * so that caller can assign to
|
||||
a char * without a warning. */
|
||||
|
@ -1065,6 +1079,8 @@ enum bfd_architecture
|
|||
|
||||
bfd_arch_a29k, /* AMD 29000 */
|
||||
bfd_arch_sparc, /* SPARC */
|
||||
#define bfd_mach_sparc 1
|
||||
#define bfd_mach_sparc64 2
|
||||
bfd_arch_mips, /* MIPS Rxxxx */
|
||||
bfd_arch_i386, /* Intel 386 */
|
||||
bfd_arch_we32k, /* AT&T WE32xxx */
|
||||
|
@ -2253,7 +2269,9 @@ CAT(NAME,_get_symbol_info),\
|
|||
CAT(NAME,_bfd_is_local_label),\
|
||||
CAT(NAME,_get_lineno),\
|
||||
CAT(NAME,_find_nearest_line),\
|
||||
CAT(NAME,_bfd_make_debug_symbol)
|
||||
CAT(NAME,_bfd_make_debug_symbol),\
|
||||
CAT(NAME,_read_minisymbols),\
|
||||
CAT(NAME,_minisymbol_to_symbol)
|
||||
long (*_bfd_get_symtab_upper_bound) PARAMS ((bfd *));
|
||||
long (*_bfd_canonicalize_symtab) PARAMS ((bfd *,
|
||||
struct symbol_cache_entry **));
|
||||
|
@ -2277,10 +2295,18 @@ CAT(NAME,_bfd_make_debug_symbol)
|
|||
/* Back-door to allow format-aware applications to create debug symbols
|
||||
while using BFD for everything else. Currently used by the assembler
|
||||
when creating COFF files. */
|
||||
asymbol * (*_bfd_make_debug_symbol) PARAMS ((
|
||||
asymbol * (*_bfd_make_debug_symbol) PARAMS ((
|
||||
bfd *abfd,
|
||||
void *ptr,
|
||||
unsigned long size));
|
||||
#define bfd_read_minisymbols(b, d, m, s) \
|
||||
BFD_SEND (b, _read_minisymbols, (b, d, m, s))
|
||||
long (*_read_minisymbols) PARAMS ((bfd *, boolean, PTR *,
|
||||
unsigned int *));
|
||||
#define bfd_minisymbol_to_symbol(b, d, m, f) \
|
||||
BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f))
|
||||
asymbol *(*_minisymbol_to_symbol) PARAMS ((bfd *, boolean, const PTR,
|
||||
asymbol *));
|
||||
|
||||
/* Routines for relocs. */
|
||||
#define BFD_JUMP_TABLE_RELOCS(NAME)\
|
||||
|
|
377
bfd/coffcode.h
377
bfd/coffcode.h
|
@ -16,7 +16,7 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/*
|
||||
Most of this hacked by Steve Chamberlain,
|
||||
|
@ -302,6 +302,16 @@ CODE_FRAGMENT
|
|||
#define IMAGE_BASE 0
|
||||
#endif
|
||||
|
||||
|
||||
static bfd_vma
|
||||
pe_value(bfd_link_pe_info_dval *ptr, bfd_vma def)
|
||||
{
|
||||
if (ptr && ptr->defined)
|
||||
return ptr->value;
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
#include "coffswap.h"
|
||||
|
||||
/* void warning(); */
|
||||
|
@ -1661,20 +1671,186 @@ coff_add_missing_symbols (abfd)
|
|||
#endif /* ! defined (RS6000COFF_C) */
|
||||
|
||||
#ifdef COFF_WITH_PE
|
||||
static void add_data_entry (abfd, aout, idx, name)
|
||||
static void add_data_entry (abfd, aout, idx, name, base)
|
||||
bfd *abfd;
|
||||
struct internal_aouthdr *aout;
|
||||
int idx;
|
||||
char *name;
|
||||
bfd_vma base;
|
||||
{
|
||||
asection *sec = bfd_get_section_by_name (abfd, name);
|
||||
|
||||
/* add import directory information if it exists */
|
||||
if (sec != NULL)
|
||||
{
|
||||
aout->DataDirectory[idx].VirtualAddress = sec->lma - NT_IMAGE_BASE;
|
||||
aout->DataDirectory[idx].Size = sec->_raw_size;
|
||||
aout->pe->DataDirectory[idx].VirtualAddress = sec->lma - base;
|
||||
aout->pe->DataDirectory[idx].Size = sec->_raw_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fill_pe_header_info (abfd, internal_f, internal_a, end_of_image)
|
||||
bfd *abfd;
|
||||
struct internal_filehdr *internal_f;
|
||||
struct internal_aouthdr *internal_a;
|
||||
bfd_vma end_of_image;
|
||||
{
|
||||
/* assign other filehdr fields for DOS header and NT signature */
|
||||
|
||||
bfd_link_pe_info *pe_info = coff_data (abfd)->link_info->pe_info;
|
||||
|
||||
internal_f->f_timdat = time (0);
|
||||
|
||||
if (pe_value (&pe_info->dll, 0))
|
||||
internal_f->f_flags |= F_DLL ;
|
||||
|
||||
|
||||
if (bfd_get_section_by_name (abfd, ".reloc"))
|
||||
internal_f->f_flags &= ~F_RELFLG;
|
||||
|
||||
|
||||
memset (internal_f->pe, 0, sizeof (struct internal_extra_pe_filehdr));
|
||||
memset (internal_a->pe, 0, sizeof (struct internal_extra_pe_aouthdr));
|
||||
|
||||
|
||||
internal_a->pe->ImageBase = pe_value (&pe_info->image_base, IMAGE_BASE);
|
||||
|
||||
if (internal_a->tsize)
|
||||
internal_a->text_start -= internal_a->pe->ImageBase;
|
||||
if (internal_a->dsize)
|
||||
internal_a->data_start -= internal_a->pe->ImageBase;
|
||||
if (internal_a->entry)
|
||||
internal_a->entry -= internal_a->pe->ImageBase;
|
||||
|
||||
|
||||
internal_f->pe->e_magic = DOSMAGIC;
|
||||
internal_f->pe->e_cblp = 0x90;
|
||||
internal_f->pe->e_cp = 0x3;
|
||||
internal_f->pe->e_crlc = 0x0;
|
||||
internal_f->pe->e_cparhdr = 0x4;
|
||||
internal_f->pe->e_minalloc = 0x0;
|
||||
internal_f->pe->e_maxalloc = 0xffff;
|
||||
internal_f->pe->e_ss = 0x0;
|
||||
internal_f->pe->e_sp = 0xb8;
|
||||
internal_f->pe->e_csum = 0x0;
|
||||
internal_f->pe->e_ip = 0x0;
|
||||
internal_f->pe->e_cs = 0x0;
|
||||
internal_f->pe->e_lfarlc = 0x40;
|
||||
internal_f->pe->e_ovno = 0x0;
|
||||
{
|
||||
int idx;
|
||||
for (idx=0; idx < 4; idx++)
|
||||
internal_f->pe->e_res[idx] = 0x0;
|
||||
}
|
||||
internal_f->pe->e_oemid = 0x0;
|
||||
internal_f->pe->e_oeminfo = 0x0;
|
||||
{
|
||||
int idx;
|
||||
for (idx=0; idx < 10; idx++)
|
||||
internal_f->pe->e_res2[idx] = 0x0;
|
||||
}
|
||||
internal_f->pe->e_lfanew = 0x80;
|
||||
|
||||
/* this next collection of data are mostly just characters. It appears
|
||||
to be constant within the headers put on NT exes */
|
||||
internal_f->pe->dos_message[0] = 0x0eba1f0e;
|
||||
internal_f->pe->dos_message[1] = 0xcd09b400;
|
||||
internal_f->pe->dos_message[2] = 0x4c01b821;
|
||||
internal_f->pe->dos_message[3] = 0x685421cd;
|
||||
internal_f->pe->dos_message[4] = 0x70207369;
|
||||
internal_f->pe->dos_message[5] = 0x72676f72;
|
||||
internal_f->pe->dos_message[6] = 0x63206d61;
|
||||
internal_f->pe->dos_message[7] = 0x6f6e6e61;
|
||||
internal_f->pe->dos_message[8] = 0x65622074;
|
||||
internal_f->pe->dos_message[9] = 0x6e757220;
|
||||
internal_f->pe->dos_message[10] = 0x206e6920;
|
||||
internal_f->pe->dos_message[11] = 0x20534f44;
|
||||
internal_f->pe->dos_message[12] = 0x65646f6d;
|
||||
internal_f->pe->dos_message[13] = 0x0a0d0d2e;
|
||||
internal_f->pe->dos_message[14] = 0x24;
|
||||
internal_f->pe->dos_message[15] = 0x0;
|
||||
internal_f->pe->nt_signature = NT_SIGNATURE;
|
||||
|
||||
|
||||
/* write all of the other optional header data */
|
||||
|
||||
|
||||
|
||||
internal_a->pe->SectionAlignment = pe_value (&pe_info->section_alignment,
|
||||
NT_SECTION_ALIGNMENT);
|
||||
|
||||
internal_a->pe->FileAlignment = pe_value (&pe_info->file_alignment,
|
||||
NT_FILE_ALIGNMENT);
|
||||
|
||||
internal_a->pe->MajorOperatingSystemVersion =
|
||||
pe_value (&pe_info->major_os_version, 1);
|
||||
|
||||
internal_a->pe->MinorOperatingSystemVersion =
|
||||
pe_value (&pe_info->minor_os_version, 0);
|
||||
|
||||
internal_a->pe->MajorImageVersion =
|
||||
pe_value (&pe_info->major_image_version, 1);
|
||||
|
||||
internal_a->pe->MinorImageVersion =
|
||||
pe_value (&pe_info->minor_image_version, 0);
|
||||
|
||||
|
||||
internal_a->pe->MajorSubsystemVersion =
|
||||
pe_value (&pe_info->major_subsystem_version, 3);
|
||||
|
||||
|
||||
internal_a->pe->MinorSubsystemVersion =
|
||||
pe_value (&pe_info->minor_subsystem_version, 10);
|
||||
|
||||
|
||||
|
||||
internal_a->pe->Subsystem =
|
||||
pe_value (&pe_info->subsystem, BFD_PE_CONSOLE);
|
||||
|
||||
|
||||
|
||||
|
||||
/* Virtual start address, take virtual start address of last section,
|
||||
add its physical size and round up the next page (NT_SECTION_ALIGNMENT).
|
||||
An assumption has been made that the sections stored in the abfd
|
||||
structure are in order and that I have successfully saved the last
|
||||
section's address and size. */
|
||||
|
||||
internal_a->pe->SizeOfImage =
|
||||
(end_of_image - internal_a->pe->ImageBase
|
||||
+ internal_a->pe->SectionAlignment - 1)
|
||||
& ~ (internal_a->pe->SectionAlignment-1);
|
||||
|
||||
/* Start of .text section will do here since it is the first section after
|
||||
the headers. Note that NT_IMAGE_BASE has already been removed above */
|
||||
internal_a->pe->SizeOfHeaders = internal_a->text_start;
|
||||
internal_a->pe->CheckSum = 0;
|
||||
internal_a->pe->DllCharacteristics = 0;
|
||||
|
||||
internal_a->pe->SizeOfStackReserve = pe_value (&pe_info->stack_reserve,
|
||||
NT_DEF_RESERVE);
|
||||
internal_a->pe->SizeOfStackCommit = pe_value (&pe_info->stack_commit,
|
||||
NT_DEF_COMMIT);
|
||||
|
||||
internal_a->pe->SizeOfHeapReserve = pe_value (&pe_info->heap_reserve,
|
||||
NT_DEF_RESERVE);
|
||||
internal_a->pe->SizeOfHeapCommit = pe_value (&pe_info->heap_commit,
|
||||
NT_DEF_COMMIT);
|
||||
|
||||
internal_a->pe->LoaderFlags = 0;
|
||||
internal_a->pe->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; /* 0x10 */
|
||||
|
||||
/* first null out all data directory entries .. */
|
||||
memset (internal_a->pe->DataDirectory, sizeof (internal_a->pe->DataDirectory), 0);
|
||||
|
||||
add_data_entry (abfd, internal_a, 0, ".edata", internal_a->pe->ImageBase);
|
||||
add_data_entry (abfd, internal_a, 1, ".idata", internal_a->pe->ImageBase);
|
||||
add_data_entry (abfd, internal_a, 2, ".rsrc" ,internal_a->pe->ImageBase);
|
||||
add_data_entry (abfd, internal_a, 5, ".reloc", internal_a->pe->ImageBase);
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1700,6 +1876,21 @@ coff_write_object_contents (abfd)
|
|||
struct internal_filehdr internal_f;
|
||||
struct internal_aouthdr internal_a;
|
||||
|
||||
#ifdef COFF_IMAGE_WITH_PE
|
||||
struct internal_extra_pe_aouthdr extra_a;
|
||||
struct internal_extra_pe_filehdr extra_f;
|
||||
|
||||
bfd_link_pe_info *pe_info = coff_data (abfd)->link_info->pe_info;
|
||||
bfd_link_pe_info defs;
|
||||
if (!pe_info)
|
||||
{
|
||||
/* Just use sensible defaults */
|
||||
memset (&defs, 0, sizeof (defs));
|
||||
coff_data (abfd)->link_info->pe_info = &defs;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
|
||||
if (abfd->output_has_begun == false)
|
||||
|
@ -1885,7 +2076,6 @@ coff_write_object_contents (abfd)
|
|||
field does not belong here. We fill it with a 0 so it compares the
|
||||
same but is not a reasonable time. -- gnu@cygnus.com
|
||||
*/
|
||||
internal_f.f_timdat = 0;
|
||||
|
||||
internal_f.f_flags = 0;
|
||||
|
||||
|
@ -1906,58 +2096,6 @@ coff_write_object_contents (abfd)
|
|||
else
|
||||
internal_f.f_flags |= F_AR32W;
|
||||
|
||||
#ifdef COFF_WITH_PE
|
||||
/* assign other filehdr fields for DOS header and NT signature */
|
||||
internal_f.e_magic = DOSMAGIC;
|
||||
internal_f.e_cblp = 0x90;
|
||||
internal_f.e_cp = 0x3;
|
||||
internal_f.e_crlc = 0x0;
|
||||
internal_f.e_cparhdr = 0x4;
|
||||
internal_f.e_minalloc = 0x0;
|
||||
internal_f.e_maxalloc = 0xffff;
|
||||
internal_f.e_ss = 0x0;
|
||||
internal_f.e_sp = 0xb8;
|
||||
internal_f.e_csum = 0x0;
|
||||
internal_f.e_ip = 0x0;
|
||||
internal_f.e_cs = 0x0;
|
||||
internal_f.e_lfarlc = 0x40;
|
||||
internal_f.e_ovno = 0x0;
|
||||
{
|
||||
int idx;
|
||||
for (idx=0; idx < 4; idx++)
|
||||
internal_f.e_res[idx] = 0x0;
|
||||
}
|
||||
internal_f.e_oemid = 0x0;
|
||||
internal_f.e_oeminfo = 0x0;
|
||||
{
|
||||
int idx;
|
||||
for (idx=0; idx < 10; idx++)
|
||||
internal_f.e_res2[idx] = 0x0;
|
||||
}
|
||||
internal_f.e_lfanew = 0x80;
|
||||
|
||||
/* this next collection of data are mostly just characters. It appears
|
||||
to be constant within the headers put on NT exes */
|
||||
internal_f.dos_message[0] = 0x0eba1f0e;
|
||||
internal_f.dos_message[1] = 0xcd09b400;
|
||||
internal_f.dos_message[2] = 0x4c01b821;
|
||||
internal_f.dos_message[3] = 0x685421cd;
|
||||
internal_f.dos_message[4] = 0x70207369;
|
||||
internal_f.dos_message[5] = 0x72676f72;
|
||||
internal_f.dos_message[6] = 0x63206d61;
|
||||
internal_f.dos_message[7] = 0x6f6e6e61;
|
||||
internal_f.dos_message[8] = 0x65622074;
|
||||
internal_f.dos_message[9] = 0x6e757220;
|
||||
internal_f.dos_message[10] = 0x206e6920;
|
||||
internal_f.dos_message[11] = 0x20534f44;
|
||||
internal_f.dos_message[12] = 0x65646f6d;
|
||||
internal_f.dos_message[13] = 0x0a0d0d2e;
|
||||
internal_f.dos_message[14] = 0x24;
|
||||
internal_f.dos_message[15] = 0x0;
|
||||
internal_f.nt_signature = NT_SIGNATURE;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
FIXME, should do something about the other byte orders and
|
||||
architectures.
|
||||
|
@ -2077,126 +2215,29 @@ coff_write_object_contents (abfd)
|
|||
if (text_sec)
|
||||
{
|
||||
internal_a.tsize = bfd_get_section_size_before_reloc (text_sec);
|
||||
internal_a.text_start = internal_a.tsize ?
|
||||
(text_sec->vma - IMAGE_BASE) : 0;
|
||||
internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
|
||||
}
|
||||
if (data_sec)
|
||||
{
|
||||
internal_a.dsize = bfd_get_section_size_before_reloc (data_sec);
|
||||
internal_a.data_start = internal_a.dsize ?
|
||||
(data_sec->vma - IMAGE_BASE) : 0;
|
||||
internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
|
||||
}
|
||||
if (bss_sec)
|
||||
{
|
||||
internal_a.bsize = bfd_get_section_size_before_reloc (bss_sec);
|
||||
}
|
||||
|
||||
internal_a.entry = bfd_get_start_address (abfd) - IMAGE_BASE;
|
||||
internal_a.entry = bfd_get_start_address (abfd);
|
||||
internal_f.f_nsyms = obj_raw_syment_count (abfd);
|
||||
|
||||
#ifdef COFF_WITH_PE /* write all of the other optional header data */
|
||||
/* Note; the entries for subsystem, stack reserve, stack commit, heap reserve
|
||||
and heap commit may be supplied on the command line via the -subsystem,
|
||||
-stack and/or -heap switches. This data is initially stored in variable
|
||||
link_info. This is eventually passed to the bfd (from ld) in (cofflink.c)
|
||||
_bfd_coff_final_link. Once this function gets it, we copy it into variables
|
||||
NT_subsystem and NT_stack_heap which are defined in internal.h. With
|
||||
respect to the stack/heap reserve/commit parameters, if nothing has been
|
||||
defined for these, the input values will be '0' (i.e. the values stored
|
||||
in NT_stack_heap) will be 0. */
|
||||
|
||||
internal_a.ImageBase = NT_IMAGE_BASE; /* 0x400000 */
|
||||
internal_a.SectionAlignment = NT_SECTION_ALIGNMENT; /* 0x1000 */
|
||||
internal_a.FileAlignment = NT_FILE_ALIGNMENT; /* 0x200 */
|
||||
internal_a.MajorOperatingSystemVersion = 1;
|
||||
internal_a.MinorOperatingSystemVersion = 0;
|
||||
internal_a.MajorImageVersion = 0;
|
||||
internal_a.MinorImageVersion = 0;
|
||||
internal_a.MajorSubsystemVersion = 3;
|
||||
internal_a.MinorSubsystemVersion = 0xA;
|
||||
internal_a.Reserved1 = 0;
|
||||
/* Virtual start address, take virtual start address of last section,
|
||||
add its physical size and round up the next page (NT_SECTION_ALIGNMENT).
|
||||
An assumption has been made that the sections stored in the abfd
|
||||
structure are in order and that I have successfully saved the last
|
||||
section's address and size. */
|
||||
|
||||
internal_a.SizeOfImage =
|
||||
(end_of_image - NT_IMAGE_BASE + NT_SECTION_ALIGNMENT - 1)
|
||||
& ~ (NT_SECTION_ALIGNMENT-1);
|
||||
|
||||
/* Start of .text section will do here since it is the first section after
|
||||
the headers. Note that NT_IMAGE_BASE has already been removed above */
|
||||
internal_a.SizeOfHeaders = internal_a.text_start;
|
||||
internal_a.CheckSum = 0;
|
||||
switch (NT_subsystem)
|
||||
{
|
||||
/* The possible values are:
|
||||
1 - NATIVE Doesn't require a subsystem
|
||||
2 - WINDOWS_GUI runs in Windows GUI subsystem
|
||||
3 - WINDOWS_CUI runs in Windows char sub. (console app)
|
||||
5 - OS2_CUI runs in OS/2 character subsystem
|
||||
7 - POSIX_CUI runs in Posix character subsystem */
|
||||
case native:
|
||||
internal_a.Subsystem = 1;
|
||||
break;
|
||||
case windows:
|
||||
internal_a.Subsystem = 2;
|
||||
break;
|
||||
case console:
|
||||
internal_a.Subsystem = 3;
|
||||
break;
|
||||
case os2:
|
||||
internal_a.Subsystem = 5;
|
||||
break;
|
||||
case posix:
|
||||
internal_a.Subsystem = 7;
|
||||
break;
|
||||
default:
|
||||
internal_a.Subsystem = 3;
|
||||
}
|
||||
internal_a.DllCharacteristics = 0;
|
||||
if (NT_stack_heap.stack_defined)
|
||||
{
|
||||
internal_a.SizeOfStackReserve = NT_stack_heap.stack_reserve;
|
||||
/* since commit is an optional parameter, verify that it is non-zero */
|
||||
if (NT_stack_heap.stack_commit > 0)
|
||||
internal_a.SizeOfStackCommit = NT_stack_heap.stack_commit;
|
||||
else
|
||||
internal_a.SizeOfStackCommit = NT_DEF_COMMIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
internal_a.SizeOfStackReserve = NT_DEF_RESERVE; /* 0x100000 */
|
||||
internal_a.SizeOfStackCommit = NT_DEF_COMMIT; /* 0x1000 */
|
||||
}
|
||||
if (NT_stack_heap.heap_defined)
|
||||
{
|
||||
internal_a.SizeOfHeapReserve = NT_stack_heap.heap_reserve;
|
||||
/* since commit is an optional parameter, verify that it is non-zero */
|
||||
if (NT_stack_heap.heap_commit > 0)
|
||||
internal_a.SizeOfHeapCommit = NT_stack_heap.heap_commit;
|
||||
else
|
||||
internal_a.SizeOfHeapCommit = NT_DEF_COMMIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
internal_a.SizeOfHeapReserve = NT_DEF_RESERVE; /* 0x100000 */
|
||||
internal_a.SizeOfHeapCommit = NT_DEF_COMMIT; /* 0x1000 */
|
||||
}
|
||||
internal_a.LoaderFlags = 0;
|
||||
internal_a.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; /* 0x10 */
|
||||
|
||||
/* first null out all data directory entries .. */
|
||||
memset (internal_a.DataDirectory, sizeof (internal_a.DataDirectory), 0);
|
||||
|
||||
add_data_entry (abfd, &internal_a, 0, ".edata");
|
||||
add_data_entry (abfd, &internal_a, 1, ".idata");
|
||||
add_data_entry (abfd, &internal_a, 2, ".rsrc");
|
||||
add_data_entry (abfd, &internal_a, 5, ".reloc");
|
||||
|
||||
|
||||
#ifdef COFF_IMAGE_WITH_PE
|
||||
|
||||
internal_f.pe = & extra_f;
|
||||
internal_a.pe = & extra_a;
|
||||
|
||||
fill_pe_header_info (abfd, &internal_f, &internal_a, end_of_image);
|
||||
#endif
|
||||
|
||||
/* now write them */
|
||||
|
@ -2393,8 +2434,6 @@ coff_slurp_symbol_table (abfd)
|
|||
|
||||
if (obj_symbols (abfd))
|
||||
return true;
|
||||
if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
|
||||
return false;
|
||||
|
||||
/* Read in the symbol table */
|
||||
if ((native_symbols = coff_get_normalized_symtab (abfd)) == NULL)
|
||||
|
@ -3025,6 +3064,12 @@ static CONST bfd_coff_backend_data bfd_coff_std_swap_table =
|
|||
#ifndef coff_bfd_is_local_label
|
||||
#define coff_bfd_is_local_label bfd_generic_is_local_label
|
||||
#endif
|
||||
#ifndef coff_read_minisymbols
|
||||
#define coff_read_minisymbols _bfd_generic_read_minisymbols
|
||||
#endif
|
||||
#ifndef coff_minisymbol_to_symbol
|
||||
#define coff_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
|
||||
#endif
|
||||
|
||||
/* The reloc lookup routine must be supplied by each individual COFF
|
||||
backend. */
|
||||
|
@ -3032,6 +3077,10 @@ static CONST bfd_coff_backend_data bfd_coff_std_swap_table =
|
|||
#define coff_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
|
||||
#endif
|
||||
|
||||
#ifndef coff_bfd_get_relocated_section_contents
|
||||
#define coff_bfd_get_relocated_section_contents \
|
||||
bfd_generic_get_relocated_section_contents
|
||||
#endif
|
||||
#ifndef coff_bfd_relax_section
|
||||
#define coff_bfd_relax_section bfd_generic_relax_section
|
||||
#endif
|
||||
|
|
|
@ -79,8 +79,6 @@ struct coff_final_link_info
|
|||
/* Buffer large enough to hold swapped relocs of any input section. */
|
||||
struct internal_reloc *internal_relocs;
|
||||
|
||||
enum bfd_link_subsystem subsystem;
|
||||
bfd_link_stack_heap stack_heap_parameters;
|
||||
};
|
||||
|
||||
static struct bfd_hash_entry *coff_link_hash_newfunc
|
||||
|
@ -524,16 +522,18 @@ coff_link_add_symbols (abfd, info)
|
|||
/* parse out a -heap <reserved>,<commit> line */
|
||||
|
||||
static char *
|
||||
dores_com (ptr, def,res, com)
|
||||
dores_com (ptr, res, com)
|
||||
char *ptr;
|
||||
int *def;
|
||||
int *res;
|
||||
int *com;
|
||||
bfd_link_pe_info_dval *res;
|
||||
bfd_link_pe_info_dval *com;
|
||||
{
|
||||
*def = 1;
|
||||
*res = strtoul (ptr, &ptr, 0);
|
||||
if (ptr[0] == ',')
|
||||
*com = strtoul (ptr+1, &ptr, 0);
|
||||
res->defined = 1;
|
||||
res->value = strtoul (ptr, &ptr, 0);
|
||||
if (ptr[0] == ',')
|
||||
{
|
||||
com->value = strtoul (ptr+1, &ptr, 0);
|
||||
com->defined = 1;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
@ -552,7 +552,8 @@ char **dst;
|
|||
/* Process any magic embedded commands in a section called .drectve */
|
||||
|
||||
static int
|
||||
process_embedded_commands (abfd)
|
||||
process_embedded_commands (info, abfd)
|
||||
struct bfd_link_info *info;
|
||||
bfd *abfd;
|
||||
{
|
||||
asection *sec = bfd_get_section_by_name (abfd, ".drectve");
|
||||
|
@ -624,16 +625,15 @@ process_embedded_commands (abfd)
|
|||
else if (strncmp (s,"-heap", 5) == 0)
|
||||
{
|
||||
s = dores_com (s+5,
|
||||
&NT_stack_heap.heap_defined,
|
||||
&NT_stack_heap.heap_reserve,
|
||||
&NT_stack_heap.heap_commit);
|
||||
&info->pe_info->heap_reserve,
|
||||
&info->pe_info->heap_commit);
|
||||
}
|
||||
else if (strncmp (s,"-stack", 6) == 0)
|
||||
{
|
||||
s = dores_com (s+6,
|
||||
&NT_stack_heap.heap_defined,
|
||||
&NT_stack_heap.heap_reserve,
|
||||
&NT_stack_heap.heap_commit);
|
||||
&info->pe_info->stack_reserve,
|
||||
&info->pe_info->stack_commit);
|
||||
|
||||
}
|
||||
else
|
||||
s++;
|
||||
|
@ -681,14 +681,7 @@ _bfd_coff_final_link (abfd, info)
|
|||
finfo.external_relocs = NULL;
|
||||
finfo.internal_relocs = NULL;
|
||||
|
||||
if (obj_pe(abfd))
|
||||
{
|
||||
/* store the subsystem, stack and heap parameters in variables defined
|
||||
in internal.h so that when they are needed to write the NT optional
|
||||
file header (coffcode.h), they will be available */
|
||||
NT_subsystem = info->subsystem;
|
||||
NT_stack_heap = info->stack_heap_parameters;
|
||||
}
|
||||
coff_data (abfd)->link_info = info;
|
||||
|
||||
finfo.strtab = _bfd_stringtab_init ();
|
||||
if (finfo.strtab == NULL)
|
||||
|
@ -1278,7 +1271,7 @@ coff_link_input_bfd (finfo, input_bfd)
|
|||
|
||||
if (obj_pe (output_bfd))
|
||||
{
|
||||
if (!process_embedded_commands (input_bfd))
|
||||
if (!process_embedded_commands (finfo->info, input_bfd))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* BFD COFF object file private structure.
|
||||
Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
@ -16,7 +16,7 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "bfdlink.h"
|
||||
|
||||
|
@ -24,6 +24,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
|
||||
#define coff_data(bfd) ((bfd)->tdata.coff_obj_data)
|
||||
#define exec_hdr(bfd) (coff_data(bfd)->hdr)
|
||||
#define obj_pe(bfd) (coff_data(bfd)->pe)
|
||||
#define obj_symbols(bfd) (coff_data(bfd)->symbols)
|
||||
#define obj_sym_filepos(bfd) (coff_data(bfd)->sym_filepos)
|
||||
|
||||
|
@ -34,7 +35,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
#define obj_conv_table_size(bfd) (coff_data(bfd)->conv_table_size)
|
||||
|
||||
#define obj_coff_external_syms(bfd) (coff_data (bfd)->external_syms)
|
||||
#define obj_coff_keep_syms(bfd) (coff_data (bfd)->keep_syms)
|
||||
#define obj_coff_strings(bfd) (coff_data (bfd)->strings)
|
||||
#define obj_coff_keep_strings(bfd) (coff_data (bfd)->keep_strings)
|
||||
#define obj_coff_sym_hashes(bfd) (coff_data (bfd)->sym_hashes)
|
||||
|
||||
/* `Tdata' information kept for COFF files. */
|
||||
|
@ -63,16 +66,48 @@ typedef struct coff_tdata
|
|||
unsigned local_auxesz;
|
||||
unsigned local_linesz;
|
||||
|
||||
/* Used by the COFF backend linker. */
|
||||
/* The unswapped external symbols. May be NULL. Read by
|
||||
_bfd_coff_get_external_symbols. */
|
||||
PTR external_syms;
|
||||
/* If this is true, the external_syms may not be freed. */
|
||||
boolean keep_syms;
|
||||
|
||||
/* The string table. May be NULL. Read by
|
||||
_bfd_coff_read_string_table. */
|
||||
char *strings;
|
||||
/* If this is true, the strings may not be freed. */
|
||||
boolean keep_strings;
|
||||
|
||||
/* is this a PE format coff file */
|
||||
int pe;
|
||||
/* Used by the COFF backend linker. */
|
||||
struct coff_link_hash_entry **sym_hashes;
|
||||
struct bfd_link_info *link_info;
|
||||
} coff_data_type;
|
||||
|
||||
/* We take the address of the first element of a asymbol to ensure that the
|
||||
* macro is only ever applied to an asymbol. */
|
||||
#define coffsymbol(asymbol) ((coff_symbol_type *)(&((asymbol)->the_bfd)))
|
||||
|
||||
/* The used_by_bfd field of a section may be set to a pointer to this
|
||||
structure. */
|
||||
|
||||
struct coff_section_tdata
|
||||
{
|
||||
/* The relocs, swapped into COFF internal form. This may be NULL. */
|
||||
struct internal_reloc *relocs;
|
||||
/* If this is true, the relocs entry may not be freed. */
|
||||
boolean keep_relocs;
|
||||
/* The section contents. This may be NULL. */
|
||||
bfd_byte *contents;
|
||||
/* If this is true, the contents entry may not be freed. */
|
||||
boolean keep_contents;
|
||||
};
|
||||
|
||||
/* An accessor macro for the coff_section_tdata structure. */
|
||||
#define coff_section_data(abfd, sec) \
|
||||
((struct coff_section_tdata *) (sec)->used_by_bfd)
|
||||
|
||||
/* COFF linker hash table entries. */
|
||||
|
||||
struct coff_link_hash_entry
|
||||
|
@ -132,12 +167,15 @@ extern long coff_get_symtab_upper_bound PARAMS ((bfd *));
|
|||
extern long coff_get_symtab PARAMS ((bfd *, asymbol **));
|
||||
extern int coff_count_linenumbers PARAMS ((bfd *));
|
||||
extern struct coff_symbol_struct *coff_symbol_from PARAMS ((bfd *, asymbol *));
|
||||
extern boolean coff_renumber_symbols PARAMS ((bfd *));
|
||||
extern boolean coff_renumber_symbols PARAMS ((bfd *, int *));
|
||||
extern void coff_mangle_symbols PARAMS ((bfd *));
|
||||
extern boolean coff_write_symbols PARAMS ((bfd *));
|
||||
extern boolean coff_write_linenumbers PARAMS ((bfd *));
|
||||
extern alent *coff_get_lineno PARAMS ((bfd *, asymbol *));
|
||||
extern asymbol *coff_section_symbol PARAMS ((bfd *, char *));
|
||||
extern boolean _bfd_coff_get_external_symbols PARAMS ((bfd *));
|
||||
extern const char *_bfd_coff_read_string_table PARAMS ((bfd *));
|
||||
extern boolean _bfd_coff_free_symbols PARAMS ((bfd *));
|
||||
extern struct coff_ptr_struct *coff_get_normalized_symtab PARAMS ((bfd *));
|
||||
extern long coff_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
|
||||
extern asymbol *coff_make_empty_symbol PARAMS ((bfd *));
|
||||
|
@ -175,6 +213,12 @@ extern boolean _bfd_coff_link_add_symbols
|
|||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
extern boolean _bfd_coff_final_link
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
extern struct internal_reloc *_bfd_coff_read_internal_relocs
|
||||
PARAMS ((bfd *, asection *, boolean, bfd_byte *, boolean,
|
||||
struct internal_reloc *));
|
||||
extern boolean _bfd_coff_generic_relocate_section
|
||||
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
|
||||
struct internal_reloc *, struct internal_syment *, asection **));
|
||||
|
||||
/* And more taken from the source .. */
|
||||
|
||||
|
@ -365,6 +409,20 @@ typedef struct
|
|||
struct internal_reloc *relocs,
|
||||
struct internal_syment *syms,
|
||||
asection **sections));
|
||||
reloc_howto_type *(*_bfd_coff_rtype_to_howto) PARAMS ((
|
||||
bfd *abfd,
|
||||
asection *sec,
|
||||
struct internal_reloc *rel,
|
||||
struct coff_link_hash_entry *h,
|
||||
struct internal_syment *sym,
|
||||
bfd_vma *addendp));
|
||||
boolean (*_bfd_coff_adjust_symndx) PARAMS ((
|
||||
bfd *obfd,
|
||||
struct bfd_link_info *info,
|
||||
bfd *ibfd,
|
||||
asection *sec,
|
||||
struct internal_reloc *reloc,
|
||||
boolean *adjustedp));
|
||||
|
||||
} bfd_coff_backend_data;
|
||||
|
||||
|
@ -462,4 +520,10 @@ typedef struct
|
|||
#define bfd_coff_relocate_section(obfd,info,ibfd,o,con,rel,isyms,secs)\
|
||||
((coff_backend_info (ibfd)->_bfd_coff_relocate_section)\
|
||||
(obfd, info, ibfd, o, con, rel, isyms, secs))
|
||||
#define bfd_coff_rtype_to_howto(abfd, sec, rel, h, sym, addendp)\
|
||||
((coff_backend_info (abfd)->_bfd_coff_rtype_to_howto)\
|
||||
(abfd, sec, rel, h, sym, addendp))
|
||||
#define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\
|
||||
((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\
|
||||
(obfd, info, ibfd, sec, rel, adjustedp))
|
||||
|
||||
|
|
Loading…
Reference in New Issue