/* Support for the generic parts of most COFF variants, for BFD.
- Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
Free Software Foundation, Inc.
Written by Cygnus Support.
if (_bfd_coff_get_external_symbols (abfd))
{
bfd_byte *esymstart, *esym, *esymend;
+ int seen_state = 0;
+ char *target_name = NULL;
esymstart = esym = (bfd_byte *) obj_coff_external_syms (abfd);
- esymend = esym + obj_raw_syment_count (abfd) * SYMESZ;
+ esymend = esym + obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd);
while (esym < esymend)
{
abort ();
}
- /* The MS documentation is vague, but it appears to
- require that n_sclass be C_STAT for both entries;
- However, the Alpha compiler uses C_EXT for the one
- with the "real" name, at least for string-pooled
- constants. */
- if (isym.n_scnum == section->target_index
- && (isym.n_sclass == C_STAT || isym.n_sclass == C_EXT)
- && isym.n_type == T_NULL
- && isym.n_value == 0)
+ if (isym.n_scnum == section->target_index)
{
- /* The first TWO entries with the section # are both
- of interest to us. The first one is the "section
+ /* According to the MSVC documentation, the first
+ TWO entries with the section # are both of
+ interest to us. The first one is the "section
symbol" (section name). The second is the comdat
- symbol name. 'value' must be zero for it to
- apply. Here, we've found a qualifying entry; we
- distinguish the first from the second by numaux
- (which should be 0 for the second). FIXME: We
- should use the first one first rather than
- counting on numaux. */
- if (isym.n_numaux == 1)
- {
- union internal_auxent aux;
+ symbol name. Here, we've found the first
+ qualifying entry; we distinguish it from the
+ second with a state flag.
- symname = _bfd_coff_internal_syment_name (abfd, &isym,
- buf);
- if (symname == NULL)
- abort ();
+ In the case of gas-generated (at least until that
+ is fixed) .o files, it isn't necessarily the
+ second one. It may be some other later symbol.
- if (strcmp (name, symname) != 0)
- abort ();
+ Since gas also doesn't follow MS conventions and
+ emits the section similar to .text$<name>, where
+ <something> is the name we're looking for, we
+ distinguish the two as follows:
- /* This is the section symbol. */
+ If the section name is simply a section name (no
+ $) we presume it's MS-generated, and look at
+ precisely the second symbol for the comdat name.
+ If the section name has a $, we assume it's
+ gas-generated, and look for <something> (whatever
+ follows the $) as the comdat symbol. */
- bfd_coff_swap_aux_in (abfd, (PTR) (esym + SYMESZ),
- isym.n_type, isym.n_sclass,
- 0, isym.n_numaux, (PTR) &aux);
+ /* All 3 branches use this */
+ symname = _bfd_coff_internal_syment_name (abfd, &isym, buf);
- /* FIXME: Microsoft uses NODUPLICATES and
- ASSOCIATIVE, but gnu uses ANY and SAME_SIZE.
- Unfortunately, gnu doesn't do the comdat
- symbols right. So, until we can fix it to do
- the right thing, we are temporarily disabling
- comdats for the MS types (they're used in
- DLLs and C++, but we don't support *their*
- C++ libraries anyway - DJ. */
+ if (symname == NULL)
+ abort ();
- switch (aux.x_scn.x_comdat)
- {
- case IMAGE_COMDAT_SELECT_NODUPLICATES:
-/* FIXME: This is bogus. It breaks cross-compilers. */
-#ifdef __INTERIX
- sec_flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
+ switch (seen_state)
+ {
+ case 0:
+ {
+ /* The first time we've seen the symbol. */
+ union internal_auxent aux;
+
+ seen_state = 1;
+
+ /* If it isn't the stuff we're expecting, die;
+ The MS documentation is vague, but it
+ appears that the second entry serves BOTH
+ as the comdat symbol and the defining
+ symbol record (either C_STAT or C_EXT,
+ possibly with an aux entry with debug
+ information if it's a function.) It
+ appears the only way to find the second one
+ is to count. (On Intel, they appear to be
+ adjacent, but on Alpha, they have been
+ found separated.)
+
+ Here, we think we've found the first one,
+ but there's some checking we can do to be
+ sure. */
+
+ if (! (isym.n_sclass == C_STAT
+ && isym.n_type == T_NULL
+ && isym.n_value == 0))
+ abort ();
+
+ /* FIXME LATER: MSVC generates section names
+ like .text for comdats. Gas generates
+ names like .text$foo__Fv (in the case of a
+ function). See comment above for more. */
+
+ if (strcmp (name, symname) != 0)
+ abort ();
+
+ /* This is the section symbol. */
+
+ bfd_coff_swap_aux_in (abfd, (PTR) (esym + bfd_coff_symesz (abfd)),
+ isym.n_type, isym.n_sclass,
+ 0, isym.n_numaux, (PTR) &aux);
+
+ target_name = strchr (name, '$');
+ if (target_name != NULL)
+ {
+ /* Gas mode. */
+ seen_state = 2;
+ /* Skip the `$'. */
+ target_name += 1;
+ }
+
+ /* FIXME: Microsoft uses NODUPLICATES and
+ ASSOCIATIVE, but gnu uses ANY and
+ SAME_SIZE. Unfortunately, gnu doesn't do
+ the comdat symbols right. So, until we can
+ fix it to do the right thing, we are
+ temporarily disabling comdats for the MS
+ types (they're used in DLLs and C++, but we
+ don't support *their* C++ libraries anyway
+ - DJ. */
+
+ /* Cygwin does not follow the MS style, and
+ uses ANY and SAME_SIZE where NODUPLICATES
+ and ASSOCIATIVE should be used. For
+ Interix, we just do the right thing up
+ front. */
+
+ switch (aux.x_scn.x_comdat)
+ {
+ case IMAGE_COMDAT_SELECT_NODUPLICATES:
+#ifdef STRICT_PE_FORMAT
+ sec_flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
+#else
+ sec_flags &= ~SEC_LINK_ONCE;
+#endif
+ break;
+
+ case IMAGE_COMDAT_SELECT_ANY:
+ sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
+ break;
+
+ case IMAGE_COMDAT_SELECT_SAME_SIZE:
+ sec_flags |= SEC_LINK_DUPLICATES_SAME_SIZE;
+ break;
+
+ case IMAGE_COMDAT_SELECT_EXACT_MATCH:
+ /* Not yet fully implemented ??? */
+ sec_flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS;
+ break;
+
+ /* debug$S gets this case; other
+ implications ??? */
+
+ /* There may be no symbol... we'll search
+ the whole table... Is this the right
+ place to play this game? Or should we do
+ it when reading it in. */
+ case IMAGE_COMDAT_SELECT_ASSOCIATIVE:
+#ifdef STRICT_PE_FORMAT
+ /* FIXME: This is not currently implemented. */
+ sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
#else
- sec_flags &= ~SEC_LINK_ONCE;
+ sec_flags &= ~SEC_LINK_ONCE;
#endif
- break;
-
- case IMAGE_COMDAT_SELECT_ANY:
- sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
- break;
+ break;
- case IMAGE_COMDAT_SELECT_SAME_SIZE:
- sec_flags |= SEC_LINK_DUPLICATES_SAME_SIZE;
- break;
+ default: /* 0 means "no symbol" */
+ /* debug$F gets this case; other
+ implications ??? */
+ sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
+ break;
+ }
+ }
+ break;
- case IMAGE_COMDAT_SELECT_EXACT_MATCH:
- /* Not yet fully implemented in the linker. */
- sec_flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS;
- break;
+ case 2:
+ /* Gas mode: the first matching on partial name. */
- case IMAGE_COMDAT_SELECT_ASSOCIATIVE:
-/* FIXME: This is bogus. It breaks cross-compilers. */
-#ifdef __INTERIX
- /* FIXME: This is not currently implemented. */
- sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
-#else
- sec_flags &= ~SEC_LINK_ONCE;
+#ifndef TARGET_UNDERSCORE
+#define TARGET_UNDERSCORE 0
#endif
- break;
-
- default:
- /* FIXME: Shouldn't this be at least a
- warning? */
- sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
- break;
+ /* Is this the name we're looking for? */
+ if (strcmp (target_name,
+ symname + (TARGET_UNDERSCORE ? 1 : 0)) != 0)
+ {
+ /* Not the name we're looking for */
+ esym += (isym.n_numaux + 1) * bfd_coff_symesz (abfd);
+ continue;
}
- }
- else
- {
- char *newname;
-
- /* This should be the the second symbol with the
- section #. It is the actual symbol name.
- Intel puts the two adjacent, but Alpha (at
- least) spreads them out. */
-
- section->comdat =
- bfd_alloc (abfd, sizeof (struct bfd_comdat_info));
- if (section->comdat == NULL)
- abort ();
- section->comdat->symbol = (esym - esymstart) / SYMESZ;
- symname = _bfd_coff_internal_syment_name (abfd, &isym,
- buf);
- if (symname == NULL)
- abort ();
-
- newname = bfd_alloc (abfd, strlen (symname) + 1);
- if (newname == NULL)
- abort ();
- strcpy (newname, symname);
- section->comdat->name = newname;
-
- break;
+ /* Fall through. */
+ case 1:
+ /* MSVC mode: the lexically second symbol (or
+ drop through from the above). */
+ {
+ char *newname;
+
+ /* This must the the second symbol with the
+ section #. It is the actual symbol name.
+ Intel puts the two adjacent, but Alpha (at
+ least) spreads them out. */
+
+ section->comdat =
+ bfd_alloc (abfd, sizeof (struct bfd_comdat_info));
+ if (section->comdat == NULL)
+ abort ();
+ section->comdat->symbol =
+ (esym - esymstart) / bfd_coff_symesz (abfd);
+
+ newname = bfd_alloc (abfd, strlen (symname) + 1);
+ if (newname == NULL)
+ abort ();
+
+ strcpy (newname, symname);
+ section->comdat->name = newname;
+
+ }
+
+ goto breakloop;
}
}
- esym += (isym.n_numaux + 1) * SYMESZ;
+ esym += (isym.n_numaux + 1) * bfd_coff_symesz (abfd);
}
+ breakloop:
}
}
. unsigned int _bfd_auxesz;
. unsigned int _bfd_relsz;
. unsigned int _bfd_linesz;
+. unsigned int _bfd_filnmlen;
. boolean _bfd_coff_long_filenames;
. boolean _bfd_coff_long_section_names;
. unsigned int _bfd_coff_default_section_alignment_power;
.#define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz)
.#define bfd_coff_relsz(abfd) (coff_backend_info (abfd)->_bfd_relsz)
.#define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz)
+.#define bfd_coff_filnmlen(abfd) (coff_backend_info (abfd)->_bfd_filnmlen)
.#define bfd_coff_long_filenames(abfd) (coff_backend_info (abfd)->_bfd_coff_long_filenames)
.#define bfd_coff_long_section_names(abfd) \
. (coff_backend_info (abfd)->_bfd_coff_long_section_names)
*/
#if defined(M88) || defined(I960)
- if (internal_f->f_opthdr != 0 && AOUTSZ != internal_f->f_opthdr)
+ if (internal_f->f_opthdr != 0 && bfd_coff_aoutsz (abfd) != internal_f->f_opthdr)
return false;
#endif
ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_2BYTES, 1)
ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_1BYTES, 0)
-#ifdef POWERPC_LE_PE
- if (strcmp (section->name, ".idata$2") == 0)
- {
- section->alignment_power = 0;
- }
- else if (strcmp (section->name, ".idata$3") == 0)
- {
- section->alignment_power = 0;
- }
- else if (strcmp (section->name, ".idata$4") == 0)
- {
- section->alignment_power = 2;
- }
- else if (strcmp (section->name, ".idata$5") == 0)
- {
- section->alignment_power = 2;
- }
- else if (strcmp (section->name, ".idata$6") == 0)
- {
- section->alignment_power = 1;
- }
- else if (strcmp (section->name, ".reloc") == 0)
- {
- section->alignment_power = 1;
- }
- else if (strncmp (section->name, ".stab", 5) == 0)
- {
- section->alignment_power = 2;
- }
-#endif
-
/* In a PE image file, the s_paddr field holds the virtual size of a
section, while the s_size field holds the raw size. We also keep
the original section flag value, since not every bit can be
coff->local_n_btshft = N_BTSHFT;
coff->local_n_tmask = N_TMASK;
coff->local_n_tshift = N_TSHIFT;
- coff->local_symesz = SYMESZ;
- coff->local_auxesz = AUXESZ;
- coff->local_linesz = LINESZ;
+ coff->local_symesz = bfd_coff_symesz (abfd);
+ coff->local_auxesz = bfd_coff_auxesz (abfd);
+ coff->local_linesz = bfd_coff_linesz (abfd);
+
+ coff->timestamp = internal_f->f_timdat;
obj_raw_syment_count (abfd) =
obj_conv_table_size (abfd) =
#ifdef RS6000COFF_C
if ((internal_f->f_flags & F_SHROBJ) != 0)
abfd->flags |= DYNAMIC;
- if (aouthdr != NULL && internal_f->f_opthdr >= AOUTSZ)
+ if (aouthdr != NULL && internal_f->f_opthdr >= bfd_coff_aoutsz (abfd))
{
struct internal_aouthdr *internal_a =
(struct internal_aouthdr *) aouthdr;
coff->flags = 0;
#endif
+#ifdef COFF_WITH_PE
+ /* FIXME: I'm not sure this is ever executed, since peicode.h
+ defines coff_mkobject_hook. */
+ if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0)
+ abfd->flags |= HAS_DEBUG;
+#endif
+
return (PTR) coff;
}
#endif
#endif
#ifdef ARMMAGIC
case ARMMAGIC:
+ case ARMPEMAGIC:
+ case THUMBPEMAGIC:
arch = bfd_arch_arm;
switch (internal_f->f_flags & F_ARM_ARCHITECTURE_MASK)
{
cputype = 0;
else
{
- bfd_byte buf[SYMESZ];
+ bfd_byte *buf;
struct internal_syment sym;
+ buf = (bfd_byte *) bfd_malloc (bfd_coff_symesz (abfd));
if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
- || bfd_read (buf, 1, SYMESZ, abfd) != SYMESZ)
- return false;
+ || (bfd_read (buf, 1, bfd_coff_symesz (abfd), abfd)
+ != bfd_coff_symesz (abfd)))
+ {
+ free (buf);
+ return false;
+ }
coff_swap_sym_in (abfd, (PTR) buf, (PTR) &sym);
if (sym.n_sclass == C_FILE)
cputype = sym.n_type & 0xff;
else
cputype = 0;
+ free (buf);
}
}
#ifdef SH_ARCH_MAGIC_BIG
case SH_ARCH_MAGIC_BIG:
case SH_ARCH_MAGIC_LITTLE:
+#ifdef COFF_WITH_PE
+ case SH_ARCH_MAGIC_WINCE:
+#endif
arch = bfd_arch_sh;
machine = 0;
break;
#endif
+#ifdef MIPS_ARCH_MAGIC_WINCE
+ case MIPS_ARCH_MAGIC_WINCE:
+ arch = bfd_arch_mips;
+ machine = 0;
+ break;
+#endif
+
#ifdef H8500MAGIC
case H8500MAGIC:
arch = bfd_arch_h8500;
#endif
if (q->sym_ptr_ptr)
{
+#ifdef SECTION_RELATIVE_ABSOLUTE_SYMBOL_P
+ if (SECTION_RELATIVE_ABSOLUTE_SYMBOL_P (q,s))
+#else
if (q->sym_ptr_ptr == bfd_abs_section_ptr->symbol_ptr_ptr)
+#endif
/* This is a relocation relative to the absolute symbol. */
n.r_symndx = -1;
else
n.r_type = q->howto->type;
#endif
coff_swap_reloc_out (abfd, &n, &dst);
- if (bfd_write ((PTR) & dst, 1, RELSZ, abfd) != RELSZ)
+ if (bfd_write ((PTR) & dst, 1, bfd_coff_relsz (abfd), abfd)
+ != bfd_coff_relsz (abfd))
return false;
}
#endif
#ifdef ARMMAGIC
case bfd_arch_arm:
+#ifdef ARM_WINCE
+ * magicp = ARMPEMAGIC;
+#else
* magicp = ARMMAGIC;
+#endif
* flagsp = 0;
if (APCS_SET (abfd))
{
#ifdef SH_ARCH_MAGIC_BIG
case bfd_arch_sh:
+#ifdef COFF_IMAGE_WITH_PE
+ *magicp = SH_ARCH_MAGIC_WINCE;
+#else
if (bfd_big_endian (abfd))
*magicp = SH_ARCH_MAGIC_BIG;
else
*magicp = SH_ARCH_MAGIC_LITTLE;
+#endif
+ return true;
+ break;
+#endif
+
+#ifdef MIPS_ARCH_MAGIC_WINCE
+ case bfd_arch_mips:
+ *magicp = MIPS_ARCH_MAGIC_WINCE;
return true;
break;
#endif
{
asection *current;
asection *previous = (asection *) NULL;
- file_ptr sofar = FILHSZ;
+ file_ptr sofar = bfd_coff_filhsz (abfd);
boolean align_adjust;
#ifdef ALIGN_SECTIONS_IN_FILE
file_ptr old_sofar;
}
if (abfd->flags & EXEC_P)
- sofar += AOUTSZ;
+ sofar += bfd_coff_aoutsz (abfd);
#ifdef RS6000COFF_C
else if (xcoff_data (abfd)->full_aouthdr)
- sofar += AOUTSZ;
+ sofar += bfd_coff_aoutsz (abfd);
else
sofar += SMALL_AOUTSZ;
#endif
- sofar += abfd->section_count * SCNHSZ;
+ sofar += abfd->section_count * bfd_coff_scnhsz (abfd);
#ifdef RS6000COFF_C
/* XCOFF handles overflows in the reloc and line number count fields
by allocating a new section header to hold the correct counts. */
for (current = abfd->sections; current != NULL; current = current->next)
if (current->reloc_count >= 0xffff || current->lineno_count >= 0xffff)
- sofar += SCNHSZ;
+ sofar += bfd_coff_scnhsz (abfd);
#endif
#ifdef COFF_IMAGE_WITH_PE
asection *current;
boolean hasrelocs = false;
boolean haslinno = false;
+ boolean hasdebug = false;
file_ptr scn_base;
file_ptr reloc_base;
file_ptr lineno_base;
/* Make a pass through the symbol table to count line number entries and
put them into the correct asections */
- lnno_size = coff_count_linenumbers (abfd) * LINESZ;
+ lnno_size = coff_count_linenumbers (abfd) * bfd_coff_linesz (abfd);
if (abfd->output_has_begun == false)
{
for (current = abfd->sections; current != NULL; current =
current->next)
- reloc_size += current->reloc_count * RELSZ;
+ reloc_size += current->reloc_count * bfd_coff_relsz (abfd);
lineno_base = reloc_base + reloc_size;
sym_base = lineno_base + lnno_size;
{
current->line_filepos = lineno_base;
current->moving_line_filepos = lineno_base;
- lineno_base += current->lineno_count * LINESZ;
+ lineno_base += current->lineno_count * bfd_coff_linesz (abfd);
}
else
{
if (current->reloc_count)
{
current->rel_filepos = reloc_base;
- reloc_base += current->reloc_count * RELSZ;
+ reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
}
else
{
internal_f.f_nscns = 0;
if ((abfd->flags & EXEC_P) != 0)
- scn_base = FILHSZ + AOUTSZ;
+ scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
else
{
- scn_base = FILHSZ;
+ scn_base = bfd_coff_filhsz (abfd);
#ifdef RS6000COFF_C
if (xcoff_data (abfd)->full_aouthdr)
- scn_base += AOUTSZ;
+ scn_base += bfd_coff_aoutsz (abfd);
else
scn_base += SMALL_AOUTSZ;
#endif
current = current->next)
{
struct internal_scnhdr section;
-
-#ifdef COFF_WITH_PE
- /* If we've got a .reloc section, remember. */
+ boolean is_reloc_section = false;
#ifdef COFF_IMAGE_WITH_PE
if (strcmp (current->name, ".reloc") == 0)
{
+ is_reloc_section = true;
+ hasrelocs = true;
pe_data (abfd)->has_reloc_section = 1;
}
#endif
-#endif
internal_f.f_nscns++;
strncpy (section.s_name, current->name, SCNNMLEN);
section.s_lnnoptr = current->line_filepos;
section.s_nreloc = current->reloc_count;
section.s_nlnno = current->lineno_count;
+#ifndef COFF_IMAGE_WITH_PE
+ /* In PEI, relocs come in the .reloc section. */
if (current->reloc_count != 0)
hasrelocs = true;
+#endif
if (current->lineno_count != 0)
haslinno = true;
+ if ((current->flags & SEC_DEBUGGING) != 0
+ && ! is_reloc_section)
+ hasdebug = true;
#ifdef RS6000COFF_C
/* Indicate the use of an XCOFF overflow section header. */
{
SCNHDR buff;
if (coff_swap_scnhdr_out (abfd, §ion, &buff) == 0
- || bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ)
+ || bfd_write ((PTR) (&buff), 1, bfd_coff_scnhsz (abfd), abfd)
+ != bfd_coff_scnhsz (abfd))
return false;
}
scnhdr.s_nlnno = current->target_index;
scnhdr.s_flags = STYP_OVRFLO;
if (coff_swap_scnhdr_out (abfd, &scnhdr, &buff) == 0
- || bfd_write ((PTR) &buff, 1, SCNHSZ, abfd) != SCNHSZ)
+ || bfd_write ((PTR) &buff, 1, bfd_coff_scnhsz (abfd), abfd)
+ != bfd_coff_scnhsz (abfd))
return false;
}
}
internal_f.f_flags = 0;
if (abfd->flags & EXEC_P)
- internal_f.f_opthdr = AOUTSZ;
+ internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
else
{
internal_f.f_opthdr = 0;
#ifdef RS6000COFF_C
if (xcoff_data (abfd)->full_aouthdr)
- internal_f.f_opthdr = AOUTSZ;
+ internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
else
internal_f.f_opthdr = SMALL_AOUTSZ;
#endif
internal_f.f_flags |= F_LNNO;
if (abfd->flags & EXEC_P)
internal_f.f_flags |= F_EXEC;
+#ifdef COFF_IMAGE_WITH_PE
+ if (! hasdebug)
+ internal_f.f_flags |= IMAGE_FILE_DEBUG_STRIPPED;
+#endif
#ifndef COFF_WITH_PE
if (bfd_little_endian (abfd))
RS6K_AOUTHDR_OMAGIC;
#endif
+#if defined(SH) && defined(COFF_WITH_PE)
+#define __A_MAGIC_SET__
+ internal_a.magic = SH_PE_MAGIC;
+#endif
+
+#if defined(MIPS) && defined(COFF_WITH_PE)
+#define __A_MAGIC_SET__
+ internal_a.magic = MIPS_PE_MAGIC;
+#endif
+
#ifndef __A_MAGIC_SET__
#include "Your aouthdr magic number is not being set!"
#else
/* now write them */
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
return false;
+
{
- char buff[FILHSZ];
+ char * buff;
+ bfd_size_type amount;
+
+ buff = bfd_malloc (bfd_coff_filhsz (abfd));
+ if (buff == NULL)
+ return false;
+
coff_swap_filehdr_out (abfd, (PTR) & internal_f, (PTR) buff);
- if (bfd_write ((PTR) buff, 1, FILHSZ, abfd) != FILHSZ)
+ amount = bfd_write ((PTR) buff, 1, bfd_coff_filhsz (abfd), abfd);
+
+ free (buff);
+
+ if (amount != bfd_coff_filhsz (abfd))
return false;
}
+
if (abfd->flags & EXEC_P)
{
/* Note that peicode.h fills in a PEAOUTHDR, not an AOUTHDR.
include/coff/pe.h sets AOUTSZ == sizeof(PEAOUTHDR)) */
- char buff[AOUTSZ];
+ char * buff;
+ bfd_size_type amount;
+
+ buff = bfd_malloc (bfd_coff_aoutsz (abfd));
+ if (buff == NULL)
+ return false;
+
coff_swap_aouthdr_out (abfd, (PTR) & internal_a, (PTR) buff);
- if (bfd_write ((PTR) buff, 1, AOUTSZ, abfd) != AOUTSZ)
+ amount = bfd_write ((PTR) buff, 1, bfd_coff_aoutsz (abfd), abfd);
+
+ free (buff);
+
+ if (amount != bfd_coff_aoutsz (abfd))
return false;
}
#ifdef RS6000COFF_C
/* XCOFF seems to always write at least a small a.out header. */
coff_swap_aouthdr_out (abfd, (PTR) &internal_a, (PTR) &buff);
if (xcoff_data (abfd)->full_aouthdr)
- size = AOUTSZ;
+ size = bfd_coff_aoutsz (abfd);
else
size = SMALL_AOUTSZ;
if (bfd_write ((PTR) &buff, 1, size, abfd) != size)
native_lineno = (LINENO *) buy_and_read (abfd,
asect->line_filepos,
SEEK_SET,
- (size_t) (LINESZ *
+ (size_t) (bfd_coff_linesz (abfd) *
asect->lineno_count));
lineno_cache =
(alent *) bfd_alloc (abfd, (size_t) ((asect->lineno_count + 1) * sizeof (alent)));
for (sec = abfd->sections; sec != NULL; sec = sec->next)
if (sec->line_filepos <= (file_ptr) src->u.syment.n_value
&& ((file_ptr) (sec->line_filepos
- + sec->lineno_count * LINESZ)
+ + sec->lineno_count * bfd_coff_linesz (abfd))
> (file_ptr) src->u.syment.n_value))
break;
if (sec == NULL)
dst->symbol.section = sec;
dst->symbol.value = ((src->u.syment.n_value
- sec->line_filepos)
- / LINESZ);
+ / bfd_coff_linesz (abfd));
src->fix_line = 1;
}
}
#endif
case C_BLOCK: /* ".bb" or ".eb" */
- case C_FCN: /* ".bf" or ".ef" */
+ case C_FCN: /* ".bf" or ".ef" (or PE ".lf") */
case C_EFCN: /* physical end of function */
- dst->symbol.flags = BSF_LOCAL;
#if defined COFF_WITH_PE
/* PE sets the symbol to a value relative to the start
of the section. */
dst->symbol.value = src->u.syment.n_value;
+ if (strcmp (dst->symbol.name, ".bf") != 0)
+ {
+ /* PE uses funny values for .ef and .lf; don't
+ relocate them. */
+ dst->symbol.flags = BSF_DEBUGGING;
+ }
+ else
+ dst->symbol.flags = BSF_DEBUGGING | BSF_DEBUGGING_RELOC;
#else
/* Base the value as an index from the base of the
section. */
+ dst->symbol.flags = BSF_LOCAL;
dst->symbol.value = (src->u.syment.n_value
- dst->symbol.section->vma);
#endif
return COFF_SYMBOL_LOCAL;
}
-#if 0
+#ifdef STRICT_PE_FORMAT
/* This is correct for Microsoft generated objects, but it
breaks gas generated objects. */
(RELOC *) buy_and_read (abfd,
asect->rel_filepos,
SEEK_SET,
- (size_t) (RELSZ *
+ (size_t) (bfd_coff_relsz (abfd) *
asect->reloc_count));
reloc_cache = (arelent *)
bfd_alloc (abfd, (size_t) (asect->reloc_count * sizeof (arelent)));
#define coff_SWAP_scnhdr_in coff_swap_scnhdr_in
#endif
-
-
-static CONST bfd_coff_backend_data bfd_coff_std_swap_table =
+static const bfd_coff_backend_data bfd_coff_std_swap_table =
{
coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in,
coff_SWAP_aux_out, coff_SWAP_sym_out,
coff_SWAP_lineno_out, coff_SWAP_reloc_out,
coff_SWAP_filehdr_out, coff_SWAP_aouthdr_out,
coff_SWAP_scnhdr_out,
- FILHSZ, AOUTSZ, SCNHSZ, SYMESZ, AUXESZ, RELSZ, LINESZ,
+ FILHSZ, AOUTSZ, SCNHSZ, SYMESZ, AUXESZ, RELSZ, LINESZ, FILNMLEN,
#ifdef COFF_LONG_FILENAMES
true,
#else