/* BFD back-end for MIPS Extended-Coff files.
- Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+ Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Original version by Per Bothner.
- Full support by Ian Lance Taylor, ian@cygnus.com.
+ Full support added by Ian Lance Taylor, ian@cygnus.com.
This file is part of BFD, the Binary File Descriptor library.
#include "coff/symconst.h"
#include "coff/ecoff-ext.h"
#include "libcoff.h"
-
-/* `Tdata' information kept for ECOFF files. */
-
-#define ecoff_data(abfd) ((abfd)->tdata.ecoff_obj_data)
-
-typedef struct ecoff_tdata
-{
- /* The reloc file position, set by
- ecoff_compute_section_file_positions. */
- file_ptr reloc_filepos;
-
- /* The symbol table file position, set by ecoff_mkobject_hook. */
- file_ptr sym_filepos;
-
- /* The cached gp value. This is used when relocating. */
- bfd_vma gp;
-
- /* The register masks. When linking, all the masks found in the
- input files are combined into the masks of the output file. */
- unsigned long gprmask;
- unsigned long cprmask[4];
-
- /* The size of the unswapped ECOFF symbolic information. */
- bfd_size_type raw_size;
-
- /* The unswapped ECOFF symbolic information. */
- PTR raw_syments;
-
- /* The swapped ECOFF symbolic header. */
- HDRR symbolic_header;
-
- /* Pointers to the unswapped symbolic information. */
- unsigned char *line;
- struct dnr_ext *external_dnr;
- struct pdr_ext *external_pdr;
- struct sym_ext *external_sym;
- struct opt_ext *external_opt;
- union aux_ext *external_aux;
- char *ss;
- char *ssext;
- struct fdr_ext *external_fdr;
- struct rfd_ext *external_rfd;
- struct ext_ext *external_ext;
-
- /* The swapped FDR information. */
- FDR *fdr;
-
- /* The FDR index. This is set for an input BFD to a link so that
- the external symbols can set their FDR index correctly. */
- unsigned int ifdbase;
-
- /* The canonical BFD symbols. */
- struct ecoff_symbol_struct *canonical_symbols;
-
-} ecoff_data_type;
+#include "libecoff.h"
/* Each canonical asymbol really looks like this. */
of the swapping routines from coffswap.h, and some of the generic
COFF routines in coffgen.c, but, unlike the real COFF targets, does
not use coffcode.h itself. */
-
+\f
+/* Prototypes for static functions. */
+
+static boolean ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr));
+static asection *ecoff_make_section_hook PARAMS ((bfd *abfd, char *name));
+static boolean ecoff_new_section_hook PARAMS ((bfd *abfd, asection *section));
+static boolean ecoff_mkobject PARAMS ((bfd *abfd));
+static PTR ecoff_mkobject_hook PARAMS ((bfd *abfd, PTR filehdr, PTR aouthdr));
+static boolean ecoff_set_arch_mach_hook PARAMS ((bfd *abfd, PTR filehdr));
+static long ecoff_sec_to_styp_flags PARAMS ((CONST char *name,
+ flagword flags));
+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));
+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,
+ asymbol **alocation));
+static void ecoff_emit_aggregate PARAMS ((bfd *abfd, char *string,
+ RNDXR *rndx, long isym,
+ CONST char *which));
+static char *ecoff_type_to_string PARAMS ((bfd *abfd, union aux_ext *aux_ptr,
+ int indx, int bigendian));
+static void ecoff_print_symbol PARAMS ((bfd *abfd, PTR filep,
+ asymbol *symbol,
+ bfd_print_symbol_type how));
+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,
+ PTR dst));
+static bfd_reloc_status_type ecoff_generic_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd));
+static bfd_reloc_status_type ecoff_refhi_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd));
+static bfd_reloc_status_type ecoff_gprel_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd));
+static boolean ecoff_slurp_reloc_table PARAMS ((bfd *abfd, asection *section,
+ asymbol **symbols));
+static unsigned int ecoff_canonicalize_reloc PARAMS ((bfd *abfd,
+ asection *section,
+ arelent **relptr,
+ asymbol **symbols));
+static boolean ecoff_find_nearest_line PARAMS ((bfd *abfd,
+ asection *section,
+ asymbol **symbols,
+ bfd_vma offset,
+ CONST char **filename_ptr,
+ CONST char **fnname_ptr,
+ unsigned int *retline_ptr));
+static void ecoff_clear_output_flags PARAMS ((bfd *abfd));
+static boolean ecoff_rel PARAMS ((bfd *output_bfd, bfd_seclet_type *seclet,
+ asection *output_section, PTR data,
+ boolean relocateable));
+static boolean ecoff_dump_seclet PARAMS ((bfd *abfd, bfd_seclet_type *seclet,
+ asection *section, PTR data,
+ boolean relocateable));
+static long ecoff_add_string PARAMS ((bfd *output_bfd, FDR *fdr,
+ CONST char *string, boolean external));
+static boolean ecoff_get_debug PARAMS ((bfd *output_bfd,
+ bfd_seclet_type *seclet,
+ asection *section,
+ boolean relocateable));
+static boolean ecoff_bfd_seclet_link PARAMS ((bfd *abfd, PTR data,
+ boolean relocateable));
+static boolean ecoff_set_arch_mach PARAMS ((bfd *abfd,
+ enum bfd_architecture arch,
+ unsigned long machine));
+static int ecoff_sizeof_headers PARAMS ((bfd *abfd, boolean reloc));
+static void ecoff_compute_section_file_positions PARAMS ((bfd *abfd));
+static boolean ecoff_set_section_contents PARAMS ((bfd *abfd,
+ asection *section,
+ PTR location,
+ file_ptr offset,
+ bfd_size_type count));
+static boolean ecoff_write_object_contents PARAMS ((bfd *abfd));
+static unsigned int ecoff_armap_hash PARAMS ((CONST char *s,
+ unsigned int *rehash,
+ unsigned int size,
+ unsigned int hlog));
+static boolean ecoff_slurp_armap PARAMS ((bfd *abfd));
+static boolean ecoff_write_armap PARAMS ((bfd *abfd, unsigned int elength,
+ struct orl *map,
+ unsigned int orl_count,
+ int stridx));
+static bfd_target *ecoff_archive_p PARAMS ((bfd *abfd));
+\f
/* Get the generic COFF swapping routines, except for the reloc,
symbol, and lineno ones. Give them ecoff names. */
#define MIPSECOFF
/* See whether the magic number matches. */
static boolean
-DEFUN(ecoff_bad_format_hook, (abfd, filehdr),
- bfd *abfd AND
- PTR filehdr)
+ecoff_bad_format_hook (abfd, filehdr)
+ bfd *abfd;
+ PTR filehdr;
{
struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
/* This is a hook needed by SCO COFF, but we have nothing to do. */
static asection *
-DEFUN (ecoff_make_section_hook, (abfd, name),
- bfd *abfd AND
- char *name)
+ecoff_make_section_hook (abfd, name)
+ bfd *abfd;
+ char *name;
{
return (asection *) NULL;
}
/* Initialize a new section. */
static boolean
-DEFUN (ecoff_new_section_hook, (abfd, section),
- bfd *abfd AND
- asection *section)
+ecoff_new_section_hook (abfd, section)
+ bfd *abfd;
+ asection *section;
{
section->alignment_power = abfd->xvec->align_power_min;
return true;
}
+/* Set the alignment of a section; we have nothing to do. */
+
#define ecoff_set_alignment_hook \
((void (*) PARAMS ((bfd *, asection *, PTR))) bfd_void)
+/* Create an ECOFF object. */
+
static boolean
-DEFUN (ecoff_mkobject, (abfd),
- bfd *abfd)
+ecoff_mkobject (abfd)
+ bfd *abfd;
{
abfd->tdata.ecoff_obj_data = ((struct ecoff_tdata *)
bfd_zalloc (abfd, sizeof(ecoff_data_type)));
return true;
}
-/* Create the COFF backend specific information. */
+/* Create the ECOFF backend specific information. */
static PTR
ecoff_mkobject_hook (abfd, filehdr, aouthdr)
{
int i;
+ ecoff->text_start = internal_a->text_start;
+ ecoff->text_end = internal_a->text_start + internal_a->tsize;
ecoff->gp = internal_a->gp_value;
ecoff->gprmask = internal_a->gprmask;
for (i = 0; i < 4; i++)
}
/* Determine the machine architecture and type. */
+
static boolean
-DEFUN (ecoff_set_arch_mach_hook, (abfd, filehdr),
- bfd *abfd AND
- PTR filehdr)
+ecoff_set_arch_mach_hook (abfd, filehdr)
+ bfd *abfd;
+ PTR filehdr;
{
- long machine;
- enum bfd_architecture arch;
struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+ enum bfd_architecture arch;
- machine = 0;
- switch (internal_f->f_magic) {
- case MIPS_MAGIC_1:
- case MIPS_MAGIC_2:
- case MIPS_MAGIC_3:
- arch = bfd_arch_mips;
- machine = 0;
- break;
-
- default: /* Unreadable input file type */
- arch = bfd_arch_obscure;
- break;
- }
+ switch (internal_f->f_magic)
+ {
+ case MIPS_MAGIC_1:
+ case MIPS_MAGIC_LITTLE:
+ case MIPS_MAGIC_BIG:
+ arch = bfd_arch_mips;
+ break;
+
+ default:
+ arch = bfd_arch_obscure;
+ break;
+ }
+
+ bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
- bfd_default_set_arch_mach(abfd, arch, machine);
return true;
}
/* Get the section s_flags to use for a section. */
static long
-DEFUN (sec_to_styp_flags, (name, flags),
- CONST char *name AND
- flagword flags)
+ecoff_sec_to_styp_flags (name, flags)
+ CONST char *name;
+ flagword flags;
{
long styp;
/* Get the BFD flags to use for a section. */
static flagword
-DEFUN (styp_to_sec_flags, (abfd, hdr),
- bfd *abfd AND
- PTR hdr)
+ecoff_styp_to_sec_flags (abfd, hdr)
+ bfd *abfd;
+ PTR hdr;
{
struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
long styp_flags = internal_s->s_flags;
}
\f
/* Read in and swap the important symbolic information for an ECOFF
- object file. */
+ object file. FIXME: This is called by gdb. If there is ever
+ another ECOFF target, it should be moved into some sort of target
+ specific structure. */
-static boolean
-DEFUN (ecoff_slurp_symbolic_info, (abfd),
- bfd *abfd)
+boolean
+ecoff_slurp_symbolic_info (abfd)
+ bfd *abfd;
{
struct hdr_ext external_symhdr;
HDRR *internal_symhdr;
{
long cbline, issmax, issextmax;
- cbline = (internal_symhdr->cbLine + 3) &~ 4;
- issmax = (internal_symhdr->issMax + 3) &~ 4;
- issextmax = (internal_symhdr->issExtMax + 3) &~ 4;
+ cbline = (internal_symhdr->cbLine + 3) &~ 3;
+ issmax = (internal_symhdr->issMax + 3) &~ 3;
+ issextmax = (internal_symhdr->issExtMax + 3) &~ 3;
raw_size = (cbline * sizeof (unsigned char)
+ internal_symhdr->idnMax * sizeof (struct dnr_ext)
+ internal_symhdr->ipdMax * sizeof (struct pdr_ext)
/* Create an empty symbol. */
static asymbol *
-DEFUN (ecoff_make_empty_symbol, (abfd),
- bfd *abfd)
+ecoff_make_empty_symbol (abfd)
+ bfd *abfd;
{
ecoff_symbol_type *new;
/* Set the BFD flags and section for an ECOFF symbol. */
static void
-DEFUN (ecoff_set_symbol_info, (abfd, ecoff_sym, asym, ext),
- bfd *abfd AND
- SYMR *ecoff_sym AND
- asymbol *asym AND
- int ext)
+ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext)
+ bfd *abfd;
+ SYMR *ecoff_sym;
+ asymbol *asym;
+ int ext;
{
asym->the_bfd = abfd;
asym->value = ecoff_sym->value;
case stLabel:
case stProc:
case stStaticProc:
- case stBlock:
case stNil:
break;
default:
/* Read an ECOFF symbol table. */
static boolean
-DEFUN (ecoff_slurp_symbol_table, (abfd),
- bfd *abfd)
+ecoff_slurp_symbol_table (abfd)
+ bfd *abfd;
{
bfd_size_type internal_size;
ecoff_symbol_type *internal;
}
static unsigned int
-DEFUN (ecoff_get_symtab_upper_bound, (abfd),
- bfd *abfd)
+ecoff_get_symtab_upper_bound (abfd)
+ bfd *abfd;
{
if (ecoff_slurp_symbolic_info (abfd) == false
|| bfd_get_symcount (abfd) == 0)
}
static unsigned int
-DEFUN (ecoff_get_symtab, (abfd, alocation),
- bfd *abfd AND
- asymbol **alocation)
+ecoff_get_symtab (abfd, alocation)
+ bfd *abfd;
+ asymbol **alocation;
{
unsigned int counter = 0;
ecoff_symbol_type *symbase;
}
/* Turn ECOFF type information into a printable string.
- emit_aggregate and type_to_string are from gcc/mips-tdump.c, with
- swapping added and used_ptr removed. */
+ ecoff_emit_aggregate and ecoff_type_to_string are from
+ gcc/mips-tdump.c, with swapping added and used_ptr removed. */
/* Write aggregate information to a string. */
static void
-DEFUN (emit_aggregate, (abfd, string, rndx, isym, which),
- bfd *abfd AND
- char *string AND
- RNDXR *rndx AND
- long isym AND
- CONST char *which)
+ecoff_emit_aggregate (abfd, string, rndx, isym, which)
+ bfd *abfd;
+ char *string;
+ RNDXR *rndx;
+ long isym;
+ CONST char *which;
{
int ifd = rndx->rfd;
int indx = rndx->index;
/* Convert the type information to string format. */
static char *
-DEFUN (type_to_string, (abfd, aux_ptr, indx, bigendian),
- bfd *abfd AND
- union aux_ext *aux_ptr AND
- int indx AND
- int bigendian)
+ecoff_type_to_string (abfd, aux_ptr, indx, bigendian)
+ bfd *abfd;
+ union aux_ext *aux_ptr;
+ int indx;
+ int bigendian;
{
AUXU u;
struct qual {
case btStruct: /* Structure (Record) */
ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
- emit_aggregate (abfd, p1, &rndx,
- AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
- "struct");
+ ecoff_emit_aggregate (abfd, p1, &rndx,
+ AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
+ "struct");
indx++; /* skip aux words */
break;
case btUnion: /* Union */
ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
- emit_aggregate (abfd, p1, &rndx,
- AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
- "union");
+ ecoff_emit_aggregate (abfd, p1, &rndx,
+ AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
+ "union");
indx++; /* skip aux words */
break;
case btEnum: /* Enumeration */
ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
- emit_aggregate (abfd, p1, &rndx,
- AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
- "enum");
+ ecoff_emit_aggregate (abfd, p1, &rndx,
+ AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
+ "enum");
indx++; /* skip aux words */
break;
/* Print information about an ECOFF symbol. */
static void
-DEFUN (ecoff_print_symbol, (abfd, filep, symbol, how),
- bfd *abfd AND
- PTR filep AND
- asymbol *symbol AND
- bfd_print_symbol_type how)
+ecoff_print_symbol (abfd, filep, symbol, how)
+ bfd *abfd;
+ PTR filep;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
{
FILE *file = (FILE *)filep;
(AUX_GET_ISYM (bigendian,
&aux_base[ecoff_ext.asym.index])
+ sym_base),
- type_to_string (abfd, aux_base, indx + 1,
- bigendian));
+ ecoff_type_to_string (abfd, aux_base, indx + 1,
+ bigendian));
else
printf ("\n Local symbol: %d",
(indx
default:
if (!MIPS_IS_STAB (&ecoff_ext.asym))
printf ("\n Type: %s",
- type_to_string (abfd, aux_base, indx, bigendian));
+ ecoff_type_to_string (abfd, aux_base, indx,
+ bigendian));
break;
}
}
/* Swap a reloc in. */
static void
-DEFUN (ecoff_swap_reloc_in, (abfd, ext, intern),
- bfd *abfd AND
- RELOC *ext AND
- struct internal_reloc *intern)
+ecoff_swap_reloc_in (abfd, ext, intern)
+ bfd *abfd;
+ RELOC *ext;
+ struct internal_reloc *intern;
{
intern->r_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_vaddr);
if (abfd->xvec->header_byteorder_big_p != false)
/* Swap a reloc out. */
static unsigned int
-DEFUN (ecoff_swap_reloc_out, (abfd, src, dst),
- bfd *abfd AND
- PTR src AND
- PTR dst)
+ecoff_swap_reloc_out (abfd, src, dst)
+ bfd *abfd;
+ PTR src;
+ PTR dst;
{
struct internal_reloc *intern = (struct internal_reloc *) src;
RELOC *ext = (RELOC *) dst;
/* Read in the relocs for a section. */
static boolean
-DEFUN (ecoff_slurp_reloc_table, (abfd, section, symbols),
- bfd *abfd AND
- asection *section AND
- asymbol **symbols)
+ecoff_slurp_reloc_table (abfd, section, symbols)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
{
RELOC *external_relocs;
arelent *internal_relocs;
/* Get a canonical list of relocs. */
static unsigned int
-DEFUN (ecoff_canonicalize_reloc, (abfd, section, relptr, symbols),
- bfd *abfd AND
- asection *section AND
- arelent **relptr AND
- asymbol **symbols)
+ecoff_canonicalize_reloc (abfd, section, relptr, symbols)
+ bfd *abfd;
+ asection *section;
+ arelent **relptr;
+ asymbol **symbols;
{
unsigned int count;
wanted location. */
static boolean
-DEFUN (ecoff_find_nearest_line, (abfd,
- section,
- ignore_symbols,
- offset,
- filename_ptr,
- functionname_ptr,
- retline_ptr),
- bfd *abfd AND
- asection *section AND
- asymbol **ignore_symbols AND
- bfd_vma offset AND
- CONST char **filename_ptr AND
- CONST char **functionname_ptr AND
- unsigned int *retline_ptr)
+ecoff_find_nearest_line (abfd,
+ section,
+ ignore_symbols,
+ offset,
+ filename_ptr,
+ functionname_ptr,
+ retline_ptr)
+ bfd *abfd;
+ asection *section;
+ asymbol **ignore_symbols;
+ bfd_vma offset;
+ CONST char **filename_ptr;
+ CONST char **functionname_ptr;
+ unsigned int *retline_ptr;
{
FDR *fdr_ptr;
FDR *fdr_start;
/* If we're not in the .text section, we don't have any line
numbers. */
- if (strcmp (section->name, _TEXT) != 0)
+ if (strcmp (section->name, _TEXT) != 0
+ || offset < ecoff_data (abfd)->text_start
+ || offset >= ecoff_data (abfd)->text_end)
return false;
/* Make sure we have the FDR's. */
fdr_hold = (FDR *) NULL;
for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
{
+ if (fdr_ptr->cpd == 0)
+ continue;
if (offset < fdr_ptr->adr)
break;
- if (fdr_ptr->cpd > 0)
- fdr_hold = fdr_ptr;
+ fdr_hold = fdr_ptr;
}
if (fdr_hold == (FDR *) NULL)
return false;
offset -= count * 4;
}
- /* If offset is too large, this line is not interesting. */
- if (offset > 100)
- return false;
-
/* If fdr_ptr->rss is -1, then this file does not have full symbols,
at least according to gdb/mipsread.c. */
if (fdr_ptr->rss == -1)
once. */
static void
-DEFUN (ecoff_clear_output_flags, (abfd),
- bfd *abfd)
+ecoff_clear_output_flags (abfd)
+ bfd *abfd;
{
register asection *o;
register bfd_seclet_type *p;
any. */
static boolean
-DEFUN (ecoff_rel, (output_bfd, seclet, output_section, data, relocateable),
- bfd *output_bfd AND
- bfd_seclet_type *seclet AND
- asection *output_section AND
- PTR data AND
- boolean relocateable)
+ecoff_rel (output_bfd, seclet, output_section, data, relocateable)
+ bfd *output_bfd;
+ bfd_seclet_type *seclet;
+ asection *output_section;
+ PTR data;
+ boolean relocateable;
{
bfd *input_bfd;
HDRR *output_symhdr;
HDRR *input_symhdr;
- ecoff_symbol_type *sym_ptr;
- ecoff_symbol_type *sym_end;
if ((output_section->flags & SEC_HAS_CONTENTS)
&& !(output_section->flags & SEC_NEVER_LOAD)
/* Handle an arbitrary seclet on the first pass. */
static boolean
-DEFUN (ecoff_dump_seclet, (abfd, seclet, section, data, relocateable),
- bfd *abfd AND
- bfd_seclet_type *seclet AND
- asection *section AND
- PTR data AND
- boolean relocateable)
+ecoff_dump_seclet (abfd, seclet, section, data, relocateable)
+ bfd *abfd;
+ bfd_seclet_type *seclet;
+ asection *section;
+ PTR data;
+ boolean relocateable;
{
switch (seclet->type)
{
external string base. */
static long
-DEFUN (ecoff_add_string, (output_bfd, fdr, string, external),
- bfd *output_bfd AND
- FDR *fdr AND
- CONST char *string AND
- boolean external)
+ecoff_add_string (output_bfd, fdr, string, external)
+ bfd *output_bfd;
+ FDR *fdr;
+ CONST char *string;
+ boolean external;
{
HDRR *symhdr;
size_t len;
/* Accumulate the debugging information from an input section. */
static boolean
-DEFUN (ecoff_get_debug, (output_bfd, seclet, section, relocateable),
- bfd *output_bfd AND
- bfd_seclet_type *seclet AND
- asection *section AND
- boolean relocateable)
+ecoff_get_debug (output_bfd, seclet, section, relocateable)
+ bfd *output_bfd;
+ bfd_seclet_type *seclet;
+ asection *section;
+ boolean relocateable;
{
bfd *input_bfd;
HDRR *output_symhdr;
ecoff_data_type *input_ecoff;
unsigned int count;
struct sym_ext *sym_out;
- struct ext_ext *ext_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;
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));
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;
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;
fdr = *fdr_ptr;
/* The memory address for this fdr is the address for the seclet
- plus the offset to this fdr within input_bfd. */
+ plus the offset to this fdr within input_bfd. For some
+ reason the offset of the first procedure pointer is also
+ added in. */
fdr.adr = (bfd_get_section_vma (output_bfd, section)
+ seclet->offset
- + (fdr_ptr->adr - input_ecoff->fdr->adr));
+ + (fdr_ptr->adr - input_ecoff->fdr->adr)
+ + pdr_off);
fdr.issBase += output_symhdr->issMax;
fdr.isymBase += output_symhdr->isymMax;
seclets. */
static boolean
-DEFUN (ecoff_bfd_seclet_link, (abfd, data, relocateable),
- bfd *abfd AND
- PTR data AND
- boolean relocateable)
+ecoff_bfd_seclet_link (abfd, data, relocateable)
+ bfd *abfd;
+ PTR data;
+ boolean relocateable;
{
HDRR *symhdr;
int ipass;
the return value. */
static boolean
-DEFUN (ecoff_set_arch_mach, (abfd, arch, machine),
- bfd *abfd AND
- enum bfd_architecture arch AND
- unsigned long machine)
+ecoff_set_arch_mach (abfd, arch, machine)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long machine;
{
bfd_default_set_arch_mach (abfd, arch, machine);
return arch == bfd_arch_mips;
reloc_filepos. */
static void
-DEFUN (ecoff_compute_section_file_positions, (abfd),
- bfd *abfd)
+ecoff_compute_section_file_positions (abfd)
+ bfd *abfd;
{
asection *current;
file_ptr sofar;
/* Set the contents of a section. */
static boolean
-DEFUN (ecoff_set_section_contents, (abfd, section, location, offset, count),
- bfd *abfd AND
- asection *section AND
- PTR location AND
- file_ptr offset AND
- bfd_size_type count)
+ecoff_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ asection *section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
{
if (abfd->output_has_begun == false)
ecoff_compute_section_file_positions (abfd);
/* Write out an ECOFF file. */
static boolean
-DEFUN (ecoff_write_object_contents, (abfd),
- bfd *abfd)
+ecoff_write_object_contents (abfd)
+ bfd *abfd;
{
asection *current;
unsigned int count;
section.s_nreloc = current->reloc_count;
section.s_nlnno = 0;
- section.s_flags = sec_to_styp_flags (current->name, current->flags);
+ section.s_flags = ecoff_sec_to_styp_flags (current->name,
+ current->flags);
{
SCNHDR buff;
/* Set up the file header. */
- internal_f.f_magic = MIPS_MAGIC_2;
+ if (abfd->xvec->header_byteorder_big_p != false)
+ internal_f.f_magic = MIPS_MAGIC_BIG;
+ else
+ internal_f.f_magic = MIPS_MAGIC_LITTLE;
/*
We will NOT put a fucking timestamp in the header here. Every time you
/* Set up the ``optional'' header. */
internal_a.magic = ZMAGIC;
- /* FIXME: What should this be? */
- internal_a.vstamp = 0;
+ /* FIXME: This is what Ultrix puts in, and it makes the Ultrix
+ linker happy. But, is it right? */
+ internal_a.vstamp = 0x20a;
/* At least on Ultrix, these have to be rounded to page boundaries.
FIXME: Is this true on other platforms? */
/* Read in the armap. */
static boolean
-DEFUN (ecoff_slurp_armap, (abfd),
- bfd *abfd)
+ecoff_slurp_armap (abfd)
+ bfd *abfd;
{
char nextname[17];
unsigned int i;
/* Make sure we have the right byte ordering. */
if (((nextname[ARMAP_HEADER_ENDIAN_INDEX] == ARMAP_BIG_ENDIAN)
^ (abfd->xvec->header_byteorder_big_p != false))
- || ((nextname[ARMAP_OBJECT_MARKER_INDEX] == ARMAP_BIG_ENDIAN)
+ || ((nextname[ARMAP_OBJECT_ENDIAN_INDEX] == ARMAP_BIG_ENDIAN)
^ (abfd->xvec->byteorder_big_p != false)))
{
bfd_error = wrong_format;
/* Write out an armap. */
static boolean
-DEFUN (ecoff_write_armap, (abfd, elength, map, orl_count, stridx),
- bfd *abfd AND
- unsigned int elength AND
- struct orl *map AND
- unsigned int orl_count AND
- int stridx)
+ecoff_write_armap (abfd, elength, map, orl_count, stridx)
+ bfd *abfd;
+ unsigned int elength;
+ struct orl *map;
+ unsigned int orl_count;
+ int stridx;
{
unsigned int hashsize, hashlog;
unsigned int symdefsize;
complain that the index is out of date. Actually, the Ultrix
linker just checks the archive name; the GNU linker may check the
date. */
- if (stat (abfd->filename, &statbuf) < 0)
- statbuf.st_mtime = time ((PTR) NULL);
+ stat (abfd->filename, &statbuf);
sprintf (hdr.ar_date, "%ld", (long) (statbuf.st_mtime + 60));
/* The DECstation uses zeroes for the uid, gid and mode of the
and the extended name table. */
static bfd_target *
-DEFUN (ecoff_archive_p, (abfd),
- bfd *abfd)
+ecoff_archive_p (abfd)
+ bfd *abfd;
{
char armag[SARMAG + 1];
return abfd->xvec;
}
\f
+/* 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. */
+
static CONST bfd_coff_backend_data bfd_ecoff_std_swap_table = {
(void (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_in */
(void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, true,
ecoff_swap_filehdr_in, ecoff_swap_aouthdr_in, ecoff_swap_scnhdr_in,
ecoff_bad_format_hook, ecoff_set_arch_mach_hook, ecoff_mkobject_hook,
- styp_to_sec_flags, ecoff_make_section_hook, ecoff_set_alignment_hook,
+ ecoff_styp_to_sec_flags, ecoff_make_section_hook, ecoff_set_alignment_hook,
ecoff_slurp_symbol_table
};
#define ecoff_get_lineno \
((alent *(*) PARAMS ((bfd *, asymbol *))) bfd_nullvoidptr)
+/* 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_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
#define ecoff_bfd_debug_info_end bfd_void
#define ecoff_bfd_debug_info_accumulate \
((void (*) PARAMS ((bfd *, struct sec *))) bfd_void)
-#define ecoff_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
+#define ecoff_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
#define ecoff_bfd_relax_section bfd_generic_relax_section
bfd_target ecoff_little_vec =