-/* Support for Intel 960 COFF and Motorola 88k BCS COFF (and maybe others)
+/* Support for the generic parts of most COFF variants, for BFD.
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Written by Cygnus Support.
the relocations used by the 88k format @xref{Relocations}. Then the
major portion of coff code is included (@code{coffcode.h}) which
defines the methods used to act upon the types defined in
-@code{m88k-bcs.h} and @code{internalcoff.h}.
+@code{m88k-bcs.h} and @code{internalcoff.h}.
The Intel i960 processor version of coff is implemented in
-@code{icoff.c}. This file has the same structure as
+@code{icoff.c}. This file has the same structure as
@code{m88k-bcs.c}, except that it includes @code{intel-coff.h} rather
-than @code{m88k-bcs.h}.
+than @code{m88k-bcs.h}.
@subsection Porting To A New Version of Coff
your coff flavour is called foo. Copy the @code{i386coff.c} to @code{foocoff.c},
copy @code{../include/i386coff.h} to @code{../include/foocoff.h} and
add the lines to @code{targets.c} and @code{Makefile.in} so that your
-new back end is used.
+new back end is used.
Alter the shapes of the structures in @code{../include/foocoff.h} so
that they match what you need. You will probably also have to add
The simple canonical form for symbols used by BFD is not rich enough
to keep all the information available in a coff symbol table. The back
end gets around this by keeping the original symbol table around,
-"behind the sceens".
+"behind the scenes".
When a symbol table is requested (through a call to
@code{bfd_canonicalize_symtab}, a request gets through to
present.
When the symbols have come from a coff file then all the debugging
-information is preserved.
+information is preserved.
Symbol tables are provided for writing to the back end in a vector of
pointers to pointers. This allows applications like the linker to
accumulate and output large symbol tables without having to do too
much byte copying.
-The symbol table is not output to a writable BFD until it is closed.
+The symbol table is not output to a writable BFD until it is closed.
The order of operations on the canonical symbol table at that point
are:
@table @code
symbol marked as a file place holder (@code{C_FILE}) to point to the
next file place holder in the list. It also marks each @code{offset}
field in the list with the offset from the first symbol of the current
-symbol.
+symbol.
Another function of this procedure is to turn the canonical value form
of BFD into the form used by coff. Internally, BFD expects symbol
*/
-/* $Id$ */
#define PUTWORD bfd_h_put_32
#define PUTHALF bfd_h_put_16
+#define PUTBYTE bfd_h_put_8
#ifndef GET_FCN_LNNOPTR
#define GET_FCN_LNNOPTR(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
#ifndef PUT_LNSZ_SIZE
#define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte*) ext->x_sym.x_misc.x_lnsz.x_size)
#endif
-#ifndef GET_SCN_SCNLEN
+#ifndef GET_SCN_SCNLEN
#define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen)
#endif
#ifndef GET_SCN_NRELOC
#ifndef GET_SCN_NLINNO
#define GET_SCN_NLINNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nlinno)
#endif
-#ifndef PUT_SCN_SCNLEN
+#ifndef PUT_SCN_SCNLEN
#define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen)
#endif
#ifndef PUT_SCN_NRELOC
#define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_scn.x_nreloc)
#endif
#ifndef PUT_SCN_NLINNO
-#define PUT_SCN_NLINNO(abfd,in, ext) bfd_h_put_16(abfd,in, (bfd_byte *) ext->x_scn.x_nlinno)
+#define PUT_SCN_NLINNO(abfd,in, ext) bfd_h_put_16(abfd,in, (bfd_byte *) ext->x_scn.x_nlinno)
+#endif
+#ifndef GET_LINENO_LNNO
+#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) (ext->l_lnno));
+#endif
+#ifndef PUT_LINNO_LNNO
+#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_16(abfd,val, (bfd_byte *) (ext->l_lnno));
#endif
-
\f
/* void warning(); */
-/*
- * Return a word with STYP_* (scnhdr.s_flags) flags set to represent the
+/*
+ * Return a word with STYP_* (scnhdr.s_flags) flags set to represent the
* incoming SEC_* flags. The inverse of this function is styp_to_sec_flags().
* NOTE: If you add to/change this routine, you should mirror the changes
* in styp_to_sec_flags().
*/
-static long
+static long
DEFUN(sec_to_styp_flags, (sec_name, sec_flags),
CONST char * sec_name AND
flagword sec_flags)
return((long)STYP_DATA);
} else if (!strcmp(sec_name, _BSS)) {
return((long)STYP_BSS);
- }
+ }
/* Try and figure out what it should be */
- if (sec_flags & SEC_CODE) styp_flags = STYP_TEXT;
- if (sec_flags & SEC_DATA) styp_flags = STYP_DATA;
- else if (sec_flags & SEC_READONLY)
+ if (sec_flags & SEC_CODE) styp_flags = STYP_TEXT;
+ if (sec_flags & SEC_DATA) styp_flags = STYP_DATA;
+ else if (sec_flags & SEC_READONLY)
#ifdef STYP_LIT /* 29k readonly text/data section */
- styp_flags = STYP_LIT;
+ styp_flags = STYP_LIT;
#else
- styp_flags = STYP_TEXT;
+ styp_flags = STYP_TEXT;
#endif /* STYP_LIT */
else if (sec_flags & SEC_LOAD) styp_flags = STYP_TEXT;
return(styp_flags);
}
-/*
+/*
* Return a word with SEC_* flags set to represent the incoming
- * STYP_* flags (from scnhdr.s_flags). The inverse of this
- * function is sec_to_styp_flags().
+ * STYP_* flags (from scnhdr.s_flags). The inverse of this
+ * function is sec_to_styp_flags().
* NOTE: If you add to/change this routine, you should mirror the changes
* in sec_to_styp_flags().
*/
-static flagword
+static flagword
DEFUN(styp_to_sec_flags, (styp_flags),
long styp_flags)
{
/* **********************************************************************
Here are all the routines for swapping the structures seen in the
-outside world into the internal forms.
+outside world into the internal forms.
*/
{
reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr);
reloc_dst->r_symndx = bfd_h_get_32(abfd, (bfd_byte *) reloc_src->r_symndx);
+
+#ifdef RS6000COFF_C
+ reloc_dst->r_type = bfd_h_get_8(abfd, reloc_src->r_type);
+ reloc_dst->r_size = bfd_h_get_8(abfd, reloc_src->r_size);
+#else
reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type);
+#endif
+
#if M88
reloc_dst->r_offset = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_offset);
#endif
#ifndef NO_COFF_SYMBOLS
-static void
+static void
DEFUN(coff_swap_sym_in,(abfd, ext1, in1),
bfd *abfd AND
PTR ext1 AND
}
bfd_h_put_32(abfd, in->n_value , (bfd_byte *) ext->e_value);
bfd_h_put_16(abfd, in->n_scnum , (bfd_byte *) ext->e_scnum);
- if (sizeof(ext->e_type) == 2)
+ if (sizeof(ext->e_type) == 2)
{
bfd_h_put_16(abfd, in->n_type , (bfd_byte *) ext->e_type);
}
case C_FILE:
if (ext->x_file.x_fname[0] == 0) {
in->x_file.x_n.x_zeroes = 0;
- in->x_file.x_n.x_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
+ in->x_file.x_n.x_offset =
+ bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
} else {
#if FILNMLEN != E_FILNMLEN
-> Error, we need to cope with truncating or extending FILNMLEN!;
memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
#endif
}
+ break;
+ /* RS/6000 "csect" auxents */
+#ifdef RS6000COFF_C
+ case C_EXT:
+ case C_HIDEXT:
+ in->x_csect.x_scnlen = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_csect.x_scnlen);
+ in->x_csect.x_parmhash = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_csect.x_parmhash);
+ in->x_csect.x_snhash = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_csect.x_snhash);
+ /* We don't have to hack bitfields in x_smtyp because it's defined by
+ shifts-and-ands, which are equivalent on all byte orders. */
+ in->x_csect.x_smtyp = bfd_h_get_8 (abfd, (bfd_byte *) ext->x_csect.x_smtyp);
+ in->x_csect.x_smclas = bfd_h_get_8 (abfd, (bfd_byte *) ext->x_csect.x_smclas);
+ in->x_csect.x_stab = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_csect.x_stab);
+ in->x_csect.x_snstab = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_csect.x_snstab);
break;
+#endif
+
case C_STAT:
#ifdef C_LEAFSTAT
case C_LEAFSTAT:
switch (class) {
case C_FILE:
if (in->x_file.x_fname[0] == 0) {
- PUTWORD(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes );
+ PUTWORD(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
PUTWORD(abfd,
in->x_file.x_n.x_offset,
(bfd_byte *) ext->x_file.x_n.x_offset);
#else
memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
#endif
- }
+ }
+ break;
+
+#ifdef RS6000COFF_C
+ /* RS/6000 "csect" auxents */
+ case C_EXT:
+ case C_HIDEXT:
+ PUTWORD (abfd, in->x_csect.x_scnlen, ext->x_csect.x_scnlen);
+ PUTWORD (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
+ PUTHALF (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
+ /* We don't have to hack bitfields in x_smtyp because it's defined by
+ shifts-and-ands, which are equivalent on all byte orders. */
+ PUTBYTE (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
+ PUTBYTE (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
+ PUTWORD (abfd, in->x_csect.x_stab, ext->x_csect.x_stab);
+ PUTHALF (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab);
break;
+#endif
+
case C_STAT:
#ifdef C_LEAFSTAT
case C_LEAFSTAT:
#endif
case C_HIDDEN:
if (type == T_NULL) {
-
PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext);
PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext);
PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext);
struct internal_lineno *in = (struct internal_lineno *)in1;
in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx);
-#if defined(M88)
- in->l_lnno = bfd_h_get_32(abfd, (bfd_byte *) ext->l_lnno);
-#else
- in->l_lnno = bfd_h_get_16(abfd, (bfd_byte *) ext->l_lnno);
-#endif
+ in->l_lnno = GET_LINENO_LNNO(abfd, ext);
}
static unsigned int
{
struct internal_lineno *in = (struct internal_lineno *)inp;
struct external_lineno *ext = (struct external_lineno *)outp;
- PUTWORD(abfd, in->l_addr.l_symndx, (bfd_byte *) ext->l_addr.l_symndx);
-#if defined(M88)
- PUTWORD(abfd, in->l_lnno, (bfd_byte *) ext->l_lnno);
-#else
- PUTHALF(abfd, in->l_lnno, (bfd_byte *) ext->l_lnno);
-#endif
+ PUTWORD(abfd, in->l_addr.l_symndx, (bfd_byte *)
+ ext->l_addr.l_symndx);
+
+ PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
return sizeof(struct external_lineno);
}
#endif /* NO_COFF_LINENOS */
-static void
+static void
DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1),
bfd *abfd AND
PTR aouthdr_ext1 AND
#ifdef I960
aouthdr_int->tagentries = bfd_h_get_32(abfd, (bfd_byte *) aouthdr_ext->tagentries);
#endif
+
+#ifdef RS6000COFF_C
+ aouthdr_int->o_toc = bfd_h_get_32(abfd, aouthdr_ext->o_toc);
+ aouthdr_int->o_snentry = bfd_h_get_16(abfd, aouthdr_ext->o_snentry);
+ aouthdr_int->o_sntext = bfd_h_get_16(abfd, aouthdr_ext->o_sntext);
+ aouthdr_int->o_sndata = bfd_h_get_16(abfd, aouthdr_ext->o_sndata);
+ aouthdr_int->o_sntoc = bfd_h_get_16(abfd, aouthdr_ext->o_sntoc);
+ aouthdr_int->o_snloader = bfd_h_get_16(abfd, aouthdr_ext->o_snloader);
+ aouthdr_int->o_snbss = bfd_h_get_16(abfd, aouthdr_ext->o_snbss);
+ aouthdr_int->o_algntext = bfd_h_get_16(abfd, aouthdr_ext->o_algntext);
+ aouthdr_int->o_algndata = bfd_h_get_16(abfd, aouthdr_ext->o_algndata);
+ aouthdr_int->o_modtype = bfd_h_get_16(abfd, aouthdr_ext->o_modtype);
+ aouthdr_int->o_maxstack = bfd_h_get_32(abfd, aouthdr_ext->o_maxstack);
+#endif
}
static unsigned int
return sizeof(AOUTHDR);
}
-static void
+static void
DEFUN(coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int),
bfd *abfd AND
SCNHDR *scnhdr_ext AND
#endif
}
-static unsigned int
+static unsigned int
DEFUN(coff_swap_scnhdr_out,(abfd, in, out),
bfd *abfd AND
PTR in AND
PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
#endif
-#if defined(I960)
+#if defined(I960)
PUTWORD(abfd, scnhdr_int->s_align, (bfd_byte *) scnhdr_ext->s_align);
#endif
return sizeof(SCNHDR);
name[sizeof (hdr->s_name)] = 0;
return_section = bfd_make_section(abfd, name);
+ if (return_section == NULL)
+ return false;
}
/* s_paddr is presumed to be = to s_vaddr */
long machine;
size_t readsize; /* length of file_info */
SCNHDR *external_sections;
-
+
/* Build a play area */
if (coff_mkobject(abfd) != true)
return 0;
coff = coff_data(abfd);
-
-
+
+
external_sections = (SCNHDR *)bfd_alloc(abfd, readsize = (nscns * SCNHSZ));
-
+
if (bfd_read((PTR)external_sections, 1, readsize, abfd) != readsize) {
goto fail;
}
-
-
+
+
/* Now copy data as required; construct all asections etc */
coff->symbol_index_slew = 0;
coff->relocbase =0;
machine = 0;
break;
#endif
-
-#ifdef A29K_MAGIC_BIG
+
+#ifdef A29K_MAGIC_BIG
case A29K_MAGIC_BIG:
case A29K_MAGIC_LITTLE:
arch = bfd_arch_a29k;
machine = 0;
break;
#endif
-
+
#ifdef MIPS
case MIPS_MAGIC_1:
case MIPS_MAGIC_2:
machine = 0;
break;
#endif
-
+
#ifdef MC68MAGIC
case MC68MAGIC:
case M68MAGIC:
case I960ROMAGIC:
case I960RWMAGIC:
arch = bfd_arch_i960;
- switch (F_I960TYPE & internal_f->f_flags)
+ switch (F_I960TYPE & internal_f->f_flags)
{
default:
case F_I960CORE:
case F_I960KA:
machine = bfd_mach_i960_ka_sa;
break;
-
}
break;
#endif
#endif
-
+
+#ifdef U802ROMAGIC
+ case U802ROMAGIC:
+ case U802WRMAGIC:
+ case U802TOCMAGIC:
+ arch = bfd_arch_rs6000;
+ machine = 6000;
+ break;
+#endif
+
+
default: /* Unreadable input file type */
arch = bfd_arch_obscure;
break;
}
-
+
bfd_default_set_arch_mach(abfd, arch, machine);
if (!(internal_f->f_flags & F_RELFLG))
abfd->flags |= HAS_RELOC;
abfd->flags |= HAS_LINENO;
if (!(internal_f->f_flags & F_LSYMS))
abfd->flags |= HAS_LOCALS;
-
-
+
+
bfd_get_symcount(abfd) = internal_f->f_nsyms;
if (internal_f->f_nsyms)
abfd->flags |= HAS_SYMS;
-
+
coff->sym_filepos = internal_f->f_symptr;
-
+
/* These members communicate important constants about the symbol table
to GDB's symbol-reading code. These `constants' unfortunately vary
from coff implementation to implementation... */
coff->local_auxesz = AUXESZ;
coff->local_linesz = LINESZ;
#endif
-
+
coff->symbols = (coff_symbol_type *) NULL;
bfd_get_start_address(abfd) = internal_f->f_opthdr ? internal_a->entry : 0;
-
+
return abfd->xvec;
fail:
bfd_release(abfd, coff);
AOUTHDR opthdr;
struct internal_filehdr internal_f;
struct internal_aouthdr internal_a;
-
+
bfd_error = system_call_error;
-
+
/* figure out how much to read */
if (bfd_read((PTR) &filehdr, 1, FILHSZ, abfd) != FILHSZ)
return 0;
-
+
bfd_swap_filehdr_in(abfd, &filehdr, &internal_f);
-
+
if (BADMAG(internal_f)) {
bfd_error = wrong_format;
return 0;
}
nscns =internal_f.f_nscns;
-
+
if (internal_f.f_opthdr) {
if (bfd_read((PTR) &opthdr, 1,AOUTSZ, abfd) != AOUTSZ) {
return 0;
}
bfd_swap_aouthdr_in(abfd, (char *)&opthdr, (char *)&internal_a);
}
-
+
/* Seek past the opt hdr stuff */
bfd_seek(abfd, internal_f.f_opthdr + FILHSZ, SEEK_SET);
-
+
/* if the optional header is NULL or not the correct size then
quit; the only difference I can see between m88k dgux headers (MC88DMAGIC)
and Intel 960 readwrite headers (I960WRMAGIC) is that the
optional header is of a different size.
-
+
But the mips keeps extra stuff in it's opthdr, so dont check
when doing that
*/
-
+
#if defined(M88) || defined(I960)
if (internal_f.f_opthdr != 0 && AOUTSZ != internal_f.f_opthdr)
return (bfd_target *)NULL;
#endif
-
+
return coff_real_object_p(abfd, nscns, &internal_f, &internal_a);
}
#ifndef NO_COFF_LINENOS
-static void
+static void
DEFUN(coff_count_linenumbers,(abfd),
bfd *abfd)
{
s = s->next;
}
}
-
-
+
+
for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
asymbol *q_maybe = *p;
if (q_maybe->the_bfd->xvec->flavour == bfd_target_coff_flavour) {
#ifndef NO_COFF_SYMBOLS
-/*
+/*
Takes a bfd and a symbol, returns a pointer to the coff specific area
of the symbol if there is one.
*/
bfd *ignore_abfd AND
asymbol *symbol)
{
- if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour)
+ if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour)
return (coff_symbol_type *)NULL;
-
+
if (symbol->the_bfd->tdata == (PTR)NULL)
return (coff_symbol_type *)NULL;
-
+
return (coff_symbol_type *) symbol;
}
else if (coff_symbol_ptr->symbol.flags & BSF_UNDEFINED) {
syment->n_scnum = N_UNDEF;
syment->n_value = 0;
- }
+ }
else if (coff_symbol_ptr->symbol.flags & BSF_ABSOLUTE) {
syment->n_scnum = N_ABS;
syment->n_value = coff_symbol_ptr->symbol.value;
- }
+ }
else {
if (coff_symbol_ptr->symbol.section) {
- syment->n_scnum =
+ syment->n_scnum =
coff_symbol_ptr->symbol.section->output_section->index+1;
-
- syment->n_value =
+
+ syment->n_value =
coff_symbol_ptr->symbol.value +
coff_symbol_ptr->symbol.section->output_offset +
coff_symbol_ptr->symbol.section->output_section->vma;
else {
syment->n_scnum = N_ABS;
- syment->n_value = coff_symbol_ptr->symbol.value;
+ syment->n_value = coff_symbol_ptr->symbol.value;
}
}
}
/* run through all the symbols in the symbol table and work out what
- their indexes into the symbol table will be when output
+ their indexes into the symbol table will be when output
Coff requires that each C_FILE symbol points to the next one in the
chain, and that the last one points to the first external symbol. We
unsigned int native_index = 0;
struct internal_syment *last_file = (struct internal_syment *)NULL;
unsigned int symbol_index;
- for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
+ for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
{
coff_symbol_type *coff_symbol_ptr = coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
if (coff_symbol_ptr && coff_symbol_ptr->native) {
combined_entry_type *s = coff_symbol_ptr->native;
int i;
- if (s->u.syment.n_sclass == C_FILE)
+ if (s->u.syment.n_sclass == C_FILE)
{
if (last_file != (struct internal_syment *)NULL) {
last_file->n_value = native_index;
entries are changed to the entries' index in the output symbol table.
*/
-static void
+static void
DEFUN(coff_mangle_symbols,(bfd_ptr),
bfd *bfd_ptr)
{
unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
-
unsigned int symbol_index;
-
- for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
+ for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
{
- coff_symbol_type *coff_symbol_ptr = coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
- if (coff_symbol_ptr && coff_symbol_ptr->native ) {
+ coff_symbol_type *coff_symbol_ptr =
+ coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
+
+ if (coff_symbol_ptr && coff_symbol_ptr->native) {
int i;
combined_entry_type *s = coff_symbol_ptr->native;
-
-
-
-
for (i = 0; i < s->u.syment.n_numaux ; i++) {
combined_entry_type *a = s + i + 1;
if (a->fix_tag) {
- a->u.auxent.x_sym.x_tagndx.l = a->u.auxent.x_sym.x_tagndx.p->offset;
+ a->u.auxent.x_sym.x_tagndx.l =
+ a->u.auxent.x_sym.x_tagndx.p->offset;
}
if (a->fix_end) {
a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l =
}
}
-#if 0
- unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
- asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
- struct internal_syment *last_tagndx = (struct internal_syment *)NULL;
- struct internal_syment *last_file = (struct internal_syment *)NULL;
- struct internal_syment *last_fcn = (struct internal_syment *)NULL;
- struct internal_syment *block_stack[50];
- struct internal_syment **last_block = &block_stack[0];
- boolean first_time = true;
- unsigned int symbol_index;
- unsigned int native_index = 0;
-
- for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) {
- coff_symbol_type *coff_symbol_ptr =
- coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
- if (coff_symbol_ptr == (coff_symbol_type *)NULL) {
- /*
- This symbol has no coff information in it, it will take up
- only one slot in the output symbol table
- */
- native_index++;
- }
- else {
- struct internal_syment *syment = coff_symbol_ptr->native;
- if (syment == (struct internal_syment *)NULL) {
- native_index++;
- }
- else {
- /* Normalize the symbol flags */
- if (coff_symbol_ptr->symbol.flags & BSF_FORT_COMM) {
- /* a common symbol is undefined with a value */
- syment->n_scnum = N_UNDEF;
- syment->n_value = coff_symbol_ptr->symbol.value;
- }
- else if (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) {
- syment->n_value = coff_symbol_ptr->symbol.value;
- }
- else if (coff_symbol_ptr->symbol.flags & BSF_UNDEFINED) {
- syment->n_scnum = N_UNDEF;
- syment->n_value = 0;
- }
- else if (coff_symbol_ptr->symbol.flags & BSF_ABSOLUTE) {
- syment->n_scnum = N_ABS;
- syment->n_value = coff_symbol_ptr->symbol.value;
- }
- else {
- syment->n_scnum =
- coff_symbol_ptr->symbol.section->output_section->index+1;
-
- syment->n_value =
- coff_symbol_ptr->symbol.value +
- coff_symbol_ptr->symbol.section->output_offset +
- coff_symbol_ptr->symbol.section->output_section->vma;
- }
-
-
- /* If this symbol ties up something then do it */
-
- if (syment->n_sclass == C_FILE && last_file != (struct internal_syment *)NULL)
- {
- last_file->n_value = native_index;
- }
- else if ((syment->n_sclass == C_EXT
- || syment->n_sclass == C_STAT
-#ifdef C_LEAFEXT
- || syment->n_sclass == C_LEAFEXT
- || syment->n_sclass == C_LEAFSTAT
-#endif
- )
- && last_fcn != (struct internal_syment *)NULL)
- {
- union internal_auxent *auxent = (union internal_auxent *)(last_fcn+1);
- auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = native_index;
- last_fcn = (struct internal_syment *)NULL;
-
- }
- else if (syment->n_sclass == C_EOS && last_tagndx != (struct internal_syment*)NULL)
- {
- union internal_auxent *auxent = (union internal_auxent *)(last_tagndx+1);
- /* Remember that we keep the native index in the offset
- so patch the beginning of the struct to point to this
- */
-/*if (last_
- auxent->x_sym.x_tagndx = last_tagndx->_n._n_n._n_offset;*/
- auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = syment->n_numaux + 1 + native_index;
- /* Now point the eos to the structure */
- auxent = (union internal_auxent *)(syment+1);
- auxent->x_sym.x_tagndx.l = last_tagndx->_n._n_n._n_offset;
- }
- else if (syment->n_sclass == C_BLOCK
- && coff_symbol_ptr->symbol.name[1] == 'e')
- {
- union internal_auxent *auxent = (union internal_auxent *)((*(--last_block))+1);
- auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = native_index + syment->n_numaux + 1;
- }
- if (syment->n_sclass == C_EXT
- && !ISFCN(syment->n_type)
- && first_time == true
- && last_file != (struct internal_syment *)NULL) {
- /* This is the first external symbol seen which isn't a
- function place it in the last .file entry */
- last_file->n_value = native_index;
- first_time = false;
- }
-#ifdef C_LEAFPROC
- if (syment->n_sclass == C_LEAFPROC &&
- syment->n_numaux == 2) {
- union internal_auxent *auxent = (union internal_auxent *)(syment+2);
- /* This is the definition of a leaf proc, we'll relocate the
- address */
- auxent->x_bal.x_balntry =
- coff_symbol_ptr->symbol.section->output_offset +
- coff_symbol_ptr->symbol.section->output_section->vma +
- auxent->x_bal.x_balntry ;
- }
-#endif
- /* If this symbol needs to be tied up then remember some facts */
- if (syment->n_sclass == C_FILE)
- {
- last_file = syment;
- }
- if (syment->n_numaux != 0) {
- /*
- If this symbol would like to point to something in the
- future then remember where it is
- */
- if (uses_x_sym_x_tagndx_p(bfd_ptr, syment)) {
- /*
- If this is a ref to a structure then we'll tie it up
- now - there are never any forward refs for one
- */
- if (syment->n_sclass == C_STRTAG ||
- syment->n_sclass == C_ENTAG ||
- syment->n_sclass == C_UNTAG) {
- last_tagndx = syment;
- }
- else {
- /*
- This is a ref to a structure - the structure must
- have been defined within the same file, and previous
- to this point, so we can deduce the new tagndx
- directly.
- */
- union internal_auxent *auxent = (union internal_auxent *)(syment+1);
- bfd *bfd_ptr = coff_symbol_ptr->symbol.the_bfd;
- struct internal_syment *base = obj_raw_syments(bfd_ptr);
-/* auxent->x_sym.x_tagndx = base[auxent->x_sym.x_tagndx]._n._n_n._n_offset;*/
-
-
- }
- }
- if (ISFCN(syment->n_type)) {
- last_fcn = syment;
- }
- if (syment->n_sclass == C_BLOCK
- && coff_symbol_ptr->symbol.name[1] == 'b')
- {
- *last_block++ = syment;
- }
- }
- syment->_n._n_n._n_offset = native_index;
- native_index = native_index + 1 + syment->n_numaux;
- }
- }
- }
-}
-
-
-#endif
-static int string_size;
+static int string_size;
static void
DEFUN(coff_fix_symbol_name,(ignore_abfd, symbol, native),
bfd *ignore_abfd AND
name = (char *)symbol->name;
}
name_length = strlen(name);
-
+
if (native->u.syment.n_sclass == C_FILE) {
strncpy(native->u.syment._n._n_name, ".file", SYMNMLEN);
auxent = &(native+1)->u.auxent;
-
+
#ifdef COFF_LONG_FILENAMES
if (name_length <= FILNMLEN) {
strncpy(auxent->x_file.x_fname, name, FILNMLEN);
-static unsigned int
+static unsigned int
DEFUN(coff_write_symbol,(abfd, symbol, native, written),
bfd *abfd AND
asymbol *symbol AND
coff_fix_symbol_name(abfd, symbol, native);
coff_swap_sym_out(abfd, &native->u.syment, &buf);
bfd_write((PTR)& buf, 1, SYMESZ, abfd);
- for (j = 0; j != native->u.syment.n_numaux; j++)
+ for (j = 0; j != native->u.syment.n_numaux; j++)
{
AUXENT buf1;
bzero((PTR)&buf, AUXESZ);
}
#endif
}
-
+
#ifdef HASPAD1
native->u.syment.pad1[0] = 0;
native->u.syment.pad1[0] = 0;
#endif
-
+
native->u.syment.n_type = 0;
if (symbol->flags & BSF_LOCAL)
native->u.syment.n_sclass = C_STAT;
- else
+ else
native->u.syment.n_sclass = C_EXT;
native->u.syment.n_numaux = 0;
return coff_write_symbol(abfd, symbol, native, written);
}
-static unsigned int
+static unsigned int
DEFUN(coff_write_native_symbol,(abfd, symbol, written),
bfd *abfd AND
coff_symbol_type *symbol AND
lineno[count].u.offset = written;
if (native->u.syment.n_numaux) {
union internal_auxent *a = &((native+1)->u.auxent);
-
- a->x_sym.x_fcnary.x_fcn.x_lnnoptr =
+
+ a->x_sym.x_fcnary.x_fcn.x_lnnoptr =
symbol->symbol.section->output_section->moving_line_filepos;
}
/*
}
symbol->symbol.section->output_section->moving_line_filepos +=
count * LINESZ;
-
}
return coff_write_symbol(abfd, &( symbol->symbol), native,written);
}
-static void
+static void
DEFUN(coff_write_symbols,(abfd),
bfd *abfd)
{
asymbol **p;
string_size = 0;
-
-
+
+
/* Seek to the right place */
bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
-
+
/* Output all the symbols we have */
-
+
written = 0;
- for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
+ for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
{
asymbol *symbol = *p;
coff_symbol_type *c_symbol = coff_symbol_from(abfd, symbol);
-
-
if (c_symbol == (coff_symbol_type *) NULL ||
c_symbol->native == (combined_entry_type *)NULL)
bfd_get_symcount(abfd) = written;
/* Now write out strings */
-
- if (string_size != 0)
+
+ if (string_size != 0)
{
unsigned int size = string_size + 4;
bfd_byte buffer[4];
bfd_h_put_32(abfd, size, buffer);
bfd_write((PTR) buffer, 1, sizeof(buffer), abfd);
- for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
+ for (p = abfd->outsymbols, i = 0;
+ i < limit;
+ i++, p++)
{
asymbol *q = *p;
size_t name_length = strlen(q->name);
maxlen = ((c_symbol != NULL && c_symbol->native != NULL) &&
(c_symbol->native->u.syment.n_sclass == C_FILE)) ?
FILNMLEN : SYMNMLEN;
-
+
if (name_length > maxlen) {
bfd_write((PTR) (q->name), 1, name_length + 1, abfd);
}
out 4 so that any stupid coff reader which tries to read
the string table even when there isn't one won't croak.
*/
-
+
uint32e_type size = 4;
size = size;
bfd_write((PTR)&size, 1, sizeof(size), abfd);
-
+
}
}
@code{external_reloc} and written out to disk.
*/
-static void
+static void
DEFUN(coff_write_relocs,(abfd),
bfd *abfd)
{
for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
unsigned int i;
struct external_reloc dst;
-
+
arelent **p = s->orelocation;
bfd_seek(abfd, s->rel_filepos, SEEK_SET);
for (i = 0; i < s->reloc_count; i++) {
#ifndef NO_COFF_LINENOS
-static void
+static void
DEFUN(coff_write_linenumbers,(abfd),
bfd *abfd)
{
#ifndef NO_COFF_SYMBOLS
-static void
+static void
DEFUN(coff_print_symbol,(ignore_abfd, filep, symbol, how),
bfd *ignore_abfd AND
PTR filep AND
fprintf(file, "coff %lx %lx", (unsigned long) coffsymbol(symbol)->native,
(unsigned long) coffsymbol(symbol)->lineno);
break;
+ case bfd_print_symbol_nm:
case bfd_print_symbol_all:
{
CONST char *section_name = symbol->section == (asection *) NULL ?
"*abs" : symbol->section->name;
bfd_print_symbol_vandf((PTR) file, symbol);
-
+
fprintf(file, " %-5s %s %s %s",
section_name,
coffsymbol(symbol)->native ? "n" : "g",
coffsymbol(symbol)->lineno ? "l" : " ",
symbol->name);
}
-
-
+
+
break;
}
}
unsigned short *flagsp)
{
switch (bfd_get_arch(abfd)) {
-
+
#ifdef I960ROMAGIC
-
+
case bfd_arch_i960:
-
+
{
unsigned flags;
*magicp = I960ROMAGIC;
*magicp = MC68MAGIC;
return true;
#endif
-
+
#ifdef MC88MAGIC
case bfd_arch_m88k:
*magicp = MC88OMAGIC;
return true;
break;
#endif
-
+
+#ifdef U802TOCMAGIC
+ case bfd_arch_rs6000:
+ *magicp = U802TOCMAGIC;
+ break;
+#endif
+
default: /* Unknown architecture */
/* return false; -- fall through to "return false" below, to avoid
- "statement never reached" errors on the one below. */
+ "statement never reached" errors on the one below. */
break;
}
-
+
return false;
}
/* Calculate the file position for each section. */
-static void
+static void
DEFUN(coff_compute_section_file_positions,(abfd),
bfd *abfd)
{
- asection *current;
- file_ptr sofar = FILHSZ;
- if (bfd_get_start_address(abfd)) {
- /*
- A start address may have been added to the original file. In this
- case it will need an optional header to record it.
- */
- abfd->flags |= EXEC_P;
- }
- if (abfd->flags & EXEC_P)
- sofar += AOUTSZ;
-
-
- sofar += abfd->section_count * SCNHSZ;
- for (current = abfd->sections;
- current != (asection *)NULL;
- current = current->next) {
- /* Only deal with sections which have contents */
- if (!(current->flags & SEC_HAS_CONTENTS))
- continue;
-
- /* Align the sections in the file to the same boundary on
- which they are aligned in virtual memory. I960 doesn't
- do this (FIXME) so we can stay in sync with Intel. 960
- doesn't yet page from files... */
+ asection *current;
+ asection *previous = (asection *)NULL;
+ file_ptr sofar = FILHSZ;
+ file_ptr old_sofar;
+ if (bfd_get_start_address(abfd))
+ {
+ /* A start address may have been added to the original file. In this
+ case it will need an optional header to record it. */
+ abfd->flags |= EXEC_P;
+ }
+
+ if (abfd->flags & EXEC_P)
+ sofar += AOUTSZ;
+
+ sofar += abfd->section_count * SCNHSZ;
+ for (current = abfd->sections;
+ current != (asection *)NULL;
+ current = current->next) {
+
+ /* Only deal with sections which have contents */
+ if (!(current->flags & SEC_HAS_CONTENTS))
+ continue;
+
+ /* Align the sections in the file to the same boundary on
+ which they are aligned in virtual memory. I960 doesn't
+ do this (FIXME) so we can stay in sync with Intel. 960
+ doesn't yet page from files... */
#ifndef I960
- sofar = ALIGN(sofar, 1 << current->alignment_power);
-#endif
- /* FIXME, in demand paged files, the low order bits of the file
- offset must match the low order bits of the virtual address.
- "Low order" is apparently implementation defined. Add code
- here to round sofar up to match the virtual address. */
-
- current->filepos = sofar;
- sofar += current->size;
- }
- obj_relocbase(abfd) = sofar;
+ {
+ /* make sure this section is aligned on the right boundary - by
+ padding the previous section up if necessary */
+
+ old_sofar= sofar;
+ sofar = ALIGN(sofar, 1 << current->alignment_power);
+ if (previous != (asection *)NULL) {
+ previous->size += sofar - old_sofar;
+ }
+ }
+
+#endif
+ /* FIXME, in demand paged files, the low order bits of the file
+ offset must match the low order bits of the virtual address.
+ "Low order" is apparently implementation defined. Add code
+ here to round sofar up to match the virtual address. */
+
+ current->filepos = sofar;
+
+ /* make sure that this section is of the right size too */
+ old_sofar = sofar += current->size;
+ sofar = ALIGN(sofar, 1 << current->alignment_power);
+ current->size += sofar - old_sofar ;
+
+ previous = current;
+ }
+ obj_relocbase(abfd) = sofar;
}
asection *text_sec = NULL;
asection *data_sec = NULL;
asection *bss_sec = NULL;
-
+
struct internal_filehdr internal_f;
struct internal_aouthdr internal_a;
-
-
+
+
bfd_error = system_call_error;
-
-
+
+
if(abfd->output_has_begun == false) {
coff_compute_section_file_positions(abfd);
}
-
+
if (abfd->sections != (asection *)NULL) {
scn_base = abfd->sections->filepos;
}
if (bfd_seek(abfd, scn_base, SEEK_SET) != 0)
return false;
reloc_base = obj_relocbase(abfd);
-
+
/* Make a pass through the symbol table to count line number entries and
put them into the correct asections */
-
+
#ifndef NO_COFF_LINENOS
coff_count_linenumbers(abfd);
#endif
data_base = scn_base;
-
+
/* Work out the size of the reloc and linno areas */
-
+
for (current = abfd->sections; current != NULL; current = current->next) {
reloc_size += current->reloc_count * RELSZ;
#ifndef NO_COFF_LINENOS
#endif
data_base += SCNHSZ;
}
-
+
lineno_base = reloc_base + reloc_size;
sym_base = lineno_base + lnno_size;
-
+
/* Indicate in each section->line_filepos its actual file address */
for (current = abfd->sections; current != NULL; current = current->next) {
if (current->lineno_count) {
current->rel_filepos = 0;
}
}
-
+
/* Write section headers to the file. */
-
+
bfd_seek(abfd,
(file_ptr) ((abfd->flags & EXEC_P) ?
(FILHSZ + AOUTSZ) : FILHSZ),
SEEK_SET);
-
+
{
#if 0
unsigned int pad = abfd->flags & D_PAGED ? data_base : 0;
#endif
unsigned int pad = 0;
-
+
for (current = abfd->sections; current != NULL; current = current->next) {
struct internal_scnhdr section;
strncpy(&(section.s_name[0]), current->name, 8);
if (current->size - pad == 0 ||
(current->flags & SEC_LOAD) == 0) {
section.s_scnptr = 0;
-
}
else {
section.s_scnptr = current->filepos;
hasrelocs = true;
if (current->lineno_count != 0)
haslinno = true;
-
+
section.s_flags = sec_to_styp_flags(current->name,current->flags);
if (!strcmp(current->name, _TEXT)) {
data_sec = current;
} else if (!strcmp(current->name, _BSS)) {
bss_sec = current;
- }
-
+ }
+
#ifdef I960
section.s_align = (current->alignment_power
? 1 << current->alignment_power
internal_f.f_flags |= flags;
/* ...and the "opt"hdr... */
-#ifdef A29K
+#ifdef A29K
# ifdef ULTRA3 /* NYU's machine */
/* FIXME: This is a bogus check. I really want to see if there
* is a .shbss or a .shdata section, if so then set the magic
* number to indicate a shared data executable.
- */
+ */
if (internal_f.f_nscns >= 7)
internal_a.magic = SHMAGIC; /* Shared magic */
else
#define __A_MAGIC_SET__
#endif /* A29K */
#ifdef I960
- internal_a.magic = (magic == I960ROMAGIC ? NMAGIC : OMAGIC);
+ internal_a.magic = (magic == I960ROMAGIC ? NMAGIC : OMAGIC);
#define __A_MAGIC_SET__
#endif /* I960 */
#if M88
#if M68 || I386 || MIPS
#define __A_MAGIC_SET__
- /* Never was anything here for the 68k */
+ /* Never was anything here for the 68k */
#endif /* M88 */
+#if RS6000COFF_C
+#define __A_MAGIC_SET__
+ internal_a.magic = (abfd->flags & D_PAGED)? RS6K_AOUTHDR_ZMAGIC:
+ (abfd->flags & WP_TEXT)? RS6K_AOUTHDR_NMAGIC:
+ RS6K_AOUTHDR_OMAGIC;
+#endif
+
#ifndef __A_MAGIC_SET__
# include "Your aouthdr magic number is not being set!"
#else
}
#endif
-static PTR
+static PTR
buy_and_read(abfd, where, seek_direction, size)
bfd *abfd;
file_ptr where;
char string_table_size_buffer[4];
unsigned int string_table_size;
char *string_table;
- /*
- At this point we should be "seek"'d to the end of the
- symbols === the symbol table size.
- */
-
+
+ /* At this point we should be "seek"'d to the end of the
+ symbols === the symbol table size. */
if (bfd_read((char *) string_table_size_buffer,
sizeof(string_table_size_buffer),
1, abfd) != sizeof(string_table_size)) {
bfd_error = system_call_error;
return (NULL);
} /* on error */
-
+
string_table_size = bfd_h_get_32(abfd, (bfd_byte *) string_table_size_buffer);
-
+
if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) {
bfd_error = no_memory;
return (NULL);
if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) {
bfd_error = system_call_error;
return (NULL);
- }
+ }
return string_table;
}
+/* Allocate space for the ".debug" section, and read it.
+ We did not read the debug section until now, because
+ we didn't want to go to the trouble until someone needed it. */
+
+static char *
+DEFUN(build_debug_section,(abfd),
+ bfd *abfd)
+{
+ char *debug_section;
+ long position;
+
+ asection *sect = bfd_get_section_by_name (abfd, ".debug");
+
+ if (!sect) {
+ bfd_error = no_debug_section;
+ return NULL;
+ }
+
+ debug_section = (PTR) bfd_alloc (abfd, bfd_section_size (abfd, sect));
+ if (debug_section == NULL) {
+ bfd_error = no_memory;
+ return NULL;
+ }
+
+ /* Seek to the beginning of the `.debug' section and read it.
+ Save the current position first; it is needed by our caller.
+ Then read debug section and reset the file pointer. */
+
+ position = bfd_tell (abfd);
+ bfd_seek (abfd, sect->filepos, SEEK_SET);
+ if (bfd_read (debug_section, bfd_section_size (abfd, sect), 1, abfd)
+ != bfd_section_size (abfd, sect)) {
+ bfd_error = system_call_error;
+ return NULL;
+ }
+ bfd_seek (abfd, position, SEEK_SET);
+ return debug_section;
+}
+
+
/* Return a pointer to a malloc'd copy of 'name'. 'name' may not be
\0-terminated, but will not exceed 'maxlen' characters. The copy *will*
be \0-terminated. */
{
int len;
char *newname;
-
+
for (len = 0; len < maxlen; ++len) {
if (name[len] == '\0') {
break;
}
}
-
+
if ((newname = (PTR) bfd_alloc(abfd, len+1)) == NULL) {
bfd_error = no_memory;
return (NULL);
}
-/*
-read a symbol table into freshly mallocated memory, swap it, and knit the
-symbol names into a normalized form. By normalized here I mean that all
-symbols have an n_offset pointer that points to a NULL terminated string.
-Oh, and the first symbol MUST be a C_FILE. If there wasn't one there
-before, put one there.
-*/
+/* Read a symbol table into freshly bfd_allocated memory, swap it, and
+ knit the symbol names into a normalized form. By normalized here I
+ mean that all symbols have an n_offset pointer that points to a null-
+ terminated string. */
+
+#ifndef SYMNAME_IN_DEBUG
+#define SYMNAME_IN_DEBUG(x) 0
+#endif
static combined_entry_type *
DEFUN(get_normalized_symtab,(abfd),
bfd *abfd)
{
-
combined_entry_type *internal;
combined_entry_type *internal_ptr;
combined_entry_type *internal_end;
SYMENT *raw_src;
SYMENT *raw_end;
char *string_table = NULL;
+ char *debug_section = NULL;
unsigned long size;
-
unsigned int raw_size;
if (obj_raw_syments(abfd) != (combined_entry_type *)NULL) {
return obj_raw_syments(abfd);
*/
/* Swap all the raw entries */
- for (raw_src = raw, internal_ptr = internal; raw_src < raw_end; raw_src++, internal_ptr++) {
+ for (raw_src = raw, internal_ptr = internal;
+ raw_src < raw_end;
+ raw_src++, internal_ptr++) {
+
unsigned int i;
- coff_swap_sym_in(abfd, (char *)raw_src, (char *)&internal_ptr->u.syment);
+ coff_swap_sym_in(abfd, (char *)raw_src, (char *)&internal_ptr->u.syment);
internal_ptr->fix_tag = 0;
internal_ptr->fix_end = 0;
- for (i = internal_ptr->u.syment.n_numaux; i; --i, raw_src++, internal_ptr++) {
+ for (i = internal_ptr->u.syment.n_numaux;
+ i;
+ --i, raw_src++, internal_ptr++) {
+
(internal_ptr+1)->fix_tag = 0;
(internal_ptr+1)->fix_end = 0;
- coff_swap_aux_in(abfd, (char *)(raw_src +1), internal_ptr->u.syment.n_type,
- internal_ptr->u.syment.n_sclass, & (internal_ptr+1)->u.auxent);
+ coff_swap_aux_in(abfd, (char *)(raw_src +1),
+ internal_ptr->u.syment.n_type,
+ internal_ptr->u.syment.n_sclass,
+ &(internal_ptr+1)->u.auxent);
- coff_pointerize_aux(abfd,
+ coff_pointerize_aux(abfd,
internal,
internal_ptr->u.syment.n_type,
internal_ptr->u.syment.n_sclass,
internal_ptr +1);
}
}
-
+
/* Free all the raw stuff */
bfd_release(abfd, raw);
for (internal_ptr = internal; internal_ptr < internal_end;
- internal_ptr ++)
+ internal_ptr ++)
{
if (internal_ptr->u.syment.n_sclass == C_FILE) {
/* make a file symbol point to the name in the auxent, since
the text ".file" is redundant */
if ((internal_ptr+1)->u.auxent.x_file.x_n.x_zeroes == 0) {
- /* the filename is a long one, point into the string table
- */
+ /* the filename is a long one, point into the string table */
if (string_table == NULL) {
string_table = build_string_table(abfd);
}
else {
/* ordinary short filename, put into memory anyway */
internal_ptr->u.syment._n._n_n._n_offset = (int)
- copy_name(abfd, (internal_ptr+1)->u.auxent.x_file.x_fname, FILNMLEN);
-
+ copy_name(abfd, (internal_ptr+1)->u.auxent.x_file.x_fname,
+ FILNMLEN);
}
}
else {
if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) {
- /*
- This is a "short" name. Make it long.
- */
+ /* This is a "short" name. Make it long. */
unsigned long i = 0;
char *newstring = NULL;
- /*
- find the length of this string without walking into memory
- that isn't ours.
- */
-
+
+ /* find the length of this string without walking into memory
+ that isn't ours. */
for (i = 0; i < 8; ++i) {
if (internal_ptr->u.syment._n._n_name[i] == '\0') {
break;
} /* if end of string */
} /* possible lengths of this string. */
-
+
if ((newstring = (PTR) bfd_alloc(abfd, ++i)) == NULL) {
bfd_error = no_memory;
return (NULL);
strncpy(newstring, internal_ptr->u.syment._n._n_name, i-1);
internal_ptr->u.syment._n._n_n._n_offset = (int) newstring;
internal_ptr->u.syment._n._n_n._n_zeroes = 0;
-
}
- else {
- /* This is a long name already. Just point it at the string in memory. */
+ else if (!SYMNAME_IN_DEBUG(&internal_ptr->u.syment)) {
+ /* Long name already. Point symbol at the string in the table. */
if (string_table == NULL) {
string_table = build_string_table(abfd);
}
- internal_ptr->u.syment._n._n_n._n_offset =
- (int) (string_table - 4 + internal_ptr->u.syment._n._n_n._n_offset);
- }
+ internal_ptr->u.syment._n._n_n._n_offset = (int)
+ (string_table - 4 + internal_ptr->u.syment._n._n_n._n_offset);
+ }
+ else {
+ /* Long name in debug section. Very similar. */
+ if (debug_section == NULL) {
+ debug_section = build_debug_section(abfd);
+ }
+ internal_ptr->u.syment._n._n_n._n_offset = (int)
+ (debug_section + internal_ptr->u.syment._n._n_n._n_offset);
+ }
}
internal_ptr += internal_ptr->u.syment.n_numaux;
- }
+ }
obj_raw_syments(abfd) = internal;
- obj_string_table(abfd) = string_table;
-
+
return (internal);
} /* get_normalized_symtab() */
{
LINENO *native_lineno;
alent *lineno_cache;
-
+
BFD_ASSERT(asect->lineno == (alent *) NULL);
-
+
native_lineno = (LINENO *) buy_and_read(abfd,
asect->line_filepos,
SEEK_SET,
if (lineno_cache == NULL) {
bfd_error = no_memory;
return false;
- } else {
+ } else {
unsigned int counter = 0;
alent *cache_ptr = lineno_cache;
LINENO *src = native_lineno;
-
+
while (counter < asect->lineno_count) {
struct internal_lineno dst;
coff_swap_lineno_in(abfd, src, &dst);
cache_ptr->line_number = dst.l_lnno;
-
+
if (cache_ptr->line_number == 0) {
coff_symbol_type *sym =
(coff_symbol_type *) (dst.l_addr.l_symndx
cache_ptr->u.offset = dst.l_addr.l_paddr
- bfd_section_vma(abfd, asect);
} /* If no linenumber expect a symbol index */
-
+
cache_ptr++;
src++;
counter++;
}
cache_ptr->line_number = 0;
-
+
}
asect->lineno = lineno_cache;
/* FIXME, free native_lineno here, or use alloca or something. */
combined_entry_type *native_symbols;
coff_symbol_type *cached_area;
unsigned int *table_ptr;
-
+
unsigned int number_of_symbols = 0;
if (obj_symbols(abfd))
return true;
bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
-
+
/* Read in the symbol table */
if ((native_symbols = get_normalized_symtab(abfd)) == NULL) {
return (false);
} /* on error */
-
-
+
/* Allocate enough room for all the symbols in cached form */
cached_area =
(coff_symbol_type *)
bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(coff_symbol_type)));
-
+
if (cached_area == NULL) {
bfd_error = no_memory;
return false;
table_ptr =
(unsigned int *)
bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(unsigned int)));
-
+
if (table_ptr == NULL) {
bfd_error = no_memory;
return false;
- } else {
+ }
+ else
+ {
coff_symbol_type *dst = cached_area;
unsigned int last_native_index = bfd_get_symcount(abfd);
unsigned int this_index = 0;
combined_entry_type *src = native_symbols + this_index;
table_ptr[this_index] = number_of_symbols;
dst->symbol.the_bfd = abfd;
-
+
dst->symbol.name = (char *)(src->u.syment._n._n_n._n_offset);
/*
We use the native name field to point to the cached field
dst->symbol.flags |= BSF_NOT_AT_END;
#endif
/* Fall through to next case */
-
+
#endif
-
+
case C_EXT:
+#ifdef RS6000COFF_C
+ case C_HIDEXT:
+#endif
if ((src->u.syment.n_scnum) == 0) {
if ((src->u.syment.n_value) == 0) {
dst->symbol.flags = BSF_UNDEFINED;
dst->symbol.flags |= BSF_NOT_AT_END;
}
}
-
+
+
break;
+
case C_STAT: /* static */
#ifdef I960
case C_LEAFSTAT: /* static leaf procedure */
else
dst->symbol.value = (src->u.syment.n_value) ;
break;
-
+
case C_MOS: /* member of structure */
case C_EOS: /* end of structure */
#ifdef NOTDEF /* C_AUTOARG has the same value */
case C_AUTOARG: /* 960-specific storage class */
#endif
case C_TPDEF: /* type definition */
-
case C_ARG:
case C_AUTO: /* automatic variable */
case C_FIELD: /* bit field */
case C_MOE: /* member of enumeration */
case C_MOU: /* member of union */
case C_UNTAG: /* union tag */
-
dst->symbol.flags = BSF_DEBUGGING;
dst->symbol.value = (src->u.syment.n_value);
break;
-
+
case C_FILE: /* file name */
case C_STRTAG: /* structure tag */
+#ifdef RS6000COFF_C
+ case C_BINCL: /* beginning of include file */
+ case C_EINCL: /* ending of include file */
+ case C_GSYM:
+ case C_LSYM:
+ case C_PSYM:
+ case C_RSYM:
+ case C_RPSYM:
+ case C_STSYM:
+ case C_DECL:
+ case C_ENTRY:
+ case C_FUN:
+ case C_BSTAT:
+ case C_ESTAT:
+#endif
dst->symbol.flags = BSF_DEBUGGING;
dst->symbol.value = (src->u.syment.n_value);
-
break;
+
case C_BLOCK: /* ".bb" or ".eb" */
case C_FCN: /* ".bf" or ".ef" */
case C_EFCN: /* physical end of function */
Base the value as an index from the base of the section
*/
dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma;
-
break;
+
case C_NULL:
case C_EXTDEF: /* external definition */
case C_ULABEL: /* undefined label */
case C_LINE: /* line # reformatted as symbol table entry */
case C_ALIAS: /* duplicate tag */
case C_HIDDEN: /* ext symbol in dmert public lib */
-
default:
-
- fprintf(stderr,"Unrecognized storage class %d\n",
+
+ fprintf(stderr,"Unrecognized storage class %d\n",
src->u.syment.n_sclass);
abort();
dst->symbol.flags = BSF_DEBUGGING;
dst->symbol.value = (src->u.syment.n_value);
-
break;
}
-
+
BFD_ASSERT(dst->symbol.flags != 0);
-
+
dst->native = src;
-
+
dst->symbol.udata = 0;
dst->lineno = (alent *) NULL;
this_index += (src->u.syment.n_numaux) + 1;
number_of_symbols++;
} /* walk the native symtab */
} /* bfdize the native symtab */
-
+
obj_symbols(abfd) = cached_area;
obj_raw_syments(abfd) = native_symbols;
-
+
bfd_get_symcount(abfd) = number_of_symbols;
obj_convert(abfd) = table_ptr;
/* Slurp the line tables for each section too */
{
if (!coff_slurp_symbol_table(abfd))
return 0;
-
+
return (bfd_get_symcount(abfd) + 1) * (sizeof(coff_symbol_type *));
}
static unsigned int
-coff_get_symtab(abfd, alocation)
-bfd *abfd;
-asymbol **alocation;
- {
+DEFUN(coff_get_symtab, (abfd, alocation),
+ bfd *abfd AND
+ asymbol **alocation)
+{
unsigned int counter = 0;
coff_symbol_type *symbase;
coff_symbol_type **location = (coff_symbol_type **) (alocation);
if (!coff_slurp_symbol_table(abfd))
- return 0;
-
- for (symbase = obj_symbols(abfd); counter++ < bfd_get_symcount(abfd);)
- *(location++) = symbase++;
+ return 0;
+
+ symbase = obj_symbols(abfd);
+ while (counter < bfd_get_symcount(abfd))
+ {
+ /* This nasty code looks at the symbol to decide whether or
+ not it is descibes a constructor/destructor entry point. It
+ is structured this way to (hopefully) speed non matches */
+
+ if (symbase->symbol.name[9] == '$')
+ {
+ bfd_constructor_entry(abfd,
+ (asymbol **)location,
+ symbase->symbol.name[10] == 'I' ?
+ "CTOR" : "DTOR");
+ }
+
+ *(location++) = symbase++;
+ counter++;
+ }
*location++ = 0;
return bfd_get_symcount(abfd);
- }
+}
#endif /* NO_COFF_SYMBOLS */
/*doc*
@subsubsection Reading Relocations
Coff relocations are easily transformed into the internal BFD form
-(@code{arelent}).
+(@code{arelent}).
Reading a coff relocation table is done in the following stages:
@itemize @bullet
-@item
+@item
The entire coff relocation table is read into memory.
@item
Each relocation is processed in turn, first it is swapped from the
bfd *abfd AND
sec_ptr asect AND
asymbol **symbols)
- {
+{
RELOC *native_relocs;
arelent *reloc_cache;
if (asect->relocation)
return true;
if (asect->reloc_count == 0)
- return true;
+ return true;
+ if (asect->flags & SEC_CONSTRUCTOR)
+ return true;
#ifndef NO_COFF_SYMBOLS
if (!coff_slurp_symbol_table(abfd))
- return false;
+ return false;
#endif
native_relocs =
- (RELOC *) buy_and_read(abfd,
- asect->rel_filepos,
- SEEK_SET,
- (size_t) (RELSZ *
- asect->reloc_count));
+ (RELOC *) buy_and_read(abfd,
+ asect->rel_filepos,
+ SEEK_SET,
+ (size_t) (RELSZ *
+ asect->reloc_count));
reloc_cache = (arelent *)
- bfd_alloc(abfd, (size_t) (asect->reloc_count * sizeof(arelent)));
-
+ bfd_alloc(abfd, (size_t) (asect->reloc_count * sizeof(arelent)));
+
if (reloc_cache == NULL) {
- bfd_error = no_memory;
- return false;
+ bfd_error = no_memory;
+ return false;
} { /* on error */
- arelent *cache_ptr;
- RELOC *src;
- for (cache_ptr = reloc_cache,
- src = native_relocs;
- cache_ptr < reloc_cache + asect->reloc_count;
- cache_ptr++,
- src++) {
- struct internal_reloc dst;
- asymbol *ptr;
- bfd_swap_reloc_in(abfd, src, &dst);
-
- dst.r_symndx += obj_symbol_slew(abfd);
- cache_ptr->sym_ptr_ptr = symbols + obj_convert(abfd)[dst.r_symndx];
-#ifdef A29K
- /* AMD has two relocation entries for the 'consth' instruction.
- * The first is R_IHIHALF (part 1), the second is R_IHCONST
- * (part 2). The second entry's r_symndx does not contain
- * an index to a symbol but rather a value (apparently).
- * Also, see the ifdef below for saving the r_symndx value in addend.
- */
- if (dst.r_type == R_IHCONST) {
+ arelent *cache_ptr;
+ RELOC *src;
+ for (cache_ptr = reloc_cache,
+ src = native_relocs;
+ cache_ptr < reloc_cache + asect->reloc_count;
+ cache_ptr++,
+ src++) {
+ struct internal_reloc dst;
+ asymbol *ptr;
+ bfd_swap_reloc_in(abfd, src, &dst);
+
+ dst.r_symndx += obj_symbol_slew(abfd);
+ cache_ptr->sym_ptr_ptr = symbols + obj_convert(abfd)[dst.r_symndx];
+#ifdef A29K
+ /* AMD has two relocation entries for the 'consth' instruction.
+ * The first is R_IHIHALF (part 1), the second is R_IHCONST
+ * (part 2). The second entry's r_symndx does not contain
+ * an index to a symbol but rather a value (apparently).
+ * Also, see the ifdef below for saving the r_symndx value in addend.
+ */
+ if (dst.r_type == R_IHCONST) {
ptr = NULL;
- } else
+ } else
#endif
- ptr = *(cache_ptr->sym_ptr_ptr);
- cache_ptr->address = dst.r_vaddr;
- /*
- The symbols definitions that we have read in have been
- relocated as if their sections started at 0. But the offsets
- refering to the symbols in the raw data have not been
- modified, so we have to have a negative addend to compensate.
-
- Note that symbols which used to be common must be left alone
- */
-
- if (ptr && ptr->the_bfd == abfd
- && ptr->section != (asection *) NULL
- && ((ptr->flags & BSF_OLD_COMMON)== 0))
+ ptr = *(cache_ptr->sym_ptr_ptr);
+ cache_ptr->address = dst.r_vaddr;
+ /*
+ The symbols definitions that we have read in have been
+ relocated as if their sections started at 0. But the offsets
+ refering to the symbols in the raw data have not been
+ modified, so we have to have a negative addend to compensate.
+
+ Note that symbols which used to be common must be left alone */
+
+ if (ptr && ptr->the_bfd == abfd
+ && ptr->section != (asection *) NULL
+ && ((ptr->flags & BSF_OLD_COMMON)== 0))
{
#ifndef M88
- cache_ptr->addend = -(ptr->section->vma + ptr->value);
+ cache_ptr->addend = -(ptr->section->vma + ptr->value);
#else
- cache_ptr->addend = 0;
+ cache_ptr->addend = 0;
#endif
}
- else {
- cache_ptr->addend = 0;
- }
-
- cache_ptr->address -= asect->vma;
-
- cache_ptr->section = (asection *) NULL;
-
-#ifdef A29K
- if (dst.r_type == R_IHCONST) {
- /* Add in the value which was stored in the symbol index */
- /* See above comment */
- cache_ptr->addend += dst.r_symndx;
- /* Throw away the bogus symbol pointer */
- cache_ptr->sym_ptr_ptr = 0;
- }
- cache_ptr->howto = howto_table + dst.r_type;
+ else {
+ cache_ptr->addend = 0;
+ }
+
+ cache_ptr->address -= asect->vma;
+
+ cache_ptr->section = (asection *) NULL;
+
+#ifdef A29K
+ if (dst.r_type == R_IHCONST) {
+ /* Add in the value which was stored in the symbol index */
+ /* See above comment */
+ cache_ptr->addend += dst.r_symndx;
+ /* Throw away the bogus symbol pointer */
+ cache_ptr->sym_ptr_ptr = 0;
+ }
+ cache_ptr->howto = howto_table + dst.r_type;
#endif
#if I386
- cache_ptr->howto = howto_table + dst.r_type;
+ cache_ptr->howto = howto_table + dst.r_type;
#endif
#if I960
- cache_ptr->howto = howto_table + dst.r_type;
+ cache_ptr->howto = howto_table + dst.r_type;
#endif
#if M68
- cache_ptr->howto = howto_table + dst.r_type - R_RELBYTE;
+ cache_ptr->howto = howto_table + dst.r_type - R_RELBYTE;
#endif
#if M88
- if (dst.r_type >= R_PCR16L && dst.r_type <= R_VRT32) {
- cache_ptr->howto = howto_table + dst.r_type - R_PCR16L;
- cache_ptr->addend += dst.r_offset << 16;
- }
- else {
- BFD_ASSERT(0);
- }
+ if (dst.r_type >= R_PCR16L && dst.r_type <= R_VRT32) {
+ cache_ptr->howto = howto_table + dst.r_type - R_PCR16L;
+ cache_ptr->addend += dst.r_offset << 16;
+ }
+ else {
+ BFD_ASSERT(0);
+ }
#endif
-
- }
-
+ }
}
-
+
asect->relocation = reloc_cache;
return true;
- }
+}
/* This is stupid. This function should be a boolean predicate */
static unsigned int
-coff_canonicalize_reloc(abfd, section, relptr, symbols)
-bfd *abfd;
-sec_ptr section;
-arelent **relptr;
-asymbol **symbols;
- {
+DEFUN(coff_canonicalize_reloc, (abfd, section, relptr, symbols),
+bfd *abfd AND
+sec_ptr section AND
+arelent **relptr AND
+asymbol **symbols)
+{
arelent *tblptr = section->relocation;
unsigned int count = 0;
- if (!(tblptr || coff_slurp_reloc_table(abfd, section, symbols)))
- return 0;
- tblptr = section->relocation;
- if (!tblptr)
- return 0;
-
- for (; count++ < section->reloc_count;)
- *relptr++ = tblptr++;
-
- *relptr = 0;
-
+
+
+ if (section->flags & SEC_CONSTRUCTOR)
+ {
+ /* this section has relocs made up by us, they are not in the
+ file, so take them out of their chain and place them into
+ the data area provided */
+ arelent_chain *chain = section->constructor_chain;
+ for (count = 0; count < section->reloc_count; count ++)
+ {
+ *relptr ++ = &chain->relent;
+ chain = chain->next;
+ }
+
+ }
+ else
+ {
+ coff_slurp_reloc_table(abfd, section, symbols);
+
+
+ tblptr = section->relocation;
+ if (!tblptr)
+ return 0;
+
+ for (; count++ < section->reloc_count;)
+ *relptr++ = tblptr++;
+
+
+ }
+ *relptr = 0;
return section->reloc_count;
- }
+}
#ifndef NO_COFF_SYMBOLS
static bfd_vma cache_offset;
static unsigned int cache_i;
static alent *cache_l;
-
+
unsigned int i = 0;
coff_data_type *cof = coff_data(abfd);
/* Run through the raw syments if available */
combined_entry_type *p;
alent *l;
unsigned int line_base = 0;
-
-
+
+
*filename_ptr = 0;
*functionname_ptr = 0;
*line_ptr = 0;
-
+
/* Don't try and find line numbers in a non coff file */
if (abfd->xvec->flavour != bfd_target_coff_flavour)
return false;
-
+
if (cof == NULL)
return false;
p = cof->raw_syments;
-
+
for (i = 0; i < cof->raw_syment_count; i++) {
if (p->u.syment.n_sclass == C_FILE) {
/* File name has been moved into symbol */
i = 0;
l = section->lineno;
}
-
+
for (; i < section->lineno_count; i++) {
if (l->line_number == 0) {
/* Get the symbol this line number points at */
}
l++;
}
-
+
cache_abfd = abfd;
cache_section = section;
cache_offset = offset;
#endif /* NO_COFF_SYMBOLS */
-static int
+static int
DEFUN(coff_sizeof_headers,(abfd, reloc),
bfd *abfd AND
boolean reloc)
- {
+{
size_t size;
-
+
if (reloc == false) {
- size = FILHSZ + AOUTSZ;
+ size = FILHSZ + AOUTSZ;
}
else {
- size = FILHSZ;
+ size = FILHSZ;
}
-
+
size += abfd->section_count * SCNHSZ;
return size;
- }
+}
#define coff_core_file_failing_command _bfd_dummy_core_file_failing_command
#define coff_bfd_debug_info_start bfd_void
#define coff_bfd_debug_info_end bfd_void
#define coff_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
-