aboutsummaryrefslogtreecommitdiff
path: root/bfd/coffcode.h
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/coffcode.h')
-rw-r--r--bfd/coffcode.h375
1 files changed, 212 insertions, 163 deletions
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 14326fb..08964fc 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,21 +1671,187 @@ 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
/* SUPPRESS 558 */
@@ -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