/*
 * aof.h
 *
 * Definitions for Acorn Object Format
 *
 *  1993-1998 Straylight
 */

/*----- Licensing note ----------------------------------------------------*
 *
 * This file is part of Straylight's AOF library (aoflib).
 *
 * Aoflib 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, or (at your option)
 * any later version.
 *
 * Aoflib 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 Aoflib.  If not, write to the Free Software Foundation,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifndef __aof_h
#define __aof_h

#define aof_RELOC (0xC5E2D080ul)	/* Relocatable object type	*/

typedef struct
{
  unsigned long type;			/* Type of object file		*/
  int version;				/* Version number of the format	*/
  int areas;				/* Number of AREAs defined	*/
  int symbols;				/* Number of symbols in table	*/
  int entryArea;			/* Index of AREA with ENTRY att	*/
  int entryOff;				/* Offset in AREA for ENTRY	*/
}
aof_fixedHeader;

typedef struct
{
  int name;				/* AREA name (OBJ_STRT offset)	*/

  int alignment			:8;	/* AREA alignment (must be 2)	*/

  int 				:1;	/* Reserved bit			*/
  int code			:1;	/* AREA contains code		*/
  int common			:1;	/* Common AREA definition	*/
  int commonRef			:1;	/* Reference to common AREA	*/
  int zinit			:1;	/* AREA is zero-initialised	*/
  int readonly			:1;	/* AREA is (sort-of) readonly	*/
  int				:1;	/* Reserved bit			*/
  int debug			:1;	/* AREA contains debug tables	*/
  int				:16;	/* Reserved shortword		*/

  int size;				/* Size of this AREA		*/
  int relocs;				/* Number of relocations	*/
  int				:32;	/* Reserved word		*/
}
aof_areaEntry;

typedef struct
{
  aof_fixedHeader hdr;			/* The fixed header info	*/
  aof_areaEntry table[1];		/* AREA table (unsized array)	*/
}
aof_header;

typedef struct
{
  int name;				/* Name string table entry	*/

  int defined			:1;	/* Symbol defined in file	*/
  int export			:1;	/* Symbol is exported globally	*/
  int absolute			:1;	/* Symbol not relative to AREA	*/
  int ignoreCase		:1;	/* Symbol is not case sensitive	*/
  int weak			:1;	/* Symbol is weak external ref	*/
  int strong			:1;	/* Symbol is strong global	*/
  int common			:1;	/* Symbol is in a common AREA	*/
  int				:32-7;	/* Pad out to integer boundary	*/

  int value;				/* Value of the symbol		*/
  int area;				/* Offset of AREA name		*/
}
aof_symbol;

typedef struct
{
  int offset;				/* Offset of word to relocate	*/
  union
  {
    struct
    {
      int symbol		:16;	/* Symbol to relocate by/to	*/
      int field			:2;	/* Field size to alter		*/
      int type			:1;	/* Relocation type		*/
      int symreloc		:1;	/* Relocation is symbol-relative*/
      int			:12;	/* Reserved bits		*/
    }
    type_1;				/* Type 1 relocation directive	*/

    struct
    {
      int symbol		:24;	/* Symbol to relocate by/to	*/
      int field			:2;	/* Field size to alter		*/
      int type			:1;	/* Relocation type		*/
      int symreloc		:1;	/* Relocation is symbol-relative*/
      int			:3;	/* Reserved bits		*/
      int set_me		:1;	/* Set this bit for type 2	*/
    }
    type_2;				/* Type 2 relocation directive	*/
  }
  t;
}
aof_relocstr;

enum
{
  aof_BYTE,
  aof_HALFWORD,
  aof_FULLWORD
};

enum
{
  aof_ADDITIVE,
  aof_PCRELATIVE
};

typedef struct
{
  char *p;				/* Pointer to string table	*/
  int size;				/* Current allocated size	*/
  int next;				/* Next position to fill	*/
}
aof_chunkinfo;

typedef struct
{
  aof_chunkinfo *area;
  aof_chunkinfo *symt;
  aof_chunkinfo *strt;
  aof_chunkinfo *reloc;
}
aof_file;

int aof_fillBlock(void *p,size_t offset,size_t l,aof_chunkinfo *i);

int aof_addBlock(void *p,size_t l,aof_chunkinfo *i);

#define aof_string(string,i) \
  (aof_addBlock(string,strlen(string)+1,i))
#define aof_add(z,i) \
  (aof_addBlock(&(z),sizeof(z),i))
#define aof_fill(z,o,i) \
  (aof_fillBlock(&(z),o,sizeof(z),i))
#define aof_int(x,i) \
  (aof_addBlock((o=x,&o),sizeof(int),i))
#define aof_byte(x,i) \
  (aof_addBlock((o=x,&o),1,i))
#define aof_align(i) \
  (aof_addBlock((o=0,&o),(4-i.next)&3,&i))

int aof_branch(int from,int to);

void aof_reloc(char *name,int offset,int weak,aof_file *f);

void aof_reloc_b(char *name,int offset,aof_file *f);

void aof_roff(int offset,aof_file *f);

void aof_addsym(char *name,int offset,int local,int area,aof_file *f);

#endif
