* Makefile.in: versados.o is now conditionally built.
* coffcode.h (add_data_entry): New function.
(coff_write_object_contents): Clean up. Calculate
data entries.
* cofflink.c (_bfd_coff_generic_relocate_section):
.reloc and .edata sections are IMAGE_BASED too.
If there's a base_file then write out base information.
* configure.host (i386-*-pe): New.
* syms.c (coff_section_type): Only scan prefixes.
* targets.c (bfd_target_vector): Versados is now conditionally
built.
* config/m68k-coff.mt: Build versados.o
* hosts/i386pe.h: New file.
+Wed Jun 28 18:04:42 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * Makefile.in: versados.o is now conditionally built.
+ * coffcode.h (add_data_entry): New function.
+ (coff_write_object_contents): Clean up. Calculate
+ data entries.
+ * cofflink.c (_bfd_coff_generic_relocate_section):
+ .reloc and .edata sections are IMAGE_BASED too.
+ If there's a base_file then write out base information.
+ * configure.host (i386-*-pe): New.
+ * syms.c (coff_section_type): Only scan prefixes.
+ * targets.c (bfd_target_vector): Versados is now conditionally
+ built.
+ * config/m68k-coff.mt: Build versados.o
+ * hosts/i386pe.h: New file.
+
Mon Jun 26 13:53:49 1995 Jeff Law (law@snake.cs.utah.edu)
* elf32-hpa.c (elf32_hppa_relocate_section): Close comment before
archive.o archures.o bfd.o cache.o coffgen.o core.o \
format.o init.o libbfd.o opncls.o reloc.o \
section.o syms.o targets.o hash.o linker.o \
- elf.o srec.o binary.o
+ elf.o srec.o binary.o tekhex.o
# This list is alphabetized to make it easier to keep in sync
# with the decls and initializer in archures.c.
i386bsd.o \
i386linux.o \
i386lynx.o \
+ i386msdos.o \
i386netbsd.o \
i386mach3.o \
i386os9k.o \
ns32knetbsd.o \
oasys.o \
pc532-mach.o \
+ pe-arm.o \
+ pei-arm.o \
+ pe-i386.o \
+ pei-i386.o \
reloc16.o \
sparclynx.o \
sparcnetbsd.o \
# if configured as $(oldincludedir) -- which it usually isnt.
$(INSTALL_DATA) $(BFD_H) $(includedir)/bfd.h
$(INSTALL_DATA) $(INCDIR)/ansidecl.h $(includedir)/ansidecl.h
+ $(INSTALL_DATA) $(INCDIR)/bfdlink.h $(includedir)/bfdlink.h
$(INSTALL_DATA) $(INCDIR)/obstack.h $(includedir)/obstack.h
-if test -z "$(oldincludedir)"; then true; else \
test -d $(oldincludedir) || mkdir $(oldincludedir); \
$(INSTALL_DATA) $(BFD_H) $(oldincludedir)/bfd.h; \
$(INSTALL_DATA) $(INCDIR)/ansidecl.h $(oldincludedir)/ansidecl.h; \
+ $(INSTALL_DATA) $(INCDIR)/bfdlink.h $(oldincludedir)/bfdlink.h; \
$(INSTALL_DATA) $(INCDIR)/obstack.h $(oldincludedir)/obstack.h; \
$(MAKE) subdir_do DO=install "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS); \
fi
archures.o: archures.c
coff-i386.o: coff-i386.c $(INCDIR)/coff/i386.h $(INCDIR)/coff/internal.h \
libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+pe-i386.o: pe-i386.c coff-i386.c $(INCDIR)/coff/i386.h $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+pei-i386.o: pei-i386.c coff-i386.c $(INCDIR)/coff/i386.h $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
coff-go32.o: coff-go32.c coff-i386.c $(INCDIR)/coff/i386.h \
$(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
coffcode.h coffswap.h
coff-i960.o: coff-i960.c $(INCDIR)/coff/i960.h $(INCDIR)/coff/internal.h \
libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
srec.o: srec.c $(INCDIR)/libiberty.h
+versados.o: versados.c $(INCDIR)/libiberty.h
binary.o: binary.c
tekhex.o: tekhex.c $(INCDIR)/libiberty.h
oasys.o: oasys.c $(INCDIR)/oasys.h liboasys.h
libaout.h $(INCDIR)/aout/aout64.h $(INCDIR)/coff/internal.h \
$(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \
libcoff.h libecoff.h
-ecofflink.o: ecofflink.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \
- $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h
+ecofflink.o: ecofflink.c $(INCDIR)/bfdlink.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/coff/internal.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h
coff-m68k.o: coff-m68k.c $(INCDIR)/coff/m68k.h $(INCDIR)/coff/internal.h \
libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
coff-u68k.o: coff-u68k.c coff-m68k.c $(INCDIR)/coff/m68k.h \
/* BFD back-end for Intel 386 COFF files.
- Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
#include "sysdep.h"
#include "libbfd.h"
#include "obstack.h"
+
#include "coff/i386.h"
+
#include "coff/internal.h"
+
+#ifdef COFF_WITH_PE
+#include "coff/pe.h"
+#endif
+
#include "libcoff.h"
static bfd_reloc_status_type coff_i386_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
-static const struct reloc_howto_struct *coff_i386_rtype_to_howto
+static reloc_howto_type *coff_i386_rtype_to_howto
PARAMS ((bfd *, asection *, struct internal_reloc *,
struct coff_link_hash_entry *, struct internal_syment *,
+
bfd_vma *));
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
-
/* The page size is a guess based on ELF. */
#define COFF_PAGE_SIZE 0x1000
return bfd_reloc_continue;
}
+
+
+#ifndef PCRELOFFSET
+#define PCRELOFFSET false
+#endif
+
static reloc_howto_type howto_table[] =
{
{0},
{4},
{5},
HOWTO (R_DIR32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_i386_reloc, /* special_function */
+ "dir32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+ /* {7}, */
+ HOWTO (7, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
false), /* pcrel_offset */
- {7},
{010},
{011},
{012},
true, /* partial_inplace */
0x000000ff, /* src_mask */
0x000000ff, /* dst_mask */
- false), /* pcrel_offset */
+ PCRELOFFSET), /* pcrel_offset */
HOWTO (R_RELWORD, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
true, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
- false), /* pcrel_offset */
+ PCRELOFFSET), /* pcrel_offset */
HOWTO (R_RELLONG, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
true, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
+ PCRELOFFSET), /* pcrel_offset */
HOWTO (R_PCRBYTE, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
true, /* partial_inplace */
0x000000ff, /* src_mask */
0x000000ff, /* dst_mask */
- false), /* pcrel_offset */
+ PCRELOFFSET), /* pcrel_offset */
HOWTO (R_PCRWORD, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
true, /* partial_inplace */
0x0000ffff, /* src_mask */
0x0000ffff, /* dst_mask */
- false), /* pcrel_offset */
+ PCRELOFFSET), /* pcrel_offset */
HOWTO (R_PCRLONG, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
true, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
- false) /* pcrel_offset */
+ PCRELOFFSET) /* pcrel_offset */
};
/* Turn a howto into a reloc nunmber */
/* We use the special COFF backend linker. */
#define coff_relocate_section _bfd_coff_generic_relocate_section
-static const struct reloc_howto_struct *
+static reloc_howto_type *
coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
bfd *abfd;
asection *sec;
struct internal_syment *sym;
bfd_vma *addendp;
{
- const struct reloc_howto_struct *howto;
+
+ reloc_howto_type *howto;
howto = howto_table + rel->r_type;
+#ifdef COFF_WITH_PE
+ *addendp = 0;
+#endif
+
if (howto->pc_relative)
*addendp += sec->vma;
function will be adding in the final value of the symbol. We
need to subtract out the current size in order to get the
correct result. */
+
BFD_ASSERT (h != NULL);
+
+
+#ifndef COFF_WITH_PE
+ /* I think we *do* want to bypass this. If we don't, I have seen some data
+ parameters get the wrong relcation address. If I link two versions
+ with and without this section bypassed and then do a binary comparison,
+ the addresses which are different can be looked up in the map. The
+ case in which this section has been bypassed has addresses which correspond
+ to values I can find in the map */
*addendp -= sym->n_value;
+#endif
}
/* If the output symbol is common (in which case this must be a
relocateable link), we need to add in the final size of the
common symbol. */
- if (h != NULL && h->root.type == bfd_link_hash_common)
+ if (h != NULL && h->root.type == bfd_link_hash_common)
*addendp += h->root.u.c.size;
+
+#ifdef COFF_WITH_PE
+ if (howto->pc_relative)
+ *addendp -= 4;
+#endif
+
return howto;
}
*/
+#ifndef IMAGE_BASE
+#define IMAGE_BASE 0
+#endif
+
#include "coffswap.h"
\f
/* void warning(); */
styp_flags = STYP_INFO;
#endif
}
- else if (!strcmp (sec_name, ".stab")
- || !strncmp (sec_name, ".stabstr", 8))
+ else if (!strncmp (sec_name, ".stab", 5))
{
styp_flags = STYP_INFO;
}
#ifdef _COMMENT
|| strcmp (name, _COMMENT) == 0
#endif
- || strcmp (name, ".stab") == 0
- || strcmp (name, ".stabstr") == 0)
+ || strncmp (name, ".stab", 5) == 0)
{
#ifdef COFF_PAGE_SIZE
sec_flags |= SEC_DEBUGGING;
.stabstr section this way for backward compatibility, although I
believe it would work anyhow. */
if (COFF_DEFAULT_SECTION_ALIGNMENT_POWER > 2
- && (strcmp (section->name, ".stab") == 0
- || strcmp (section->name, ".stabstr") == 0))
+ && (strncmp (section->name, ".stab", 5) == 0))
section->alignment_power = 2;
return true;
coff->raw_syments = (struct coff_ptr_struct *) NULL;
coff->relocbase = 0;
/* make_abs_section(abfd);*/
+
+#ifdef COFF_WITH_PE
+ obj_pe (abfd) = 1;
+#endif
return true;
}
machine = 0;
break;
#endif
-
#ifdef A29K_MAGIC_BIG
case A29K_MAGIC_BIG:
case A29K_MAGIC_LITTLE:
machine = 0;
break;
#endif
-
+#ifdef ARMMAGIC
+ case ARMMAGIC:
+ arch = bfd_arch_arm;
+ machine =0;
+ break;
+#endif
#ifdef MC68MAGIC
case MC68MAGIC:
case M68MAGIC:
*/
static boolean
-coff_write_relocs (abfd)
+coff_write_relocs (abfd, first_undef)
bfd * abfd;
+ int first_undef;
{
asection *s;
for (s = abfd->sections; s != (asection *) NULL; s = s->next)
arelent *q = p[i];
memset ((PTR) & n, 0, sizeof (n));
+ /* Now we've renumbered the symbols we know where the
+ undefined symbols live in the table. Check the reloc
+ entries for symbols who's output bfd isn't the right one.
+ This is because the symbol was undefined (which means
+ that all the pointers are never made to point to the same
+ place). This is a bad thing,'cause the symbols attached
+ to the output bfd are indexed, so that the relocation
+ entries know which symbol index they point to. So we
+ have to look up the output symbol here. */
+
+ if (q->sym_ptr_ptr[0]->the_bfd != abfd)
+ {
+ int i;
+ const char *sname = q->sym_ptr_ptr[0]->name;
+ asymbol **outsyms = abfd->outsymbols;
+ for (i = first_undef; outsyms[i]; i++)
+ {
+ const char *intable = outsyms[i]->name;
+ if (strcmp (intable, sname) == 0) {
+ /* got a hit, so repoint the reloc */
+ q->sym_ptr_ptr = outsyms + i;
+ break;
+ }
+ }
+ }
+
n.r_vaddr = q->address + s->vma;
#ifdef R_IHCONST
/* The 29k const/consth reloc pair is a real kludge. The consth
- part doesn't have a symbol; it has an offset. So rebuilt
- that here. */
+ part doesn't have a symbol; it has an offset. So rebuilt
+ that here. */
if (q->howto->type == R_IHCONST)
n.r_symndx = q->addend;
else
#endif
- if (q->sym_ptr_ptr)
- {
- if (q->sym_ptr_ptr == bfd_abs_section_ptr->symbol_ptr_ptr)
- /* This is a relocation relative to the absolute symbol. */
- n.r_symndx = -1;
- else
- {
- n.r_symndx = get_index ((*(q->sym_ptr_ptr)));
- /* Take notice if the symbol reloc points to a symbol
- we don't have in our symbol table. What should we
- do for this?? */
- if (n.r_symndx > obj_conv_table_size (abfd))
- abort ();
- }
- }
+ if (q->sym_ptr_ptr)
+ {
+ if (q->sym_ptr_ptr == bfd_abs_section_ptr->symbol_ptr_ptr)
+ /* This is a relocation relative to the absolute symbol. */
+ n.r_symndx = -1;
+ else
+ {
+ n.r_symndx = get_index ((*(q->sym_ptr_ptr)));
+ /* Take notice if the symbol reloc points to a symbol
+ we don't have in our symbol table. What should we
+ do for this?? */
+ if (n.r_symndx > obj_conv_table_size (abfd))
+ abort ();
+ }
+ }
#ifdef SWAP_OUT_RELOC_OFFSET
n.r_offset = q->addend;
}
break;
#endif
+#ifdef ARMMAGIC
+ case bfd_arch_arm:
+ *magicp = ARMMAGIC;
+ return true;
+#endif
#ifdef I386MAGIC
case bfd_arch_i386:
*magicp = I386MAGIC;
if (!(current->flags & SEC_HAS_CONTENTS))
continue;
+#ifdef COFF_WITH_PE
+ /* Do not include the .junk section. This is where we collect section
+ data which we don't need. This is mainly the MS .debug$ data which
+ stores codeview debug data. */
+ if (strcmp (current->name, ".junk") == 0)
+ {
+ continue;
+ }
+#endif
+
/* Align the sections in the file to the same boundary on
which they are aligned in virtual memory. I960 doesn't
do this (FIXME) so we can stay in sync with Intel. 960
previous = current;
}
+#ifdef COFF_WITH_PE
+ /* Normally, the starting location for the symbol table will be at the end
+ of the last section. However, when dealing with NT, the last section
+ must be as long as its size rounded up to the next page (0x1000). */
+ sofar = ((sofar + NT_FILE_ALIGNMENT - 1) /
+ NT_FILE_ALIGNMENT) * NT_FILE_ALIGNMENT;
+#endif
+
obj_relocbase (abfd) = sofar;
abfd->output_has_begun = true;
+
}
#ifndef RS6000COFF_C
#endif /* ! defined (RS6000COFF_C) */
+#ifdef COFF_WITH_PE
+static void add_data_entry (abfd, aout, idx, name)
+ bfd *abfd;
+ struct internal_aouthdr *aout;
+ int idx;
+ char *name;
+{
+ 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;
+ }
+}
+#endif
+
/* SUPPRESS 558 */
/* SUPPRESS 529 */
static boolean
asection *text_sec = NULL;
asection *data_sec = NULL;
asection *bss_sec = NULL;
+ bfd_vma end_of_image = 0;
struct internal_filehdr internal_f;
struct internal_aouthdr internal_a;
-
bfd_set_error (bfd_error_system_call);
if (abfd->output_has_begun == false)
/* Write section headers to the file. */
internal_f.f_nscns = 0;
+
+#if 0
if (bfd_seek (abfd,
(file_ptr) ((abfd->flags & EXEC_P) ?
- (FILHSZ + AOUTSZ) : FILHSZ),
+ (EXTRA_NT_HDRSZ + FILHSZ + AOUTSZ) :
+ (EXTRA_NT_HDRSZ + FILHSZ)),
SEEK_SET)
!= 0)
- return false;
+#else
+ if (bfd_seek (abfd,
+ (file_ptr) ((abfd->flags & EXEC_P) ?
+ (FILHSZ + AOUTSZ) : FILHSZ),
+ SEEK_SET)
+ != 0)
+#endif
+ return false;
{
for (current = abfd->sections;
{
struct internal_scnhdr section;
+#ifdef COFF_WITH_PE
+ /* Do not include the .junk section. This is where we collect section
+ data which we don't need. This is mainly the MS .debug$ data which
+ stores codeview debug data. */
+ if (strcmp (current->name, ".junk") == 0)
+ {
+ continue;
+ }
+#endif
internal_f.f_nscns++;
strncpy (&(section.s_name[0]), current->name, 8);
#ifdef _LIB
section.s_vaddr = current->lma;
section.s_paddr = current->lma;
section.s_size = current->_raw_size;
+
+ /* Remember the address of the end of the last section */
+
+ if (current->lma + current->_raw_size > end_of_image)
+ end_of_image = current->lma + current->_raw_size ;
+
/*
If this section has no size or is unloadable then the scnptr
will be 0 too
{
SCNHDR buff;
- coff_swap_scnhdr_out (abfd, §ion, &buff);
- if (bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ)
+#ifdef WINDOWS_NT
+ /* suppress output of the sections if they are null. ld includes
+ the bss and data sections even if there is no size assigned
+ to them. NT loader doesn't like it if these section headers are
+ included if the sections themselves are not needed */
+ if (section.s_size == 0)
+ internal_f.f_nscns--;
+ else
+ {
+ coff_swap_scnhdr_out (abfd, §ion, &buff);
+ if (bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ)
+ return false;
+ }
+#else
+ if (coff_swap_scnhdr_out (abfd, §ion, &buff) == 0
+ || bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ)
return false;
+#endif
}
}
/* Don't include the internal abs section in the section count */
/*
- We will NOT put a fucking timestamp in the header here. Every time you
- put it back, I will come in and take it out again. I'm sorry. This
- 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
- */
+ We will NOT put a fucking timestamp in the header here. Every time you
+ put it back, I will come in and take it out again. I'm sorry. This
+ 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;
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.
- */
+ FIXME, should do something about the other byte orders and
+ architectures.
+ */
memset (&internal_a, 0, sizeof internal_a);
#ifdef A29K
#ifdef ULTRA3 /* NYU's machine */
/* FIXME: This is a bogus check. I really want to see if there
- * is a .shbss or a .shdata section, if so then set the magic
- * number to indicate a shared data executable.
- */
+ * is a .shbss or a .shdata section, if so then set the magic
+ * number to indicate a shared data executable.
+ */
if (internal_f.f_nscns >= 7)
- internal_a.magic = SHMAGIC; /* Shared magic */
+ internal_a.magic = SHMAGIC; /* Shared magic */
else
#endif /* ULTRA3 */
- internal_a.magic = NMAGIC;/* Assume separate i/d */
+ internal_a.magic = NMAGIC; /* Assume separate i/d */
#define __A_MAGIC_SET__
#endif /* A29K */
#ifdef I960
#define __A_MAGIC_SET__
#if defined(LYNXOS)
internal_a.magic = LYNXCOFFMAGIC;
-#endif /* LYNXOS */
-#endif /* M68 || WE32K || M68K */
+#endif /* LYNXOS */
+#endif /* M68 || WE32K || M68K */
+#if defined(ARM)
+#define __A_MAGIC_SET__
+ internal_a.magic = ZMAGIC;
+#endif
#if defined(I386)
#define __A_MAGIC_SET__
#if defined(LYNXOS)
internal_a.magic = LYNXCOFFMAGIC;
-#else /* LYNXOS */
+#else /* LYNXOS */
internal_a.magic = ZMAGIC;
#endif /* LYNXOS */
#endif /* I386 */
#if defined(SPARC)
#define __A_MAGIC_SET__
#if defined(LYNXOS)
- internal_a.magic = LYNXCOFFMAGIC;
-#endif /* LYNXOS */
-#endif /* SPARC */
+ internal_a.magic = LYNXCOFFMAGIC;
+#endif /* LYNXOS */
+#endif /* SPARC */
#if RS6000COFF_C
#define __A_MAGIC_SET__
internal_a.magic = (abfd->flags & D_PAGED) ? RS6K_AOUTHDR_ZMAGIC :
- (abfd->flags & WP_TEXT) ? RS6K_AOUTHDR_NMAGIC :
- RS6K_AOUTHDR_OMAGIC;
+ (abfd->flags & WP_TEXT) ? RS6K_AOUTHDR_NMAGIC :
+ RS6K_AOUTHDR_OMAGIC;
#endif
#ifndef __A_MAGIC_SET__
if (bfd_get_symcount (abfd) != 0)
{
+ int firstundef;
#ifndef RS6000COFF_C
if (!coff_add_missing_symbols (abfd))
return false;
#endif
- if (!coff_renumber_symbols (abfd))
+ if (!coff_renumber_symbols (abfd, &firstundef))
return false;
coff_mangle_symbols (abfd);
if (! coff_write_symbols (abfd))
return false;
if (! coff_write_linenumbers (abfd))
return false;
- if (! coff_write_relocs (abfd))
+ if (! coff_write_relocs (abfd, firstundef))
return false;
}
if (text_sec)
{
internal_a.tsize = bfd_get_section_size_before_reloc (text_sec);
- internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
+ internal_a.text_start = internal_a.tsize ?
+ (text_sec->vma - IMAGE_BASE) : 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 : 0;
+ internal_a.data_start = internal_a.dsize ?
+ (data_sec->vma - IMAGE_BASE) : 0;
}
if (bss_sec)
{
internal_a.bsize = bfd_get_section_size_before_reloc (bss_sec);
}
- internal_a.entry = bfd_get_start_address (abfd);
+ internal_a.entry = bfd_get_start_address (abfd) - IMAGE_BASE;
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");
+
+
+
+#endif
+
/* now write them */
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
return false;
if (bfd_write ((PTR) & buff, 1, AOUTSZ, abfd) != AOUTSZ)
return false;
}
+
return true;
}
unsigned int *table_ptr;
unsigned int number_of_symbols = 0;
+
if (obj_symbols (abfd))
return true;
if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
case C_EXT:
#ifdef RS6000COFF_C
case C_HIDEXT:
+#endif
+#ifdef COFF_WITH_PE
+ /* PE uses storage class 0x68 to denote a section symbol */
+ case C_SECTION:
#endif
if ((src->u.syment.n_scnum) == 0)
{
case C_EXTDEF: /* external definition */
case C_ULABEL: /* undefined label */
case C_USTATIC: /* undefined static */
+#ifndef COFF_WITH_PE
+ /* C_LINE in regular coff is 0x68. NT has taken over this storage
+ class to represent a section symbol */
case C_LINE: /* line # reformatted as symbol table entry */
+#endif
case C_ALIAS: /* duplicate tag */
case C_HIDDEN: /* ext symbol in dmert public lib */
default:
#define OTHER_GLOBAL_CLASS C_HIDEXT
#endif
+#ifdef COFF_WITH_PE
+#define OTHER_GLOBAL_CLASS C_SECTION
+#endif
+
#ifdef OTHER_GLOBAL_CLASS
static boolean
#define coff_bfd_link_add_symbols _bfd_generic_link_add_symbols
#define coff_bfd_final_link _bfd_generic_final_link
#endif /* ! defined (coff_relocate_section) */
+#define coff_bfd_link_split_section _bfd_generic_link_split_section
#ifndef coff_adjust_symndx
#define coff_adjust_symndx NULL
#define coff_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
#define coff_get_section_contents _bfd_generic_get_section_contents
+#define coff_bfd_copy_private_symbol_data \
+ _bfd_generic_bfd_copy_private_symbol_data
#define coff_bfd_copy_private_section_data \
_bfd_generic_bfd_copy_private_section_data
#define coff_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
+#define coff_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
+#define coff_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
#ifndef coff_bfd_is_local_label
#define coff_bfd_is_local_label bfd_generic_is_local_label
char *s;
char *e;
char *copy;
- if (!s)
+ if (!sec)
return 1;
-
+
copy = malloc (sec->_raw_size);
if (!copy)
{
{
if (strncmp (sec->name, ".idata$", 7) == 0)
val -= NT_IMAGE_BASE;
+ if (strncmp (sec->name, ".reloc", 6) == 0)
+ val -= NT_IMAGE_BASE;
+ else if (strncmp (sec->name, ".edata", 5) == 0)
+ val -= NT_IMAGE_BASE;
else if (strncmp (sec->name, ".rsrc$", 6) == 0)
{
val -= NT_IMAGE_BASE;
{
if (strncmp (sec->name, ".idata$", 7) == 0)
val -= NT_IMAGE_BASE;
+ else if (strncmp (sec->name, ".reloc", 5) == 0)
+ val -= NT_IMAGE_BASE;
+ else if (strncmp (sec->name, ".edata", 5) == 0)
+ val -= NT_IMAGE_BASE;
else if (strncmp (sec->name, ".rsrc$", 6) == 0)
{
val -= NT_IMAGE_BASE;
val = val + add_to_val;
}
+
+ if (info->base_file)
+ {
+ /* So if this is non pcrelative, and is referenced
+ to a section or a common symbol, then it needs a reloc */
+ if (!howto->pc_relative
+ && (sym->n_scnum
+ || sym->n_value))
+ {
+ /* relocation to a symbol in a section which
+ isn't absolute - we output the address here
+ to a file */
+ bfd_vma addr = rel->r_vaddr +
+ + input_section->output_offset
+ + input_section->output_section->vma;
+ fwrite (&addr, 1,4, info->base_file);
+ }
+ }
rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
contents,
i[345]86-sequent-sysv4*) my_host=sysv4 ;;
i[345]86-sequent-sysv*) my_host=symmetry ;;
i[345]86-*-bsd*) my_host=i386bsd ;;
+i[345]86-*-freebsd*) my_host=i386bsd ;;
i[345]86-*-netbsd*) my_host=i386bsd ;;
i[345]86-ncr*-sysv4*) my_host=ncr3000 ;;
i[345]86-*-go32*) my_host=go32 ;;
+i[345]86-*-pe*) my_host=i386pe ;;
i[345]86-esix-sysv3*) my_host=esix ;;
i[345]86-*-sysv4*) my_host=i386v4 ;;
i[345]86-*-sysv*) my_host=i386v ;;
rs6000-*-lynx*) my_host=rs6000lynx ;;
rs6000-*-*) my_host=rs6000 ;;
+powerpc-*-aix*) my_host=rs6000 ;;
sparc-*-lynxos*) my_host=sparclynx ;;
sparc-*-netbsd*) my_host=sparcnbsd;;
i386mach3.h
i386nbsd.h
i386osf1mk.h
+i386pe.h
i386sco.h
i386v.h
i386v4.h
--- /dev/null
+#include <stddef.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#define FPRINTF_ALREADY_DECLARED
+
+#ifndef O_ACCMODE
+#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
+#endif
+#define SEEK_SET 0
+#define SEEK_CUR 1
+
+#define NO_FCNTL
+
+#include "fopen-bin.h"
+
.
. {* A pointer to the section to which this symbol is
. relative. This will always be non NULL, there are special
-. sections for undefined and absolute symbols *}
+. sections for undefined and absolute symbols. *}
. struct sec *section;
.
-. {* Back end special data. This is being phased out in favour
-. of making this a union. *}
-. PTR udata;
+. {* Back end special data. *}
+. union
+. {
+. PTR p;
+. bfd_vma i;
+. } udata;
.
.} asymbol;
*/
}
/* This presumes that a symbol can not be both BSF_DEBUGGING and
- BSF_DYNAMIC. */
+ BSF_DYNAMIC, nor both BSF_FUNCTION and BSF_FILE. */
fprintf (file, " %c%c%c%c%c%c%c",
- (type & BSF_LOCAL) ? 'l' : ' ',
- (type & BSF_GLOBAL) ? 'g' : ' ',
+ ((type & BSF_LOCAL)
+ ? (type & BSF_GLOBAL) ? '!' : 'l'
+ : (type & BSF_GLOBAL) ? 'g' : ' '),
(type & BSF_WEAK) ? 'w' : ' ',
(type & BSF_CONSTRUCTOR) ? 'C' : ' ',
(type & BSF_WARNING) ? 'W' : ' ',
(type & BSF_INDIRECT) ? 'I' : ' ',
- (type & BSF_DEBUGGING) ? 'd'
- : (type & BSF_DYNAMIC) ? 'D' : ' ');
+ (type & BSF_DEBUGGING) ? 'd' : (type & BSF_DYNAMIC) ? 'D' : ' ',
+ (type & BSF_FUNCTION) ? 'F' : (type & BSF_FILE) ? 'f' : ' ');
}
};
/* Return the single-character symbol type corresponding to
- section S, or '?' for an unknown COFF section. */
+ section S, or '?' for an unknown COFF section.
+
+ Check for any leading string which matches, so .text5 returns
+ 't' as well as .text */
static char
coff_section_type (s)
{
CONST struct section_to_type *t;
- for (t = &stt[0]; t->section; t++)
- if (!strcmp (s, t->section))
+ for (t = &stt[0]; t->section; t++)
+ if (!strncmp (s, t->section, strlen (t->section)))
return t->type;
+
return '?';
}
return 'U';
if (bfd_is_ind_section (symbol->section))
return 'I';
+ if (symbol->flags & BSF_WEAK)
+ return 'W';
if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL)))
return '?';
{
abort ();
}
+
+/*
+FUNCTION
+ bfd_copy_private_symbol_data
+
+SYNOPSIS
+ boolean bfd_copy_private_symbol_data(bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym);
+
+DESCRIPTION
+ Copy private symbol information from @var{isym} in the BFD
+ @var{ibfd} to the symbol @var{osym} in the BFD @var{obfd}.
+ Return <<true>> on success, <<false>> on error. Possible error
+ returns are:
+
+ o <<bfd_error_no_memory>> -
+ Not enough memory exists to create private data for @var{osec}.
+
+.#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \
+. BFD_SEND (ibfd, _bfd_copy_private_symbol_data, \
+. (ibfd, isymbol, obfd, osymbol))
+
+*/
. bfd_target_srec_flavour,
. bfd_target_som_flavour,
. bfd_target_os9k_flavour,
-. bfd_target_msdos_flavour
+. bfd_target_versados_flavour
.};
.
.{* Forward declaration. *}
.CAT(NAME,_bfd_copy_private_bfd_data),\
.CAT(NAME,_bfd_merge_private_bfd_data),\
.CAT(NAME,_bfd_copy_private_section_data),\
+.CAT(NAME,_bfd_copy_private_symbol_data),\
.CAT(NAME,_bfd_set_private_flags)
. {* Called to copy BFD general private data from one object file
. to another. *}
. to another. *}
. boolean (*_bfd_copy_private_section_data) PARAMS ((bfd *, sec_ptr,
. bfd *, sec_ptr));
+. {* Called to copy BFD private symbol data from one symbol
+. to another. *}
+. boolean (*_bfd_copy_private_symbol_data) PARAMS ((bfd *, asymbol *,
+. bfd *, asymbol *));
. {* Called to set private backend flags *}
. boolean (*_bfd_set_private_flags) PARAMS ((bfd *, flagword));
.
.CAT(NAME,_bfd_relax_section),\
.CAT(NAME,_bfd_link_hash_table_create),\
.CAT(NAME,_bfd_link_add_symbols),\
-.CAT(NAME,_bfd_final_link)
+.CAT(NAME,_bfd_final_link),\
+.CAT(NAME,_bfd_link_split_section)
. int (*_bfd_sizeof_headers) PARAMS ((bfd *, boolean));
. bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *,
. struct bfd_link_info *, struct bfd_link_order *,
. section of the BFD. *}
. boolean (*_bfd_final_link) PARAMS ((bfd *, struct bfd_link_info *));
.
+. {* Should this section be split up into smaller pieces during linking. *}
+. boolean (*_bfd_link_split_section) PARAMS ((bfd *, struct sec *));
+.
. {* Routines to handle dynamic symbols and relocs. *}
.#define BFD_JUMP_TABLE_DYNAMIC(NAME)\
.CAT(NAME,_get_dynamic_symtab_upper_bound),\
we can't intermix extern's and initializers. */
extern const bfd_target a29kcoff_big_vec;
extern const bfd_target a_out_adobe_vec;
+extern const bfd_target aout_arm_big_vec;
+extern const bfd_target aout_arm_little_vec;
extern const bfd_target aout_mips_big_vec;
extern const bfd_target aout_mips_little_vec;
extern const bfd_target aout0_big_vec;
extern const bfd_target apollocoff_vec;
+extern const bfd_target armpe_vec;
+extern const bfd_target armpei_vec;
extern const bfd_target b_out_vec_big_host;
extern const bfd_target b_out_vec_little_host;
/* start-sanitize-arc */
extern const bfd_target i386dynix_vec;
extern const bfd_target i386os9k_vec;
extern const bfd_target i386coff_vec;
+extern const bfd_target i386pe_vec;
+extern const bfd_target i386pei_vec;
extern const bfd_target go32coff_vec;
extern const bfd_target i386linux_vec;
extern const bfd_target i386lynx_aout_vec;
extern const bfd_target sparccoff_vec;
extern const bfd_target sunos_big_vec;
extern const bfd_target tekhex_vec;
+extern const bfd_target versados_vec;
extern const bfd_target we32kcoff_vec;
extern const bfd_target w65_vec;
extern const bfd_target z8kcoff_vec;
&i386msdos_vec,
&i386netbsd_vec,
&i386os9k_vec,
+ &i386pe_vec,
+ &i386pei_vec,
+ &armpe_vec,
+ &armpei_vec,
&icoff_big_vec,
&icoff_little_vec,
&ieee_vec,
#endif
&pc532machaout_vec,
#if 0
- /* We have no way of distinguishing this from other a.out variants */
+ /* We have no way of distinguishing these from other a.out variants */
+ &aout_arm_big_vec,
+ &aout_arm_little_vec,
&riscix_vec,
#endif
&rs6000coff_vec,
&aout0_big_vec,
&tekhex_vec,
&we32kcoff_vec,
+ &versados_vec,
&z8kcoff_vec,
#endif /* not SELECT_VECS */
/* Always support S-records, for convenience. */
&srec_vec,
&symbolsrec_vec,
-
+/* And tekhex */
+ &tekhex_vec,
/* Likewise for binary output. */
&binary_vec,