Files
2021-10-31 21:20:46 +02:00

247 lines
12 KiB
C

/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-97 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@estar.msk.su
* FIDO: 2:5020/209
*
* ARM Object File Loader
*
*/
#ifndef __AOF_H__
#define __AOF_H__
//-------------------------------------------------------------------------
struct chunk_header_t
{
uint32 ChunkFileId;
#define AOF_MAGIC 0xC3CBC6C5L // magic value of chunk file
#define AOF_MAGIC_B 0xC5C6CBC3L // magic value of chunk file (big endian)
uint32 max_chunks; // defines the number of the entries in the
// header, fixed when the file is created.
uint32 num_chunks; // defines how many chunks are currently used in
// the file, which can vary from 0 to maxChunks.
// It is redundant in that it can be found by scanning
// the entries.
};
//-------------------------------------------------------------------------
struct chunk_entry_t
{
char chunkId[8]; // an 8-byte field identifying what data the chunk
// contains. Note that this is an 8-byte field, not
// a 2-word field, so it has the same byte order
// independent of endianness.
#define OBJ_HEAD "OBJ_HEAD" // AOF Header
#define OBJ_AREA "OBJ_AREA" // Areas
#define OBJ_IDFN "OBJ_IDFN" // Identification
#define OBJ_SYMT "OBJ_SYMT" // Symbol Table
#define OBJ_STRT "OBJ_STRT" // String Table
uint32 file_offset; // a one-word field defining the byte offset within
// the file of the start of the chunk. All chunks are
// word-aligned, so it must be divisible by four.
// A value of zero indicates that the chunk entry
// is unused.
uint32 size; // a one-word field defining the exact byte size
// of the chunk's contents (which need not be a
// multiple of four).
};
//-------------------------------------------------------------------------
struct aof_header_t
{
uint32 obj_file_type; // the value 0xC5E2D080 marks the file as being in
// relocatable object format (the usual output of
// compilers and assemblers and the usual input to
// the linker). The endianness of the object code
// can be deduced from this value and must be
// identical to the endianness of the containing
// chunk file.
#define OBJ_FILE_TYPE_MAGIC 0xC5E2D080L
uint32 version; // encodes the version of AOF with which the object
// file complies
// version 1.50 is denoted by decimal 150
// version 2.00 is denoted by decimal 200
// this version is denoted by decimal 310 (0x136)
uint32 num_areas; // Number of Areas
uint32 num_syms; // Number of Symbols
uint32 entry_area; // Entry Area Index. in the range 1 to Number of
// Areas, gives the 1-origin index in the following
// array of area headers of the area containing the
// entry point. The entry address is defined to be
// the base address of this area plus Entry Offset.
// A value of 0 for Entry Area Index signifies that
// no program entry address is defined by this AOF
// file.
uint32 entry_offset;
};
//-------------------------------------------------------------------------
struct area_header_t
{
uint32 name; // Area name (offset into string table)
uint32 flags; // Attributes + Alignment
// The least significant eight bits of this word
// encode the alignment of the start of the area as a
// power of 2 and must have a value between 2 and 32.
#define AREA_ABS 0x00000100L // The absolute attribute: denotes that the
// area must be placed at its Base Address.
// This bit is not usually set by language
// processors.
#define AREA_CODE 0x00000200L // CODE (otherwise DATA)
#define AREA_COMMON 0x00000400L // The area is a common definition.
#define AREA_COMREF 0x00000800L // The area is a reference to a common block:
// preclude the area having initializing data
// (see AREA_BSS). In effect, AREA_COMREF
// implies AREA_BSS.
// If both bits AREA_COMMON and AREA_COMREF
// are set, bit AREA_COMREF is ignored.
#define AREA_BSS 0x00001000L // Zero-initialized: the area has no
// initializing data in this object file,
// and that the area contents are missing from
// the OBJ_AREA chunk.
#define AREA_RDONLY 0x00002000L // Readonly area
#define AREA_PIC 0x00004000L // The position independent (PI) area
#define AREA_DEBUG 0x00008000L // The debugging table.
// CODE areas only:
#define AREA_32BIT 0x00010000L // 32-bit area (not 26bit)
#define AREA_REENTR 0x00020000L // The re-entrant area
#define AREA_EXTFP 0x00040000L // Extended floating-point instruction set
// is used in the area.
#define AREA_NOCHK 0x00080000L // No Software Stack Check
#define AREA_THUMB 0x00100000L // Thumb code area
#define AREA_HALFW 0x00200000L // Halfword instructions may be present
#define AREA_INTER 0x00400000L // Area has been compiled to be suitable for
// ARM/Thumb interworking.
// DATA areas only:
#define AREA_BASED 0x00100000L // Based area
inline int get_based_reg() { return int(flags >> 24) & 15; }
#define AREA_SHARED 0x00200000L // Shared Library Stub Data
uint32 size; // Area Size. Gives the size of the area in bytes,
// which must be a multiple of 4. Unless the
// "Not Initialised" bit (bit 12) is set in the area
// attributes, there must be this number of bytes
// for this area in the OBJ_AREA chunk.
// If the "Not Initialised" bit is set, there must be
// no initializing bytes for this area in the
// OBJ_AREA chunk.
uint32 num_relocs; // Number of Relocations. Specifies the number of
// relocation directives which apply to this area
// (which is equivalent to the number of relocation
// records following the area's contents in the
// OBJ_AREA chunk.
uint32 baseaddr; // Base Address or 0. Is unused unless the area has
// the absolute attribute. In this case, the field
// records the base address of the area. In general,
// giving an area a base address prior to linking
// will cause problems for the linker and may prevent
// linking altogether, unless only a single object
// file is involved.
};
//-------------------------------------------------------------------------
// segment flag bits in IDA for ARM module:
// the bits are kept in netnode().altval(seg_start_ea)
#ifdef _NETNODE_HPP
#define SEGFL_NETNODE_NAME "$ arm segflags"
#define SEGFL_BREG 0x000F
#define SEGFL_PIC 0x0010
#define SEGFL_REENTR 0x0020
#define SEGFL_HALFW 0x0040
#define SEGFL_INTER 0x0080
#define SEGFL_COMDEF 0x0100
#define SEGFL_BASED 0x0200
#define SEGFL_ALIGN 0x7C00
#define SEGFL_SHIFT 10
inline void set_arm_segm_flags(ea_t ea, ushort flags)
{
netnode n;
n.create(SEGFL_NETNODE_NAME);
n.altset_ea(ea, flags);
}
inline ushort get_arm_segm_flags(ea_t ea)
{
return (ushort)netnode(SEGFL_NETNODE_NAME).altval_ea(ea);
}
#endif
//-------------------------------------------------------------------------
struct reloc_t
{
uint32 offset;
uint32 type; // Low 24bits are SID
size_t sid(void) { return size_t(type & 0x00FFFFFFL); }
#define RF_II 0x60000000uL // if RF_FT == 11, then:
// 00 no constraint (the linker may modify as many contiguous instructions as it needs to)
// 01 the linker will modify at most 1 instruction
// 10 the linker will modify at most 2 instructions
// 11 the linker will modify at most 3 instructions
#define RF_B 0x10000000uL // Based
#define RF_A 0x08000000uL // 1: The subject field is relocated by the
// value of the symbol of which SID is the
// zero-origin index in the symbol table
// chunk.
// 0: The subject field is relocated by the
// base of the area of which SID is the
// zero-origin index in the array of areas,
// (or, equivalently, in the array of area
// headers).
#define RF_R 0x04000000uL // PC relative
#define RF_FT 0x03000000uL
#define RF_FT_BYTE 0x00000000uL // 00 the field to be relocated is a byte
#define RF_FT_HALF 0x01000000uL // 01 the field to be relocated is a halfword (two bytes)
#define RF_FT_WORD 0x02000000uL // 10 the field to be relocated is a word (four bytes)
#define RF_FT_INSN 0x03000000uL // 11 the field to be relocated is an instruction or instruction sequence
};
//-------------------------------------------------------------------------
struct sym_t
{
uint32 name; // Offset in the string table (in chunk OBJ_STRT) of
// the character string name of the symbol.
uint32 flags; // Attributes.
#define SF_DEF 0x00000001 // Symbol is defined in this file
#define SF_PUB 0x00000002 // Symbol has a global scope
#define SF_ABS 0x00000004 // Absolute attribute
#define SF_ICASE 0x00000008 // Case-insensitive attribute
#define SF_WEAK 0x00000010 // Weak attribute
#define SF_STRNG 0x00000020 // Strong attribute
#define SF_COMM 0x00000040 // Common attribute
// Code symbols only:
#define SF_CDATA 0x00000100 // Code area datum attribute
#define SF_FPREG 0x00000200 // FP args in FP regs attribute
#define SF_LEAF 0x00000800 // Simple leaf function attribute
#define SF_THUMB 0x00001000 // Thumb symbol
uint32 value; // is meaningful only if the symbol is a defining
// occurrence (bit 0 of Attributes set), or a common
// symbol (bit 6 of Attributes set):
// - if the symbol is absolute (bits 0-2 of
// Attributes set), this field contains the value
// of the symbol
// - if the symbol is a common symbol (bit 6 of
// Attributes set), this contains the byte length
// of the referenced common area
// - otherwise, value is interpreted as an offset
// from the base address of the area named by
// Area Name, which must be an area defined in
// this object file
uint32 area; // Area Name is meaningful only if the symbol is a
// non-absolute defining occurrence (bit 0 of
// Attributes set, bit 2 unset). In this case it
// gives the index into the string table for the name
// of the area in which the symbol is defined (which
// must be an area in this object file).
};
#endif