update to ida 7.6, add builds
This commit is contained in:
197
idasdk76/ldr/hpsom/common.cpp
Normal file
197
idasdk76/ldr/hpsom/common.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void sys_clock::swap(void)
|
||||
{
|
||||
secs = swap32(secs);
|
||||
nanosecs = swap32(nanosecs);
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void header::swap(void)
|
||||
{
|
||||
system_id= swap16(system_id);
|
||||
a_magic= swap16(a_magic);
|
||||
file_time.swap();
|
||||
version_id= swap32(version_id);
|
||||
entry_space= swap32(entry_space);
|
||||
entry_subspace= swap32(entry_subspace);
|
||||
entry_offset= swap32(entry_offset);
|
||||
aux_header_location= swap32(aux_header_location);
|
||||
aux_header_size= swap32(aux_header_size);
|
||||
som_length= swap32(som_length);
|
||||
presumed_dp= swap32(presumed_dp);
|
||||
space_location= swap32(space_location);
|
||||
space_total= swap32(space_total);
|
||||
subspace_location= swap32(subspace_location);
|
||||
subspace_total= swap32(subspace_total);
|
||||
loader_fixup_location= swap32(loader_fixup_location);
|
||||
loader_fixup_total= swap32(loader_fixup_total);
|
||||
space_strings_location= swap32(space_strings_location);
|
||||
space_strings_size= swap32(space_strings_size);
|
||||
init_array_location= swap32(init_array_location);
|
||||
init_array_total= swap32(init_array_total);
|
||||
compiler_location= swap32(compiler_location);
|
||||
compiler_total= swap32(compiler_total);
|
||||
symbol_location= swap32(symbol_location);
|
||||
symbol_total= swap32(symbol_total);
|
||||
fixup_request_location= swap32(fixup_request_location);
|
||||
fixup_request_total= swap32(fixup_request_total);
|
||||
symbol_strings_location= swap32(symbol_strings_location);
|
||||
symbol_strings_size= swap32(symbol_strings_size);
|
||||
unloadable_sp_location= swap32(unloadable_sp_location);
|
||||
unloadable_sp_size= swap32(unloadable_sp_size);
|
||||
checksum= swap32(checksum);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void aux_id::swap(void)
|
||||
{
|
||||
type = swap16(type);
|
||||
length = swap32(length);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void som_exec_auxhdr::swap(void)
|
||||
{
|
||||
header_id.swap();
|
||||
exec_tsize = swap32(exec_tsize); /* text size */
|
||||
exec_tmem = swap32(exec_tmem); /* start address of text */
|
||||
exec_tfile = swap32(exec_tfile); /* file ptr to text */
|
||||
exec_dsize = swap32(exec_dsize); /* data size */
|
||||
exec_dmem = swap32(exec_dmem); /* start address of data */
|
||||
exec_dfile = swap32(exec_dfile); /* file ptr to data */
|
||||
exec_bsize = swap32(exec_bsize); /* bss size */
|
||||
exec_entry = swap32(exec_entry); /* address of entry point */
|
||||
exec_flags = swap32(exec_flags); /* loader flags */
|
||||
exec_bfill = swap32(exec_bfill); /* bss initialization value */
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void user_string_aux_hdr::swap(void) /* Version string auxiliary header */
|
||||
{
|
||||
header_id.swap();
|
||||
string_length = swap32(string_length); /* strlen(user_string) */
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void copyright_aux_hdr::swap(void)
|
||||
{
|
||||
header_id.swap();
|
||||
string_length = swap32(string_length); /* strlen(user_string) */
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void shlib_version_aux_hdr::swap(void)
|
||||
{
|
||||
header_id.swap();
|
||||
version = swap16(version); /* version number */
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void space_dictionary_record::swap(void)
|
||||
{
|
||||
name.n_strx = swap32(name.n_strx);
|
||||
space_number = swap32(space_number);
|
||||
subspace_index = swap32(subspace_index);
|
||||
subspace_quantity = swap32(subspace_quantity);
|
||||
loader_fix_index = swap32(loader_fix_index);
|
||||
loader_fix_quantity = swap32(loader_fix_quantity);
|
||||
init_pointer_index = swap32(init_pointer_index);
|
||||
init_pointer_quantity = swap32(init_pointer_quantity);
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void subspace_dictionary_record::swap(void)
|
||||
{
|
||||
space_index = swap32(space_index);
|
||||
file_loc_init_value = swap32(file_loc_init_value);
|
||||
initialization_length = swap32(initialization_length);
|
||||
subspace_start = swap32(subspace_start);
|
||||
subspace_length = swap32(subspace_length);
|
||||
reserved2 = swap16(reserved2);
|
||||
alignment = swap16(alignment);
|
||||
name.n_strx = swap32(name.n_strx);
|
||||
fixup_request_index = swap32(fixup_request_index);
|
||||
fixup_request_quantity = swap32(fixup_request_quantity);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void symbol_dictionary_record::swap(void)
|
||||
{
|
||||
name.n_strx = swap32(name.n_strx);
|
||||
qualifier_name.n_strx = swap32(qualifier_name.n_strx);
|
||||
symbol_info = swap32(symbol_info);
|
||||
symbol_value = swap32(symbol_value);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void dl_header::swap(void)
|
||||
{
|
||||
hdr_version = swap32(hdr_version);
|
||||
ltptr_value = swap32(ltptr_value);
|
||||
shlib_list_loc = swap32(shlib_list_loc);
|
||||
shlib_list_count = swap32(shlib_list_count);
|
||||
import_list_loc = swap32(import_list_loc);
|
||||
import_list_count = swap32(import_list_count);
|
||||
hash_table_loc = swap32(hash_table_loc);
|
||||
hash_table_size = swap32(hash_table_size);
|
||||
export_list_loc = swap32(export_list_loc);
|
||||
export_list_count = swap32(export_list_count);
|
||||
string_table_loc = swap32(string_table_loc);
|
||||
string_table_size = swap32(string_table_size);
|
||||
dreloc_loc = swap32(dreloc_loc);
|
||||
dreloc_count = swap32(dreloc_count);
|
||||
dlt_loc = swap32(dlt_loc);
|
||||
plt_loc = swap32(plt_loc);
|
||||
dlt_count = swap32(dlt_count);
|
||||
plt_count = swap32(plt_count);
|
||||
highwater_mark = swap16(highwater_mark);
|
||||
flags = swap16(flags);
|
||||
export_ext_loc = swap32(export_ext_loc);
|
||||
module_loc = swap32(module_loc);
|
||||
module_count = swap32(module_count);
|
||||
elaborator = swap32(elaborator);
|
||||
initializer = swap32(initializer);
|
||||
embedded_path = swap32(embedded_path);
|
||||
initializer_count = swap32(initializer_count);
|
||||
tdsize = swap32(tdsize);
|
||||
fastbind_list_loc = swap32(fastbind_list_loc);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void import_entry::swap(void)
|
||||
{
|
||||
name = swap32(name);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void misc_info::swap(void)
|
||||
{
|
||||
version = swap16(version);
|
||||
flags = swap16(flags);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void export_entry::swap(void)
|
||||
{
|
||||
next = swap32(next);
|
||||
name = swap32(name);
|
||||
value = swap32(value);
|
||||
if ( type == ST_STORAGE )
|
||||
info.size = swap32(info.size);
|
||||
else
|
||||
info.misc.swap();
|
||||
module_index = swap16(module_index);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static uint32 compute_som_checksum(void *p)
|
||||
{
|
||||
int n = sizeof(header) / sizeof(uint32);
|
||||
uint32 *ptr = (uint32 *)p;
|
||||
uint32 sum = 0;
|
||||
for ( int i=0; i < n; i++ )
|
||||
sum ^= *ptr++;
|
||||
return sum;
|
||||
}
|
||||
|
||||
441
idasdk76/ldr/hpsom/hpsom.cpp
Normal file
441
idasdk76/ldr/hpsom/hpsom.cpp
Normal file
@@ -0,0 +1,441 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Copyright (c) 1990-2000 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* E-mail: ig@datarescue.com
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../idaldr.h"
|
||||
#include <typeinf.hpp>
|
||||
#include "hpsom.hpp"
|
||||
|
||||
#include "common.cpp"
|
||||
|
||||
static int first_text_subspace_idx = -1;
|
||||
static int32 first_text_subspace_fpos = -1;
|
||||
static char *dl_strings = NULL;
|
||||
static size_t dl_ssize = 0;
|
||||
static ea_t data_start = 0;
|
||||
static int64 fsize = 0;
|
||||
//--------------------------------------------------------------------------
|
||||
static void complain_fixup(void)
|
||||
{
|
||||
static bool complained = false;
|
||||
if ( !complained )
|
||||
{
|
||||
warning("The input file contains relocation information.\n"
|
||||
"Currently IDA doesn't handle relocation information,\n"
|
||||
"so it will be skipped");
|
||||
complained = true;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static int idaapi accept_file(
|
||||
qstring *fileformatname,
|
||||
qstring *processor,
|
||||
linput_t *li,
|
||||
const char *)
|
||||
{
|
||||
header h;
|
||||
qlseek(li, 0);
|
||||
if ( qlread(li, &h, sizeof(h)) != sizeof(h) )
|
||||
return 0;
|
||||
if ( compute_som_checksum(&h) != 0 )
|
||||
return 0;
|
||||
h.swap();
|
||||
const char *type;
|
||||
switch ( h.a_magic )
|
||||
{
|
||||
case EXELIB_MAGIC : type = "Executable Library"; break;
|
||||
case REL_MAGIC : type = "Relocatable"; break;
|
||||
case EXE_MAGIC : type = "Non-sharable, executable"; break;
|
||||
case SHREXE_MAGIC : type = "Sharable, executable"; break;
|
||||
case SHREXELD_MAGIC: type = "Sharable, demand-loadable executable"; break;
|
||||
case DLL_MAGIC : type = "Dynamic Load Library"; break;
|
||||
case SHLIB_MAGIC : type = "Shared Library"; break;
|
||||
case RELLIB_MAGIC : type = "Relocatable Library"; break;
|
||||
default: return 0;
|
||||
}
|
||||
fileformatname->sprnt("HP-UX SOM (%s)", type);
|
||||
*processor = "hppa";
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static void load_aux_headers(linput_t *li, int32 fpos, size_t size)
|
||||
{
|
||||
if ( size == 0 )
|
||||
return;
|
||||
|
||||
size_t rest = fsize - fpos;
|
||||
if ( rest <= size )
|
||||
loader_failure("Wrong header::aux_header_size");
|
||||
qlseek(li, fpos);
|
||||
|
||||
while ( size > 0 )
|
||||
{
|
||||
char buf[4096];
|
||||
CASSERT(sizeof(buf) >= sizeof(aux_id));
|
||||
aux_id &aih = *(aux_id *)buf;
|
||||
lread(li, &aih, sizeof(aih));
|
||||
aih.swap();
|
||||
size_t total = sizeof(aih) + aih.length;
|
||||
if ( total < sizeof(aih) || total >= sizeof(buf) )
|
||||
loader_failure("Wrong aux_header size %" FMT_Z, total);
|
||||
if ( total > size )
|
||||
return; // loader_failure("Illegal aux header size %u, rest %u", total, size);
|
||||
size -= total;
|
||||
lread(li, &aih+1, aih.length);
|
||||
switch ( aih.type )
|
||||
{
|
||||
case HPUX_AUX_ID:
|
||||
{
|
||||
som_exec_auxhdr *p = (som_exec_auxhdr*)buf;
|
||||
p->swap();
|
||||
inf_set_start_cs(0);
|
||||
inf_set_start_ip(p->exec_entry);
|
||||
data_start = p->exec_dmem;
|
||||
}
|
||||
break;
|
||||
case VERSION_AUX_ID:
|
||||
case COPYRIGHT_AUX_ID:
|
||||
case SHLIB_VERSION_AUX_ID:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static char *get_name(linput_t *li, int32 tableoff, size_t tablesize, int32 nidx, char *buf, size_t bufsize)
|
||||
{
|
||||
if ( nidx >= tablesize )
|
||||
{
|
||||
APPZERO(buf, buf+bufsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
qoff64_t fpos = qltell(li);
|
||||
qlseek(li, tableoff+nidx-4);
|
||||
uint32 len;
|
||||
lread(li, &len, sizeof(len));
|
||||
len = swap32(len);
|
||||
if ( len >= bufsize )
|
||||
len = uint32(bufsize-1);
|
||||
lread(li, buf, len);
|
||||
buf[len] = '\0';
|
||||
qlseek(li, fpos);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
inline char *get_space_name(linput_t *li, const header &h, int32 nidx, char *buf, size_t bufsize)
|
||||
{
|
||||
return get_name(li,
|
||||
h.space_strings_location,
|
||||
h.space_strings_size,
|
||||
nidx,
|
||||
buf,
|
||||
bufsize);
|
||||
}
|
||||
|
||||
inline char *get_symbol_name(linput_t *li, const header &h, int32 nidx, char *buf, size_t bufsize)
|
||||
{
|
||||
return get_name(li,
|
||||
h.symbol_strings_location,
|
||||
h.symbol_strings_size,
|
||||
nidx,
|
||||
buf,
|
||||
bufsize);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static void load_spaces(linput_t *li, const header &h, int32 fpos, int n)
|
||||
{
|
||||
if ( n == 0 )
|
||||
return;
|
||||
|
||||
qlseek(li, fpos);
|
||||
space_dictionary_record sr;
|
||||
validate_array_count_or_die(li, n, sizeof(sr), "Number of spaces", fpos);
|
||||
for ( int i=0; i < n; i++ )
|
||||
{
|
||||
lread(li, &sr, sizeof(sr));
|
||||
sr.swap();
|
||||
char buf[MAXSTR];
|
||||
get_space_name(li, h, sr.name.n_strx, buf, sizeof(buf));
|
||||
if ( streq(buf, "$TEXT$") )
|
||||
first_text_subspace_idx = sr.subspace_index;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static void load_subspaces(linput_t *li, const header &h, qoff64_t fpos, int n)
|
||||
{
|
||||
if ( n == 0 )
|
||||
return;
|
||||
subspace_dictionary_record sr;
|
||||
validate_array_count_or_die(li, n, sizeof(sr), "Number of subspaces", fpos);
|
||||
for ( int i=0; i < n; i++,fpos+=sizeof(sr) )
|
||||
{
|
||||
qlseek(li, fpos);
|
||||
lread(li, &sr, sizeof(sr));
|
||||
sr.swap();
|
||||
|
||||
if ( !sr.is_loadable() || !sr.subspace_length )
|
||||
continue;
|
||||
if ( sr.fixup_request_quantity )
|
||||
complain_fixup();
|
||||
ea_t start = sr.subspace_start;
|
||||
ea_t end = start + sr.initialization_length;
|
||||
qoff64_t fpos2 = sr.file_loc_init_value;
|
||||
if ( end < start || fpos2 > fsize || fsize-fpos2 < end-start )
|
||||
loader_failure("Wrong segment size %a..%a", start, end);
|
||||
file2base(li, fpos2, start, end, FILEREG_PATCHABLE);
|
||||
char buf[MAXSTR];
|
||||
char *name = get_space_name(li, h, sr.name.n_strx, buf, sizeof(buf));
|
||||
set_selector(i, 0);
|
||||
const char *sclass = strstr(name, "CODE") != NULL ? CLASS_CODE : CLASS_DATA;
|
||||
|
||||
segment_t s;
|
||||
s.sel = setup_selector(i);
|
||||
s.start_ea = start;
|
||||
s.end_ea = start + sr.subspace_length;
|
||||
s.align = saRelByte;
|
||||
s.comb = scPub;
|
||||
s.bitness = (uchar)PH.get_segm_bitness();
|
||||
if ( !add_segm_ex(&s, name, sclass, ADDSEG_NOSREG|ADDSEG_SPARSE) )
|
||||
loader_failure("Failed to create segment %a..%a", s.start_ea, s.end_ea);
|
||||
|
||||
if ( i == first_text_subspace_idx )
|
||||
first_text_subspace_fpos = sr.file_loc_init_value;
|
||||
// sr.alignment,
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static void load_symbols(linput_t *li, const header &h, int32 fpos, int n)
|
||||
{
|
||||
if ( n == 0 )
|
||||
return;
|
||||
qlseek(li, fpos);
|
||||
symbol_dictionary_record sr;
|
||||
validate_array_count_or_die(li, n, sizeof(sr), "Number of symbols", fpos);
|
||||
for ( int i=0; i < n; i++ )
|
||||
{
|
||||
lread(li, &sr, sizeof(sr));
|
||||
sr.swap();
|
||||
if ( sr.symbol_scope() == SS_UNSAT )
|
||||
continue;
|
||||
char buf[MAXSTR];
|
||||
char *name = get_symbol_name(li, h, sr.name.n_strx, buf, sizeof(buf));
|
||||
ea_t ea = sr.symbol_value & ~3;
|
||||
switch ( sr.symbol_type() )
|
||||
{
|
||||
case ST_NULL:
|
||||
case ST_ABSOLUTE:
|
||||
break;
|
||||
case ST_DATA:
|
||||
force_name(ea, name, SN_IDBENC);
|
||||
break;
|
||||
case ST_STUB:
|
||||
append_cmt(ea, "STUB", false);
|
||||
// fallthrough
|
||||
case ST_CODE:
|
||||
case ST_ENTRY:
|
||||
case ST_MILLICODE:
|
||||
case ST_MILLI_EXT:
|
||||
add_entry(ea, ea, name, true, AEF_IDBENC);
|
||||
add_entry(ea, ea, name, true, AEF_IDBENC);
|
||||
break;
|
||||
case ST_PRI_PROG:
|
||||
case ST_STORAGE:
|
||||
case ST_MODULE:
|
||||
case ST_SYM_EXT:
|
||||
case ST_ARG_EXT:
|
||||
case ST_PLABEL:
|
||||
case ST_OCT_DIS:
|
||||
case ST_TSTORAGE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static char *get_text_name(int nidx, char *buf, size_t bufsize)
|
||||
{
|
||||
if ( nidx == -1 )
|
||||
return NULL;
|
||||
if ( nidx >= 0 && nidx < dl_ssize )
|
||||
qstrncpy(buf, dl_strings + nidx, bufsize);
|
||||
else
|
||||
qsnprintf(buf, bufsize, "0x%08X", nidx);
|
||||
return buf;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static void load_imports(linput_t *li, const dl_header &dl)
|
||||
{
|
||||
if ( dl.import_list_count == 0 )
|
||||
return;
|
||||
qoff64_t fpos = first_text_subspace_fpos + dl.import_list_loc;
|
||||
qlseek(li, fpos);
|
||||
ea_t ea = data_start + dl.dlt_loc;
|
||||
int n = dl.dlt_count;
|
||||
import_entry ie;
|
||||
validate_array_count_or_die(li, dl.import_list_count, sizeof(ie), "Number of imports", fpos);
|
||||
for ( int i=0; i < dl.import_list_count; i++ )
|
||||
{
|
||||
lread(li, &ie, sizeof(ie));
|
||||
ie.swap();
|
||||
if ( n == 0 )
|
||||
ea = data_start + dl.plt_loc;
|
||||
n--;
|
||||
char buf[MAXSTR];
|
||||
buf[0] = '.';
|
||||
get_text_name(ie.name, &buf[1], sizeof(buf)-1);
|
||||
force_name(ea, buf, SN_IDBENC);
|
||||
create_dword(ea, 4);
|
||||
op_plain_offset(ea, 0, 0);
|
||||
if ( n > 0 )
|
||||
{
|
||||
ea += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
ea_t ea2 = get_dword(ea);
|
||||
force_name(ea2, &buf[1], SN_IDBENC);
|
||||
add_func(ea2);
|
||||
set_func_cmt(get_func(ea2), "THUNK", false);
|
||||
create_dword(ea+4, 4);
|
||||
ea += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static void load_exports(linput_t *li, const dl_header &dl)
|
||||
{
|
||||
if ( dl.export_list_count == 0 )
|
||||
return;
|
||||
export_entry ee;
|
||||
qoff64_t fpos = first_text_subspace_fpos + dl.export_list_loc;
|
||||
qlseek(li, fpos);
|
||||
validate_array_count_or_die(li, dl.export_list_count, sizeof(ee), "Number of exports", fpos);
|
||||
for ( int i=0; i < dl.export_list_count; i++ )
|
||||
{
|
||||
lread(li, &ee, sizeof(ee));
|
||||
ee.swap();
|
||||
char buf[MAXSTR];
|
||||
const char *name = get_text_name(ee.name, buf, sizeof(buf));
|
||||
add_entry(ee.value, ee.value, name, ee.type == ST_CODE, AEF_IDBENC);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static void load_dl_header(linput_t *li)
|
||||
{
|
||||
if ( first_text_subspace_fpos == -1 )
|
||||
return;
|
||||
qlseek(li, first_text_subspace_fpos);
|
||||
dl_header dl;
|
||||
lread(li, &dl, sizeof(dl));
|
||||
dl.swap();
|
||||
switch ( dl.hdr_version )
|
||||
{
|
||||
case OLD_HDR_VERSION: break;
|
||||
case HDR_VERSION: break;
|
||||
default:
|
||||
msg("Unknown DL header version, skipping...\n");
|
||||
}
|
||||
if ( dl.string_table_size != 0 )
|
||||
{
|
||||
qoff64_t fpos = first_text_subspace_fpos + dl.string_table_loc;
|
||||
qlseek(li, fpos);
|
||||
dl_ssize = dl.string_table_size;
|
||||
validate_array_count_or_die(li, dl_ssize, 1, "String table size", fpos);
|
||||
dl_strings = (char *)qalloc(dl_ssize);
|
||||
if ( dl_strings == NULL )
|
||||
nomem("dl_strings");
|
||||
lread(li, dl_strings, dl_ssize);
|
||||
}
|
||||
if ( dl.dreloc_count != 0 )
|
||||
complain_fixup();
|
||||
|
||||
load_imports(li, dl);
|
||||
load_exports(li, dl);
|
||||
|
||||
qfree(dl_strings);
|
||||
dl_strings = NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void idaapi load_file(linput_t *li, ushort /*neflag*/, const char * /*fileformatname*/)
|
||||
{
|
||||
set_processor_type("hppa", SETPROC_LOADER);
|
||||
|
||||
header h;
|
||||
qlseek(li, 0);
|
||||
lread(li, &h, sizeof(h));
|
||||
h.swap();
|
||||
inf_set_baseaddr(0);
|
||||
|
||||
fsize = qlsize(li);
|
||||
load_aux_headers(li, h.aux_header_location, h.aux_header_size);
|
||||
load_spaces(li, h, h.space_location, h.space_total);
|
||||
load_subspaces(li, h, h.subspace_location, h.subspace_total);
|
||||
load_symbols(li, h, h.symbol_location, h.symbol_total);
|
||||
load_dl_header(li);
|
||||
create_filename_cmt();
|
||||
|
||||
size_t dp = h.presumed_dp;
|
||||
if ( dp == 0 )
|
||||
{
|
||||
// 23 61 28 00 ldil ...., %dp
|
||||
// 37 7B 01 60 ldo 0xB0(%dp), %dp
|
||||
insn_t insn;
|
||||
if ( decode_insn(&insn, inf_get_start_ip()) > 0
|
||||
&& insn.Op1.type == o_imm
|
||||
&& insn.Op2.type == o_reg )
|
||||
{
|
||||
uval_t v = insn.Op1.value;
|
||||
if ( decode_insn(&insn, insn.ea+4) && insn.Op1.type == o_displ )
|
||||
dp = size_t(v + insn.Op1.addr);
|
||||
}
|
||||
}
|
||||
|
||||
if ( dp != 0 )
|
||||
set_gotea(dp);
|
||||
|
||||
add_til("hpux", ADDTIL_DEFAULT);
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
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,
|
||||
};
|
||||
542
idasdk76/ldr/hpsom/hpsom.hpp
Normal file
542
idasdk76/ldr/hpsom/hpsom.hpp
Normal file
@@ -0,0 +1,542 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Copyright (c) 1990-2000 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* E-mail: ig@datarescue.com
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HPSOM_HPP
|
||||
#define HPSOM_HPP
|
||||
|
||||
// The timestamp is a two-word structure as shown below. If unused, both fields are
|
||||
// zero.
|
||||
|
||||
struct sys_clock
|
||||
{
|
||||
uint secs;
|
||||
uint nanosecs;
|
||||
void swap(void);
|
||||
};
|
||||
|
||||
struct header
|
||||
{
|
||||
short system_id; /* system id */
|
||||
#define SYSTEM_10 0x20B // PA-RISC 1.0
|
||||
#define SYSTEM_11 0x210 // PA-RISC 1.1
|
||||
#define SYSTEM_20 0x214 // PA-RISC 2.0
|
||||
short int a_magic; /* magic number */
|
||||
#define EXELIB_MAGIC 0x104 // Executable SOM Library
|
||||
#define REL_MAGIC 0x106 // Relocatable SOM
|
||||
#define EXE_MAGIC 0x107 // Non-sharable, executable SOM
|
||||
#define SHREXE_MAGIC 0x108 // Sharable, executable SOM
|
||||
#define SHREXELD_MAGIC 0x10B // Sharable, demand-loadable executable SOM
|
||||
#define DLL_MAGIC 0x10D // Dynamic Load Library
|
||||
#define SHLIB_MAGIC 0x10E // Shared Library
|
||||
#define RELLIB_MAGIC 0x619 // Relocatable SOM Library
|
||||
uint version_id; /* a.out format version */
|
||||
struct sys_clock file_time; /* timestamp */
|
||||
uint entry_space; /* index of space containing entry point */
|
||||
uint entry_subspace; /* subspace index of entry */
|
||||
uint entry_offset; /* offset of entry point */
|
||||
uint aux_header_location; /* file ptr to aux hdrs */
|
||||
uint aux_header_size; /* sizeof aux hdrs */
|
||||
uint som_length; /* length of object module */
|
||||
uint presumed_dp; /* DP value assumed during compilation */
|
||||
uint space_location; /* file ptr to space dict */
|
||||
uint space_total; /* # of spaces */
|
||||
uint subspace_location; /* file ptr to subsp dict */
|
||||
uint subspace_total; /* # of subspaces */
|
||||
uint loader_fixup_location; /* space reference array */
|
||||
uint loader_fixup_total; /* # of space reference recs */
|
||||
uint space_strings_location; /* file ptr to sp. strings */
|
||||
uint space_strings_size; /* sizeof sp. strings */
|
||||
uint init_array_location; /* location of init pointers */
|
||||
uint init_array_total; /* # of init pointers */
|
||||
uint compiler_location; /* file ptr to comp recs */
|
||||
uint compiler_total; /* # of compiler recs */
|
||||
uint symbol_location; /* file ptr to sym table */
|
||||
uint symbol_total; /* # of symbols */
|
||||
uint fixup_request_location; /* file ptr to fixups */
|
||||
uint fixup_request_total; /* # of fixups */
|
||||
uint symbol_strings_location; /* file ptr to sym strings */
|
||||
uint symbol_strings_size; /* sizeof sym strings */
|
||||
uint unloadable_sp_location; /* file ptr to debug info */
|
||||
uint unloadable_sp_size; /* size of debug info */
|
||||
uint checksum; /* header checksum */
|
||||
void swap(void);
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Auxiliary Headers
|
||||
//
|
||||
// The auxiliary headers are contained in a single contiguous area in the file, and
|
||||
// are located by a pointer in the file header. Auxiliary headers are used for two
|
||||
// purposes: to attach users' version and copyright strings to an object file, and
|
||||
// to contain the information needed to load an executable program. In an
|
||||
// executable program, the HP-UX auxiliary header must precede all other auxiliary
|
||||
// headers.
|
||||
|
||||
struct aux_id
|
||||
{
|
||||
unsigned char flags;
|
||||
#define AUX_MANDATORY 0x10 /* linker must understand aux hdr info */
|
||||
#define AUX_COPY 0x20 /* copy aux hdr without modification */
|
||||
#define AUX_APPEND 0x40 /* merge multiple entries of same type */
|
||||
#define AUX_IGNORE 0x80 /* ignore aux hdr if type unknown */
|
||||
|
||||
bool mandatory(void) { return (flags & AUX_MANDATORY) != 0; }
|
||||
bool copy(void) { return (flags & AUX_COPY ) != 0; }
|
||||
bool append(void) { return (flags & AUX_APPEND ) != 0; }
|
||||
bool ignore(void) { return (flags & AUX_IGNORE ) != 0; }
|
||||
|
||||
uchar reserved;
|
||||
ushort type; /* aux hdr type */
|
||||
uint length; /* sizeof rest of aux hdr */
|
||||
void swap(void);
|
||||
};
|
||||
|
||||
/* Values for the aux_id.type field */
|
||||
#define HPUX_AUX_ID 4
|
||||
#define VERSION_AUX_ID 6
|
||||
#define COPYRIGHT_AUX_ID 9
|
||||
#define SHLIB_VERSION_AUX_ID 10
|
||||
|
||||
struct som_exec_auxhdr /* HP-UX auxiliary header */
|
||||
{
|
||||
struct aux_id header_id; /* aux header id */
|
||||
int32 exec_tsize; /* text size */
|
||||
int32 exec_tmem; /* start address of text */
|
||||
int32 exec_tfile; /* file ptr to text */
|
||||
int32 exec_dsize; /* data size */
|
||||
int32 exec_dmem; /* start address of data */
|
||||
int32 exec_dfile; /* file ptr to data */
|
||||
int32 exec_bsize; /* bss size */
|
||||
int32 exec_entry; /* address of entry point */
|
||||
int32 exec_flags; /* loader flags */
|
||||
int32 exec_bfill; /* bss initialization value */
|
||||
void swap(void);
|
||||
};
|
||||
|
||||
/* Values for exec_flags */
|
||||
#define TRAP_NIL_PTRS 01
|
||||
|
||||
struct user_string_aux_hdr /* Version string auxiliary header */
|
||||
{
|
||||
struct aux_id header_id; /* aux header id */
|
||||
uint string_length; /* strlen(user_string) */
|
||||
char user_string[1]; /* user-defined string */
|
||||
void swap(void);
|
||||
};
|
||||
|
||||
struct copyright_aux_hdr /* Copyright string auxiliary header */
|
||||
{
|
||||
struct aux_id header_id; /* aux header id */
|
||||
uint string_length; /* strlen(user_string) */
|
||||
char copyright[1]; /* user-defined string */
|
||||
void swap(void);
|
||||
};
|
||||
|
||||
struct shlib_version_aux_hdr
|
||||
{
|
||||
struct aux_id header_id; /* aux header id */
|
||||
short version; /* version number */
|
||||
void swap(void);
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Space Dictionary
|
||||
//
|
||||
// The space dictionary consists of a sequence of space records
|
||||
//
|
||||
// The strings for the space names are contained in the space strings table, which
|
||||
// is located by a pointer in the file header. Each entry in the space strings
|
||||
// table is preceded by a 4-byte integer that defines the length of the string, and
|
||||
// is terminated by one to five null characters to pad the string out to a word
|
||||
// boundary. Indices to this table are relative to the start of the table, and
|
||||
// point to the first byte of the string (not the preceding length word). The union
|
||||
// defined above is used for all such string pointers; the character pointer is
|
||||
// defined for programs that read the string table into memory and wish to relocate
|
||||
// in-memory copies of space records.
|
||||
|
||||
|
||||
|
||||
union name_pt
|
||||
{
|
||||
// char *n_name;
|
||||
uint n_strx;
|
||||
};
|
||||
|
||||
struct space_dictionary_record
|
||||
{
|
||||
union name_pt name; /* index to space name */
|
||||
|
||||
unsigned char flags;
|
||||
#define SPACE_IS_LOADABLE 0x80 /* space is loadable */
|
||||
#define SPACE_IS_DEFINED 0x40 /* space is defined within file */
|
||||
#define SPACE_IS_PRIVATE 0x20 /* space is not sharable */
|
||||
#define SPACE_HAS_INTERM 0x10 /* contains intermediate code */
|
||||
#define SPACE_IS_TSPEC 0x08 /* space is $thread_specific$ */
|
||||
bool is_loadable(void) { return (flags & SPACE_IS_LOADABLE) != 0; }
|
||||
bool is_defined(void) { return (flags & SPACE_IS_DEFINED ) != 0; }
|
||||
bool is_private(void) { return (flags & SPACE_IS_PRIVATE ) != 0; }
|
||||
bool has_intermediate_code(void) { return (flags & SPACE_HAS_INTERM ) != 0; }
|
||||
bool is_tspecific(void) { return (flags & SPACE_IS_TSPEC ) != 0; }
|
||||
unsigned char reserved;
|
||||
unsigned char sort_key; /* sort key for space */
|
||||
unsigned char reserved2; /* reserved */
|
||||
|
||||
int space_number; /* space index */
|
||||
int subspace_index; /* index to first subspace */
|
||||
uint subspace_quantity; /* # of subspaces in space */
|
||||
int loader_fix_index; /* index into loader fixup array */
|
||||
uint loader_fix_quantity; /* # of loader fixups in space */
|
||||
int init_pointer_index; /* index into init pointer array */
|
||||
uint init_pointer_quantity; /* # of init ptrs */
|
||||
void swap(void);
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Subspace Dictionary
|
||||
//
|
||||
// The subspace dictionary consists of a sequence of subspace records, as defined
|
||||
// in <scnhdr.h>. Strings for subspace names are contained in the space strings
|
||||
// table.
|
||||
|
||||
struct subspace_dictionary_record
|
||||
{
|
||||
int space_index; /* index into space dictionary */
|
||||
|
||||
unsigned char f1;
|
||||
#define SUBS_F1_ACCESS 0xFE /* access and priv levels of subsp */
|
||||
#define SUBS_F1_MEMRES 0x01 /* lock in memory during exec */
|
||||
int access_control_bits(void) { return (f1 & SUBS_F1_ACCESS) >> 1; }
|
||||
bool memory_resident(void) { return (f1 & SUBS_F1_MEMRES) != 0; }
|
||||
|
||||
unsigned char f2;
|
||||
#define SUBS_F2_DUPCOM 0x80 /* duplicate data symbols allowed */
|
||||
#define SUBS_F2_INICOM 0x40 /* initialized common block */
|
||||
#define SUBS_F2_ISLOAD 0x20 /* subspace is loadable */
|
||||
#define SUBS_F2_QUADR 0x18 /* quadrant in space subsp should reside in */
|
||||
#define SUBS_F2_FROZEN 0x04 /* lock in memory when OS booted */
|
||||
#define SUBS_F2_FIRST 0x02 /* must be first subspace */
|
||||
#define SUBS_F2_CODE 0x01 /* subspace contains only code */
|
||||
bool dup_common(void) { return (f2 & SUBS_F2_DUPCOM) != 0; }
|
||||
bool is_common(void) { return (f2 & SUBS_F2_INICOM) != 0; }
|
||||
bool is_loadable(void) { return (f2 & SUBS_F2_ISLOAD) != 0; }
|
||||
int quadrant(void) { return (f2 & SUBS_F2_QUADR ) >> 3; }
|
||||
bool initially_frozen(void) { return (f2 & SUBS_F2_FROZEN) != 0; }
|
||||
bool is_first(void) { return (f2 & SUBS_F2_FIRST ) != 0; }
|
||||
bool code_only(void) { return (f2 & SUBS_F2_CODE ) != 0; }
|
||||
|
||||
unsigned char sort_key; /* subspace sort key */
|
||||
|
||||
unsigned char f3;
|
||||
#define SUBS_F3_REPINI 0x80 /* init values to be replicated to fill subsp len */
|
||||
#define SUBS_F3_CONTIN 0x40 /* subspace is a continuation */
|
||||
#define SUBS_F3_ISTSPC 0x20 /* subspace contains TLS */
|
||||
bool replicate_init(void) { return (f3 & SUBS_F3_REPINI) != 0; }
|
||||
bool continuation(void) { return (f3 & SUBS_F3_CONTIN) != 0; }
|
||||
bool is_tspecific(void) { return (f3 & SUBS_F3_ISTSPC) != 0; }
|
||||
|
||||
int file_loc_init_value; /* file location or init value */
|
||||
uint initialization_length; /* length of initialization */
|
||||
uint subspace_start; /* starting offset */
|
||||
uint subspace_length; /* total subspace length */
|
||||
unsigned short reserved2; /* reserved */
|
||||
unsigned short alignment; /* alignment required */
|
||||
union name_pt name; /* index of subspace name */
|
||||
int fixup_request_index; /* index to first fixup */
|
||||
uint fixup_request_quantity; /* # of fixup requests */
|
||||
void swap(void);
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Symbol Table
|
||||
//
|
||||
// The symbol table consists of a sequence of entries described by the structure
|
||||
// shown below, from <syms.h>. Strings for symbol and qualifier names are contained
|
||||
// in the symbol strings table, whose structure is identical with the space strings
|
||||
// table.
|
||||
|
||||
struct symbol_dictionary_record
|
||||
{
|
||||
unsigned char f1;
|
||||
#define SYM_F1_HIDDEN 0x80 /* symbol not visible to loader */
|
||||
#define SYM_F1_SECDEF 0x40 /* secondary def symbol */
|
||||
#define SYM_F1_TYPE 0x3F /* symbol type */
|
||||
bool hidden(void) { return (f1 & SYM_F1_HIDDEN) != 0; }
|
||||
bool secondary_def(void) { return (f1 & SYM_F1_SECDEF) != 0; }
|
||||
int symbol_type(void) { return (f1 & SYM_F1_TYPE); }
|
||||
|
||||
unsigned char f2;
|
||||
#define SYM_F2_SCOPE 0xF0 /* symbol value */
|
||||
#define SYM_F2_CHKLVL 0x0E /* type checking level */
|
||||
#define SYM_F2_MSTQUL 0x01 /* qualifier required */
|
||||
int symbol_scope(void) { return (f2 & SYM_F2_SCOPE ) >> 4; }
|
||||
int check_level(void) { return (f2 & SYM_F2_CHKLVL) >> 1; }
|
||||
bool must_qualify(void) { return (f2 & SYM_F2_MSTQUL) != 0; }
|
||||
|
||||
unsigned short f3;
|
||||
#define SYM_F3_FROZEN 0x8000 /* lock in memory when OS booted */
|
||||
#define SYM_F3_MEMRES 0x4000 /* lock in memory during exec */
|
||||
#define SYM_F3_ISCOM 0x2000 /* common block */
|
||||
#define SYM_F3_DUPCOM 0x1000 /* duplicate data symbols allowed */
|
||||
#define SYM_F3_XLEAST 0x0C00 /* MPE-only */
|
||||
#define SYM_F3_ARGREL 0x03FF /* parameter relocation bits */
|
||||
bool initially_frozen(void) { return (f3 & SYM_F3_FROZEN) != 0; }
|
||||
bool memory_resident(void) { return (f3 & SYM_F3_MEMRES) != 0; }
|
||||
bool is_common(void) { return (f3 & SYM_F3_ISCOM ) != 0; }
|
||||
bool dup_common(void) { return (f3 & SYM_F3_DUPCOM) != 0; }
|
||||
int xleast(void) { return (f3 & SYM_F3_XLEAST) >>10; }
|
||||
int arg_reloc(void) { return (f3 & SYM_F3_ARGREL); }
|
||||
|
||||
union name_pt name; /* index to symbol name */
|
||||
union name_pt qualifier_name; /* index to qual name */
|
||||
uint symbol_info; /* subspace index */
|
||||
uint symbol_value; /* symbol value */
|
||||
void swap(void);
|
||||
};
|
||||
|
||||
/* Values for symbol_type */
|
||||
#define ST_NULL 0 /* unused symbol entry */
|
||||
#define ST_ABSOLUTE 1 /* non-relocatable symbol */
|
||||
#define ST_DATA 2 /* initialized data symbol */
|
||||
#define ST_CODE 3 /* generic code symbol */
|
||||
#define ST_PRI_PROG 4 /* program entry point */
|
||||
#define ST_SEC_PROG 5 /* secondary prog entry point*/
|
||||
#define ST_ENTRY 6 /* procedure entry point */
|
||||
#define ST_STORAGE 7 /* storage request */
|
||||
#define ST_STUB 8 /* MPE-only */
|
||||
#define ST_MODULE 9 /* Pascal module name */
|
||||
#define ST_SYM_EXT 10 /* symbol extension record */
|
||||
#define ST_ARG_EXT 11 /* argument extension record */
|
||||
#define ST_MILLICODE 12 /* millicode entry point */
|
||||
#define ST_PLABEL 13 /* MPE-only */
|
||||
#define ST_OCT_DIS 14 /* Used by OCT only--ptr to translated code */
|
||||
#define ST_MILLI_EXT 15 /* address of external millicode */
|
||||
#define ST_TSTORAGE 16 /* TLS common symbol */
|
||||
|
||||
/* Values for symbol_scope */
|
||||
#define SS_UNSAT 0 /* unsatisfied reference */
|
||||
#define SS_EXTERNAL 1 /* import request to external symbol */
|
||||
#define SS_LOCAL 2 /* local symbol */
|
||||
#define SS_UNIVERSAL 3 /* global symbol */
|
||||
|
||||
// The meaning of the symbol value depends on the symbol type. For the code symbols
|
||||
// (generic code, program entry points, procedure and millicode entry points), the
|
||||
// low-order two bits of the symbol value encode the execution privilege level,
|
||||
// which is not used on HP-UX, but is generally set to 3. The symbol value with
|
||||
// those bits masked out is the address of the symbol (which is always a multiple
|
||||
// of 4). For data symbols, the symbol value is simply the address of the symbol.
|
||||
// For thread local storage symbols (not commons), the symbol value is the thread
|
||||
// local storage offset in a library or executable file, and is the size of the
|
||||
// symbol if in a relocatable object file. For storage requests and thread local
|
||||
// storage commons, the symbol value is the number of bytes requested; the linker
|
||||
// allocates space for the largest request for each symbol in the $BSS$ or $TBSS$
|
||||
// subspaces, unless a local or universal symbol is found for that symbol (in which
|
||||
// case the storage request is treated like an unsatisfied reference).
|
||||
//
|
||||
// If a relocatable file is compiled with parameter type checking, extension
|
||||
// records follow symbols that define and reference procedure entry points and
|
||||
// global variables. The first extension record, the symbol extension record,
|
||||
// defines the type of the return value or global variable, and (if a procedure or
|
||||
// function) the number of parameters and the types of the first three parameters.
|
||||
// If more parameter type descriptors are needed, one or more argument extension
|
||||
// records follow, each containing four more descriptors. A check level of 0
|
||||
// specifies no type checking; no extension records follow. A check level of 1 or
|
||||
// more specifies checking of the return value or global variable type. A check
|
||||
// level of 2 or more specifies checking of the number of parameters, and a check
|
||||
// level of 3 specifies checking the types of each individual parameter. The linker
|
||||
// performs the requested level of type checking between unsatisfied symbols and
|
||||
// local or universal symbols as it resolves symbol references.
|
||||
|
||||
union arg_descriptor
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint reserved: 3; /* reserved */
|
||||
uint packing: 1; /* packing algorithm used */
|
||||
uint alignment: 4; /* byte alignment */
|
||||
uint mode: 4; /* type of descriptor and its use */
|
||||
uint structure: 4; /* structure of symbol */
|
||||
uint hash: 1; /* set if arg_type is hashed */
|
||||
int arg_type: 15; /* data type */
|
||||
} arg_desc;
|
||||
uint word;
|
||||
};
|
||||
|
||||
struct symbol_extension_record
|
||||
{
|
||||
uint type: 8; /* always ST_SYM_EXT */
|
||||
uint max_num_args: 8; /* max # of parameters */
|
||||
uint min_num_args: 8; /* min # of parameters */
|
||||
uint num_args: 8; /* actual # of parameters */
|
||||
union arg_descriptor symbol_desc; /* symbol type desc. */
|
||||
union arg_descriptor argument_desc[3]; /* first 3 parameters */
|
||||
};
|
||||
|
||||
struct argument_desc_array
|
||||
{
|
||||
uint type: 8; /* always ST_ARG_EXT */
|
||||
uint reserved: 24; /* reserved */
|
||||
union arg_descriptor argument_desc[4]; /* next 4 parameters */
|
||||
};
|
||||
|
||||
// The alignment field in arg_descriptor indicates the minimum alignment of the
|
||||
// data, where a value of n represents 2^n byte alignment. The values for the mode,
|
||||
// structure, and arg_type (when the data type is not hashed) fields in
|
||||
// arg_descriptor are given in the following table.
|
||||
//
|
||||
// Value mode structure arg_type
|
||||
// 0 any any any
|
||||
// 1 value parm scalar void
|
||||
// 2 reference parm array signed byte
|
||||
// 3 value-result struct unsigned byte
|
||||
// 4 name pointer signed short
|
||||
// 5 variable int32 ptr unsigned short
|
||||
// 6 function return C string signed int32
|
||||
// 7 procedure Pascal string unsigned int32
|
||||
// 8 int32 ref parm procedure signed dbl word
|
||||
// 9 function unsigned dbl word
|
||||
// 10 label short real
|
||||
// 11 real
|
||||
// 12 int32 real
|
||||
// 13 short complex
|
||||
// 14 complex
|
||||
// 15 int32 complex
|
||||
// 16 packed decimal
|
||||
// 17 struct/array
|
||||
//
|
||||
//
|
||||
// For procedure entry points, the parameter relocation bits define the locations
|
||||
// of the formal parameters and the return value. Normally, the first four words of
|
||||
// the parameter list are passed in general registers (r26-r23) instead of on the
|
||||
// stack, and the return value is returned in r29. Floating-point parameters in
|
||||
// this range are passed instead in floating-point registers (fr4-fr7) and a
|
||||
// floating-point value is returned in fr4. The parameter relocation bits consist
|
||||
// of five pairs of bits that describe the first four words of the parameter list
|
||||
// and the return value. The leftmost pair of bits describes the first parameter
|
||||
// word, and the rightmost pair of bits describes the return value. The meanings of
|
||||
// these bits are shown in the following table.
|
||||
//
|
||||
// Bits Meaning
|
||||
// 00 No parameter or return value
|
||||
// 01 Parameter or return value in general register
|
||||
// 10 Parameter or return value in floating-point register
|
||||
// 11 Double-precision floating-point value
|
||||
//
|
||||
//
|
||||
// For double-precision floating-point parameters, the odd-numbered parameter word
|
||||
// should be marked 11 and the even-numbered parameter word should be marked 10.
|
||||
// Double-precision return values are simply marked 11.
|
||||
//
|
||||
// Every procedure call is tagged with a similar set of bits (see "Relocation
|
||||
// Information" below), so that the linker can match each call with the
|
||||
// expectations of the procedure entry point. If the call and entry point mismatch,
|
||||
// the linker creates a stub that relocates the parameters and return value as
|
||||
// appropriate.
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// DL header
|
||||
//
|
||||
// The DL header appears in every shared library and in incomplete executables (program
|
||||
// files linked with shared libraries--may contain unsatisfied symbols which will be satis-fied
|
||||
// at run time by the dynamic loader). It is assumed to be at offset 0 in the $TEXT$
|
||||
// space. It defines fields used by the dynamic loader and various other tools when attach-ing
|
||||
// the shared libraries at run time. The header contains information on the location of
|
||||
// the export and import lists, the module table, the linkage tables, as well as the sizes of
|
||||
// the tables.
|
||||
|
||||
|
||||
struct dl_header
|
||||
{
|
||||
int hdr_version; /* header version number */
|
||||
#define OLD_HDR_VERSION 89060912 // prior to 10.0
|
||||
#define HDR_VERSION 93092112
|
||||
int ltptr_value; /* data offset of LT pointer (R19) */
|
||||
int shlib_list_loc; /* text offset of shlib list */
|
||||
int shlib_list_count; /* count of items in shlib list */
|
||||
int import_list_loc; /* text offset of import list */
|
||||
int import_list_count; /* count of items in import list */
|
||||
int hash_table_loc; /* text offset of export hash table */
|
||||
int hash_table_size; /* count of slots in export hash table */
|
||||
int export_list_loc; /* text offset of export list */
|
||||
int export_list_count; /* count of items in export list */
|
||||
int string_table_loc; /* text offset of string table */
|
||||
int string_table_size; /* length in bytes of string table */
|
||||
int dreloc_loc; /* text offset of dynamic reloc records */
|
||||
int dreloc_count; /* number of dynamic relocation records */
|
||||
int dlt_loc; /* data offset of data linkage table */
|
||||
int plt_loc; /* data offset of procedure linkage table */
|
||||
int dlt_count; /* number of dlt entries in linkage table */
|
||||
int plt_count; /* number of plt entries in linkage table */
|
||||
short highwater_mark; /* highest version number seen in lib or in shlib list*/
|
||||
short flags; /* various flags */
|
||||
#define ELAB_DEFINED 1 /* an elaborator has been defined for this library */
|
||||
#define INIT_DEFINED 2 /* an initializer has been defined for this library */
|
||||
#define SHLIB_PATH_ENABLE 4 /* allow search of SHLIB_PATH at runtime */
|
||||
#define EMBED_PATH_ENABLE 8 /*allow search of embed path at runtime*/
|
||||
#define SHLIB_PATH_FIRST 16 /* search SHLIB_PATH first */
|
||||
#define SEARCH_ALL_STORS 32 /* search all shlibs to satisfy STOR import */
|
||||
#define SHLIB_INTERNAL_NAME 64 /*shlib has an internal name, for library-level versioning support*/
|
||||
int export_ext_loc; /* text offset of export extension tbl */
|
||||
int module_loc; /* text offset of module table*/
|
||||
int module_count; /* number of module entries */
|
||||
int elaborator; /* import index of elaborator */
|
||||
int initializer; /* import index of initializer */
|
||||
int embedded_path; /* index into string table for search path. index must be > 0 to be valid */
|
||||
int initializer_count; /* count of items in initializer import list*/
|
||||
int tdsize; /* size of the TSD area */
|
||||
int fastbind_list_loc; /* text-relative offset of fastbind info */
|
||||
void swap(void);
|
||||
};
|
||||
|
||||
// Import entry
|
||||
|
||||
struct import_entry // parallel with DLT followed by PLT
|
||||
{
|
||||
int name; /* offset in string table */
|
||||
short reserved2; /* unused */
|
||||
unsigned char type; /* symbol type */
|
||||
unsigned char flags;
|
||||
#define IMP_ENTRY_BYPASS 0x80 /* address of code symbol not taken in shlib */
|
||||
#define IMP_ENTRY_TPREL 0x40 /* new field*/
|
||||
bool bypassable(void) { return (flags & IMP_ENTRY_BYPASS) != 0; }
|
||||
bool is_tp_relative(void) { return (flags & IMP_ENTRY_TPREL ) != 0; }
|
||||
void swap(void);
|
||||
};
|
||||
|
||||
// Export entry
|
||||
|
||||
struct misc_info
|
||||
{
|
||||
short version; /* months since January, 1990 */
|
||||
ushort flags;
|
||||
#define MISC_INFO_RELOC 0x3FF /* parameter relocation bits (5*2) */
|
||||
uint arg_reloc(void) { return flags & MISC_INFO_RELOC; }
|
||||
void swap(void);
|
||||
};
|
||||
|
||||
struct export_entry
|
||||
{
|
||||
int next; /* index of next export entry in hash chain */
|
||||
int name; /* offset within string table */
|
||||
int value; /* offset of symbol (subject to relocation) */
|
||||
union
|
||||
{
|
||||
int size; /* storage request area size in bytes */
|
||||
struct misc_info misc; /* version, etc. N/A to storage requests */
|
||||
} info;
|
||||
unsigned char type; /* symbol type */
|
||||
unsigned char flags;
|
||||
#define EXP_ENTRY_TPREL 0x80 /* TLS export*/
|
||||
bool is_tp_relative(void) { return (flags & EXP_ENTRY_TPREL ) != 0; }
|
||||
short module_index; /* index of module defining this symbol */
|
||||
void swap(void);
|
||||
};
|
||||
|
||||
#endif // ifndef HPSOM_HPP
|
||||
14
idasdk76/ldr/hpsom/makefile
Normal file
14
idasdk76/ldr/hpsom/makefile
Normal file
@@ -0,0 +1,14 @@
|
||||
PROC=hpsom
|
||||
|
||||
include ../loader.mak
|
||||
|
||||
# MAKEDEP dependency list ------------------
|
||||
$(F)hpsom$(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)typeinf.hpp $(I)ua.hpp $(I)xref.hpp ../idaldr.h \
|
||||
common.cpp hpsom.cpp hpsom.hpp
|
||||
Reference in New Issue
Block a user