247 lines
12 KiB
C
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
|