IDA C++ SDK 9.2
Loading...
Searching...
No Matches
frame.hpp
Go to the documentation of this file.
1/*
2 * Interactive disassembler (IDA).
3 * Copyright (c) 1990-2025 Hex-Rays
4 * ALL RIGHTS RESERVED.
5 *
6 */
7
8#ifndef _FRAME_HPP
9#define _FRAME_HPP
10#include <idp.hpp>
11
42
43// name of stkvar to denote the return address slot
44#define FRAME_UDM_NAME_R "__return_address"
45// name of stkvar to denote the saved register slots
46#define FRAME_UDM_NAME_S "__saved_registers"
47
48class op_t;
49
50// We need to trace value of SP register. For this we introduce
51// an array of SP register change points.
52
53// SP register change point
54//
55// NOTE: To manipulate/modify stack points, please use the specialized
56// functions provided below in this file (stack pointer change points)
57
59{
60 ea_t ea; // linear address
61 sval_t spd; // here we keep a cumulative difference from [BP-frsize]
62
64 {
65 if ( ea < r.ea )
66 return -1;
67 if ( ea > r.ea )
68 return 1;
69 return 0;
70 }
71};
73// we declare a struct to be able to forward declare it in other files
74struct stkpnts_t : public qvector<stkpnt_t>
75{
77};
78
79//--------------------------------------------------------------------------
80// F R A M E M A N I P U L A T I O N
81//--------------------------------------------------------------------------
82
92
93idaman bool ida_export add_frame(
94 func_t *pfn,
95 sval_t frsize,
96 ushort frregs,
97 asize_t argsize);
98
99
103
104idaman bool ida_export del_frame(func_t *pfn);
105
106
117
118idaman bool ida_export set_frame_size(
119 func_t *pfn,
120 asize_t frsize,
121 ushort frregs,
122 asize_t argsize);
123
124
132
133idaman asize_t ida_export get_frame_size(const func_t *pfn);
134
135
138
139idaman int ida_export get_frame_retsize(const func_t *pfn);
140
149
155
156idaman void ida_export get_frame_part(range_t *range, const func_t *pfn, frame_part_t part);
157
159
160inline ea_t frame_off_args(const func_t *pfn)
161{
162 range_t range;
163 get_frame_part(&range, pfn, FPC_ARGS);
164 return range.start_ea;
165}
166
168
169inline ea_t frame_off_retaddr(const func_t *pfn)
170{
171 range_t range;
172 get_frame_part(&range, pfn, FPC_RETADDR);
173 return range.start_ea;
174}
175
177
178inline ea_t frame_off_savregs(const func_t *pfn)
179{
180 range_t range;
181 get_frame_part(&range, pfn, FPC_SAVREGS);
182 return range.start_ea;
183}
184
186
187inline ea_t frame_off_lvars(const func_t *pfn)
188{
189 range_t range;
190 get_frame_part(&range, pfn, FPC_LVARS);
191 return range.start_ea;
192}
193
195
196inline bool processor_t::is_funcarg_off(const func_t *pfn, uval_t frameoff) const
197{
200 return stkup()
201 ? frameoff < args.end_ea
202 : frameoff >= args.start_ea;
203}
204
206
207inline sval_t processor_t::lvar_off(const func_t *pfn, uval_t frameoff) const
208{
209 range_t lvars;
210 get_frame_part(&lvars, pfn, FPC_LVARS);
211 return stkup()
212 ? frameoff - lvars.start_ea
213 : lvars.end_ea - frameoff;
214}
215
220
221idaman bool ida_export get_func_frame(tinfo_t *out, const func_t *pfn);
222
223inline bool get_func_frame(tinfo_t *tif, ea_t ea) { return get_func_frame(tif, get_func(ea)); }
224
228
230{
231 return pfn != nullptr ? soff - pfn->frsize + pfn->fpd : soff;
232}
233
234
240
241idaman bool ida_export update_fpd(func_t *pfn, asize_t fpd);
242
243
252
253idaman bool ida_export set_purged(ea_t ea, int nbytes, bool override_old_value);
254
255
256//--------------------------------------------------------------------------
257// S T A C K V A R I A B L E S
258//--------------------------------------------------------------------------
259
267
268idaman bool ida_export add_stkvar(const insn_t &insn, const op_t &x, sval_t v, int flags);
269
273#define STKVAR_VALID_SIZE 0x0001
277#define STKVAR_KEEP_EXISTING 0x0002
280
289
290idaman bool ida_export define_stkvar(
291 func_t *pfn,
292 const char *name,
293 sval_t off,
294 const tinfo_t &tif,
295 const struct value_repr_t *repr=nullptr);
296
297
306
307idaman bool ida_export add_frame_member(
308 const func_t *pfn,
309 const char *name,
310 uval_t offset,
311 const tinfo_t &tif,
312 const struct value_repr_t *repr=nullptr,
313 uint etf_flags=0);
314
315
317
318inline THREAD_SAFE bool is_anonymous_member_name(const char *name)
319{
320 return name == nullptr
321 || strncmp(name, "anonymous", 9) == 0;
322}
323
324
326
327inline THREAD_SAFE bool is_dummy_member_name(const char *name)
328{
329 return name == nullptr
330 || strncmp(name, "arg_", 4) == 0
331 || strncmp(name, "var_", 4) == 0
333}
334
335
339
340idaman bool ida_export is_special_frame_member(tid_t tid);
341
342
350
351idaman bool ida_export set_frame_member_type(
352 const func_t *pfn,
353 uval_t offset,
354 const tinfo_t &tif,
355 const struct value_repr_t *repr=nullptr,
356 uint etf_flags=0);
357
358
364
365idaman bool ida_export delete_frame_members(
366 const func_t *pfn,
367 uval_t start_offset,
368 uval_t end_offset);
369
370
376
377idaman ssize_t ida_export build_stkvar_name(
378 qstring *buf,
379 const func_t *pfn,
380 sval_t v);
381
382
389
391 func_t *pfn,
392 const insn_t &insn,
393 int n);
394
395
402
403idaman sval_t ida_export calc_frame_offset(
404 func_t *pfn,
405 sval_t off,
406 const insn_t *insn = nullptr,
407 const op_t *op = nullptr);
408
409
420
421idaman int ida_export delete_wrong_frame_info(
422 func_t *pfn,
423 bool idaapi should_reanalyze(const insn_t &insn));
424
425
426//--------------------------------------------------------------------------
427// R E G I S T E R V A R I A B L E S
428//--------------------------------------------------------------------------
432
433idaman void ida_export free_regvar(struct regvar_t *v);
434
439struct regvar_t : public range_t
440{
441 char *canon = nullptr;
442 char *user = nullptr;
443 char *cmt = nullptr;
444
446 regvar_t(const regvar_t &r) : range_t(r)
447 {
448 canon = ::qstrdup(r.canon);
449 user = ::qstrdup(r.user);
450 cmt = ::qstrdup(r.cmt);
451 }
454 {
455 if ( this != &r )
456 {
457 free_regvar(this);
458 new (this) regvar_t(r);
459 }
460 return *this;
461 }
462 void swap(regvar_t &r)
463 {
464 uchar buf[sizeof(*this)];
465 memcpy(buf, &r, sizeof(buf));
466 memcpy(&r, this, sizeof(buf));
467 memcpy(this, buf, sizeof(buf));
468 }
469#ifndef SWIG
471#endif
472};
474
483
484idaman int ida_export add_regvar(
485 func_t *pfn,
486 ea_t ea1,
487 ea_t ea2,
488 const char *canon,
489 const char *user,
490 const char *cmt);
494#define REGVAR_ERROR_OK 0
495#define REGVAR_ERROR_ARG (-1)
496#define REGVAR_ERROR_RANGE (-2)
497#define REGVAR_ERROR_NAME (-3)
499
510
511idaman regvar_t *ida_export find_regvar(func_t *pfn, ea_t ea1, ea_t ea2, const char *canon, const char *user);
512
513
519
520inline regvar_t *find_regvar(func_t *pfn, ea_t ea, const char *canon)
521{
522 return find_regvar(pfn, ea, ea+1, canon, nullptr);
523}
524
525
529
530inline bool has_regvar(func_t *pfn, ea_t ea)
531{
532 return find_regvar(pfn, ea, ea+1, nullptr, nullptr) != nullptr;
533}
534
535
541
542idaman int ida_export rename_regvar(func_t *pfn, regvar_t *v, const char *user);
543
544
550
551idaman int ida_export set_regvar_cmt(func_t *pfn, regvar_t *v, const char *cmt);
552
553
559
560idaman int ida_export del_regvar(func_t *pfn, ea_t ea1, ea_t ea2, const char *canon);
561
563
564//--------------------------------------------------------------------------
565// S P R E G I S T E R C H A N G E P O I N T S
566//--------------------------------------------------------------------------
567
575
576idaman bool ida_export add_auto_stkpnt(func_t *pfn, ea_t ea, sval_t delta);
577
578
583
584idaman bool ida_export add_user_stkpnt(ea_t ea, sval_t delta);
585
586
591
592idaman bool ida_export del_stkpnt(func_t *pfn, ea_t ea);
593
594
600
601idaman sval_t ida_export get_spd(func_t *pfn, ea_t ea);
602
603
611
612idaman sval_t ida_export get_effective_spd(func_t *pfn, ea_t ea);
613
614
620
621idaman sval_t ida_export get_sp_delta(func_t *pfn, ea_t ea);
622
623
631
632idaman bool ida_export set_auto_spd(func_t *pfn, ea_t ea, sval_t new_spd);
633
634
646
647idaman bool ida_export recalc_spd(ea_t cur_ea);
648
649
668
669idaman bool ida_export recalc_spd_for_basic_block(func_t *pfn, ea_t cur_ea);
670
671
674{
678
680 {
681 int code = ::compare(ea, r.ea);
682 if ( code == 0 )
683 {
684 code = ::compare(type, r.type);
685 if ( code == 0 )
686 code = ::compare(opnum, r.opnum);
687 }
688 return code;
689 }
690};
693
700
701idaman void ida_export build_stkvar_xrefs(xreflist_t *out, func_t *pfn, uval_t start_offset, uval_t end_offset);
702
703
704#endif // _FRAME_HPP
A function is a set of continuous ranges of addresses with characteristics.
Definition funcs.hpp:85
asize_t fpd
frame pointer delta.
Definition funcs.hpp:177
asize_t frsize
size of local variables part of frame in bytes.
Definition funcs.hpp:169
Operand of an instruction.
Definition ua.hpp:170
Reimplementation of vector class from STL.
Definition pro.h:2250
qvector(void)
Definition pro.h:2328
Primary mechanism for managing type information.
Definition typeinf.hpp:3046
idaman bool ida_export add_frame_member(const func_t *pfn, const char *name, uval_t offset, const tinfo_t &tif, const struct value_repr_t *repr=nullptr, uint etf_flags=0)
Add member to the frame type.
idaman asize_t ida_export get_frame_size(const func_t *pfn)
Get full size of a function frame.
idaman bool ida_export get_func_frame(tinfo_t *out, const func_t *pfn)
Get type of function frame.
THREAD_SAFE bool is_dummy_member_name(const char *name)
Is member name an auto-generated name?
Definition frame.hpp:327
idaman int ida_export get_frame_retsize(const func_t *pfn)
Get size of function return address.
ea_t frame_off_retaddr(const func_t *pfn)
Get starting address of return address section.
Definition frame.hpp:169
idaman void ida_export get_frame_part(range_t *range, const func_t *pfn, frame_part_t part)
Get offsets of the frame part in the frame.
idaman bool ida_export add_auto_stkpnt(func_t *pfn, ea_t ea, sval_t delta)
Add automatic SP register change point.
idaman bool ida_export add_frame(func_t *pfn, sval_t frsize, ushort frregs, asize_t argsize)
Add function frame.
idaman sval_t ida_export get_effective_spd(func_t *pfn, ea_t ea)
Get effective difference between the initial and current values of ESP.
idaman bool ida_export define_stkvar(func_t *pfn, const char *name, sval_t off, const tinfo_t &tif, const struct value_repr_t *repr=nullptr)
Define/redefine a stack variable.
ea_t frame_off_args(const func_t *pfn)
Get starting address of arguments section.
Definition frame.hpp:160
idaman bool ida_export is_special_frame_member(tid_t tid)
Is stkvar with TID the return address slot or the saved registers slot ?
idaman sval_t ida_export get_sp_delta(func_t *pfn, ea_t ea)
Get modification of SP made at the specified location.
idaman sval_t ida_export get_spd(func_t *pfn, ea_t ea)
Get difference between the initial and current values of ESP.
idaman bool ida_export add_stkvar(const insn_t &insn, const op_t &x, sval_t v, int flags)
Automatically add stack variable.
idaman bool ida_export set_frame_size(func_t *pfn, asize_t frsize, ushort frregs, asize_t argsize)
Set size of function frame.
frame_part_t
Parts of a frame.
Definition frame.hpp:143
@ FPC_LVARS
Definition frame.hpp:147
@ FPC_ARGS
Definition frame.hpp:144
@ FPC_RETADDR
Definition frame.hpp:145
@ FPC_SAVREGS
Definition frame.hpp:146
idaman bool ida_export recalc_spd_for_basic_block(func_t *pfn, ea_t cur_ea)
Recalculate SP delta for the current instruction.
sval_t soff_to_fpoff(func_t *pfn, uval_t soff)
Convert struct offsets into fp-relative offsets.
Definition frame.hpp:229
idaman bool ida_export set_purged(ea_t ea, int nbytes, bool override_old_value)
Set the number of purged bytes for a function or data item (funcptr).
idaman bool ida_export update_fpd(func_t *pfn, asize_t fpd)
Update frame pointer delta.
idaman sval_t ida_export calc_frame_offset(func_t *pfn, sval_t off, const insn_t *insn=nullptr, const op_t *op=nullptr)
Calculate the offset of stack variable in the frame.
qvector< xreflist_entry_t > xreflist_t
vector of xrefs to variables in a function's stack frame
Definition frame.hpp:692
idaman bool ida_export del_frame(func_t *pfn)
Delete a function frame.
idaman bool ida_export delete_frame_members(const func_t *pfn, uval_t start_offset, uval_t end_offset)
Delete frame members.
idaman bool ida_export set_auto_spd(func_t *pfn, ea_t ea, sval_t new_spd)
Add such an automatic SP register change point so that at EA the new cumulative SP delta (that is,...
idaman void ida_export build_stkvar_xrefs(xreflist_t *out, func_t *pfn, uval_t start_offset, uval_t end_offset)
Fill 'out' with a list of all the xrefs made from function 'pfn' to specified range of the pfn's stac...
idaman int ida_export delete_wrong_frame_info(func_t *pfn, bool idaapi should_reanalyze(const insn_t &insn))
Find and delete wrong frame info.
idaman bool ida_export add_user_stkpnt(ea_t ea, sval_t delta)
Add user-defined SP register change point.
idaman bool ida_export set_frame_member_type(const func_t *pfn, uval_t offset, const tinfo_t &tif, const struct value_repr_t *repr=nullptr, uint etf_flags=0)
Change type of the frame member.
ea_t frame_off_savregs(const func_t *pfn)
Get starting address of saved registers section.
Definition frame.hpp:178
THREAD_SAFE bool is_anonymous_member_name(const char *name)
Is member name prefixed with "anonymous"?
Definition frame.hpp:318
idaman bool ida_export del_stkpnt(func_t *pfn, ea_t ea)
Delete SP register change point.
DECLARE_TYPE_AS_MOVABLE(stkpnt_t)
idaman bool ida_export recalc_spd(ea_t cur_ea)
Recalculate SP delta for an instruction that stops execution.
idaman ssize_t ida_export build_stkvar_name(qstring *buf, const func_t *pfn, sval_t v)
Build automatic stack variable name.
ea_t frame_off_lvars(const func_t *pfn)
Get start address of local variables section.
Definition frame.hpp:187
idaman ea_t ida_export calc_stkvar_struc_offset(func_t *pfn, const insn_t &insn, int n)
Calculate offset of stack variable in the frame structure.
idaman func_t *ida_export get_func(ea_t ea)
Get pointer to function structure by address.
int code
Definition fpro.h:88
idaman size_t n
Definition pro.h:997
idaman int ida_export rename_regvar(func_t *pfn, regvar_t *v, const char *user)
Rename a register variable.
idaman void ida_export free_regvar(struct regvar_t *v)
idaman int ida_export add_regvar(func_t *pfn, ea_t ea1, ea_t ea2, const char *canon, const char *user, const char *cmt)
Define a register variable.
idaman regvar_t *ida_export find_regvar(func_t *pfn, ea_t ea1, ea_t ea2, const char *canon, const char *user)
Find a register variable definition (powerful version).
idaman int ida_export set_regvar_cmt(func_t *pfn, regvar_t *v, const char *cmt)
Set comment for a register variable.
idaman int ida_export del_regvar(func_t *pfn, ea_t ea1, ea_t ea2, const char *canon)
Delete a register variable definition.
bool has_regvar(func_t *pfn, ea_t ea)
Is there a register variable definition?
Definition frame.hpp:530
carglist_t * args
Definition hexrays.hpp:7323
Contains definition of the interface to IDP modules.
int nbytes
Definition kernwin.hpp:2861
uval_t uval_t
Definition kernwin.hpp:1878
uint64 asize_t
Definition pro.h:423
adiff_t sval_t
signed value used by the processor.
Definition pro.h:446
uint64 ea_t
Definition pro.h:421
unsigned char uchar
unsigned 8 bit value
Definition pro.h:337
idaman THREAD_SAFE char *ida_export qstrdup(const char *string)
System independent strdup.
unsigned int uint
unsigned 32 bit value
Definition pro.h:339
ptrdiff_t ssize_t
Signed size_t - used to check for size overflows when the counter becomes negative.
Definition pro.h:381
unsigned short ushort
unsigned 16 bit value
Definition pro.h:338
ea_t tid_t
type id (for enums, structs, etc)
Definition pro.h:5010
int compare_containers(const T &l, const T &r)
Template to compare any 2 containers of the same type. Returns -1/0/1.
Definition pro.h:4555
_qstring< char > qstring
regular string
Definition pro.h:3694
int compare(const T &a, const T &b)
Definition pro.h:4514
sval_t lvar_off(const func_t *pfn, uval_t frameoff) const
Does the given offset lie within the local variables section?
Definition frame.hpp:207
bool stkup(void) const
PR_STACK_UP
Definition idp.hpp:625
bool is_funcarg_off(const func_t *pfn, uval_t frameoff) const
Does the given offset lie within the arguments section?
Definition frame.hpp:196
Base class for an range.
Definition range.hpp:35
ea_t end_ea
end_ea excluded
Definition range.hpp:38
ea_t start_ea
start_ea included
Definition range.hpp:37
range_t(ea_t ea1=0, ea_t ea2=0)
Definition range.hpp:39
A register variable allows the user to rename a general processor register to a meaningful name.
Definition frame.hpp:440
char * canon
canonical register name (case-insensitive)
Definition frame.hpp:441
char * cmt
comment to appear near definition
Definition frame.hpp:443
regvar_t & operator=(const regvar_t &r)
Definition frame.hpp:453
~regvar_t()
Definition frame.hpp:452
char * user
user-defined register name
Definition frame.hpp:442
void swap(regvar_t &r)
Definition frame.hpp:462
regvar_t()
Definition frame.hpp:445
DECLARE_COMPARISONS(regvar_t)
regvar_t(const regvar_t &r)
Definition frame.hpp:446
Definition frame.hpp:59
ea_t ea
Definition frame.hpp:60
sval_t spd
Definition frame.hpp:61
DECLARE_COMPARISONS(stkpnt_t)
Definition frame.hpp:63
Definition frame.hpp:75
DECLARE_COMPARISONS(stkpnts_t)
Definition frame.hpp:76
Visual representation of a member of a complex type (struct/union/enum)
Definition typeinf.hpp:5202
An xref to an argument or variable located in a function's stack frame.
Definition frame.hpp:674
ea_t ea
Location of the insn referencing the stack frame member.
Definition frame.hpp:675
uchar type
The type of xref (cref_t & dref_t)
Definition frame.hpp:677
DECLARE_COMPARISONS(xreflist_entry_t)
Definition frame.hpp:679
uchar opnum
Number of the operand of that instruction.
Definition frame.hpp:676