* coff-mips.c (ecoff_mkobject_hook): Mark ZMAGIC files as D_PAGED.

(ecoff_write_object_contents): If not D_PAGED, don't add the
	section headers to text_size.  If not D_PAGED, set the magic
	number to OMAGIC rather than ZMAGIC.  If creating a D_PAGED
	executable, the executable must fully occupy an even number of
	pages.
	(ecoff_set_symbol_info, make_bfd_asection, ecoff_little_vec,
	ecoff_big_vec): Consistently set section alignment power to 4,
	since ECOFF sections should be multiples of 16 bytes.
	(ecoff_little_vec, ecoff_big_vec): Added D_PAGED to object_flags.
	Made ar_pad_char and ar_max_namelen agree for both.
This commit is contained in:
Ian Lance Taylor 1993-06-09 22:08:13 +00:00
parent a058c1e807
commit de17306e90
2 changed files with 498 additions and 200 deletions

View file

@ -1,3 +1,17 @@
Wed Jun 9 15:00:01 1993 Ian Lance Taylor (ian@cygnus.com)
* coff-mips.c (ecoff_mkobject_hook): Mark ZMAGIC files as D_PAGED.
(ecoff_write_object_contents): If not D_PAGED, don't add the
section headers to text_size. If not D_PAGED, set the magic
number to OMAGIC rather than ZMAGIC. If creating a D_PAGED
executable, the executable must fully occupy an even number of
pages.
(ecoff_set_symbol_info, make_bfd_asection, ecoff_little_vec,
ecoff_big_vec): Consistently set section alignment power to 4,
since ECOFF sections should be multiples of 16 bytes.
(ecoff_little_vec, ecoff_big_vec): Added D_PAGED to object_flags.
Made ar_pad_char and ar_max_namelen agree for both.
Tue Jun 8 20:28:02 1993 Mark Eichin (eichin at tweedledumber)
* elfcode.h (elf_slurp_symbol_table): subtract section vma from
@ -10,8 +24,7 @@ Tue Jun 8 12:08:27 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
Tue Jun 8 14:27:56 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
* news.h, config/news.mh: New files.
* hosts/news.h, config/news.mh: New files.
Tue Jun 8 12:08:27 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)

View file

@ -25,6 +25,18 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "seclet.h"
#include "aout/ar.h"
#include "aout/ranlib.h"
/* FIXME: We need the definitions of N_SET[ADTB], but aout64.h defines
some other stuff which we don't want and which conflicts with stuff
we do want. */
#include "libaout.h"
#include "aout/aout64.h"
#undef OMAGIC
#undef ZMAGIC
#undef N_ABS
#undef exec_hdr
#undef obj_sym_filepos
#include "coff/mips.h"
#include "coff/internal.h"
#include "coff/sym.h"
@ -87,7 +99,8 @@ static long ecoff_sec_to_styp_flags PARAMS ((CONST char *name,
static flagword ecoff_styp_to_sec_flags PARAMS ((bfd *abfd, PTR hdr));
static asymbol *ecoff_make_empty_symbol PARAMS ((bfd *abfd));
static void ecoff_set_symbol_info PARAMS ((bfd *abfd, SYMR *ecoff_sym,
asymbol *asym, int ext));
asymbol *asym, int ext,
asymbol **indirect_ptr_ptr));
static boolean ecoff_slurp_symbol_table PARAMS ((bfd *abfd));
static unsigned int ecoff_get_symtab_upper_bound PARAMS ((bfd *abfd));
static unsigned int ecoff_get_symtab PARAMS ((bfd *abfd,
@ -100,6 +113,9 @@ static char *ecoff_type_to_string PARAMS ((bfd *abfd, union aux_ext *aux_ptr,
static void ecoff_print_symbol PARAMS ((bfd *abfd, PTR filep,
asymbol *symbol,
bfd_print_symbol_type how));
static void ecoff_get_symbol_info PARAMS ((bfd *abfd,
asymbol *symbol,
symbol_info *ret));
static void ecoff_swap_reloc_in PARAMS ((bfd *abfd, RELOC *ext,
struct internal_reloc *intern));
static unsigned int ecoff_swap_reloc_out PARAMS ((bfd *abfd, PTR src,
@ -194,6 +210,147 @@ static bfd_target *ecoff_archive_p PARAMS ((bfd *abfd));
#define coff_swap_scnhdr_out ecoff_swap_scnhdr_out
#include "coffswap.h"
/* How to process the various relocs types. */
static reloc_howto_type ecoff_howto_table[] =
{
/* Reloc type 0 is ignored. The reloc reading code ensures that
this is a reference to the .abs section, which will cause
bfd_perform_relocation to do nothing. */
HOWTO (ECOFF_R_IGNORE, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
false, /* complain_on_overflow */
0, /* special_function */
"IGNORE", /* name */
false, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
false), /* pcrel_offset */
/* A 16 bit reference to a symbol, normally from a data section. */
HOWTO (ECOFF_R_REFHALF, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
true, /* complain_on_overflow */
ecoff_generic_reloc, /* special_function */
"REFHALF", /* name */
true, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A 32 bit reference to a symbol, normally from a data section. */
HOWTO (ECOFF_R_REFWORD, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
true, /* complain_on_overflow */
ecoff_generic_reloc, /* special_function */
"REFWORD", /* name */
true, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
false), /* pcrel_offset */
/* A 26 bit absolute jump address. */
HOWTO (ECOFF_R_JMPADDR, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
true, /* complain_on_overflow */
ecoff_generic_reloc, /* special_function */
"JMPADDR", /* name */
true, /* partial_inplace */
0x3ffffff, /* src_mask */
0x3ffffff, /* dst_mask */
false), /* pcrel_offset */
/* The high 16 bits of a symbol value. Handled by the function
ecoff_refhi_reloc. */
HOWTO (ECOFF_R_REFHI, /* type */
16, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
true, /* complain_on_overflow */
ecoff_refhi_reloc, /* special_function */
"REFHI", /* name */
true, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* The low 16 bits of a symbol value. */
HOWTO (ECOFF_R_REFLO, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
true, /* complain_on_overflow */
ecoff_reflo_reloc, /* special_function */
"REFLO", /* name */
true, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A reference to an offset from the gp register. Handled by the
function ecoff_gprel_reloc. */
HOWTO (ECOFF_R_GPREL, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
true, /* complain_on_overflow */
ecoff_gprel_reloc, /* special_function */
"GPREL", /* name */
true, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A reference to a literal using an offset from the gp register.
Handled by the function ecoff_gprel_reloc. */
HOWTO (ECOFF_R_LITERAL, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
true, /* complain_on_overflow */
ecoff_gprel_reloc, /* special_function */
"LITERAL", /* name */
true, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false) /* pcrel_offset */
};
#define ECOFF_HOWTO_COUNT \
(sizeof ecoff_howto_table / sizeof ecoff_howto_table[0])
/* This stuff is somewhat copied from coffcode.h. */
static asection bfd_debug_section = { "*DEBUG*" };
@ -307,6 +464,8 @@ ecoff_mkobject_hook (abfd, filehdr, aouthdr)
ecoff->gprmask = internal_a->gprmask;
for (i = 0; i < 4; i++)
ecoff->cprmask[i] = internal_a->cprmask[i];
if (internal_a->magic == ZMAGIC)
abfd->flags |= D_PAGED;
}
return (PTR) ecoff;
@ -631,17 +790,39 @@ ecoff_make_empty_symbol (abfd)
/* Set the BFD flags and section for an ECOFF symbol. */
static void
ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext)
ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, indirect_ptr_ptr)
bfd *abfd;
SYMR *ecoff_sym;
asymbol *asym;
int ext;
asymbol **indirect_ptr_ptr;
{
asym->the_bfd = abfd;
asym->value = ecoff_sym->value;
asym->section = &bfd_debug_section;
asym->udata = NULL;
/* An indirect symbol requires two consecutive stabs symbols. */
if (*indirect_ptr_ptr != (asymbol *) NULL)
{
BFD_ASSERT (MIPS_IS_STAB (ecoff_sym));
(*indirect_ptr_ptr)->value = (bfd_vma) asym;
asym->flags = BSF_DEBUGGING;
asym->section = &bfd_und_section;
*indirect_ptr_ptr = NULL;
return;
}
if (MIPS_IS_STAB (ecoff_sym)
&& (MIPS_UNMARK_STAB (ecoff_sym->index) | N_EXT) == (N_INDR | N_EXT))
{
asym->flags = BSF_DEBUGGING | BSF_INDIRECT;
asym->section = &bfd_ind_section;
/* Pass this symbol on to the next call to this function. */
*indirect_ptr_ptr = asym;
return;
}
/* Most symbol types are just for debugging. */
switch (ecoff_sym->st)
{
@ -781,6 +962,76 @@ ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext)
default:
break;
}
/* Look for special constructors symbols and make relocation entries
in a special construction section. These are produced by the
-fgnu-linker argument to g++. */
if (MIPS_IS_STAB (ecoff_sym))
{
switch (MIPS_UNMARK_STAB (ecoff_sym->index))
{
default:
break;
case N_SETA:
case N_SETT:
case N_SETD:
case N_SETB:
{
const char *name;
asection *section;
arelent_chain *reloc_chain;
/* Get a section with the same name as the symbol (usually
__CTOR_LIST__ or __DTOR_LIST__). FIXME: gcc uses the
name ___CTOR_LIST (three underscores). We need
__CTOR_LIST (two underscores), since ECOFF doesn't use
a leading underscore. This should be handled by gcc,
but instead we do it here. Actually, this should all
be done differently anyhow. */
name = bfd_asymbol_name (asym);
if (name[0] == '_' && name[1] == '_' && name[2] == '_')
{
++name;
asym->name = name;
}
section = bfd_get_section_by_name (abfd, name);
if (section == (asection *) NULL)
{
char *copy;
copy = (char *) bfd_alloc (abfd, strlen (name) + 1);
strcpy (copy, name);
section = bfd_make_section (abfd, copy);
}
/* Build a reloc pointing to this constructor. */
reloc_chain = (arelent_chain *) bfd_alloc (abfd,
sizeof (arelent_chain));
reloc_chain->relent.sym_ptr_ptr =
bfd_get_section (asym)->symbol_ptr_ptr;
reloc_chain->relent.address = section->_raw_size;
reloc_chain->relent.addend = asym->value;
/* FIXME: Assumes 32 bit __CTOR_LIST__ entries. */
reloc_chain->relent.howto = ecoff_howto_table + ECOFF_R_REFWORD;
/* Set up the constructor section to hold the reloc. */
section->flags = SEC_CONSTRUCTOR;
++section->reloc_count;
section->alignment_power = 4;
reloc_chain->next = section->constructor_chain;
section->constructor_chain = reloc_chain;
/* FIXME: Assumes 32 bit __CTOR_LIST__ entries. */
section->_raw_size += 4;
/* Mark the symbol as a constructor. */
asym->flags |= BSF_CONSTRUCTOR;
}
break;
}
}
}
/* Read an ECOFF symbol table. */
@ -792,6 +1043,7 @@ ecoff_slurp_symbol_table (abfd)
bfd_size_type internal_size;
ecoff_symbol_type *internal;
ecoff_symbol_type *internal_ptr;
asymbol *indirect_ptr;
struct ext_ext *eraw_src;
struct ext_ext *eraw_end;
FDR *fdr_ptr;
@ -816,6 +1068,7 @@ ecoff_slurp_symbol_table (abfd)
}
internal_ptr = internal;
indirect_ptr = NULL;
eraw_src = ecoff_data (abfd)->external_ext;
eraw_end = eraw_src + ecoff_data (abfd)->symbolic_header.iextMax;
for (; eraw_src < eraw_end; eraw_src++, internal_ptr++)
@ -826,11 +1079,12 @@ ecoff_slurp_symbol_table (abfd)
internal_ptr->symbol.name = (ecoff_data (abfd)->ssext
+ internal_esym.asym.iss);
ecoff_set_symbol_info (abfd, &internal_esym.asym,
&internal_ptr->symbol, 1);
&internal_ptr->symbol, 1, &indirect_ptr);
internal_ptr->fdr = ecoff_data (abfd)->fdr + internal_esym.ifd;
internal_ptr->local = false;
internal_ptr->native.enative = eraw_src;
}
BFD_ASSERT (indirect_ptr == (asymbol *) NULL);
/* The local symbols must be accessed via the fdr's, because the
string and aux indices are relative to the fdr information. */
@ -852,12 +1106,13 @@ ecoff_slurp_symbol_table (abfd)
+ fdr_ptr->issBase
+ internal_sym.iss);
ecoff_set_symbol_info (abfd, &internal_sym,
&internal_ptr->symbol, 0);
&internal_ptr->symbol, 0, &indirect_ptr);
internal_ptr->fdr = fdr_ptr;
internal_ptr->local = true;
internal_ptr->native.lnative = lraw_src;
}
}
BFD_ASSERT (indirect_ptr == (asymbol *) NULL);
ecoff_data (abfd)->canonical_symbols = internal;
@ -1248,6 +1503,17 @@ ecoff_type_to_string (abfd, aux_ptr, indx, bigendian)
return buffer2;
}
/* Return information about ECOFF symbol SYMBOL in RET. */
static void
ecoff_get_symbol_info (abfd, symbol, ret)
bfd *abfd; /* Ignored. */
asymbol *symbol;
symbol_info *ret;
{
bfd_symbol_info (symbol, ret);
}
/* Print information about an ECOFF symbol. */
static void
@ -1287,17 +1553,6 @@ ecoff_print_symbol (abfd, filep, symbol, how)
(unsigned) ecoff_ext.asym.sc);
}
break;
case bfd_print_symbol_nm:
{
CONST char *section_name = symbol->section->name;
bfd_print_symbol_vandf ((PTR) file, symbol);
fprintf (file, " %-5s %s %s",
section_name,
ecoffsymbol (symbol)->local ? "l" : "e",
symbol->name);
}
break;
case bfd_print_symbol_all:
/* Print out the symbols in a reasonable way */
{
@ -1384,9 +1639,9 @@ ecoff_print_symbol (abfd, filep, symbol, how)
printf ("\n First symbol: %ld", indx + sym_base);
else
printf ("\n First symbol: %ld",
(AUX_GET_ISYM (bigendian,
&aux_base[ecoff_ext.asym.index])
+ sym_base));
(long) (AUX_GET_ISYM (bigendian,
&aux_base[ecoff_ext.asym.index])
+ sym_base));
break;
case stProc:
@ -1395,9 +1650,9 @@ ecoff_print_symbol (abfd, filep, symbol, how)
;
else if (ecoffsymbol (symbol)->local)
printf ("\n End+1 symbol: %-7ld Type: %s",
(AUX_GET_ISYM (bigendian,
&aux_base[ecoff_ext.asym.index])
+ sym_base),
(long) (AUX_GET_ISYM (bigendian,
&aux_base[ecoff_ext.asym.index])
+ sym_base),
ecoff_type_to_string (abfd, aux_base, indx + 1,
bigendian));
else
@ -1779,147 +2034,6 @@ ecoff_gprel_reloc (abfd,
return bfd_reloc_ok;
}
/* How to process the various relocs types. */
static reloc_howto_type ecoff_howto_table[] =
{
/* Reloc type 0 is ignored. The reloc reading code ensures that
this is a reference to the .abs section, which will cause
bfd_perform_relocation to do nothing. */
HOWTO (ECOFF_R_IGNORE, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
false, /* complain_on_overflow */
0, /* special_function */
"IGNORE", /* name */
false, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
false), /* pcrel_offset */
/* A 16 bit reference to a symbol, normally from a data section. */
HOWTO (ECOFF_R_REFHALF, /* type */
0, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
true, /* complain_on_overflow */
ecoff_generic_reloc, /* special_function */
"REFHALF", /* name */
true, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A 32 bit reference to a symbol, normally from a data section. */
HOWTO (ECOFF_R_REFWORD, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
true, /* complain_on_overflow */
ecoff_generic_reloc, /* special_function */
"REFWORD", /* name */
true, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
false), /* pcrel_offset */
/* A 26 bit absolute jump address. */
HOWTO (ECOFF_R_JMPADDR, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
true, /* complain_on_overflow */
ecoff_generic_reloc, /* special_function */
"JMPADDR", /* name */
true, /* partial_inplace */
0x3ffffff, /* src_mask */
0x3ffffff, /* dst_mask */
false), /* pcrel_offset */
/* The high 16 bits of a symbol value. Handled by the function
ecoff_refhi_reloc. */
HOWTO (ECOFF_R_REFHI, /* type */
16, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
true, /* complain_on_overflow */
ecoff_refhi_reloc, /* special_function */
"REFHI", /* name */
true, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* The low 16 bits of a symbol value. */
HOWTO (ECOFF_R_REFLO, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
true, /* complain_on_overflow */
ecoff_reflo_reloc, /* special_function */
"REFLO", /* name */
true, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A reference to an offset from the gp register. Handled by the
function ecoff_gprel_reloc. */
HOWTO (ECOFF_R_GPREL, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
true, /* complain_on_overflow */
ecoff_gprel_reloc, /* special_function */
"GPREL", /* name */
true, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false), /* pcrel_offset */
/* A reference to a literal using an offset from the gp register.
Handled by the function ecoff_gprel_reloc. */
HOWTO (ECOFF_R_LITERAL, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize (obsolete) */
false, /* pc_relative */
0, /* bitpos */
false, /* absolute (obsolete) */
true, /* complain_on_overflow */
ecoff_gprel_reloc, /* special_function */
"LITERAL", /* name */
true, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
false) /* pcrel_offset */
};
#define ECOFF_HOWTO_COUNT \
(sizeof ecoff_howto_table / sizeof ecoff_howto_table[0])
/* Read in the relocs for a section. */
static boolean
@ -2517,7 +2631,6 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
struct sym_ext *sym_out;
ecoff_symbol_type *esym_ptr;
ecoff_symbol_type *esym_end;
unsigned long pdr_off;
FDR *fdr_ptr;
FDR *fdr_end;
struct fdr_ext *fdr_out;
@ -2684,15 +2797,6 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
memcpy (output_ecoff->external_pdr + output_symhdr->ipdMax,
input_ecoff->external_pdr,
input_symhdr->ipdMax * sizeof (struct pdr_ext));
if (input_symhdr->ipdMax == 0)
pdr_off = 0;
else
{
PDR pdr;
ecoff_swap_pdr_in (input_bfd, input_ecoff->external_pdr, &pdr);
pdr_off = pdr.adr;
}
memcpy (output_ecoff->external_opt + output_symhdr->ioptMax,
input_ecoff->external_opt,
input_symhdr->ioptMax * sizeof (struct opt_ext));
@ -2705,7 +2809,6 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
struct pdr_ext *pdr_in;
struct pdr_ext *pdr_end;
struct pdr_ext *pdr_out;
int first_pdr;
struct opt_ext *opt_in;
struct opt_ext *opt_end;
struct opt_ext *opt_out;
@ -2726,19 +2829,12 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
pdr_in = input_ecoff->external_pdr;
pdr_end = pdr_in + input_symhdr->ipdMax;
pdr_out = output_ecoff->external_pdr + output_symhdr->ipdMax;
first_pdr = 1;
pdr_off = 0;
for (; pdr_in < pdr_end; pdr_in++, pdr_out++)
{
PDR pdr;
ecoff_swap_pdr_in (input_bfd, pdr_in, &pdr);
ecoff_swap_pdr_out (output_bfd, &pdr, pdr_out);
if (first_pdr)
{
pdr_off = pdr.adr;
first_pdr = 0;
}
}
opt_in = input_ecoff->external_opt;
opt_end = opt_in + input_symhdr->ioptMax;
@ -2762,6 +2858,7 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
for (; fdr_ptr < fdr_end; fdr_ptr++, fdr_out++)
{
FDR fdr;
unsigned long pdr_off;
fdr = *fdr_ptr;
@ -2769,6 +2866,17 @@ ecoff_get_debug (output_bfd, seclet, section, relocateable)
plus the offset to this fdr within input_bfd. For some
reason the offset of the first procedure pointer is also
added in. */
if (fdr.cpd == 0)
pdr_off = 0;
else
{
PDR pdr;
ecoff_swap_pdr_in (input_bfd,
input_ecoff->external_pdr + fdr.ipdFirst,
&pdr);
pdr_off = pdr.adr;
}
fdr.adr = (bfd_get_section_vma (output_bfd, section)
+ seclet->offset
+ (fdr_ptr->adr - input_ecoff->fdr->adr)
@ -3188,6 +3296,7 @@ ecoff_compute_section_file_positions (abfd)
affect the section size, though. FIXME: Does this work for
other platforms? */
if ((abfd->flags & EXEC_P) != 0
&& (abfd->flags & D_PAGED) != 0
&& first_data != false
&& (current->flags & SEC_CODE) == 0)
{
@ -3294,12 +3403,16 @@ ecoff_write_object_contents (abfd)
/* At least on Ultrix, the symbol table of an executable file must
be aligned to a page boundary. FIXME: Is this true on other
platforms? */
if ((abfd->flags & EXEC_P) != 0)
if ((abfd->flags & EXEC_P) != 0
&& (abfd->flags & D_PAGED) != 0)
sym_base = (sym_base + ROUND_SIZE - 1) &~ (ROUND_SIZE - 1);
ecoff_data (abfd)->sym_filepos = sym_base;
text_size = ecoff_sizeof_headers (abfd, false);
if ((abfd->flags & D_PAGED) != 0)
text_size = ecoff_sizeof_headers (abfd, false);
else
text_size = 0;
text_start = 0;
data_size = 0;
data_start = 0;
@ -3435,7 +3548,10 @@ ecoff_write_object_contents (abfd)
internal_f.f_flags |= F_AR32W;
/* Set up the ``optional'' header. */
internal_a.magic = ZMAGIC;
if ((abfd->flags & D_PAGED) != 0)
internal_a.magic = ZMAGIC;
else
internal_a.magic = OMAGIC;
/* FIXME: This is what Ultrix puts in, and it makes the Ultrix
linker happy. But, is it right? */
@ -3443,10 +3559,20 @@ ecoff_write_object_contents (abfd)
/* At least on Ultrix, these have to be rounded to page boundaries.
FIXME: Is this true on other platforms? */
internal_a.tsize = (text_size + ROUND_SIZE - 1) &~ (ROUND_SIZE - 1);
internal_a.text_start = text_start &~ (ROUND_SIZE - 1);
internal_a.dsize = (data_size + ROUND_SIZE - 1) &~ (ROUND_SIZE - 1);
internal_a.data_start = data_start &~ (ROUND_SIZE - 1);
if ((abfd->flags & D_PAGED) != 0)
{
internal_a.tsize = (text_size + ROUND_SIZE - 1) &~ (ROUND_SIZE - 1);
internal_a.text_start = text_start &~ (ROUND_SIZE - 1);
internal_a.dsize = (data_size + ROUND_SIZE - 1) &~ (ROUND_SIZE - 1);
internal_a.data_start = data_start &~ (ROUND_SIZE - 1);
}
else
{
internal_a.tsize = text_size;
internal_a.text_start = text_start;
internal_a.dsize = data_size;
internal_a.data_start = data_start;
}
/* On Ultrix, the initial portions of the .sbss and .bss segments
are at the end of the data section. The bsize field in the
@ -3628,6 +3754,24 @@ ecoff_write_object_contents (abfd)
!= ecoff_data (abfd)->raw_size)
return false;
}
else if ((abfd->flags & EXEC_P) != 0
&& (abfd->flags & D_PAGED) != 0)
{
char c;
/* A demand paged executable must occupy an even number of
pages. */
if (bfd_seek (abfd, (file_ptr) ecoff_data (abfd)->sym_filepos - 1,
SEEK_SET) != 0)
return false;
if (bfd_read (&c, 1, 1, abfd) == 0)
c = 0;
if (bfd_seek (abfd, (file_ptr) ecoff_data (abfd)->sym_filepos - 1,
SEEK_SET) != 0)
return false;
if (bfd_write (&c, 1, 1, abfd) != 1)
return false;
}
return true;
}
@ -4061,6 +4205,151 @@ ecoff_archive_p (abfd)
return abfd->xvec;
}
#ifdef HOST_IRIX4
#include <core.out.h>
struct sgi_core_struct
{
int sig;
char cmd[CORE_NAMESIZE];
};
#define core_hdr(bfd) ((bfd)->tdata.sgi_core_data)
#define core_signal(bfd) (core_hdr(bfd)->sig)
#define core_command(bfd) (core_hdr(bfd)->cmd)
static asection *
make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
bfd *abfd;
CONST char *name;
flagword flags;
bfd_size_type _raw_size;
bfd_vma vma;
file_ptr filepos;
{
asection *asect;
asect = bfd_make_section (abfd, name);
if (!asect)
return NULL;
asect->flags = flags;
asect->_raw_size = _raw_size;
asect->vma = vma;
asect->filepos = filepos;
asect->alignment_power = 4;
return asect;
}
static bfd_target *
ecoff_core_file_p (abfd)
bfd *abfd;
{
int val;
int i;
char *secname;
struct coreout coreout;
struct idesc *idg, *idf, *ids;
val = bfd_read ((PTR)&coreout, 1, sizeof coreout, abfd);
if (val != sizeof coreout)
return 0;
if (coreout.c_magic != CORE_MAGIC
|| coreout.c_version != CORE_VERSION1)
return 0;
core_hdr (abfd) = (struct sgi_core_struct *) bfd_zalloc (abfd, sizeof (struct sgi_core_struct));
if (!core_hdr (abfd))
return NULL;
strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE);
core_signal (abfd) = coreout.c_sigcause;
bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET);
for (i = 0; i < coreout.c_nvmap; i++)
{
struct vmap vmap;
val = bfd_read ((PTR)&vmap, 1, sizeof vmap, abfd);
if (val != sizeof vmap)
break;
switch (vmap.v_type)
{
case VDATA:
secname = ".data";
break;
case VSTACK:
secname = ".stack";
break;
default:
continue;
}
if (!make_bfd_asection (abfd, secname,
SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS,
vmap.v_len,
vmap.v_vaddr,
vmap.v_offset,
2))
return NULL;
}
/* Make sure that the regs are contiguous within the core file. */
idg = &coreout.c_idesc[I_GPREGS];
idf = &coreout.c_idesc[I_FPREGS];
ids = &coreout.c_idesc[I_SPECREGS];
if (idg->i_offset + idg->i_len != idf->i_offset
|| idf->i_offset + idf->i_len != ids->i_offset)
return 0; /* Can't deal with non-contig regs */
bfd_seek (abfd, idg->i_offset, SEEK_SET);
make_bfd_asection (abfd, ".reg",
SEC_ALLOC+SEC_HAS_CONTENTS,
idg->i_len + idf->i_len + ids->i_len,
0,
idg->i_offset);
/* OK, we believe you. You're a core file (sure, sure). */
return abfd->xvec;
}
static char *
ecoff_core_file_failing_command (abfd)
bfd *abfd;
{
return core_command (abfd);
}
static int
ecoff_core_file_failing_signal (abfd)
bfd *abfd;
{
return core_signal (abfd);
}
static boolean
ecoff_core_file_matches_executable_p (core_bfd, exec_bfd)
bfd *core_bfd, *exec_bfd;
{
return true; /* XXX - FIXME */
}
#else /* not def HOST_IRIX4 */
#define ecoff_core_file_p _bfd_dummy_target
#define ecoff_core_file_failing_command _bfd_dummy_core_file_failing_command
#define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
#define ecoff_core_file_matches_executable_p \
_bfd_dummy_core_file_matches_executable_p
#endif
/* This is the COFF backend structure. The backend_data field of the
bfd_target structure is set to this. The section reading code in
coffgen.c uses this structure. */
@ -4089,10 +4378,6 @@ static CONST bfd_coff_backend_data bfd_ecoff_std_swap_table = {
/* These bfd_target functions are defined in other files. */
#define ecoff_core_file_failing_command _bfd_dummy_core_file_failing_command
#define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
#define ecoff_core_file_matches_executable_p \
_bfd_dummy_core_file_matches_executable_p
#define ecoff_truncate_arname bfd_dont_truncate_arname
#define ecoff_openr_next_archived_file bfd_generic_openr_next_archived_file
#define ecoff_generic_stat_arch_elt bfd_generic_stat_arch_elt
@ -4118,14 +4403,14 @@ bfd_target ecoff_little_vec =
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect
flags */
0, /* leading underscore */
'/', /* ar_pad_char */
' ', /* ar_pad_char */
15, /* ar_max_namelen */
3, /* minimum alignment power */
4, /* minimum alignment power */
_do_getl64, _do_getl_signed_64, _do_putl64,
_do_getl32, _do_getl_signed_32, _do_putl32,
_do_getl16, _do_getl_signed_16, _do_putl16, /* data */
@ -4152,13 +4437,13 @@ bfd_target ecoff_big_vec =
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect flags */
0, /* leading underscore */
' ', /* ar_pad_char */
16, /* ar_max_namelen */
3, /* minimum alignment power */
15, /* ar_max_namelen */
4, /* minimum alignment power */
_do_getb64, _do_getb_signed_64, _do_putb64,
_do_getb32, _do_getb_signed_32, _do_putb32,
_do_getb16, _do_getb_signed_16, _do_putb16,
@ -4166,7 +4451,7 @@ bfd_target ecoff_big_vec =
_do_getb32, _do_getb_signed_32, _do_putb32,
_do_getb16, _do_getb_signed_16, _do_putb16,
{_bfd_dummy_target, coff_object_p, /* bfd_check_format */
ecoff_archive_p, _bfd_dummy_target},
ecoff_archive_p, ecoff_core_file_p},
{bfd_false, ecoff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
bfd_false},
{bfd_false, ecoff_write_object_contents, /* bfd_write_contents */