/* 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
- Free Software Foundation, Inc.
+ Copyright (C) 1990-2014 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
*/
+#include "libiberty.h"
+
#ifdef COFF_WITH_PE
#include "peicode.h"
#else
#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"
#if defined (COFF_LONG_SECTION_NAMES)
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])
styp_flags = STYP_DEBUG_INFO;
}
#ifdef COFF_LONG_SECTION_NAMES
- else if (CONST_STRNEQ (sec_name, GNU_LINKONCE_WI))
+ else if (CONST_STRNEQ (sec_name, GNU_LINKONCE_WI)
+ || 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)
sec_to_styp_flags (const char *sec_name, flagword sec_flags)
{
long styp_flags = 0;
+ 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)
+#endif
+ || CONST_STRNEQ (sec_name, ".stab"))
+ is_dbg = TRUE;
/* caution: there are at least three groups of symbols that have
very similar bits and meanings: IMAGE_SCN*, SEC_*, and STYP_*.
but there are more IMAGE_SCN_* flags. */
/* FIXME: There is no gas syntax to specify the debug section flag. */
- if (CONST_STRNEQ (sec_name, DOT_DEBUG)
- || CONST_STRNEQ (sec_name, GNU_LINKONCE_WI))
- sec_flags = SEC_DEBUGGING | SEC_READONLY;
+ if (is_dbg)
+ {
+ 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 RELOC */
if ((sec_flags & SEC_CODE) != 0)
styp_flags |= IMAGE_SCN_CNT_CODE;
- if ((sec_flags & SEC_DATA) != 0)
+ if ((sec_flags & (SEC_DATA | SEC_DEBUGGING)) != 0)
styp_flags |= IMAGE_SCN_CNT_INITIALIZED_DATA;
if ((sec_flags & SEC_ALLOC) != 0 && (sec_flags & SEC_LOAD) == 0)
styp_flags |= IMAGE_SCN_CNT_UNINITIALIZED_DATA; /* ==STYP_BSS */
styp_flags |= IMAGE_SCN_LNK_COMDAT;
if ((sec_flags & SEC_DEBUGGING) != 0)
styp_flags |= IMAGE_SCN_MEM_DISCARDABLE;
- if ((sec_flags & SEC_EXCLUDE) != 0)
+ if ((sec_flags & SEC_EXCLUDE) != 0 && !is_dbg)
styp_flags |= IMAGE_SCN_LNK_REMOVE;
- if ((sec_flags & SEC_NEVER_LOAD) != 0)
+ if ((sec_flags & SEC_NEVER_LOAD) != 0 && !is_dbg)
styp_flags |= IMAGE_SCN_LNK_REMOVE;
/* skip IN_MEMORY */
/* 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
#ifdef COFF_LONG_SECTION_NAMES
|| CONST_STRNEQ (name, GNU_LINKONCE_WI)
+ || CONST_STRNEQ (name, GNU_LINKONCE_WT)
#endif
|| CONST_STRNEQ (name, ".stab"))
{
if (! ((isym.n_sclass == C_STAT
|| isym.n_sclass == C_EXT)
- && isym.n_type == T_NULL
+ && BTYPE (isym.n_type) == T_NULL
&& isym.n_value == 0))
abort ();
amt = sizeof (struct coff_comdat_info);
coff_section_data (abfd, section)->comdat
- = bfd_alloc (abfd, amt);
+ = (struct coff_comdat_info *) bfd_alloc (abfd, amt);
if (coff_section_data (abfd, section)->comdat == NULL)
abort ();
(esym - esymstart) / bfd_coff_symesz (abfd);
amt = strlen (symname) + 1;
- newname = bfd_alloc (abfd, amt);
+ newname = (char *) bfd_alloc (abfd, amt);
if (newname == NULL)
abort ();
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)
+#endif
+ || CONST_STRNEQ (name, ".stab"))
+ is_dbg = TRUE;
/* Assume read only unless IMAGE_SCN_MEM_WRITE is specified. */
sec_flags = SEC_READONLY;
mean that a given section contains debug information. Thus
we only set the SEC_DEBUGGING flag on sections that we
recognise as containing debug information. */
- if (CONST_STRNEQ (name, DOT_DEBUG)
+ if (is_dbg
#ifdef _COMMENT
|| strcmp (name, _COMMENT) == 0
#endif
-#ifdef COFF_LONG_SECTION_NAMES
- || CONST_STRNEQ (name, GNU_LINKONCE_WI)
-#endif
- || CONST_STRNEQ (name, ".stab"))
- sec_flags |= SEC_DEBUGGING;
+ )
+ {
+ sec_flags |= SEC_DEBUGGING | SEC_READONLY;
+ }
break;
case IMAGE_SCN_MEM_SHARED:
sec_flags |= SEC_COFF_SHARED;
break;
case IMAGE_SCN_LNK_REMOVE:
- sec_flags |= SEC_EXCLUDE;
+ if (!is_dbg)
+ sec_flags |= SEC_EXCLUDE;
break;
case IMAGE_SCN_CNT_CODE:
sec_flags |= SEC_CODE | SEC_ALLOC | SEC_LOAD;
break;
case IMAGE_SCN_CNT_INITIALIZED_DATA:
- sec_flags |= SEC_DATA | SEC_ALLOC | SEC_LOAD;
+ if (is_dbg)
+ sec_flags |= SEC_DEBUGGING;
+ else
+ sec_flags |= SEC_DATA | SEC_ALLOC | SEC_LOAD;
break;
case IMAGE_SCN_CNT_UNINITIALIZED_DATA:
sec_flags |= SEC_ALLOC;
. 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 *);
. ((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))
.
{
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. */
@@ The 10 is a guess at a plausible maximum number of aux entries
(but shouldn't be a constant). */
amt = sizeof (combined_entry_type) * 10;
- native = bfd_zalloc (abfd, amt);
+ native = (combined_entry_type *) bfd_zalloc (abfd, amt);
if (native == NULL)
return FALSE;
for n_numaux is already correct. */
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;
file_ptr oldpos = bfd_tell (abfd);
bfd_size_type relsz = bfd_coff_relsz (abfd);
- bfd_seek (abfd, (file_ptr) hdr->s_relptr, 0);
+ if (bfd_seek (abfd, (file_ptr) hdr->s_relptr, 0) != 0)
+ return;
if (bfd_bread (& dst, relsz, abfd) != relsz)
return;
coff_swap_reloc_in (abfd, &dst, &n);
- bfd_seek (abfd, oldpos, 0);
+ if (bfd_seek (abfd, oldpos, 0) != 0)
+ return;
section->reloc_count = hdr->s_nreloc = n.r_vaddr - 1;
section->rel_filepos += relsz;
}
abfd->flags |= HAS_DEBUG;
#endif
+ if ((internal_f->f_flags & F_GO32STUB) != 0)
+ coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE);
+ if (coff->go32stub != NULL)
+ memcpy (coff->go32stub, internal_f->go32stub, GO32_STUBSIZE);
+
return coff;
}
#endif
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;
machine = bfd_mach_m68020;
break;
#endif
-#ifdef MAXQ20MAGIC
- case MAXQ20MAGIC:
- arch = bfd_arch_maxq;
- switch (internal_f->f_flags & F_MACHMASK)
- {
- case F_MAXQ10:
- machine = bfd_mach_maxq10;
- break;
- case F_MAXQ20:
- machine = bfd_mach_maxq20;
- break;
- default:
- return FALSE;
- }
- break;
-#endif
#ifdef MC88MAGIC
case MC88MAGIC:
case MC88DMAGIC:
unsigned int indaux,
combined_entry_type *aux)
{
- int class = symbol->u.syment.n_sclass;
+ int n_sclass = symbol->u.syment.n_sclass;
- if (CSECT_SYM_P (class)
+ if (CSECT_SYM_P (n_sclass)
&& indaux + 1 == symbol->u.syment.n_numaux)
{
if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) == XTY_LD)
entries know which symbol index they point to. So we
have to look up the output symbol here. */
- if (q->sym_ptr_ptr[0]->the_bfd != abfd)
+ if (q->sym_ptr_ptr[0] != NULL && q->sym_ptr_ptr[0]->the_bfd != abfd)
{
int j;
const char *sname = q->sym_ptr_ptr[0]->name;
n.r_symndx = q->addend;
else
#endif
- if (q->sym_ptr_ptr)
+ if (q->sym_ptr_ptr && q->sym_ptr_ptr[0] != NULL)
{
#ifdef SECTION_RELATIVE_ABSOLUTE_SYMBOL_P
if (SECTION_RELATIVE_ABSOLUTE_SYMBOL_P (q, s))
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
-
-#ifdef MAXQ20MAGIC
- case bfd_arch_maxq:
- * magicp = MAXQ20MAGIC;
- switch (bfd_get_mach (abfd))
- {
- case bfd_mach_maxq10: * flagsp = F_MAXQ10; return TRUE;
- case bfd_mach_maxq20: * flagsp = F_MAXQ20; return TRUE;
- default: return FALSE;
- }
-#endif
-
default: /* Unknown architecture. */
/* Fall through to "return FALSE" below, to avoid
"statement never reached" errors on the one below. */
coff_compute_section_file_positions (bfd * abfd)
{
asection *current;
- asection *previous = NULL;
file_ptr sofar = bfd_coff_filhsz (abfd);
bfd_boolean align_adjust;
+ unsigned int target_index;
#ifdef ALIGN_SECTIONS_IN_FILE
+ asection *previous = NULL;
file_ptr old_sofar;
#endif
+#ifdef COFF_IMAGE_WITH_PE
+ int page_size;
+
+ if (coff_data (abfd)->link_info)
+ {
+ page_size = pe_data (abfd)->pe_opthdr.FileAlignment;
+
+ /* If no file alignment has been set, default to one.
+ This repairs 'ld -r' for arm-wince-pe target. */
+ if (page_size == 0)
+ page_size = 1;
+ }
+ else
+ page_size = PE_DEF_FILE_ALIGNMENT;
+#else
+#ifdef COFF_PAGE_SIZE
+ int page_size = COFF_PAGE_SIZE;
+#endif
+#endif
+
#ifdef RS6000COFF_C
/* On XCOFF, if we have symbols, set up the .debug section. */
if (bfd_get_symcount (abfd) > 0)
}
#endif
-#ifdef COFF_IMAGE_WITH_PE
- int page_size;
-
- if (coff_data (abfd)->link_info)
- {
- page_size = pe_data (abfd)->pe_opthdr.FileAlignment;
-
- /* If no file alignment has been set, default to one.
- This repairs 'ld -r' for arm-wince-pe target. */
- if (page_size == 0)
- page_size = 1;
- }
- else
- page_size = PE_DEF_FILE_ALIGNMENT;
-#else
-#ifdef COFF_PAGE_SIZE
- int page_size = COFF_PAGE_SIZE;
-#endif
-#endif
-
if (bfd_get_start_address (abfd))
/* A start address may have been added to the original file. In this
case it will need an optional header to record it. */
unsigned int count;
asection **section_list;
unsigned int i;
- int target_index;
bfd_size_type amt;
#ifdef COFF_PAGE_SIZE
/* We allocate an extra cell to simplify the final loop. */
amt = sizeof (struct asection *) * (count + 1);
- section_list = bfd_malloc (amt);
+ section_list = (asection **) bfd_malloc (amt);
if (section_list == NULL)
return FALSE;
#else /* ! COFF_IMAGE_WITH_PE */
{
/* Set the target_index field. */
- int target_index;
-
target_index = 1;
for (current = abfd->sections; current != NULL; current = current->next)
current->target_index = target_index++;
}
#endif /* ! COFF_IMAGE_WITH_PE */
+ if (target_index >= bfd_coff_max_nscns (abfd))
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ (*_bfd_error_handler)
+ (_("%B: too many sections (%d)"), abfd, target_index);
+ return FALSE;
+ }
+
align_adjust = FALSE;
for (current = abfd->sections;
current != NULL;
if (!(current->flags & SEC_HAS_CONTENTS))
continue;
+ current->rawsize = current->size;
+
#ifdef COFF_IMAGE_WITH_PE
/* Make sure we skip empty sections in a PE image. */
if (current->size == 0)
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)
#ifdef COFF_IMAGE_WITH_PE
/* Set the padded size. */
- current->size = (current->size + page_size -1) & -page_size;
+ current->size = (current->size + page_size - 1) & -page_size;
#endif
sofar += current->size;
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
previous = current;
+#endif
}
/* It is now safe to write to the output file. If we needed an
asection *current;
bfd_boolean hasrelocs = FALSE;
bfd_boolean haslinno = FALSE;
+#ifdef COFF_IMAGE_WITH_PE
bfd_boolean hasdebug = FALSE;
+#endif
file_ptr scn_base;
file_ptr reloc_base;
file_ptr lineno_base;
current = current->next)
{
struct internal_scnhdr section;
+#ifdef COFF_IMAGE_WITH_PE
bfd_boolean is_reloc_section = FALSE;
-#ifdef COFF_IMAGE_WITH_PE
if (strcmp (current->name, DOT_RELOC) == 0)
{
is_reloc_section = TRUE;
#endif
if (current->lineno_count != 0)
haslinno = TRUE;
+#ifdef COFF_IMAGE_WITH_PE
if ((current->flags & SEC_DEBUGGING) != 0
&& ! is_reloc_section)
hasdebug = TRUE;
+#endif
#ifdef RS6000COFF_C
#ifndef XCOFF64
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
-
-#ifdef MAXQ20MAGIC
-#define __A_MAGIC_SET__
- internal_a.magic = MAXQ20MAGIC;
-#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;
char * buff;
bfd_size_type amount = bfd_coff_filhsz (abfd);
- buff = bfd_malloc (amount);
+ buff = (char *) bfd_malloc (amount);
if (buff == NULL)
return FALSE;
char * buff;
bfd_size_type amount = bfd_coff_aoutsz (abfd);
- buff = bfd_malloc (amount);
+ buff = (char *) bfd_malloc (amount);
if (buff == NULL)
return FALSE;
BFD_ASSERT (asect->lineno == NULL);
amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent);
- lineno_cache = bfd_alloc (abfd, amt);
+ lineno_cache = (alent *) bfd_alloc (abfd, amt);
if (lineno_cache == NULL)
return FALSE;
{
(*_bfd_error_handler)
(_("%B: warning: illegal symbol index %ld in line numbers"),
- abfd, dst.l_addr.l_symndx);
+ abfd, (long) symndx);
symndx = 0;
warned = TRUE;
}
alent *n_lineno_cache;
/* Create a table of functions. */
- func_table = bfd_alloc (abfd, nbr_func * sizeof (alent *));
+ func_table = (alent **) bfd_alloc (abfd, nbr_func * sizeof (alent *));
if (func_table != NULL)
{
alent **p = func_table;
/* Create the new sorted table. */
amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent);
- n_lineno_cache = bfd_alloc (abfd, amt);
+ n_lineno_cache = (alent *) bfd_alloc (abfd, amt);
if (n_lineno_cache != NULL)
{
alent *n_cache_ptr = n_lineno_cache;
/* Allocate enough room for all the symbols in cached form. */
amt = obj_raw_syment_count (abfd);
amt *= sizeof (coff_symbol_type);
- cached_area = bfd_alloc (abfd, amt);
+ cached_area = (coff_symbol_type *) bfd_alloc (abfd, amt);
if (cached_area == NULL)
return FALSE;
amt = obj_raw_syment_count (abfd);
amt *= sizeof (unsigned int);
- table_ptr = bfd_alloc (abfd, amt);
+ table_ptr = (unsigned int *) bfd_alloc (abfd, amt);
if (table_ptr == NULL)
return FALSE;
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)
to the symbol instead of the index. FIXME: This
should use a union. */
src->u.syment.n_value =
- (long) (native_symbols + src->u.syment.n_value);
+ (long) (intptr_t) (native_symbols + src->u.syment.n_value);
dst->symbol.value = src->u.syment.n_value;
src->fix_value = 1;
break;
&& src->u.syment.n_value == 0
&& src->u.syment.n_scnum == 0)
break;
+#ifdef RS6000COFF_C
+ /* XCOFF specific: deleted entry. */
+ if (src->u.syment.n_value == C_NULL_VALUE)
+ break;
+#endif
/* Fall through. */
case C_EXTDEF: /* External definition. */
case C_ULABEL: /* Undefined label. */
amt = (bfd_size_type) bfd_coff_relsz (abfd) * asect->reloc_count;
native_relocs = (RELOC *) buy_and_read (abfd, asect->rel_filepos, amt);
amt = (bfd_size_type) asect->reloc_count * sizeof (arelent);
- reloc_cache = bfd_alloc (abfd, amt);
+ reloc_cache = (arelent *) bfd_alloc (abfd, amt);
if (reloc_cache == NULL || native_relocs == NULL)
return FALSE;
{
(*_bfd_error_handler)
(_("%B: warning: illegal symbol index %ld in relocs"),
- abfd, dst.r_symndx);
+ abfd, (long) dst.r_symndx);
cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
ptr = NULL;
}
/* Calculate any reloc addend by looking at the symbol. */
CALC_ADDEND (abfd, ptr, dst, cache_ptr);
+ (void) ptr;
cache_ptr->address -= asect->vma;
/* !! cache_ptr->section = NULL;*/
#endif /* ! defined (coff_relocate_section) */
#define coff_bfd_link_just_syms _bfd_generic_link_just_syms
+#define coff_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
#define coff_bfd_link_split_section _bfd_generic_link_split_section
#ifndef coff_start_final_link
#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 UUID 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
#define coff_bfd_gc_sections bfd_generic_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
#define coff_bfd_merge_sections bfd_generic_merge_sections
#endif
#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
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, \
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, \
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, \