diff options
Diffstat (limited to 'bfd/coffcode.h')
-rw-r--r-- | bfd/coffcode.h | 2353 |
1 files changed, 1425 insertions, 928 deletions
diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 63630c3..2dea71a 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -5,17 +5,234 @@ This file is part of BFD, the Binary File Diddler. BFD is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 1, or (at your option) any later version. +terms of the GNU General Public License as published by the Free Software +Foundation; either version 1, or (at your option) any later version. BFD is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - details. +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. You should have received a copy of the GNU General Public License along with - BFD; see the file COPYING. If not, write to the Free Software Foundation, - 675 Mass Ave, Cambridge, MA 02139, USA. +BFD; see the file COPYING. If not, write to the Free Software Foundation, +675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/*doc* +@section coff backends + +BFD supports a number of different flavours of coff format. The major +difference between formats are the sizes and alignments of fields in +structures on disk, and the occasional extra field. + +Coff in all its varieties is implimented with a few common files and a +number of implementation specific files. For example, The 88k bcs coff +format is implemented in the file @code{m88k-bcs.c}. This file +@code{#include}s @code{m88k-bcs.h} which defines the external +structure of the coff format for the 88k, and @code{internalcoff.h} +which defines the internal structure. @code{m88k-bcs.c} also defines +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}. + +The Intel i960 processor version of coff is implemented in +@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}. + +@subsection Porting To A New Version of Coff + +The recommended method is to select from the existing implimentations +the version of coff which is most like the one you want to use, for +our purposes, we'll say that i386 coff is the one you select, and that +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. + +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 +@code{#ifdef}s to the code in @code{internalcoff.h} and +@code{coffcode.h} if your version of coff is too wild. + +You can verify that your new bfd backend works quite simply by +building @code{objdump} from the @code{binutils} directory, and +making sure that its version of what's going on at your host systems +idea (assuming it has the pretty standard coff dump utility (usually +called @code{att-dump} or just @code{dump})) are the same. + +Then clean up your code, and send what you've done to Cygnus. Then your stuff +will be in the next release, and you won't have to keep integrating +it. + +@subsection How The Coff Backend Works + +@subsubsection Bit Twiddling +Each flavour of coff supported in bfd has its own header file +descibing the external layout of the structures. There is also an +internal description of the coff layout (in @code{internalcoff.h}) +file (@code{}). A major function of the coff backend is swapping the +bytes and twiddling the bits to translate the external form of the +structures into the normal internal form. This is all performed in the +@code{bfd_swap}_@i{thing}_@i{direction} routines. Some elements are +different sizes between different versions of coff, it is the duty of +the coff version specific include file to override the definitions of +various packing routines in @code{coffcode.h}. Eg the size of line +number entry in coff is sometimes 16 bits, and sometimes 32 bits. +@code{#define}ing @code{PUT_LNSZ_LNNO} and @code{GET_LNSZ_LNNO} will +select the correct one. No doubt, some day someone will find a version +of coff which has a varying field size not catered for at the moment. +To port bfd, that person will have to add more @code{#defines}. + +Three of the bit twiddling routines are exported to @code{gdb}; +@code{coff_swap_aux_in}, @code{coff_swap_sym_in} and +@code{coff_swap_linno_in}. @code{GDB} reads the symbol table on its +own, but uses bfd to fix things up. + +@subsubsection Symbol Reading +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". + +When a symbol table is requested (through a call to +@code{bfd_canonicalize_symtab}, a request gets through to +@code{get_normalized_symtab}. This reads the symbol table from the +coff file and swaps all the structures inside into the internal form. +It also fixes up all the pointers in the table (represented in the file +by offsets from the first symbol in the table) into physical pointers +to elements in the new internal table. This involves some work since +the meanings of fields changes depending upon context; a field that is a +pointer to another structure in the symbol table at one moment may be +the size in bytes of a structure in the next. + +Another pass is made over the table. All symbols which mark file names +(@code{C_FILE} symbols) are modified so that the internal string +points to the value in the auxent (the real filename) rather than the +normal text associated with the symbol (@code{".file"}). + +At this time the symbol names are moved around. Coff stores all +symbols less than nine characters long physically within the symbol +table, longer strings are kept at the end of the file in the string +table. This pass moves all strings into memory, and replaces them with +pointers to the strings. + +The symbol table is massaged once again, this time to create the +canonical table used by the bfd application. Each symbol is inspected +in turn, and a decision made (using the @code{sclass} field) about the +various flags to set in the @code{asymbol} @xref{Symbols}. The +generated canonical table shares strings with the hidden internal +symbol table. + +Any linenumbers are read from the coff file too, and attatched to the +symbols which own the functions the linenumbers belong to. + +@subsubsection Symbol Writing +Writing a symbol to a coff file which didn't come from a coff file +will lose any debugging information. The @code{asymbol} structure +remembers the bfd from which was born, and on output the back end +makes sure that the same destination target as source target is +present. + +When the symbols have come from a coff file then all the debugging +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 order of operations on the canonical symbol table at that point +are: +@table @code +@item coff_renumber_symbols +This function runs through the provided symbol table and patches each +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. + +Another function of this procedure is to turn the canonical value form +of bfd into the form used by coff. Internally, bfd expects symbol +values to be offsets from a section base; so a symbol physically at +0x120, but in a section starting at 0x100, would have the value 0x20. +Coff expects symbols to contain their final value, so symbols have +their values changed at this point to reflect their sum with their +owning section. Note that this transformation uses the +@code{output_section} field of the @code{asymbol}'s @code{asection} +@xref{Sections}. +@item coff_mangle_symbols +This routine runs though the provided symbol table and uses the +offsets generated by the previous pass and the pointers generated when +the symbol table was read in to create the structured hierachy +required by coff. It changes each pointer to a symbol to an index into +the symbol table of the symbol being referenced. +@item coff_write_symbols +This routine runs through the symbol table and patches up the symbols +from their internal form into the coff way, calls the bit twiddlers +and writes out the tabel to the file. +@end table +*/ + +/*proto* + +The hidden information for an asymbol is: + +*+++ + +$ typedef struct coff_ptr_struct +$ { + +Remembers the offset from the first symbol in the file for this +symbol. Generated by @code{coff_renumber_symbols}. + +$ unsigned int offset; + +Should the tag field of this symbol be renumbered. +Created by @code{coff_pointerize_aux}. + +$ char fix_tag; + +Should the endidx field of this symbol be renumbered. +Created by @code{coff_pointerize_aux}. + +$ char fix_end; + +The container for the symbol structure as read and translated from the file. + +$ union { +$ union internal_auxent auxent; +$ struct internal_syment syment; +$ } u; +$ } combined_entry_type; +$ + +*--- + +Each canonical asymbol really looks like this: + +*+++ + +$ typedef struct coff_symbol_struct +$ { + +The actual symbol which the rest of bfd works with + +$ asymbol symbol; + +A pointer to the hidden information for this symbol + +$ combined_entry_type *native; + +A pointer to the linenumber information for this symbol + +$ struct lineno_cache_entry *lineno; +$ } coff_symbol_type; + +*--- + */ /* $Id$ */ @@ -23,11 +240,6 @@ You should have received a copy of the GNU General Public License along with #include "archures.h" /* Machine architectures and types */ -/* SUPPRESS 558 */ -/* SUPPRESS 590 */ -/* SUPPRESS 529 */ -/* SUPPRESS 530 */ - /* Align an address upward to a boundary, expressed as a number of bytes. E.g. align to an 8-byte boundary with argument of 8. */ #define ALIGN(this, boundary) \ @@ -38,22 +250,59 @@ You should have received a copy of the GNU General Public License along with #define i960_align(addr, align) \ ( ((addr) + ((1<<(align))-1)) & (-1 << (align))) -#define sp(x) bfd_h_put_x(abfd, x, &x) #define PUTWORD bfd_h_put_32 #define PUTHALF bfd_h_put_16 -#ifndef I960 -#define GDB_EXPORT static -#else -#define GDB_EXPORT /* nothing */ + +#ifndef GET_FCN_LNNOPTR +#define GET_FCN_LNNOPTR(abfd, ext) bfd_h_get_32(abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr) +#endif + +#ifndef GET_FCN_ENDNDX +#define GET_FCN_ENDNDX(abfd, ext) bfd_h_get_32(abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx) +#endif + +#ifndef PUT_FCN_LNNOPTR +#define PUT_FCN_LNNOPTR(abfd, in, ext) PUTWORD(abfd, in, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr) +#endif +#ifndef PUT_FCN_ENDNDX +#define PUT_FCN_ENDNDX(abfd, in, ext) PUTWORD(abfd, in, ext->x_sym.x_fcnary.x_fcn.x_endndx) +#endif +#ifndef GET_LNSZ_LNNO +#define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_16(abfd, ext->x_sym.x_misc.x_lnsz.x_lnno) +#endif +#ifndef GET_LNSZ_SIZE +#define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_16(abfd, ext->x_sym.x_misc.x_lnsz.x_size) +#endif +#ifndef PUT_LNSZ_LNNO +#define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_16(abfd, in, ext->x_sym.x_misc.x_lnsz.x_lnno) +#endif +#ifndef PUT_LNSZ_SIZE +#define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, ext->x_sym.x_misc.x_lnsz.x_size) +#endif +#ifndef GET_SCN_SCNLEN +#define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, ext->x_scn.x_scnlen) +#endif +#ifndef GET_SCN_NRELOC +#define GET_SCN_NRELOC(abfd, ext) bfd_h_get_16(abfd, ext->x_scn.x_nreloc) +#endif +#ifndef GET_SCN_NLINNO +#define GET_SCN_NLINNO(abfd, ext) bfd_h_get_16(abfd, ext->x_scn.x_nlinno) +#endif +#ifndef PUT_SCN_SCNLEN +#define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, ext->x_scn.x_scnlen) +#endif +#ifndef PUT_SCN_NRELOC +#define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in,ext->x_scn.x_nreloc) +#endif +#ifndef PUT_SCN_NLINNO +#define PUT_SCN_NLINNO(abfd,in, ext) bfd_h_put_16(abfd,in, ext->x_scn.x_nlinno) #endif -PROTO(static void,force_indices_file_symbol_relative,(bfd *abfd, - struct internal_syment *symtab)); /* void warning(); */ -extern asection abs_section; + static int DEFUN(get_index,(symbol), @@ -71,10 +320,9 @@ DEFUN(set_index,(symbol, idx), } - - - -/* All the swapping routines: +/* ********************************************************************** +Here are all the routines for swapping the structures seen in the +outside world into the internal forms. */ @@ -123,7 +371,7 @@ DEFUN(bfd_swap_filehdr_in,(abfd, filehdr_src, filehdr_dst), filehdr_dst->f_flags = bfd_h_get_16(abfd,filehdr_src-> f_flags); } -GDB_EXPORT void +static void DEFUN(bfd_swap_filehdr_out,(abfd, filehdr_in, filehdr_out), bfd *abfd AND struct internal_filehdr *filehdr_in AND @@ -141,11 +389,14 @@ DEFUN(bfd_swap_filehdr_out,(abfd, filehdr_in, filehdr_out), static void -DEFUN(coff_swap_sym_in,(abfd, ext, in), +DEFUN(coff_swap_sym_in,(abfd, ext1, in1), bfd *abfd AND - SYMENT *ext AND - struct internal_syment *in) + PTR ext1 AND + PTR in1) { + SYMENT *ext = (SYMENT *)ext1; + struct internal_syment *in = (struct internal_syment *)in1; + if( ext->e.e_name[0] == 0) { in->_n._n_n._n_zeroes = 0; in->_n._n_n._n_offset = bfd_h_get_32(abfd, ext->e.e.e_offset); @@ -165,7 +416,7 @@ DEFUN(coff_swap_sym_in,(abfd, ext, in), in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux); } -GDB_EXPORT void +static void DEFUN(coff_swap_sym_out,(abfd,in, ext), bfd *abfd AND struct internal_syment *in AND @@ -193,13 +444,15 @@ DEFUN(coff_swap_sym_out,(abfd,in, ext), } static void -DEFUN(coff_swap_aux_in,(abfd, ext, type, class, in), +DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, in1), bfd *abfd AND - AUXENT *ext AND + PTR ext1 AND int type AND int class AND - union internal_auxent *in) + PTR in1) { + AUXENT *ext = (AUXENT *)ext1; + union internal_auxent *in = (union internal_auxent *)in1; switch (class) { case C_FILE: if (ext->x_file.x_fname[0] == 0) { @@ -217,14 +470,16 @@ DEFUN(coff_swap_aux_in,(abfd, ext, type, class, in), #endif case C_HIDDEN: if (type == T_NULL) { - in->x_scn.x_scnlen = bfd_h_get_32(abfd, ext->x_scn.x_scnlen); - in->x_scn.x_nreloc = bfd_h_get_16(abfd, ext->x_scn.x_nreloc); - in->x_scn.x_nlinno = bfd_h_get_16(abfd, ext->x_scn.x_nlinno); + in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext); + in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext); + in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext); break; } default: - in->x_sym.x_tagndx = bfd_h_get_32(abfd, ext->x_sym.x_tagndx); + in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, ext->x_sym.x_tagndx); +#ifndef NO_TVNDX in->x_sym.x_tvndx = bfd_h_get_16(abfd, ext->x_sym.x_tvndx); +#endif if (ISARY(type) || class == C_BLOCK) { in->x_sym.x_fcnary.x_ary.x_dimen[0] = bfd_h_get_16(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]); @@ -232,21 +487,20 @@ DEFUN(coff_swap_aux_in,(abfd, ext, type, class, in), in->x_sym.x_fcnary.x_ary.x_dimen[2] = bfd_h_get_16(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]); in->x_sym.x_fcnary.x_ary.x_dimen[3] = bfd_h_get_16(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]); } - else { - in->x_sym.x_fcnary.x_fcn.x_lnnoptr = bfd_h_get_32(abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr); - in->x_sym.x_fcnary.x_fcn.x_endndx = bfd_h_get_32(abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx); - } + in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR(abfd, ext); + in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX(abfd, ext); + if (ISFCN(type)) { in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, ext->x_sym.x_misc.x_fsize); } else { - in->x_sym.x_misc.x_lnsz.x_lnno = bfd_h_get_16(abfd, ext->x_sym.x_misc.x_lnsz.x_lnno); - in->x_sym.x_misc.x_lnsz.x_size = bfd_h_get_16(abfd, ext->x_sym.x_misc.x_lnsz.x_size); + in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext); + in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext); } } } -GDB_EXPORT void +static void DEFUN(coff_swap_aux_out,(abfd, in, type, class, ext), bfd *abfd AND union internal_auxent *in AND @@ -260,7 +514,10 @@ DEFUN(coff_swap_aux_out,(abfd, in, type, class, ext), PUTWORD(abfd, 0, ext->x_file.x_n.x_zeroes ); PUTWORD(abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset); } - + else { + memcpy ( ext->x_file.x_fname,in->x_file.x_fname, + sizeof (in->x_file.x_fname)); + } break; case C_STAT: #ifdef C_LEAFSTAT @@ -268,64 +525,86 @@ DEFUN(coff_swap_aux_out,(abfd, in, type, class, ext), #endif case C_HIDDEN: if (type == T_NULL) { - PUTWORD(abfd, in->x_scn.x_scnlen, ext->x_scn.x_scnlen); - PUTWORD(abfd, in->x_scn.x_nreloc, ext->x_scn.x_nreloc); - PUTWORD(abfd, in->x_scn.x_nlinno, ext->x_scn.x_nlinno); + + 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); break; } default: - PUTWORD(abfd, in->x_sym.x_tagndx, ext->x_sym.x_tagndx); + PUTWORD(abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx); +#ifndef NO_TVNDX PUTWORD(abfd, in->x_sym.x_tvndx , ext->x_sym.x_tvndx); +#endif - if (ISARY(type) || class == C_BLOCK) { - bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],ext->x_sym.x_fcnary.x_ary.x_dimen[0]); - bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],ext->x_sym.x_fcnary.x_ary.x_dimen[1]); - bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],ext->x_sym.x_fcnary.x_ary.x_dimen[2]); - bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],ext->x_sym.x_fcnary.x_ary.x_dimen[3]); - } - else { - PUTWORD(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr); - PUTWORD(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx, ext->x_sym.x_fcnary.x_fcn.x_endndx); - } if (ISFCN(type)) { - PUTWORD(abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize); + PUTWORD(abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize); + PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext); + PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext); } else { - bfd_h_put_16(abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext->x_sym.x_misc.x_lnsz.x_lnno); - bfd_h_put_16(abfd, in->x_sym.x_misc.x_lnsz.x_size, ext->x_sym.x_misc.x_lnsz.x_size); + + if (ISARY(type) || class == C_BLOCK) { + bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],ext->x_sym.x_fcnary.x_ary.x_dimen[0]); + bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],ext->x_sym.x_fcnary.x_ary.x_dimen[1]); + bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],ext->x_sym.x_fcnary.x_ary.x_dimen[2]); + bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],ext->x_sym.x_fcnary.x_ary.x_dimen[3]); + + } + PUT_LNSZ_LNNO(abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext); + PUT_LNSZ_SIZE(abfd, in->x_sym.x_misc.x_lnsz.x_size, ext); + + PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext); + PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext); + + } } } -GDB_EXPORT void -DEFUN(coff_swap_lineno_in,(abfd, ext, in), +static void +DEFUN(coff_swap_lineno_in,(abfd, ext1, in1), bfd *abfd AND - LINENO *ext AND - struct internal_lineno *in) + PTR ext1 AND + PTR in1) { - in->l_addr.l_symndx = bfd_h_get_32(abfd, ext->l_addr.l_symndx); - in->l_lnno = bfd_h_get_16(abfd, ext->l_lnno); + LINENO *ext = (LINENO *)ext1; + struct internal_lineno *in = (struct internal_lineno *)in1; + + in->l_addr.l_symndx = bfd_h_get_32(abfd, ext->l_addr.l_symndx); +#if defined(M88) + in->l_lnno = bfd_h_get_32(abfd, ext->l_lnno); +#else + in->l_lnno = bfd_h_get_16(abfd, ext->l_lnno); +#endif } -GDB_EXPORT void +static void DEFUN(coff_swap_lineno_out,(abfd, in, ext), bfd *abfd AND struct internal_lineno *in AND struct external_lineno *ext) { PUTWORD(abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx); +#if defined(M88) + PUTWORD(abfd, in->l_lnno, ext->l_lnno); +#else PUTHALF(abfd, in->l_lnno, ext->l_lnno); +#endif } -GDB_EXPORT void -DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext, aouthdr_int), +static void +DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1), bfd *abfd AND - AOUTHDR *aouthdr_ext AND - struct internal_aouthdr *aouthdr_int) + PTR aouthdr_ext1 AND + PTR aouthdr_int1) { + AOUTHDR *aouthdr_ext = (AOUTHDR *) aouthdr_ext1; + struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1; + aouthdr_int->magic = bfd_h_get_16(abfd, aouthdr_ext->magic); aouthdr_int->vstamp = bfd_h_get_16(abfd, aouthdr_ext->vstamp); aouthdr_int->tsize = bfd_h_get_32(abfd, aouthdr_ext->tsize); @@ -339,7 +618,7 @@ DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext, aouthdr_int), #endif } -GDB_EXPORT void +static void DEFUN(bfd_swap_aouthdr_out,(abfd, aouthdr_in, aouthdr_out), bfd *abfd AND struct internal_aouthdr *aouthdr_in AND @@ -358,7 +637,7 @@ DEFUN(bfd_swap_aouthdr_out,(abfd, aouthdr_in, aouthdr_out), #endif } -GDB_EXPORT void +static void DEFUN(coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int), bfd *abfd AND SCNHDR *scnhdr_ext AND @@ -371,9 +650,14 @@ DEFUN(coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int), scnhdr_int->s_scnptr = bfd_h_get_32(abfd, scnhdr_ext->s_scnptr); scnhdr_int->s_relptr = bfd_h_get_32(abfd, scnhdr_ext->s_relptr); scnhdr_int->s_lnnoptr = bfd_h_get_32(abfd, scnhdr_ext->s_lnnoptr); + scnhdr_int->s_flags = bfd_h_get_32(abfd, scnhdr_ext->s_flags); +#if defined(M88) + scnhdr_int->s_nreloc = bfd_h_get_32(abfd, scnhdr_ext->s_nreloc); + scnhdr_int->s_nlnno = bfd_h_get_32(abfd, scnhdr_ext->s_nlnno); +#else scnhdr_int->s_nreloc = bfd_h_get_16(abfd, scnhdr_ext->s_nreloc); scnhdr_int->s_nlnno = bfd_h_get_16(abfd, scnhdr_ext->s_nlnno); - scnhdr_int->s_flags = bfd_h_get_32(abfd, scnhdr_ext->s_flags); +#endif #ifdef I960 scnhdr_int->s_align = bfd_h_get_32(abfd, scnhdr_ext->s_align); #endif @@ -393,13 +677,49 @@ DEFUN(swap_scnhdr_out,(abfd, scnhdr_int, scnhdr_ext), PUTWORD(abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr); PUTWORD(abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr); PUTWORD(abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc); +#if defined(M88) + PUTWORD(abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno); + PUTWORD(abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags); +#else PUTHALF(abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno); PUTHALF(abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags); -#ifdef I960 +#endif + +#if defined(I960) PUTWORD(abfd, scnhdr_int->s_align, scnhdr_ext->s_align); #endif } + +/* **********************************************************************/ +/* 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. + */ +static char * +DEFUN(copy_name,(abfd, name, maxlen), + bfd *abfd AND + char *name AND + int maxlen) +{ + 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); + } + strncpy(newname, name, len); + newname[len] = '\0'; + return newname; +} + /* initialize a section structure with information peculiar to this particular implementation of coff @@ -410,19 +730,7 @@ DEFUN(coff_new_section_hook,(abfd_ignore, section_ignore), bfd *abfd_ignore AND asection *section_ignore) { -#ifdef MC88MAGIC - /* FIXME, shouldn't this ifdef be on something that says we are - actually COMPILING FOR an 88K coff file, rather than simply - knowing its magic number? */ - /* Align to at least 16 bytes */ - section_ignore->alignment_power = 4; -#endif -#if M68 - section_ignore->alignment_power = 3; -#endif -#if I386 - section_ignore->alignment_power = 2; -#endif + section_ignore->alignment_power = abfd_ignore->xvec->align_power_min; return true; } @@ -514,23 +822,23 @@ DEFUN(coff_real_object_p,(abfd, nscns, internal_f, internal_a), struct internal_aouthdr *internal_a) { coff_data_type *coff; - + 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; @@ -647,53 +955,53 @@ DEFUN(coff_real_object_p,(abfd, nscns, internal_f, internal_a), static bfd_target * DEFUN(coff_object_p,(abfd), bfd *abfd) - { - int nscns; - FILHDR filehdr; - AOUTHDR opthdr; - struct internal_filehdr internal_f; - struct internal_aouthdr internal_a; +{ + int nscns; + FILHDR filehdr; + AOUTHDR opthdr; + struct internal_filehdr internal_f; + struct internal_aouthdr internal_a; - bfd_error = system_call_error; + bfd_error = system_call_error; - /* figure out how much to read */ - if (bfd_read((PTR) &filehdr, 1, FILHSZ, abfd) != FILHSZ) - return 0; + /* 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); + bfd_swap_filehdr_in(abfd, &filehdr, &internal_f); - if (BADMAG(internal_f)) { - bfd_error = wrong_format; - return 0; - } - nscns =internal_f.f_nscns; + 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, &opthdr, &internal_a); + if (internal_f.f_opthdr) { + if (bfd_read((PTR) &opthdr, 1,AOUTSZ, abfd) != AOUTSZ) { + return 0; } + bfd_swap_aouthdr_in(abfd, &opthdr, &internal_a); + } - /* Seek past the opt hdr stuff */ - bfd_seek(abfd, internal_f.f_opthdr + FILHSZ, SEEK_SET); + /* 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 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 + */ #ifndef MIPS - if (internal_f.f_opthdr != 0 && AOUTSZ != internal_f.f_opthdr) - return (bfd_target *)NULL; + 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); - } + return coff_real_object_p(abfd, nscns, &internal_f, &internal_a); +} @@ -706,15 +1014,15 @@ static coff_symbol_type * DEFUN(coff_symbol_from,(abfd, symbol), bfd *abfd AND asymbol *symbol) - { - if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour_enum) - return (coff_symbol_type *)NULL; +{ + if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour_enum) + return (coff_symbol_type *)NULL; - if (symbol->the_bfd->tdata == (PTR)NULL) - return (coff_symbol_type *)NULL; + if (symbol->the_bfd->tdata == (PTR)NULL) + return (coff_symbol_type *)NULL; - return (coff_symbol_type *) symbol; - } + return (coff_symbol_type *) symbol; +} @@ -725,101 +1033,167 @@ DEFUN(coff_symbol_from,(abfd, symbol), static void DEFUN(coff_count_linenumbers,(abfd), bfd *abfd) - { - unsigned int limit = bfd_get_symcount(abfd); - unsigned int i; - asymbol **p; - { - asection *s = abfd->sections->output_section; - while (s) { - BFD_ASSERT(s->lineno_count == 0); - s = s->next; - } +{ + unsigned int limit = bfd_get_symcount(abfd); + unsigned int i; + asymbol **p; + { + asection *s = abfd->sections->output_section; + while (s) { + BFD_ASSERT(s->lineno_count == 0); + 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_enum) { - coff_symbol_type *q = coffsymbol(q_maybe); - if (q->lineno) { - /* - This symbol has a linenumber, increment the owning - section's linenumber count - */ - alent *l = q->lineno; + 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_enum) { + coff_symbol_type *q = coffsymbol(q_maybe); + if (q->lineno) { + /* + This symbol has a linenumber, increment the owning + section's linenumber count + */ + alent *l = q->lineno; + q->symbol.section->output_section->lineno_count++; + l++; + while (l->line_number) { q->symbol.section->output_section->lineno_count++; l++; - while (l->line_number) { - q->symbol.section->output_section->lineno_count++; - l++; - } } } } } +} -/* -This function returns true if the supplied SYMENT has an AUXENT with -a tagndx field which should be relocated. -The coff book says that all auxents have this and should be moved, -but all the actual implementations I've looked at do this .. -(sac@cygnus.com) -*/ -static boolean -DEFUN(uses_x_sym_x_tagndx_p,(abfd, native), - bfd *abfd AND - struct internal_syment *native) - { - if (BTYPE(native->n_type) == T_STRUCT) return true; - if (BTYPE(native->n_type) == T_UNION) return true; - if (BTYPE(native->n_type) == T_ENUM) return true; - return false; - } +static void +DEFUN(fixup_symbol_value,(coff_symbol_ptr, syment), +coff_symbol_type *coff_symbol_ptr AND +struct internal_syment *syment) +{ + /* 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; + } +} -/* -This procedure runs through the native entries in a coff symbol table -and links up all the elements which should point to one another, in -particular these are: +/* run through all the symbols in the symbol table and work out what + their indexes into the symbol table will be when output -strtag, entag and untags have an auxent endindex which points to the -first syment after the .eos. This is simple to do, we just keep a -pointer to the symbol with the most recent pending strtag and patch it -when we see the eos. This works since coff structs are never nested. + 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 + do that here too. -ISFCN type entries have an endindex which points to the next static or -extern in the table, thereby skipping the function contents. -The coff book says that an ISFCN's tagindex -points to the first .bf for the function, so far I havn't seen it -used. We do this using the same mechanism as strtags. +*/ +static void +DEFUN(coff_renumber_symbols,(bfd_ptr), + bfd *bfd_ptr) +{ + unsigned int symbol_count = bfd_get_symcount(bfd_ptr); + asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; + 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++) + { + 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; -Each file entry has a value which points to the next file entry, -the last file entry points to the first extern symbol in the table -which is not an ISFCN. + if (s->u.syment.n_sclass == C_FILE) + { + if (last_file != (struct internal_syment *)NULL) { + last_file->n_value = native_index; + } + last_file = &(s->u.syment); + } + else { -Each .bb entry points to the matching .eb entry, but these are nested -so we keep a stack of them. + /* Modify the symbol values according to their section and + type */ -The tagndx of .eos items points to the strtag attached to them, this -is simply the last_tagndx again. + fixup_symbol_value(coff_symbol_ptr, &(s->u.syment)); + } + for (i = 0; i < s->u.syment.n_numaux + 1; i++) { + s[i].offset = native_index ++; + } + } + else { + native_index++; + } + } +} -The tagndx of items with type strtag point to the defining struct. -This bit is complicated; We know that a struct ref and def must be -within the same file, so all the natives will be in the same vector. -This means that we can subtracts two pointers and get the index -differences between to items, used to work out the true index of the -target. -We store in the name field of each syment the actual native index -applied so we can dig it out through a pointer. */ +/*doc* + Run thorough the symbol table again, and fix it so that all pointers to + entries are changed to the entries' index in the output symbol table. +*/ 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 native_index = 0; + unsigned int 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 ) { + 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; + } + if (a->fix_end) { + a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l = + a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset; + } + + } + } + } +} + +#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; @@ -891,7 +1265,7 @@ DEFUN(coff_mangle_symbols,(bfd_ptr), && 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 = native_index; + auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = native_index; last_fcn = (struct internal_syment *)NULL; } @@ -901,17 +1275,18 @@ DEFUN(coff_mangle_symbols,(bfd_ptr), /* Remember that we keep the native index in the offset so patch the beginning of the struct to point to this */ - auxent->x_sym.x_tagndx = last_tagndx->_n._n_n._n_offset; - auxent->x_sym.x_fcnary.x_fcn.x_endndx = syment->n_numaux + 1 + native_index; +/*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 = last_tagndx->_n._n_n._n_offset; + 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 = native_index + syment->n_numaux + 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) @@ -964,7 +1339,7 @@ DEFUN(coff_mangle_symbols,(bfd_ptr), 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; +/* auxent->x_sym.x_tagndx = base[auxent->x_sym.x_tagndx]._n._n_n._n_offset;*/ } @@ -986,16 +1361,209 @@ DEFUN(coff_mangle_symbols,(bfd_ptr), } +#endif +static int string_size; +static void +DEFUN(coff_fix_symbol_name,(abfd, symbol, native), + bfd *abfd AND + asymbol *symbol AND + combined_entry_type *native) +{ + unsigned int name_length; + union internal_auxent *auxent; +CONST char * name = symbol->name; + + if (name == (char *) NULL) { + /* + coff symbols always have names, so we'll make one up + */ + name = symbol->name = "strange"; + } + 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); + } + else { + auxent->x_file.x_n.x_offset = string_size + 4; + auxent->x_file.x_n.x_zeroes = 0; + string_size += name_length + 1; + } +#else + strncpy(auxent->x_file.x_fname, name, FILNMLEN); + if (name_length > FILNMLEN) { + name[FILNMLEN] = '\0'; + } +#endif + } + else + { /* NOT A C_FILE SYMBOL */ + if (name_length <= SYMNMLEN) { + /* This name will fit into the symbol neatly */ + strncpy(native->u.syment._n._n_name, symbol->name, SYMNMLEN); + } + else { + native->u.syment._n._n_n._n_offset = string_size + 4; + native->u.syment._n._n_n._n_zeroes = 0; + string_size += name_length + 1; + } + } +} + + + +static unsigned int +DEFUN(coff_write_symbol,(abfd, symbol, native, written), +bfd *abfd AND +asymbol *symbol AND +combined_entry_type *native AND +unsigned int written) +{ + unsigned int numaux = native->u.syment.n_numaux; + int type = native->u.syment.n_type; + int class = native->u.syment.n_sclass; + SYMENT buf; + unsigned int j; + + 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++) + { + AUXENT buf1; + coff_swap_aux_out(abfd, + &( (native + j + 1)->u.auxent), type, class, &buf1); + bfd_write((PTR) (&buf1), 1, AUXESZ, abfd); + } + /* + Reuse somewhere in the symbol to keep the index + */ + set_index(symbol, written); + return written + 1 + numaux; +} + + +static unsigned int +DEFUN(coff_write_alien_symbol,(abfd, symbol, written), + bfd *abfd AND + asymbol *symbol AND + unsigned int written) +{ + /* + This symbol has been created by the loader, or come from a non + coff format. It has no native element to inherit, make our + own + */ + combined_entry_type *native; + combined_entry_type dummy; + native = &dummy; + native->u.syment.n_type = T_NULL; +#ifdef I960 + native->u.syment.n_flags = 0; +#endif + if (symbol->flags & BSF_ABSOLUTE) { + native->u.syment.n_scnum = N_ABS; + native->u.syment.n_value = symbol->value; + } + else if (symbol->flags & (BSF_UNDEFINED | BSF_FORT_COMM)) { + native->u.syment.n_scnum = N_UNDEF; + native->u.syment.n_value = symbol->value; + } + else if (symbol->flags & BSF_DEBUGGING) { + /* + remove name so it doesn't take up any space + */ + symbol->name = ""; + } + else { + native->u.syment.n_scnum = symbol->section->output_section->index + + 1; + native->u.syment.n_value = symbol->value + + symbol->section->output_section->vma + + symbol->section->output_offset; +#ifdef I960 + /* Copy the any flags from the the file hdr into the symbol */ + { + coff_symbol_type *c = coff_symbol_from(abfd, symbol); + if (c != (coff_symbol_type *)NULL) { + native->u.syment.n_flags = c->symbol.the_bfd->flags; + } + } +#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 + native->u.syment.n_sclass = C_EXT; + native->u.syment.n_numaux = 0; + + return coff_write_symbol(abfd, symbol, native, written); +} + +static unsigned int +DEFUN(coff_write_native_symbol,(abfd, symbol, written), +bfd *abfd AND +coff_symbol_type *symbol AND +unsigned int written) +{ + /* + Does this symbol have an ascociated line number - if so then + make it remember this symbol index. Also tag the auxent of + this symbol to point to the right place in the lineno table + */ + combined_entry_type *native = symbol->native; + + alent *lineno = symbol->lineno; + + if (lineno) { + unsigned int count = 0; + 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 = + symbol->symbol.section->output_section->moving_line_filepos; + } + /* + And count and relocate all other linenumbers + */ + count++; + while (lineno[count].line_number) { + lineno[count].u.offset += + symbol->symbol.section->output_section->vma + + symbol->symbol.section->output_offset; + count++; + } + symbol->symbol.section->output_section->moving_line_filepos += + count * LINESZ; + + } + return coff_write_symbol(abfd, &( symbol->symbol), native,written); +} + static void DEFUN(coff_write_symbols,(abfd), -bfd *abfd) + bfd *abfd) { unsigned int i; unsigned int limit = bfd_get_symcount(abfd); unsigned int written = 0; - struct internal_syment dummy; + asymbol **p; - unsigned int string_size = 0; + + string_size = 0; /* Seek to the right place */ @@ -1004,160 +1572,48 @@ bfd *abfd) /* Output all the symbols we have */ written = 0; - for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) { - asymbol *symbol = *p; - coff_symbol_type *c_symbol = coff_symbol_from(abfd, symbol); - - unsigned int j; - struct internal_syment *native; - if (c_symbol == (coff_symbol_type *) NULL || - c_symbol->native == (struct internal_syment *) NULL) { - /* - This symbol has been created by the loader, or come from a non - coff format. It has no native element to inherit, make our - own - */ - - native = &dummy; - native->n_type = T_NULL; -#ifdef I960 - native->n_flags = 0; -#endif - if (symbol->flags & BSF_ABSOLUTE) { - native->n_scnum = N_ABS; - native->n_value = symbol->value; - } - else if (symbol->flags & (BSF_UNDEFINED | BSF_FORT_COMM)) { - native->n_scnum = N_UNDEF; - native->n_value = symbol->value; - } - else if (symbol->flags & BSF_DEBUGGING) { - /* - remove name so it doesn't take up any space - */ - symbol->name = ""; - continue; - } - else { - native->n_scnum = symbol->section->output_section->index + - 1; - native->n_value = symbol->value + - symbol->section->output_section->vma + - symbol->section->output_offset; -#ifdef I960 - /* Copy the any flags from the the file hdr into the symbol */ - { - coff_symbol_type *c = coff_symbol_from(abfd, symbol); - if (c != (coff_symbol_type *)NULL) { - native->n_flags = c->symbol.the_bfd->flags; - } - } -#endif - } - -#ifdef HASPAD1 - native->pad1[0] = 0; - native->pad1[0] = 0; -#endif - - native->n_type = 0; - if (symbol->flags & BSF_LOCAL) - native->n_sclass = C_STAT; - else - native->n_sclass = C_EXT; - native->n_numaux = 0; - } - else - /* - Does this symbol have an ascociated line number - if so then - make it remember this symbol index. Also tag the auxent of - this symbol to point to the right place in the lineno table - */ - { - alent *lineno = c_symbol->lineno; - native = c_symbol->native; - if (lineno) { - unsigned int count = 0; - lineno[count].u.offset = written; - if (native->n_numaux) { - union internal_auxent *a = (union internal_auxent *) (native + 1); - - a->x_sym.x_fcnary.x_fcn.x_lnnoptr = - c_symbol->symbol.section->output_section->moving_line_filepos; - } - /* - And count and relocate all other linenumbers - */ - count++; - while (lineno[count].line_number) { - lineno[count].u.offset += - c_symbol->symbol.section->output_section->vma + - c_symbol->symbol.section->output_offset; - count++; - } - c_symbol->symbol.section->output_section->moving_line_filepos += - count * LINESZ; - - } - } /* if symbol new to coff */ - - /* Fix the symbol names */ + for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) { - unsigned int name_length; - if (symbol->name == (char *) NULL) { - /* - coff symbols always have names, so we'll make one up - */ - symbol->name = "strange"; - } - name_length = strlen(symbol->name); - if (name_length <= SYMNMLEN) { - /* This name will fit into the symbol neatly */ - strncpy(native->_n._n_name, symbol->name, SYMNMLEN); - } - else { - native->_n._n_n._n_offset = string_size + 4; - native->_n._n_n._n_zeroes = 0; - string_size += name_length + 1; - } - { - unsigned int numaux = native->n_numaux; - int type = native->n_type; - int class = native->n_sclass; - SYMENT buf; - coff_swap_sym_out(abfd, native, &buf); - bfd_write((PTR)& buf, 1, SYMESZ, abfd); - for (j = 0; j != native->n_numaux; - j++) { - AUXENT buf1; - coff_swap_aux_out(abfd, - (union internal_auxent *)(native + j + 1), type, class, &buf1); - bfd_write((PTR) (native + j + 1), 1, AUXESZ, abfd); + 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) + { + written = coff_write_alien_symbol(abfd, symbol, written); } - /* - Reuse somewhere in the symbol to keep the index - */ - set_index(symbol, written); - written += 1 + numaux; - } + else + { + written = coff_write_native_symbol(abfd, c_symbol, written); + } + } - } /* for each out symbol */ - + bfd_get_symcount(abfd) = written; + /* Now write out strings */ - if (string_size) { - unsigned int size = string_size + 4; - size = size; - bfd_write((PTR) &size, 1, sizeof(size), abfd); - for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) { - asymbol *q = *p; - size_t name_length = strlen(q->name); - if (name_length > SYMNMLEN) { - bfd_write((PTR) (q->name), 1, name_length + 1, abfd); - } - } - } + if (string_size != 0) + { + unsigned int size = string_size + 4; + size = size; + bfd_write((PTR) &size, 1, sizeof(size), abfd); + for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) + { + asymbol *q = *p; + size_t name_length = strlen(q->name); + int maxlen; + coff_symbol_type* c_symbol = coff_symbol_from(abfd, q); + 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); + } + } + } else { /* We would normally not write anything here, but we'll write out 4 so that any stupid coff reader which tries to read @@ -1169,278 +1625,289 @@ bfd *abfd) bfd_write((PTR)&size, 1, sizeof(size), abfd); } - } +/*doc* +@subsubsection Writing Relocations +To write a relocations, all the back end does is step though the +canonical relocation table, and create an @code{internal_reloc}. The +symbol index to use is removed from the @code{offset} field in the +symbol table supplied, the address comes directly from the sum of the +section base address and the relocation offset and the type is dug +directly from the howto field. + +Then the @code{internal_reloc} is swapped into the shape of an +@code{external_reloc} and written out to disk. +*/ static void -coff_write_relocs(abfd) -bfd *abfd; - { - asection *s; - for (s = abfd->sections; s != (asection *) NULL; s = s->next) { - unsigned int i; - struct external_reloc dst; +DEFUN(coff_write_relocs,(abfd), + bfd *abfd) +{ + asection *s; + 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++) { - struct internal_reloc n; - arelent *q = p[i]; - memset((PTR)&n, 0, sizeof(n)); - n.r_vaddr = q->address + s->vma; - if (q->sym_ptr_ptr) { - n.r_symndx = get_index((*(q->sym_ptr_ptr))); - } + arelent **p = s->orelocation; + bfd_seek(abfd, s->rel_filepos, SEEK_SET); + for (i = 0; i < s->reloc_count; i++) { + struct internal_reloc n; + arelent *q = p[i]; + memset((PTR)&n, 0, sizeof(n)); + n.r_vaddr = q->address + s->vma; + if (q->sym_ptr_ptr) { + n.r_symndx = get_index((*(q->sym_ptr_ptr))); + } #ifdef SELECT_RELOC - /* Work out reloc type from what is required */ - SELECT_RELOC(n.r_type, q->howto); + /* Work out reloc type from what is required */ + SELECT_RELOC(n.r_type, q->howto); #else - n.r_type = q->howto->type; + n.r_type = q->howto->type; #endif - bfd_swap_reloc_out(abfd, &n, &dst); - bfd_write((PTR) &n, 1, RELSZ, abfd); - } + bfd_swap_reloc_out(abfd, &n, &dst); + bfd_write((PTR) &n, 1, RELSZ, abfd); } } +} static void DEFUN(coff_write_linenumbers,(abfd), bfd *abfd) - { - asection *s; - for (s = abfd->sections; s != (asection *) NULL; s = s->next) { - if (s->lineno_count) { - asymbol **q = abfd->outsymbols; - bfd_seek(abfd, s->line_filepos, SEEK_SET); - /* Find all the linenumbers in this section */ - while (*q) { - asymbol *p = *q; - alent *l = BFD_SEND(p->the_bfd, _get_lineno, (p->the_bfd, p)); - if (l) { - /* Found a linenumber entry, output */ - struct internal_lineno out; - LINENO buff; - bzero( (PTR)&out, sizeof(out)); - out.l_lnno = 0; +{ + asection *s; + for (s = abfd->sections; s != (asection *) NULL; s = s->next) { + if (s->lineno_count) { + asymbol **q = abfd->outsymbols; + bfd_seek(abfd, s->line_filepos, SEEK_SET); + /* Find all the linenumbers in this section */ + while (*q) { + asymbol *p = *q; + alent *l = BFD_SEND(p->the_bfd, _get_lineno, (p->the_bfd, p)); + if (l) { + /* Found a linenumber entry, output */ + struct internal_lineno out; + LINENO buff; + memset( (PTR)&out, 0, sizeof(out)); + out.l_lnno = 0; + out.l_addr.l_symndx = l->u.offset; + coff_swap_lineno_out(abfd, &out, &buff); + bfd_write((PTR) &buff, 1, LINESZ, abfd); + l++; + while (l->line_number) { + out.l_lnno = l->line_number; out.l_addr.l_symndx = l->u.offset; coff_swap_lineno_out(abfd, &out, &buff); bfd_write((PTR) &buff, 1, LINESZ, abfd); l++; - while (l->line_number) { - out.l_lnno = l->line_number; - out.l_addr.l_symndx = l->u.offset; - coff_swap_lineno_out(abfd, &out, &buff); - bfd_write((PTR) &buff, 1, LINESZ, abfd); - l++; - } } - q++; } + q++; } } } +} static asymbol * coff_make_empty_symbol(abfd) bfd *abfd; - { - coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type)); - if (new == NULL) { - bfd_error = no_memory; - return (NULL); - } /* on error */ - new->native = 0; - new->lineno = (alent *) NULL; - new->symbol.the_bfd = abfd; - return &new->symbol; - } +{ + coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type)); + if (new == NULL) { + bfd_error = no_memory; + return (NULL); + } /* on error */ + new->native = 0; + new->lineno = (alent *) NULL; + new->symbol.the_bfd = abfd; + return &new->symbol; +} static void -coff_print_symbol(ignore_abfd, file, symbol, how) -bfd *ignore_abfd; -FILE *file; -asymbol *symbol; -bfd_print_symbol_enum_type how; - { - switch (how) { - case bfd_print_symbol_name_enum: - fprintf(file, "%s", symbol->name); - break; - case bfd_print_symbol_type_enum: - fprintf(file, "coff %lx %lx", (unsigned long) coffsymbol(symbol)->native, - (unsigned long) coffsymbol(symbol)->lineno); - break; - case bfd_print_symbol_all_enum: - { - CONST char *section_name = symbol->section == (asection *) NULL ? - "*abs" : symbol->section->name; - bfd_print_symbol_vandf((PTR) file, symbol); +DEFUN(coff_print_symbol,(ignore_abfd, file, symbol, how), + bfd *ignore_abfd AND + FILE *file AND + asymbol *symbol AND + bfd_print_symbol_enum_type how) +{ + switch (how) { + case bfd_print_symbol_name_enum: + fprintf(file, "%s", symbol->name); + break; + case bfd_print_symbol_type_enum: + fprintf(file, "coff %lx %lx", (unsigned long) coffsymbol(symbol)->native, + (unsigned long) coffsymbol(symbol)->lineno); + break; + case bfd_print_symbol_all_enum: + { + 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); - } + fprintf(file, " %-5s %s %s %s", + section_name, + coffsymbol(symbol)->native ? "n" : "g", + coffsymbol(symbol)->lineno ? "l" : " ", + symbol->name); + } - break; - } + break; } +} static alent * -coff_get_lineno(ignore_abfd, symbol) -bfd *ignore_abfd; -asymbol *symbol; - { - return coffsymbol(symbol)->lineno; - } +DEFUN(coff_get_lineno,(ignore_abfd, symbol), + bfd *ignore_abfd AND + asymbol *symbol) +{ + return coffsymbol(symbol)->lineno; +} /* Set flags and magic number of a coff file from architecture and machine type. Result is true if we can represent the arch&type, false if not. */ static boolean -coff_set_flags(abfd, magicp, flagsp) -bfd *abfd; -unsigned *magicp, -*flagsp; - { +DEFUN(coff_set_flags,(abfd, magicp, flagsp), + bfd *abfd AND + unsigned *magicp AND + unsigned short *flagsp) +{ - switch (abfd->obj_arch) { + switch (abfd->obj_arch) { #ifdef I960ROMAGIC - case bfd_arch_i960: + case bfd_arch_i960: - { - unsigned flags; - *magicp = I960ROMAGIC; - /* - ((bfd_get_file_flags(abfd) & WP_TEXT) ? I960ROMAGIC : - I960RWMAGIC); FIXME??? - */ - switch (abfd->obj_machine) { - case bfd_mach_i960_core: - flags = F_I960CORE; - break; - case bfd_mach_i960_kb_sb: - flags = F_I960KB; - break; - case bfd_mach_i960_mc: - flags = F_I960MC; - break; - case bfd_mach_i960_xa: - flags = F_I960XA; - break; - case bfd_mach_i960_ca: - flags = F_I960CA; - break; - case bfd_mach_i960_ka_sa: - flags = F_I960KA; - break; - default: - return false; - } - *flagsp = flags; - return true; + { + unsigned flags; + *magicp = I960ROMAGIC; + /* + ((bfd_get_file_flags(abfd) & WP_TEXT) ? I960ROMAGIC : + I960RWMAGIC); FIXME??? + */ + switch (abfd->obj_machine) { + case bfd_mach_i960_core: + flags = F_I960CORE; + break; + case bfd_mach_i960_kb_sb: + flags = F_I960KB; + break; + case bfd_mach_i960_mc: + flags = F_I960MC; + break; + case bfd_mach_i960_xa: + flags = F_I960XA; + break; + case bfd_mach_i960_ca: + flags = F_I960CA; + break; + case bfd_mach_i960_ka_sa: + flags = F_I960KA; + break; + default: + return false; } - break; + *flagsp = flags; + return true; + } + break; #endif #ifdef MIPS - case bfd_arch_mips: - *magicp = MIPS_MAGIC_2; - return true; - break; + case bfd_arch_mips: + *magicp = MIPS_MAGIC_2; + return true; + break; #endif #ifdef I386MAGIC - case bfd_arch_i386: - *magicp = I386MAGIC; - return true; + case bfd_arch_i386: + *magicp = I386MAGIC; + return true; #endif #ifdef MC68MAGIC - case bfd_arch_m68k: - *magicp = MC68MAGIC; - return true; + case bfd_arch_m68k: + *magicp = MC68MAGIC; + return true; #endif #ifdef MC88MAGIC - case bfd_arch_m88k: - *magicp = MC88OMAGIC; - return true; - break; + case bfd_arch_m88k: + *magicp = MC88OMAGIC; + return true; + break; #endif - default: /* Unknown architecture */ - return false; - } - + default: /* Unknown architecture */ return false; } + + return false; +} static boolean -coff_set_arch_mach(abfd, arch, machine) -bfd *abfd; -enum bfd_architecture arch; -unsigned long machine; - { - unsigned dummy1, - dummy2; +DEFUN(coff_set_arch_mach,(abfd, arch, machine), + bfd *abfd AND + enum bfd_architecture arch AND + unsigned long machine) +{ + unsigned dummy1; + unsigned short dummy2; abfd->obj_arch = arch; abfd->obj_machine = machine; if (arch != bfd_arch_unknown && coff_set_flags(abfd, &dummy1, &dummy2) != true) return false; /* We can't represent this type */ - return true; /* We're easy ... */ + return true; /* We're easy ... */ } /* Calculate the file position for each section. */ static void -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 != 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... */ +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... */ #ifndef I960 - sofar = ALIGN(sofar, 1 << current->alignment_power); + 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; + /* 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; +} @@ -1449,37 +1916,37 @@ bfd *abfd; /* SUPPRESS 529 */ static boolean DEFUN(coff_write_object_contents,(abfd), -bfd *abfd) -{ - asection *current; - boolean hasrelocs = false; - boolean haslinno = false; - file_ptr reloc_base; - file_ptr lineno_base; - file_ptr sym_base; - file_ptr scn_base; - file_ptr data_base; - unsigned long reloc_size = 0; - unsigned long lnno_size = 0; - asection *text_sec = NULL; - asection *data_sec = NULL; - asection *bss_sec = NULL; - - struct internal_filehdr internal_f; - struct internal_aouthdr internal_a; + bfd *abfd) + { + asection *current; + boolean hasrelocs = false; + boolean haslinno = false; + file_ptr reloc_base; + file_ptr lineno_base; + file_ptr sym_base; + file_ptr scn_base; + file_ptr data_base; + unsigned long reloc_size = 0; + unsigned long lnno_size = 0; + asection *text_sec = NULL; + asection *data_sec = NULL; + asection *bss_sec = NULL; - struct icofdata *coff = obj_icof(abfd); + struct internal_filehdr internal_f; + struct internal_aouthdr internal_a; + struct icofdata *coff = obj_icof(abfd); - bfd_error = system_call_error; + 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(abfd->output_has_begun == false) { + coff_compute_section_file_positions(abfd); + } + + if (abfd->sections != (asection *)NULL) { + scn_base = abfd->sections->filepos; } else { scn_base = 0; @@ -1648,10 +2115,8 @@ bfd *abfd) { int magic = 0; int flags = 0; - coff_set_flags(abfd, &magic, &flags); + coff_set_flags(abfd, &magic, &internal_f.f_flags); internal_f.f_magic = magic; - internal_f.f_flags = flags; - /* ...and the "opt"hdr... */ #ifdef I960 @@ -1665,6 +2130,7 @@ bfd *abfd) obj_sym_filepos(abfd) = sym_base; if (bfd_get_symcount(abfd) != 0) { + coff_renumber_symbols(abfd); coff_mangle_symbols(abfd); coff_write_symbols(abfd); coff_write_linenumbers(abfd); @@ -1701,13 +2167,46 @@ bfd *abfd) return true; } +/* +this function transforms the offsets into the symbol table into +pointers to syments. +*/ + + +static void +DEFUN(coff_pointerize_aux,(abfd, table_base, type, class, auxent), +bfd *abfd AND +combined_entry_type *table_base AND +int type AND +int class AND +combined_entry_type *auxent) +{ + /* Don't bother if this is a file or a section */ + if (class == C_STAT && type == T_NULL) return; + if (class == C_FILE) return; + + /* Otherwise patch up */ + if (ISFCN(type) || ISTAG(class) || class == C_BLOCK) { + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = table_base + + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l; + auxent->fix_end = 1; + } +if (auxent->u.auxent.x_sym.x_tagndx.l != 0) { + auxent->u.auxent.x_sym.x_tagndx.p = table_base + auxent->u.auxent.x_sym.x_tagndx.l; + auxent->fix_tag = 1; +} + + + +} + static boolean -coff_set_section_contents(abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - size_t count; +DEFUN(coff_set_section_contents,(abfd, section, location, offset, count), + bfd *abfd AND + sec_ptr section AND + PTR location AND + file_ptr offset AND + size_t count) { if (abfd->output_has_begun == false) /* set by bfd.c handler */ coff_compute_section_file_positions(abfd); @@ -1765,67 +2264,39 @@ buy_and_read(abfd, where, seek_direction, size) return (area); } /* buy_and_read() */ -static void -DEFUN(offset_symbol_indices,(abfd, symtab, count, offset), - bfd *abfd AND - struct internal_syment *symtab AND - unsigned long count AND - long offset) + + +static char * +DEFUN(build_string_table,(abfd), +bfd *abfd) { - struct internal_syment *end = symtab + count; - for (; symtab < end; ++symtab) { - if (symtab->n_sclass == C_FILE) { - symtab->n_value = 0; - } - else if (symtab->n_sclass == C_ALIAS) { - /* - These guys have indices in their values. - */ - symtab->n_value = symtab->n_value + offset; - } - else if (symtab->n_numaux) { - /* - anybody else without an aux, has no indices. - */ - - if (symtab->n_sclass == C_EOS - || (BTYPE(symtab->n_type) == T_STRUCT - && symtab->n_sclass != C_STRTAG) - || BTYPE(symtab->n_type) == T_UNION - || BTYPE(symtab->n_type) == T_ENUM) { - /* If the tagndx is 0 then the struct hasn't really been - defined, so leave it alone */ - - if(((union internal_auxent *) (symtab + 1))->x_sym.x_tagndx != 0) { - ((union internal_auxent *) (symtab + 1))->x_sym.x_tagndx += offset; - } - - } /* These guys have a tagndx */ - if (symtab->n_sclass == C_STRTAG - || symtab->n_sclass == C_UNTAG - || symtab->n_sclass == C_ENTAG - || symtab->n_sclass == C_BLOCK - || symtab->n_sclass == C_FCN - || ISFCN(symtab->n_type)) { - - ((union internal_auxent *) (symtab + - 1))->x_sym.x_fcnary.x_fcn.x_endndx - += offset; - - } /* These guys have an endndx */ -#ifndef I960 - if (ISFCN(symtab->n_type)) { - ((union internal_auxent *) (symtab + 1))->x_sym.x_tvndx += offset; - } /* These guys have a tvndx. I think... - (FIXME) */ -#endif /* Not I960 */ - - } /* if value, else if aux */ - symtab += symtab->n_numaux; - } /* walk the symtab */ - - return; -} /* offset_symbol_indices() */ + 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. + */ + + 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, string_table_size_buffer); + + if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) { + bfd_error = no_memory; + return (NULL); + } /* on mallocation error */ + if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) { + bfd_error = system_call_error; + return (NULL); + } + return string_table; +} /* read a symbol table into freshly mallocated memory, swap it, and knit the @@ -1835,31 +2306,31 @@ Oh, and the first symbol MUST be a C_FILE. If there wasn't one there before, put one there. */ -static struct internal_syment * +static combined_entry_type * DEFUN(get_normalized_symtab,(abfd), bfd *abfd) { - struct internal_syment *internal; - struct internal_syment *internal_ptr; - struct internal_syment *internal_end; + combined_entry_type *internal; + combined_entry_type *internal_ptr; + combined_entry_type *internal_end; SYMENT *raw; SYMENT *raw_src; SYMENT *raw_end; char *string_table = NULL; unsigned long size; - char string_table_size_buffer[4]; + unsigned long string_table_size = 0; unsigned int raw_size; - if (obj_raw_syments(abfd) != (struct internal_syment *)NULL) { + if (obj_raw_syments(abfd) != (combined_entry_type *)NULL) { return obj_raw_syments(abfd); } - if ((size = bfd_get_symcount(abfd) * sizeof(struct internal_syment)) == 0) { + if ((size = bfd_get_symcount(abfd) * sizeof(combined_entry_type)) == 0) { bfd_error = no_symbols; return (NULL); } - internal = (struct internal_syment *)bfd_alloc(abfd, size); + internal = (combined_entry_type *)bfd_alloc(abfd, size); internal_end = internal + bfd_get_symcount(abfd); raw_size = bfd_get_symcount(abfd) * SYMESZ; @@ -1880,96 +2351,92 @@ bfd *abfd) /* Swap all the raw entries */ for (raw_src = raw, internal_ptr = internal; raw_src < raw_end; raw_src++, internal_ptr++) { unsigned int i; - coff_swap_sym_in(abfd, raw_src,internal_ptr); - for (i = internal_ptr->n_numaux; i; --i, raw_src++, internal_ptr++) { - coff_swap_aux_in(abfd, (AUXENT *)(raw_src +1), internal_ptr->n_type, - internal_ptr->n_sclass, (union - internal_auxent *)(internal_ptr +1)); + coff_swap_sym_in(abfd, raw_src,&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++) { + (internal_ptr+1)->fix_tag = 0; + (internal_ptr+1)->fix_end = 0; + + coff_swap_aux_in(abfd, (AUXENT *)(raw_src +1), internal_ptr->u.syment.n_type, + internal_ptr->u.syment.n_sclass, & (internal_ptr+1)->u.auxent); + + 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_src); - for (internal_ptr = internal; internal_ptr < internal_end; internal_ptr ++) { + for (internal_ptr = internal; internal_ptr < internal_end; + 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 + */ + if (string_table == NULL) { + string_table = build_string_table(abfd); + } - if (internal_ptr->_n._n_n._n_zeroes != 0) { - /* - 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. - */ + internal_ptr->u.syment._n._n_n._n_offset = + (int) (string_table - 4 + + (internal_ptr+1)->u.auxent.x_file.x_n.x_offset); + } + 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); + + } + } + else { + if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) { + /* + 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. + */ - for (i = 0; i < 8; ++i) { - if (internal_ptr->_n._n_name[i] == '\0') { - break; - } /* if end of string */ - } /* possible lengths of this string. */ + 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); - } /* on error */ - bzero(newstring, i); - strncpy(newstring, internal_ptr->_n._n_name, i-1); - internal_ptr->_n._n_n._n_offset = (int) newstring; - internal_ptr->_n._n_n._n_zeroes = 0; + if ((newstring = (PTR) bfd_alloc(abfd, ++i)) == NULL) { + bfd_error = no_memory; + return (NULL); + } /* on error */ + bzero(newstring, i); + 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 { - if (string_table == NULL) { - /* - NOTE: we don't read the string table until now because we - don't necessarily know that we have one until now. - */ - /* - 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, string_table_size_buffer); - - if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) { - bfd_error = no_memory; - return (NULL); - } /* on mallocation error */ - if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) { - bfd_error = system_call_error; - return (NULL); - } /* on error */ - } /* have not yet read the string table. */ - /* - This is a long name already. Just point it at the string in - memory. - */ - internal_ptr->_n._n_n._n_offset = (int) (string_table - 4 + internal_ptr->_n._n_n._n_offset); + } + else { + /* This is a long name already. Just point it at the string in memory. */ + 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 += internal_ptr->u.syment.n_numaux; + } - } /* switch on type of symbol name */ - - internal_ptr += internal_ptr->n_numaux; - } /* for each symbol */ -#if 0 -#ifndef GNU960 - /* I'm not sure of the repercussions of this, so the Intel - folks will always do the force - */ - if (obj_symbol_slew(abfd) > 0) - force_indices_file_symbol_relative(abfd, internal); -#else - force_indices_file_symbol_relative(abfd, internal); -#endif -#endif obj_raw_syments(abfd) = internal; obj_string_table(abfd) = string_table; @@ -1994,6 +2461,23 @@ DEFUN(section_from_bfd_index,(abfd, index), +/*doc* +@subsubsection Reading Linenumbers +Createing the linenumber table is done by reading in the entire coff +linenumber table, and creating another table for internal use. + +A coff line number table is structured so that each +function is marked as having a line number of 0. Each line within the +function is an offset from the first line in the function. The base of +the line number information for the table is stored in the symbol +associated with the function. + +The information is copied from the external to the internal table, and +each symbol which marks a function is marked by pointing its... + +**How does this work ?** + +*/ static boolean coff_slurp_line_table(abfd, asect) @@ -2029,7 +2513,7 @@ asection *asect; coff_symbol_type *sym = (coff_symbol_type *) (dst.l_addr.l_symndx + obj_symbol_slew(abfd) - + obj_raw_syments(abfd))->_n._n_n._n_zeroes; + + obj_raw_syments(abfd))->u.syment._n._n_n._n_zeroes; cache_ptr->u.sym = (asymbol *) sym; sym->lineno = cache_ptr; } @@ -2053,193 +2537,193 @@ asection *asect; static boolean DEFUN(coff_slurp_symbol_table,(abfd), bfd *abfd) - { - struct internal_syment *native_symbols; - coff_symbol_type *cached_area; - unsigned int *table_ptr; +{ + 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); + 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 */ + /* 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))); + /* 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; - } /* on error */ - table_ptr = - (unsigned int *) - bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(unsigned int))); + if (cached_area == NULL) { + bfd_error = no_memory; + return false; + } /* on error */ + 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 { - coff_symbol_type *dst = cached_area; - unsigned int last_native_index = bfd_get_symcount(abfd); - unsigned int this_index = 0; - while (this_index < last_native_index) { - struct internal_syment *src = native_symbols + this_index; - table_ptr[this_index] = number_of_symbols; - dst->symbol.the_bfd = abfd; + if (table_ptr == NULL) { + bfd_error = no_memory; + return false; + } else { + coff_symbol_type *dst = cached_area; + unsigned int last_native_index = bfd_get_symcount(abfd); + unsigned int this_index = 0; + while (this_index < last_native_index) { + 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->_n._n_n._n_offset); - /* - We use the native name field to point to the cached field - */ - src->_n._n_n._n_zeroes = (int) dst; - dst->symbol.section = section_from_bfd_index(abfd, - src->n_scnum); - switch (src->n_sclass) { + dst->symbol.name = (char *)(src->u.syment._n._n_n._n_offset); + /* + We use the native name field to point to the cached field + */ + src->u.syment._n._n_n._n_zeroes = (int) dst; + dst->symbol.section = section_from_bfd_index(abfd, + src->u.syment.n_scnum); + switch (src->u.syment.n_sclass) { #ifdef I960 - case C_LEAFEXT: + case C_LEAFEXT: #if 0 - dst->symbol.value = src->n_value - dst->symbol.section->vma; - dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL; - dst->symbol.flags |= BSF_NOT_AT_END; + dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma; + dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL; + dst->symbol.flags |= BSF_NOT_AT_END; #endif - /* Fall through to next case */ + /* Fall through to next case */ #endif - case C_EXT: - if ((src->n_scnum) == 0) { - if ((src->n_value) == 0) { - dst->symbol.flags = BSF_UNDEFINED; - dst->symbol.value= 0; - } - else { - dst->symbol.flags = BSF_FORT_COMM; - dst->symbol.value = (src->n_value); - } + case C_EXT: + if ((src->u.syment.n_scnum) == 0) { + if ((src->u.syment.n_value) == 0) { + dst->symbol.flags = BSF_UNDEFINED; + dst->symbol.value= 0; } else { + dst->symbol.flags = BSF_FORT_COMM; + dst->symbol.value = (src->u.syment.n_value); + } + } + else { + /* + Base the value as an index from the base of the + section + */ + if (dst->symbol.section == (asection *) NULL) { + dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL | BSF_ABSOLUTE; + dst->symbol.value = src->u.syment.n_value; + } + else { + dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL; + dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma; + } + if (ISFCN((src->u.syment.n_type))) { /* - Base the value as an index from the base of the - section - */ - if (dst->symbol.section == (asection *) NULL) { - dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL | BSF_ABSOLUTE; - dst->symbol.value = src->n_value; - } - else { - dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL; - dst->symbol.value = src->n_value - dst->symbol.section->vma; - } - if (ISFCN((src->n_type))) { - /* - A function ext does not go at the end of a file - */ - dst->symbol.flags |= BSF_NOT_AT_END; - } + A function ext does not go at the end of a file + */ + dst->symbol.flags |= BSF_NOT_AT_END; } + } - break; - case C_STAT: /* static */ + break; + case C_STAT: /* static */ #ifdef I960 - case C_LEAFSTAT: /* static leaf procedure */ + case C_LEAFSTAT: /* static leaf procedure */ #endif - case C_LABEL: /* label */ - dst->symbol.flags = BSF_LOCAL; - /* - Base the value as an index from the base of the section - */ - dst->symbol.value = (src->n_value) - dst->symbol.section->vma; - break; + case C_LABEL: /* label */ + dst->symbol.flags = BSF_LOCAL; + /* + 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_MOS: /* member of structure */ - case C_EOS: /* end of structure */ - case C_REGPARM: /* register parameter */ - case C_REG: /* register variable */ + case C_MOS: /* member of structure */ + case C_EOS: /* end of structure */ + case C_REGPARM: /* register parameter */ + case C_REG: /* register variable */ #ifdef C_AUTOARG - case C_AUTOARG: /* 960-specific storage class */ + case C_AUTOARG: /* 960-specific storage class */ #endif - case C_TPDEF: /* type definition */ + case C_TPDEF: /* type definition */ - case C_ARG: - case C_AUTO: /* automatic variable */ - case C_FIELD: /* bit field */ - case C_ENTAG: /* enumeration tag */ - case C_MOE: /* member of enumeration */ - case C_MOU: /* member of union */ - case C_UNTAG: /* union tag */ + case C_ARG: + case C_AUTO: /* automatic variable */ + case C_FIELD: /* bit field */ + case C_ENTAG: /* enumeration tag */ + 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->n_value); - break; + dst->symbol.flags = BSF_DEBUGGING; + dst->symbol.value = (src->u.syment.n_value); + break; - case C_FILE: /* file name */ - case C_STRTAG: /* structure tag */ - dst->symbol.flags = BSF_DEBUGGING; - dst->symbol.value = (src->n_value); + case C_FILE: /* file name */ + case C_STRTAG: /* structure tag */ + 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" */ - dst->symbol.flags = BSF_LOCAL; - /* - Base the value as an index from the base of the section - */ - dst->symbol.value = (src->n_value) - dst->symbol.section->vma; + break; + case C_BLOCK: /* ".bb" or ".eb" */ + case C_FCN: /* ".bf" or ".ef" */ + dst->symbol.flags = BSF_LOCAL; + /* + 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_EFCN: /* physical end of function */ - case C_NULL: - case C_EXTDEF: /* external definition */ - case C_ULABEL: /* undefined label */ - case C_USTATIC: /* undefined static */ - case C_LINE: /* line # reformatted as symbol table entry */ - case C_ALIAS: /* duplicate tag */ - case C_HIDDEN: /* ext symbol in dmert public lib */ + break; + case C_EFCN: /* physical end of function */ + case C_NULL: + case C_EXTDEF: /* external definition */ + case C_ULABEL: /* undefined label */ + case C_USTATIC: /* undefined static */ + case C_LINE: /* line # reformatted as symbol table entry */ + case C_ALIAS: /* duplicate tag */ + case C_HIDDEN: /* ext symbol in dmert public lib */ - default: + default: - abort(); - dst->symbol.flags = BSF_DEBUGGING; - dst->symbol.value = (src->n_value); + abort(); + dst->symbol.flags = BSF_DEBUGGING; + dst->symbol.value = (src->u.syment.n_value); - break; - } + break; + } - BFD_ASSERT(dst->symbol.flags != 0); + BFD_ASSERT(dst->symbol.flags != 0); - dst->native = src; + dst->native = src; - dst->symbol.udata = 0; - dst->lineno = (alent *) NULL; - this_index += (src->n_numaux) + 1; - dst++; - 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 */ - { - asection *p; - p = abfd->sections; - while (p) { - coff_slurp_line_table(abfd, p); - p = p->next; - } + dst->symbol.udata = 0; + dst->lineno = (alent *) NULL; + this_index += (src->u.syment.n_numaux) + 1; + dst++; + 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 */ + { + asection *p; + p = abfd->sections; + while (p) { + coff_slurp_line_table(abfd, p); + p = p->next; } - return true; - } /* coff_slurp_symbol_table() */ + } + return true; +} /* coff_slurp_symbol_table() */ static unsigned int coff_get_symtab_upper_bound(abfd) @@ -2281,6 +2765,33 @@ sec_ptr asect; return (asect->reloc_count + 1) * sizeof(arelent *); } +/*doc* +@subsubsection Reading Relocations +Coff relocations are easily transformed into the internal bfd form +(@code{arelent}). + +Reading a coff relocation table is done in the following stages: +@itemize @bullet +@item +The entire coff relocation table is read into memory. +@item +Each relocation is processed in turn, first it is swapped from the +external to the internal form. +@item +The symbol referenced in the relocation's symbol index is turned into +a pointer into the canonical symbol table. Note that this table is the +same as the one returned by a call to @code{bfd_canonicalize_symtab}. +The back end will call the routine and save the result if a +canonicalization hasn't been done. +@item +The reloc index is turned into a pointer to a howto structure, in a +back end specific way. For instance, the 386 and 960 use the +@code{r_type} to directly produce an index into a howto table vector; +the 88k subtracts a number from the @code{r_type} field and creates an +addend field. +@end itemize +*/ + static boolean DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols), bfd *abfd AND @@ -2336,7 +2847,12 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols), && ptr->section != (asection *) NULL && ((ptr->flags & BSF_OLD_COMMON)== 0)) { +#ifndef M88 cache_ptr->addend = -(ptr->section->vma + ptr->value); +#else + cache_ptr->addend = 0; +#endif + } else { cache_ptr->addend = 0; @@ -2430,7 +2946,7 @@ DEFUN(coff_find_nearest_line,(abfd, unsigned int i = 0; struct icofdata *cof = obj_icof(abfd); /* Run through the raw syments if available */ - struct internal_syment *p; + combined_entry_type *p; alent *l; unsigned int line_base = 0; @@ -2445,40 +2961,16 @@ DEFUN(coff_find_nearest_line,(abfd, if (cof == (struct icofdata *)NULL) return false; - + p = cof->raw_syments; - /* - I don't know for sure what's right, but this isn't it. First off, an - object file may not have any C_FILE's in it. After - get_normalized_symtab(), it should have at least 1, the one I put - there, but otherwise, all bets are off. Point #2, the first C_FILE - isn't necessarily the right C_FILE because any given object may have - many. I think you'll have to track sections as they coelesce in order - to find the C_STAT symbol for this section. Then you'll have to work - backwards to find the previous C_FILE, or choke if you get to a C_STAT - for the same kind of section. That will mean that the original object - file didn't have a C_FILE. xoxorich. - */ -/* -#ifdef WEREBEINGPEDANTIC - return false; -#endif - */ for (i = 0; i < cof->raw_syment_count; i++) { - if (p->n_sclass == C_FILE) { - /* File name is embeded in auxent */ - /* - This isn't right. The fname should probably be normalized - during get_normalized_symtab(). In any case, what was here - wasn't right because a SYMENT.n_name isn't an - AUXENT.x_file.x_fname. xoxorich. - */ - - *filename_ptr = ((AUXENT *) (p + 1))->x_file.x_fname; + if (p->u.syment.n_sclass == C_FILE) { + /* File name has been moved into symbol */ + *filename_ptr = (char *) p->u.syment._n._n_n._n_offset; break; } - p += 1 + p->n_numaux; + p += 1 + p->u.syment.n_numaux; } /* Now wander though the raw linenumbers of the section */ /* @@ -2503,16 +2995,16 @@ DEFUN(coff_find_nearest_line,(abfd, coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym); *functionname_ptr = coff->symbol.name; if (coff->native) { - struct internal_syment *s = coff->native; - s = s + 1 + s->n_numaux; + combined_entry_type *s = coff->native; + s = s + 1 + s->u.syment.n_numaux; /* S should now point to the .bf of the function */ - if (s->n_numaux) { + if (s->u.syment.n_numaux) { /* The linenumber is stored in the auxent */ - union internal_auxent *a = (union internal_auxent *) (s + 1); + union internal_auxent *a = &((s + 1)->u.auxent); line_base = a->x_sym.x_misc.x_lnsz.x_lnno; } } @@ -2530,6 +3022,7 @@ DEFUN(coff_find_nearest_line,(abfd, cache_offset = offset; cache_i = i; cache_l = l; + return true; } @@ -2572,3 +3065,7 @@ DEFUN(coff_sizeof_headers,(abfd, reloc), #define coff_generic_stat_arch_elt bfd_generic_stat_arch_elt #define coff_get_section_contents bfd_generic_get_section_contents #define coff_close_and_cleanup bfd_generic_close_and_cleanup + +#define coff_bfd_debug_info_start bfd_void +#define coff_bfd_debug_info_end bfd_void +#define coff_bfd_debug_info_accumulate bfd_void |