/* BFD COFF object file private structure.
   Copyright (C) 1990-1991 Free Software Foundation, Inc.
   Written by Cygnus Support.

This file is part of BFD, the Binary File Descriptor library.

This program 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 2 of the License, or
(at your option) any later version.

This program 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.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */


/* Object file tdata; access macros */

#define coff_data(bfd)		((bfd)->tdata.coff_obj_data)
#define exec_hdr(bfd)		(coff_data(bfd)->hdr)
#define obj_symbols(bfd)	(coff_data(bfd)->symbols)
#define	obj_sym_filepos(bfd)	(coff_data(bfd)->sym_filepos)

#define obj_relocbase(bfd)	(coff_data(bfd)->relocbase)
#define obj_raw_syments(bfd)	(coff_data(bfd)->raw_syments)
#define obj_convert(bfd)	(coff_data(bfd)->conversion_table)
#define obj_conv_table_size(bfd) (coff_data(bfd)->conv_table_size)
#if CFILE_STUFF
#define obj_symbol_slew(bfd)	(coff_data(bfd)->symbol_index_slew)
#else
#define obj_symbol_slew(bfd) 0
#endif


/* `Tdata' information kept for COFF files.  */

typedef struct coff_tdata
{
  struct   coff_symbol_struct *symbols;	/* symtab for input bfd */
  unsigned int *conversion_table;
  int conv_table_size;
  file_ptr sym_filepos;

  long symbol_index_slew;	/* used during read to mark whether a
				   C_FILE symbol as been added. */

  struct coff_ptr_struct *raw_syments;
  struct lineno *raw_linenos;
  unsigned int raw_syment_count;
  unsigned short flags;

  /* These are only valid once writing has begun */
  long int relocbase;

  /* These members communicate important constants about the symbol table
     to GDB's symbol-reading code.  These `constants' unfortunately vary
     from coff implementation to implementation...  */
  unsigned local_n_btmask;
  unsigned local_n_btshft;
  unsigned local_n_tmask;
  unsigned local_n_tshift;
  unsigned local_symesz;
  unsigned local_auxesz;
  unsigned local_linesz;
} coff_data_type;

/* We take the address of the first element of a asymbol to ensure that the
 * macro is only ever applied to an asymbol.  */
#define coffsymbol(asymbol) ((coff_symbol_type *)(&((asymbol)->the_bfd)))



/* And more taken from the source .. */

typedef struct coff_ptr_struct 
{

        /* Remembers the offset from the first symbol in the file for
          this symbol. Generated by coff_renumber_symbols. */
unsigned int offset;

        /* Should the tag field of this symbol be renumbered.
          Created by coff_pointerize_aux. */
char fix_tag;

        /* Should the endidx field of this symbol be renumbered.
          Created by 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;

    /* Have the line numbers been relocated yet ? */
boolean done_lineno;
} coff_symbol_type;
typedef struct {
  void (*_bfd_coff_swap_aux_in) PARAMS ((
       bfd            *abfd ,
       PTR             ext,
       int             type,
       int             class ,
       PTR             in));

  void (*_bfd_coff_swap_sym_in) PARAMS ((
       bfd            *abfd ,
       PTR             ext,
       PTR             in));

  void (*_bfd_coff_swap_lineno_in) PARAMS ((
       bfd            *abfd,
       PTR            ext,
       PTR             in));

 unsigned int (*_bfd_coff_swap_aux_out) PARAMS ((
       bfd   	*abfd,
       PTR	in,
       int    	type,
       int    	class,
       PTR    	ext));

 unsigned int (*_bfd_coff_swap_sym_out) PARAMS ((
      bfd      *abfd,
      PTR	in,
      PTR	ext));

 unsigned int (*_bfd_coff_swap_lineno_out) PARAMS ((
      	bfd   	*abfd,
      	PTR	in,
	PTR	ext));

 unsigned int (*_bfd_coff_swap_reloc_out) PARAMS ((
      	bfd     *abfd,
     	PTR	src,
	PTR	dst));

 unsigned int (*_bfd_coff_swap_filehdr_out) PARAMS ((
      	bfd  	*abfd,
	PTR 	in,
	PTR 	out));

 unsigned int (*_bfd_coff_swap_aouthdr_out) PARAMS ((
      	bfd 	*abfd,
	PTR 	in,
	PTR	out));

 unsigned int (*_bfd_coff_swap_scnhdr_out) PARAMS ((
      	bfd  	*abfd,
      	PTR	in,
	PTR	out));

} bfd_coff_backend_data;

extern bfd_coff_backend_data bfd_coff_std_swap_table;

#define coff_backend_info(abfd) ((bfd_coff_backend_data *) (abfd)->xvec->backend_data)

#define bfd_coff_swap_aux_in(a,e,t,c,i) \
        ((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,i))

#define bfd_coff_swap_sym_in(a,e,i) \
        ((coff_backend_info (a)->_bfd_coff_swap_sym_in) (a,e,i))

#define bfd_coff_swap_lineno_in(a,e,i) \
        ((coff_backend_info ( a)->_bfd_coff_swap_lineno_in) (a,e,i))

#define bfd_coff_swap_reloc_out(abfd, i, o) \
        ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_out) (abfd, i, o))

#define bfd_coff_swap_lineno_out(abfd, i, o) \
        ((coff_backend_info (abfd)->_bfd_coff_swap_lineno_out) (abfd, i, o))

#define bfd_coff_swap_aux_out(abfd, i, t,c,o) \
        ((coff_backend_info (abfd)->_bfd_coff_swap_aux_out) (abfd, i,t,c, o))

#define bfd_coff_swap_sym_out(abfd, i,o) \
        ((coff_backend_info (abfd)->_bfd_coff_swap_sym_out) (abfd, i, o))

#define bfd_coff_swap_scnhdr_out(abfd, i,o) \
        ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_out) (abfd, i, o))

#define bfd_coff_swap_filehdr_out(abfd, i,o) \
        ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_out) (abfd, i, o))

#define bfd_coff_swap_aouthdr_out(abfd, i,o) \
        ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_out) (abfd, i, o))