update to ida 7.6, add builds

This commit is contained in:
2021-10-31 21:20:46 +02:00
parent e0e0f2be99
commit b1809fe2d9
1408 changed files with 279193 additions and 302468 deletions

660
idasdk76/ldr/aout/aout.cpp Normal file
View File

@@ -0,0 +1,660 @@
/*
* This Loader Module is written by Yury Haron
*
*/
/*
L O A D E R for a.out (Linux)
*/
#include "../idaldr.h"
//#define DEBUG
#include "aout.h"
#include "common.cpp"
#include "../../module/sparc/notify_codes.hpp"
class aout_t
{
public:
exec ex;
nlist *symtab;
char *strtab;
uint32 symcount; // number of symbols in symtab
uint32 text; // first address of each section
uint32 data;
uint32 bss;
uint32 extrn;
uint32 top; // next available address
uint32 treloff; // file offset of each section
uint32 dreloff;
uint32 symoff;
uint32 stroff;
bool msb;
aout_t(void)
{
memset((void*) this, 0, sizeof(*this));
}
~aout_t()
{
if ( symtab != NULL )
{
qfree(symtab);
symtab = NULL;
}
if ( strtab != NULL )
{
qfree(strtab);
strtab = NULL;
}
}
};
//--------------------------------------------------------------------------
static const char *guess_processor(const exec &ex)
{
if ( N_MACHTYPE(ex) )
{
switch ( N_MACHTYPE(ex) )
{
case M_386:
case M_386_NETBSD:
return "metapc";
case M_ARM:
case M_ARM6_NETBSD:
return "arm";
case M_SPARC:
return "sparcb";
default:
break;
}
}
return NULL;
}
//--------------------------------------------------------------------------
//
// check input file format. if recognized, then return 1
// and fill 'fileformatname'.
// otherwise return 0
//
static int idaapi accept_file(
qstring *fileformatname,
qstring *processor,
linput_t *li,
const char *)
{
exec ex;
int i = get_aout_file_format_index(li, &ex);
#ifdef DEBUG
msg("getfmtindex=%d\n", i);
#endif
if ( i == 0 )
return 0;
static const char *const ff[] =
{
"demand-paged executable with NULL-ptr check", // q
"object or impure executable", // o
"demand-paged executable", // z
"core", // c
"pure executable", // n
"OpenBSD demand-paged executable", // zo
};
fileformatname->sprnt("a.out (%s)", ff[i-1]);
*processor = guess_processor(ex);
#ifdef DEBUG
msg("%s\n", fileformatname.c_str());
#endif
return f_AOUT;
}
//--------------------------------------------------------------------------
static void create32(
processor_t &ph,
ushort sel,
ea_t start_ea,
ea_t end_ea,
const char *name,
const char *classname)
{
set_selector(sel, 0);
if ( !add_segm(sel, start_ea, end_ea, name, classname, ADDSEG_SPARSE) )
loader_failure();
if ( ph.id == PLFM_386 )
set_segm_addressing(getseg(start_ea), 1);
}
//--------------------------------------------------------------------------
bool ana_hdr(processor_t &ph, linput_t *li, exec *_ex)
{
bool msb = false;
exec &ex = *_ex;
lread(li, &ex, sizeof(ex));
if ( N_BADMAG(ex) )
{
swap_exec(ex);
msb = true;
msg("Assuming big-endian...\n");
}
const char *proc = guess_processor(ex);
if ( proc != NULL )
{
set_processor_type(proc, SETPROC_LOADER);
if ( N_MACHTYPE(ex) == M_SPARC )
sparc_module_t::set_v8(true); // set SPARC_V8 parameter
}
else
{
if ( ask_yn(ASKBTN_YES,
"HIDECANCEL\n"
"AUTOHIDE REGISTRY\n"
"Missing machine type. Continue?") <= ASKBTN_NO )
{
loader_failure();
}
if ( ph.id == -1 )
set_processor_type(inf_get_procname().c_str(), SETPROC_LOADER);
}
return msb;
}
//--------------------------------------------------------------------------
inline fixup_type_t get_hi22_reltype()
{
static fixup_type_t hi22_reltype = FIXUP_CUSTOM;
if ( hi22_reltype == FIXUP_CUSTOM )
hi22_reltype = find_custom_fixup("HI22");
return hi22_reltype;
}
//--------------------------------------------------------------------------
inline fixup_type_t get_lo10_reltype()
{
static fixup_type_t lo10_reltype = FIXUP_CUSTOM;
if ( lo10_reltype == FIXUP_CUSTOM )
lo10_reltype = find_custom_fixup("LO10");
return lo10_reltype;
}
//--------------------------------------------------------------------------
static void do_fixup(uint32 where, uint32 delta, uint32 target, fixup_type_t type, int external)
{
fixup_data_t fd(type);
if ( external )
fd.set_extdef();
fd.displacement = delta;
if ( external )
target -= delta;
segment_t *s = getseg(target);
if ( s != NULL )
{
fd.sel = s->sel;
fd.off = target - get_segm_base(s);
}
else
{
fd.off = target;
}
fd.set(where);
}
#define S_MASK(x) ((1 << (x)) - 1)
//----------------------------------------------------------------------
static void do_relocation_sparc(
linput_t *li,
const aout_t &ctx,
uint32 off,
uint32 len,
int seg)
{
const segment_t *seg_p = getnseg(seg);
if ( seg_p == NULL )
{
msg("relocation data for missing segment %d ignored\n", seg);
return;
}
uint32 base = seg == 1 ? ctx.text : ctx.data;
#ifdef DEBUG
msg("seg %d base 0x%08X\n", seg, base);
#endif
// load relocation table
uint32 relcount = len / sizeof(reloc_info_sparc);
validate_array_count(li, &relcount, sizeof(reloc_info_sparc), "Relocation count", off);
if ( relcount == 0 )
return;
reloc_info_sparc *reltab = qalloc_array<reloc_info_sparc>(relcount);
if ( reltab == NULL )
loader_failure("Unable to allocate relocation table for %u entries\n", relcount);
qlseek(li, off);
for ( reloc_info_sparc *rel = reltab; rel < reltab + relcount; rel++ )
{
uint32 temp = 0;
lread4bytes(li, &rel->r_address, ctx.msb);
lread4bytes(li, &temp, ctx.msb);
lread4bytes(li, &rel->r_addend, ctx.msb);
rel->r_index = (temp >> 8) & 0x00FFFFFF;
rel->r_extern = (temp >> 7) & 1;
rel->r_type = (reloc_type_sparc) ((temp) & 0x1F);
#ifdef DEBUG
if ( rel->r_address >= 0x80C8 && rel->r_address <= 0x8200 )
msg("%08X: index=0x%06X extern=%d type=%02X addend=0x%08X\n",
rel->r_address, rel->r_index, rel->r_extern, rel->r_type, rel->r_addend);
#endif
}
// perform relocation
for ( reloc_info_sparc *rel = reltab; rel < reltab + relcount; rel++ )
{
uint32 where = base + rel->r_address;
uint32 instr = get_dword(where);
fixup_type_t type = FIXUP_OFF32;
uint32 target = where;
uint32 value;
uint32 merged;
#ifdef DEBUG
value = instr;
merged = instr;
#endif
if ( rel->r_extern )
{
if ( rel->r_index >= ctx.symcount )
{
msg("%08X: relocation to extern symbol idx %08X out of bounds, ignored\n", where, rel->r_index);
continue;
}
nlist *sym = &ctx.symtab[rel->r_index];
// The in-database address for this symbol was set when loading the symtab.
target = sym->n_value;
target += rel->r_addend;
/*
if ( (sym->n_type & N_TYPE ) != N_ABS &&
(sym->n_type & N_TYPE) != N_COMM)
target += where;
if ( (rel->r_type == SPARC_RELOC_PC10 ) ||
(rel->r_type == SPARC_RELOC_PC22))
target -= where;
*/
}
else
{
if ( rel->r_type == SPARC_RELOC_HI22 || rel->r_type == SPARC_RELOC_LO10 )
target = rel->r_addend;
if ( seg == 2 && rel->r_type == SPARC_RELOC_32 )
target = rel->r_addend;
/*
if ( (rel->r_index == N_TEXT ) ||
(rel->r_index == N_DATA) ||
(rel->r_index == N_BSS))
target = rel->r_addend;
*/
}
uint32 delta = 0;
switch ( rel->r_type )
{
case SPARC_RELOC_32:
value = instr;
target += value;
merged = target;
break;
case SPARC_RELOC_WDISP30:
value = (instr & S_MASK(30));
target += value;
merged = (instr & ~S_MASK(30)) | ((target >> 2) & S_MASK(30));
break;
case SPARC_RELOC_WDISP22:
value = (instr & S_MASK(22));
target += value;
merged = (instr & ~S_MASK(22)) | ((target >> 2) & S_MASK(22));
break;
case SPARC_RELOC_HI22:
value = (instr & S_MASK(22)) << 10;
target += value;
merged = (instr & ~S_MASK(22)) | ((target >> 10) & S_MASK(22));
delta = 0; //-(target & S_MASK(10));
type = get_hi22_reltype();
break;
case SPARC_RELOC_LO10:
value = (instr & S_MASK(10));
target += value;
merged = (instr & ~S_MASK(10)) | ((target) & S_MASK(10));
type = get_lo10_reltype();
break;
default:
msg("Unsupported sparc relocation type 0x%02X, ignored\n", rel->r_type);
continue;
}
#ifdef DEBUG
// if ( rel->r_address < 0x300 )
// msg("%08X: %08X -> %08X (%08X -> %08X)\n", where, instr, merged, value, target);
#endif
put_dword(where, merged);
do_fixup(where, rel->r_extern ? rel->r_addend : delta, target, type, rel->r_extern);
}
qfree(reltab);
}
//----------------------------------------------------------------------
static void do_relocation(linput_t *li, const aout_t &ctx, uint32 off, uint32 len, int seg)
{
switch ( N_MACHTYPE(ctx.ex) )
{
case M_SPARC:
do_relocation_sparc(li, ctx, off, len, seg);
break;
default:
msg("Warning: Relocation in image file not supported yet for this processor\n");
break;
}
}
//----------------------------------------------------------------------
void load_syms(linput_t *li, aout_t &ctx)
{
// get string table length
uint32 tabsize = 0;
qlseek(li, ctx.stroff);
lread4bytes(li, &tabsize, ctx.msb);
#ifdef DEBUG
msg("symoff=0x%08x symlen=0x%08x stroff=0x%08x strlen=0x%08x\n",
ctx.symoff, ctx.ex.a_syms, ctx.stroff, tabsize);
#endif
// load string table
char *strtab = (char *)qalloc(tabsize+1);
if ( strtab == NULL )
loader_failure("Unable to allocate string table for %u bytes\n", tabsize+1);
qlseek(li, ctx.stroff);
lreadbytes(li, strtab, tabsize, false);
strtab[tabsize] = '\0'; // ensure trailing zero
// load symbol table
ctx.symcount = ctx.ex.a_syms / sizeof(nlist);
validate_array_count_or_die(li, ctx.symcount, sizeof(nlist),
"Number of symbols", ctx.symoff);
nlist *symtab = qalloc_array<nlist>(ctx.symcount);
if ( symtab == NULL )
loader_failure("Unable to allocate symbol table for %u entries\n", ctx.symcount);
qlseek(li, ctx.symoff);
uint32 extern_count = 0;
for ( nlist *sym = symtab; sym < symtab + ctx.symcount; sym++ )
{
lread4bytes(li, &sym->n_un.n_strx, ctx.msb);
lreadbytes(li, &sym->n_type, 1, ctx.msb);
lreadbytes(li, &sym->n_other, 1, ctx.msb);
lread2bytes(li, &sym->n_desc, ctx.msb);
lread4bytes(li, &sym->n_value, ctx.msb);
if ( sym->n_type == N_EXT )
extern_count++;
}
// create extern section
uint32 extern_base = ctx.top;
if ( extern_count != 0 )
{
// create new segment
add_segm(0, extern_base, extern_base + (extern_count * 4), "extern", "XTRN", ADDSEG_SPARSE);
ctx.extrn = extern_base;
ctx.top += extern_count * 4;
}
// import symbols
#ifdef DEBUG
int i = 0;
#endif
uint32 i_extern = 0;
for ( nlist *sym = symtab; sym < symtab + ctx.symcount; sym++ )
{
if ( sym->n_type & N_STAB ) // debug stab info, not a symbol
continue;
if ( sym->n_type == N_EXT )
{
sym->n_value = extern_base + (i_extern * 4);
if ( getseg(sym->n_value) )
put_dword(sym->n_value, 0);
i_extern++;
}
if ( getseg(sym->n_value) != NULL )
{
if ( sym->n_un.n_strx < tabsize )
{
set_name(sym->n_value, strtab + sym->n_un.n_strx,
(sym->n_type & N_EXT ? SN_PUBLIC : SN_NON_PUBLIC)|SN_NOCHECK|SN_NOWARN|SN_IDBENC);
}
else
{
msg("%08X: type=0x%02X other=0x%02X desc=0x%04X: bad str offset %08X\n",
sym->n_value, sym->n_type, sym->n_other, sym->n_desc,
sym->n_un.n_strx);
}
}
if ( (sym->n_type & N_TYPE) == N_ABS )
{
#ifdef DEBUG
msg("%04X: %08X: type=0x%02X other=0x%02X desc=0x%04X: %s\n",
i, sym->n_value, sym->n_type, sym->n_other, sym->n_desc,
strtab + sym->n_un.n_strx);
#endif
}
#ifdef DEBUG
i++;
#endif
}
ctx.strtab = strtab;
ctx.symtab = symtab;
}
//--------------------------------------------------------------------------
static void handle_ld_info(linput_t *li, int diroff, int base)
{
lddir_t lddir;
qlseek(li, diroff);
lread(li, &lddir, sizeof(lddir));
ld_info_t ldinfo;
qlseek(li, lddir.ldinfo-base);
lread(li, &ldinfo, sizeof(ldinfo));
qoff64_t fpos = ldinfo.symbols - base;
int nsyms = (ldinfo.strings - ldinfo.symbols) / sizeof(ld_symbol_t);
validate_array_count(li, &nsyms, sizeof(ld_symbol_t), "Symbol count", fpos);
qlseek(li, fpos);
for ( int i=0; i < nsyms; i++ )
{
ld_symbol_t sym;
lread(li, &sym, sizeof(sym));
char name[MAXSTR];
qlgetz(li, ldinfo.strings + sym.nameoff - base, name, sizeof(name));
set_name(sym.addr, name, SN_IDBENC);
if ( (sym.flags & (AOUT_LD_FUNC|AOUT_LD_DEF)) == AOUT_LD_FUNC )
{ // imported function
put_byte(sym.addr, 0xC3); // return
if ( sym.addr <= ldinfo.ldentry )
warning("interr: symbol #%d (%s) is not in the plt", i, name);
}
}
}
//--------------------------------------------------------------------------
//
// load file into the database.
//
void idaapi load_file(linput_t *li, ushort /*neflag*/, const char * /*fileformatname*/)
{
processor_t &ph = PH;
aout_t ctx;
exec &ex = ctx.ex;
ctx.msb = ana_hdr(ph, li, &ex);
ctx.symtab = NULL;
ctx.symcount = 0;
ctx.strtab = NULL;
ctx.treloff = N_TRELOFF(ex);
ctx.dreloff = N_DRELOFF(ex);
ctx.symoff = N_SYMOFF(ex);
ctx.stroff = N_STROFF(ex);
int txtoff = N_TXTOFF(ex);
int txtadr;
switch ( ph.id )
{
case PLFM_SPARC:
txtoff = N_TXTOFF_SPARC(ex);
txtadr = N_TXTADDR_SPARC(ex);
ctx.treloff = N_TRELOFF_SPARC(ex);
ctx.dreloff = N_DRELOFF_SPARC(ex);
ctx.symoff = N_SYMOFF_SPARC(ex);
ctx.stroff = N_STROFF_SPARC(ex);
break;
case PLFM_ARM:
txtadr = N_TXTADDR_ARM(ex);
break;
default:
txtadr = N_TXTADDR(ex);
switch ( N_MAGIC(ex) )
{
// case NMAGIC:
// case CMAGIC:
default:
loader_failure("This image type is not supported yet");
case ZMAGIC:
if ( qlsize(li) < ex.a_text + ex.a_data + N_SYMSIZE(ex) + txtoff )
{
txtoff = 0;
txtadr = 0x1000;
}
else if ( txtoff < 512 )
{
loader_failure("Size of demand page < size of block");
}
// fallthrough
case QMAGIC:
if ( ex.a_text & 0xFFF || ex.a_data & 0xFFF )
loader_failure("Executable is not page aligned");
break;
case OMAGIC:
txtoff = sizeof(ex);
break;
}
break;
}
inf_set_baseaddr(0);
uint32 base, top;
top = base = txtadr;
if ( ex.a_text || ex.a_data )
{
top += ex.a_text;
// msg("txtoff=%d, base=%d top=%d end=%d\n", txtoff, base, top, top+ex.a_data);
file2base(li, txtoff, base, top + ex.a_data, FILEREG_PATCHABLE);
if ( ex.a_text )
{
create32(ph, 1, base, top, NAME_CODE, CLASS_CODE);
inf_set_start_cs(1);
inf_set_start_ip(ex.a_entry);
ctx.text = base;
}
if ( ex.a_data )
{
base = top;
create32(ph, 2, base, top += ex.a_data, NAME_DATA, CLASS_DATA);
set_default_dataseg(2);
ctx.data = base;
}
}
if ( ex.a_bss )
{
create32(ph, 3, top, top + ex.a_bss, NAME_BSS, CLASS_BSS);
ctx.bss = top;
}
ctx.top = top + ex.a_bss;
if ( ex.a_syms )
load_syms(li, ctx);
if ( N_TRSIZE(ex) )
do_relocation(li, ctx, ctx.treloff, N_TRSIZE(ex), 1);
if ( N_DRSIZE(ex) )
do_relocation(li, ctx, ctx.dreloff, N_DRSIZE(ex), 2);
// We come in here for the regular a.out style of shared libraries */
// ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
// return -ENOEXEC;
// }
// For QMAGIC, the starting address is 0x20 into the page. We mask
// this off to get the starting address for the page */
// start_addr = ex.a_entry & 0xfffff000;
//////
if ( ph.id != PLFM_SPARC && N_FLAGS(ex) & EX_PIC )
handle_ld_info(li, ex.a_text, txtadr);
create_filename_cmt();
add_pgm_cmt("Flag value: %Xh", N_FLAGS(ex));
}
//----------------------------------------------------------------------
//
// LOADER DESCRIPTION BLOCK
//
//----------------------------------------------------------------------
loader_t LDSC =
{
IDP_INTERFACE_VERSION,
0, // loader flags
//
// check input file format. if recognized, then return 1
// and fill 'fileformatname'.
// otherwise return 0
//
accept_file,
//
// load file into the database.
//
load_file,
//
// create output file from the database.
// this function may be absent.
//
NULL,
// take care of a moved segment (fix up relocations, for example)
NULL,
NULL,
};

283
idasdk76/ldr/aout/aout.h Normal file
View File

@@ -0,0 +1,283 @@
#ifndef __AOUT_H__
#define __AOUT_H__
#pragma pack(push, 1)
struct exec
{
uint32 a_info; // Use macros N_MAGIC, etc for access
uint32 a_text; // length of text, in bytes
uint32 a_data; // length of data, in bytes
uint32 a_bss; // length of bss area for file, in bytes
uint32 a_syms; // length of symbol table data in file, in bytes
uint32 a_entry; // start address
uint32 a_trsize; // length of relocation info for text, in bytes
uint32 a_drsize; // length of relocation info for data, in bytes
// Added for i960
// uint32 a_tload; // Text runtime load adderr
// uint32 a_dload; // Data runtime load address
// uchar a_talign; // Alignment of text segment
// uchar a_dalign; // Alignmrnt of data segment
// uchar a_balign; // Alignment of bss segment
// char a_relaxable;// Enough info for linker relax
};
//====================
#define N_TRSIZE(a) ((a).a_trsize)
#define N_DRSIZE(a) ((a).a_drsize)
#define N_SYMSIZE(a) ((a).a_syms)
#define N_DYNAMIC(exec) ((exec).a_info & 0x80000000ul)
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
//====================
enum machine_type
{
// M_OLDSUN2 = 0,
M_UNKNOWN = 0,
M_68010 = 1,
M_68020 = 2,
M_SPARC = 3,
/*-----------------11.07.98 04:09-------------------
* skip a bunch so we don't run into any of suns numbers */
/*-----------------11.07.98 04:09-------------------
* make these up for the ns32k*/
M_NS32032 = (64), /* ns32032 running ? */
M_NS32532 = (64 + 5), /* ns32532 running mach */
M_386 = 100,
M_29K = 101, /* AMD 29000 */
M_386_DYNIX = 102, /* Sequent running dynix */
M_ARM = 103, /* Advanced Risc Machines ARM */
M_SPARCLET = 131, /* SPARClet = M_SPARC + 128 */
M_386_NETBSD = 134, /* NetBSD/i386 binary */
M_68K_NETBSD = 135, /* NetBSD/m68k binary */
M_68K4K_NETBSD = 136, /* NetBSD/m68k4k binary */
M_532_NETBSD = 137, /* NetBSD/ns32k binary */
M_SPARC_NETBSD = 138, /* NetBSD/sparc binary */
M_PMAX_NETBSD = 139, /* NetBSD/pmax (MIPS little-endian) binary */
M_VAX_NETBSD = 140, /* NetBSD/vax binary */
M_ALPHA_NETBSD = 141, /* NetBSD/alpha binary */
M_ARM6_NETBSD = 143, /* NetBSD/arm32 binary */
M_SPARCLET_1 = 147, /* 0x93, reserved */
M_MIPS1 = 151, /* MIPS R2000/R3000 binary */
M_MIPS2 = 152, /* MIPS R4000/R6000 binary */
M_SPARCLET_2 = 163, /* 0xa3, reserved */
M_SPARCLET_3 = 179, /* 0xb3, reserved */
M_SPARCLET_4 = 195, /* 0xc3, reserved */
M_HP200 = 200, /* HP 200 (68010) BSD binary */
M_HP300 = (300 % 256), /* HP 300 (68020+68881) BSD binary */
M_HPUX = (0x20c % 256), /* HP 200/300 HPUX binary */
M_SPARCLET_5 = 211, /* 0xd3, reserved */
M_SPARCLET_6 = 227, /* 0xe3, reserved */
M_SPARCLET_7 = 243 /* 0xf3, reserved */
};
//====================
#define OMAGIC 0407 // object file or impure executable
#define NMAGIC 0410 // pure executeable
#define ZMAGIC 0413 // demand-paged executable
#define BMAGIC 0415 // Used by a b.out object
#define QMAGIC 0314 // demand-paged executable with the header in the text.
// The first page is unmapped to help trap NULL pointer
// referenced
#define CMAGIC 0421 // core file
//====================
// Flags:
#define EX_PIC 0x80 /* contains position independent code */
#define EX_DYNAMIC 0x40 /* contains run-time link-edit info */
#define EX_DPMASK 0xC0 /* mask for the above */
//====================
#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
&& N_MAGIC(x) != NMAGIC \
&& N_MAGIC(x) != ZMAGIC \
&& N_MAGIC(x) != QMAGIC)
#define _N_HDROFF(x) (1024 - sizeof(struct exec))
#define N_TXTOFF(x) \
(N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
(N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
#define N_DRELOFF(x) (N_TRELOFF(x) + N_TRSIZE(x))
#define N_SYMOFF(x) (N_DRELOFF(x) + N_DRSIZE(x))
#define N_STROFF(x) (N_SYMOFF(x) + (x).a_syms)
// Address of text segment in memory after it is loaded
#define PAGE_SIZE (1UL << 12)
#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? PAGE_SIZE : 0)
#define PAGE_SIZE_ARM 0x8000UL
#define N_TXTADDR_ARM(x) (N_MAGIC(x) == QMAGIC ? 0 : PAGE_SIZE_ARM)
// Address of data segment in memory after it is loaded. (for linux)
/*
#define SEGMENT_SIZE 1024
#define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1))
#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
#define N_DATADDR(x) \
(N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) : \
(_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
// Address of bss segment in memory after it is loaded
#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
*/
//========================
struct nlist
{
union
{
int32 n_strx;
} n_un;
uchar n_type;
char n_other;
short n_desc;
uint32 n_value;
};
#define N_UNDF 0 // Undefined symbol
#define N_ABS 2 // Absolute symbol -- addr
#define N_TEXT 4 // Text sym -- offset in text segment
#define N_DATA 6 // Data sym -- offset in data segment
#define N_BSS 8 // BSS sym -- offset in bss segment
#define N_COMM 0x12 // Common symbol (visible after shared)
#define N_FN 0x1F // File name of .o file
#define N_FN_SEQ 0x0C // N_FN from Sequent compilers
#define N_EXT 1 // External (ORed wits UNDF, ABS, TEXT, DATA or BSS)
#define N_TYPE 0x1E
#define N_STAB 0xE0 // If present - debug symbol
#define N_INDR 0xA // symbol refernced to another symbol
#define N_SETA 0x14 // Absolute set element symbol
#define N_SETT 0x16 // Text set element symbol
#define N_SETD 0x18 // Data set element symbol
#define N_SETB 0x1A // Bss set element symbol
#define N_SETV 0x1C // Pointer to set vector in data area. (from LD)
#define N_WARNING 0x1E // Text has warnings
// Weak symbols
#define N_WEAKU 0x0D // Weak undefined
#define N_WEAKA 0x0E // Weak Absolute
#define N_WEAKT 0x0F // Weak Text
#define N_WEAKD 0x10 // Weak Data
#define N_WEAKB 0x11 // Weak BSS
//=======================
struct relocation_info
{
int32 r_address; // Adress (within segment) to be relocated
uint32 r_symbolnum:24;// The meaning of r_symbolnum depends on r_extern
uint32 r_pcrel:1; // Nonzero means value is a pc-relative offset
uint32 r_length:2; // Length (exp of 2) of the field to be relocated.
uint32 r_extern:1; // 1 => relocate with value of symbol.
// r_symbolnum is the index of the symbol
// in file's the symbol table.
// 0 => relocate with the address of a segment.
// r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
uint32 r_bsr:1;
uint32 r_disp:1;
uint32 r_pad:2;
};
//============================
// The SPARC_ prefix is added to the canonical names below to avoid a name
// conflict if other architectures are added
enum reloc_type_sparc
{
SPARC_RELOC_8, SPARC_RELOC_16, SPARC_RELOC_32, // simplest relocs
SPARC_RELOC_DISP8, SPARC_RELOC_DISP16, SPARC_RELOC_DISP32, // disp's (pc-rel)
SPARC_RELOC_WDISP30, SPARC_RELOC_WDISP22, // SR word disp's
SPARC_RELOC_HI22, SPARC_RELOC_22, // SR 22-bit relocs
SPARC_RELOC_13, SPARC_RELOC_LO10, // SR 13&10-bit relocs
SPARC_RELOC_SFA_BASE, SPARC_RELOC_SFA_OFF13, // SR S.F.A. relocs
SPARC_RELOC_BASE10, SPARC_RELOC_BASE13, SPARC_RELOC_BASE22, // base_relative pic
SPARC_RELOC_PC10, SPARC_RELOC_PC22, // special pc-rel pic
SPARC_RELOC_JMP_TBL, // jmp_tbl_rel in pic
SPARC_RELOC_SEGOFF16, // ShLib offset-in-seg
SPARC_RELOC_GLOB_DAT, SPARC_RELOC_JMP_SLOT, SPARC_RELOC_RELATIVE, // rtld relocs
};
struct reloc_info_sparc
{
uint32 r_address; // relocation address (offset in segment)
uint32 r_index:24; // segment index or symbol index
uint32 r_extern:1; // if F, r_index==SEG#, if T, SYM index
uint32 :2; // unused
uint32 r_type:5; // type of relocation to perform
uint32 r_addend; // addend for relocation value
};
CASSERT(sizeof(reloc_info_sparc) == 12);
#define N_PAGSIZ_SPARC(x) 0x02000
#define N_SEGSIZ_SPARC(x) N_PAGSIZ_SPARC
#define N_TXTOFF_SPARC(x) ((N_MAGIC(x) == ZMAGIC) ? 0 : sizeof (struct exec))
#define N_TXTADDR_SPARC(x) \
((N_MAGIC(x) == OMAGIC) ? (x).a_entry \
: ((N_MAGIC(x) == ZMAGIC) && ((x).a_entry < N_PAGSIZ_SPARC(x)) ? 0 \
: N_PAGSIZ_SPARC(x)) \
)
#define N_DATOFF_SPARC(x) (N_TXTOFF_SPARC(x) + (x).a_text)
#define N_DATADDR_SPARC(x) \
((N_MAGIC(x) == OMAGIC) ? (N_TXTADDR_SPARC(x) + (x).a_text) \
: (N_SEGSIZ_SPARC(x)+((N_TXTADDR_SPARC(x)+(x).a_text-1) \
& ~(N_SEGSIZ_SPARC(x)-1))))
#define N_BSSADDR_SPARC(x) (N_DATADDR_SPARC(x) + (x).a_data)
#define N_TRELOFF_SPARC(x) (N_DATOFF_SPARC(x) + (x).a_data)
#define N_DRELOFF_SPARC(x) (N_TRELOFF_SPARC(x) + N_TRSIZE(x))
#define N_SYMOFF_SPARC(x) (N_DRELOFF_SPARC(x) + N_DRSIZE(x))
#define N_STROFF_SPARC(x) (N_SYMOFF_SPARC(x) + (x).a_syms)
//============================
// Dynamic loader info (restored from a binary form in pc_bsd.aout, not exact):
struct lddir_t
{
uint32 unknown0; // 8
uint32 unknown1; // offset dword_5010
uint32 ldinfo;
};
struct ld_info_t
{
uint32 unknown0; // 0
uint32 onemoretable;
uint32 unknown1; // 0
uint32 off_5060; // points to the end of this struct
uint32 ldentry; // main dynamic loader entry
uint32 imports;
uint32 pairs; // pairs of symbol numbers
uint32 symbols;
uint32 unknown2; // 0
uint32 unknown3; // 16h
uint32 strings;
uint32 unknown4; // 310h
uint32 unknown5; // 4000h
uint32 unknown6; // 148h
uint32 unknown7; // offset dword_5000
};
struct ld_symbol_t
{
uint32 nameoff; // offset from the beginning of the string table
uint32 flags;
#define AOUT_LD_FUNC 0x200
#define AOUT_LD_DEF 0x004 // defined, otherwise - imported
#define AOUT_LD_DATA 0x002 // data
uint32 addr; // pointer to the object
uint32 zero; // always zero?
};
#pragma pack(pop)
#endif

View File

@@ -0,0 +1,76 @@
//--------------------------------------------------------------------------
static void swap_exec(exec &ex)
{
ex.a_info = swap32(ex.a_info);
ex.a_text = swap32(ex.a_text);
ex.a_data = swap32(ex.a_data);
ex.a_bss = swap32(ex.a_bss);
ex.a_syms = swap32(ex.a_syms);
ex.a_entry = swap32(ex.a_entry);
ex.a_trsize = swap32(ex.a_trsize);
ex.a_drsize = swap32(ex.a_drsize);
}
//--------------------------------------------------------------------------
int get_aout_file_format_index(linput_t *li, exec *_ex)
{
exec &ex = *_ex;
int i = 0;
if ( qlread(li, &ex, sizeof(ex)) != sizeof(ex) )
return false;
if ( N_BADMAG(ex) )
{
swap_exec(ex);
switch ( N_MACHTYPE(ex) )
{
case M_386_NETBSD:
case M_68K_NETBSD:
case M_68K4K_NETBSD:
case M_532_NETBSD:
case M_SPARC:
case M_SPARC_NETBSD:
case M_PMAX_NETBSD:
case M_VAX_NETBSD:
case M_ALPHA_NETBSD:
case M_ARM6_NETBSD:
break;
default:
return false;
}
}
switch ( N_MAGIC(ex) )
{
case NMAGIC:
++i;
case CMAGIC:
++i;
case ZMAGIC:
++i;
case OMAGIC:
++i;
case QMAGIC:
if ( N_MACHTYPE(ex) == M_SPARC )
break; // SPARC uses different TXTOFF
#ifdef DEBUG
msg("magic=%04x text=%08x data=%08x symsize=%08x txtoff=%08x sum=%08x // qlsize=%08x\n", N_MAGIC(ex), ex.a_text, ex.a_data,
N_SYMSIZE(ex), N_TXTOFF(ex), ex.a_text + ex.a_data + N_SYMSIZE(ex) + N_TXTOFF(ex),
qlsize(li));
#endif
if ( qlsize(li) >= ex.a_text + ex.a_data + N_SYMSIZE(ex) + N_TXTOFF(ex) )
break;
if ( N_MAGIC(ex) == ZMAGIC
&& qlsize(li) >= ex.a_text + ex.a_data + N_SYMSIZE(ex) )
{
i = 5; // OpenBSD demand-paged
break;
}
default:
return false;
}
return i+1;
}

View File

@@ -0,0 +1,14 @@
PROC=aout
include ../loader.mak
# MAKEDEP dependency list ------------------
$(F)aout$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)config.hpp $(I)diskio.hpp $(I)entry.hpp \
$(I)fixup.hpp $(I)fpro.h $(I)funcs.hpp \
$(I)ida.hpp $(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp \
$(I)lines.hpp $(I)llong.hpp $(I)loader.hpp $(I)nalt.hpp \
$(I)name.hpp $(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
$(I)range.hpp $(I)segment.hpp $(I)segregs.hpp $(I)ua.hpp \
$(I)xref.hpp ../../module/sparc/notify_codes.hpp \
../idaldr.h aout.cpp aout.h common.cpp