Tue Aug 29 13:50:21 1995 steve chamberlain <sac@slash.cygnus.com>
* 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.
This commit is contained in:
parent
f88ebc6861
commit
3ea928f5a9
|
@ -1,3 +1,12 @@
|
|||
Tue Aug 29 13:50:21 1995 steve chamberlain <sac@slash.cygnus.com>
|
||||
|
||||
* 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
|
||||
|
|
|
@ -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
|
||||
|
|
157
bfd/coffcode.h
157
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,16 +1733,29 @@ 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;
|
||||
internal_f->pe->e_cp = 0x3;
|
||||
|
@ -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--;
|
||||
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
|
||||
{
|
||||
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 (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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
511
bfd/coffswap.h
511
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;
|
||||
|
@ -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]);
|
||||
#error we need to cope with truncating or extending DIMNUM
|
||||
#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);
|
||||
}
|
||||
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 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
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if DIMNUM != E_DIMNUM
|
||||
#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]);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
#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);
|
||||
|
||||
|
||||
/* 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
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
#else
|
||||
PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr,
|
||||
(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);
|
||||
#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;
|
||||
}
|
||||
/* start-sanitize-mpw */
|
||||
#else
|
||||
/* Same routine, but with some pre-expanded macros, so ^&%$#&! MPW C doesn't
|
||||
corrupt itself and then freak out. */
|
||||
|
||||
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,
|
||||
(bfd_byte *) scnhdr_ext->s_paddr);
|
||||
bfd_h_put_32 (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);
|
||||
#endif
|
||||
return sizeof(SCNHDR);
|
||||
}
|
||||
|
||||
#endif
|
||||
/* end-sanitize-mpw */
|
||||
|
|
Loading…
Reference in New Issue