1,5 → 1,5 |
/* Support for the generic parts of most COFF variants, for BFD. |
Copyright 1990-2013 Free Software Foundation, Inc. |
Copyright (C) 1990-2015 Free Software Foundation, Inc. |
Written by Cygnus Support. |
|
This file is part of BFD, the Binary File Descriptor library. |
337,6 → 337,9 |
. union internal_auxent auxent; |
. struct internal_syment syment; |
. } u; |
. |
. {* Selector for the union above. *} |
. bfd_boolean is_sym; |
.} combined_entry_type; |
. |
. |
928,12 → 931,7 |
|
bfd_coff_swap_sym_in (abfd, esym, & isym); |
|
if (sizeof (internal_s->s_name) > SYMNMLEN) |
{ |
/* This case implies that the matching |
symbol name will be in the string table. */ |
abort (); |
} |
BFD_ASSERT (sizeof (internal_s->s_name) <= SYMNMLEN); |
|
if (isym.n_scnum == section->target_index) |
{ |
964,8 → 962,12 |
/* All 3 branches use this. */ |
symname = _bfd_coff_internal_syment_name (abfd, &isym, buf); |
|
/* PR 17512 file: 078-11867-0.004 */ |
if (symname == NULL) |
abort (); |
{ |
_bfd_error_handler (_("%B: unable to load COMDAT section name"), abfd); |
break; |
} |
|
switch (seen_state) |
{ |
1007,6 → 1009,13 |
|
seen_state = 1; |
|
/* PR 17512: file: e2cfe54f. */ |
if (esym + bfd_coff_symesz (abfd) >= esymend) |
{ |
_bfd_error_handler (_("%B: warning: No symbol for section '%s' found"), |
abfd, symname); |
break; |
} |
/* This is the section symbol. */ |
bfd_coff_swap_aux_in (abfd, (esym + bfd_coff_symesz (abfd)), |
isym.n_type, isym.n_sclass, |
1160,7 → 1169,7 |
flagword *flags_ptr) |
{ |
struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr; |
long styp_flags = internal_s->s_flags; |
unsigned long styp_flags = internal_s->s_flags; |
flagword sec_flags; |
bfd_boolean result = TRUE; |
bfd_boolean is_dbg = FALSE; |
1183,7 → 1192,7 |
/* Process each flag bit in styp_flags in turn. */ |
while (styp_flags) |
{ |
long flag = styp_flags & - styp_flags; |
unsigned long flag = styp_flags & - styp_flags; |
char * unhandled = NULL; |
|
styp_flags &= ~ flag; |
1343,6 → 1352,10 |
. COFF_SYMBOL_PE_SECTION |
.}; |
. |
.typedef asection * (*coff_gc_mark_hook_fn) |
. (asection *, struct bfd_link_info *, struct internal_reloc *, |
. struct coff_link_hash_entry *, struct internal_syment *); |
. |
Special entry points for gdb to swap in coff symbol table parts: |
.typedef struct |
.{ |
1393,6 → 1406,7 |
. unsigned int _bfd_coff_default_section_alignment_power; |
. bfd_boolean _bfd_coff_force_symnames_in_strings; |
. unsigned int _bfd_coff_debug_string_prefix_length; |
. unsigned int _bfd_coff_max_nscns; |
. |
. void (*_bfd_coff_swap_filehdr_in) |
. (bfd *, void *, void *); |
1530,6 → 1544,9 |
. ((coff_backend_info (abfd)->_bfd_coff_set_long_section_names) (abfd, enable)) |
.#define bfd_coff_default_section_alignment_power(abfd) \ |
. (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power) |
.#define bfd_coff_max_nscns(abfd) \ |
. (coff_backend_info (abfd)->_bfd_coff_max_nscns) |
. |
.#define bfd_coff_swap_filehdr_in(abfd, i,o) \ |
. ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o)) |
. |
1793,6 → 1810,7 |
in case this symbol winds up getting written out. The value 0 |
for n_numaux is already correct. */ |
|
native->is_sym = TRUE; |
native->u.syment.n_type = T_NULL; |
native->u.syment.n_sclass = sclass; |
|
2066,7 → 2084,11 |
#endif |
|
if ((internal_f->f_flags & F_GO32STUB) != 0) |
{ |
coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE); |
if (coff->go32stub == NULL) |
return NULL; |
} |
if (coff->go32stub != NULL) |
memcpy (coff->go32stub, internal_f->go32stub, GO32_STUBSIZE); |
|
2092,12 → 2114,6 |
machine = 0; |
switch (internal_f->f_magic) |
{ |
#ifdef OR32_MAGIC_BIG |
case OR32_MAGIC_BIG: |
case OR32_MAGIC_LITTLE: |
arch = bfd_arch_or32; |
break; |
#endif |
#ifdef PPCMAGIC |
case PPCMAGIC: |
arch = bfd_arch_powerpc; |
2277,6 → 2293,8 |
bfd_size_type amt = bfd_coff_symesz (abfd); |
|
buf = bfd_malloc (amt); |
if (buf == NULL) |
return FALSE; |
if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 |
|| bfd_bread (buf, amt, abfd) != amt) |
{ |
2500,11 → 2518,13 |
unsigned int indaux, |
combined_entry_type *aux) |
{ |
BFD_ASSERT (symbol->is_sym); |
int n_sclass = symbol->u.syment.n_sclass; |
|
if (CSECT_SYM_P (n_sclass) |
&& indaux + 1 == symbol->u.syment.n_numaux) |
{ |
BFD_ASSERT (! aux->is_sym); |
if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) == XTY_LD) |
{ |
aux->u.auxent.x_csect.x_scnlen.p = |
2537,6 → 2557,7 |
/* Return TRUE if we don't want to pointerize this aux entry, which |
is the case for the lastfirst aux entry for a C_LEAFPROC symbol. */ |
return (indaux == 1 |
&& symbol->is_sym |
&& (symbol->u.syment.n_sclass == C_LEAFPROC |
|| symbol->u.syment.n_sclass == C_LEAFSTAT |
|| symbol->u.syment.n_sclass == C_LEAFEXT)); |
2559,6 → 2580,8 |
combined_entry_type *aux ATTRIBUTE_UNUSED, |
unsigned int indaux ATTRIBUTE_UNUSED) |
{ |
BFD_ASSERT (symbol->is_sym); |
BFD_ASSERT (! aux->is_sym); |
#ifdef RS6000COFF_C |
if (CSECT_SYM_P (symbol->u.syment.n_sclass) |
&& indaux + 1 == symbol->u.syment.n_numaux) |
2660,11 → 2683,17 |
amt = s->reloc_count; |
amt *= sizeof (arelent *); |
p = bfd_malloc (amt); |
if (p == NULL && s->reloc_count > 0) |
if (p == NULL) |
{ |
if (s->reloc_count > 0) |
return FALSE; |
} |
else |
{ |
memcpy (p, s->orelocation, (size_t) amt); |
qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr); |
} |
} |
#endif |
|
if (bfd_seek (abfd, s->rel_filepos, SEEK_SET) != 0) |
3064,15 → 3093,6 |
return TRUE; |
#endif |
|
#ifdef OR32_MAGIC_BIG |
case bfd_arch_or32: |
if (bfd_big_endian (abfd)) |
* magicp = OR32_MAGIC_BIG; |
else |
* magicp = OR32_MAGIC_LITTLE; |
return TRUE; |
#endif |
|
default: /* Unknown architecture. */ |
/* Fall through to "return FALSE" below, to avoid |
"statement never reached" errors on the one below. */ |
3136,7 → 3156,7 |
asection *current; |
file_ptr sofar = bfd_coff_filhsz (abfd); |
bfd_boolean align_adjust; |
int target_index; |
unsigned int target_index; |
#ifdef ALIGN_SECTIONS_IN_FILE |
asection *previous = NULL; |
file_ptr old_sofar; |
3145,7 → 3165,8 |
#ifdef COFF_IMAGE_WITH_PE |
int page_size; |
|
if (coff_data (abfd)->link_info) |
if (coff_data (abfd)->link_info |
|| (pe_data (abfd) && pe_data (abfd)->pe_opthdr.FileAlignment)) |
{ |
page_size = pe_data (abfd)->pe_opthdr.FileAlignment; |
|
3153,7 → 3174,16 |
This repairs 'ld -r' for arm-wince-pe target. */ |
if (page_size == 0) |
page_size = 1; |
|
/* PR 17512: file: 0ac816d3. */ |
if (page_size < 0) |
{ |
bfd_set_error (bfd_error_file_too_big); |
(*_bfd_error_handler) |
(_("%B: page size is too large (0x%x)"), abfd, page_size); |
return FALSE; |
} |
} |
else |
page_size = PE_DEF_FILE_ALIGNMENT; |
#else |
3176,9 → 3206,10 |
{ |
coff_symbol_type *cf; |
|
cf = coff_symbol_from (abfd, *symp); |
cf = coff_symbol_from (*symp); |
if (cf != NULL |
&& cf->native != NULL |
&& cf->native->is_sym |
&& SYMNAME_IN_DEBUG (&cf->native->u.syment)) |
{ |
size_t len; |
3304,7 → 3335,7 |
} |
#endif /* ! COFF_IMAGE_WITH_PE */ |
|
if (target_index >= 32768) |
if (target_index >= bfd_coff_max_nscns (abfd)) |
{ |
bfd_set_error (bfd_error_file_too_big); |
(*_bfd_error_handler) |
3873,9 → 3904,10 |
/* See if this is the section symbol. */ |
if (strcmp ((*psym)->name, current->name) == 0) |
{ |
csym = coff_symbol_from (abfd, *psym); |
csym = coff_symbol_from (*psym); |
if (csym == NULL |
|| csym->native == NULL |
|| ! csym->native->is_sym |
|| csym->native->u.syment.n_numaux < 1 |
|| csym->native->u.syment.n_sclass != C_STAT |
|| csym->native->u.syment.n_type != T_NULL) |
3898,6 → 3930,7 |
x_associated field is not currently supported. */ |
|
aux = csym->native + 1; |
BFD_ASSERT (! aux->is_sym); |
switch (current->flags & SEC_LINK_DUPLICATES) |
{ |
case SEC_LINK_DUPLICATES_DISCARD: |
4043,8 → 4076,6 |
internal_f.f_flags |= F_DYNLOAD; |
#endif |
|
memset (&internal_a, 0, sizeof internal_a); |
|
/* Set up architecture-dependent stuff. */ |
{ |
unsigned int magic = 0; |
4154,11 → 4185,6 |
internal_a.magic = MIPS_PE_MAGIC; |
#endif |
|
#ifdef OR32 |
#define __A_MAGIC_SET__ |
internal_a.magic = NMAGIC; /* Assume separate i/d. */ |
#endif |
|
#ifndef __A_MAGIC_SET__ |
#include "Your aouthdr magic number is not being set!" |
#else |
4325,7 → 4351,18 |
} |
#endif |
|
/* Now write them. */ |
#ifdef COFF_WITH_PE |
{ |
/* After object contents are finalized so we can compute a reasonable hash, |
but before header is written so we can update it to point to debug directory. */ |
struct pe_tdata *pe = pe_data (abfd); |
|
if (pe->build_id.after_write_object_contents != NULL) |
(*pe->build_id.after_write_object_contents) (abfd); |
} |
#endif |
|
/* Now write header. */ |
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) |
return FALSE; |
|
4460,11 → 4497,11 |
void * area = bfd_alloc (abfd, size); |
|
if (!area) |
return (NULL); |
return NULL; |
if (bfd_seek (abfd, where, SEEK_SET) != 0 |
|| bfd_bread (area, size, abfd) != size) |
return (NULL); |
return (area); |
return NULL; |
return area; |
} |
|
/* |
4498,6 → 4535,8 |
const coff_symbol_type *s1 = (const coff_symbol_type *) (al1->u.sym); |
const coff_symbol_type *s2 = (const coff_symbol_type *) (al2->u.sym); |
|
if (s1 == NULL || s2 == NULL) |
return 0; |
if (s1->symbol.value < s2->symbol.value) |
return -1; |
else if (s1->symbol.value > s2->symbol.value) |
4515,9 → 4554,11 |
unsigned int counter; |
alent *cache_ptr; |
bfd_vma prev_offset = 0; |
int ordered = 1; |
bfd_boolean ordered = TRUE; |
unsigned int nbr_func; |
LINENO *src; |
bfd_boolean have_func; |
bfd_boolean ret = TRUE; |
|
BFD_ASSERT (asect->lineno == NULL); |
|
4540,40 → 4581,67 |
asect->lineno = lineno_cache; |
src = native_lineno; |
nbr_func = 0; |
have_func = FALSE; |
|
for (counter = 0; counter < asect->lineno_count; counter++) |
for (counter = 0; counter < asect->lineno_count; counter++, src++) |
{ |
struct internal_lineno dst; |
|
bfd_coff_swap_lineno_in (abfd, src, &dst); |
cache_ptr->line_number = dst.l_lnno; |
/* Appease memory checkers that get all excited about |
uninitialised memory when copying alents if u.offset is |
larger than u.sym. (64-bit BFD on 32-bit host.) */ |
memset (&cache_ptr->u, 0, sizeof (cache_ptr->u)); |
|
if (cache_ptr->line_number == 0) |
{ |
bfd_boolean warned; |
bfd_signed_vma symndx; |
combined_entry_type * ent; |
bfd_vma symndx; |
coff_symbol_type *sym; |
|
nbr_func++; |
warned = FALSE; |
have_func = FALSE; |
symndx = dst.l_addr.l_symndx; |
if (symndx < 0 |
|| (bfd_vma) symndx >= obj_raw_syment_count (abfd)) |
if (symndx >= obj_raw_syment_count (abfd)) |
{ |
(*_bfd_error_handler) |
(_("%B: warning: illegal symbol index %ld in line numbers"), |
abfd, (long) symndx); |
symndx = 0; |
warned = TRUE; |
(_("%B: warning: illegal symbol index 0x%lx in line number entry %d"), |
abfd, (long) symndx, counter); |
cache_ptr->line_number = -1; |
ret = FALSE; |
continue; |
} |
|
ent = obj_raw_syments (abfd) + symndx; |
/* FIXME: We should not be casting between ints and |
pointers like this. */ |
sym = ((coff_symbol_type *) |
((symndx + obj_raw_syments (abfd)) |
->u.syment._n._n_n._n_zeroes)); |
if (! ent->is_sym) |
{ |
(*_bfd_error_handler) |
(_("%B: warning: illegal symbol index 0x%lx in line number entry %d"), |
abfd, (long) symndx, counter); |
cache_ptr->line_number = -1; |
ret = FALSE; |
continue; |
} |
sym = (coff_symbol_type *) (ent->u.syment._n._n_n._n_zeroes); |
|
/* PR 17512 file: 078-10659-0.004 */ |
if (sym < obj_symbols (abfd) |
|| sym >= obj_symbols (abfd) + bfd_get_symcount (abfd)) |
{ |
(*_bfd_error_handler) |
(_("%B: warning: illegal symbol in line number entry %d"), |
abfd, counter); |
cache_ptr->line_number = -1; |
ret = FALSE; |
continue; |
} |
|
have_func = TRUE; |
nbr_func++; |
cache_ptr->u.sym = (asymbol *) sym; |
if (sym->lineno != NULL && ! warned) |
if (sym->lineno != NULL) |
(*_bfd_error_handler) |
(_("%B: warning: duplicate line number information for `%s'"), |
abfd, bfd_asymbol_name (&sym->symbol)); |
4580,17 → 4648,21 |
|
sym->lineno = cache_ptr; |
if (sym->symbol.value < prev_offset) |
ordered = 0; |
ordered = FALSE; |
prev_offset = sym->symbol.value; |
} |
else if (!have_func) |
/* Drop line information that has no associated function. |
PR 17521: file: 078-10659-0.004. */ |
continue; |
else |
cache_ptr->u.offset = dst.l_addr.l_paddr |
- bfd_section_vma (abfd, asect); |
|
cache_ptr->u.offset = (dst.l_addr.l_paddr |
- bfd_section_vma (abfd, asect)); |
cache_ptr++; |
src++; |
} |
cache_ptr->line_number = 0; |
|
asect->lineno_count = cache_ptr - lineno_cache; |
memset (cache_ptr, 0, sizeof (*cache_ptr)); |
bfd_release (abfd, native_lineno); |
|
/* On some systems (eg AIX5.3) the lineno table may not be sorted. */ |
4607,15 → 4679,17 |
alent **p = func_table; |
unsigned int i; |
|
for (i = 0; i < counter; i++) |
for (i = 0; i < asect->lineno_count; i++) |
if (lineno_cache[i].line_number == 0) |
*p++ = &lineno_cache[i]; |
|
BFD_ASSERT ((unsigned int) (p - func_table) == nbr_func); |
|
/* Sort by functions. */ |
qsort (func_table, nbr_func, sizeof (alent *), coff_sort_func_alent); |
|
/* Create the new sorted table. */ |
amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent); |
amt = (bfd_size_type) asect->lineno_count * sizeof (alent); |
n_lineno_cache = (alent *) bfd_alloc (abfd, amt); |
if (n_lineno_cache != NULL) |
{ |
4626,25 → 4700,29 |
coff_symbol_type *sym; |
alent *old_ptr = func_table[i]; |
|
/* Copy the function entry and update it. */ |
*n_cache_ptr = *old_ptr; |
sym = (coff_symbol_type *)n_cache_ptr->u.sym; |
sym->lineno = n_cache_ptr; |
n_cache_ptr++; |
old_ptr++; |
|
/* Copy the line number entries. */ |
while (old_ptr->line_number != 0) |
/* Update the function entry. */ |
sym = (coff_symbol_type *) old_ptr->u.sym; |
/* PR binutils/17512: Point the lineno to where |
this entry will be after the memcpy below. */ |
sym->lineno = lineno_cache + (n_cache_ptr - n_lineno_cache); |
/* Copy the function and line number entries. */ |
do |
*n_cache_ptr++ = *old_ptr++; |
while (old_ptr->line_number != 0); |
} |
n_cache_ptr->line_number = 0; |
BFD_ASSERT ((bfd_size_type) (n_cache_ptr - n_lineno_cache) == (amt / sizeof (alent))); |
|
memcpy (lineno_cache, n_lineno_cache, amt); |
} |
else |
ret = FALSE; |
bfd_release (abfd, func_table); |
} |
else |
ret = FALSE; |
} |
|
return TRUE; |
return ret; |
} |
|
/* Slurp in the symbol table, converting it to generic form. Note |
4659,6 → 4737,7 |
unsigned int *table_ptr; |
bfd_size_type amt; |
unsigned int number_of_symbols = 0; |
bfd_boolean ret = TRUE; |
|
if (obj_symbols (abfd)) |
return TRUE; |
4676,7 → 4755,7 |
|
amt = obj_raw_syment_count (abfd); |
amt *= sizeof (unsigned int); |
table_ptr = (unsigned int *) bfd_alloc (abfd, amt); |
table_ptr = (unsigned int *) bfd_zalloc (abfd, amt); |
|
if (table_ptr == NULL) |
return FALSE; |
4690,8 → 4769,9 |
{ |
combined_entry_type *src = native_symbols + this_index; |
table_ptr[this_index] = number_of_symbols; |
|
dst->symbol.the_bfd = abfd; |
|
BFD_ASSERT (src->is_sym); |
dst->symbol.name = (char *) (src->u.syment._n._n_n._n_offset); |
/* We use the native name field to point to the cached field. */ |
src->u.syment._n._n_n._n_zeroes = (bfd_hostptr_t) dst; |
4698,6 → 4778,8 |
dst->symbol.section = coff_section_from_bfd_index (abfd, |
src->u.syment.n_scnum); |
dst->symbol.flags = 0; |
/* PR 17512: file: 079-7098-0.001:0.1. */ |
dst->symbol.value = 0; |
dst->done_lineno = FALSE; |
|
switch (src->u.syment.n_sclass) |
4971,13 → 5053,14 |
#if defined(TIC80COFF) || defined(TICOFF) |
case C_UEXT: /* Tentative external definition. */ |
#endif |
case C_EXTLAB: /* External load time label. */ |
case C_HIDDEN: /* Ext symbol in dmert public lib. */ |
default: |
(*_bfd_error_handler) |
(_("%B: Unrecognized storage class %d for %s symbol `%s'"), |
abfd, src->u.syment.n_sclass, |
dst->symbol.section->name, dst->symbol.name); |
ret = FALSE; |
case C_EXTLAB: /* External load time label. */ |
case C_HIDDEN: /* Ext symbol in dmert public lib. */ |
dst->symbol.flags = BSF_DEBUGGING; |
dst->symbol.value = (src->u.syment.n_value); |
break; |
4984,9 → 5067,9 |
} |
|
dst->native = src; |
|
dst->symbol.udata.i = 0; |
dst->lineno = NULL; |
|
this_index += (src->u.syment.n_numaux) + 1; |
dst++; |
number_of_symbols++; |
5005,12 → 5088,13 |
p = abfd->sections; |
while (p) |
{ |
coff_slurp_line_table (abfd, p); |
if (! coff_slurp_line_table (abfd, p)) |
return FALSE; |
p = p->next; |
} |
} |
|
return TRUE; |
return ret; |
} |
|
/* Classify a COFF symbol. A couple of targets have globally visible |
5069,13 → 5153,13 |
if (syment->n_value == 0) |
{ |
asection *sec; |
char * name; |
char buf[SYMNMLEN + 1]; |
|
name = _bfd_coff_internal_syment_name (abfd, syment, buf) |
sec = coff_section_from_bfd_index (abfd, syment->n_scnum); |
if (sec != NULL |
&& (strcmp (bfd_get_section_name (abfd, sec), |
_bfd_coff_internal_syment_name (abfd, syment, buf)) |
== 0)) |
if (sec != NULL && name != NULL |
&& (strcmp (bfd_get_section_name (abfd, sec), name) == 0)) |
return COFF_SYMBOL_PE_SECTION; |
} |
#endif |
5144,8 → 5228,9 |
coffsym = (obj_symbols (abfd) \ |
+ (cache_ptr->sym_ptr_ptr - symbols)); \ |
else if (ptr) \ |
coffsym = coff_symbol_from (abfd, ptr); \ |
coffsym = coff_symbol_from (ptr); \ |
if (coffsym != NULL \ |
&& coffsym->native->is_sym \ |
&& coffsym->native->u.syment.n_scnum == 0) \ |
cache_ptr->addend = 0; \ |
else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ |
5268,7 → 5353,7 |
static reloc_howto_type * |
coff_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, |
asection *sec ATTRIBUTE_UNUSED, |
struct internal_reloc *rel, |
struct internal_reloc *rel ATTRIBUTE_UNUSED, |
struct coff_link_hash_entry *h ATTRIBUTE_UNUSED, |
struct internal_syment *sym ATTRIBUTE_UNUSED, |
bfd_vma *addendp ATTRIBUTE_UNUSED) |
5360,10 → 5445,6 |
} |
#endif |
|
#ifndef coff_bfd_link_hash_table_free |
#define coff_bfd_link_hash_table_free _bfd_generic_link_hash_table_free |
#endif |
|
/* If coff_relocate_section is defined, we can use the optimized COFF |
backend linker. Otherwise we must continue to use the old linker. */ |
|
5497,6 → 5578,7 |
#else |
2, |
#endif |
32768, |
coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in, |
coff_SWAP_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook, |
coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook, |
5537,6 → 5619,7 |
#else |
2, |
#endif |
32768, |
coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in, |
coff_SWAP_reloc_in, ticoff0_bad_format_hook, coff_set_arch_mach_hook, |
coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook, |
5578,6 → 5661,7 |
#else |
2, |
#endif |
32768, |
coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in, |
coff_SWAP_reloc_in, ticoff1_bad_format_hook, coff_set_arch_mach_hook, |
coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook, |
5591,6 → 5675,253 |
}; |
#endif |
|
#ifdef COFF_WITH_PE_BIGOBJ |
/* The UID for bigobj files. */ |
|
static const char header_bigobj_classid[16] = |
{ |
0xC7, 0xA1, 0xBA, 0xD1, |
0xEE, 0xBA, |
0xa9, 0x4b, |
0xAF, 0x20, |
0xFA, 0xF6, 0x6A, 0xA4, 0xDC, 0xB8 |
}; |
|
/* Swap routines. */ |
|
static void |
coff_bigobj_swap_filehdr_in (bfd * abfd, void * src, void * dst) |
{ |
struct external_ANON_OBJECT_HEADER_BIGOBJ *filehdr_src = |
(struct external_ANON_OBJECT_HEADER_BIGOBJ *) src; |
struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst; |
|
filehdr_dst->f_magic = H_GET_16 (abfd, filehdr_src->Machine); |
filehdr_dst->f_nscns = H_GET_32 (abfd, filehdr_src->NumberOfSections); |
filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->TimeDateStamp); |
filehdr_dst->f_symptr = |
GET_FILEHDR_SYMPTR (abfd, filehdr_src->PointerToSymbolTable); |
filehdr_dst->f_nsyms = H_GET_32 (abfd, filehdr_src->NumberOfSymbols); |
filehdr_dst->f_opthdr = 0; |
filehdr_dst->f_flags = 0; |
|
/* Check other magic numbers. */ |
if (H_GET_16 (abfd, filehdr_src->Sig1) != IMAGE_FILE_MACHINE_UNKNOWN |
|| H_GET_16 (abfd, filehdr_src->Sig2) != 0xffff |
|| H_GET_16 (abfd, filehdr_src->Version) != 2 |
|| memcmp (filehdr_src->ClassID, header_bigobj_classid, 16) != 0) |
filehdr_dst->f_opthdr = 0xffff; |
|
/* Note that CLR metadata are ignored. */ |
} |
|
static unsigned int |
coff_bigobj_swap_filehdr_out (bfd *abfd, void * in, void * out) |
{ |
struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in; |
struct external_ANON_OBJECT_HEADER_BIGOBJ *filehdr_out = |
(struct external_ANON_OBJECT_HEADER_BIGOBJ *) out; |
|
memset (filehdr_out, 0, sizeof (*filehdr_out)); |
|
H_PUT_16 (abfd, IMAGE_FILE_MACHINE_UNKNOWN, filehdr_out->Sig1); |
H_PUT_16 (abfd, 0xffff, filehdr_out->Sig2); |
H_PUT_16 (abfd, 2, filehdr_out->Version); |
memcpy (filehdr_out->ClassID, header_bigobj_classid, 16); |
H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->Machine); |
H_PUT_32 (abfd, filehdr_in->f_nscns, filehdr_out->NumberOfSections); |
H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->TimeDateStamp); |
PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, |
filehdr_out->PointerToSymbolTable); |
H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->NumberOfSymbols); |
|
return bfd_coff_filhsz (abfd); |
} |
|
static void |
coff_bigobj_swap_sym_in (bfd * abfd, void * ext1, void * in1) |
{ |
SYMENT_BIGOBJ *ext = (SYMENT_BIGOBJ *) ext1; |
struct internal_syment *in = (struct internal_syment *) in1; |
|
if (ext->e.e_name[0] == 0) |
{ |
in->_n._n_n._n_zeroes = 0; |
in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset); |
} |
else |
{ |
#if SYMNMLEN != E_SYMNMLEN |
#error we need to cope with truncating or extending SYMNMLEN |
#else |
memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN); |
#endif |
} |
|
in->n_value = H_GET_32 (abfd, ext->e_value); |
in->n_scnum = H_GET_32 (abfd, ext->e_scnum); |
in->n_type = H_GET_16 (abfd, ext->e_type); |
in->n_sclass = H_GET_8 (abfd, ext->e_sclass); |
in->n_numaux = H_GET_8 (abfd, ext->e_numaux); |
} |
|
static unsigned int |
coff_bigobj_swap_sym_out (bfd * abfd, void * inp, void * extp) |
{ |
struct internal_syment *in = (struct internal_syment *) inp; |
SYMENT_BIGOBJ *ext = (SYMENT_BIGOBJ *) extp; |
|
if (in->_n._n_name[0] == 0) |
{ |
H_PUT_32 (abfd, 0, ext->e.e.e_zeroes); |
H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset); |
} |
else |
{ |
#if SYMNMLEN != E_SYMNMLEN |
#error we need to cope with truncating or extending SYMNMLEN |
#else |
memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN); |
#endif |
} |
|
H_PUT_32 (abfd, in->n_value, ext->e_value); |
H_PUT_32 (abfd, in->n_scnum, ext->e_scnum); |
|
H_PUT_16 (abfd, in->n_type, ext->e_type); |
H_PUT_8 (abfd, in->n_sclass, ext->e_sclass); |
H_PUT_8 (abfd, in->n_numaux, ext->e_numaux); |
|
return SYMESZ_BIGOBJ; |
} |
|
static void |
coff_bigobj_swap_aux_in (bfd *abfd, |
void * ext1, |
int type, |
int in_class, |
int indx, |
int numaux, |
void * in1) |
{ |
AUXENT_BIGOBJ *ext = (AUXENT_BIGOBJ *) ext1; |
union internal_auxent *in = (union internal_auxent *) in1; |
|
switch (in_class) |
{ |
case C_FILE: |
if (numaux > 1) |
{ |
if (indx == 0) |
memcpy (in->x_file.x_fname, ext->File.Name, |
numaux * sizeof (AUXENT_BIGOBJ)); |
} |
else |
memcpy (in->x_file.x_fname, ext->File.Name, sizeof (ext->File.Name)); |
break; |
|
case C_STAT: |
case C_LEAFSTAT: |
case C_HIDDEN: |
if (type == T_NULL) |
{ |
in->x_scn.x_scnlen = H_GET_32 (abfd, ext->Section.Length); |
in->x_scn.x_nreloc = |
H_GET_16 (abfd, ext->Section.NumberOfRelocations); |
in->x_scn.x_nlinno = |
H_GET_16 (abfd, ext->Section.NumberOfLinenumbers); |
in->x_scn.x_checksum = H_GET_32 (abfd, ext->Section.Checksum); |
in->x_scn.x_associated = H_GET_16 (abfd, ext->Section.Number) |
| (H_GET_16 (abfd, ext->Section.HighNumber) << 16); |
in->x_scn.x_comdat = H_GET_8 (abfd, ext->Section.Selection); |
return; |
} |
break; |
|
default: |
in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->Sym.WeakDefaultSymIndex); |
/* Characteristics is ignored. */ |
break; |
} |
} |
|
static unsigned int |
coff_bigobj_swap_aux_out (bfd * abfd, |
void * inp, |
int type, |
int in_class, |
int indx ATTRIBUTE_UNUSED, |
int numaux ATTRIBUTE_UNUSED, |
void * extp) |
{ |
union internal_auxent * in = (union internal_auxent *) inp; |
AUXENT_BIGOBJ *ext = (AUXENT_BIGOBJ *) extp; |
|
memset (ext, 0, AUXESZ); |
|
switch (in_class) |
{ |
case C_FILE: |
memcpy (ext->File.Name, in->x_file.x_fname, sizeof (ext->File.Name)); |
|
return AUXESZ; |
|
case C_STAT: |
case C_LEAFSTAT: |
case C_HIDDEN: |
if (type == T_NULL) |
{ |
H_PUT_32 (abfd, in->x_scn.x_scnlen, ext->Section.Length); |
H_PUT_16 (abfd, in->x_scn.x_nreloc, |
ext->Section.NumberOfRelocations); |
H_PUT_16 (abfd, in->x_scn.x_nlinno, |
ext->Section.NumberOfLinenumbers); |
H_PUT_32 (abfd, in->x_scn.x_checksum, ext->Section.Checksum); |
H_PUT_16 (abfd, in->x_scn.x_associated & 0xffff, |
ext->Section.Number); |
H_PUT_16 (abfd, (in->x_scn.x_associated >> 16), |
ext->Section.HighNumber); |
H_PUT_8 (abfd, in->x_scn.x_comdat, ext->Section.Selection); |
return AUXESZ; |
} |
break; |
} |
|
H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->Sym.WeakDefaultSymIndex); |
H_PUT_32 (abfd, 1, ext->Sym.WeakSearchType); |
|
return AUXESZ; |
} |
|
static bfd_coff_backend_data bigobj_swap_table = |
{ |
coff_bigobj_swap_aux_in, coff_bigobj_swap_sym_in, coff_SWAP_lineno_in, |
coff_bigobj_swap_aux_out, coff_bigobj_swap_sym_out, |
coff_SWAP_lineno_out, coff_SWAP_reloc_out, |
coff_bigobj_swap_filehdr_out, coff_SWAP_aouthdr_out, |
coff_SWAP_scnhdr_out, |
FILHSZ_BIGOBJ, AOUTSZ, SCNHSZ, SYMESZ_BIGOBJ, AUXESZ_BIGOBJ, |
RELSZ, LINESZ, FILNMLEN_BIGOBJ, |
TRUE, |
COFF_DEFAULT_LONG_SECTION_NAMES, |
COFF_DEFAULT_SECTION_ALIGNMENT_POWER, |
FALSE, |
2, |
1U << 31, |
coff_bigobj_swap_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in, |
coff_SWAP_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook, |
coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook, |
coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook, |
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate, |
coff_classify_symbol, coff_compute_section_file_positions, |
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto, |
coff_adjust_symndx, coff_link_add_one_symbol, |
coff_link_output_has_begun, coff_final_link_postscript, |
bfd_pe_print_pdata /* huh */ |
}; |
|
#endif /* COFF_WITH_PE_BIGOBJ */ |
|
#ifndef coff_close_and_cleanup |
#define coff_close_and_cleanup _bfd_generic_close_and_cleanup |
#endif |
5666,7 → 5997,7 |
#endif |
|
#ifndef coff_bfd_gc_sections |
#define coff_bfd_gc_sections bfd_generic_gc_sections |
#define coff_bfd_gc_sections bfd_coff_gc_sections |
#endif |
|
#ifndef coff_bfd_lookup_section_flags |