#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. */
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 boolean ecoff_slurp_symbolic_info PARAMS ((bfd *abfd));
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));
{
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++)
switch (internal_f->f_magic)
{
case MIPS_MAGIC_1:
- case MIPS_MAGIC_2:
- case MIPS_MAGIC_3:
+ case MIPS_MAGIC_LITTLE:
+ case MIPS_MAGIC_BIG:
arch = bfd_arch_mips;
break;
}
\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
+boolean
ecoff_slurp_symbolic_info (abfd)
bfd *abfd;
{
{
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)
case stLabel:
case stProc:
case stStaticProc:
- case stBlock:
case stNil:
break;
default:
/* 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)
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;
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;
/* 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
/* 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;