static bfd_vma
-pe_value(bfd_link_pe_info_dval *ptr, bfd_vma def)
+pe_value(ptr, def)
+ bfd_link_pe_info_dval *ptr;
+ bfd_vma def;
{
if (ptr && ptr->defined)
return ptr->value;
{
styp_flags = STYP_INFO;
}
+#ifdef COFF_WITH_PE
+ else if (!strcmp (sec_name, ".edata"))
+ {
+ styp_flags = STYP_DATA;
+ }
+#endif
/* Try and figure out what it should be */
else if (sec_flags & SEC_CODE)
{
asection *current;
asection *previous = (asection *) NULL;
file_ptr sofar = FILHSZ;
+ int page_size;
#ifndef I960
file_ptr old_sofar;
#endif
unsigned int count;
+#ifdef COFF_IMAGE_WITH_PE
+ page_size = pe_value (&(coff_data (abfd)->link_info->pe_info->file_alignment),
+ PE_DEF_FILE_ALIGNMENT);
+#else
+ page_size = COFF_PAGE_SIZE;
+#endif
+
if (bfd_get_start_address (abfd))
{
/* A start address may have been added to the original file. In this
#endif
-#ifdef COFF_PAGE_SIZE
/* In demand paged files the low order bits of the file offset
must match the low order bits of the virtual address. */
if ((abfd->flags & D_PAGED) != 0
&& (current->flags & SEC_ALLOC) != 0)
- sofar += (current->vma - sofar) % COFF_PAGE_SIZE;
-#endif
+ sofar += (current->vma - sofar) % page_size;
current->filepos = sofar;
previous = current;
}
-#ifdef COFF_WITH_PE
+#ifdef COFF_IMAGE_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;
+ sofar = (sofar + page_size - 1) & -page_size;
+
+ if (previous)
+ previous->_raw_size = (previous->_raw_size + page_size -1) & -page_size;
#endif
obj_relocbase (abfd) = sofar;
{
aout->pe->DataDirectory[idx].VirtualAddress = sec->lma - base;
aout->pe->DataDirectory[idx].Size = sec->_raw_size;
+ sec->flags |= SEC_DATA;
}
}
static void
-fill_pe_header_info (abfd, internal_f, internal_a, end_of_image)
+fill_pe_header_info (abfd, internal_f, internal_a)
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 */
+ int sa;
+ int fa;
+ bfd_vma ib;
bfd_link_pe_info *pe_info = coff_data (abfd)->link_info->pe_info;
internal_f->f_timdat = time (0);
memset (internal_a->pe, 0, sizeof (struct internal_extra_pe_aouthdr));
- internal_a->pe->ImageBase = pe_value (&pe_info->image_base, IMAGE_BASE);
+ ib = internal_a->pe->ImageBase = pe_value (&pe_info->image_base, NT_EXE_IMAGE_BASE);
if (internal_a->tsize)
- internal_a->text_start -= internal_a->pe->ImageBase;
+ internal_a->text_start -= ib;
if (internal_a->dsize)
- internal_a->data_start -= internal_a->pe->ImageBase;
+ internal_a->data_start -= ib;
if (internal_a->entry)
- internal_a->entry -= internal_a->pe->ImageBase;
+ internal_a->entry -= ib;
+
+
+ sa = internal_a->pe->SectionAlignment = pe_value (&pe_info->section_alignment,
+ NT_SECTION_ALIGNMENT);
+
+ fa = internal_a->pe->FileAlignment = pe_value (&pe_info->file_alignment,
+ NT_FILE_ALIGNMENT);
+
+#define FA(x) (((x) + fa -1 ) & (- fa))
+#define SA(x) (((x) + sa -1 ) & (- sa))
+ /* We like to have the sizes aligned */
+
+ internal_a->bsize = FA (internal_a->bsize);
internal_f->pe->e_magic = DOSMAGIC;
internal_f->pe->e_cblp = 0x90;
/* 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->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;
+
+ /* The headers go up to where the first section starts. */
+
+ internal_a->pe->SizeOfHeaders = abfd->sections->filepos;
internal_a->pe->CheckSum = 0;
internal_a->pe->DllCharacteristics = 0;
/* 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);
-
+ add_data_entry (abfd, internal_a, 0, ".edata", ib);
+ add_data_entry (abfd, internal_a, 1, ".idata", ib);
+ add_data_entry (abfd, internal_a, 2, ".rsrc" ,ib);
+ add_data_entry (abfd, internal_a, 5, ".reloc", ib);
+ {
+ asection *sec;
+ bfd_vma dsize= 0;
+ bfd_vma isize = SA(abfd->sections->filepos);
+ bfd_vma tsize= 0;
+ bfd_vma dstart = 0;
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ int rounded = FA(sec->_raw_size);
+ if (sec->flags & SEC_DATA)
+ dsize += rounded;
+ if (sec->flags & SEC_CODE)
+ tsize += rounded;
+ isize += SA(rounded);
+ }
+ internal_a->dsize = dsize;
+ internal_a->tsize = tsize;
+ internal_a->pe->SizeOfImage = isize;
+ }
}
#endif
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;
coff_data (abfd)->link_info = info = &dummy_info;
info->pe_info = 0;
}
- pe_info = info->pe_info;
+ pe_info = (struct bfd_link_pe_info *)(info->pe_info);
if (!pe_info)
{
section.s_vaddr = 0;
else
#endif
- section.s_vaddr = current->lma;
+ 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;
-#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
+ if (obj_pe (abfd))
+ {
+ /* 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;
+ }
}
}
internal_f.pe = & extra_f;
internal_a.pe = & extra_a;
- fill_pe_header_info (abfd, &internal_f, &internal_a, end_of_image);
+ fill_pe_header_info (abfd, &internal_f, &internal_a);
#endif
/* now write them */
/* Generic COFF swapping routines, for BFD.
- Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+ Copyright 1990, 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
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. */
/* This file contains routines used to swap COFF data. It is a header
file because the details of swapping depend on the details of the
Any file which uses this must first include "coff/internal.h" and
"coff/CPU.h". The functions will then be correct for that CPU. */
+#ifndef IMAGE_BASE
+#define IMAGE_BASE 0
+#endif
+
#define PUTWORD bfd_h_put_32
#define PUTHALF bfd_h_put_16
#define PUTBYTE bfd_h_put_8
#ifndef NO_COFF_RELOCS
static void
-DEFUN(bfd_swap_reloc_in,(abfd, reloc_src, reloc_dst),
- bfd *abfd AND
- RELOC *reloc_src AND
- struct internal_reloc *reloc_dst)
+coff_swap_reloc_in (abfd, src, dst)
+ bfd *abfd;
+ PTR src;
+ PTR dst;
{
+ RELOC *reloc_src = (RELOC *) src;
+ struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
+
reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr);
reloc_dst->r_symndx = bfd_h_get_signed_32(abfd, (bfd_byte *) reloc_src->r_symndx);
static unsigned int
-DEFUN(coff_swap_reloc_out,(abfd, src, dst),
- bfd *abfd AND
- PTR src AND
- PTR dst)
+coff_swap_reloc_out (abfd, src, dst)
+ bfd *abfd;
+ PTR src;
+ PTR dst;
{
struct internal_reloc *reloc_src = (struct internal_reloc *)src;
struct external_reloc *reloc_dst = (struct external_reloc *)dst;
bfd_h_put_32(abfd, reloc_src->r_vaddr, (bfd_byte *) reloc_dst->r_vaddr);
bfd_h_put_32(abfd, reloc_src->r_symndx, (bfd_byte *) reloc_dst->r_symndx);
+
+#ifdef RS6000COFF_C
+ bfd_h_put_8 (abfd, reloc_src->r_type, (bfd_byte *) reloc_dst->r_type);
+ bfd_h_put_8 (abfd, reloc_src->r_size, (bfd_byte *) reloc_dst->r_size);
+#else
bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *)
reloc_dst->r_type);
+#endif
#ifdef SWAP_OUT_RELOC_OFFSET
SWAP_OUT_RELOC_OFFSET(abfd,
#endif /* NO_COFF_RELOCS */
static void
-DEFUN(coff_swap_filehdr_in,(abfd, src, dst),
- bfd *abfd AND
- PTR src AND
- PTR dst)
+coff_swap_filehdr_in (abfd, src, dst)
+ bfd *abfd;
+ PTR src;
+ PTR dst;
{
FILHDR *filehdr_src = (FILHDR *) src;
struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
}
static unsigned int
-DEFUN(coff_swap_filehdr_out,(abfd, in, out),
- bfd *abfd AND
- PTR in AND
- PTR out)
+coff_swap_filehdr_out (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
{
struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
FILHDR *filehdr_out = (FILHDR *)out;
+
bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat);
bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
+
+#ifdef COFF_IMAGE_WITH_PE
+ /* put in extra dos header stuff. This data remains essentially
+ constant, it just has to be tacked on to the beginning of all exes
+ for NT */
+ bfd_h_put_16(abfd, filehdr_in->pe->e_magic, (bfd_byte *) filehdr_out->e_magic);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_cblp, (bfd_byte *) filehdr_out->e_cblp);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_cp, (bfd_byte *) filehdr_out->e_cp);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_crlc, (bfd_byte *) filehdr_out->e_crlc);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_cparhdr,
+ (bfd_byte *) filehdr_out->e_cparhdr);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_minalloc,
+ (bfd_byte *) filehdr_out->e_minalloc);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_maxalloc,
+ (bfd_byte *) filehdr_out->e_maxalloc);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_ss, (bfd_byte *) filehdr_out->e_ss);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_sp, (bfd_byte *) filehdr_out->e_sp);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_csum, (bfd_byte *) filehdr_out->e_csum);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_ip, (bfd_byte *) filehdr_out->e_ip);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_cs, (bfd_byte *) filehdr_out->e_cs);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_lfarlc, (bfd_byte *) filehdr_out->e_lfarlc);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_ovno, (bfd_byte *) filehdr_out->e_ovno);
+ {
+ int idx;
+ for (idx=0; idx < 4; idx++)
+ bfd_h_put_16(abfd, filehdr_in->pe->e_res[idx],
+ (bfd_byte *) filehdr_out->e_res[idx]);
+ }
+ bfd_h_put_16(abfd, filehdr_in->pe->e_oemid, (bfd_byte *) filehdr_out->e_oemid);
+ bfd_h_put_16(abfd, filehdr_in->pe->e_oeminfo,
+ (bfd_byte *) filehdr_out->e_oeminfo);
+ {
+ int idx;
+ for (idx=0; idx < 10; idx++)
+ bfd_h_put_16(abfd, filehdr_in->pe->e_res2[idx],
+ (bfd_byte *) filehdr_out->e_res2[idx]);
+ }
+ bfd_h_put_32(abfd, filehdr_in->pe->e_lfanew, (bfd_byte *) filehdr_out->e_lfanew);
+
+ {
+ int idx;
+ for (idx=0; idx < 16; idx++)
+ bfd_h_put_32(abfd, filehdr_in->pe->dos_message[idx],
+ (bfd_byte *) filehdr_out->dos_message[idx]);
+ }
+
+ /* also put in the NT signature */
+ bfd_h_put_32(abfd, filehdr_in->pe->nt_signature,
+ (bfd_byte *) filehdr_out->nt_signature);
+
+
+#endif
+
+
+
return sizeof(FILHDR);
}
#ifndef NO_COFF_SYMBOLS
static void
-DEFUN(coff_swap_sym_in,(abfd, ext1, in1),
- bfd *abfd AND
- PTR ext1 AND
- PTR in1)
+coff_swap_sym_in (abfd, ext1, in1)
+ bfd *abfd;
+ PTR ext1;
+ PTR in1;
{
SYMENT *ext = (SYMENT *)ext1;
struct internal_syment *in = (struct internal_syment *)in1;
memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
#endif
}
- in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value);
+ in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value);
in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum);
if (sizeof(ext->e_type) == 2){
in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type);
}
in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
+
+#ifdef COFF_WITH_PE
+ /* The section symbols for the .idata$ sections have class 68, which MS
+ documentation indicates is a section symbol. The problem is that the
+ value field in the symbol is simply a copy of the .idata section's flags
+ rather than something useful. When these symbols are encountered, change
+ the value to 0 and the section number to 1 so that they will be handled
+ somewhat correctly in the bfd code. */
+ if (in->n_sclass == 0x68) {
+ in->n_value = 0x0;
+ in->n_scnum = 1;
+ /* I have tried setting the class to 3 and using the following to set
+ the section number. This will put the address of the pointer to the
+ string kernel32.dll at addresses 0 and 0x10 off start of idata section
+ which is not correct */
+/* if (strcmp (in->_n._n_name, ".idata$4") == 0) */
+/* in->n_scnum = 3; */
+/* else */
+/* in->n_scnum = 2; */
+ }
+#endif
}
static unsigned int
-DEFUN(coff_swap_sym_out,(abfd, inp, extp),
- bfd *abfd AND
- PTR inp AND
- PTR extp)
+coff_swap_sym_out (abfd, inp, extp)
+ bfd *abfd;
+ PTR inp;
+ PTR extp;
{
struct internal_syment *in = (struct internal_syment *)inp;
SYMENT *ext =(SYMENT *)extp;
}
static void
-DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, indx, numaux, in1),
- bfd *abfd AND
- PTR ext1 AND
- int type AND
- int class AND
- int indx AND
- int numaux AND
- PTR in1)
+coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
+ bfd *abfd;
+ PTR ext1;
+ int type;
+ int class;
+ int indx;
+ int numaux;
+ PTR in1;
{
AUXENT *ext = (AUXENT *)ext1;
union internal_auxent *in = (union internal_auxent *)in1;
case C_HIDEXT:
if (indx + 1 == numaux)
{
- in->x_csect.x_scnlen = bfd_h_get_32 (abfd, ext->x_csect.x_scnlen);
+ in->x_csect.x_scnlen.l = bfd_h_get_32 (abfd, ext->x_csect.x_scnlen);
in->x_csect.x_parmhash = bfd_h_get_32 (abfd,
ext->x_csect.x_parmhash);
in->x_csect.x_snhash = bfd_h_get_16 (abfd, ext->x_csect.x_snhash);
in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
#endif
- if (ISARY(type)) {
+ if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
+ {
+ in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
+ in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
+ }
+ else
+ {
#if DIMNUM != E_DIMNUM
- -> Error, we need to cope with truncating or extending DIMNUM!;
-#else
- in->x_sym.x_fcnary.x_ary.x_dimen[0] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
- in->x_sym.x_fcnary.x_ary.x_dimen[1] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
- in->x_sym.x_fcnary.x_ary.x_dimen[2] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
- in->x_sym.x_fcnary.x_ary.x_dimen[3] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
-#endif
- }
- if (class == C_BLOCK || ISFCN(type) || ISTAG(class)) {
- in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR(abfd, ext);
- in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX(abfd, ext);
- }
+ #error we need to cope with truncating or extending DIMNUM
+#endif
+ in->x_sym.x_fcnary.x_ary.x_dimen[0] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[1] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[2] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[3] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+ }
if (ISFCN(type)) {
in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
}
static unsigned int
-DEFUN(coff_swap_aux_out,(abfd, inp, type, class, indx, numaux, extp),
- bfd *abfd AND
- PTR inp AND
- int type AND
- int class AND
- int indx AND
- int numaux AND
- PTR extp)
+coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
+ bfd *abfd;
+ PTR inp;
+ int type;
+ int class;
+ int indx;
+ int numaux;
+ PTR extp;
{
union internal_auxent *in = (union internal_auxent *)inp;
AUXENT *ext = (AUXENT *)extp;
case C_HIDEXT:
if (indx + 1 == numaux)
{
- PUTWORD (abfd, in->x_csect.x_scnlen, ext->x_csect.x_scnlen);
+ PUTWORD (abfd, in->x_csect.x_scnlen.l, ext->x_csect.x_scnlen);
PUTWORD (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
PUTHALF (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
/* We don't have to hack bitfields in x_smtyp because it's
bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
#endif
- if (class == C_BLOCK || ISFCN(type) || ISTAG(class)) {
- PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
- PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
- }
-
- if (ISFCN(type)) {
- PUTWORD(abfd, in->x_sym.x_misc.x_fsize, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
- }
- else {
- if (ISARY(type)) {
+ if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
+ {
+ PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
+ PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
+ }
+ else
+ {
#if DIMNUM != E_DIMNUM
- -> Error, we need to cope with truncating or extending DIMNUM!;
-#else
- bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
- bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
- bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
- bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
-#endif
+ #error we need to cope with truncating or extending DIMNUM
+#endif
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
}
- PUT_LNSZ_LNNO(abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
- PUT_LNSZ_SIZE(abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
- }
+
+ if (ISFCN (type))
+ PUTWORD (abfd, in->x_sym.x_misc.x_fsize,
+ (bfd_byte *) ext->x_sym.x_misc.x_fsize);
+ else
+ {
+ PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
+ PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
+ }
+
return sizeof(AUXENT);
}
#ifndef NO_COFF_LINENOS
static void
-DEFUN(coff_swap_lineno_in,(abfd, ext1, in1),
- bfd *abfd AND
- PTR ext1 AND
- PTR in1)
+coff_swap_lineno_in (abfd, ext1, in1)
+ bfd *abfd;
+ PTR ext1;
+ PTR in1;
{
LINENO *ext = (LINENO *)ext1;
struct internal_lineno *in = (struct internal_lineno *)in1;
}
static unsigned int
-DEFUN(coff_swap_lineno_out,(abfd, inp, outp),
- bfd *abfd AND
- PTR inp AND
- PTR outp)
+coff_swap_lineno_out (abfd, inp, outp)
+ bfd *abfd;
+ PTR inp;
+ PTR outp;
{
struct internal_lineno *in = (struct internal_lineno *)inp;
struct external_lineno *ext = (struct external_lineno *)outp;
static void
-DEFUN(coff_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1),
- bfd *abfd AND
- PTR aouthdr_ext1 AND
- PTR aouthdr_int1)
+coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
+ bfd *abfd;
+ PTR aouthdr_ext1;
+ PTR aouthdr_int1;
{
AOUTHDR *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
}
static unsigned int
-DEFUN(coff_swap_aouthdr_out,(abfd, in, out),
- bfd *abfd AND
- PTR in AND
- PTR out)
+coff_swap_aouthdr_out (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
{
struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in;
AOUTHDR *aouthdr_out = (AOUTHDR *)out;
(bfd_byte *) aouthdr_out->text_start);
PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
(bfd_byte *) aouthdr_out->data_start);
+#ifdef COFF_WITH_PE
+ {
+ PEAOUTHDR *peaouthdr_out = (PEAOUTHDR *)aouthdr_out;
+ bfd_h_put_32 (abfd, aouthdr_in->pe->ImageBase,
+ (bfd_byte *) peaouthdr_out->ImageBase);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->SectionAlignment,
+ (bfd_byte *) peaouthdr_out->SectionAlignment);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->FileAlignment,
+ (bfd_byte *) peaouthdr_out->FileAlignment);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->MajorOperatingSystemVersion,
+ (bfd_byte *) peaouthdr_out->MajorOperatingSystemVersion);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->MinorOperatingSystemVersion,
+ (bfd_byte *) peaouthdr_out->MinorOperatingSystemVersion);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->MajorImageVersion,
+ (bfd_byte *) peaouthdr_out->MajorImageVersion);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->MinorImageVersion,
+ (bfd_byte *) peaouthdr_out->MinorImageVersion);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->MajorSubsystemVersion,
+ (bfd_byte *) peaouthdr_out->MajorSubsystemVersion);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->MinorSubsystemVersion,
+ (bfd_byte *) peaouthdr_out->MinorSubsystemVersion);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->Reserved1,
+ (bfd_byte *) peaouthdr_out->Reserved1);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfImage,
+ (bfd_byte *) peaouthdr_out->SizeOfImage);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfHeaders,
+ (bfd_byte *) peaouthdr_out->SizeOfHeaders);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->CheckSum,
+ (bfd_byte *) peaouthdr_out->CheckSum);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->Subsystem,
+ (bfd_byte *) peaouthdr_out->Subsystem);
+ bfd_h_put_16 (abfd, aouthdr_in->pe->DllCharacteristics,
+ (bfd_byte *) peaouthdr_out->DllCharacteristics);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfStackReserve,
+ (bfd_byte *) peaouthdr_out->SizeOfStackReserve);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfStackCommit,
+ (bfd_byte *) peaouthdr_out->SizeOfStackCommit);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfHeapReserve,
+ (bfd_byte *) peaouthdr_out->SizeOfHeapReserve);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->SizeOfHeapCommit,
+ (bfd_byte *) peaouthdr_out->SizeOfHeapCommit);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->LoaderFlags,
+ (bfd_byte *) peaouthdr_out->LoaderFlags);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->NumberOfRvaAndSizes,
+ (bfd_byte *) peaouthdr_out->NumberOfRvaAndSizes);
+ {
+ int idx;
+ for (idx=0; idx < 16; idx++)
+ {
+ bfd_h_put_32 (abfd, aouthdr_in->pe->DataDirectory[idx].VirtualAddress,
+ (bfd_byte *) peaouthdr_out->DataDirectory[idx][0]);
+ bfd_h_put_32 (abfd, aouthdr_in->pe->DataDirectory[idx].Size,
+ (bfd_byte *) peaouthdr_out->DataDirectory[idx][1]);
+ }
+ }
+}
+#endif
+
#ifdef I960
bfd_h_put_32(abfd, aouthdr_in->tagentries, (bfd_byte *) aouthdr_out->tagentries);
#endif
}
static void
-DEFUN(coff_swap_scnhdr_in,(abfd, ext, in),
- bfd *abfd AND
- PTR ext AND
- PTR in)
+coff_swap_scnhdr_in (abfd, ext, in)
+ bfd *abfd;
+ PTR ext;
+ PTR in;
{
SCNHDR *scnhdr_ext = (SCNHDR *) ext;
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
#ifdef I960
scnhdr_int->s_align = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_align);
#endif
+
+#ifdef NT_EXE_IMAGE_BASE
+/*
+ if (scnhdr_int->s_vaddr != 0) {
+ scnhdr_int->s_vaddr += NT_EXE_IMAGE_BASE;
+ }
+*/
+#endif
}
-/* start-sanitize-mpw */
-#ifndef MPW_C
-/* end-sanitize-mpw */
static unsigned int
-DEFUN(coff_swap_scnhdr_out,(abfd, in, out),
- bfd *abfd AND
- PTR in AND
- PTR out)
+coff_swap_scnhdr_out (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
{
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
SCNHDR *scnhdr_ext = (SCNHDR *)out;
+ unsigned int ret = sizeof (SCNHDR);
memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
- PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr,
+
+#ifdef COFF_IMAGE_WITH_PE
+
+ {
+ bfd_link_pe_info *pe_info = coff_data (abfd)->link_info->pe_info;
+
+ PUT_SCNHDR_VADDR (abfd,
+ (scnhdr_int->s_vaddr
+ - pe_value (&pe_info->image_base,
+ NT_EXE_IMAGE_BASE)),
(bfd_byte *) scnhdr_ext->s_vaddr);
- PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr,
- (bfd_byte *) scnhdr_ext->s_paddr);
- PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size,
- (bfd_byte *) scnhdr_ext->s_size);
- PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
- (bfd_byte *) scnhdr_ext->s_scnptr);
- PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
- (bfd_byte *) scnhdr_ext->s_relptr);
- PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
- (bfd_byte *) scnhdr_ext->s_lnnoptr);
- PUTWORD(abfd, scnhdr_int->s_flags, (bfd_byte *) scnhdr_ext->s_flags);
-#if defined(M88)
- PUTWORD(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
- PUTWORD(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
-#else
- PUTHALF(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
- PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
-#endif
-#if defined(I960)
- PUTWORD(abfd, scnhdr_int->s_align, (bfd_byte *) scnhdr_ext->s_align);
+
+ /* NT wants the physical address data to be the size (s_size data) of
+ the section */
+#if 1
+ PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_size,
+ (bfd_byte *) scnhdr_ext->s_paddr);
#endif
- return sizeof(SCNHDR);
+ /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
+ value except for the BSS section, its s_size should be 0 */
+ if (strcmp (scnhdr_int->s_name, _BSS) == 0)
+ PUT_SCNHDR_SIZE (abfd, 0, (bfd_byte *) scnhdr_ext->s_size);
+ else
+ {
+ bfd_vma rounded_size;
+ rounded_size = ((scnhdr_int->s_size + NT_FILE_ALIGNMENT - 1) /
+ NT_FILE_ALIGNMENT) *
+ NT_FILE_ALIGNMENT;
+ PUT_SCNHDR_SIZE (abfd, rounded_size, (bfd_byte *) scnhdr_ext->s_size);
+ }
}
-/* start-sanitize-mpw */
#else
-/* Same routine, but with some pre-expanded macros, so ^&%$#&! MPW C doesn't
- corrupt itself and then freak out. */
+ PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr,
+ (bfd_byte *) scnhdr_ext->s_vaddr);
-static unsigned int
-DEFUN(coff_swap_scnhdr_out,(abfd, in, out),
- bfd *abfd AND
- PTR in AND
- PTR out)
-{
- struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
- SCNHDR *scnhdr_ext = (SCNHDR *)out;
- memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
- bfd_h_put_32 (abfd, scnhdr_int->s_vaddr,
- (bfd_byte *) scnhdr_ext->s_vaddr);
- bfd_h_put_32 (abfd, scnhdr_int->s_paddr,
+ PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr,
(bfd_byte *) scnhdr_ext->s_paddr);
- bfd_h_put_32 (abfd, scnhdr_int->s_size,
+ PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size,
(bfd_byte *) scnhdr_ext->s_size);
+#endif
PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
(bfd_byte *) scnhdr_ext->s_scnptr);
PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
(bfd_byte *) scnhdr_ext->s_relptr);
PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
(bfd_byte *) scnhdr_ext->s_lnnoptr);
+#ifdef COFF_IMAGE_WITH_PE
+ /* Extra flags must be set when dealing with NT. All sections should also
+ have the IMAGE_SCN_MEM_READ (0x40000000) flag set. In addition, the
+ .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
+ sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
+ (this is especially important when dealing with the .idata section since
+ the addresses for routines from .dlls must be overwritten). If .reloc
+ section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
+ (0x02000000). Also, the resource data should also be read and
+ writable. */
+ {
+ int flags = scnhdr_int->s_flags;
+ if (strcmp (scnhdr_int->s_name, ".data") == 0 ||
+ strcmp (scnhdr_int->s_name, ".CRT") == 0 ||
+ strcmp (scnhdr_int->s_name, ".rsrc") == 0 ||
+ strcmp (scnhdr_int->s_name, ".bss") == 0)
+ flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
+ else if (strcmp (scnhdr_int->s_name, ".text") == 0)
+ flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
+ else if (strcmp (scnhdr_int->s_name, ".reloc") == 0)
+ flags = SEC_DATA| IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE;
+ else if (strcmp (scnhdr_int->s_name, ".idata") == 0)
+ flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA;
+ else if (strcmp (scnhdr_int->s_name, ".rdata") == 0
+ || strcmp (scnhdr_int->s_name, ".edata") == 0)
+ flags = IMAGE_SCN_MEM_READ | SEC_DATA;
+
+ PUTWORD(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
+ }
+#else
PUTWORD(abfd, scnhdr_int->s_flags, (bfd_byte *) scnhdr_ext->s_flags);
+#endif
#if defined(M88)
PUTWORD(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
PUTWORD(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
#else
- PUTHALF(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
- PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
+ if (scnhdr_int->s_nlnno <= 0xffff)
+ PUTHALF(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
+ else
+ {
+ (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff",
+ bfd_get_filename (abfd),
+ scnhdr_int->s_nlnno);
+ bfd_set_error (bfd_error_file_truncated);
+ PUTHALF (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
+ ret = 0;
+ }
+ if (scnhdr_int->s_nreloc <= 0xffff)
+ PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
+ else
+ {
+ (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff",
+ bfd_get_filename (abfd),
+ scnhdr_int->s_nreloc);
+ bfd_set_error (bfd_error_file_truncated);
+ PUTHALF (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
+ ret = 0;
+ }
#endif
#if defined(I960)
PUTWORD(abfd, scnhdr_int->s_align, (bfd_byte *) scnhdr_ext->s_align);
#endif
- return sizeof(SCNHDR);
+ return ret;
}
-
-#endif
-/* end-sanitize-mpw */