Porting Guide from IDA 9.x to 9.4
Introduction
This Porting Guide covers the new address-based (ea_t) and copy-based APIs introduced in IDA 9.4 across the C++ SDK, and shows how to migrate from the older pointer-based equivalents (segment_t*, func_t*, and similar).
The legacy APIs are deprecated but not yet removed. Existing plugins and scripts continue to compile and run without changes in IDA 9.4.
Migrating now ensures your code stays compatible when these APIs are eventually removed.
Segment API (segment.hpp, segregs.hpp)
The new API replaces segment_t* pointer-based functions with ea_t-based (address-based) functions and segment_info_t copy-based access. This avoids pointer lifetime issues: the new functions use a segment's start_ea as a stable handle instead of a raw pointer that can be invalidated.
New types
segment_info_t
Copy-based segment descriptor (replaces segment_t*). Use get_segment_info() to fill it, modify via setters, then call set_segment_info() to apply changes.
lock_segment_ea
RAII helper to lock a segment by address (replaces lock_segment).
Segment lookup and iteration
getseg(ea)
get_segment_info(&si, ea)
getnseg(n)
get_segment_ea_by_num(n) or get_segment_info_by_num(&si, n)
get_first_seg()
get_first_segment_ea()
get_last_seg()
get_last_segment_ea()
get_next_seg(ea)
get_next_segment_ea(ea)
get_prev_seg(ea)
get_prev_segment_ea(ea)
get_segm_by_name(name)
get_segment_ea_by_name(name)
get_segm_by_sel(sel)
get_segment_ea_by_sel(sel)
Segment enumeration by selector
enumerate_segments_with_selector(sel, func, ud)
enumerate_segments_with_selector_ea(sel, visitor)
The new function takes a std::function visitor (segment_selector_visitor_t) that receives each matching segment's start_ea instead of a segment_t* + void *ud callback pair. The visitor returns BADADDR to continue and any other value to stop the enumeration (that value is returned to the caller). Because the visitor is a closure, the separate ud user-data pointer is no longer needed.
Before (deprecated):
After (new API):
Segment creation
add_segm_ex(segment_t*, name, sclass, flags)
add_segment_ex(segment_info_t*, flags)
Segment names
get_segm_name(&buf, s, flags)
get_segment_name(&buf, ea, flags)
get_visible_segm_name(&buf, s)
get_segment_name(&buf, ea, GN_VISIBLE)
set_segm_name(s, name, flags)
set_segment_name(ea, name, flags)
Segment class and type
get_segm_class(&buf, s)
get_segment_class(&buf, ea)
set_segm_class(s, sclass, flags)
set_segment_class(ea, sclass, flags)
Segment comments
get_segment_cmt(&buf, s, repeatable)
get_segment_cmt_by_ea(&buf, ea, repeatable)
set_segment_cmt(s, cmt, repeatable)
set_segment_cmt_by_ea(ea, cmt, repeatable)
Segment addressing and base
get_segm_para(s)
get_segment_para(ea)
get_segm_base(s)
get_segment_base(ea)
set_segm_base(s, newbase)
set_segment_base_ea(ea, newbase)
set_segm_addressing(s, bitness)
set_segment_addressing(ea, bitness)
Segment movement and status
move_segm(s, to, flags)
move_segment(ea, to, flags)
change_segment_status(s, is_deb_segm)
change_segment_status_by_ea(ea, is_deb_segm)
Segment visibility
set_visible_segm(s, visible)
set_visible_segment(ea, visible)
Segment locking
lock_segm(segm, lock)
lock_segment_by_ea(ea, lock)
lock_segment (RAII class)
lock_segment_ea (RAII class)
is_segm_locked(segm)
is_segment_locked(ea)
Address adjustment
segm_adjust_diff(s, delta)
adjust_segment_diff(ea, delta)
segm_adjust_ea(s, ea)
adjust_segment_ea(seg_ea, ea)
Output helpers
std_out_segm_footer(ctx, seg)
std_out_segment_footer(ctx, seg_ea)
Segment registers (segregs.hpp)
set_default_sreg_value(sg, rg, value)
set_default_sreg_value_ea(seg_ea, rg, value)
Migration example
Before (deprecated):
After (new API):
Source file API (lines.hpp)
get_sourcefile(ea, bounds)
get_sourcefile_by_ea(&filename, ea, bounds)
Returns bool; copies filename into qstring* instead of returning an internal const char* pointer with lifetime issues
Hidden range API (bytes.hpp)
The new API replaces hidden_range_t* pointer-based functions with ea_t-based (address-based) functions and hidden_range_info_t copy-based access. This avoids pointer lifetime issues: the new functions use a range's start_ea as a stable handle instead of a raw pointer that can be invalidated.
New types
hidden_range_info_t
Copy-based hidden range descriptor (replaces hidden_range_t*). Use get_hidden_range_info() to fill it, modify via setters, then call update_hidden_range_info() to apply changes.
Lookup and iteration
get_hidden_range(ea)
get_hidden_range_info(&hri, ea)
getn_hidden_range(n)
get_hidden_range_info_by_num(&hri, n)
get_first_hidden_range()
get_first_hidden_range_ea()
get_last_hidden_range()
get_last_hidden_range_ea()
get_next_hidden_range(ea)
get_next_hidden_range_ea(ea)
get_prev_hidden_range(ea)
get_prev_hidden_range_ea(ea)
Update
update_hidden_range(hidden_range_t*)
update_hidden_range_info(&hri)
Migration example
Before (deprecated):
After (new API):
Output context API (ua.hpp)
outctx_t virtual methods
outctx_t::gen_func_header(func_t*)
outctx_t::gen_function_header(ea_t)
outctx_t::gen_func_footer(const func_t*)
outctx_t::gen_function_footer(ea_t)
Function API (funcs.hpp)
The new API replaces func_t* pointer-based functions with ea_t-based (address-based) functions and copy-based info types. This avoids pointer lifetime issues: func_t* can be invalidated by del_func(), add_func(), set_func_start/end(), undo operations, and recursive IDB event callbacks.
Because func_t is a union (entry chunks and tail chunks share the same C++ type but use different fields), the new API provides two distinct copy types: func_entry_info_t for function entries and func_tail_info_t for tails.
New types
fchunk_info_t
Lightweight chunk descriptor (range + flags) for entry or tail chunks. Base class for func_entry_info_t and func_tail_info_t. Use get_fchunk_info() to fill.
func_entry_info_t
Copy-based function entry descriptor (extends fchunk_info_t). Use get_func_entry_info() to fill, modify via setters, then call set_func_entry_info() to apply changes. Controlled by GFI_* fill flags.
func_tail_info_t
Copy-based function tail descriptor (extends fchunk_info_t). Use get_func_tail_info() to fill. Exposes owner, flags, referer count. Use func_parent_iterator_t for full referer enumeration.
function_tail_iterator_t
ea-based function tail iterator. Replaces func_tail_iterator_t(pfn, ea) with function_tail_iterator_t(func_ea, ea).
function_parent_iterator_t
ea-based function parent iterator. Replaces func_parent_iterator_t(fnt) with function_parent_iterator_t(tail_ea).
function_item_iterator_t
ea-based function item iterator. Replaces func_item_iterator_t(pfn, ea) with function_item_iterator_t(func_ea, ea).
func_chunk_visitor_t
std::function<void(ea_t chunk_start, ea_t chunk_end)> callback type for iterate_func_chunks_ea().
lock_func_ea
RAII helper to lock a function by address (replaces lock_func).
Fill flags for get_func_entry_info()
GFI_NAME
Populate the function name
GFI_CMT
Populate the regular comment
GFI_CMT_RPT
Populate the repeatable comment
GFI_COMMENTS
GFI_CMT | GFI_CMT_RPT
GFI_ALL
GFI_NAME | GFI_COMMENTS
Numeric fields (flags, frsize, frregs, argsize, fpd, color, frame_id) are always populated. String fields (name, comments) are only populated when the corresponding GFI_* flag is passed, to avoid unnecessary work.
Function lookup and navigation
get_func(ea)
get_func_start(ea) or get_func_entry_info(&fi, ea)
getn_func(n)
get_func_ea_by_num(n) or get_func_entry_info_by_num(&fi, n)
get_prev_func(ea)
get_prev_func_ea(ea)
get_next_func(ea)
get_next_func_ea(ea)
Function chunk lookup and navigation
get_fchunk(ea)
get_fchunk_start(ea), get_fchunk_info(&fci, ea), or get_func_tail_info(&ti, ea)
getn_fchunk(n)
get_fchunk_ea_by_num(n)
get_prev_fchunk(ea)
get_prev_fchunk_info(&fci, ea) or get_prev_fchunk_ea(ea)
get_next_fchunk(ea)
get_next_fchunk_info(&fci, ea) or get_next_fchunk_ea(ea)
Function creation
add_func_ex(pfn) / add_func(ea1, ea2)
add_function_ex(&fi)
find_func_bounds(nfn, flags)
find_function_bounds(&fi, flags)
Function properties
pfn->flags
get_func_flags(ea) / set_func_flags(ea, flags) / set_func_flag(ea, flag, on_off)
is_func_entry(pfn)
is_function_entry(ea)
is_func_tail(pfn)
is_function_tail(ea)
pfn->owner (tail chunk)
get_tail_owner(tail_ea)
get_func_bitness(pfn)
get_func_bitness_ea(ea)
get_func_bits(pfn)
get_func_bitness_ea(ea)
get_func_bytes(pfn)
get_func_bitness_ea(ea)
calc_func_size(pfn)
calc_func_size_ea(ea)
get_func_ranges(ranges, pfn)
get_func_ranges_ea(ranges, ea)
update_func(pfn)
set_func_entry_info(&fi)
Function comments
get_func_cmt(&buf, pfn, rpt)
get_func_cmt_ea(&buf, ea, rpt)
set_func_cmt(pfn, cmt, rpt)
set_func_cmt_ea(ea, cmt, rpt)
Function visibility
is_visible_func(pfn)
(get_func_flags(ea) & FUNC_HIDDEN) == 0
is_finally_visible_func(pfn)
check SCF_SHHID_FUNC flag + get_func_flags(ea)
set_visible_func(pfn, vis)
set_visible_func_ea(ea, vis)
Function chunk manipulation
get_func_chunknum(pfn, ea)
get_func_chunknum_ea(func_ea, ea)
func_contains(pfn, ea)
function_contains(func_ea, ea)
is_same_fchunk(ea1, ea2)
append_func_tail(pfn, ea1, ea2)
append_func_tail_ea(func_ea, ea1, ea2)
remove_func_tail(pfn, tail_ea)
remove_func_tail_ea(func_ea, tail_ea)
set_tail_owner(fnt, new_owner)
set_tail_owner_ea(tail_ea, new_owner)
iterate_func_chunks(pfn, cb, ud)
iterate_func_chunks_ea(func_ea, visitor)
calc_thunk_func_target(pfn, fptr)
calc_thunk_function_target(fi, fptr)
set_func_name_if_jumpfunc(pfn, old)
set_function_name_if_jumpfunc(func_ea, old)
reanalyze_function(pfn, ea1, ea2)
reanalyze_function_ea(func_ea, ea1, ea2)
pfn->tailqty
get_func_tail_qty(func_ea)
pfn->tailqty / pfn->tails[i]
get_func_tails(&out, func_ea)
get_prev_func_addr(pfn, ea)
get_prev_function_addr(func_ea, ea)
get_next_func_addr(pfn, ea)
get_next_function_addr(func_ea, ea)
Register arguments
add_regarg(pfn, reg, tif, name)
add_func_regarg(func_ea, reg, tif, name)
Function locking
lock_func_range(pfn, lk)
lock_func_range_ea(ea, lk)
lock_func (RAII class)
lock_func_ea (RAII class)
is_func_locked(pfn)
is_func_locked_ea(ea)
Migration examples
Simple case — check if address is in a function:
Before (deprecated):
After (new API):
Multi-field access — using func_entry_info_t:
Tail chunk handling:
Before (deprecated):
After (new API):
Iterating function chunks:
Before (deprecated):
After (new API):
Frame API (frame.hpp)
The new API replaces func_t* pointer-based frame functions with ea_t-based equivalents. Using ea_t (the function's start address) as a stable handle avoids pointer lifetime issues.
Frame manipulation
add_frame(pfn, frsize, frregs, argsize)
add_frame_ea(func_ea, frsize, frregs, argsize)
del_frame(pfn)
del_frame_ea(func_ea)
set_frame_size(pfn, frsize, frregs, arg)
set_frame_size_ea(func_ea, frsize, frregs, arg)
get_frame_size(pfn)
get_frame_size_ea(func_ea)
get_frame_retsize(pfn)
get_frame_retsize_ea(func_ea)
get_frame_part(&range, pfn, part)
get_frame_part_ea(&range, func_ea, part)
frame_off_args(pfn)
frame_off_args_ea(func_ea)
frame_off_retaddr(pfn)
frame_off_retaddr_ea(func_ea)
frame_off_savregs(pfn)
frame_off_savregs_ea(func_ea)
frame_off_lvars(pfn)
frame_off_lvars_ea(func_ea)
get_func_frame(&tif, pfn)
get_func_frame_ea(&tif, func_ea)
tinfo_t::get_func_frame(pfn)
tinfo_t::get_function_frame(func_ea)
soff_to_fpoff(pfn, soff)
soff_to_fpoff_ea(func_ea, soff)
update_fpd(pfn, fpd)
update_fpd_ea(func_ea, fpd)
processor_t::is_funcarg_off(pfn, off)
processor_t::is_funcarg_off_ea(func_ea, off)
processor_t::lvar_off(pfn, off)
processor_t::lvar_off_ea(func_ea, off)
Note: get_frame_part_ea() returns bool (false if no function at func_ea), improving on the old void return type that would crash on nullptr.
Stack variables
define_stkvar(pfn, name, off, tif, repr)
define_stkvar_ea(func_ea, name, off, tif, repr)
add_frame_member(pfn, name, off, tif, repr, fl)
add_frame_member_ea(func_ea, name, off, tif, repr, fl)
set_frame_member_type(pfn, off, tif, repr, fl)
set_frame_member_type_ea(func_ea, off, tif, repr, fl)
delete_frame_members(pfn, soff, eoff)
delete_frame_members_ea(func_ea, soff, eoff)
build_stkvar_name(&buf, pfn, v)
build_stkvar_name_ea(&buf, func_ea, v)
calc_stkvar_struc_offset(pfn, insn, n)
calc_stkvar_struc_offset_ea(func_ea, insn, n)
calc_frame_offset(pfn, off, insn, op)
calc_frame_offset_ea(func_ea, off, insn, op)
delete_wrong_frame_info(pfn, cb)
delete_wrong_frame_info_ea(func_ea, cb)
build_stkvar_xrefs(&out, pfn, soff, eoff)
build_stkvar_xrefs_ea(&out, func_ea, soff, eoff)
Register variables
add_regvar(pfn, ea1, ea2, canon, user, cmt)
add_func_regvar(func_ea, ea1, ea2, canon, user, cmt)
find_regvar(pfn, ea1, ea2, canon, user)
find_func_regvar(&rv, func_ea, ea1, ea2, canon, user)
find_regvar(pfn, ea, canon)
find_func_regvar(&rv, func_ea, ea, canon)
has_regvar(pfn, ea)
has_func_regvar(func_ea, ea)
rename_regvar(pfn, v, user)
rename_func_regvar(func_ea, index, user)
set_regvar_cmt(pfn, v, cmt)
set_func_regvar_cmt(func_ea, index, cmt)
del_regvar(pfn, ea1, ea2, canon)
del_func_regvar(func_ea, ea1, ea2, canon)
pfn->regvarqty / pfn->regvars[i]
get_func_regvars(&out, func_ea)
pfn->regvars[i] (by index)
get_func_regvar(&rv, func_ea, index)
pfn->regvars[i].start_ea/end_ea = ...
set_func_regvar_range(func_ea, index, range)
Unlike the deprecated find_regvar(), which returned an unsafe regvar_t* pointing into kernel data, find_func_regvar() returns the index of the register variable (or -1 if not found) and, when rv is not nullptr, copies the found regvar into *rv. rename_func_regvar() / set_func_regvar_cmt() take that index. To change a regvar's address range, use set_func_regvar_range() (the new range must be well-formed and must keep the variables sorted by start_ea):
Register arguments
pfn->regargqty
get_func_regarg_qty(func_ea)
pfn->regargs[i]
get_func_regarg(&out, func_ea, n)
pfn->regargqty / pfn->regargs[i]
get_func_regargs(&out, func_ea)
Tail referers
pfn->refqty
get_tail_referer_qty(tail_ea)
pfn->refqty / pfn->referers[i]
get_tail_referer(tail_ea, n)
pfn->refqty / pfn->referers[i]
get_tail_referers(&out, tail_ea)
SP change points
add_auto_stkpnt(pfn, ea, delta)
add_func_auto_stkpnt(func_ea, ea, delta)
del_stkpnt(pfn, ea)
del_func_stkpnt(func_ea, ea)
get_spd(pfn, ea)
get_func_spd(func_ea, ea)
get_effective_spd(pfn, ea)
get_func_effective_spd(func_ea, ea)
get_sp_delta(pfn, ea)
get_func_sp_delta(func_ea, ea)
set_auto_spd(pfn, ea, new_spd)
set_func_auto_spd(func_ea, ea, new_spd)
recalc_spd_for_basic_block(pfn, cur_ea)
recalc_func_spd_for_basic_block(func_ea, cur_ea)
pfn->pntqty
get_func_stkpnt_qty(func_ea)
pfn->pntqty / pfn->points[i]
get_func_stkpnts(&out, func_ea)
Local labels
pfn->llabelqty
get_func_llabel_qty(func_ea)
pfn->llabelqty / pfn->llabels[i]
get_func_llabels(&out, func_ea)
Note: For SP change point functions, func_ea may be BADADDR to auto-resolve the function from the instruction address (matching old nullptr behavior).
NOT deprecated (already ea-based or no func_t*): add_stkvar, set_purged, add_user_stkpnt, recalc_spd, is_special_frame_member, is_anonymous_member_name, is_dummy_member_name, free_regvar.
Migration example
Before (deprecated):
After (new API):
Processor events (processor_t::event_t)
Function events
ev_is_jump_func
ev_is_jump_function
func_t* -> func_entry_info_t *
ev_func_bounds
ev_function_bounds
func_t* -> fchunk_info_t *
ev_verify_sp
ev_verify_function_sp
func_t* -> ea_t func_ea
ev_verify_noreturn
ev_verify_function_noreturn
func_t* -> ea_t func_ea
ev_create_func_frame
ev_create_function_frame
func_t* -> ea_t func_ea
ev_get_frame_retsize
ev_get_function_retsize
func_t* -> ea_t func_ea
The following events replace asm_t callback function pointers:
Deprecated (asm_t callback)
New (event)
Parameter change
asm_t::out_func_header(outctx_t&, func_t*)
ev_out_function_header
func_t* -> ea_t func_ea
asm_t::out_func_footer(outctx_t&, func_t*)
ev_out_function_footer
func_t* -> ea_t func_ea
Inline wrappers (processor_t:: static methods):
is_jump_func(func_t*, ...)
is_jump_function(func_entry_info_t*, ...)
func_bounds(int*, func_t*, ea_t)
function_bounds(int*, ea_t func_ea, ea_t)
verify_sp(func_t*)
verify_function_sp(ea_t func_ea)
verify_noreturn(func_t*)
verify_function_noreturn(ea_t func_ea)
create_func_frame(func_t*)
create_function_frame(ea_t func_ea)
get_frame_retsize(int*, const func_t*)
get_function_retsize(int*, ea_t func_ea)
(asm_t callback)
out_function_header(outctx_t&, ea_t func_ea)
(asm_t callback)
out_function_footer(outctx_t&, ea_t func_ea)
Newly added events
ev_is_outlined_function
is_outlined_function(ea_t func_ea)
Segment events
ev_out_segstart
ev_out_segment_start
segment_t* -> ea_t seg_start_ea
ev_out_segend
ev_out_segment_end
segment_t* -> ea_t seg_start_ea
ev_creating_segm
ev_creating_segment
segment_t* -> segment_info_t*
ev_moving_segm
ev_moving_segment
segment_t* -> ea_t seg_start_ea
IDB events (idb_event::event_code_t)
Segment events
segm_added
segment_added
segment_t* -> ea_t seg_start_ea
changing_segm_start
changing_segment_start
segment_t* -> ea_t seg_start_ea
segm_start_changed
segment_start_changed
segment_t* -> ea_t seg_start_ea
changing_segm_end
changing_segment_end
segment_t* -> ea_t seg_start_ea
segm_end_changed
segment_end_changed
segment_t* -> ea_t seg_start_ea
changing_segm_name
changing_segment_name
segment_t* -> ea_t seg_start_ea
segm_name_changed
segment_name_changed
segment_t* -> ea_t seg_start_ea
changing_segm_class
changing_segment_class
segment_t* -> ea_t seg_start_ea
segm_class_changed
segment_class_changed
segment_t* -> ea_t seg_start_ea
segm_attrs_updated
segment_attrs_updated
segment_t* -> ea_t seg_start_ea
adding_segm
(dropped)
no replacement
Function events
func_added(func_t*)
function_added(ea_t)
func_t* -> ea_t func_ea
func_updated(func_t*)
function_updated(ea_t)
func_t* -> ea_t func_ea
set_func_start(func_t*, ea_t)
set_function_start(fchunk_info_t*, ea_t)
func_t* -> fchunk_info_t *fchunk
set_func_end(func_t*, ea_t)
set_function_end(fchunk_info_t*, ea_t)
func_t* -> fchunk_info_t *fchunk
deleting_func(func_t*)
deleting_function(ea_t)
func_t* -> ea_t func_ea
func_tail_appended(func_t*, func_t*)
function_tail_appended(ea_t, func_tail_info_t*)
func_t* -> ea_t func_ea, func_t* -> func_tail_info_t*
deleting_func_tail(func_t*, range_t*)
deleting_function_tail(ea_t, const range_t*)
func_t* -> ea_t func_ea
func_tail_deleted(func_t*, ea_t)
function_tail_deleted(ea_t, ea_t)
func_t* -> ea_t func_ea
tail_owner_changed(func_t*, ea_t, ea_t)
function_tail_owner_changed(func_tail_info_t*, ea_t, ea_t)
func_t* -> func_tail_info_t*
func_noret_changed(func_t*)
function_noret_changed(ea_t)
func_t* -> ea_t func_ea
stkpnts_changed(func_t*)
function_stkpnts_changed(ea_t)
func_t* -> ea_t func_ea
thunk_func_created(func_t*)
thunk_function_created(ea_t)
func_t* -> ea_t func_ea
frame_deleted(func_t*)
function_frame_deleted(ea_t)
func_t* -> ea_t func_ea
Note: func_deleted(ea_t) already uses ea_t — no change needed.
Flow chart API (gdl.hpp)
The new API replaces qflow_chart_t (which stores a func_t* pointer) with qflow_chart_ea_t (which stores an ea_t function address). This avoids pointer lifetime issues: the function's start_ea is used as a stable handle instead of a raw func_t* that can be invalidated.
New types
qflow_chart_ea_t
ea-based flow chart (replaces qflow_chart_t). Stores ea_t func_ea instead of func_t *pfn. Same graph interface.
Flow chart construction
qflow_chart_t(title, pfn, ea1, ea2, flags)
qflow_chart_ea_t(title, func_ea, ea1, ea2, flags)
qflow_chart_t::create(title, pfn, ea1, ea2, flags)
qflow_chart_ea_t::create(title, func_ea, ea1, ea2, flags)
create_qflow_chart(qflow_chart_t&)
create_func_flow_chart(qflow_chart_ea_t&)
append_to_flowchart(qflow_chart_t&, ea1, ea2)
append_to_func_flow_chart(qflow_chart_ea_t&, ea1, ea2)
fc_calc_block_type(qflow_chart_t&, blknum)
fc_calc_func_block_type(qflow_chart_ea_t&, blknum)
create_multirange_qflow_chart(qflow_chart_t&, ranges)
create_multirange_func_flow_chart(qflow_chart_ea_t&, ranges)
gen_flow_graph(file, title, pfn, ea1, ea2, flags)
gen_flow_graph_ea(file, title, func_ea, ea1, ea2, flags)
Migration example
Before (deprecated):
After (new API):
Cross-reference API (xref.hpp)
has_external_refs(pfn, ea)
has_external_refs_ea(func_ea, ea)
Name API (name.hpp)
is_name_defined_locally(pfn, name, ignore, ea1, ea2)
is_name_defined_locally_ea(func_ea, name, ignore, ea1, ea2)
Lumina API (lumina.hpp)
calc_func_metadata(hash, fi, pfn, append_metadata)
calc_function_metadata(hash, fi, func_ea, append_metadata)
metadata_appender_t(mcr, pfn)
metadata_appender_ea_t(mcr, func_ea)
lumina_client_t::push_md(..., metadata_appender_t*)
lumina_client_t::push_md(..., metadata_appender_ea_t*)
The old lumina_client_t::push_md() virtual method is renamed to obsolete_push_md() (preserving its vtable slot). The new push_md() virtual method uses metadata_appender_ea_t* and is added after del_history().
Decompiler API (micro.hpp, c.hpp)
mba_t::get_curfunc()
mba_t::get_curfunc_ea()
cfunc_t::get_curfunc()
cfunc_t::get_curfunc_ea()
mba_t::inline_func(cdg, blknum, mba_ranges_t &, ...)
mba_t::inline_function(cdg, blknum, decomp_ranges_t &, ...)
decompile(const mba_ranges_t &, ...)
decompile(const decomp_ranges_t &, ...)
decompile_func(func_t *pfn, ...)
decompile_function(ea_t func_ea, ...)
gen_microcode(const mba_ranges_t &, ...)
gen_microcode(const decomp_ranges_t &, ...)
create_empty_mba(const mba_ranges_t &, ...)
create_empty_mba(const decomp_ranges_t &, ...)
inline_func() is retained as a thin wrapper that converts its mba_ranges_t argument into a decomp_ranges_t and delegates to inline_function(); new code should call inline_function() directly.
decompile(const mba_ranges_t &, ...) is retained as a thin wrapper that converts via set_from_mbr() and forwards to the new decompile(const decomp_ranges_t &, ...) overload; new code should call the ea-based overload directly.
decompile_snippet(const rangevec_t &, ...) keeps its name and signature but now builds a decomp_ranges_t and calls the new decompile() overload, so existing callers do not need to change.
gen_microcode(const mba_ranges_t &, ...) is retained as a thin wrapper marked DEPRECATED; it converts via set_from_mbr() and forwards to the new gen_microcode(const decomp_ranges_t &, ...) overload. Similarly, create_empty_mba(const mba_ranges_t &, ...) is DEPRECATED; use the new create_empty_mba(const decomp_ranges_t &, ...) overload instead.
Migration examples
Before (deprecated):
After (new API):
Flow chart type in decompiler internals
The internal decompiler code (codegen_t::analyze_prolog, mba_t flow-chart helpers, processor-module codegen overrides) has been switched from the pointer-based qflow_chart_t to the ea-based qflow_chart_ea_t (see the Flow chart section above). Plugins that override codegen_t::analyze_prolog must update their signature.
codegen_t::analyze_prolog(const qflow_chart_t &, ...)
codegen_t::analyze_prolog(const qflow_chart_ea_t &, ...)
Decompiler events (hexrays_event_t)
Two new events carry a qflow_chart_ea_t* instead of the legacy qflow_chart_t*. The decompiler fires the deprecated event first, then the new one, so plugins can migrate at their own pace — existing hooks keep working, and new code should subscribe to the _ea variant.
hxe_flowchart
hxe_flowchart_ea
qflow_chart_t* -> qflow_chart_ea_t*
hxe_prolog
hxe_prolog_ea
qflow_chart_t* -> qflow_chart_ea_t*
hxe_inlining_func
hxe_inlining_function
mba_ranges_t* -> decomp_ranges_t*
hxe_inlined_func
hxe_inlined_function
mba_ranges_t* -> decomp_ranges_t*
Migration example (event handler)
Before (deprecated):
After (new API):
Decompilation ranges
The new API replaces mba_ranges_t (which stores a func_t* pointer) with decomp_ranges_t (which stores an ea_t function address). The associated iterators are also replaced.
New types
mba_ranges_t
decomp_ranges_t
Ranges to decompile (function or snippet mode)
mba_item_iterator_t
decomp_item_iterator_t
Item iterator over decompilation ranges
mba_range_iterator_t
decomp_range_iterator_t
Chunk iterator over decompilation ranges
Key differences in decomp_ranges_t vs mba_ranges_t:
func_t *pfn→ea_t func_ea(BADADDR when not in function mode)Uses
function_item_iterator_t/function_tail_iterator_tinstead offunc_item_iterator_t/func_tail_iterator_tUses
function_contains()andget_func_tail_qty()instead offunc_contains()andpfn->tailqty
Migration example
Before (deprecated):
After (new API):
Chooser API (kernwin.hpp)
The new API adds ea-based chooser types and inline functions that avoid passing func_t* pointers through the callui() variadic interface.
New chooser types
chtype_stkvar_xref
chtype_stkvar_xref_ea
chtype_func
chtype_func_ea
New chooser functions
choose_stkvar_xref(pfn, stkvar_tid)
choose_stkvar_xref_ea(func_ea, stkvar_tid)
choose_func(title, default_ea)
choose_func_ea(title, default_ea)
Note: choose_func() returns func_t*, choose_func_ea() returns ea_t.
Migration example
Before (deprecated):
After (new API):
Built-in window API (kernwin.hpp)
Frame window
open_frame_window(pfn, offset)
open_frame_window_ea(func_ea, offset)
The new function uses ui_open_builtin2 instead of ui_open_builtin.
UI events (kernwin.hpp)
Function prototype editor
ui_prompt_function_prototype_ex / prompt_function_prototype_ex()
ui_prompt_function_prototype / prompt_function_prototype()
The new event and inline function take ea_t func_ea instead of func_t *pfn.
Last updated
Was this helpful?
