Files
sigmaker-ida/idasdk75/dbg/mac/mac_local_impl.cpp
2021-06-05 21:10:25 +03:00

204 lines
5.0 KiB
C++

#include <loader.hpp>
#include "macho_rebase.cpp"
//--------------------------------------------------------------------------
// installs or uninstalls debugger specific idc functions
inline bool register_idc_funcs(bool)
{
return true;
}
//--------------------------------------------------------------------------
void idaapi rebase_if_required_to(ea_t new_base)
{
// not a shared cache lib: it's safe to just use the imagebase
ea_t base = get_imagebase();
if ( base == 0 )
{
// old databases don't have it set; use info from netnode
netnode n(MACHO_NODE);
if ( exist(n) )
base = n.altval(MACHO_ALT_IMAGEBASE);
}
if ( base != BADADDR
&& new_base != BADADDR
&& base != new_base
&& !rebase_scattered_segments(new_base) )
{
rebase_or_warn(base, new_base);
}
}
//--------------------------------------------------------------------------
enum macopt_idx_t
{
MAC_OPT_SYMBOL_PATH // path to symbols extracted from dyld shared cache
};
//--------------------------------------------------------------------------
struct mac_cfgopt_t
{
const char *name;
char type;
char index;
void *var;
size_t size;
};
//lint -esym(843, g_must_save_cfg) could be declared as const
static bool g_must_save_cfg = false;
//--------------------------------------------------------------------------
static const mac_cfgopt_t g_cfgopts[] =
{
{ "SYMBOL_PATH", IDPOPT_STR, MAC_OPT_SYMBOL_PATH, &g_dbgmod.dyld.symbol_path, 0 },
};
CASSERT(IS_QSTRING(g_dbgmod.dyld.symbol_path));
//--------------------------------------------------------------------------
static const mac_cfgopt_t *find_option(const char *name)
{
for ( int i=0; i < qnumber(g_cfgopts); i++ )
if ( strcmp(g_cfgopts[i].name, name) == 0 )
return &g_cfgopts[i];
return NULL;
}
//--------------------------------------------------------------------------
static void load_mac_options()
{
if ( !netnode::inited() )
return;
netnode node(MAC_NODE);
if ( !exist(node) )
return;
for ( int i = 0; i < qnumber(g_cfgopts); i++ )
{
const mac_cfgopt_t &opt = g_cfgopts[i];
if ( opt.type == IDPOPT_STR )
node.supstr((qstring *)opt.var, opt.index);
else
node.supval(opt.index, opt.var, opt.size);
}
}
//--------------------------------------------------------------------------
static void save_mac_options()
{
if ( !g_must_save_cfg || !netnode::inited() )
return;
netnode node;
node.create(MAC_NODE);
if ( node != BADNODE )
{
for ( int i = 0; i < qnumber(g_cfgopts); i++ )
{
const mac_cfgopt_t &opt = g_cfgopts[i];
if ( opt.type == IDPOPT_STR )
node.supset(opt.index, ((qstring *)opt.var)->c_str(), 0);
else
node.supset(opt.index, opt.var, opt.size);
}
}
g_must_save_cfg = false;
}
//--------------------------------------------------------------------------
const char *idaapi set_mac_options(const char *keyword, int pri, int value_type, const void *value)
{
if ( keyword == NULL )
{
static const char form[] =
"Mac OSX Debugger Options\n%/"
"<#Path to symbol files extracted from dyld_shared_cache#~S~ymbol path:q:1023:60::>\n";
qstring path = g_dbgmod.dyld.symbol_path;
if ( !ask_form(form, NULL, &path) )
return IDPOPT_OK;
g_dbgmod.dyld.symbol_path = path;
g_must_save_cfg = true;
}
else
{
if ( *keyword == '\0' )
{
load_mac_options();
return IDPOPT_OK;
}
const mac_cfgopt_t *opt = find_option(keyword);
if ( opt == NULL )
return IDPOPT_BADKEY;
if ( opt->type != value_type )
return IDPOPT_BADTYPE;
if ( opt->type == IDPOPT_STR )
{
qstring *pvar = (qstring *)opt->var;
*pvar = (char *)value;
}
if ( pri == IDPOPT_PRI_HIGH )
g_must_save_cfg = true;
}
return IDPOPT_OK;
}
//--------------------------------------------------------------------------
static ssize_t idaapi ui_callback(void *, int notification_code, va_list)
{
if ( notification_code == ui_saving )
save_mac_options();
return 0;
}
//--------------------------------------------------------------------------
static bool init_plugin(void)
{
#ifndef RPC_CLIENT
if ( !init_subsystem() )
return false;
#endif
if ( !netnode::inited() || is_miniidb() || inf_is_snapshot() )
{
#ifdef __MAC__
// local debugger is available if we are running under MAC OS X
return true;
#else
// for other systems only the remote debugger is available
return debugger.is_remote();
#endif
}
if ( inf_get_filetype() != S_FILETYPE ) // only Mach-O files
return false;
processor_t &ph = PH;
if ( ph.id != TARGET_PROCESSOR && ph.id != -1 )
return false;
hook_to_notification_point(HT_UI, ui_callback);
return true;
}
//--------------------------------------------------------------------------
inline void term_plugin(void)
{
#ifndef RPC_CLIENT
term_subsystem();
#endif
unhook_from_notification_point(HT_UI, ui_callback);
save_mac_options();
}
//--------------------------------------------------------------------------
static const char comment[] = "Userland Mac OS X debugger plugin.";