From 3ea928f5a902b2dd53d16cfda009c5b8a9653398 Mon Sep 17 00:00:00 2001 From: Steve Chamberlain Date: Tue, 29 Aug 1995 21:05:59 +0000 Subject: [PATCH] Tue Aug 29 13:50:21 1995 steve chamberlain * libbfd.h, bfd-in2.h: regenerated. * coff-arm.c (aoutarm_std_relo): New entry at 11. (arm_reloc_type_lookup) : Understand type 11. * coff-i386.c (howto_table): fix name of rva type. (coff-i386_rtype_to_howto): Understand R_IMAGEBASE type. * coffcode.h (sec_to_styp_flags): .edata is data. (coff_compute_section_file_positions): Get page size right for PE. (fill_pe_header_info): Fix fields. (coff_write_object_contents): Remove end_of_image calc. (_bfd_coff_generate_reloc_section): Remove orphaned comment. * coffswap.h (coff_swap_scnhdr_in): Don't always add IMAGE_BASE. (coff_swap_scnhdr_out): Setup PE flags correctly. * reloc.c (BFD_RELOC_RVA): New field. --- bfd/ChangeLog | 9 + bfd/coff-arm.c | 90 +++++++-- bfd/coffcode.h | 161 +++++++++------- bfd/cofflink.c | 21 +- bfd/coffswap.h | 507 ++++++++++++++++++++++++++++++++++--------------- 5 files changed, 550 insertions(+), 238 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1a13b002df..96f22ac4aa 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +Tue Aug 29 13:50:21 1995 steve chamberlain + + * bfd-in2.h: regenerated. + +Thu Aug 24 17:49:59 1995 Ian Lance Taylor (ian@cygnus.com) + + * cofflink.c (coff_link_input_bfd): Don't include line numbers for + a section if its output section has no contents. + Wed Aug 23 16:48:52 1995 Ian Lance Taylor (ian@cygnus.com) * ecoff.c (_bfd_ecoff_slurp_symbolic_info): Add parentheses to FIX diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c index f9d12b096d..3136a8d15c 100644 --- a/bfd/coff-arm.c +++ b/bfd/coff-arm.c @@ -128,6 +128,10 @@ coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, return bfd_reloc_continue; } +#ifndef PCRELOFFSET +#define PCRELOFFSET true +#endif + static reloc_howto_type aoutarm_std_reloc_howto[] = { /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */ @@ -172,7 +176,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = PCRELOFFSET), HOWTO( 3, 2, - 3, + 2, 26, true, 0, @@ -224,7 +228,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = true), HOWTO( 7, 2, - 3, + 2, 26, false, 0, @@ -261,7 +265,20 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = true, 0xffffffff, 0xffffffff, - false) + false), + HOWTO( 11, + 0, + 2, + 32, + false, + 0, + complain_overflow_bitfield, + coff_arm_reloc, + "rva32", + true, + 0xffffffff, + 0xffffffff, + PCRELOFFSET), }; @@ -366,6 +383,7 @@ arm_reloc_type_lookup(abfd,code) ASTD (BFD_RELOC_8_PCREL, 4); ASTD (BFD_RELOC_16_PCREL, 5); ASTD (BFD_RELOC_32_PCREL, 6); + ASTD (BFD_RELOC_RVA, 11); default: return (CONST struct reloc_howto_struct *) 0; } } @@ -505,18 +523,10 @@ i3coff_object_p(a) return coff_object_p(a); } -const bfd_target -#ifdef TARGET_SYM - TARGET_SYM = -#else - armcoff_vec = -#endif +#ifdef TARGET_LITTLE_SYM +const bfd_target TARGET_LITTLE_SYM = { -#ifdef TARGET_NAME - TARGET_NAME, -#else - "coff-arm", /* name */ -#endif + TARGET_LITTLE_NAME, /* name or coff-arm-little */ bfd_target_coff_flavour, false, /* data byte order is little */ false, /* header byte order is little */ @@ -562,3 +572,55 @@ const bfd_target COFF_SWAP_TABLE, }; +#endif + +#ifdef TARGET_BIG_SYM +const bfd_target TARGET_BIG_SYM = +{ + TARGET_BIG_NAME, /* name or coff-arm-big */ + bfd_target_coff_flavour, + true, /* data byte order is big */ + true, /* header byte order is big */ + + (HAS_RELOC | EXEC_P | /* object flags */ + HAS_LINENO | HAS_DEBUG | + HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), + + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ +#ifdef TARGET_UNDERSCORE + TARGET_UNDERSCORE, /* leading underscore */ +#else + 0, /* leading underscore */ +#endif + '/', /* ar_pad_char */ + 15, /* ar_max_namelen */ + + 2, /* minimum alignment power */ + bfd_getb64, bfd_getb_signed_64, bfd_putb64, + bfd_getb32, bfd_getb_signed_32, bfd_putb32, + bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ + bfd_getb64, bfd_getb_signed_64, bfd_putb64, + bfd_getb32, bfd_getb_signed_32, bfd_putb32, + bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ + +/* Note that we allow an object file to be treated as a core file as well. */ + {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */ + bfd_generic_archive_p, i3coff_object_p}, + {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ + bfd_false}, + {bfd_false, coff_write_object_contents, /* bfd_write_contents */ + _bfd_write_archive_contents, bfd_false}, + + BFD_JUMP_TABLE_GENERIC (coff), + BFD_JUMP_TABLE_COPY (coff), + BFD_JUMP_TABLE_CORE (_bfd_nocore), + BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), + BFD_JUMP_TABLE_SYMBOLS (coff), + BFD_JUMP_TABLE_RELOCS (coff), + BFD_JUMP_TABLE_WRITE (coff), + BFD_JUMP_TABLE_LINK (coff), + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + + COFF_SWAP_TABLE, +}; +#endif diff --git a/bfd/coffcode.h b/bfd/coffcode.h index f155ce2dc3..d5282e3a10 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -304,7 +304,9 @@ CODE_FRAGMENT 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; @@ -377,6 +379,12 @@ sec_to_styp_flags (sec_name, sec_flags) { 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) { @@ -1499,11 +1507,19 @@ coff_compute_section_file_positions (abfd) 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 @@ -1554,13 +1570,11 @@ coff_compute_section_file_positions (abfd) #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; @@ -1582,12 +1596,14 @@ coff_compute_section_file_positions (abfd) 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; @@ -1685,19 +1701,22 @@ static void add_data_entry (abfd, aout, idx, name, base) { 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); @@ -1714,15 +1733,28 @@ fill_pe_header_info (abfd, internal_f, internal_a, end_of_image) 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; @@ -1775,14 +1807,6 @@ fill_pe_header_info (abfd, internal_f, internal_a, end_of_image) /* 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); @@ -1803,28 +1827,20 @@ fill_pe_header_info (abfd, internal_f, internal_a, end_of_image) 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; @@ -1844,12 +1860,30 @@ fill_pe_header_info (abfd, internal_f, internal_a, end_of_image) /* 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 @@ -1871,7 +1905,6 @@ coff_write_object_contents (abfd) 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; @@ -1891,7 +1924,7 @@ coff_write_object_contents (abfd) 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) { @@ -1991,15 +2024,10 @@ coff_write_object_contents (abfd) 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 @@ -2052,24 +2080,27 @@ coff_write_object_contents (abfd) { 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; + } } } @@ -2247,7 +2278,7 @@ coff_write_object_contents (abfd) 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 */ diff --git a/bfd/cofflink.c b/bfd/cofflink.c index c4c42d5a8e..43bb69f45a 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -1622,7 +1622,17 @@ coff_link_input_bfd (finfo, input_bfd) bfd_byte *eline; bfd_byte *elineend; - if (o->lineno_count == 0) + /* FIXME: If SEC_HAS_CONTENTS is not for the section, then + build_link_order in ldwrite.c will not have created a + link order, which means that we will not have seen this + input section in _bfd_coff_final_link, which means that + we will not have allocated space for the line numbers of + this section. I don't think line numbers can be + meaningful for a section which does not have + SEC_HAS_CONTENTS set, but, if they do, this must be + changed. */ + if (o->lineno_count == 0 + || (o->output_section->flags & SEC_HAS_CONTENTS) == 0) continue; if (bfd_seek (input_bfd, o->line_filepos, SEEK_SET) != 0 @@ -2225,15 +2235,6 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, if (howto == NULL) return false; - /* WINDOWS_NT; in this next section, the value of 'val' will be computed. - With respect to the .idata and .rsrc sections, the NT_IMAGE_BASE - must be removed from the value that is to be relocated (NT_IMAGE_BASE - is currently defined in internal.h and has value 400000). Now this - value should only be removed from addresses being relocated in the - .idata and .rsrc sections, not the .text section which should have - the 'real' address. In addition, the .rsrc val's must also be - adjusted by the input_section->vma. */ - val = 0; if (h == NULL) diff --git a/bfd/coffswap.h b/bfd/coffswap.h index 3e15ddcb28..4b35942057 100644 --- a/bfd/coffswap.h +++ b/bfd/coffswap.h @@ -1,5 +1,5 @@ /* 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. @@ -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. */ /* 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 @@ -26,6 +26,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 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 @@ -168,11 +172,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #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); @@ -191,17 +198,23 @@ DEFUN(bfd_swap_reloc_in,(abfd, reloc_src, reloc_dst), 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, @@ -218,10 +231,10 @@ DEFUN(coff_swap_reloc_out,(abfd, src, dst), #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; @@ -236,13 +249,14 @@ DEFUN(coff_swap_filehdr_in,(abfd, src, 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); @@ -251,6 +265,61 @@ DEFUN(coff_swap_filehdr_out,(abfd, in, out), 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); } @@ -258,10 +327,10 @@ DEFUN(coff_swap_filehdr_out,(abfd, in, out), #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; @@ -277,7 +346,7 @@ DEFUN(coff_swap_sym_in,(abfd, ext1, 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); @@ -287,13 +356,34 @@ DEFUN(coff_swap_sym_in,(abfd, ext1, in1), } 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; @@ -324,14 +414,14 @@ DEFUN(coff_swap_sym_out,(abfd, inp, 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; @@ -357,7 +447,7 @@ DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, indx, numaux, 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); @@ -392,20 +482,25 @@ DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, indx, numaux, in1), 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); @@ -417,14 +512,14 @@ DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, indx, numaux, in1), } 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; @@ -453,7 +548,7 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, indx, numaux, 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 @@ -487,28 +582,35 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, indx, numaux, extp), 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); } @@ -517,10 +619,10 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, indx, numaux, extp), #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; @@ -530,10 +632,10 @@ DEFUN(coff_swap_lineno_in,(abfd, ext1, 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; @@ -548,10 +650,10 @@ DEFUN(coff_swap_lineno_out,(abfd, inp, 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; @@ -616,10 +718,10 @@ DEFUN(coff_swap_aouthdr_in,(abfd, aouthdr_ext1, 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; @@ -634,6 +736,64 @@ DEFUN(coff_swap_aouthdr_out,(abfd, in, 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 @@ -662,10 +822,10 @@ DEFUN(coff_swap_aouthdr_out,(abfd, in, out), } 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; @@ -695,88 +855,137 @@ DEFUN(coff_swap_scnhdr_in,(abfd, ext, 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 */ -- 2.34.1