From e9614321dab85385acefe9183152cca532e3553b Mon Sep 17 00:00:00 2001 From: Steve Chamberlain Date: Tue, 22 Aug 1995 01:02:23 +0000 Subject: [PATCH] Mon Aug 21 17:49:28 1995 steve chamberlain * 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. --- bfd/ChangeLog | 19 +++ bfd/bfd-in2.h | 70 ++++++--- bfd/coffcode.h | 375 ++++++++++++++++++++++++++++--------------------- bfd/cofflink.c | 45 +++--- bfd/libcoff.h | 72 +++++++++- 5 files changed, 366 insertions(+), 215 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index bd93fea8f90..4d034364eeb 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,22 @@ +Mon Aug 21 17:49:28 1995 steve chamberlain + + * 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 * linker.c (link_action): If an undefined reference follows an diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 91d5cc9738f..c04bd4d8b3a 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -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)\ diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 14326fbe531..08964fc68f7 100644 --- a/bfd/coffcode.h +++ b/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 diff --git a/bfd/cofflink.c b/bfd/cofflink.c index 003e3b99898..c4c42d5a8ef 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -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 , 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; } diff --git a/bfd/libcoff.h b/bfd/libcoff.h index 99a2347cde6..ccd42219c87 100644 --- a/bfd/libcoff.h +++ b/bfd/libcoff.h @@ -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)) -- 2.30.2