#define OBJ_HEADER "obj-ecoff.h"
#include "as.h"
#include "coff/internal.h"
#include "bfd/libcoff.h"
#include "bfd/libecoff.h"
static int ecoff_sec_sym_ok_for_reloc PARAMS ((asection *));
static void obj_ecoff_frob_symbol PARAMS ((symbolS *, int *));
static void ecoff_pop_insert PARAMS ((void));
static int ecoff_separate_stab_sections PARAMS ((void));
const pseudo_typeS obj_pseudo_table[] =
{
{ "def", ecoff_directive_def, 0 },
{ "dim", ecoff_directive_dim, 0 },
{ "endef", ecoff_directive_endef, 0 },
{ "file", ecoff_directive_file, 0 },
{ "scl", ecoff_directive_scl, 0 },
{ "size", ecoff_directive_size, 0 },
{ "esize", ecoff_directive_size, 0 },
{ "tag", ecoff_directive_tag, 0 },
{ "type", ecoff_directive_type, 0 },
{ "etype", ecoff_directive_type, 0 },
{ "val", ecoff_directive_val, 0 },
{ "begin", ecoff_directive_begin, 0 },
{ "bend", ecoff_directive_bend, 0 },
{ "end", ecoff_directive_end, 0 },
{ "ent", ecoff_directive_ent, 0 },
{ "fmask", ecoff_directive_fmask, 0 },
{ "frame", ecoff_directive_frame, 0 },
{ "loc", ecoff_directive_loc, 0 },
{ "mask", ecoff_directive_mask, 0 },
{ "extern", ecoff_directive_extern, 0 },
#ifndef TC_MIPS
{ "weakext", ecoff_directive_weakext, 0 },
#endif
{ "bgnb", s_ignore, 0 },
{ "endb", s_ignore, 0 },
{ "verstamp", s_ignore, 0 },
{ NULL, s_ignore, 0 }
};
void
ecoff_frob_file_before_fix ()
{
bfd_vma addr;
asection **sec;
static const char *const names[] = {
".text", ".rdata", ".init", ".fini",
".data", ".lita", ".lit8", ".lit4", ".sdata", ".got",
".sbss", ".bss",
};
#define n_names ((int) (sizeof (names) / sizeof (names[0])))
asection *secs[n_names];
int i;
addr = 0;
for (i = 0; i < n_names; i++)
secs[i] = 0;
for (sec = &stdoutput->sections; *sec != (asection *) NULL; )
{
for (i = 0; i < n_names; i++)
if (!strcmp ((*sec)->name, names[i]))
{
secs[i] = *sec;
bfd_section_list_remove (stdoutput, sec);
break;
}
if (i == n_names)
{
bfd_set_section_vma (stdoutput, *sec, addr);
addr += bfd_section_size (stdoutput, *sec);
sec = &(*sec)->next;
}
}
for (i = 0; i < n_names; i++)
if (secs[i])
{
bfd_set_section_vma (stdoutput, secs[i], addr);
addr += bfd_section_size (stdoutput, secs[i]);
}
for (i = n_names - 1; i >= 0; i--)
if (secs[i])
bfd_section_list_insert (stdoutput, &stdoutput->sections, secs[i]);
{
unsigned long gprmask = 0;
unsigned long fprmask = 0;
unsigned long *cprmask = NULL;
#ifdef TC_MIPS
gprmask = mips_gprmask;
cprmask = mips_cprmask;
#endif
#ifdef TC_ALPHA
alpha_frob_ecoff_data ();
if (! bfd_ecoff_set_gp_value (stdoutput, alpha_gp_value))
as_fatal (_("Can't set GP value"));
gprmask = alpha_gprmask;
fprmask = alpha_fprmask;
#endif
if (! bfd_ecoff_set_regmasks (stdoutput, gprmask, fprmask, cprmask))
as_fatal (_("Can't set register masks"));
}
}
void
ecoff_frob_file ()
{
const struct ecoff_debug_swap * const debug_swap
= &ecoff_backend (stdoutput)->debug_swap;
bfd_vma addr ATTRIBUTE_UNUSED;
HDRR *hdr;
char *buf;
char *set;
assert (ecoff_data (stdoutput) != 0);
hdr = &ecoff_data (stdoutput)->debug_info.symbolic_header;
ecoff_build_debug (hdr, &buf, debug_swap);
set = buf;
#define SET(ptr, count, type, size) \
if (hdr->count == 0) \
ecoff_data (stdoutput)->debug_info.ptr = (type) NULL; \
else \
{ \
ecoff_data (stdoutput)->debug_info.ptr = (type) set; \
set += hdr->count * size; \
}
SET (line, cbLine, unsigned char *, sizeof (unsigned char));
SET (external_dnr, idnMax, PTR, debug_swap->external_dnr_size);
SET (external_pdr, ipdMax, PTR, debug_swap->external_pdr_size);
SET (external_sym, isymMax, PTR, debug_swap->external_sym_size);
SET (external_opt, ioptMax, PTR, debug_swap->external_opt_size);
SET (external_aux, iauxMax, union aux_ext *, sizeof (union aux_ext));
SET (ss, issMax, char *, sizeof (char));
SET (ssext, issExtMax, char *, sizeof (char));
SET (external_rfd, crfd, PTR, debug_swap->external_rfd_size);
SET (external_fdr, ifdMax, PTR, debug_swap->external_fdr_size);
SET (external_ext, iextMax, PTR, debug_swap->external_ext_size);
#undef SET
}
void
obj_ecoff_set_ext (sym, ext)
symbolS *sym;
EXTR *ext;
{
const struct ecoff_debug_swap * const debug_swap
= &ecoff_backend (stdoutput)->debug_swap;
ecoff_symbol_type *esym;
know (bfd_asymbol_flavour (symbol_get_bfdsym (sym))
== bfd_target_ecoff_flavour);
esym = ecoffsymbol (symbol_get_bfdsym (sym));
esym->local = FALSE;
esym->native = xmalloc (debug_swap->external_ext_size);
(*debug_swap->swap_ext_out) (stdoutput, ext, esym->native);
}
static int
ecoff_sec_sym_ok_for_reloc (sec)
asection *sec ATTRIBUTE_UNUSED;
{
return 1;
}
static void
obj_ecoff_frob_symbol (sym, puntp)
symbolS *sym;
int *puntp ATTRIBUTE_UNUSED;
{
ecoff_frob_symbol (sym);
}
static void
ecoff_pop_insert ()
{
pop_insert (obj_pseudo_table);
}
static int
ecoff_separate_stab_sections ()
{
return 0;
}
const struct format_ops ecoff_format_ops =
{
bfd_target_ecoff_flavour,
0,
1,
0,
ecoff_new_file,
obj_ecoff_frob_symbol,
ecoff_frob_file,
0,
ecoff_frob_file_before_fix,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
ecoff_generate_asm_lineno,
ecoff_stab,
ecoff_separate_stab_sections,
0,
ecoff_sec_sym_ok_for_reloc,
ecoff_pop_insert,
ecoff_set_ext,
ecoff_read_begin_hook,
ecoff_symbol_new_hook
};