For the complete documentation index, see llms.txt. This page is also available as Markdown.

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

Type
Description

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (segment_info_t-based)

add_segm_ex(segment_t*, name, sclass, flags)

add_segment_ex(segment_info_t*, flags)

Segment names

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

get_segm_class(&buf, s)

get_segment_class(&buf, ea)

set_segm_class(s, sclass, flags)

set_segment_class(ea, sclass, flags)

Segment comments

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

set_visible_segm(s, visible)

set_visible_segment(ea, visible)

Segment locking

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

segm_adjust_diff(s, delta)

adjust_segment_diff(ea, delta)

segm_adjust_ea(s, ea)

adjust_segment_ea(seg_ea, ea)

Output helpers

Deprecated (pointer-based)
New (ea-based)

std_out_segm_footer(ctx, seg)

std_out_segment_footer(ctx, seg_ea)

Segment registers (segregs.hpp)

Deprecated (pointer-based)
New (ea-based)

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)

Deprecated (pointer-based)
New (safe)
Notes

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

Type
Description

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

Deprecated (pointer-based)
New (ea-based / copy-based)

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

Deprecated (pointer-based)
New (copy-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Type
Description

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()

Flag
Description

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

add_func_ex(pfn) / add_func(ea1, ea2)

add_function_ex(&fi)

find_func_bounds(nfn, flags)

find_function_bounds(&fi, flags)

Function properties

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

add_regarg(pfn, reg, tif, name)

add_func_regarg(func_ea, reg, tif, name)

Function locking

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated
New
Parameter change

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):

Deprecated
New

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

Event
Inline wrapper

ev_is_outlined_function

is_outlined_function(ea_t func_ea)

Segment events

Deprecated
New
Parameter change

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

Deprecated
New
Parameter change

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

Deprecated
New
Parameter change

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

Type
Description

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

Deprecated (pointer-based)
New (ea-based)

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)

Deprecated (pointer-based)
New (ea-based)

has_external_refs(pfn, ea)

has_external_refs_ea(func_ea, ea)

Name API (name.hpp)

Deprecated (pointer-based)
New (ea-based)

is_name_defined_locally(pfn, name, ignore, ea1, ea2)

is_name_defined_locally_ea(func_ea, name, ignore, ea1, ea2)

Lumina API (lumina.hpp)

Deprecated (pointer-based)
New (ea-based)

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)

Deprecated (pointer-based)
New (ea-based)

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.

Deprecated (pointer-based)
New (ea-based)

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.

Deprecated
New
Parameter change

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

Deprecated (pointer-based)
New (ea-based)
Description

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 *pfnea_t func_ea (BADADDR when not in function mode)

  • Uses function_item_iterator_t / function_tail_iterator_t instead of func_item_iterator_t / func_tail_iterator_t

  • Uses function_contains() and get_func_tail_qty() instead of func_contains() and pfn->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

Deprecated
New

chtype_stkvar_xref

chtype_stkvar_xref_ea

chtype_func

chtype_func_ea

New chooser functions

Deprecated (pointer-based)
New (ea-based)

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

Deprecated (pointer-based)
New (ea-based)

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

Deprecated
New

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?