/* 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
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Written by Cygnus Support.
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
+ information can be used by a client of the BFD library when deciding
+ what output format to generate, and means that a BFD that is opened
+ for read and subsequently converted to a writeable BFD and modified
+ in-place will retain whatever format it had on input.
If @code{COFF_LONG_SECTION_NAMES} is simply defined (blank), or is
defined to the value "1", then long section names are enabled by
*/
+#include "libiberty.h"
+
#ifdef COFF_WITH_PE
#include "peicode.h"
#else
#define DOT_DEBUG ".debug"
#define GNU_LINKONCE_WI ".gnu.linkonce.wi."
+#define DOT_RELOC ".reloc"
#if defined (COFF_LONG_SECTION_NAMES)
/* Needed to expand the inputs to BLANKOR1TOODD. */
but there's some checking we can do to be
sure. */
- if (! (isym.n_sclass == C_STAT
+ if (! ((isym.n_sclass == C_STAT
+ || isym.n_sclass == C_EXT)
&& isym.n_type == T_NULL
&& isym.n_value == 0))
abort ();
names like .text$foo__Fv (in the case of a
function). See comment above for more. */
- if (strcmp (name, symname) != 0)
+ if (isym.n_sclass == C_STAT && strcmp (name, symname) != 0)
_bfd_error_handler (_("%B: warning: COMDAT symbol '%s' does not match section name '%s'"),
abfd, symname, name);
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 ();
.#define bfd_coff_print_pdata(a,p) \
. ((coff_backend_info (a)->_bfd_coff_print_pdata) (a, p))
.
+.{* Macro: Returns true if the bfd is a PE executable as opposed to a
+. PE object file. *}
+.#define bfd_pei_p(abfd) \
+. (CONST_STRNEQ ((abfd)->xvec->name, "pei-"))
*/
/* See whether the magic number matches. */
@@ 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;
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
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))
asection *previous = NULL;
file_ptr sofar = bfd_coff_filhsz (abfd);
bfd_boolean align_adjust;
+ int target_index;
#ifdef ALIGN_SECTIONS_IN_FILE
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
+ /* Clear D_PAGED if section alignment is smaller than
+ COFF_PAGE_SIZE. */
+ if (pe_data (abfd)->pe_opthdr.SectionAlignment < COFF_PAGE_SIZE)
+ abfd->flags &= ~D_PAGED;
+#endif
+
count = 0;
for (current = abfd->sections; current != NULL; current = current->next)
++count;
/* 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 >= 32768)
+ {
+ 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;
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, ".reloc") == 0)
+ if (strcmp (current->name, DOT_RELOC) == 0)
{
is_reloc_section = TRUE;
hasrelocs = 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
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;
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;
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;
#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
_bfd_generic_section_already_linked
#endif
+#ifndef coff_bfd_define_common_symbol
+#define coff_bfd_define_common_symbol bfd_generic_define_common_symbol
+#endif
+
#define CREATE_BIG_COFF_TARGET_VEC(VAR, NAME, EXTRA_O_FLAGS, EXTRA_S_FLAGS, UNDER, ALTERNATIVE, SWAP_TABLE) \
const bfd_target VAR = \
{ \