/* Support for the generic parts of most COFF variants, for BFD.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 1990-2018 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
The Microsoft PE variants of the Coff object file format add
an extension to support the use of long section names. This
- extension is defined in section 4 of the Microsoft PE/COFF
+ extension is defined in section 4 of the Microsoft PE/COFF
specification (rev 8.1). If a section name is too long to fit
into the section header's @code{s_name} field, it is instead
placed into the string table, and the @code{s_name} field is
- filled with a slash ("/") followed by the ASCII decimal
+ filled with a slash ("/") followed by the ASCII decimal
representation of the offset of the full name relative to the
string table base.
expecting the MS standard format may become confused; @file{PEview} is
one known example.
- The functionality is supported in BFD by code implemented under
+ The functionality is supported in BFD by code implemented under
the control of the macro @code{COFF_LONG_SECTION_NAMES}. If not
defined, the format does not support long section names in any way.
- If defined, it is used to initialise a flag,
- @code{_bfd_coff_long_section_names}, and a hook function pointer,
+ If defined, it is used to initialise a flag,
+ @code{_bfd_coff_long_section_names}, and a hook function pointer,
@code{_bfd_coff_set_long_section_names}, in the Coff backend data
structure. The flag controls the generation of long section names
in output BFDs at runtime; if it is false, as it will be by default
points to a function that allows the value of the flag to be altered
at runtime, on formats that support long section names at all; on
other formats it points to a stub that returns an error indication.
-
+
With input BFDs, the flag is set according to whether any long section
names are detected while reading the section headers. For a completely
new BFD, the flag is set to the default for the target format. This
.typedef struct coff_ptr_struct
.{
. {* Remembers the offset from the first symbol in the file for
-. this symbol. Generated by coff_renumber_symbols. *}
+. this symbol. Generated by coff_renumber_symbols. *}
. unsigned int offset;
.
. {* Should the value of this symbol be renumbered. Used for
. unsigned int fix_value : 1;
.
. {* Should the tag field of this symbol be renumbered.
-. Created by coff_pointerize_aux. *}
+. Created by coff_pointerize_aux. *}
. unsigned int fix_tag : 1;
.
. {* Should the endidx field of this symbol be renumbered.
-. Created by coff_pointerize_aux. *}
+. Created by coff_pointerize_aux. *}
. unsigned int fix_end : 1;
.
. {* Should the x_csect.x_scnlen field be renumbered.
-. Created by coff_pointerize_aux. *}
+. Created by coff_pointerize_aux. *}
. unsigned int fix_scnlen : 1;
.
. {* Fix up an XCOFF C_BINCL/C_EINCL symbol. The value is the
. unsigned int fix_line : 1;
.
. {* The container for the symbol structure as read and translated
-. from the file. *}
+. from the file. *}
. union
. {
. union internal_auxent auxent;
. struct internal_syment syment;
. } u;
+.
+. {* Selector for the union above. *}
+. bfd_boolean is_sym;
.} combined_entry_type;
.
.
#define STRING_SIZE_SIZE 4
#define DOT_DEBUG ".debug"
+#define DOT_ZDEBUG ".zdebug"
#define GNU_LINKONCE_WI ".gnu.linkonce.wi."
#define GNU_LINKONCE_WT ".gnu.linkonce.wt."
#define DOT_RELOC ".reloc"
#define COFFLONGSECTIONCATHELPER(x,y) x ## y
/* If the input macro Y is blank or '1', return an odd number; if it is
'0', return an even number. Result undefined in all other cases. */
-#define BLANKOR1TOODD(y) COFFLONGSECTIONCATHELPER(1,y)
+#define BLANKOR1TOODD(y) COFFLONGSECTIONCATHELPER(1,y)
/* Defined to numerical 0 or 1 according to whether generation of long
section names is disabled or enabled by default. */
#define COFF_ENABLE_LONG_SECTION_NAMES (BLANKOR1TOODD(COFF_LONG_SECTION_NAMES) & 1)
styp_flags = STYP_LIT;
#endif /* _LIT */
}
- else if (CONST_STRNEQ (sec_name, DOT_DEBUG))
+ else if (CONST_STRNEQ (sec_name, DOT_DEBUG)
+ || CONST_STRNEQ (sec_name, DOT_ZDEBUG))
{
/* Handle the XCOFF debug section and DWARF2 debug sections. */
if (!sec_name[6])
}
#ifdef COFF_LONG_SECTION_NAMES
else if (CONST_STRNEQ (sec_name, GNU_LINKONCE_WI)
- || CONST_STRNEQ (sec_name, GNU_LINKONCE_WT))
+ || CONST_STRNEQ (sec_name, GNU_LINKONCE_WT))
{
styp_flags = STYP_DEBUG_INFO;
}
{
styp_flags = STYP_TYPCHK;
}
+ else if (sec_flags & SEC_DEBUGGING)
+ {
+ int i;
+
+ for (i = 0; i < XCOFF_DWSECT_NBR_NAMES; i++)
+ if (!strcmp (sec_name, xcoff_dwsect_names[i].name))
+ {
+ styp_flags = STYP_DWARF | xcoff_dwsect_names[i].flag;
+ break;
+ }
+ }
#endif
/* Try and figure out what it should be */
else if (sec_flags & SEC_CODE)
bfd_boolean is_dbg = FALSE;
if (CONST_STRNEQ (sec_name, DOT_DEBUG)
+ || CONST_STRNEQ (sec_name, DOT_ZDEBUG)
#ifdef COFF_LONG_SECTION_NAMES
|| CONST_STRNEQ (sec_name, GNU_LINKONCE_WI)
|| CONST_STRNEQ (sec_name, GNU_LINKONCE_WT)
/* FIXME: There is no gas syntax to specify the debug section flag. */
if (is_dbg)
- sec_flags = SEC_DEBUGGING | SEC_READONLY;
+ {
+ sec_flags &= (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
+ | SEC_LINK_DUPLICATES_SAME_CONTENTS
+ | SEC_LINK_DUPLICATES_SAME_SIZE);
+ sec_flags |= SEC_DEBUGGING | SEC_READONLY;
+ }
/* skip LOAD */
/* READONLY later */
/* skip SORT */
if (sec_flags & SEC_LINK_ONCE)
styp_flags |= IMAGE_SCN_LNK_COMDAT;
- /* skip LINK_DUPLICATES */
+ if ((sec_flags
+ & (SEC_LINK_DUPLICATES_DISCARD | SEC_LINK_DUPLICATES_SAME_CONTENTS
+ | SEC_LINK_DUPLICATES_SAME_SIZE)) != 0)
+ styp_flags |= IMAGE_SCN_LNK_COMDAT;
+
/* skip LINKER_CREATED */
if ((sec_flags & SEC_COFF_NOREAD) == 0)
}
else if (styp_flags & STYP_PAD)
sec_flags = 0;
+#ifdef RS6000COFF_C
+ else if (styp_flags & STYP_EXCEPT)
+ sec_flags |= SEC_LOAD;
+ else if (styp_flags & STYP_LOADER)
+ sec_flags |= SEC_LOAD;
+ else if (styp_flags & STYP_TYPCHK)
+ sec_flags |= SEC_LOAD;
+ else if (styp_flags & STYP_DWARF)
+ sec_flags |= SEC_DEBUGGING;
+#endif
else if (strcmp (name, _TEXT) == 0)
{
if (sec_flags & SEC_NEVER_LOAD)
sec_flags |= SEC_ALLOC;
}
else if (CONST_STRNEQ (name, DOT_DEBUG)
+ || CONST_STRNEQ (name, DOT_ZDEBUG)
#ifdef _COMMENT
|| strcmp (name, _COMMENT) == 0
#endif
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)
{
/* 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)
{
|| isym.n_sclass == C_EXT)
&& BTYPE (isym.n_type) == T_NULL
&& isym.n_value == 0))
- abort ();
+ {
+ /* Malformed input files can trigger this test.
+ cf PR 21781. */
+ _bfd_error_handler (_("%B: error: unexpected symbol '%s' in COMDAT section"),
+ abfd, symname);
+ goto breakloop;
+ }
/* FIXME LATER: MSVC generates section names
like .text for comdats. Gas generates
function). See comment above for more. */
if (isym.n_sclass == C_STAT && strcmp (name, symname) != 0)
- _bfd_error_handler (_("%B: warning: COMDAT symbol '%s' does not match section name '%s'"),
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%B: warning: COMDAT symbol '%s'"
+ " does not match section name '%s'"),
abfd, symname, name);
seen_state = 1;
+ /* PR 17512: file: e2cfe54f. */
+ if (esym + bfd_coff_symesz (abfd) >= esymend)
+ {
+ /* xgettext:c-format */
+ _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,
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;
if (CONST_STRNEQ (name, DOT_DEBUG)
+ || CONST_STRNEQ (name, DOT_ZDEBUG)
#ifdef COFF_LONG_SECTION_NAMES
|| CONST_STRNEQ (name, GNU_LINKONCE_WI)
|| CONST_STRNEQ (name, GNU_LINKONCE_WT)
/* 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;
/* Generate a warning message rather using the 'unhandled'
variable as this will allow some .sys files generate by
other toolchains to be processed. See bugzilla issue 196. */
- _bfd_error_handler (_("%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"),
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%B: Warning: Ignoring section flag"
+ " IMAGE_SCN_MEM_NOT_PAGED in section %s"),
abfd, name);
break;
case IMAGE_SCN_MEM_EXECUTE:
/* If the section flag was not handled, report it here. */
if (unhandled != NULL)
{
- (*_bfd_error_handler)
- (_("%B (%s): Section flag %s (0x%x) ignored"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B (%s): Section flag %s (%#lx) ignored"),
abfd, name, unhandled, flag);
result = FALSE;
}
. 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
.{
. bfd_boolean _bfd_coff_long_section_names;
. bfd_boolean (*_bfd_coff_set_long_section_names)
. (bfd *, int);
-.
+.
. 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 *);
.
. bfd_boolean (*_bfd_coff_pointerize_aux_hook)
. (bfd *, combined_entry_type *, combined_entry_type *,
-. unsigned int, combined_entry_type *);
+. unsigned int, combined_entry_type *);
.
. bfd_boolean (*_bfd_coff_print_aux)
. (bfd *, FILE *, combined_entry_type *, combined_entry_type *,
-. combined_entry_type *, unsigned int);
+. combined_entry_type *, unsigned int);
.
. void (*_bfd_coff_reloc16_extra_cases)
. (bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *,
-. bfd_byte *, unsigned int *, unsigned int *);
+. bfd_byte *, unsigned int *, unsigned int *);
.
. int (*_bfd_coff_reloc16_estimate)
. (bfd *, asection *, arelent *, unsigned int,
-. struct bfd_link_info *);
+. struct bfd_link_info *);
.
. enum coff_symbol_classification (*_bfd_coff_classify_symbol)
. (bfd *, struct internal_syment *);
.
. bfd_boolean (*_bfd_coff_relocate_section)
. (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
-. struct internal_reloc *, struct internal_syment *, asection **);
+. struct internal_reloc *, struct internal_syment *, asection **);
.
. reloc_howto_type *(*_bfd_coff_rtype_to_howto)
. (bfd *, asection *, struct internal_reloc *,
-. struct coff_link_hash_entry *, struct internal_syment *,
-. bfd_vma *);
+. struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *);
.
. bfd_boolean (*_bfd_coff_adjust_symndx)
. (bfd *, struct bfd_link_info *, bfd *, asection *,
-. struct internal_reloc *, bfd_boolean *);
+. struct internal_reloc *, bfd_boolean *);
.
. bfd_boolean (*_bfd_coff_link_add_one_symbol)
. (struct bfd_link_info *, bfd *, const char *, flagword,
-. asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean,
-. struct bfd_link_hash_entry **);
+. asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean,
+. struct bfd_link_hash_entry **);
.
. bfd_boolean (*_bfd_coff_link_output_has_begun)
. (bfd *, struct coff_final_link_info *);
. ((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))
.
. (abfd, file, base, symbol, aux, indaux))
.
.#define bfd_coff_reloc16_extra_cases(abfd, link_info, link_order,\
-. reloc, data, src_ptr, dst_ptr)\
+. reloc, data, src_ptr, dst_ptr)\
. ((coff_backend_info (abfd)->_bfd_coff_reloc16_extra_cases)\
. (abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr))
.
. ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\
. (obfd, info, ibfd, sec, rel, adjustedp))
.#define bfd_coff_link_add_one_symbol(info, abfd, name, flags, section,\
-. value, string, cp, coll, hashp)\
+. value, string, cp, coll, hashp)\
. ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\
. (info, abfd, name, flags, section, value, string, cp, coll, hashp))
.
{
combined_entry_type *native;
bfd_size_type amt;
+ unsigned char sclass = C_STAT;
section->alignment_power = COFF_DEFAULT_SECTION_ALIGNMENT_POWER;
if (bfd_xcoff_text_align_power (abfd) != 0
&& strcmp (bfd_get_section_name (abfd, section), ".text") == 0)
section->alignment_power = bfd_xcoff_text_align_power (abfd);
- if (bfd_xcoff_data_align_power (abfd) != 0
+ else if (bfd_xcoff_data_align_power (abfd) != 0
&& strcmp (bfd_get_section_name (abfd, section), ".data") == 0)
section->alignment_power = bfd_xcoff_data_align_power (abfd);
+ else
+ {
+ int i;
+
+ for (i = 0; i < XCOFF_DWSECT_NBR_NAMES; i++)
+ if (strcmp (bfd_get_section_name (abfd, section),
+ xcoff_dwsect_names[i].name) == 0)
+ {
+ section->alignment_power = 0;
+ sclass = C_DWARF;
+ break;
+ }
+ }
#endif
/* Set up the section symbol. */
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 = C_STAT;
+ native->u.syment.n_sclass = sclass;
coffsymbol (section->symbol)->native = native;
if ((1 << i) >= hdr->s_align)
break;
#endif
-#ifdef TIC80COFF
- /* TI tools puts the alignment power in bits 8-11. */
- i = (hdr->s_flags >> 8) & 0xF ;
-#endif
#ifdef COFF_DECODE_ALIGNMENT
i = COFF_DECODE_ALIGNMENT(hdr->s_flags);
#endif
section->rel_filepos += relsz;
}
else if (hdr->s_nreloc == 0xffff)
- (*_bfd_error_handler)
- ("%s: warning: claims to have 0xffff relocs, without overflow",
- bfd_get_filename (abfd));
+ _bfd_error_handler
+ (_("%B: warning: claims to have 0xffff relocs, without overflow"),
+ abfd);
}
#undef ALIGN_SET
#undef ELIFALIGN_SET
#else /* ! RS6000COFF_C */
-#define coff_set_alignment_hook \
- ((void (*) (bfd *, asection *, void *)) bfd_void)
+static void
+coff_set_alignment_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section ATTRIBUTE_UNUSED,
+ void *scnhdr ATTRIBUTE_UNUSED)
+{
+}
#endif /* ! RS6000COFF_C */
#endif /* ! COFF_WITH_PE */
#endif
if ((internal_f->f_flags & F_GO32STUB) != 0)
- coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE);
+ {
+ 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);
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;
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)
{
#endif
default:
arch = bfd_arch_obscure;
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("Unrecognized TI COFF target id '0x%x'"),
internal_f->f_target_id);
break;
return TRUE;
}
-#ifdef SYMNAME_IN_DEBUG
-
static bfd_boolean
-symname_in_debug_hook (bfd * abfd ATTRIBUTE_UNUSED, struct internal_syment *sym)
+symname_in_debug_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED)
{
+#ifdef SYMNAME_IN_DEBUG
return SYMNAME_IN_DEBUG (sym) != 0;
-}
-
#else
-
-#define symname_in_debug_hook \
- (bfd_boolean (*) (bfd *, struct internal_syment *)) bfd_false
-
+ return FALSE;
#endif
+}
#ifdef RS6000COFF_C
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 =
/* 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));
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)
if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) != XTY_LD)
{
BFD_ASSERT (! aux->fix_scnlen);
-#ifdef XCOFF64
- fprintf (file, "val %5lld",
- (long long) aux->u.auxent.x_csect.x_scnlen.l);
-#else
- fprintf (file, "val %5ld", (long) aux->u.auxent.x_csect.x_scnlen.l);
-#endif
+ fprintf (file, "val %5" BFD_VMA_FMT "d",
+ aux->u.auxent.x_csect.x_scnlen.l);
}
else
{
fprintf (file, "indx ");
if (! aux->fix_scnlen)
-#ifdef XCOFF64
- fprintf (file, "%4lld",
- (long long) aux->u.auxent.x_csect.x_scnlen.l);
-#else
- fprintf (file, "%4ld", (long) aux->u.auxent.x_csect.x_scnlen.l);
-#endif
+ fprintf (file, "%4" BFD_VMA_FMT "d",
+ aux->u.auxent.x_csect.x_scnlen.l);
else
fprintf (file, "%4ld",
(long) (aux->u.auxent.x_csect.x_scnlen.p - table_base));
amt = s->reloc_count;
amt *= sizeof (arelent *);
p = bfd_malloc (amt);
- if (p == NULL && s->reloc_count > 0)
- return FALSE;
- memcpy (p, s->orelocation, (size_t) amt);
- qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr);
+ 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 (n.r_symndx > obj_conv_table_size (abfd))
{
bfd_set_error (bfd_error_bad_value);
- _bfd_error_handler (_("%B: reloc against a non-existant symbol index: %ld"),
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%B: reloc against a non-existent"
+ " symbol index: %ld"),
abfd, n.r_symndx);
return FALSE;
}
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. */
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;
#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;
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
+ /* xgettext:c-format */
+ (_("%B: page size is too large (0x%x)"), abfd, page_size);
+ return FALSE;
+ }
}
else
page_size = PE_DEF_FILE_ALIGNMENT;
{
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;
}
#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)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: too many sections (%d)"), abfd, target_index);
return FALSE;
}
padding the previous section up if necessary. */
old_sofar = sofar;
+ sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+
#ifdef RS6000COFF_C
- /* AIX loader checks the text section alignment of (vma - filepos)
- So even though the filepos may be aligned wrt the o_algntext, for
- AIX executables, this check fails. This shows up when a native
- AIX executable is stripped with gnu strip because the default vma
- of native is 0x10000150 but default for gnu is 0x10000140. Gnu
- stripped gnu excutable passes this check because the filepos is
- 0x0140. This problem also show up with 64 bit shared objects. The
- data section must also be aligned. */
+ /* Make sure the file offset and the vma of .text/.data are at the
+ same page offset, so that the file can be mmap'ed without being
+ relocated. Failing that, AIX is able to load and execute the
+ program, but it will be silently relocated (possible as
+ executables are PIE). But the relocation is slightly costly and
+ complexify the use of addr2line or gdb. So better to avoid it,
+ like does the native linker. Usually gnu ld makes sure that
+ the vma of .text is the file offset so this issue shouldn't
+ appear unless you are stripping such an executable.
+
+ AIX loader checks the text section alignment of (vma - filepos),
+ and the native linker doesn't try to align the text sections.
+ For example:
+
+ 0 .text 000054cc 10000128 10000128 00000128 2**5
+ CONTENTS, ALLOC, LOAD, CODE
+ */
+
if (!strcmp (current->name, _TEXT)
|| !strcmp (current->name, _DATA))
{
- bfd_vma pad;
- bfd_vma align;
-
- sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
-
- align = 1 << current->alignment_power;
- pad = abs (current->vma - sofar) % align;
-
- if (pad)
- {
- pad = align - pad;
- sofar += pad;
- }
- }
- else
-#else
- {
- sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+ bfd_vma align = 4096;
+ bfd_vma sofar_off = sofar % align;
+ bfd_vma vma_off = current->vma % align;
+
+ if (vma_off > sofar_off)
+ sofar += vma_off - sofar_off;
+ else if (vma_off < sofar_off)
+ sofar += align + vma_off - sofar_off;
}
#endif
if (previous != NULL)
incremented in coff_set_section_contents. This is right for
SVR3.2. */
if (strcmp (current->name, _LIB) == 0)
- bfd_set_section_vma (abfd, current, 0);
+ (void) bfd_set_section_vma (abfd, current, 0);
#endif
#ifdef ALIGN_SECTIONS_IN_FILE
NUL-terminated. We use a temporary buffer so that we can still
sprintf all eight chars without splatting a terminating NUL
over the first byte of the following member (s_paddr). */
- char s_name_buf[SCNNMLEN + 1];
+ /* PR 21096: The +20 is to stop a bogus warning from gcc7 about
+ a possible buffer overflow. */
+ char s_name_buf[SCNNMLEN + 1 + 20];
/* An inherent limitation of the /nnnnnnn notation used to indicate
the offset of the long name in the string table is that we
if (string_size >= 10000000)
{
bfd_set_error (bfd_error_file_too_big);
- (*_bfd_error_handler)
- (_("%B: section %s: string table overflow at offset %ld"),
- abfd, current->name, string_size);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: section %A: string table overflow at offset %ld"),
+ abfd, current, (unsigned long) string_size);
return FALSE;
}
- /* snprintf not strictly necessary now we've verified the value
- has less than eight ASCII digits, but never mind. */
- snprintf (s_name_buf, SCNNMLEN + 1, "/%lu", (unsigned long) string_size);
+ /* We do not need to use snprintf here as we have already verfied
+ that string_size is not too big, plus we have an overlarge
+ buffer, just in case. */
+ sprintf (s_name_buf, "/%lu", (unsigned long) string_size);
/* Then strncpy takes care of any padding for us. */
strncpy (section.s_name, s_name_buf, SCNNMLEN);
string_size += len + 1;
? 1 << current->alignment_power
: 0);
#endif
-#ifdef TIC80COFF
- /* TI COFF puts the alignment power in bits 8-11 of the flags. */
- section.s_flags |= (current->alignment_power & 0xF) << 8;
-#endif
#ifdef COFF_ENCODE_ALIGNMENT
COFF_ENCODE_ALIGNMENT(section, current->alignment_power);
+ if ((unsigned int)COFF_DECODE_ALIGNMENT(section.s_flags)
+ != current->alignment_power)
+ {
+ bfd_boolean warn = coff_data (abfd)->link_info
+ && !bfd_link_relocatable (coff_data (abfd)->link_info);
+
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B:%s section %s: alignment 2**%u not representable"),
+ abfd, warn ? " warning:" : "", current->name,
+ current->alignment_power);
+ if (!warn)
+ {
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return FALSE;
+ }
+ }
#endif
#ifdef COFF_IMAGE_WITH_PE
/* 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)
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:
bfd_size_type amt;
internal_f.f_nscns++;
- strncpy (&(scnhdr.s_name[0]), current->name, 8);
+ memcpy (scnhdr.s_name, ".ovrflo", 8);
scnhdr.s_paddr = current->reloc_count;
scnhdr.s_vaddr = current->lineno_count;
scnhdr.s_size = 0;
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
}
#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;
- a (four byte) word holding the length of this record, in words,
- a word that always seems to be set to "2",
- the path to a shared library, null-terminated and then padded
- to a whole word boundary.
+ to a whole word boundary.
bfd_assert calls have been added to alert if an attempt is made
to write a section which doesn't follow these assumptions. The
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;
}
/*
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)
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);
+ if (asect->lineno_count > asect->size)
+ {
+ _bfd_error_handler
+ (_("%B: warning: line number count (%#lx) exceeds section size (%#lx)"),
+ abfd, (unsigned long) asect->lineno_count, (unsigned long) asect->size);
+ return FALSE;
+ }
+
amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent);
lineno_cache = (alent *) bfd_alloc (abfd, amt);
if (lineno_cache == NULL)
native_lineno = (LINENO *) buy_and_read (abfd, asect->line_filepos, amt);
if (native_lineno == NULL)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: warning: line number table read failed"), abfd);
bfd_release (abfd, lineno_cache);
return FALSE;
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;
+ unsigned long 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;
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"),
+ abfd, 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
+ /* xgettext:c-format */
+ (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"),
+ abfd, 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
+ /* xgettext:c-format */
+ (_("%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)
- (*_bfd_error_handler)
+ if (sym->lineno != NULL)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: warning: duplicate line number information for `%s'"),
abfd, bfd_asymbol_name (&sym->symbol));
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. */
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)
{
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
unsigned int *table_ptr;
bfd_size_type amt;
unsigned int number_of_symbols = 0;
+ bfd_boolean ret = TRUE;
if (obj_symbols (abfd))
return TRUE;
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;
{
combined_entry_type *src = native_symbols + this_index;
table_ptr[this_index] = number_of_symbols;
- dst->symbol.the_bfd = abfd;
+ 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;
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)
#endif
#ifdef RS6000COFF_C
case C_HIDEXT:
+#if ! defined _AIX52 && ! defined AIX_WEAK_SUPPORT
+ case C_AIX_WEAKEXT:
+#endif
#endif
#ifdef C_SYSTEM
case C_SYSTEM: /* System Wide variable. */
&& src->u.syment.n_scnum > 0)
dst->symbol.flags = BSF_LOCAL;
#endif
- if (src->u.syment.n_sclass == C_WEAKEXT)
+ if (src->u.syment.n_sclass == C_WEAKEXT
+#ifdef RS6000COFF_C
+ || src->u.syment.n_sclass == C_AIX_WEAKEXT
+#endif
+ )
dst->symbol.flags |= BSF_WEAK;
break;
case C_THUMBSTAT: /* Thumb static. */
case C_THUMBLABEL: /* Thumb label. */
case C_THUMBSTATFUNC:/* Thumb static function. */
+#endif
+#ifdef RS6000COFF_C
+ case C_DWARF: /* A label in a dwarf section. */
+ case C_INFO: /* A label in a comment section. */
#endif
case C_LABEL: /* Label. */
if (src->u.syment.n_scnum == N_DEBUG)
&& src->u.syment.n_scnum == 0)
break;
#ifdef RS6000COFF_C
- /* XCOFF specific: deleted entry. */
- if (src->u.syment.n_value == C_NULL_VALUE)
- break;
+ /* XCOFF specific: deleted entry. */
+ if (src->u.syment.n_value == C_NULL_VALUE)
+ break;
#endif
/* Fall through. */
case C_EXTDEF: /* External definition. */
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)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: Unrecognized storage class %d for %s symbol `%s'"),
abfd, src->u.syment.n_sclass,
dst->symbol.section->name, dst->symbol.name);
+ ret = FALSE;
+ /* Fall through. */
+ case C_HIDDEN: /* Ext symbol in dmert public lib. */
+ /* PR 20722: These symbols can also be generated by
+ building DLLs with --gc-sections enabled. */
dst->symbol.flags = BSF_DEBUGGING;
dst->symbol.value = (src->u.syment.n_value);
break;
}
dst->native = src;
-
dst->symbol.udata.i = 0;
dst->lineno = NULL;
+
this_index += (src->u.syment.n_numaux) + 1;
dst++;
number_of_symbols++;
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
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
{
char buf[SYMNMLEN + 1];
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("warning: %B: local symbol `%s' has no section"),
abfd, _bfd_coff_internal_syment_name (abfd, syment, buf));
}
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 \
#else
cache_ptr->address = dst.r_vaddr;
- if (dst.r_symndx != -1)
+ if (dst.r_symndx != -1 && symbols != NULL)
{
if (dst.r_symndx < 0 || dst.r_symndx >= obj_conv_table_size (abfd))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: warning: illegal symbol index %ld in relocs"),
- abfd, (long) dst.r_symndx);
+ abfd, dst.r_symndx);
cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
ptr = NULL;
}
if (cache_ptr->howto == NULL)
{
- (*_bfd_error_handler)
- (_("%B: illegal relocation type %d at address 0x%lx"),
- abfd, dst.r_type, (long) dst.r_vaddr);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: illegal relocation type %d at address %#Lx"),
+ abfd, dst.r_type, dst.r_vaddr);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
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)
return section->reloc_count;
}
+#ifndef coff_set_reloc
+#define coff_set_reloc _bfd_generic_set_reloc
+#endif
+
#ifndef coff_reloc16_estimate
#define coff_reloc16_estimate dummy_reloc16_estimate
}
#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. */
_bfd_generic_copy_link_hash_symbol_type
#define coff_bfd_link_split_section _bfd_generic_link_split_section
+#define coff_bfd_link_check_relocs _bfd_generic_link_check_relocs
+
#ifndef coff_start_final_link
#define coff_start_final_link NULL
#endif
#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,
#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,
#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,
};
#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);
+ BFD_ASSERT (sizeof (in->n_scnum) >= 4);
+ 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
#endif
#ifndef coff_bfd_is_target_special_symbol
-#define coff_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define coff_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false
#endif
#ifndef coff_read_minisymbols
#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
+#define coff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
#endif
#ifndef coff_bfd_merge_sections
#ifndef coff_section_already_linked
#define coff_section_already_linked \
- _bfd_generic_section_already_linked
+ _bfd_coff_section_already_linked
#endif
#ifndef coff_bfd_define_common_symbol
#define coff_bfd_define_common_symbol bfd_generic_define_common_symbol
#endif
+#ifndef coff_bfd_define_start_stop
+#define coff_bfd_define_start_stop bfd_generic_define_start_stop
+#endif
+
#define CREATE_BIG_COFF_TARGET_VEC(VAR, NAME, EXTRA_O_FLAGS, EXTRA_S_FLAGS, UNDER, ALTERNATIVE, SWAP_TABLE) \
const bfd_target VAR = \
{ \
UNDER, /* Leading symbol underscore. */ \
'/', /* AR_pad_char. */ \
15, /* AR_max_namelen. */ \
+ 0, /* match priority. */ \
\
/* Data conversion functions. */ \
bfd_getb64, bfd_getb_signed_64, bfd_putb64, \
bfd_getb32, bfd_getb_signed_32, bfd_putb32, \
bfd_getb16, bfd_getb_signed_16, bfd_putb16, \
\
- /* bfd_check_format. */ \
- { _bfd_dummy_target, coff_object_p, bfd_generic_archive_p, \
- _bfd_dummy_target }, \
- /* bfd_set_format. */ \
- { bfd_false, coff_mkobject, _bfd_generic_mkarchive, bfd_false }, \
- /* bfd_write_contents. */ \
- { bfd_false, coff_write_object_contents, _bfd_write_archive_contents, \
- bfd_false }, \
+ { /* bfd_check_format. */ \
+ _bfd_dummy_target, \
+ coff_object_p, \
+ bfd_generic_archive_p, \
+ _bfd_dummy_target \
+ }, \
+ { /* bfd_set_format. */ \
+ _bfd_bool_bfd_false_error, \
+ coff_mkobject, \
+ _bfd_generic_mkarchive, \
+ _bfd_bool_bfd_false_error \
+ }, \
+ { /* bfd_write_contents. */ \
+ _bfd_bool_bfd_false_error, \
+ coff_write_object_contents, \
+ _bfd_write_archive_contents, \
+ _bfd_bool_bfd_false_error \
+ }, \
\
BFD_JUMP_TABLE_GENERIC (coff), \
BFD_JUMP_TABLE_COPY (coff), \
UNDER, /* Leading symbol underscore. */ \
'/', /* AR_pad_char. */ \
15, /* AR_max_namelen. */ \
+ 0, /* match priority. */ \
\
/* Data conversion functions. */ \
bfd_getb64, bfd_getb_signed_64, bfd_putb64, \
bfd_getb32, bfd_getb_signed_32, bfd_putb32, \
bfd_getb16, bfd_getb_signed_16, bfd_putb16, \
\
- /* bfd_check_format. */ \
- { _bfd_dummy_target, coff_object_p, bfd_generic_archive_p, \
- _bfd_dummy_target }, \
- /* bfd_set_format. */ \
- { bfd_false, coff_mkobject, _bfd_generic_mkarchive, bfd_false }, \
- /* bfd_write_contents. */ \
- { bfd_false, coff_write_object_contents, _bfd_write_archive_contents, \
- bfd_false }, \
+ { /* bfd_check_format. */ \
+ _bfd_dummy_target, \
+ coff_object_p, \
+ bfd_generic_archive_p, \
+ _bfd_dummy_target \
+ }, \
+ { /* bfd_set_format. */ \
+ _bfd_bool_bfd_false_error, \
+ coff_mkobject, \
+ _bfd_generic_mkarchive, \
+ _bfd_bool_bfd_false_error \
+ }, \
+ { /* bfd_write_contents. */ \
+ _bfd_bool_bfd_false_error, \
+ coff_write_object_contents, \
+ _bfd_write_archive_contents, \
+ _bfd_bool_bfd_false_error \
+ }, \
\
BFD_JUMP_TABLE_GENERIC (coff), \
BFD_JUMP_TABLE_COPY (coff), \
UNDER, /* Leading symbol underscore. */ \
'/', /* AR_pad_char. */ \
15, /* AR_max_namelen. */ \
+ 0, /* match priority. */ \
\
/* Data conversion functions. */ \
bfd_getl64, bfd_getl_signed_64, bfd_putl64, \
bfd_getl64, bfd_getl_signed_64, bfd_putl64, \
bfd_getl32, bfd_getl_signed_32, bfd_putl32, \
bfd_getl16, bfd_getl_signed_16, bfd_putl16, \
- /* bfd_check_format. */ \
- { _bfd_dummy_target, coff_object_p, bfd_generic_archive_p, \
- _bfd_dummy_target }, \
- /* bfd_set_format. */ \
- { bfd_false, coff_mkobject, _bfd_generic_mkarchive, bfd_false }, \
- /* bfd_write_contents. */ \
- { bfd_false, coff_write_object_contents, _bfd_write_archive_contents, \
- bfd_false }, \
+ \
+ { /* bfd_check_format. */ \
+ _bfd_dummy_target, \
+ coff_object_p, \
+ bfd_generic_archive_p, \
+ _bfd_dummy_target \
+ }, \
+ { /* bfd_set_format. */ \
+ _bfd_bool_bfd_false_error, \
+ coff_mkobject, \
+ _bfd_generic_mkarchive, \
+ _bfd_bool_bfd_false_error \
+ }, \
+ { /* bfd_write_contents. */ \
+ _bfd_bool_bfd_false_error, \
+ coff_write_object_contents, \
+ _bfd_write_archive_contents, \
+ _bfd_bool_bfd_false_error \
+ }, \
\
BFD_JUMP_TABLE_GENERIC (coff), \
BFD_JUMP_TABLE_COPY (coff), \