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

108 lines
2.8 KiB
C++

#include <set>
#include <idp.hpp>
#include <dbg.hpp>
#include <loader.hpp>
#include <segregs.hpp>
#include <segment.hpp>
#include "deb_arm.hpp"
#include "arm_regs.cpp"
//--------------------------------------------------------------------------
int is_arm_valid_bpt(bpttype_t type, ea_t ea, int len)
{
if ( type == BPT_SOFT )
{
if ( (ea & 1) != 0 )
return BPT_BAD_ADDR;
}
else
{
if ( type != BPT_RDWR // type is good?
&& type != BPT_WRITE
&& type != BPT_EXEC )
{
return BPT_BAD_TYPE;
}
if ( (ea & (len-1)) != 0 ) // alignment is good?
return BPT_BAD_ALIGN;
if ( len != 1 )
{
warning("AUTOHIDE REGISTRY\n"
"xScale supports only 1 byte length hardware breakpoints");
return BPT_BAD_LEN;
}
}
return BPT_OK;
}
//--------------------------------------------------------------------------
// if bit0 is set, ensure that thumb mode
// if bit0 is clear, ensure that arm mode
static void handle_arm_thumb_modes(ea_t ea)
{
bool should_be_thumb = (ea & 1) != 0;
bool is_thumb = processor_t::get_code16_mode(ea);
if ( should_be_thumb != is_thumb )
processor_t::set_code16_mode(ea, should_be_thumb);
}
//--------------------------------------------------------------------------
static easet_t pending_addresses;
static ssize_t idaapi dbg_callback(void *, int code, va_list)
{
// we apply thumb/arm switches when the process is suspended.
// it is quite late (normally we should do it as soon as the corresponding
// segment is created) but i did not manage to make it work.
// in the segm_added event the addresses are not enabled yet,
// so switching modes fails.
if ( code == dbg_suspend_process && !pending_addresses.empty() )
{
for ( easet_t::iterator p=pending_addresses.begin();
p != pending_addresses.end();
++p )
{
handle_arm_thumb_modes(*p);
}
pending_addresses.clear();
}
return 0;
}
//--------------------------------------------------------------------------
// For ARM processors the low bit means 1-thumb, 0-arm mode.
// The following function goes over the address list and sets the mode
// in IDA database according to bit0. It also resets bit0 for all addresses.
void set_arm_thumb_modes(ea_t *addrs, int qty)
{
for ( int i=0; i < qty; i++ )
{
ea_t ea = addrs[i];
segment_t *s = getseg(ea);
if ( s == NULL )
pending_addresses.insert(ea);
else
handle_arm_thumb_modes(ea);
addrs[i] = ea & ~1;
}
}
//--------------------------------------------------------------------------
void processor_specific_init(void)
{
hook_to_notification_point(HT_DBG, dbg_callback);
}
//--------------------------------------------------------------------------
void processor_specific_term(void)
{
unhook_from_notification_point(HT_DBG, dbg_callback);
pending_addresses.clear();
}