IDA C++ SDK 9.2
Loading...
Searching...
No Matches
pro.h
Go to the documentation of this file.
1/*
2 * Interactive disassembler (IDA).
3 * Copyright (c) 1990-2026 Hex-Rays
4 * ALL RIGHTS RESERVED.
5 *
6 */
7
8#ifndef _PRO_H
9#define _PRO_H
10
34
36#define IDA_SDK_VERSION 940
37
38//---------------------------------------------------------------------------
39#if !defined(__NT__) && !defined(__LINUX__) && !defined(__MAC__)
40# if defined(_MSC_VER)
41# define __NT__
42# elif defined(__APPLE__)
43# define __MAC__
44# elif defined(__linux__)
45# define __LINUX__
46# else
47# error "Please define one of: __NT__, __LINUX__, __MAC__"
48# endif
49#endif
50
51// Linux or Mac imply Unix
52#if defined(__LINUX__) || defined(__MAC__)
53#ifndef __UNIX__
54#define __UNIX__
55#endif
56#endif
57
59#ifndef __X86__
60#define BADMEMSIZE 0x7FFFFFFFFFFFFFFFull
61#else
62#define BADMEMSIZE 0x7FFFFFFFu
63#endif
64
66#define ENUM_SIZE(t) : t
67
68// this is necessary to have S_IFMT, S_IFREG and S_IFDIR defined in windows
69// in order to define S_ISDIR and S_ISREG
70#define _CRT_DECLARE_NONSTDC_NAMES 1
71#ifndef SWIG
72#include <stdlib.h> /* size_t, nullptr, memory */
73#include <stdarg.h>
74#include <stddef.h>
75#include <stdio.h>
76#include <assert.h>
77#include <limits.h>
78#include <ctype.h>
79#include <time.h>
80#include <stdint.h>
81#ifdef __cplusplus
82#include <memory>
83#include <new>
84#include <string>
85#include <utility>
86#endif
87#if defined(__NT__)
88# include <malloc.h>
89#endif
90
92#if defined(_MSC_VER)
93# define WIN32_LEAN_AND_MEAN
94# include <string.h>
95# include <io.h>
96# include <direct.h>
97#else
98# include <wchar.h>
99# include <string.h>
100# include <unistd.h>
101# include <sys/stat.h>
102# include <errno.h>
103#endif
104#ifdef __cplusplus
105# include <set>
106# include <map>
107# include <algorithm>
108# include <initializer_list>
109#endif
110#include <fcntl.h>
111#include <sys/types.h>
112#include <sys/stat.h>
113
114#endif // SWIG
115
116#define STL_SUPPORT_PRESENT
117
118//---------------------------------------------------------------------------
123#if defined(__cplusplus) || defined(SWIG)
124#define EXTERNC extern "C"
125#define C_INCLUDE EXTERNC \
126 {
127
128#define C_INCLUDE_END }
129#define INLINE inline
130#else
131#define EXTERNC
132#define C_INCLUDE
133#define C_INCLUDE_END
134#define INLINE __inline
135#endif
136
137//---------------------------------------------------------------------------
138#ifndef MAXSTR
139#define MAXSTR 1024
140#endif
141
142#define SMAXSTR QSTRINGIZE(MAXSTR)
143
145#ifdef __NT__
146#define NT_CDECL __cdecl
147#else
148#define NT_CDECL
149#endif
150
158#if defined(SWIG)
159#define constexpr
160#define DEPRECATED
161#define NORETURN
162#define PACKED
163#define PACKED_ALIGNED(al)
164#define AS_STRFTIME(format_idx)
165#define AS_PRINTF(format_idx, varg_idx)
166#define AS_SCANF(format_idx, varg_idx)
167#define WARN_UNUSED_RESULT
168#elif defined(__GNUC__)
169#define DEPRECATED __attribute__((deprecated))
170#define NORETURN __attribute__((noreturn))
171#define PACKED __attribute__((__packed__))
172#define PACKED_ALIGNED(al) __attribute__((__packed__)) __attribute__((__aligned__(al)))
173#define AS_STRFTIME(format_idx) __attribute__((format(strftime, format_idx, 0)))
174#define AS_PRINTF(format_idx, varg_idx) __attribute__((format(printf, format_idx, varg_idx)))
175#define AS_SCANF(format_idx, varg_idx) __attribute__((format(scanf, format_idx, varg_idx)))
176#define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
177#else
178#define DEPRECATED __declspec(deprecated)
179#define NORETURN __declspec(noreturn)
180#define PACKED
181#define PACKED_ALIGNED(al)
182#define AS_STRFTIME(format_idx)
183#define AS_PRINTF(format_idx, varg_idx)
184#define AS_SCANF(format_idx, varg_idx)
185#define WARN_UNUSED_RESULT _Check_return_
186#endif
187
190#if defined(__GNUC__) && !defined(SWIG) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402
191#define GCC_DIAG_JOINSTR(x,y) _QSTRINGIZE(x ## y)
192# define GCC_DIAG_DO_PRAGMA(x) _Pragma (#x)
193# define GCC_DIAG_PRAGMA(x) GCC_DIAG_DO_PRAGMA(GCC diagnostic x)
194# if (((__GNUC__ * 100) + __GNUC_MINOR__) >= 406) || defined(__clang__)
195# define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(push) \
196 GCC_DIAG_PRAGMA(ignored GCC_DIAG_JOINSTR(-W,x))
197# define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(pop)
198# else
199# define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(ignored GCC_DIAG_JOINSTR(-W,x))
200# define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(warning GCC_DIAG_JOINSTR(-W,x))
201# endif
202#else
203# define GCC_DIAG_OFF(x)
204# define GCC_DIAG_ON(x)
205#endif
206
207#if defined(_MSC_VER) && !defined(SWIG)
208# define MSC_DIAG_OFF(x) __pragma(warning(push)) \
209 __pragma(warning(disable : x))
210# define MSC_DIAG_ON(x) __pragma(warning(pop))
211#else
212# define MSC_DIAG_OFF(x)
213# define MSC_DIAG_ON(x)
214#endif
215
216// A function attribute to disable ASAN
217#if defined(__clang__) || defined (__GNUC__)
218# define DISABLE_ASAN __attribute__((no_sanitize_address))
219#else
220# define DISABLE_ASAN
221#endif
222
223#if defined(DONT_DEPRECATE)
224#undef DEPRECATED
225#define DEPRECATED
226#endif
227
228//---------------------------------------------------------------------------
229
230#define __MF__ 0
233
234//---------------------------------------------------------------------------
236#define qnotused(x) (void)x
237
238#ifdef __clang__
239# define NONNULL _Nonnull
240#else
241# define NONNULL
242#endif
243
244// this macro can be used as a suffix for declarations/definitions instead of qnotused()
245#if defined(__clang__) || defined(__GNUC__)
246# define QUNUSED __attribute__((unused))
247#else
248# define QUNUSED
249#endif
250
252#ifdef __GNUC__
253#define va_argi(va, type) ((type)va_arg(va, int))
254#else
255#define va_argi(va, type) va_arg(va, type)
256#endif
257
258//---------------------------------------------------------------------------
259#define CONST_CAST(x) const_cast<x>
260#define _QSTRINGIZE(x) #x
261#define QSTRINGIZE(x) _QSTRINGIZE(x)
262
263//---------------------------------------------------------------------------
264
271#if defined(SWIG) // for SWIG
272 #define idaapi
273 #define idaman
274 #define ida_export
275 #define ida_export_data
276 #define ida_module_data
277 #define __fastcall
278 #define ida_local
279#elif defined(APIDEF) // for API DEF files
280 #define idaapi
281 #define idaman
282 #define ida_export ida_export
283 #define ida_export_data ida_export_data
284 #define ida_module_data
285 #define __fastcall
286 #define ida_local
287#elif defined(__NT__) // MS Windows
288 #define idaapi __stdcall
289 #define ida_export idaapi
290 #ifdef __CODE_CHECKER__
291 // tell lint that this function will be exported
292 #define idaman EXTERNC __declspec(dllexport)
293 #else
294 #define idaman EXTERNC
295 #endif
296 #if defined(__KERNEL__) // kernel
297 #define ida_export_data
298 #define ida_module_data
299 #else // modules
300 #define ida_export_data __declspec(dllimport)
301 #define ida_module_data __declspec(dllexport)
302 #endif
303 #define ida_local
304#elif defined(__UNIX__) // for unix
305 #define idaapi
306 #if defined(__MAC__)
307 #define idaman EXTERNC __attribute__((visibility("default")))
308 #define ida_local __attribute__((visibility("hidden")))
309 #else
310 #if __GNUC__ >= 4
311 #define idaman EXTERNC __attribute__ ((visibility("default")))
312 #define ida_local __attribute__((visibility("hidden")))
313 #else
314 #define idaman EXTERNC
315 #define ida_local
316 #endif
317 #endif
318 #define ida_export
319 #define ida_export_data
320 #define ida_module_data
321 #define __fastcall
322#endif
323
325#define THREAD_SAFE
326
329#define newapi
330
331//---------------------------------------------------------------------------
332#ifndef __cplusplus
333typedef int bool;
334#define false 0
335#define true 1
336#endif
337
338//---------------------------------------------------------------------------
339// Linux C mode compiler already has these types defined
340#if !defined(__LINUX__) || defined(__cplusplus)
341typedef unsigned char uchar;
342typedef unsigned short ushort;
343typedef unsigned int uint;
344#endif
345
346typedef char int8;
347typedef signed char sint8;
348typedef unsigned char uint8;
349typedef short int16;
350typedef unsigned short uint16;
351typedef int int32;
352typedef unsigned int uint32;
353
354#include <llong.hpp>
355
356
358#if defined(__UNIX__)
359INLINE int64 qatoll(const char *nptr) { return nptr != nullptr ? atoll(nptr) :0; }
360#elif defined(_MSC_VER)
361INLINE int64 qatoll(const char *nptr) { return nptr != nullptr ? _atoi64(nptr) :0; }
362#else
363INLINE int64 qatoll(const char *nptr) { return nptr != nullptr ? atol(nptr) : 0; }
364#endif
365
366// VS2010 lacks strtoull
367#ifdef _MSC_VER
368#define strtoull _strtoui64
369#endif
370
373#if defined(_MSC_VER)
374typedef wchar_t wchar16_t;
376#elif defined(__GNUC__)
377typedef uint16 wchar16_t;
378typedef uint32 wchar32_t;
379#endif
380
384#if !defined(_SSIZE_T_DEFINED) && !defined(__ssize_t_defined) && !defined(__GNUC__)
385typedef ptrdiff_t ssize_t;
386#endif
387
392#if defined(__GNUC__) && !defined(__MINGW32__)
393 #define FMT_64 "ll"
394 #define FMT_Z "zu"
395 #define FMT_ZX "zX"
396 #define FMT_ZS "zd"
397#elif defined(_MSC_VER) && _MSC_VER >= 1900
398 #define FMT_64 "I64"
399 #define FMT_Z "zu"
400 #define FMT_ZX "zX"
401 #define FMT_ZS "td"
402#elif defined(_MSC_VER) || defined(__MINGW32__)
403 #define FMT_64 "I64"
404 #ifndef __X86__
405 #define FMT_Z "I64u"
406 #define FMT_ZX "I64X"
407 #define FMT_ZS "I64d"
408 #else
409 #define FMT_Z "u"
410 #define FMT_ZX "X"
411 #define FMT_ZS "d"
412 #endif
413#elif !defined(SWIG)
414 #error "unknown compiler"
415#endif
416
424#ifdef __EA64__
425 typedef uint64 ea_t;
426 typedef uint64 sel_t;
428 typedef int64 adiff_t;
429 #define FMT_EA FMT_64
430 #ifdef __GNUC__
431 #define SVAL_MIN LLONG_MIN
432 #define SVAL_MAX LLONG_MAX
433 #else
434 #define SVAL_MIN _I64_MIN
435 #define SVAL_MAX _I64_MAX
436 #endif
437#else
438 typedef uint32 ea_t;
439 typedef uint32 sel_t;
440 typedef uint32 asize_t;
441 typedef int32 adiff_t;
442 #define SVAL_MIN INT_MIN
443 #define SVAL_MAX INT_MAX
444 #define FMT_EA ""
445#endif
446
453
454typedef uint32 ea32_t;
457typedef uint64 ea64_t;
460
462typedef int error_t;
463
465
469
470// A position in the difference source.
471// This is an abstract value that depends on the difference source.
472// It should be something that can be used to conveniently retrieve information
473// from a difference source. For example, for the name list it can be the index
474// in the name list. For structure view it can be the position in the list of structs.
475// Please note that this is not necessarily an address. However, for the purpose
476// of comparing the contents of the disassembly listing it can be an address.
477//
478// diffpos_t instances must have the following property: adding or removing
479// items to diff_source_t should not invalidate the existing diffpos_t instances.
480// They must stay valid after adding or removing items to diff_source_t.
481// Naturally, deleting an item pointed by diffpos_t may render it incorrect,
482// this is acceptable and expected.
483typedef size_t diffpos_t;
485
486#ifdef __cplusplus
487#define DEFARG(decl, val) decl = val
488#else
489#define DEFARG(decl, val) decl
490#endif
491
492#ifndef SWIG
493#define BADADDR ea_t(-1)
494#define BADSEL sel_t(-1)
495#define BADADDR32 ea32_t(-1)
496#define BADADDR64 ea64_t(-1)
497
498//-------------------------------------------------------------------------
499// Time related functions
500
505
507
508INLINE THREAD_SAFE uint32 get_secs(qtime64_t t)
509{
510 return (uint32)(t>>32);
511}
512
513
515
516INLINE THREAD_SAFE uint32 get_usecs(qtime64_t t)
517{
518 return (uint32)(t);
519}
520
521
525
526INLINE THREAD_SAFE qtime64_t make_qtime64(uint32 secs, DEFARG(int32 usecs, 0))
527{
528 return ((qtime64_t)(secs) << 32) | usecs;
529}
530
531
539
540idaman THREAD_SAFE bool ida_export qctime(char *buf, size_t bufsize, qtime32_t t);
541
542
550
551idaman THREAD_SAFE bool ida_export qctime_utc(char *buf, size_t bufsize, qtime32_t t);
552
553
558
559idaman THREAD_SAFE bool ida_export qlocaltime(struct tm *_tm, time_t t);
560
561
563
564INLINE THREAD_SAFE bool qlocaltime64(struct tm *_tm, qtime64_t t)
565{
566 return qlocaltime(_tm, get_secs(t));
567}
568
569
574
575idaman bool ida_export qgmtime(struct tm *_tm, time_t t);
576
577
579
580INLINE THREAD_SAFE bool qgmtime64(struct tm *_tm, qtime64_t t)
581{
582 return qgmtime(_tm, get_secs(t));
583}
584
585
586// Inverse of qgmtime()
587
588idaman time_t ida_export qtimegm(const struct tm *ptm);
589
590
601
602idaman AS_STRFTIME(3) THREAD_SAFE size_t ida_export qstrftime(
603 char *buf,
604 size_t bufsize,
605 const char *format,
606 time_t t);
607
608
610
611idaman AS_STRFTIME(3) THREAD_SAFE size_t ida_export qstrftime64(
612 char *buf,
613 size_t bufsize,
614 const char *format,
615 qtime64_t t);
616
617
619
620idaman THREAD_SAFE void ida_export qsleep(int milliseconds);
621
622
627
628idaman THREAD_SAFE uint64 ida_export get_nsec_stamp(void);
629
632
633idaman THREAD_SAFE qtime64_t ida_export qtime64(void);
634
635
640
641idaman THREAD_SAFE bool ida_export gen_rand_buf(void *buffer, size_t bufsz);
642
643
644#define qoff64_t int64
645
663
664// non standard functions are missing:
665#ifdef _MSC_VER
666#if _MSC_VER <= 1200
667# define for if(0); else for
668#else
669# pragma warning(disable : 4200)
670# if _MSC_VER >= 1921 && _MSC_VER < 1924 // avoid compiler bug:
671# pragma function(memmove) // https://developercommunity.visualstudio.com/content/problem/583227/vs-2019-cl-1921277022-memmove-instrinsic-optimizat.html
672# endif
673#endif
677#define chdir _chdir
678#define fileno _fileno
679#define getcwd _getcwd
680#define memicmp _memicmp
681# define F_OK 0
682# define W_OK 2
683# define R_OK 4
685#endif
686
687//---------------------------------------------------------------------------
688/* error codes */
689/*--------------------------------------------------*/
690
691#define eOk 0
692#define eOS 1
693#define eDiskFull 2
694#define eReadError 3
695#define eFileTooLarge 4
696
697
699
700idaman THREAD_SAFE error_t ida_export set_qerrno(error_t code);
701
702
704
705idaman THREAD_SAFE error_t ida_export get_qerrno(void);
706
707//---------------------------------------------------------------------------
708// debugging macros
711#define ZZZ msg("%s:%d\n", __FILE__, __LINE__)
712#if defined(__GNUC__)
713# define BPT __builtin_trap()
714#elif defined(_MSC_VER) // Visual C++
715# define BPT __debugbreak()
716# ifdef __CODE_CHECKER__
717 NORETURN void __debugbreak(void);
718# endif
719#endif
720
722#ifdef __CODE_CHECKER__
723#define CASSERT(cnd) static_assert((cnd), "")
724#else
725#define CASSERT(cnd) static_assert((cnd), QSTRINGIZE(cnd))
726#endif
727
731#ifdef __CODE_CHECKER__
732#define INTERR(code) interr(code)
733#else
734#define INTERR(code) do { if ( under_debugger ) BPT; interr(code); } while(1)
735#endif
736
737#define QASSERT(code, cond) do if ( !(cond) ) INTERR(code); while (0)
738#define QBUFCHECK(buf, size, src) ida_fill_buffer(buf, size, src, __FILE__, __LINE__)
740
741#ifdef TESTABLE_BUILD
742# define TB_QASSERT(Code, Expr) QASSERT(Code, Expr)
743# define TB_INTERR(Code) INTERR(Code)
744# define TB_CCHECK(expr) if ( !(expr) ) warning("Coherency check failed at %s:%d: " #expr, __FILE__, __LINE__)
745# define TB_INTERR_OR_RETURN(code, ...) INTERR(code)
746#else
747# define TB_QASSERT(Code, Expr)
748# define TB_INTERR(Code)
749# define TB_CCHECK(expr) if ( !(expr) ) msg("Coherency check failed: " #expr "\n")
750# define TB_INTERR_OR_RETURN(code, ...) return __VA_ARGS__
751#endif
752
753#define INTERR_EXC_FMT "Internal error %d occurred when running a script. Either\n" \
754 " - the script misused the IDA API, or\n" \
755 " - there is a logic error in IDA\n" \
756 "Please check the script first.\n" \
757 "If it appears correct, send a bug report to <support@hex-rays.com>.\n" \
758 "In any case we strongly recommend you to restart IDA as soon as possible."
759
760#ifdef __cplusplus
761struct interr_exc_t : public std::exception
762{
763 int code;
764 interr_exc_t(int _code) : code(_code) {}
765};
766#endif // __cplusplus
767idaman THREAD_SAFE NORETURN void ida_export interr(int code);
768
769// set the behavior of 'interr()'
773idaman THREAD_SAFE bool ida_export set_interr_throws(bool enable);
774
775//---------------------------------------------------------------------------
776idaman THREAD_SAFE void *ida_export qalloc(size_t size);
777idaman THREAD_SAFE void *ida_export qrealloc(void *alloc, size_t newsize);
778idaman THREAD_SAFE void *ida_export qcalloc(size_t nitems, size_t itemsize);
779idaman THREAD_SAFE void ida_export qfree(void *alloc);
780idaman THREAD_SAFE char *ida_export qstrdup(const char *string);
781#define qnew(t) ((t*)qalloc(sizeof(t)))
783#define qnewarray(t,n) use_qalloc_array
784
786#ifdef __cplusplus
787template <class T>
788T *qalloc_array(size_t n)
789{
790 return (T *)qcalloc(n, sizeof(T));
791}
792
794template <class T>
795T *qrealloc_array(T *ptr, size_t n)
796{
797 size_t nbytes = n * sizeof(T);
798 if ( nbytes < n )
799 return nullptr; // integer overflow
800 return (T *)qrealloc(ptr, nbytes);
801}
802
804#ifdef __GNUC__
805# define qnumber(arr) ( \
806 0 * sizeof(reinterpret_cast<const ::qnumber_check_type *>(arr)) \
807 + 0 * sizeof(::qnumber_check_type::check_type((arr), &(arr))) \
808 + sizeof(arr) / sizeof((arr)[0]) )
810 {
811 struct is_pointer;
812 struct is_array {};
813 template <typename T>
814 static is_pointer check_type(const T *, const T *const *);
815 static is_array check_type(const void *, const void *);
816 };
817#elif defined(_MSC_VER) && !defined(__CODE_CHECKER__)
818# define qnumber(array) _countof(array)
819#else // poor man's implementation for other compilers and lint
820# define qnumber(array) (sizeof(array)/sizeof(array[0]))
821#endif
822#endif // __cplusplus
823
824#define qoffsetof offsetof
825
828#if defined(__GNUC__) && !defined(__X86__) && !(defined(__clang__) && defined(__ARM__))
829 // gcc64 and clang x86_64 use special array-type va_list, so we have to resort to tricks like these
830 #define set_vva(va2, vp) va_copy(va2, *(va_list*)va_arg(vp, void*))
831#else
832 #ifndef va_copy
833 #define va_copy(dst, src) dst = src
834 #endif
835 #if defined(__clang__)
836 #define set_vva(va2, vp) va2 = va_arg(vp, va_list)
837 #else
838 #define set_vva(va2, vp) va_copy(va2, va_arg(vp, va_list))
839 #endif
840#endif
841
842#if defined(__LINUX__) && defined(__ARM__)
843# define NULL_VA_LIST() va_list()
844#else
845# define NULL_VA_LIST() nullptr
846#endif
847
853
854idaman THREAD_SAFE void *ida_export memrev(void *buf, ssize_t size);
855
856#if defined(__GNUC__) && !defined(_WIN32)
857idaman THREAD_SAFE int ida_export memicmp(const void *x, const void *y, size_t size);
858#endif
859
860//---------------------------------------------------------------------------
861/* strings */
864#ifdef __GNUC__
865#define strnicmp strncasecmp
866#define stricmp strcasecmp
867#elif defined(_MSC_VER)
868#define strnicmp _strnicmp
869#define stricmp _stricmp
870#endif
871
872
878
879idaman THREAD_SAFE char *ida_export strrpl(char *str, int char1, int char2);
880
881
883INLINE THREAD_SAFE char *tail(char *str) { return strchr(str, '\0'); }
884#ifdef __cplusplus
886inline THREAD_SAFE const char *tail(const char *str) { return strchr(str, '\0'); }
887#endif
888
889
893
894idaman THREAD_SAFE char *ida_export qstrncpy(char *dst, const char *src, size_t dstsize);
895
896
899
900idaman THREAD_SAFE char *ida_export qstpncpy(char *dst, const char *src, size_t dstsize);
901
902
905
906idaman THREAD_SAFE char *ida_export qstrncat(char *dst, const char *src, size_t dstsize);
907
908
910
911idaman THREAD_SAFE char *ida_export qstrtok(char *s, const char *delim, char **save_ptr);
912
913
915
916idaman THREAD_SAFE char *ida_export qstrlwr(char *str);
917
918
920
921idaman THREAD_SAFE char *ida_export qstrupr(char *str);
922
923
928
929idaman THREAD_SAFE const char *ida_export stristr(const char *s1, const char *s2);
930
931
932#ifdef __cplusplus
934inline char *idaapi stristr(char *s1, const char *s2) { return CONST_CAST(char *)(stristr((const char *)s1, s2)); }
935#endif
936
941INLINE THREAD_SAFE bool ida_local qisascii(char c) { return (c & ~0x7f) == 0; }
942INLINE THREAD_SAFE bool ida_local qisspace(char c) { return qisascii(c) && isspace((uchar)(c)) != 0; }
943INLINE THREAD_SAFE bool ida_local qisalpha(char c) { return qisascii(c) && isalpha((uchar)(c)) != 0; }
944INLINE THREAD_SAFE bool ida_local qisalnum(char c) { return qisascii(c) && isalnum((uchar)(c)) != 0; }
945INLINE THREAD_SAFE bool ida_local qispunct(char c) { return qisascii(c) && ispunct((uchar)(c)) != 0; }
946INLINE THREAD_SAFE bool ida_local qislower(char c) { return qisascii(c) && islower((uchar)(c)) != 0; }
947INLINE THREAD_SAFE bool ida_local qisupper(char c) { return qisascii(c) && isupper((uchar)(c)) != 0; }
948INLINE THREAD_SAFE bool ida_local qisprint(char c) { return qisascii(c) && isprint((uchar)(c)) != 0; }
949INLINE THREAD_SAFE bool ida_local qisdigit(char c) { return qisascii(c) && isdigit((uchar)(c)) != 0; }
950INLINE THREAD_SAFE bool ida_local qisxdigit(char c) { return qisascii(c) && isxdigit((uchar)(c)) != 0; }
952
954INLINE THREAD_SAFE int ida_local qtolower(char c) { return tolower((uchar)(c)); }
956INLINE THREAD_SAFE int ida_local qtoupper(char c) { return toupper((uchar)(c)); }
957
958// We forbid using dangerous functions in IDA
959#if !defined(USE_DANGEROUS_FUNCTIONS) && !defined(__CODE_CHECKER__)
960#undef strcpy
961#define strcpy dont_use_strcpy
962#define stpcpy dont_use_stpcpy
963#define strncpy dont_use_strncpy
964#define strcat dont_use_strcat
965#define strncat dont_use_strncat
966#define gets dont_use_gets
967#define sprintf dont_use_sprintf
968#define snprintf dont_use_snprintf
969#define wsprintfA dont_use_wsprintf
970#undef strcmpi
971#undef strncmpi
972#define strcmpi dont_use_strcmpi
973#define strncmpi dont_use_strncmpi
974#define getenv dont_use_getenv
975#define setenv dont_use_setenv
976#define putenv dont_use_putenv
977#define strtok dont_use_strtok
978#undef strlwr
979#undef strupr
980#define strlwr dont_use_strlwr
981#define strupr dont_use_strupr
982#define waitid dont_use_waitid
983#define waitpid dont_use_waitpid
984#endif
985
986//---------------------------------------------------------------------------
1000idaman AS_PRINTF(3, 4) THREAD_SAFE int ida_export qsnprintf(char *buffer, size_t n, const char *format, ...);
1001idaman AS_SCANF (2, 3) THREAD_SAFE int ida_export qsscanf(const char *input, const char *format, ...);
1002idaman AS_PRINTF(3, 0) THREAD_SAFE int ida_export qvsnprintf(char *buffer, size_t n, const char *format, va_list va);
1003idaman AS_SCANF (2, 0) THREAD_SAFE int ida_export qvsscanf(const char *input, const char *format, va_list va);
1004idaman AS_PRINTF(3, 4) THREAD_SAFE int ida_export append_snprintf(char *buf, const char *end, const char *format, ...);
1006
1007//---------------------------------------------------------------------------
1013INLINE int nowarn_qsnprintf(char *buf, size_t size, const char *format, ...)
1014{
1015 va_list va;
1016 int code;
1017 va_start(va, format);
1018#ifdef __cplusplus
1019 code = ::qvsnprintf(buf, size, format, va);
1020#else
1021 code = qvsnprintf(buf, size, format, va);
1022#endif
1023 va_end(va);
1024 return code;
1025}
1027
1028//---------------------------------------------------------------------------
1031#if defined(__NT__)
1032#define QMAXPATH 260
1033#define QMAXFILE 260
1034#else
1035#define QMAXPATH PATH_MAX
1036#define QMAXFILE PATH_MAX
1037#endif
1038
1039idaman THREAD_SAFE char *ida_export vqmakepath(char *buf, size_t bufsize, const char *s1, va_list);
1040
1041
1048
1049idaman THREAD_SAFE char *ida_export qmakepath(char *buf, size_t bufsize, const char *s1, ...);
1050
1051
1056
1057idaman void ida_export qgetcwd(char *buf, size_t bufsize);
1058
1059
1063
1064idaman int ida_export qchdir(const char *path);
1065
1066
1075
1076idaman THREAD_SAFE bool ida_export qdirname(char *buf, size_t bufsize, const char *path);
1077
1078
1085
1086idaman THREAD_SAFE char *ida_export qmakefile(
1087 char *buf,
1088 size_t bufsize,
1089 const char *base,
1090 const char *ext);
1091
1092
1098
1099idaman THREAD_SAFE char *ida_export qsplitfile(char *file, char **base, char **ext);
1100
1101
1103
1104idaman THREAD_SAFE bool ida_export qisabspath(const char *file);
1105
1106
1109
1110idaman THREAD_SAFE const char *ida_export qbasename(const char *path);
1111
1112#ifdef __cplusplus
1114inline char *qbasename(char *path) { return CONST_CAST(char *)(qbasename((const char *)path)); }
1115#endif
1116
1117
1119
1120idaman THREAD_SAFE char *ida_export qmake_full_path(char *dst, size_t dstsize, const char *src);
1121
1122
1130
1131idaman THREAD_SAFE bool ida_export search_path(
1132 char *buf,
1133 size_t bufsize,
1134 const char *file,
1135 bool search_cwd);
1136
1138#if defined(__UNIX__)
1139#define DELIMITER ":"
1140#else
1141#define DELIMITER ";"
1142#endif
1143
1144
1152
1153idaman THREAD_SAFE char *ida_export set_file_ext(
1154 char *outbuf,
1155 size_t bufsize,
1156 const char *file,
1157 const char *ext);
1158
1159
1163
1164idaman THREAD_SAFE const char *ida_export get_file_ext(const char *file);
1165
1167#ifdef __cplusplus
1168inline THREAD_SAFE bool idaapi has_file_ext(const char *file)
1169 { return get_file_ext(file) != nullptr; }
1170#endif
1171
1172
1181
1182#ifdef __cplusplus
1183inline THREAD_SAFE char *idaapi make_file_ext(
1184 char *buf,
1185 size_t bufsize,
1186 const char *file,
1187 const char *ext)
1188{
1189 if ( has_file_ext(file) )
1190 return ::qstrncpy(buf, file, bufsize);
1191 else
1192 return set_file_ext(buf, bufsize, file, ext);
1193}
1194#endif
1195
1196
1202
1203idaman THREAD_SAFE bool ida_export sanitize_file_name(char *name, size_t namesize);
1204
1205
1211
1212bool wildcard_match(const char *name, const char *pattern);
1213
1214
1221
1222bool wildcard_path_match(const char *name, const char *_pattern, int flags=0);
1223
1224#define WPM_EXPLICIT_DOT 0x01 // match dots at the beginning of a path component explicitly
1225 // example: with this bit set,
1226 // * does not match .hidden
1227 // .* matches .hidden
1228 // * matches file.ext
1229
1234
1235idaman int ida_export regex_match(const char *str, const char *pattern, bool sense_case);
1236
1237
1238//---------------------------------------------------------------------------
1239/* input/output */
1240/*--------------------------------------------------*/
1241#if !defined(__NT__) && !defined(_MSC_VER)
1242#define O_BINARY 0
1243#endif
1244
1245#ifndef SEEK_SET
1246# define SEEK_SET 0
1247# define SEEK_CUR 1
1248# define SEEK_END 2
1249#endif
1250
1251#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
1252 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
1253#endif
1254#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
1255 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
1256#endif
1257
1258/*--------------------------------------------------*/
1259/* you should use these functions for file i/o */
1260
1263
1264idaman THREAD_SAFE int ida_export qopen(const char *file, int mode);
1265
1266
1268
1269idaman THREAD_SAFE int ida_export qopen_shared(const char *file, int mode, int share_mode);
1270
1271
1273
1274idaman THREAD_SAFE int ida_export qcreate(const char *file, int stat);
1275
1276idaman THREAD_SAFE int ida_export qread(int h, void *buf, size_t n);
1277idaman THREAD_SAFE int ida_export qwrite(int h, const void *buf, size_t n);
1278idaman THREAD_SAFE qoff64_t ida_export qtell(int h);
1279idaman THREAD_SAFE qoff64_t ida_export qseek(int h, int64 offset, int whence);
1280idaman THREAD_SAFE int ida_export qclose(int h);
1281idaman THREAD_SAFE int ida_export qdup(int h);
1282idaman THREAD_SAFE int ida_export qfsync(int h);
1283
1284
1287
1288idaman THREAD_SAFE uint64 ida_export qfilesize(const char *fname);
1289
1293
1294idaman THREAD_SAFE uint64 ida_export qfilelength(int h);
1295
1301
1302idaman THREAD_SAFE int ida_export qchsize(int h, uint64 fsize);
1303
1310
1311idaman THREAD_SAFE int ida_export qmkdir(const char *file, int mode);
1312
1318
1319idaman THREAD_SAFE int ida_export qrmdir(const char *file);
1320
1322
1323idaman THREAD_SAFE bool ida_export qfileexist(const char *file);
1324
1325
1327
1328idaman THREAD_SAFE bool ida_export qisdir(const char *file);
1329
1331idaman THREAD_SAFE int ida_export qstat(const char *path, struct qstatbuf *buf);
1332idaman THREAD_SAFE int ida_export qfstat(int fd, struct qstatbuf *buf);
1333
1335
1336idaman THREAD_SAFE int ida_export qtouchfile(const char *file_name);
1337
1338//---------------------------------------------------------------------------
1340
1341idaman THREAD_SAFE void ida_export qatexit(void (idaapi *func)(void));
1342
1343
1345
1346idaman THREAD_SAFE void ida_export del_qatexit(void (idaapi*func)(void));
1347
1348#endif // SWIG
1349
1350
1353
1354idaman THREAD_SAFE NORETURN void ida_export qexit(int code);
1355
1356//---------------------------------------------------------------------------
1357#define qmin(a,b) ((a) < (b)? (a): (b))
1358#define qmax(a,b) ((a) > (b)? (a): (b))
1359#ifdef __cplusplus
1360template <class T> T qabs(T x) { return x < 0 ? -x : x; }
1361#else
1362int qabs(int x) { return x < 0 ? -x : x; }
1363#endif
1364
1365//----------------------------------------------------------------------
1367INLINE THREAD_SAFE bool idaapi test_bit(const uchar *bitmap, size_t bit)
1368{
1369 return (bitmap[bit/8] & (1<<(bit&7))) != 0;
1370}
1371
1372INLINE THREAD_SAFE void idaapi set_bit(uchar *bitmap, size_t bit)
1373{
1374 uchar *p = bitmap + bit/8;
1375 *p = (uchar)(*p | (1<<(bit&7)));
1376}
1377
1378INLINE THREAD_SAFE void idaapi clear_bit(uchar *bitmap, size_t bit)
1379{
1380 uchar *p = bitmap + bit/8;
1381 *p = (uchar)(*p & ~(1<<(bit&7)));
1382}
1383
1384INLINE THREAD_SAFE void idaapi set_bits(uchar *bitmap, size_t low, size_t high)
1385{
1386 size_t bit;
1387 for ( bit = low; bit < high; ++bit )
1388 set_bit(bitmap, bit);
1389}
1390
1391INLINE THREAD_SAFE void idaapi clear_bits(uchar *bitmap, size_t low, size_t high)
1392{
1393 size_t bit;
1394 for ( bit = low; bit < high; ++bit )
1395 clear_bit(bitmap, bit);
1396}
1397
1398INLINE THREAD_SAFE void idaapi set_all_bits(uchar *bitmap, size_t nbits)
1399{
1400 memset(bitmap, 0xFF, nbits/8);
1401 if ( (nbits & 7) != 0 )
1402 {
1403 uchar *p = bitmap + nbits/8;
1404 *p |= ((1 << (nbits&7))-1);
1405 }
1406}
1407
1408INLINE THREAD_SAFE void idaapi clear_all_bits(uchar *bitmap, size_t nbits)
1409{
1410 memset(bitmap, 0, nbits/8);
1411 if ( (nbits & 7) != 0 )
1412 {
1413 uchar *p = bitmap + nbits/8;
1414 *p &= ~((1 << (nbits&7))-1);
1415 }
1416}
1417
1420idaman int ida_export log2ceil(uint64 d64);
1421idaman int ida_export log2floor(uint64 d64);
1422
1424idaman int ida_export bitcount(uint64 x);
1425
1428idaman int ida_export bitcountr_zero(uint64 x);
1429
1431idaman size_t ida_export round_up_power2(size_t x);
1432idaman size_t ida_export round_down_power2(size_t x);
1433
1435template <class T> constexpr bool is_pow2(T val)
1436{
1437 return ((val - 1) & val) == 0;
1438}
1439
1441template <class T> T round_up(T val, T base)
1442{
1443 T r = val % base;
1444 return r != 0 ? val + base - r : val;
1445}
1446template <class T> T round_down(T val, T base)
1447{
1448 return val - val % base;
1449}
1450
1451#ifdef __cplusplus
1452//----------------------------------------------------------------------
1454namespace interval
1455{
1457 inline THREAD_SAFE constexpr uval_t last(uval_t off, asize_t s)
1458 {
1459 return off + s - 1;
1460 }
1461
1462 inline THREAD_SAFE constexpr bool overlap(uval_t off1, asize_t s1, uval_t off2, asize_t s2)
1463 {
1464 return s1 != 0 && s2 != 0 && off2 <= last(off1, s1) && off1 <= last(off2, s2);
1465 }
1466
1467 inline THREAD_SAFE constexpr bool includes(uval_t off1, asize_t s1, uval_t off2, asize_t s2)
1468 {
1469 return s1 != 0 && off2 >= off1 && last(off2, s2) <= last(off1, s1);
1470 }
1471
1472 inline THREAD_SAFE constexpr bool contains(uval_t off1, asize_t s1, uval_t off)
1473 {
1474 return s1 != 0 && off >= off1 && off <= last(off1, s1);
1475 }
1476}
1477#endif
1478
1479//----------------------------------------------------------------------
1480#ifdef __cplusplus
1484template <class T> constexpr T left_shift(const T &value, int shift)
1485{
1486 return shift >= sizeof(T)*8 ? 0 : (value << shift);
1487}
1488
1489template <class T> constexpr T right_ushift(const T &value, int shift)
1490{
1491 return shift >= sizeof(T)*8 ? 0 : (value >> shift);
1492}
1493
1494template <class T> constexpr T right_sshift(const T &value, int shift)
1495{
1496 return shift >= sizeof(T)*8 ? (value >= 0 ? 0 : -1) : (value >> shift);
1497}
1498
1500template<class T> T qrotl(T value, size_t count)
1501{
1502 const size_t nbits = sizeof(T) * 8;
1503 count %= nbits;
1504
1505 T high = value >> (nbits - count);
1506 value <<= count;
1507 value |= high;
1508 return value;
1509}
1510
1512template<class T> T qrotr(T value, size_t count)
1513{
1514 const size_t nbits = sizeof(T) * 8;
1515 count %= nbits;
1516
1517 T low = value << (nbits - count);
1518 value >>= count;
1519 value |= low;
1520 return value;
1521}
1522
1524template <class T> constexpr T make_mask(int count)
1525{
1526 return left_shift<T>(1, count) - 1;
1527}
1528
1530template<class T, class U> void idaapi setflag(T &where, U bit, bool cnd)
1531{
1532 if ( cnd )
1533 where = T(where | bit);
1534 else
1535 where = T(where & ~T(bit));
1536}
1537
1539template<class T> bool is_mul_ok(T count, T elsize)
1540{
1541 CASSERT((T)(-1) > 0); // make sure T is unsigned
1542 if ( elsize == 0 || count == 0 )
1543 return true;
1544 return count <= ((T)(-1)) / elsize;
1545}
1546
1548template<class U, class T> bool is_add_ok(U x, T y)
1549{
1550 CASSERT((U)(-1) > 0); // make sure U is unsigned
1551 return y >= 0 ? (U)y <= ((U)(-1)) - x : (U)(0-y) <= x;
1552}
1553
1555template <class T> bool is_udiv_ok(T, T b)
1556{
1557 CASSERT((T)(-1) > 0); // make sure T is unsigned
1558 return b != 0; // forbid x/0
1559}
1560
1562template <class T> bool is_sdiv_ok(T a, T b)
1563{
1564 CASSERT((T)(-1) < 0); // make sure T is signed
1565 T minval = left_shift((T)1, sizeof(T)*8-1);
1566 return b != 0 && !(a == minval && b == -1); // forbid x/0, MINVAL/-1
1567}
1568
1571template <typename T>
1572inline THREAD_SAFE constexpr T extend_sign_bits(T v, int nbits)
1573{
1574 if ( nbits <= 0 )
1575 return 0;
1576 if ( nbits >= sizeof(T) * 8 )
1577 return v;
1578 T signbit = T(1) << (nbits - 1);
1579 T mask = (signbit << 1) - 1;
1580 if ( (v & signbit) != 0 )
1581 v |= ~mask;
1582 else
1583 v &= mask;
1584 return v;
1585}
1586
1590#ifdef __GNUC__
1591# define OPERATOR_NEW(type, count) (is_mul_ok(size_t(count), sizeof(type)) \
1592 ? new type[count] \
1593 : (type *)qalloc_or_throw(BADMEMSIZE))
1594#else
1595# define OPERATOR_NEW(type, count) new type[count]
1596#endif
1597
1598#endif // __cplusplus
1599
1600//-------------------------------------------------------------------------
1603
1604idaman uint64 ida_export extend_sign(uint64 v, int nbytes, bool sign_extend);
1605
1606
1608#define MC2(c1, c2) ushort(((c2)<<8)|c1)
1609#define MC3(c1, c2, c3) uint32(((((c3)<<8)|(c2))<<8)|c1)
1610#define MC4(c1, c2, c3, c4) uint32(((((((c4)<<8)|(c3))<<8)|(c2))<<8)|c1)
1611
1612
1613//---------------------------------------------------------------------------
1620
1621idaman THREAD_SAFE int ida_export readbytes(int h, uint32 *res, int size, bool mf);
1622
1623
1630
1631idaman THREAD_SAFE int ida_export writebytes(int h, uint32 l, int size, bool mf);
1632
1633
1639
1640idaman THREAD_SAFE int ida_export read2bytes(int h, uint16 *res, bool mf);
1641
1642#define read4bytes(h, res, mf) readbytes(h, res, 4, mf)
1643#define write2bytes(h, l, mf) writebytes(h, l, 2, mf)
1644#define write4bytes(h, l, mf) writebytes(h, l, 4, mf)
1645
1646//---------------------------------------------------------------------------
1651#ifdef __cplusplus
1652# ifndef swap32
1653inline THREAD_SAFE constexpr uint32 swap32(uint32 x)
1654 { return (x>>24) | (x<<24) | ((x>>8) & 0x0000FF00) | ((x<<8) & 0x00FF0000); }
1655# endif
1656# ifndef swap16
1657inline THREAD_SAFE constexpr ushort swap16(ushort x)
1658 { return ushort((x<<8) | (x>>8)); }
1659# endif
1660#else
1661# ifndef swap32
1662# define swap32(x) uint32((x>>24) | (x<<24) | ((x>>8) & 0x0000FF00) | ((x<<8) & 0x00FF0000))
1663# endif
1664# ifndef swap16
1665# define swap16(x) ushort((x<<8) | (x>>8))
1666# endif
1667#endif
1668
1670#ifdef __EA64__
1671#define swapea swap64
1672#else
1673#define swapea swap32
1674#endif
1675
1680#if __MF__
1681#define qhtonl(x) (x)
1682#define qntohl(x) (x)
1683#define qhtons(x) (x)
1684#define qntohs(x) (x)
1685#else
1686#define qhtons(x) swap16(x)
1687#define qntohs(x) swap16(x)
1688#define qhtonl(x) swap32(x)
1689#define qntohl(x) swap32(x)
1690#endif
1691
1692
1698
1699idaman THREAD_SAFE void ida_export swap_value(void *dst, const void *src, int size);
1700
1701
1702idaman THREAD_SAFE void ida_export reloc_value(void *value, int size, adiff_t delta, bool mf);
1703
1704
1712
1713idaman THREAD_SAFE uval_t ida_export rotate_left(uval_t x, int count, size_t bits, size_t offset);
1714
1715
1716#ifdef __cplusplus
1717// Can we move around objects of type T using simple memcpy/memmove?
1718// This class can be specialized for any type T to improve qvector's behavior.
1719template <class T> struct ida_movable_type
1720{
1721 static constexpr bool value = std::is_pod<T>::value;
1722};
1723
1725// NOTE: qswap() has historically used raw byte copies for movable types.
1726// Keep that behavior for ida_movable_type<T> to avoid changing ownership
1727// semantics for legacy movable-but-non-trivially-copyable types.
1728template <class T> inline THREAD_SAFE void qswap(T &a, T &b)
1729{
1730 static_assert(
1731 ida_movable_type<T>::value || std::is_trivially_copyable<T>::value,
1732 "qswap() requires a movable or trivially-copyable type; use std::swap() for other types");
1733 char temp[sizeof(T)];
1734 memcpy(temp, (const void *) &a, sizeof(T));
1735 memcpy((void *) &a, (const void *) &b, sizeof(T));
1736 memcpy((void *) &b, temp, sizeof(T));
1737}
1738
1739//---------------------------------------------------------------------------
1740#ifndef SWIG
1743//{
1744
1752
1753THREAD_SAFE inline uchar *idaapi pack_db(uchar *ptr, uchar *end, uchar x)
1754{
1755 if ( ptr < end )
1756 *ptr++ = x;
1757 return ptr;
1758}
1759
1760
1762
1763THREAD_SAFE inline uchar idaapi unpack_db(const uchar **pptr, const uchar *end)
1764{
1765 const uchar *ptr = *pptr;
1766 uchar x = 0;
1767 if ( ptr < end )
1768 x = *ptr++;
1769 *pptr = ptr;
1770 return x;
1771}
1772
1773idaman THREAD_SAFE uchar *ida_export pack_dw(uchar *ptr, uchar *end, uint16 x);
1774idaman THREAD_SAFE uchar *ida_export pack_dd(uchar *ptr, uchar *end, uint32 x);
1775idaman THREAD_SAFE uchar *ida_export pack_dq(uchar *ptr, uchar *end, uint64 x);
1776idaman THREAD_SAFE ushort ida_export unpack_dw(const uchar **pptr, const uchar *end);
1777idaman THREAD_SAFE uint32 ida_export unpack_dd(const uchar **pptr, const uchar *end);
1778idaman THREAD_SAFE uint64 ida_export unpack_dq(const uchar **pptr, const uchar *end);
1779
1781
1782THREAD_SAFE inline uchar *pack_ea(uchar *ptr, uchar *end, ea_t ea)
1783{
1784#ifdef __EA64__
1785 return pack_dq(ptr, end, ea);
1786#else
1787 return pack_dd(ptr, end, ea);
1788#endif
1789}
1790
1792
1793THREAD_SAFE inline ea_t unpack_ea(const uchar **ptr, const uchar *end)
1794{
1795#ifdef __EA64__
1796 return unpack_dq(ptr, end);
1797#else
1798 return unpack_dd(ptr, end);
1799#endif
1800}
1801
1803THREAD_SAFE inline ea64_t unpack_ea64(const uchar **ptr, const uchar *end)
1804{
1805 return unpack_dq(ptr, end) - 1;
1806}
1807
1808
1816
1817THREAD_SAFE inline void *idaapi unpack_obj(
1818 void *destbuf,
1819 size_t destsize,
1820 const uchar **pptr,
1821 const uchar *end)
1822{
1823 const uchar *src = *pptr;
1824 const uchar *send = src + destsize;
1825 if ( send < src || send > end )
1826 return nullptr;
1827 *pptr = send;
1828 return memcpy(destbuf, src, destsize);
1829}
1830
1831
1839
1840THREAD_SAFE inline void *idaapi unpack_buf(const uchar **pptr, const uchar *end)
1841{
1842 size_t size = unpack_dd(pptr, end);
1843 if ( size == 0 )
1844 return nullptr;
1845 const uchar *src = *pptr;
1846 const uchar *srcend = src + size;
1847 if ( srcend < src || srcend > end )
1848 return nullptr;
1849 void *dst = qalloc(size);
1850 if ( dst != nullptr )
1851 {
1852 memcpy(dst, src, size);
1853 *pptr = srcend;
1854 }
1855 return dst;
1856}
1857
1858
1862
1863THREAD_SAFE inline const void *idaapi unpack_obj_inplace(
1864 const uchar **pptr,
1865 const uchar *end,
1866 size_t objsize)
1867{
1868 const uchar *ret = *pptr;
1869 const uchar *rend = ret + objsize;
1870 if ( rend < ret || rend > end )
1871 return nullptr;
1872 *pptr = rend;
1873 return ret;
1874}
1875
1876
1880
1881THREAD_SAFE inline const void *idaapi unpack_buf_inplace(
1882 const uchar **pptr,
1883 const uchar *end)
1884{
1885 size_t objsize = unpack_dd(pptr, end);
1886 return unpack_obj_inplace(pptr, end, objsize);
1887}
1888
1889
1896
1897idaman THREAD_SAFE uchar *ida_export pack_ds(
1898 uchar *ptr,
1899 uchar *end,
1900 const char *x,
1901 size_t len=0);
1902
1903
1912
1913idaman THREAD_SAFE char *ida_export unpack_ds(
1914 const uchar **pptr,
1915 const uchar *end,
1916 bool empty_null);
1917
1924THREAD_SAFE inline bool unpack_ds_to_buf(
1925 char *dst,
1926 size_t dstsize,
1927 const uchar **pptr,
1928 const uchar *end)
1929{
1930 const void *buf = unpack_buf_inplace(pptr, end);
1931 if ( buf == nullptr )
1932 return false;
1933 size_t size = *pptr - (const uchar *)buf;
1934 if ( size >= dstsize )
1935 size = dstsize - 1;
1936 memcpy(dst, buf, size);
1937 dst[size] = '\0';
1938 return true;
1939}
1940
1941
1944
1945idaman THREAD_SAFE bool ida_export unpack_xleb128(
1946 void *res,
1947 int nbits,
1948 bool is_signed,
1949 const uchar **pptr,
1950 const uchar *end);
1951
1955
1956template <class T>
1957inline THREAD_SAFE bool unpack_uleb128(T *res, const uchar **pptr, const uchar *end)
1958{
1959 CASSERT((T)(-1) > 0); // make sure T is unsigned
1960 return unpack_xleb128(res, sizeof(T)*8, false, pptr, end);
1961}
1962
1963template <class T>
1964inline THREAD_SAFE bool unpack_sleb128(T *res, const uchar **pptr, const uchar *end)
1965{
1966 CASSERT((T)(-1) < 0); // make sure T is signed
1967 return unpack_xleb128(res, sizeof(T)*8, true, pptr, end);
1968}
1969
1971
1972// packed sizes
1974static constexpr int ea_packed_size = sizeof(ea_t) + sizeof(ea_t)/4; // 5 or 10 bytes
1975static constexpr int dq_packed_size = 10;
1976static constexpr int dd_packed_size = 5;
1977static constexpr int dw_packed_size = 3;
1979
1980inline THREAD_SAFE int ds_packed_size(const char *s) { return s ? int(strlen(s)+dd_packed_size) : 1; }
1981
1982//----------------------------------------------------------------------------
1983inline THREAD_SAFE constexpr int dw_size(uchar first_byte)
1984{
1985 return (first_byte & 0x80) == 0 ? 1
1986 : (first_byte & 0xC0) == 0xC0 ? 3
1987 : 2;
1988}
1989
1990//----------------------------------------------------------------------------
1991inline THREAD_SAFE constexpr int dd_size(uchar first_byte)
1992{
1993 return (first_byte & 0x80) == 0x00 ? 1
1994 : (first_byte & 0xC0) != 0xC0 ? 2
1995 : (first_byte & 0xE0) == 0xE0 ? 5
1996 : 4;
1997}
1998
1999//----------------------------------------------------------------------------
2000// unpack data from an object which must have the following functions:
2001// ssize_t read(void *buf, size_t count)
2002// bool eof() - return true if there is no more data to read
2003template <class T>
2004inline THREAD_SAFE uchar extract_db(T &v)
2005{
2006 uchar x = 0;
2007 v.read(&x, 1);
2008 return x;
2009}
2010
2011template <class T>
2012inline THREAD_SAFE void *extract_obj(T &v, void *destbuf, size_t destsize)
2013{
2014 if ( destsize == 0 )
2015 return nullptr;
2016 return v.read(destbuf, destsize) == destsize ? destbuf : nullptr;
2017}
2018
2019template <class T>
2020inline THREAD_SAFE uint16 extract_dw(T &v)
2021{
2022 uchar packed[dw_packed_size];
2023 packed[0] = extract_db(v);
2024 int psize = dw_size(packed[0]);
2025 extract_obj(v, &packed[1], psize-1);
2026 const uchar *ptr = packed;
2027 return unpack_dw(&ptr, packed + psize);
2028}
2029
2030template <class T>
2031inline THREAD_SAFE uint32 extract_dd(T &v)
2032{
2033 uchar packed[dd_packed_size];
2034 packed[0] = extract_db(v);
2035 int psize = dd_size(packed[0]);
2036 extract_obj(v, &packed[1], psize-1);
2037 const uchar *ptr = packed;
2038 return unpack_dd(&ptr, packed + psize);
2039}
2040
2041template <class T>
2042inline THREAD_SAFE uint64 extract_dq(T &v)
2043{
2044 uint32 l = extract_dd(v);
2045 uint32 h = extract_dd(v);
2046 return make_uint64(l, h);
2047}
2048
2049template <class T>
2050inline THREAD_SAFE ea_t extract_ea(T &v)
2051{
2052#ifdef __EA64__
2053 return extract_dq(v);
2054#else
2055 return extract_dd(v);
2056#endif
2057}
2058
2059template <class T>
2060inline THREAD_SAFE void *extract_buf(T &v, size_t size)
2061{
2062 void *buf = qalloc(size);
2063 if ( buf == nullptr )
2064 return nullptr;
2065 return extract_obj(v, buf, size);
2066}
2067
2068template <class T>
2069inline THREAD_SAFE void *extract_array(T &v, size_t *sz, size_t maxsize)
2070{
2071 size_t size = extract_dd(v);
2072 if ( size == 0 || size > maxsize )
2073 return nullptr;
2074 *sz = size;
2075 return extract_buf(v, size);
2076}
2077
2078inline const char *unpack_str(const uchar **pptr, const uchar *end)
2079{ // zero terminated string, return inplace ptr
2080 const uchar *ptr = *pptr;
2081 const uchar *str = ptr;
2082 do
2083 if ( ptr >= end )
2084 return nullptr; // no terminating zero?
2085 while ( *ptr++ != '\0' );
2086 *pptr = ptr;
2087 return (char*)str;
2088}
2089
2091#endif // SWIG
2092#endif // cplusplus
2093
2099#define APPCHAR(buf, end, chr) \
2100 do \
2101 { \
2102 char __chr = (chr); \
2103 QASSERT(518, (buf) < (end)); \
2104 *(buf)++ = __chr; \
2105 if ( (buf) >= (end) ) \
2106 { \
2107 (buf) = (end)-1; \
2108 (buf)[0] = '\0'; \
2109 } \
2110 } while (0)
2111
2114#define APPZERO(buf, end) \
2115 do \
2116 { \
2117 QASSERT(519, (buf) < (end)); \
2118 *(buf) = '\0'; \
2119 } while (0)
2120
2122#define APPEND(buf, end, name) \
2123 do \
2124 { \
2125 QASSERT(520, (buf) < (end)); \
2126 const char *__ida_in = (name); \
2127 while ( true ) \
2128 { \
2129 if ( (buf) == (end)-1 ) \
2130 { \
2131 (buf)[0] = '\0'; \
2132 break; \
2133 } \
2134 if ( (*(buf) = *__ida_in++) == '\0' ) \
2135 break; \
2136 (buf)++; \
2137 } \
2138 } while ( 0 )
2140
2142
2143idaman THREAD_SAFE void *ida_export qalloc_or_throw(size_t size);
2144
2145
2147
2148idaman THREAD_SAFE void *ida_export qrealloc_or_throw(void *ptr, size_t size);
2149
2150
2157
2158idaman THREAD_SAFE void *ida_export qvector_reserve(void *vec, void *old, size_t cnt, size_t elsize);
2159
2160#if defined(__cplusplus)
2165 #if defined(SWIG)
2166 #define DEFINE_MEMORY_ALLOCATION_FUNCS()
2167 #else
2168 #define PLACEMENT_DELETE void operator delete(void *, void *) {}
2169 #define DEFINE_MEMORY_ALLOCATION_FUNCS() \
2170 void *operator new (size_t _s) { return qalloc_or_throw(_s); } \
2171 void *operator new[](size_t _s) { return qalloc_or_throw(_s); } \
2172 void *operator new(size_t /*size*/, void *_v) { return _v; } \
2173 void operator delete (void *_blk) { qfree(_blk); } \
2174 void operator delete[](void *_blk) { qfree(_blk); } \
2175 PLACEMENT_DELETE
2176 #endif
2177
2179#define DECLARE_COMPARISON_OPERATORS(type) \
2180 bool operator==(const type &r) const { return compare(r) == 0; } \
2181 bool operator!=(const type &r) const { return compare(r) != 0; } \
2182 bool operator< (const type &r) const { return compare(r) < 0; } \
2183 bool operator> (const type &r) const { return compare(r) > 0; } \
2184 bool operator<=(const type &r) const { return compare(r) <= 0; } \
2185 bool operator>=(const type &r) const { return compare(r) >= 0; }
2186
2189#define DECLARE_COMPARISONS(type) \
2190 DECLARE_COMPARISON_OPERATORS(type) \
2191 int compare(const type &r) const
2192
2193// Internal declarations to detect movable types
2195#define DECLARE_TYPE_AS_MOVABLE(T) template <> struct ida_movable_type<T> { static constexpr bool value = true; }
2196
2197
2198template <class T> inline constexpr THREAD_SAFE bool may_move_bytes(void)
2199{
2201}
2203
2208template<class T>
2209inline void shift_down(T *dst, T *src, size_t cnt)
2210{
2211 if ( may_move_bytes<T>() )
2212 {
2213 memmove((void *) dst, (const void *) src, cnt * sizeof(T));
2214 }
2215 else
2216 {
2217 ssize_t s = ssize_t(cnt);
2218 while ( --s >= 0 )
2219 {
2220 new(dst) T(std::move(*src));
2221 src->~T();
2222 ++src;
2223 ++dst;
2224 }
2225 }
2226}
2227
2231template<class T>
2232inline void shift_up(T *dst, T *src, size_t cnt)
2233{
2234 if ( may_move_bytes<T>() )
2235 {
2236 memmove((void *) dst, (const void *) src, cnt * sizeof(T));
2237 }
2238 else
2239 {
2240 ssize_t s = cnt;
2241 dst += s;
2242 src += s;
2243 while ( --s >= 0 )
2244 {
2245 --src;
2246 --dst;
2247 new(dst) T(std::move(*src));
2248 src->~T();
2249 }
2250 }
2251}
2252
2253
2254//---------------------------------------------------------------------------
2261template <class T> class qvector
2262{
2263 T *array;
2264 size_t n, alloc;
2265 friend void *ida_export qvector_reserve(void *vec, void *old, size_t cnt, size_t elsize);
2267 qvector<T> &assign(const qvector<T> &x)
2268 {
2269 size_t _newsize = x.n;
2270 if ( _newsize > 0 )
2271 {
2272 array = static_cast<T*>(qalloc_or_throw(_newsize * sizeof(T)));
2273 alloc = _newsize;
2274 copy_range(x, 0, _newsize);
2275 }
2276 return *this;
2277 }
2279 void copy_range(const qvector<T> &x, size_t from, size_t _newsize)
2280 {
2281 if constexpr ( std::is_trivially_copyable<T>::value )
2282 {
2283 memcpy((void *) (array + from), (const void *) (x.array + from), (_newsize - from) * sizeof(T));
2284 }
2285 else
2286 {
2287 for ( size_t i = from; i < _newsize; i++ )
2288 new(array+i) T(x.array[i]);
2289 }
2290 n = _newsize;
2291 }
2292 void free_memory()
2293 {
2294 qfree(array);
2295 array = nullptr;
2296 alloc = 0;
2297 }
2299 void _reallocate_array(size_t new_alloc)
2300 {
2301 if ( array == nullptr || new_alloc == 0 )
2302 return;
2303 if ( may_move_bytes<T>() )
2304 {
2305 T *new_array = (T*)qrealloc(array, new_alloc * sizeof(T));
2306 if ( new_array != nullptr )
2307 {
2308 array = new_array;
2309 alloc = new_alloc;
2310 }
2311 }
2312 else
2313 {
2314 T *new_array = (T*)qalloc(new_alloc * sizeof(T));
2315 if ( new_array != nullptr )
2316 {
2317 shift_down(new_array, array, n);
2318 qfree(array);
2319 array = new_array;
2320 alloc = new_alloc;
2321 }
2322 }
2323 }
2325 void resize_less(size_t _newsize)
2326 {
2327 if ( !std::is_trivially_destructible<T>::value )
2328 {
2329 size_t _size = n;
2330 for ( size_t i = _newsize; i < _size; i++ )
2331 array[i].~T();
2332 }
2333 n = _newsize;
2334#ifdef TESTABLE_BUILD_DEBUG_CONTAINERS
2336 if ( n == 0 )
2337 free_memory();
2338#endif
2339 }
2342 void resize_more_trivial(size_t _newsize)
2343 {
2344 reserve(_newsize);
2345 if constexpr ( std::is_trivially_copyable<T>::value )
2346 {
2347 memset((void *) (array + n), 0, (_newsize - n) * sizeof(T));
2348 }
2349 else
2350 {
2351 for ( size_t i = n; i < _newsize; ++i )
2352 new (array + i) T();
2353 }
2354 n = _newsize;
2355 }
2357 void resize_more(size_t _newsize, const T &x)
2358 {
2359 reserve(_newsize);
2360 for ( size_t i = n; i < _newsize; i++ )
2361 new(array+i) T(x);
2362 n = _newsize;
2363 }
2364
2365 bool ref_within_range(const T &x) const
2366 {
2367 const T *const p = &x;
2368 return p >= array && p < array + alloc;
2369 }
2370
2371public:
2372 typedef T value_type;
2374 qvector(void) : array(nullptr), n(0), alloc(0) {}
2376 qvector(const qvector<T> &x) : array(nullptr), n(0), alloc(0) { assign(x); }
2377#ifndef SWIG
2379 qvector(qvector<T> &&x) noexcept
2380 {
2381 array = x.array; x.array = nullptr;
2382 n = x.n; x.n = 0;
2383 alloc = x.alloc; x.alloc = 0;
2384 }
2385
2386 qvector(std::initializer_list<T> l) : array(nullptr), n(0), alloc(0)
2387 {
2388 const size_t sz = l.size();
2389 if ( sz == 0 )
2390 return;
2391
2392 array = static_cast<T*>(qalloc_or_throw(sz * sizeof(T)));
2393 alloc = sz;
2394
2395 if constexpr ( std::is_trivially_copyable<T>::value )
2396 {
2397 memcpy((void *) array, (const void *) l.begin(), sz * sizeof(T));
2398 }
2399 else
2400 {
2401 static_assert(std::is_nothrow_copy_constructible<T>::value,
2402 "T must be nothrow-copy-constructible in order avoid potential memory leaks");
2403 const T *const data = l.begin();
2404 for ( size_t idx = 0; idx < sz; ++idx )
2405 new (array + idx) T(data[idx]);
2406 }
2407
2408 n = sz;
2409 }
2410#endif
2413 {
2414 if ( array != nullptr )
2415 {
2416 resize_less(0);
2417 free_memory();
2418 }
2419 }
2422 void push_back(const T &x)
2423 {
2424 TB_QASSERT(1907, !ref_within_range(x));
2425 T val(x);
2426 reserve(n+1);
2427 new (array+n) T(std::move(val));
2428 ++n;
2429 }
2430#ifndef SWIG
2432 void push_back(T &&x)
2433 {
2434 bool aliasing = ref_within_range(x);
2435 TB_QASSERT(1977, !aliasing);
2436 if ( aliasing )
2437 {
2438 // If x aliases an element inside the same container and
2439 // reserve triggers a reallocation, the reference x becomes
2440 // dangling immediately. Any attempt to read/move from x
2441 // after reserve would be UB.
2442 // Therefore, we capture the value first while x still refers
2443 // to a valid object.
2444 T val(std::move(x));
2445 reserve(n+1);
2446 new (array+n) T(std::move(val));
2447 }
2448 else
2449 {
2450 reserve(n+1);
2451 new (array+n) T(std::move(x));
2452 }
2453 ++n;
2454 }
2455#endif
2456
2457#ifndef SWIG
2460 template <typename... Args>
2461 void emplace_back(Args && ... args)
2462 {
2463 // If any args... are references to elements inside this same container,
2464 // and reserve reallocates, those references dangle before we use them.
2465 reserve(n+1);
2466 new (array+n) T(std::forward<Args>(args)...);
2467 ++n;
2468 }
2469#endif
2470
2473 T &push_back(void)
2474 {
2475 reserve(n+1);
2476 T *ptr = array + n;
2477 new (ptr) T;
2478 ++n;
2479 return *ptr;
2480 }
2481
2482 void pop_back(void)
2483 {
2484 if ( n > 0 )
2485 {
2486 array[--n].~T();
2487#ifdef TESTABLE_BUILD
2489 if ( n == 0 )
2490 free_memory();
2491#endif
2492 }
2493 }
2494 size_t size(void) const { return n; }
2495 bool empty(void) const { return n == 0; }
2496 const T &operator[](size_t _idx) const { return array[_idx]; }
2497 T &operator[](size_t _idx) { return array[_idx]; }
2498 const T &at(size_t _idx) const { return array[_idx]; }
2499 T &at(size_t _idx) { return array[_idx]; }
2500 const T &front(void) const { return array[0]; }
2501 T &front(void) { return array[0]; }
2502 const T &back(void) const { return array[n-1]; }
2503 T &back(void) { return array[n-1]; }
2505 void qclear(void)
2506 {
2507 resize_less(0);
2508 }
2509
2510 void clear(void)
2511 {
2512 if ( array != nullptr )
2513 {
2514 qclear();
2515 free_memory();
2516 }
2517 }
2518
2520 {
2521 qvector<T> copy(x);
2522 return operator=(std::move(copy));
2523 }
2524#ifndef SWIG
2527 {
2528 qvector<T> m(std::forward<qvector<T>>(x));
2529 clear();
2530 array = m.array; m.array = nullptr;
2531 n = m.n; m.n = 0;
2532 alloc = m.alloc; m.alloc = 0;
2533 return *this;
2534 }
2535#endif
2540 void resize(size_t _newsize, const T &x)
2541 {
2542#ifdef TESTABLE_BUILD
2543 QASSERT(1908, !ref_within_range(x));
2544#endif
2545 if ( _newsize < n )
2546 resize_less(_newsize);
2547 else if ( _newsize > n )
2548 {
2549 if ( ref_within_range(x) )
2550 resize_more(_newsize, T(x));
2551 else
2552 resize_more(_newsize, x);
2553 }
2554 }
2555
2556 void resize(size_t _newsize)
2557 {
2558 if ( std::is_trivially_constructible<T>::value
2559 && std::is_trivially_copyable<T>::value
2560 && _newsize > n )
2561 {
2562 resize_more_trivial(_newsize);
2563 }
2564 else if ( _newsize == n )
2565 {
2566 return;
2567 }
2568#if __cplusplus >= 201703
2569 else if constexpr ( std::is_default_constructible<T>::value )
2570 resize(_newsize, T());
2571 else if ( _newsize < n )
2572 resize_less(_newsize);
2573 else
2574 QASSERT(3396, false);
2575#else
2576 resize(_newsize, T());
2577#endif
2578 }
2579#ifndef SWIG
2580 // Resize the array but do not initialize elements
2581 void resize_noinit(size_t _newsize)
2582 {
2583 CASSERT(std::is_trivially_constructible<T>::value);
2584 CASSERT(std::is_trivially_destructible<T>::value);
2585 reserve(_newsize);
2586 n = _newsize;
2587 }
2588#endif
2590 void grow(const T &x=T())
2591 {
2592#ifdef TESTABLE_BUILD
2593 QASSERT(1909, !ref_within_range(x));
2594#endif
2595 T val(x);
2596 reserve(n+1);
2597 new(array+n) T(std::move(val));
2598 ++n;
2599 }
2600
2602 size_t capacity(void) const { return alloc; }
2605 void reserve(size_t cnt)
2606 {
2607 if ( cnt > alloc )
2608 {
2609 if ( may_move_bytes<T>() )
2610 {
2611 array = (T *)qvector_reserve(this, array, cnt, sizeof(T));
2612 }
2613 else
2614 {
2615 size_t old_alloc = alloc;
2616 T *new_array = (T *)qvector_reserve(this, nullptr, cnt, sizeof(T));
2617 size_t new_alloc = alloc;
2618 alloc = old_alloc;
2619 shift_down(new_array, array, n);
2620 qfree(array);
2621 array = new_array;
2622 alloc = new_alloc;
2623 }
2624 }
2625 }
2626
2627 void truncate(void)
2628 {
2629 if ( alloc > n )
2630 _reallocate_array(n);
2631 }
2632
2634 void swap(qvector<T> &r) noexcept
2635 {
2636 T *array2 = array;
2637 size_t n2 = n;
2638 size_t alloc2 = alloc;
2639
2640 array = r.array;
2641 n = r.n;
2642 alloc = r.alloc;
2643
2644 r.array = array2;
2645 r.n = n2;
2646 r.alloc = alloc2;
2647 }
2648
2650 T *extract(void)
2651 {
2652 truncate();
2653 alloc = 0;
2654 n = 0;
2655 T *res = array;
2656 array = nullptr;
2657 return res;
2658 }
2659
2661 void inject(T *s, size_t len)
2662 {
2663 array = s;
2664 alloc = len;
2665 n = len;
2666 }
2667
2668 bool operator == (const qvector<T> &r) const
2669 {
2670 if ( n != r.n )
2671 return false;
2672 for ( size_t i=0; i < n; i++ )
2673 if ( array[i] != r[i] )
2674 return false;
2675 return true;
2676 }
2677
2678 bool operator != (const qvector<T> &r) const { return !(*this == r); }
2679
2680 typedef T *iterator;
2681 typedef const T *const_iterator;
2682
2683 iterator begin(void) { return array; }
2684 iterator end(void) { return array + n; }
2685 const_iterator begin(void) const { return array; }
2686 const_iterator end(void) const { return array + n; }
2691 iterator insert(iterator it, const T &x)
2692 {
2693#ifdef TESTABLE_BUILD
2694 QASSERT(1910, !ref_within_range(x));
2695#endif
2696 T val(x);
2697 size_t idx = it - array;
2698 reserve(n+1);
2699 T *p = array + idx;
2700 size_t rest = end() - p;
2701 shift_up(p+1, p, rest);
2702 new(p) T(std::move(val));
2703 n++;
2704 return iterator(p);
2705 }
2706#ifndef SWIG
2709 {
2710#ifdef TESTABLE_BUILD
2711 QASSERT(1978, !ref_within_range(x));
2712#endif
2713 T val(std::forward<T>(x));
2714 size_t idx = it - array;
2715 reserve(n+1);
2716 T *p = array + idx;
2717 size_t rest = end() - p;
2718 shift_up(p+1, p, rest);
2719 new(p) T(std::move(val));
2720 n++;
2721 return iterator(p);
2722 }
2723#endif
2729 template <class it2> iterator insert(iterator it, it2 first, it2 last)
2730 {
2731 size_t cnt = last - first;
2732 if ( cnt == 0 )
2733 return it;
2734
2735 size_t idx = it - array;
2736 reserve(n+cnt);
2737 T *p = array + idx;
2738 size_t rest = end() - p;
2739 shift_up(p+cnt, p, rest);
2740 while ( first != last )
2741 {
2742 new(p) T(*first);
2743 ++p;
2744 ++first;
2745 }
2746 n += cnt;
2747 return iterator(array+idx);
2748 }
2749
2753 {
2754 it->~T();
2755 size_t rest = end() - it - 1;
2756 shift_down(it, it+1, rest);
2757 n--;
2758 return it;
2759 }
2760
2765 {
2766 for ( T *p=first; p != last; ++p )
2767 p->~T();
2768 size_t rest = end() - last;
2769 shift_down(first, last, rest);
2770 n -= last - first;
2771 return first;
2772 }
2773 // non-standard extensions:
2777 iterator find(const T &x)
2778 {
2779 iterator p;
2781 for ( p=begin(), e=end(); p != e; ++p )
2782 if ( x == *p )
2783 break;
2784 return p;
2785 }
2786
2787 const_iterator find(const T &x) const
2788 {
2789 const_iterator p, e;
2790 for ( p=begin(), e=end(); p != e; ++p )
2791 if ( x == *p )
2792 break;
2793 return p;
2794 }
2795#ifndef SWIG
2797 ssize_t index(const T &x) const
2798 {
2799 for ( const_iterator p=begin(), e=end(); p != e; ++p )
2800 if ( x == *p )
2801 return p - begin();
2802 return -1;
2803 }
2804
2805 void add(const T &x) { push_back(x); }
2806 void add(T &&x) { push_back(x); }
2807#endif
2809 bool has(const T &x) const { return find(x) != end(); }
2813 bool add_unique(const T &x)
2814 {
2815 if ( has(x) )
2816 return false;
2817 push_back(x);
2818 return true;
2819 }
2820
2823 bool del(const T &x)
2824 {
2825 iterator p = find(x);
2826 if ( p == end() )
2827 return false;
2828 erase(p);
2829 return true;
2830 }
2831#ifndef SWIG
2832 const char *dstr(void) const; // debug print
2833#endif
2834};
2835
2842
2846template<class T>
2847class qstack : public qvector<T>
2848{
2849 typedef qvector<T> inherited;
2850public:
2851 T pop(void)
2852 {
2853 T v = inherited::back();
2855 return v;
2856 }
2857 const T &top(void) const
2858 {
2859 return inherited::back();
2860 }
2861 T &top(void) { return CONST_CAST(T&)(CONST_CAST(const qstack<T>*)(this)->top()); }
2862 void push(const T &v)
2863 {
2865 }
2866};
2867
2868//---------------------------------------------------------------------------
2871template<typename T>
2873{
2874 // allocate 4MB at once. this way for 16GB we would use 4096 pools.
2875 enum
2876 {
2877 pool_size = 4*1024*1024,
2878 pool_nelems = pool_size / sizeof(T),
2879 };
2880 // we will reuse the freed space to maintain a list of free slots.
2881 // for this we need the slot size to be big enough to hold a pointer.
2882 // also, pool elements must be smaller than the pool size.
2883 CASSERT(sizeof(T) >= sizeof(void *) && pool_nelems > 0);
2884
2885 qvector<T *> pools;
2886 T *free_list = nullptr; // singly linked list
2887 T *pool_ptr = nullptr;
2888 T *pool_end = nullptr;
2889 size_t live_objects = 0;
2890
2891 //---------------------------------------------------------------------------
2892 void free_entire_pool()
2893 {
2894 for ( T *p : pools )
2895 {
2896 qfree(p);
2897 }
2898 pools.clear();
2899 free_list = nullptr;
2900 pool_ptr = nullptr;
2901 pool_end = nullptr;
2902 }
2903
2904public:
2905 // boilerplate definitions that are required for allocators:
2906 typedef T value_type;
2907 typedef T *pointer;
2908 typedef const T *const_pointer;
2909 typedef T &reference;
2910 typedef const T &const_reference;
2911 typedef size_t size_type;
2912 typedef ptrdiff_t difference_type;
2914 template<typename U> pool_allocator_t(const pool_allocator_t<U> &) {}
2916 pool_allocator_t &operator=(const pool_allocator_t &) { return *this; }
2919 bool operator==(const pool_allocator_t &r) const { return this == &r; }
2920
2921 //---------------------------------------------------------------------------
2922 T *allocate(size_t n)
2923 {
2924 if ( n != 1 )
2925 return (T*)qalloc_or_throw(n*sizeof(T));
2926
2927 live_objects++;
2928 if ( free_list != nullptr )
2929 {
2930 T *ptr = free_list;
2931 free_list = *(T**)ptr;
2932 return ptr;
2933 }
2934
2935 if ( pool_ptr == pool_end )
2936 {
2937 pool_ptr = (T*)qalloc_or_throw(pool_nelems*sizeof(T));
2938 pool_end = pool_ptr + pool_nelems;
2939 pools.push_back(pool_ptr);
2940 }
2941 return pool_ptr++;
2942 }
2943
2944 //---------------------------------------------------------------------------
2945 void deallocate(T *ptr, size_t n)
2946 {
2947 if ( n != 1 )
2948 {
2949 qfree(ptr);
2950 }
2951 else
2952 {
2953 *(T**)ptr = free_list;
2954 free_list = ptr;
2955 if ( --live_objects == 0 )
2956 free_entire_pool();
2957 }
2958 }
2959};
2960
2961//---------------------------------------------------------------------------
2964template <class T> int lexcompare(const T &a, const T &b)
2965{
2966 if ( a < b )
2967 return -1;
2968 if ( a > b )
2969 return 1;
2970 return 0;
2971}
2972
2973//---------------------------------------------------------------------------
2979template <class T> int lexcompare_vectors(const T &a, const T &b)
2980{
2981 if ( a.size() != b.size() )
2982 return a.size() > b.size() ? 1 : -1;
2983 for ( int i=0; i < a.size(); i++ )
2984 {
2985 int code = lexcompare(a[i], b[i]);
2986 if ( code != 0 )
2987 return code;
2988 }
2989 return 0;
2990}
2991
2992//---------------------------------------------------------------------------
2994template <class T>
2996{
2997 T *ptr;
2998 void delref(void)
2999 {
3000 if ( ptr != nullptr && --ptr->refcnt == 0 )
3001 ptr->release();
3002 }
3003public:
3004 explicit qrefcnt_t(T *p) : ptr(p) {}
3005 qrefcnt_t(const qrefcnt_t &r) : ptr(r.ptr)
3006 {
3007 if ( ptr != nullptr )
3008 ptr->refcnt++;
3009 }
3011 {
3012 delref();
3013 ptr = r.ptr;
3014 if ( ptr != nullptr )
3015 ptr->refcnt++;
3016 return *this;
3017 }
3019 {
3020 delref();
3021 }
3022 void reset(void)
3023 {
3024 delref();
3025 ptr = nullptr;
3026 }
3027 operator T *() const
3028 {
3029 return ptr;
3030 }
3031 T *operator ->() const
3032 {
3033 return ptr;
3034 }
3035 T &operator *() const
3036 {
3037 return *ptr;
3038 }
3039};
3040
3041//---------------------------------------------------------------------------
3044{
3045public:
3048 qrefcnt_obj_t(void) : refcnt(1) {}
3053 virtual void idaapi release(void) = 0;
3054};
3055
3056//---------------------------------------------------------------------------
3058template <class T>
3060{
3061public:
3062 typedef T value_type;
3063 virtual bool idaapi first(void) = 0;
3064 virtual bool idaapi next(void) = 0;
3065 virtual T idaapi operator *(void) = 0;
3066 virtual T get(void) newapi { return this->operator*(); }
3067};
3068
3069
3070//---------------------------------------------------------------------------
3074inline THREAD_SAFE size_t idaapi qstrlen(const char *s) { return strlen(s); }
3075inline THREAD_SAFE size_t idaapi qstrlen(const uchar *s) { return strlen((const char *)s); }
3076idaman THREAD_SAFE size_t ida_export qstrlen(const wchar16_t *s);
3078
3087inline THREAD_SAFE int idaapi qstrcmp(const char *s1, const char *s2) { return strcmp(s1, s2); }
3088inline THREAD_SAFE int idaapi qstrcmp(const uchar *s1, const uchar *s2) { return strcmp((const char *)s1, (const char *)s2); }
3089idaman THREAD_SAFE int ida_export qstrcmp(const wchar16_t *s1, const wchar16_t *s2);
3091
3100inline THREAD_SAFE int idaapi qstrncmp(const char *s1, const char *s2, size_t len) { return strncmp(s1, s2, len); }
3101inline THREAD_SAFE int idaapi qstrncmp(const uchar *s1, const uchar *s2, size_t len) { return strncmp((const char *)s1, (const char *)s2, len); }
3102idaman THREAD_SAFE int ida_export qstrncmp(const wchar16_t *s1, const wchar16_t *s2, size_t len);
3104
3109inline THREAD_SAFE char *idaapi qstrstr(char *s1, const char *s2) { return strstr(s1, s2); }
3110inline THREAD_SAFE const char *idaapi qstrstr(const char *s1, const char *s2) { return strstr(s1, s2); }
3111inline THREAD_SAFE const uchar *idaapi qstrstr(const uchar *s1, const uchar *s2) { return (const uchar *)strstr((const char *)s1, (const char *)s2); }
3113
3118inline THREAD_SAFE char *idaapi qstrchr(char *s1, char c) { return strchr(s1, c); }
3119inline THREAD_SAFE const char *idaapi qstrchr(const char *s1, char c) { return strchr(s1, c); }
3120inline THREAD_SAFE uchar *idaapi qstrchr(uchar *s1, uchar c) { return (uchar *)strchr((char *)s1, c); }
3121inline THREAD_SAFE const uchar *idaapi qstrchr(const uchar *s1, uchar c) { return (const uchar *)strchr((const char *)s1, c); }
3122idaman THREAD_SAFE const wchar16_t *ida_export qstrchr(const wchar16_t *s1, wchar16_t c);
3123inline THREAD_SAFE wchar16_t *idaapi qstrchr(wchar16_t *s1, wchar16_t c)
3124 { return (wchar16_t *)qstrchr((const wchar16_t *)s1, c); }
3125
3126
3131inline THREAD_SAFE const char *idaapi qstrrchr(const char *s1, char c) { return strrchr(s1, c); }
3132inline THREAD_SAFE char *idaapi qstrrchr(char *s1, char c) { return strrchr(s1, c); }
3133inline THREAD_SAFE const uchar *idaapi qstrrchr(const uchar *s1, uchar c) { return (const uchar *)strrchr((const char *)s1, c); }
3134inline THREAD_SAFE uchar *idaapi qstrrchr(uchar *s1, uchar c) { return (uchar *)strrchr((const char *)s1, c); }
3135idaman THREAD_SAFE const wchar16_t *ida_export qstrrchr(const wchar16_t *s1, wchar16_t c);
3136inline THREAD_SAFE wchar16_t *idaapi qstrrchr(wchar16_t *s1, wchar16_t c)
3137 { return (wchar16_t *)qstrrchr((const wchar16_t *)s1, c); }
3138
3139
3142#define SSF_DROP_EMPTY 0x1
3144
3145//---------------------------------------------------------------------------
3146#define streq(s1, s2) (::qstrcmp((s1), (s2)) == 0)
3147#define strneq(s1, s2, count) (::qstrncmp((s1), (s2), (count)) == 0)
3148#define strieq(s1, s2) (stricmp((s1), (s2)) == 0)
3149#define strnieq(s1, s2, count) (strnicmp((s1), (s2), (count)) == 0)
3150
3151//---------------------------------------------------------------------------
3156template<class qchar>
3158{
3159 qvector<qchar> body;
3160 void assign(const qchar *ptr, size_t len)
3161 {
3162 body.resize_noinit(len+1);
3163 memmove(body.begin(), ptr, len*sizeof(qchar));
3164 body[len] = '\0';
3165 }
3166public:
3167 using value_type = qchar;
3168
3170 _qstring(void) {}
3172 _qstring(const qchar *ptr)
3173 {
3174 if ( ptr != nullptr )
3175 assign(ptr, ::qstrlen(ptr));
3176 }
3177
3178 _qstring(const qchar *ptr, size_t len)
3179 {
3180 if ( len > 0 )
3181 assign(ptr, len);
3182 }
3183
3184 _qstring(size_t count, qchar ch)
3185 {
3186 if ( count > 0 )
3187 {
3188 body.resize(count+1, ch);
3189 body[count] = 0; // ensure the terminating zero
3190 }
3191 }
3192#ifndef SWIG
3194 _qstring(_qstring &&x) : body(std::move(x.body)) {}
3196 _qstring(const _qstring &r) : body(r.body) {}
3197#endif
3198 void swap(_qstring<qchar> &r) { body.swap(r.body); }
3199 size_t length(void) const { size_t l = body.size(); return l ? l - 1 : 0; }
3200 size_t size(void) const { return body.size(); }
3201 size_t capacity(void) const { return body.capacity(); }
3202
3207 void resize(size_t s, qchar c)
3208 {
3209 size_t oldsize = body.size();
3210 if ( oldsize != 0 && s >= oldsize )
3211 body[oldsize-1] = c; // erase the terminating zero
3212 body.resize(s+1, c);
3213 body[s] = 0; // ensure the terminating zero
3214 }
3215
3216 void resize(size_t s)
3217 {
3218 if ( s == 0 )
3219 {
3220 body.clear();
3221 }
3222 else
3223 {
3224 body.resize(s+1);
3225 body[s] = 0; // ensure the terminating zero
3226 }
3227 }
3228 void remove_last(int cnt=1)
3229 {
3230 ssize_t len = body.size() - cnt;
3231 if ( len <= 1 )
3232 {
3233 body.clear();
3234 }
3235 else
3236 {
3237 body.resize_noinit(len);
3238 body[len-1] = 0;
3239 }
3240 }
3241 void reserve(size_t cnt) { body.reserve(cnt); }
3242 void clear(void) { body.clear(); }
3243 void qclear(void) { body.qclear(); }
3244 bool empty(void) const { return body.size() <= 1; }
3246 const qchar *c_str(void) const
3247 {
3248 static const qchar nullstr[] = { 0 };
3249 return body.empty() ? nullstr : &body[0];
3250 }
3251 typedef qchar *iterator;
3252 typedef const qchar *const_iterator;
3253 iterator begin(void) { return body.begin(); }
3254 const_iterator begin(void) const { return body.begin(); }
3255 iterator end(void) { return body.end(); }
3256 const_iterator end(void) const { return body.end(); }
3258 _qstring &operator=(const qchar *str)
3259 {
3260 size_t len = str == nullptr ? 0 : ::qstrlen(str);
3261 if ( len > 0 )
3262 assign(str, len);
3263 else
3264 qclear();
3265 return *this;
3266 }
3268 {
3269 if ( this != &qstr )
3270 {
3271 size_t len = qstr.length();
3272 if ( len > 0 )
3273 assign(qstr.begin(), len);
3274 else
3275 qclear();
3276 }
3277 return *this;
3278 }
3279#ifndef SWIG
3282 {
3283 body = std::move(x.body);
3284 return *this;
3285 }
3286#endif
3289 {
3290 return append(c);
3291 }
3292
3294 {
3295 return append(r);
3296 }
3297
3299 {
3300 _qstring s = *this;
3301 s += r;
3302 return s;
3303 }
3305 {
3306 return ::qstrcmp(c_str(), r.c_str());
3307 }
3308
3309 bool operator==(const qchar *r) const
3310 {
3311 return ::qstrcmp(c_str(), r) == 0;
3312 }
3313 bool operator!=(const qchar *r) const { return !(*this == r); }
3315 bool operator<(const qchar *r) const
3316 {
3317 return ::qstrcmp(c_str(), r) < 0;
3318 }
3319
3320 bool starts_with(const _qstring &str) const
3321 {
3322 return starts_with(str.begin(), str.length());
3323 }
3324 bool starts_with(const qchar *ptr, ssize_t len = -1) const
3325 {
3326 if ( ptr == nullptr )
3327 return true;
3328 if ( len == -1 )
3329 len = ::qstrlen(ptr);
3330 if ( len == 0 )
3331 return true;
3332 if ( length() < size_t(len) )
3333 return false;
3334 return strneq(begin(), ptr, len);
3335 }
3336
3337 bool ends_with(const _qstring &str) const
3338 {
3339 return ends_with(str.begin(), str.length());
3340 }
3341 bool ends_with(const qchar *ptr, ssize_t len = -1) const
3342 {
3343 if ( ptr == nullptr )
3344 return true;
3345 if ( len == -1 )
3346 len = ssize_t(::qstrlen(ptr));
3347 if ( len == 0 )
3348 return true;
3349 size_t l = length();
3350 if ( l < size_t(len) )
3351 return false;
3352 return strneq(begin() + l - len, ptr, len);
3353 }
3354
3355 const qchar &operator[](size_t idx) const
3356 {
3357 if ( !body.empty() || idx )
3358 return body[idx];
3359 static const qchar nullstr[] = { 0 };
3360 return nullstr[0];
3361 }
3362
3363 qchar &operator[](size_t idx)
3364 {
3365 if ( !body.empty() || idx )
3366 return body[idx];
3367 static qchar nullstr[] = { 0 };
3368 return nullstr[0];
3369 }
3370 const qchar &at(size_t idx) const { return body.at(idx); }
3371 qchar &at(size_t idx) { return body.at(idx); }
3373 qchar *extract(void) { return body.extract(); }
3376 void inject(qchar *s, size_t len)
3377 {
3378 body.inject(s, len);
3379 }
3380
3381 void inject(qchar *s)
3382 {
3383 if ( s != nullptr )
3384 {
3385 size_t len = ::qstrlen(s) + 1;
3386 body.inject(s, len);
3387 }
3388 }
3389
3390 qchar last(void) const
3391 {
3392 size_t len = length();
3393 return len == 0 ? '\0' : body[len-1];
3394 }
3395
3399 size_t find(const qchar *str, size_t pos=0) const
3400 {
3401 if ( pos <= length() )
3402 {
3403 const qchar *beg = c_str();
3404 const qchar *ptr = ::qstrstr(beg+pos, str);
3405 if ( ptr != nullptr )
3406 return ptr - beg;
3407 }
3408 return npos;
3409 }
3410
3412 bool replace(const qchar *what, const qchar *with)
3413 {
3415 size_t len_what = ::qstrlen(what);
3416 const qchar *_start = c_str();
3417 const qchar *last_pos = _start;
3418 while ( true )
3419 {
3420 const qchar *pos = ::qstrstr(last_pos, what);
3421 if ( pos == nullptr )
3422 break;
3423 size_t n = pos - last_pos;
3424 if ( n > 0 )
3425 result.append(last_pos, n);
3426 result.append(with);
3427 last_pos = pos + len_what;
3428 }
3429 // no match at all?
3430 if ( last_pos == _start )
3431 return false;
3432 // any pending characters?
3433 if ( *last_pos )
3434 result.append(last_pos);
3435 swap(result);
3436 return true;
3437 }
3438
3439 size_t find(const _qstring &str, size_t pos=0) const { return find(str.c_str(), pos); }
3444 size_t find(qchar c, size_t pos=0) const
3445 {
3446 if ( pos <= length() )
3447 {
3448 const qchar *beg = c_str();
3449 const qchar *ptr = qstrchr(beg+pos, c);
3450 if ( ptr != nullptr )
3451 return ptr - beg;
3452 }
3453 return npos;
3454 }
3455
3459 size_t rfind(qchar c, size_t pos=0) const
3460 {
3461 if ( pos <= length() )
3462 {
3463 const qchar *beg = c_str();
3464 const qchar *ptr = qstrrchr(beg+pos, c);
3465 if ( ptr != nullptr )
3466 return ptr - beg;
3467 }
3468 return npos;
3469 }
3470
3474 _qstring<qchar> substr(size_t pos=0, size_t n=npos) const
3475 {
3476 size_t endp = qmin(length(), n);
3477 if ( pos >= endp )
3478 pos = endp;
3479 return _qstring<qchar>(c_str()+pos, endp-pos);
3480 }
3481
3484 _qstring &remove(size_t idx, size_t cnt)
3485 {
3486 size_t len = length();
3487 if ( idx < len && cnt != 0 )
3488 {
3489 cnt += idx;
3490 if ( cnt < len )
3491 {
3492 iterator p1 = body.begin() + cnt;
3493 iterator p2 = body.begin() + idx;
3494 memmove(p2, p1, (len-cnt)*sizeof(qchar));
3495 idx += len - cnt;
3496 }
3497 body.resize_noinit(idx+1);
3498 body[idx] = '\0';
3499 }
3500 return *this;
3501 }
3502
3505 _qstring &insert(size_t idx, qchar c)
3506 {
3507 size_t len = length();
3508 body.resize_noinit(len+2);
3509 body[len+1] = '\0';
3510 if ( idx < len )
3511 {
3512 iterator p1 = body.begin() + idx;
3513 memmove(p1+1, p1, (len-idx)*sizeof(qchar));
3514 len = idx;
3515 }
3516 body[len] = c;
3517 return *this;
3518 }
3519
3523 _qstring &insert(size_t idx, const qchar *str, size_t addlen)
3524 {
3525 size_t len = length();
3526 body.resize_noinit(len+addlen+1);
3527 body[len+addlen] = '\0';
3528 if ( idx < len )
3529 {
3530 iterator p1 = body.begin() + idx;
3531 iterator p2 = p1 + addlen;
3532 memmove(p2, p1, (len-idx)*sizeof(qchar));
3533 len = idx;
3534 }
3535 memmove(body.begin()+len, str, addlen*sizeof(qchar));
3536 return *this;
3537 }
3538
3539 _qstring &insert(size_t idx, const qchar *str)
3540 {
3541 if ( str != nullptr )
3542 {
3543 size_t addlen = ::qstrlen(str);
3544 insert(idx, str, addlen);
3545 }
3546 return *this;
3547 }
3548
3549 _qstring &insert(size_t idx, const _qstring &qstr)
3550 {
3551 size_t len = length();
3552 size_t add = qstr.length();
3553 body.resize_noinit(len+add+1);
3554 body[len+add] = '\0';
3555 if ( idx < len )
3556 {
3557 iterator p1 = body.begin() + idx;
3558 iterator p2 = p1 + add;
3559 memmove(p2, p1, (len-idx)*sizeof(qchar));
3560 len = idx;
3561 }
3562 memcpy(body.begin()+len, qstr.begin(), add*sizeof(qchar));
3563 return *this;
3564 }
3565 _qstring &insert(qchar c) { return insert(0, c); }
3566 _qstring &insert(const qchar *str) { return insert(0, str); }
3567 _qstring &insert(const _qstring &qstr) { return insert(0, qstr); }
3570 {
3571 size_t len = length();
3572 body.resize_noinit(len+2);
3573 body[len] = c;
3574 body[len+1] = '\0';
3575 return *this;
3576 }
3577
3580 _qstring &append(const qchar *str, size_t addlen)
3581 {
3582 size_t len = length();
3583 body.resize_noinit(len+addlen+1);
3584 body[len+addlen] = '\0';
3585 memmove(body.begin()+len, str, addlen*sizeof(qchar));
3586 return *this;
3587 }
3588
3589 _qstring &append(const qchar *str)
3590 {
3591 if ( str != nullptr )
3592 {
3593 size_t addlen = ::qstrlen(str);
3594 append(str, addlen);
3595 }
3596 return *this;
3597 }
3598
3600 {
3601 size_t add = qstr.length();
3602 if ( add != 0 )
3603 {
3604 size_t len = length();
3605 body.resize_noinit(len+add+1);
3606 body[len+add] = '\0';
3607 memcpy(body.begin()+len, qstr.begin(), add*sizeof(qchar));
3608 }
3609 return *this;
3610 }
3611
3612 AS_PRINTF(2, 0) _qstring &cat_vsprnt(const char *format, va_list va)
3613 { // since gcc64 forbids reuse of va_list, we make a copy for the second call:
3614 va_list copy;
3615 va_copy(copy, va);
3616 size_t add = ::qvsnprintf(nullptr, 0, format, va);
3617 if ( add != 0 )
3618 {
3619 size_t len = length();
3620 body.resize_noinit(len+add+1);
3621 ::qvsnprintf(body.begin()+len, add+1, format, copy);
3622 }
3623 va_end(copy);
3624 return *this;
3625 }
3627 AS_PRINTF(2, 0) _qstring &vsprnt(const char *format, va_list va)
3628 { // since gcc64 forbids reuse of va_list, we make a copy for the second call:
3629 va_list copy;
3630 va_copy(copy, va);
3631 body.clear();
3632 size_t add = ::qvsnprintf(nullptr, 0, format, va);
3633 if ( add != 0 )
3634 {
3635 body.resize_noinit(add+1);
3636 ::qvsnprintf(body.begin(), add+1, format, copy);
3637 }
3638 va_end(copy);
3639 return *this;
3640 }
3642 AS_PRINTF(2, 3) _qstring &cat_sprnt(const char *format, ...)
3643 {
3644 va_list va;
3648 return *this;
3649 }
3651 AS_PRINTF(2, 3) _qstring &sprnt(const char *format, ...)
3652 {
3653 va_list va;
3657 return *this;
3658 }
3662 _qstring &nowarn_sprnt(const char *format, ...)
3663 {
3664 va_list va;
3665 va_start(va, format);
3666 vsprnt(format, va);
3667 va_end(va);
3668 return *this;
3669 }
3670 GCC_DIAG_ON(format-nonliteral);
3676 _qstring &fill(size_t pos, qchar c, size_t len)
3677 {
3678 size_t endp = pos + len + 1;
3679 if ( body.size() < endp )
3680 {
3681 body.resize_noinit(endp);
3682 body[endp-1] = '\0';
3683 }
3684 memset(body.begin()+pos, c, len);
3685 return *this;
3686 }
3687
3688 _qstring &fill(qchar c, size_t len)
3689 {
3690 body.qclear();
3691 if ( len > 0 )
3692 resize(len, c);
3693 return *this;
3694 }
3695
3696 _qstring &ltrim(qchar blank = ' ')
3697 {
3698 if ( !empty() )
3699 {
3700 iterator b = body.begin();
3701 iterator e = body.end()-1;
3702 while ( b < e && *b == blank )
3703 b++;
3704 if ( b > body.begin() )
3705 {
3706 memmove(body.begin(), b, sizeof(qchar)*(e-b+1));
3707 resize(e-b);
3708 }
3709 }
3710 return *this;
3711 }
3712
3713 _qstring &rtrim(qchar blank, size_t minlen = 0)
3714 {
3715 if ( size() > minlen + 1 )
3716 {
3717 iterator b = body.begin() + minlen;
3718 iterator e = body.end() - 1;
3719 // assert: e > b
3720 while ( e > b && *(e-1) == blank )
3721 e--;
3722 resize(e - body.begin());
3723 }
3724 return *this;
3725 }
3726
3728 {
3729 if ( !empty() )
3730 {
3731 iterator b = body.begin();
3732 iterator e = body.end() - 1;
3733 while ( e > b && qisspace(e[-1]) )
3734 --e;
3735 resize(e - b);
3736 }
3737 return *this;
3738 }
3739
3740 _qstring &trim2(qchar blank = ' ')
3741 {
3742 rtrim(blank);
3743 ltrim(blank);
3744 return *this;
3745 }
3746
3747 // Pushes the character 'c' into the qstring
3748 // This adds support for functions from <algorithm>
3749 void push_back(qchar c)
3750 {
3751 append(c);
3752 }
3753
3754
3759 void split(qvector<_qstring<qchar> > *out, const qchar *sep, uint32 flags=0) const;
3760
3766 static _qstring<qchar> join(const qvector<_qstring<qchar> > &parts, const qchar *sep);
3767
3769 static constexpr size_t npos = (size_t) -1;
3770};
3776
3777#ifndef SWIG // avoid "Warning 317: Specialization of non-template 'hash'."
3778
3779// allow qstring in hashed containers
3780namespace std
3781{
3782 template<class T>
3783 struct hash<_qstring<T>>
3784 {
3785 size_t operator()(const _qstring<T> &str) const noexcept
3786 {
3787 // FNV-1a, as per Wikipedia
3788#ifdef __X86__
3789 const size_t FNV_BASIS = 0x811c9dc5;
3790 const size_t FNV_PRIME = 0x01000193;
3791#else
3792 const size_t FNV_BASIS = 0xcbf29ce484222325;
3793 const size_t FNV_PRIME = 0x100000001b3;
3794#endif
3795 size_t sum = FNV_BASIS;
3796 for ( T c : str )
3797 {
3798 sum ^= c;
3799 sum *= FNV_PRIME;
3800 }
3801 return sum;
3802 }
3803 };
3804}
3805#endif
3806
3807template <> inline
3808void qstring::split(qstrvec_t *out, const char *sep, uint32 flags) const
3809{
3810 size_t seplen = ::qstrlen(sep);
3811 const char *p = begin();
3812 const char *const end = p + length();
3813 while ( p < end )
3814 {
3815 const char *psep = ::qstrstr(p, sep);
3816 size_t rem = (psep != nullptr ? psep : end) - p;
3817 if ( rem > 0 || (flags & SSF_DROP_EMPTY) == 0 )
3818 out->push_back().append(p, rem);
3819 p = psep != nullptr ? psep + seplen : end;
3820 }
3821 // Account for trailing separator sequence
3822 if ( ends_with(sep, ssize_t(seplen)) && (flags & SSF_DROP_EMPTY) == 0 )
3823 out->push_back(); // add an empty string
3824}
3825
3826template <> inline
3827qstring qstring::join(const qstrvec_t &parts, const char *sep)
3828{
3829 qstring buf;
3830 size_t nparts = parts.size();
3831 if ( nparts > 0 )
3832 {
3833 size_t seplen = ::qstrlen(sep);
3834 size_t total = (nparts - 1) * seplen; // separators
3835 for ( const auto &one : parts )
3836 total += one.length();
3837 buf.reserve(total);
3838 for ( const auto &one : parts )
3839 {
3840 if ( !buf.empty() )
3841 buf.append(sep, seplen);
3842 buf.append(one);
3843 }
3844 }
3845 return buf;
3846}
3847
3849class bytevec_t: public qvector<uchar>
3850{
3851public:
3855 bytevec_t(const void *buf, size_t sz) { append(buf, sz); }
3859 bytevec_t &append(const void *buf, size_t sz)
3860 {
3861 if ( sz > 0 )
3862 {
3863 size_t cur_sz = size();
3864 size_t new_sz = cur_sz + sz;
3865 if ( new_sz < cur_sz )
3866 new_sz = BADMEMSIZE; // integer overflow, ask too much and it will throw
3867 resize(new_sz);
3868 memcpy(begin() + cur_sz, buf, sz);
3869 }
3870 return *this;
3871 }
3872
3873 void pack_db(uint8 x) { push_back(x); }
3876 {
3877 uchar packed[dw_packed_size];
3878 size_t len = ::pack_dw(packed, packed+sizeof(packed), x) - packed;
3879 append(packed, len);
3880 }
3881
3883 {
3884 uchar packed[dd_packed_size];
3885 size_t len = ::pack_dd(packed, packed+sizeof(packed), x) - packed;
3886 append(packed, len);
3887 }
3888
3890 {
3891 uchar packed[dq_packed_size];
3892 size_t len = ::pack_dq(packed, packed+sizeof(packed), x) - packed;
3893 append(packed, len);
3894 }
3895
3897 {
3898 uchar packed[ea_packed_size];
3899 size_t len = ::pack_ea(packed, packed+sizeof(packed), x) - packed;
3900 append(packed, len);
3901 }
3902
3908 {
3909#ifdef __X86__
3910 if ( ea == BADADDR )
3911 ea = 0xFFFFFFFFFFFFFFFFULL;
3912#endif
3913 return pack_dq(ea+1);
3914 }
3915
3916 void pack_ds(const char *x)
3917 {
3918 if ( x == nullptr )
3919 x = "";
3920 size_t len = strlen(x);
3921#ifndef __X86__
3922 QASSERT(4, len <= 0xFFFFFFFF);
3923#endif
3924 pack_dd(uint32(len));
3925 append(x, len);
3926 }
3927
3928 void pack_str(const char *str)
3929 {
3930 if ( str == nullptr )
3931 str = "";
3932 size_t len = strlen(str) + 1;
3933 append(str, len);
3934 }
3935
3936 void pack_str(const qstring &s)
3937 {
3938 // the opposite operation is 'unpack_str()' which gets the length
3939 // when it encounters a terminating '\0'. Since we don't store the
3940 // string length, we cannot store zeros that 's' might contain
3941 // and thus we cannot rely on its length().
3942 pack_str(s.c_str());
3943 }
3944
3945 void pack_buf(const void *buf, size_t len)
3946 {
3947#ifndef __X86__
3948 QASSERT(5, len <= 0xFFFFFFFF);
3949#endif
3950 pack_dd(uint32(len));
3951 append(buf, len);
3952 }
3953
3955 {
3956 pack_buf(b.begin(), b.size());
3957 }
3958
3969 void pack_eavec(ea_t ea, const eavec_t &vec)
3970 {
3971 int nelems = int(vec.size());
3972 pack_dw(nelems); // 16bits, fixme!
3973 ea_t old = ea;
3974 for ( int i=0; i < nelems; i++ )
3975 {
3976 ea_t nea = vec[i];
3977 pack_ea(nea-old);
3978 old = nea;
3979 }
3980 }
3981
3985 bytevec_t &growfill(size_t sz, uchar filler=0)
3986 {
3987 if ( sz > 0 )
3988 {
3989 size_t cur_sz = size();
3990 size_t new_sz = cur_sz + sz;
3991 if ( new_sz < cur_sz )
3992 new_sz = BADMEMSIZE; // integer overflow, ask too much and it will throw
3993 resize(new_sz, filler);
3994 }
3995 return *this;
3996 }
3997
3998 void inject(void *buf, size_t len)
3999 {
4001 }
4002
4004 void tohex(qstring *out, bool upper_case=true) const
4005 {
4006 size_t len = out->length();
4007 out->resize(len + size() * 2);
4008 char *p = out->begin() + len;
4009 char *end = out->end();
4010 for ( uchar c: *this )
4011 {
4012 ::qsnprintf(p, end - p, upper_case ? "%02X" : "%02x", c);
4013 p += 2;
4014 }
4015 }
4016
4018 qstring tohex(bool upper_case=true) const
4019 {
4020 qstring buf;
4021 tohex(&buf, upper_case);
4022 return buf;
4023 }
4024
4027 bool fromhex(const qstring &str)
4028 {
4029 resize(str.length() / 2);
4030 const char *p = str.begin();
4031 for ( uchar &c: *this )
4032 {
4033 uint b = 0;
4034 if ( ::qsscanf(p, "%02X", &b) != 1 || b > 0xFF )
4035 break;
4036 c = uchar(b);
4037 p += 2;
4038 }
4039 return p == str.begin() + str.length();
4040 }
4041
4043 bool test_bit(size_t bit) const { return ::test_bit(begin(), bit); }
4045 void set_bit(size_t bit) { ::set_bit(begin(), bit); }
4047 void clear_bit(size_t bit) { ::clear_bit(begin(), bit); }
4053 bool all_zeros() const
4054 {
4055 for ( size_t i = 0; i < size(); ++i )
4056 if ( at(i) != 0 )
4057 return false;
4058 return true;
4059 }
4060
4061 void set_bits(const bytevec_t &b)
4062 {
4063 size_t nbytes = b.size();
4064 if ( size() < nbytes )
4065 resize(nbytes);
4066 for ( size_t i=0; i < nbytes; i++ )
4067 at(i) |= b[i];
4068 }
4069
4070 void set_bits(size_t low, size_t high) { ::set_bits(begin(), low, high); }
4072 void clear_bits(const bytevec_t &b)
4073 {
4074 size_t nbytes = qmin(size(), b.size());
4075 iterator p = begin();
4076 for ( size_t i=0; i < nbytes; i++, ++p )
4077 *p = (uchar)(*p & ~b[i]);
4078 }
4079
4080 void clear_bits(size_t low, size_t high) { ::clear_bits(begin(), low, high); }
4081};
4082
4085{
4089#define RELOBJ_MASK 0xF
4090#define RELSIZE_1 0
4091#define RELSIZE_2 1
4092#define RELSIZE_4 2
4093#define RELSIZE_8 3
4094#define RELSIZE_CUST 15
4095#define RELOBJ_CNT 0x80
4097};
4098
4099idaman THREAD_SAFE bool ida_export relocate_relobj(struct relobj_t *_relobj, ea_t ea, bool mf);
4100
4102struct relobj_t : public bytevec_t
4103{
4106
4107 relobj_t(void) : base(0) {}
4108 bool relocate(ea_t ea, bool mf) { return relocate_relobj(this, ea, mf); }
4109};
4110
4111#define QLIST_DEFINED
4114template <class T> class qlist
4115{
4116 struct listnode_t
4117 {
4118 listnode_t *next;
4119 listnode_t *prev;
4120 void fix_links(size_t len)
4121 {
4122 if ( len == 0 )
4123 {
4124 next = this;
4125 prev = this;
4126 }
4127 else
4128 {
4129 next->prev = this;
4130 prev->next = this;
4131 }
4132 }
4133 };
4134
4135 struct datanode_t : public listnode_t
4136 {
4137 T data;
4138 };
4139
4140 listnode_t node;
4141 size_t length;
4142
4143 void init(void)
4144 {
4145 node.next = &node;
4146 node.prev = &node;
4147 length = 0;
4148 }
4149
4150public:
4151 typedef T value_type;
4152 class const_iterator;
4154#define DEFINE_LIST_ITERATOR(iter, constness, cstr) \
4155 class iter \
4156 { \
4157 friend class qlist<T>; \
4158 constness listnode_t *cur; \
4159 iter(constness listnode_t *x) : cur(x) {} \
4160 public: \
4161 typedef constness T value_type; \
4162 iter(void) : cur(nullptr) {} \
4163 iter(const iter &x) : cur(x.cur) {} \
4164 cstr \
4165 iter &operator=(const iter &x) { cur = x.cur; return *this; } \
4166 bool operator==(const iter &x) const { return cur == x.cur; } \
4167 bool operator!=(const iter &x) const { return cur != x.cur; } \
4168 constness T &operator*(void) const { return ((datanode_t*)cur)->data; } \
4169 constness T *operator->(void) const { return &(operator*()); } \
4170 iter &operator++(void) /* prefix ++ */ \
4171 { \
4172 cur = cur->next; \
4173 return *this; \
4174 } \
4175 iter operator++(int) /* postfix ++ */ \
4176 { \
4177 iter tmp = *this; \
4178 ++(*this); \
4179 return tmp; \
4180 } \
4181 iter &operator--(void) /* prefix -- */ \
4182 { \
4183 cur = cur->prev; \
4184 return *this; \
4185 } \
4186 iter operator--(int) /* postfix -- */ \
4187 { \
4188 iter tmp = *this; \
4189 --(*this); \
4190 return tmp; \
4191 } \
4192 };
4193 DEFINE_LIST_ITERATOR(iterator,, friend class const_iterator; )
4194 DEFINE_LIST_ITERATOR(const_iterator, const, const_iterator(const iterator &x) : cur(x.cur) {} )
4195
4197#define DEFINE_REVERSE_ITERATOR(riter, iter) \
4198 class riter \
4199 { \
4200 iter p; \
4201 public: \
4202 riter(void) {} \
4203 riter(const iter &x) : p(x) {} \
4204 typename iter::value_type &operator*(void) const { iter q=p; return *--q; } \
4205 typename iter::value_type *operator->(void) const { return &(operator*()); } \
4206 riter &operator++(void) { --p; return *this; } \
4207 riter operator++(int) { iter q=p; --p; return q; } \
4208 riter &operator--(void) { ++p; return *this; } \
4209 riter operator--(int) { iter q=p; ++p; return q; } \
4210 bool operator==(const riter &x) const { return p == x.p; } \
4211 bool operator!=(const riter &x) const { return p != x.p; } \
4212 };
4213 DEFINE_REVERSE_ITERATOR(reverse_iterator, iterator)
4214 DEFINE_REVERSE_ITERATOR(const_reverse_iterator, const_iterator)
4215#undef DEFINE_LIST_ITERATOR
4216#undef DEFINE_REVERSE_ITERATOR
4218 qlist(void) { init(); }
4220 qlist(const qlist<T> &x)
4221 {
4222 init();
4223 insert(begin(), x.begin(), x.end());
4224 }
4225
4227 {
4228 init();
4229 splice(begin(), x, x.begin(), x.end());
4230 }
4231
4233 {
4234 clear();
4235 }
4236 DEFINE_MEMORY_ALLOCATION_FUNCS()
4237
4238
4239 qlist<T> &operator=(const qlist<T> &x)
4240 {
4241 if ( this != &x )
4242 {
4243 iterator first1 = begin();
4244 iterator last1 = end();
4245 const_iterator first2 = x.begin();
4246 const_iterator last2 = x.end();
4247 while ( first1 != last1 && first2 != last2 )
4248 *first1++ = *first2++;
4249 if ( first2 == last2 )
4250 erase(first1, last1);
4251 else
4252 insert(last1, first2, last2);
4253 }
4254 return *this;
4255 }
4257 qlist &operator=(qlist &&x)
4258 {
4259 if ( this != &x )
4260 {
4261 clear();
4262 splice(begin(), x, x.begin(), x.end());
4263 }
4264 return *this;
4265 }
4267 void swap(qlist<T> &x) noexcept
4268 {
4269 std::swap(node, x.node);
4270 std::swap(length, x.length);
4271 node.fix_links(length);
4272 x.node.fix_links(x.length);
4273 }
4274
4275 iterator begin(void) { return node.next; }
4276 iterator end(void) { return &node; }
4277 bool empty(void) const { return length == 0; }
4278 size_t size(void) const { return length; }
4279 T &front(void) { return *begin(); }
4280 T &back(void) { return *(--end()); }
4281
4282 const_iterator begin(void) const { return node.next; }
4283 const_iterator end(void) const { return &node; }
4284 const T&front(void) const { return *begin(); }
4285 const T&back(void) const { return *(--end()); }
4286
4287 reverse_iterator rbegin() { return reverse_iterator(end()); }
4288 reverse_iterator rend() { return reverse_iterator(begin()); }
4289 const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
4290 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
4291
4296 iterator insert(iterator p, const T &x)
4297 {
4298 datanode_t *tmp = (datanode_t*)qalloc_or_throw(sizeof(datanode_t));
4299 new (&(tmp->data)) T(x);
4300 linkin(p, tmp);
4301 return tmp;
4302 }
4306 iterator insert(iterator p)
4307 {
4308 datanode_t *tmp = (datanode_t*)qalloc_or_throw(sizeof(datanode_t));
4309 new (&(tmp->data)) T();
4310 linkin(p, tmp);
4311 return tmp;
4312 }
4315 template <class it2> void insert(iterator p, it2 first, it2 last)
4316 {
4317 while ( first != last )
4318 insert(p, *first++);
4319 }
4321 void push_front(const T &x) { insert(begin(), x); }
4323 void push_back(const T &x) { insert(end(), x); }
4325 T &push_back(void)
4326 {
4327 iterator p = insert(end());
4328 return ((datanode_t *)p.cur)->data;
4329 }
4331 iterator erase(iterator p)
4332 {
4333 listnode_t *q = p.cur->next;
4334 p.cur->prev->next = p.cur->next;
4335 p.cur->next->prev = p.cur->prev;
4336 ((datanode_t*)p.cur)->data.~T();
4337 qfree(p.cur);
4338 --length;
4339 return q;
4340 }
4342 void erase(iterator p1, iterator p2)
4343 {
4344 while ( p1 != p2 )
4345 p1 = erase(p1);
4346 }
4348 void clear(void) { erase(begin(), end()); }
4350 void pop_front(void) { erase(begin()); }
4352 void pop_back(void) { iterator tmp = end(); erase(--tmp); }
4354 void splice(iterator pos, qlist<T> &other, iterator first, iterator last)
4355 {
4356 // Nothing to do for empty range
4357 if ( first == last )
4358 return;
4359
4360 listnode_t *first_node = first.cur;
4361 listnode_t *last_node = last.cur->prev;
4362
4363 // Compute the length of the other list
4364 size_t sublength = 1;
4365
4366 // Special case: the range is the entire other list
4367 if ( first == other.begin() && last == other.end() )
4368 {
4369 sublength = other.length;
4370 }
4371 else // Otherwise, count the size of the range
4372 {
4373 listnode_t *curr_node = first_node;
4374 while ( curr_node != last_node )
4375 {
4376 curr_node = curr_node->next;
4377 ++sublength;
4378 }
4379 }
4380
4381 // Detach [first, last) from the other list (update links and length)
4382 first_node->prev->next = last_node->next;
4383 last_node->next->prev = first_node->prev;
4384 other.length -= sublength;
4385
4386 // Attach [first, last) to the current list at pos (update links and length)
4387 listnode_t *pos_node = pos.cur;
4388 listnode_t *before_pos = pos_node->prev;
4389 before_pos->next = first_node;
4390 first_node->prev = before_pos;
4391 last_node->next = pos_node;
4392 pos_node->prev = last_node;
4393 length += sublength;
4394 }
4396 bool operator==(const qlist<T> &x) const
4397 {
4398 if ( length != x.length )
4399 return false;
4400 const_iterator q=x.begin();
4401 for ( const_iterator p=begin(), e=end(); p != e; ++p,++q )
4402 if ( *p != *q )
4403 return false;
4404 return true;
4405 }
4407 bool operator!=(const qlist<T> &x) const { return !(*this == x); }
4408private:
4409 void linkin(iterator p, listnode_t *tmp)
4410 {
4411 tmp->next = p.cur;
4412 tmp->prev = p.cur->prev;
4413 p.cur->prev->next = tmp;
4414 p.cur->prev = tmp;
4415 ++length;
4416 }
4417};
4418
4419// Our containers do not care about their addresses. They can be moved around with simple memcpy
4421template <class T> struct ida_movable_type<qvector<T> > { static constexpr bool value = true; };
4422template <class T> struct ida_movable_type<_qstring<T> > { static constexpr bool value = true; };
4423template <class T> struct ida_movable_type<qlist<T> > { static constexpr bool value = false; };
4424template <class T> struct ida_movable_type<qiterator<T> > { static constexpr bool value = true; };
4426
4427//----------------------------------------------------------------------------
4428#ifndef SWIG
4434
4435THREAD_SAFE inline void unpack_eavec(
4436 eavec_t *vec,
4437 ea_t ea,
4438 const uchar **ptr,
4439 const uchar *end)
4440{
4441 ea_t old = ea;
4442 int n = unpack_dw(ptr, end);
4443 vec->resize_noinit(n);
4444 for ( int i=0; i < n; i++ )
4445 {
4446 old += unpack_ea(ptr, end);
4447 vec->at(i) = old;
4448 }
4449}
4450
4451THREAD_SAFE inline bool unpack_bytevec(
4452 bytevec_t *out,
4453 const uchar **pptr,
4454 const uchar *end)
4455{
4456 uint32 nbytes = unpack_dd(pptr, end);
4457 if ( nbytes == 0 )
4458 return true;
4459 const size_t old_size = out->size();
4460 out->resize_noinit(old_size + nbytes);
4461 return unpack_obj(out->begin() + old_size, nbytes, pptr, end) != nullptr;
4462}
4463
4464inline bool unpack_str(qstring *out, const uchar **pptr, const uchar *end)
4465{ // zero terminated string, append to qstring
4466 const char *str = unpack_str(pptr, end);
4467 if ( str == nullptr )
4468 return false;
4469 out->append(str, ((char*)*pptr-str) - 1);
4470 return true;
4471}
4472
4473// Convenience struct for unpacking a data stream
4474THREAD_SAFE struct memory_deserializer_t
4475{
4476 const uchar *ptr;
4477 const uchar *end;
4478
4479 memory_deserializer_t(const qstring &s) : ptr((uchar*)s.begin()), end(ptr+s.size()) {}
4480 memory_deserializer_t(const bytevec_t &b) : ptr(b.begin()), end(b.end()) {}
4481 memory_deserializer_t(const uchar *p, const uchar *e) : ptr(p), end(e) {}
4482 memory_deserializer_t(const void *p, size_t s) : ptr((uchar*)p), end(ptr+s) {}
4483 bool empty() const { return ptr >= end; }
4484 size_t size() const { return end-ptr; }
4485 bool advance(size_t s) { if ( size() < s ) return false; ptr += s; return true; }
4486 uint8 unpack_db() { return ::unpack_db(&ptr, end); }
4487 uint16 unpack_dw() { return ::unpack_dw(&ptr, end); }
4488 uint32 unpack_dd() { return ::unpack_dd(&ptr, end); }
4489 uint64 unpack_dq() { return ::unpack_dq(&ptr, end); }
4490 ea_t unpack_ea() { return ::unpack_ea(&ptr, end); }
4491 ea64_t unpack_ea64() { return ::unpack_ea64(&ptr, end); }
4492 // unpack zero terminated string
4493 const char *unpack_str() { return ::unpack_str(&ptr, end); }
4494 bool unpack_str(qstring *out) { return ::unpack_str(out, &ptr, end); }
4495 // string with length prefix (dd), return string allocated in the heap
4496 char *unpack_ds(bool empty_null=false)
4497 {
4498 return ::unpack_ds(&ptr, end, empty_null);
4499 }
4500 // string with length prefix (dd), return in the specified buffer
4501 bool unpack_ds_to_buf(char *buf, size_t bufsize)
4502 {
4503 return ::unpack_ds_to_buf(buf, bufsize, &ptr, end);
4504 }
4505 const void *unpack_obj_inplace(size_t objsize)
4506 {
4507 return ::unpack_obj_inplace(&ptr, end, objsize);
4508 }
4510 {
4511 return ::unpack_buf_inplace(&ptr, end);
4512 }
4513 const void *unpack_obj(void *obj, size_t objsize)
4514 {
4515 return ::unpack_obj(obj, objsize, &ptr, end);
4516 }
4517 const void *unpack_buf()
4518 {
4519 return ::unpack_buf(&ptr, end);
4520 }
4522 {
4523 ::unpack_eavec(vec, ea, &ptr, end);
4524 }
4526 {
4527 return ::unpack_bytevec(out, &ptr, end);
4528 }
4529 #define SCALAR_TYPE(n) class T, typename std::enable_if<std::is_scalar<T>::value && sizeof(T) == n, int>::type = 0
4530 template <SCALAR_TYPE(1)> void unpack(T *out) { *out = (T)unpack_db(); }
4531 template <SCALAR_TYPE(2)> void unpack(T *out) { *out = unpack_dw(); }
4532 template <SCALAR_TYPE(4)> void unpack(T *out) { *out = unpack_dd(); }
4533 template <SCALAR_TYPE(8)> void unpack(T *out) { *out = unpack_dq(); }
4534 #undef SCALAR_TYPE
4535 void unpack(qstring *out) { *out = unpack_str(); }
4536 template <class T>
4538 {
4539 uint32 cnt = unpack_dd();
4540 out->qclear();
4541 out->reserve(cnt);
4542 for ( size_t i = 0; i < cnt; i++ )
4543 unpack(&out->push_back());
4544 }
4545 // linput_t like interface
4546 ssize_t read(void *obj, size_t objsize) { return unpack_obj(obj, objsize) ? ssize_t(objsize) : -1; }
4547 bool eof() const { return empty(); }
4548};
4549#define DECLARE_MEMORY_DESERIALIZER(name) \
4550 name(const void *p, size_t s) : memory_deserializer_t(p, s) {} \
4551 using memory_deserializer_t::unpack; \
4552
4554{
4555 #define SCALAR_TYPE(n) class T, typename std::enable_if<std::is_scalar<T>::value && sizeof(T) == n, int>::type = 0
4556 template <SCALAR_TYPE(1)> void pack(T value) { pack_db(value); }
4557 template <SCALAR_TYPE(2)> void pack(T value) { pack_dw(value); }
4558 template <SCALAR_TYPE(4)> void pack(T value) { pack_dd(value); }
4559 template <SCALAR_TYPE(8)> void pack(T value) { pack_dq(value); }
4560 #undef SCALAR_TYPE
4561 void pack(const qstring &value) { pack_str(value); }
4562 template <class T>
4563 void pack(const qvector<T> &value)
4564 {
4565 pack_dd(uint32(value.size()));
4566 for ( const auto &item: value )
4567 pack(item);
4568 }
4569};
4570#define DECLARE_MEMORY_SERIALIZER(name) \
4571 using memory_serializer_t::pack; \
4572
4573#endif // SWIG
4574
4575//-------------------------------------------------------------------------
4577template <typename T>
4579{
4580 janitor_t(T &r) : resource(r) {}
4583protected:
4585};
4586
4587// Custom deleter to be used with std::unique_ptr which calls qfree
4588template <typename T>
4590{
4591 void operator() ( T *ptr ) { qfree(ptr); }
4592};
4593
4594template <typename T>
4595using qalloc_janitor_t = std::unique_ptr<T, qfree_deleter_t<T>>;
4596#ifndef SWIG
4597//-------------------------------------------------------------------------
4599template <typename, typename = void>
4600struct has_compare_method : std::false_type {};
4601// std::void_t is from c++17, so we declare it ourselves
4602template< class... > using qvoid_t = void;
4603template <typename T>
4604struct has_compare_method<T, qvoid_t<decltype(std::declval<T>().compare(std::declval<T>()))>>
4605 : std::true_type {};
4606template <class T, typename std::enable_if<has_compare_method<T>::value, int>::type = 0>
4607int compare(const T &a, const T &b)
4608{
4609 return a.compare(b);
4610}
4611template <class T, typename std::enable_if<!has_compare_method<T>::value, int>::type = 0>
4612int compare(const T &a, const T &b)
4613{
4614 if ( a < b )
4615 return -1;
4616 if ( a > b )
4617 return 1;
4618 return 0;
4619}
4620
4621//-------------------------------------------------------------------------
4622template <class T>
4623int compare(const qvector<T> &a, const qvector<T> &b)
4624{
4625 return compare_containers(a, b);
4626}
4627
4628//-------------------------------------------------------------------------
4629template <class T>
4630int compare(const qlist<T> &a, const qlist<T> &b)
4631{
4632 return compare_containers(a, b);
4633}
4634
4635//-------------------------------------------------------------------------
4636template <class T, class U>
4637int compare(const std::pair<T, U> &a, const std::pair<T, U> &b)
4638{
4639 int code = compare(a.first, b.first);
4640 if ( code != 0 )
4641 return code;
4642 return compare(a.second, b.second);
4643}
4644
4645//-------------------------------------------------------------------------
4647template <class T>
4648int compare_containers(const T &l, const T &r)
4649{
4650 auto p = std::begin(l);
4651 auto pe = std::end(l);
4652 auto q = std::begin(r);
4653 auto qe = std::end(r);
4654 for ( ; p != pe && q != qe; ++p,++q )
4655 {
4656 int code = compare(*p, *q);
4657 if ( code != 0 )
4658 return code;
4659 }
4660 if ( p == pe && q != qe )
4661 return -1;
4662 if ( p != pe && q == qe )
4663 return 1;
4664 return 0;
4665}
4666
4667#define COMPARE_POINTERS2(ptr, cmp) \
4668 do \
4669 { \
4670 if ( ptr != nullptr && r.ptr != nullptr ) \
4671 { \
4672 int _code = cmp(*ptr, *r.ptr); \
4673 if ( _code != 0 ) \
4674 return _code; \
4675 } \
4676 else if ( r.ptr != nullptr ) \
4677 { \
4678 return -1; \
4679 } \
4680 else if ( ptr != nullptr ) \
4681 { \
4682 return 1; \
4683 } \
4684 } while (0)
4685
4686#define COMPARE_POINTERS(ptr) COMPARE_POINTERS2(ptr, ::compare)
4687
4688#define COMPARE_FIELDS(fld) \
4689 do \
4690 { \
4691 int _code = ::compare(fld, r.fld); \
4692 if ( _code != 0 ) \
4693 return _code; \
4694 } while (0)
4695
4696// reverse order
4697#define COMPARE_FIELDS_REV(fld) \
4698 do \
4699 { \
4700 int _code = ::compare(r.fld, fld); \
4701 if ( _code != 0 ) \
4702 return _code; \
4703 } while (0)
4704
4705template <class T, class U>
4706int compare(const std::map<T, U> &a, const std::map<T, U> &b)
4707{
4708 return compare_containers(a, b);
4709}
4710
4711template <class T>
4712int compare(const std::set<T> &a, const std::set<T> &b)
4713{
4714 return compare_containers(a, b);
4715}
4716
4717#endif
4718
4719//-------------------------------------------------------------------------
4721template <class T> T align_up(T val, int elsize)
4722{
4723 int mask = elsize - 1;
4724 val += mask;
4725 val &= ~mask;
4726 return val;
4727}
4728
4729//-------------------------------------------------------------------------
4731template <class T> T align_down(T val, int elsize)
4732{
4733 int mask = elsize - 1;
4734 val &= ~mask;
4735 return val;
4736}
4737
4738//-------------------------------------------------------------------------
4742#define DECLARE_UNCOPYABLE(T) \
4743 T(const T &) = delete; \
4744 T &operator=(const T &) = delete; \
4745 T(T &&) = delete; \
4746 T &operator=(T &&) = delete;
4747
4748#ifndef SWIG
4749//-------------------------------------------------------------------------
4750// check the variable type
4752#define IS_QSTRING(v) (std::is_base_of<qstring, std::remove_reference<decltype(v)>::type>::value)
4753#define IS_SIZEVEC_T(v) (std::is_base_of<sizevec_t, std::remove_reference<decltype(v)>::type>::value)
4754#define IS_QSTRVEC_T(v) (std::is_base_of<qstrvec_t, std::remove_reference<decltype(v)>::type>::value)
4755
4757#endif
4758
4759#endif // __cplusplus
4760
4761#ifndef __cplusplus
4762typedef struct bytevec_tag bytevec_t;
4763typedef struct qstring_tag qstring;
4764typedef struct qwstring_tag qwstring;
4765#endif
4766
4767//----------------------------------------------------------------------------
4768
4771
4772idaman THREAD_SAFE uint32 ida_export calc_crc32(uint32 crc, const void *buf, size_t len);
4773
4774
4776
4777idaman THREAD_SAFE uint32 ida_export calc_file_crc32(class linput_t *fp);
4778
4779
4781
4782idaman THREAD_SAFE bool ida_export base64_encode(qstring *output, const void *input, size_t size);
4783
4785
4786idaman THREAD_SAFE bool ida_export base64_decode(bytevec_t *output, const char *input, size_t size);
4787
4788
4794
4795idaman THREAD_SAFE bool ida_export replace_tabs(qstring *out, const char *str, int tabsize);
4796
4797
4801idaman THREAD_SAFE char *ida_export str2user(char *dst, const char *src, size_t dstsize);
4802idaman THREAD_SAFE char *ida_export user2str(char *dst, const char *src, size_t dstsize);
4803idaman THREAD_SAFE char ida_export back_char(const char **p);
4804#ifdef __cplusplus
4805idaman THREAD_SAFE void ida_export qstr2user(qstring *dst, const char *src, int nsyms=-1);
4806inline THREAD_SAFE void qstr2user(qstring *dst, const qstring &src) { qstr2user(dst, src.c_str(), int(src.length())); }
4807idaman THREAD_SAFE void ida_export user2qstr(qstring *dst, const qstring &src);
4808#else
4809idaman THREAD_SAFE void ida_export qstr2user(qstring *dst, const qstring *src);
4810idaman THREAD_SAFE void ida_export user2qstr(qstring *dst, const qstring *src);
4811#endif
4813
4814
4823
4824inline constexpr bool is_utf8_head(char in) { return (in & 0xC0) != 0x80; }
4825
4826
4831
4832inline constexpr bool is_utf8_tail(char in) { return !is_utf8_head(in); }
4833
4834
4838
4839idaman THREAD_SAFE bool ida_export is_valid_utf8(const char *in);
4840
4841
4842#ifdef __cplusplus
4843
4849idaman THREAD_SAFE bool ida_export utf8_utf16(qwstring *out, const char *in, int nsyms=-1);
4850
4851
4859idaman THREAD_SAFE bool ida_export utf16_utf8(qstring *out, const wchar16_t *in, int nsyms=-1);
4860
4861
4862inline constexpr bool is_lead_surrogate(wchar32_t wch) { return 0xD800 <= wch && wch < 0xDC00; }
4863inline constexpr bool is_tail_surrogate(wchar32_t wch) { return 0xDC00 <= wch && wch <= 0xDFFF; }
4864inline constexpr wchar32_t utf16_surrogates_to_cp(wchar16_t lead_surrogate, wchar16_t tail_surrogate)
4865{
4866 return (0x10000 + (wchar32_t(lead_surrogate & 0x3FF) << 10)) | (tail_surrogate & 0x3FF);
4867}
4868
4869
4873#define IDBDEC_ESCAPE 0x00000001
4875
4878
4879idaman THREAD_SAFE bool ida_export idb_utf8(qstring *out, const char *in, int nsyms=-1, int flags=0);
4880
4881
4882#ifdef __NT__
4883// These are typically used in the text UI (TUI), and
4884// also to convert argv to UTF-8 at startup.
4885idaman THREAD_SAFE bool ida_export change_codepage(
4886 qstring *out,
4887 const char *in,
4888 int incp,
4889 int outcp);
4890#ifndef CP_ACP
4891#define CP_ACP 0
4892#endif
4893#ifndef CP_OEM
4894#define CP_OEM 1
4895#endif
4896#ifndef CP_UTF8
4897#define CP_UTF8 65001
4898#endif
4899INLINE THREAD_SAFE bool acp_utf8(qstring *out, const char *in)
4900{
4901 return change_codepage(out, in, CP_ACP, CP_UTF8);
4902}
4903#else // !__NT__
4904INLINE THREAD_SAFE bool idaapi change_codepage(qstring *, const char *, int, int) { return false; }
4905#endif // __NT__
4906
4907
4908//-------------------------------------------------------------------------
4909// helpers to compose 16/32-bit wchar's from [M]UTF-8-encoded data
4910inline THREAD_SAFE constexpr wchar16_t utf8_wchar16(uchar b0, uchar b1)
4911{
4912 return (wchar16_t(b0 & 0x1f) << 6) | (b1 & 0x3f);
4913}
4914
4915//-------------------------------------------------------------------------
4916inline THREAD_SAFE constexpr wchar16_t utf8_wchar16(uchar b0, uchar b1, uchar b2)
4917{
4918 return (wchar16_t(b0 & 0x0f) << 12)
4919 | (wchar16_t(b1 & 0x3f) << 6)
4920 | (b2 & 0x3f);
4921}
4922
4923//-------------------------------------------------------------------------
4924inline THREAD_SAFE constexpr wchar32_t utf8_wchar32(uchar b0, uchar b1, uchar b2, uchar b3)
4925{
4926 return (wchar32_t(b0 & 0x07) << 18)
4927 | (wchar32_t(b1 & 0x3f) << 12)
4928 | (wchar32_t(b2 & 0x3f) << 6)
4929 | (b3 & 0x3f);
4930}
4931
4932#endif // __cplusplus
4933
4934
4935#define BADCP wchar32_t(-1)
4936
4938
4939idaman THREAD_SAFE wchar32_t ida_export get_utf8_char(const char **pptr);
4940
4941
4948
4949idaman THREAD_SAFE bool ida_export prev_utf8_char(wchar32_t *out_cp, const char **p, const char *begin);
4950
4951
4962
4963idaman THREAD_SAFE size_t ida_export skip_utf8(const char **putf8, size_t n);
4964
4965
4971
4972idaman THREAD_SAFE ssize_t ida_export put_utf8_char(char *out, wchar32_t cp);
4973
4974
4976
4977idaman THREAD_SAFE bool ida_export is_cp_graphical(wchar32_t cp);
4978
4979
4980// Get number of codepoints in UTF-8 string. Any 'bad' byte
4981// (i.e., can't be decoded) counts for 1 codepoint.
4982
4983idaman THREAD_SAFE size_t ida_export qustrlen(const char *utf8);
4984
4985
4990
4991idaman THREAD_SAFE bool ida_export qustrncpy(char *dst, const char *utf8, size_t dstsize);
4992
4993
4994// A few Unicode-related helpful defines
4995
4996#define CP_BOM 0xFEFF
4997#define UTF8_BOM "\xEF\xBB\xBF"
4998#define UTF8_BOM_SZ (sizeof(UTF8_BOM) - 1)
4999
5000#define UTF16LE_BOM "\xFF\xFE"
5001#define UTF16BE_BOM "\xFE\xFF"
5002#define UTF16_BOM_SZ (sizeof(UTF16LE_BOM) - 1)
5003
5004#define UTF32LE_BOM "\xFF\xFE\x00\x00"
5005#define UTF32BE_BOM "\x00\x00\xFE\xFF"
5006#define UTF32_BOM_SZ (sizeof(UTF32LE_BOM) - 1)
5007
5008#define CP_ELLIPSIS 0x2026
5009#define UTF8_ELLIPSIS "\xE2\x80\xA6"
5010#define UTF8_ELLIPSIS_SZ (sizeof(UTF8_ELLIPSIS) - 1)
5011
5012#define CP_REPLCHAR 0xFFFD
5013#define UTF8_REPLCHAR "\xEF\xBF\xBD"
5014#define UTF8_REPLCHAR_SZ (sizeof(UTF8_REPLCHAR) - 1)
5015
5016
5017// To cover unicode, 4 bytes is enough. Still, from the UTF-8 spec at
5018// https://tools.ietf.org/html/rfc3629:
5019// "Another security issue occurs when encoding to UTF-8: the ISO/IEC
5020// 10646 description of UTF-8 allows encoding character numbers up to
5021// U+7FFFFFFF, yielding sequences of up to 6 bytes. There is therefore
5022// a risk of buffer overflow if the range of character numbers is not
5023// explicitly limited to U+10FFFF or if buffer sizing doesn't take into
5024// account the possibility of 5- and 6-byte sequences."
5025// Furthermore, since buffers holding UTF-8 sequences are usually placed
5026// onto the stack, it's probably not a bad thing to make them 8-bytes
5027// aligned -- and keep room for a terminating zero, too.
5028#define MAX_UTF8_SEQ_LEN (6 + 1 + 1)
5029
5030//------------------------------------------------------------------------
5032idaman bool ida_export is_cvt64();
5033
5034
5035
5039#define CEF_RETERR 0x1 // return -1 if iconv() returns -1
5041
5052
5053idaman ssize_t ida_export convert_encoding(
5054 bytevec_t *out,
5055 const char *fromcode,
5056 const char *tocode,
5057 const uchar *indata,
5058 ssize_t insize,
5059 DEFARG(int flags,0));
5060
5061#ifdef __cplusplus
5063 bytevec_t *out,
5064 const char *fromcode,
5065 const char *tocode,
5066 const bytevec_t *indata,
5067 DEFARG(int flags,0))
5068{
5069 QASSERT(1451, ssize_t(indata->size()) >= 0);
5070 return convert_encoding(out, fromcode, tocode, indata->begin(), ssize_t(indata->size()), flags);
5071}
5072#endif
5073
5074#define ENC_WIN1252 "windows-1252"
5075#define ENC_UTF8 "UTF-8"
5076#define ENC_MUTF8 "MUTF-8" // modified UTF-8, used by Dalvik and Java (https://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8)
5077#define ENC_UTF16 "UTF-16"
5078#define ENC_UTF16LE "UTF-16LE"
5079#define ENC_UTF16BE "UTF-16BE"
5080#define ENC_UTF32 "UTF-32"
5081#define ENC_UTF32LE "UTF-32LE"
5082#define ENC_UTF32BE "UTF-32BE"
5083
5084
5085
5086#ifndef CP_UTF8
5087#define CP_UTF8 65001
5088#endif
5089
5090#ifndef CP_UTF16
5091#define CP_UTF16 1200
5092#endif
5093
5094#ifdef __NT__
5095# ifndef INVALID_FILE_ATTRIBUTES
5096# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
5097# endif
5098# ifndef BELOW_NORMAL_PRIORITY_CLASS
5099# define BELOW_NORMAL_PRIORITY_CLASS 0x00004000
5100# endif
5101#endif
5102
5103#define SUBSTCHAR '_'
5104
5107typedef ea_t tid_t;
5108
5110#define DEFCOLOR bgcolor_t(-1)
5111
5112//-------------------------------------------------------------------------
5113// Command line
5114//-------------------------------------------------------------------------
5115
5116#ifdef __cplusplus
5119{
5120 int fd;
5123 int flags;
5127#define IOREDIR_INPUT 0x01
5128#define IOREDIR_OUTPUT 0x02
5129#define IOREDIR_APPEND 0x04
5130#define IOREDIR_QUOTED 0x08
5132 bool is_input(void) const { return (flags & IOREDIR_INPUT) != 0; }
5133 bool is_output(void) const { return (flags & IOREDIR_OUTPUT) != 0; }
5134 bool is_append(void) const { return (flags & IOREDIR_APPEND) != 0; }
5135 bool is_quoted(void) const { return (flags & IOREDIR_QUOTED) != 0; }
5136 int start;
5138};
5140#else
5141typedef struct channel_redirs_tag channel_redirs_t;
5142typedef struct qstrvec_tag qstrvec_t;
5143#endif
5144
5153
5154idaman THREAD_SAFE size_t ida_export parse_command_line(
5155 qstrvec_t *args,
5156 channel_redirs_t *redirs,
5157 const char *cmdline,
5158 int flags);
5159
5160
5171
5172char **expand_argv(int *p_argc, int argc, const char *const argv[]);
5173
5174
5176
5177INLINE void free_argv(int argc, char **argv)
5178{
5179 int i;
5180 if ( argv != nullptr )
5181 {
5182 for ( i = 0; i < argc; i++ )
5183 qfree(argv[i]);
5184 qfree(argv);
5185 }
5186}
5187
5188
5193
5194idaman bool ida_export quote_cmdline_arg(qstring *arg);
5195
5196//-------------------------------------------------------------------------
5197// Command-line tools
5198//-------------------------------------------------------------------------
5199typedef void cliopt_handler_t(const char *value, void *ud);
5200typedef void cliopt_poly_handler_t(int argc, const char **argv, void *ud);
5202{
5204 const char *longname;
5205 const char *help; // nullptr means hidden from usage
5207 int nargs; // number of arguments. Can be 0, 1 or -1.
5208 // If '-1', it means 'poly_handler' will be used
5209};
5211
5212struct cliopts_t;
5213#ifndef SWIG
5214# define DEFINE_CLIOPTS_T_HELPERS(decl) \
5215 decl void ida_export cliopts_t_add(cliopts_t &, const cliopt_t *, size_t); \
5216 decl int ida_export cliopts_t_apply(cliopts_t &, int, const char *[], void *); \
5217 decl const cliopt_t *ida_export cliopts_t_find_short(const cliopts_t &, char); \
5218 decl const cliopt_t *ida_export cliopts_t_find_long(const cliopts_t &, const char *); \
5219 decl NORETURN void ida_export cliopts_t_usage(const cliopts_t &, bool);
5220#else
5221# define DEFINE_CLIOPTS_T_HELPERS(decl)
5222#endif // SWIG
5223DEFINE_CLIOPTS_T_HELPERS(idaman)
5224
5225struct cliopts_t : public qvector<cliopt_t>
5226{
5227 qstring prog_name;
5228 qstring epilog;
5229 typedef AS_PRINTF(1, 2) int usage_printer_t(const char *format, ...);
5230 usage_printer_t *printer;
5231 bool print_usage;
5232
5233 cliopts_t(usage_printer_t *_printer, bool _print_usage = true)
5234 : printer(_printer)
5235 , print_usage(_print_usage)
5236 {}
5237
5238 void add(const cliopt_t *opts, size_t nopts) { cliopts_t_add(*this, opts, nopts); }
5239 int apply(int argc, const char *argv[], void *ud=nullptr) { return cliopts_t_apply(*this, argc, argv, ud); }
5240 const cliopt_t *find_short(char shortname) const { return cliopts_t_find_short(*this, shortname); }
5241 const cliopt_t *find_long(const char *longname) const { return cliopts_t_find_long(*this, longname); }
5242 void usage(bool is_error=true) const { return cliopts_t_usage(*this, is_error); }
5243
5244private:
5245 DEFINE_CLIOPTS_T_HELPERS(friend);
5246};
5247
5248struct plugin_option_t;
5249#ifndef SWIG
5250# define DEFINE_PLUGIN_OPTION_T_HELPERS(decl) \
5251 decl bool ida_export plugin_option_t_get_bool(const plugin_option_t *, bool *, const char *, bool);
5252#else
5253# define DEFINE_PLUGIN_OPTION_T_HELPERS(decl)
5254#endif // SWIG
5255
5260struct plugin_option_t
5261{
5262 qstring name;
5263 qstring value;
5264 const char *get_value(const char *default_value) const
5265 {
5266 return value.empty() ? default_value : value.c_str();
5267 }
5268 bool get_string(qstring *out, const char *desired_name, const char *default_value) const
5269 {
5270 if ( name != desired_name )
5271 return false;
5272 if ( out != nullptr )
5273 *out = get_value(default_value);
5274 return true;
5275 }
5276 bool get_bool(bool *out, const char *desired_name, bool default_value) const
5277 {
5278 return plugin_option_t_get_bool(this, out, desired_name, default_value);
5279 }
5280
5281private:
5283};
5286
5288{
5289 const plugin_option_t *find(const qstring &name) const
5290 {
5291 for ( const auto &one : *this )
5292 if ( one.name == name )
5293 return &one;
5294 return nullptr;
5295 }
5296
5297 bool erase(const char *name)
5298 {
5299 for ( size_t i = 0; i < size(); ++i )
5300 {
5301 if ( at(i).name == name )
5302 {
5303 qvector::erase(begin() + i);
5304 return true;
5305 }
5306 }
5307 return false;
5308 }
5309};
5310
5317idaman bool ida_export parse_plugin_options(plugin_options_t *opts, const char *optstring);
5318
5324idaman void ida_export build_plugin_options(qstring *out, const plugin_options_t &opts, const char *optname=nullptr);
5325
5326//-------------------------------------------------------------------------
5327// INSTANT DEBUGGING
5328//-------------------------------------------------------------------------
5329
5330#ifdef __cplusplus
5343#else
5344struct instant_dbgopts_t;
5345#endif
5346
5350
5351idaman bool ida_export parse_dbgopts(struct instant_dbgopts_t *ido, const char *r_switch);
5352
5353
5354//-------------------------------------------------------------------------
5355// PROCESSES
5356//-------------------------------------------------------------------------
5357
5362{
5363 size_t cb = sizeof(*this);
5364 int flags = 0;
5368#define LP_NEW_CONSOLE 0x0001
5369#define LP_TRACE 0x0002
5370#define LP_PATH_WITH_ARGS 0x0004
5371#define LP_USE_SHELL 0x0008
5373#define LP_LAUNCH_32_BIT 0x0010
5374#define LP_LAUNCH_64_BIT 0x0020
5376#define LP_NO_ASLR 0x0040
5377#define LP_DETACH_TTY 0x0080
5378#define LP_HIDE_WINDOW 0x0100
5379#define LP_SUSPENDED 0x0200
5380#define LP_DETACHED 0x0400
5381#define LP_REPLACE_ENV 0x0800
5383 const char *path = nullptr;
5384 const char *args = nullptr;
5388 char *env = nullptr;
5392 const char *startdir = nullptr;
5393 void *info = nullptr;
5395};
5396
5399
5400#ifdef __cplusplus
5401idaman THREAD_SAFE void *ida_export launch_process(
5402 const launch_process_params_t &lpp,
5403 qstring *errbuf=nullptr);
5404#else
5405idaman THREAD_SAFE void *ida_export launch_process(
5406 const struct launch_process_params_t *lpp,
5407 qstring *errbuf);
5408#endif
5409
5410
5413
5414idaman THREAD_SAFE int ida_export term_process(void *handle);
5415
5416
5421
5422idaman THREAD_SAFE int ida_export qwait_timed(int *status, int child, int flags, int timeout_ms);
5423
5424#if defined(__UNIX__)
5425# ifdef WCONTINUED
5426# define QWCONTINUED WCONTINUED
5427# else
5428# define QWCONTINUED 8
5429# endif
5430# ifdef WNOHANG
5431# define QWNOHANG WNOHANG
5432# else
5433# define QWNOHANG 1
5434# endif
5435inline THREAD_SAFE int qwait(int *status, int child, int flags)
5436{
5437 return qwait_timed(status, child, flags, (flags & QWNOHANG) != 0 ? 0 : -1);
5438}
5439#endif
5440
5441
5453
5454idaman THREAD_SAFE int ida_export check_process_exit(
5455 void *handle,
5456 int *exit_code,
5457 DEFARG(int msecs,-1));
5458
5466
5467
5470
5471idaman THREAD_SAFE enum tty_control_t ida_export is_control_tty(int fd);
5472
5473
5477
5478idaman THREAD_SAFE void ida_export qdetach_tty(void);
5479
5480
5484
5485idaman THREAD_SAFE void ida_export qcontrol_tty(void);
5486
5487//-------------------------------------------------------------------------
5489//-------------------------------------------------------------------------
5490
5492typedef int idaapi qthread_cb_t(void *ud);
5493
5495#ifdef __cplusplus
5496#define OPAQUE_HANDLE(n) typedef struct __ ## n {} *n
5497#else
5498#define OPAQUE_HANDLE(n) typedef struct __ ## n { char __dummy; } *n
5499#endif
5500OPAQUE_HANDLE(qthread_t);
5501
5502
5504
5505idaman THREAD_SAFE qthread_t ida_export qthread_create(qthread_cb_t *thread_cb, void *ud);
5506
5507
5510
5511idaman THREAD_SAFE void ida_export qthread_free(qthread_t q);
5512
5513
5515
5516idaman THREAD_SAFE bool ida_export qthread_join(qthread_t q);
5517
5518
5520
5521idaman THREAD_SAFE bool ida_export qthread_kill(qthread_t q);
5522
5523
5525
5526idaman THREAD_SAFE qthread_t ida_export qthread_self(void);
5527
5528
5530
5531idaman THREAD_SAFE bool ida_export qthread_same(qthread_t q);
5532
5533
5535
5536idaman THREAD_SAFE bool ida_export qthread_equal(qthread_t q1, qthread_t q2);
5537
5538
5540
5541idaman THREAD_SAFE bool ida_export is_main_thread(void);
5542
5543
5545
5546idaman THREAD_SAFE bool ida_export qsetenv(const char *varname, const char *value);
5547idaman THREAD_SAFE bool ida_export qgetenv(const char *varname, DEFARG(qstring *buf, nullptr));
5548
5549
5550//-------------------------------------------------------------------------
5553//-------------------------------------------------------------------------
5554OPAQUE_HANDLE(qsemaphore_t);
5555
5556idaman THREAD_SAFE qsemaphore_t ida_export qsem_create(const char *name, int init_count);
5557idaman THREAD_SAFE bool ida_export qsem_free(qsemaphore_t sem);
5558idaman THREAD_SAFE bool ida_export qsem_post(qsemaphore_t sem);
5559idaman THREAD_SAFE bool ida_export qsem_wait(qsemaphore_t sem, int timeout_ms);
5560
5561//-------------------------------------------------------------------------
5563//-------------------------------------------------------------------------
5565idaman THREAD_SAFE bool ida_export qmutex_free(qmutex_t m);
5566idaman THREAD_SAFE qmutex_t ida_export qmutex_create(void);
5567idaman THREAD_SAFE bool ida_export qmutex_lock(qmutex_t m);
5568idaman THREAD_SAFE bool ida_export qmutex_unlock(qmutex_t m);
5569
5570
5571#ifdef __cplusplus
5574{
5575 qmutex_t lock;
5576public:
5577 qmutex_locker_t(qmutex_t _lock) : lock(_lock) { qmutex_lock(lock); }
5579};
5580#endif
5581
5582//-------------------------------------------------------------------------
5583// PIPES
5584//-------------------------------------------------------------------------
5585#ifdef __NT__
5586typedef void *qhandle_t;
5588#else
5589typedef int qhandle_t;
5590const qhandle_t NULL_PIPE_HANDLE = -1;
5591#endif
5592
5593
5599
5600idaman THREAD_SAFE int ida_export qpipe_create(qhandle_t handles[2]);
5601
5602
5604
5605idaman THREAD_SAFE ssize_t ida_export qpipe_read(qhandle_t handle, void *buf, size_t size);
5606
5612
5613idaman THREAD_SAFE bool ida_export qpipe_read_n(qhandle_t handle, bytevec_t *out_bytes, size_t n);
5614
5616
5617idaman THREAD_SAFE ssize_t ida_export qpipe_write(qhandle_t handle, const void *buf, size_t size);
5618
5619
5621
5622idaman THREAD_SAFE int ida_export qpipe_close(qhandle_t handle);
5623
5624
5632
5633idaman void *ida_export pipe_process(
5634 qhandle_t *read_handle,
5635 qhandle_t *write_handle,
5637 qstring *errbuf=nullptr);
5638
5639
5650
5651idaman THREAD_SAFE int ida_export qwait_for_handles(
5652 int *idx,
5653 const qhandle_t *handles,
5654 int n,
5655 uint32 write_bitmask,
5656 int timeout_ms);
5657
5661
5662idaman THREAD_SAFE bool ida_export get_login_name(qstring *out);
5663
5666
5667idaman THREAD_SAFE int ida_export get_physical_core_count();
5668
5671
5672idaman THREAD_SAFE int ida_export get_logical_core_count();
5673
5677
5678idaman THREAD_SAFE int ida_export get_available_core_count();
5679
5680
5681#endif /* _PRO_H */
idaman int ida_export nbits(ea_t ea)
Get number of bits in a byte at the given address.
Reimplementation of the string class from STL.
Definition pro.h:3158
va_end(copy)
void inject(qchar *s, size_t len)
Assign this qstring to an existing char *.
Definition pro.h:3376
_qstring & insert(size_t idx, const qchar *str, size_t addlen)
Insert a string into the qstring.
Definition pro.h:3523
_qstring & insert(size_t idx, const _qstring &qstr)
Same as insert(size_t, const qchar *), but takes a qstring parameter.
Definition pro.h:3549
void swap(_qstring< qchar > &r)
Swap contents of two qstrings. see qvector::swap()
Definition pro.h:3198
_qstring & append(const qchar *str, size_t addlen)
Append a string to the qstring.
Definition pro.h:3580
_qstring & operator+=(const _qstring &r)
Append another qstring using '+='.
Definition pro.h:3293
const qchar * const_iterator
Definition pro.h:3252
bool empty(void) const
Does the qstring have 0 non-null elements?
Definition pro.h:3244
_qstring & operator=(const qchar *str)
Allow assignment of qstrings using '='.
Definition pro.h:3258
_qstring(const qchar *ptr)
Constructor - creates a new qstring from an existing char *.
Definition pro.h:3172
_qstring operator+(const _qstring &r) const
Get result of appending two qstrings using '+'.
Definition pro.h:3298
_qstring & insert(const qchar *str)
Prepend the qstring with 'str'.
Definition pro.h:3566
_qstring & fill(qchar c, size_t len)
Clear contents of qstring and fill with 'c'.
Definition pro.h:3688
va_copy(copy, va)
_qstring(const qchar *ptr, size_t len)
Constructor - creates a new qstring using first 'len' chars from 'ptr'.
Definition pro.h:3178
size_t rfind(qchar c, size_t pos=0) const
Search backwards for a character in the qstring.
Definition pro.h:3459
size_t find(qchar c, size_t pos=0) const
Find a character in the qstring.
Definition pro.h:3444
const_iterator begin(void) const
Get a const pointer to the beginning of the qstring.
Definition pro.h:3254
_qstring & insert(const _qstring &qstr)
Prepend the qstring with 'qstr'.
Definition pro.h:3567
_qstring & nowarn_sprnt(const char *format,...)
Definition pro.h:3662
_qstring & operator=(_qstring &&x) noexcept
Move assignment operator.
Definition pro.h:3281
void resize(size_t s, qchar c)
Resize to the given size.
Definition pro.h:3207
qchar * extract(void)
Extract C string from _qstring. Must qfree() it.
Definition pro.h:3373
vsprnt(format, va)
const_iterator end(void) const
Get a const pointer to the end of the qstring (this is not the terminating zero)
Definition pro.h:3256
bool starts_with(const _qstring &str) const
Does the string start with the specified prefix?
Definition pro.h:3320
va_start(va, format)
_qstring(_qstring &&x)
Move constructor.
Definition pro.h:3194
bool ends_with(const _qstring &str) const
Does the string end with the specified suffix?
Definition pro.h:3337
size_t size(void) const
Get number of chars in this qstring (including terminating zero)
Definition pro.h:3200
void qclear(void)
Clear qstring but do not free memory yet.
Definition pro.h:3243
iterator begin(void)
Get a pointer to the beginning of the qstring.
Definition pro.h:3253
_qstring & rtrim()
Remove all whitespace from the end of the qstring.
Definition pro.h:3727
GCC_DIAG_ON(format-nonliteral)
static constexpr size_t npos
Definition pro.h:3769
void push_back(qchar c)
Definition pro.h:3749
AS_PRINTF(2, 0) _qstring &vsprnt(const char *format
Replace qstring with the result of qvsnprintf()
AS_PRINTF(2, 3) _qstring &sprnt(const char *format
Replace qstring with the result of qsnprintf()
AS_PRINTF(2, 0) _qstring &cat_vsprnt(const char *format
Append result of qvsnprintf() to qstring.
_qstring & fill(size_t pos, qchar c, size_t len)
Fill qstring with a character.
Definition pro.h:3676
qchar & at(size_t idx)
Retrieve char at index 'idx'.
Definition pro.h:3371
size_t capacity(void) const
Get number of chars this qstring can contain (including terminating zero)
Definition pro.h:3201
void remove_last(int cnt=1)
Definition pro.h:3228
_qstring< qchar > substr(size_t pos=0, size_t n=npos) const
Get a substring.
Definition pro.h:3474
size_t find(const _qstring &str, size_t pos=0) const
Same as find(const qchar *, size_t), but takes a qstring parameter.
Definition pro.h:3439
_qstring & operator=(const _qstring &qstr)
Definition pro.h:3267
const qchar & operator[](size_t idx) const
Retrieve char at index 'idx' using '[]'.
Definition pro.h:3355
size_t length(void) const
Get number of chars in this qstring (not including terminating zero)
Definition pro.h:3199
_qstring & insert(qchar c)
Prepend the qstring with 'c'.
Definition pro.h:3565
void split(qvector< _qstring< qchar > > *out, const qchar *sep, uint32 flags=0) const
Split a string on SEP, appending the parts to OUT.
qchar & operator[](size_t idx)
Retrieve char at index 'idx' using '[]'.
Definition pro.h:3363
_qstring(void)
Constructor.
Definition pro.h:3170
va_list va
Definition pro.h:3613
qchar * iterator
Definition pro.h:3251
size_t find(const qchar *str, size_t pos=0) const
Find a substring.
Definition pro.h:3399
_qstring & remove(size_t idx, size_t cnt)
Remove characters from the qstring.
Definition pro.h:3484
bool operator<(const qchar *r) const
Compare two qstrings using '<'. see qstrcmp()
Definition pro.h:3315
static _qstring< qchar > join(const qvector< _qstring< qchar > > &parts, const qchar *sep)
Join the provided parts into a single string with each element separated by SEP.
iterator end(void)
Get a pointer to the end of the qstring (this is not the terminating zero)
Definition pro.h:3255
_qstring & ltrim(qchar blank=' ')
Remove all instances of the specified char from the beginning of the qstring.
Definition pro.h:3696
_qstring & append(qchar c)
Append c to the end of the qstring.
Definition pro.h:3569
void reserve(size_t cnt)
Increase capacity the qstring. see qvector::reserve()
Definition pro.h:3241
void inject(qchar *s)
Same as to inject(qchar *, size_t), with len = strlen(s)
Definition pro.h:3381
_qstring & insert(size_t idx, qchar c)
Insert a character into the qstring.
Definition pro.h:3505
qchar value_type
Definition pro.h:3167
_qstring(const _qstring &r)
Copy constructor (if not declared, move constructor causes it to be deleted)
Definition pro.h:3196
_qstring & append(const qchar *str)
Same as append(const qchar *, size_t), but all chars in 'str' are appended.
Definition pro.h:3589
qchar last(void) const
Get the last qchar in the string (for concatenation checks)
Definition pro.h:3390
size_t add
Definition pro.h:3616
_qstring & trim2(qchar blank=' ')
Remove all instances of the specified char from both ends of the qstring.
Definition pro.h:3740
bool replace(const qchar *what, const qchar *with)
Replace all occurrences of 'what' with 'with'.
Definition pro.h:3412
void resize(size_t s)
Similar to resize(size_t, qchar) - but any extra space is filled with zeros.
Definition pro.h:3216
bool operator!=(const qchar *r) const
Test equality of a qstring and a const char* with '!='.
Definition pro.h:3313
_qstring(size_t count, qchar ch)
Constructor - constructs the string with 'count' copies of character 'ch'.
Definition pro.h:3184
AS_PRINTF(2, 3) _qstring &cat_sprnt(const char *format
Append result of qsnprintf() to qstring.
const qchar & at(size_t idx) const
Retrieve const char at index 'idx'.
Definition pro.h:3370
_qstring & append(const _qstring &qstr)
Same as append(const qchar *), but takes a qstring argument.
Definition pro.h:3599
bool starts_with(const qchar *ptr, ssize_t len=-1) const
Definition pro.h:3324
const qchar * c_str(void) const
Convert the qstring to a char *.
Definition pro.h:3246
bool operator==(const qchar *r) const
Test equality of a qstring and a const char* using '=='.
Definition pro.h:3309
cat_vsprnt(format, va)
_qstring & insert(size_t idx, const qchar *str)
Same as insert(size_t, const qchar *, size_t), but all chars in str are inserted.
Definition pro.h:3539
GCC_DIAG_OFF(format-nonliteral)
Replace qstring with the result of qsnprintf()
_qstring & rtrim(qchar blank, size_t minlen=0)
Remove all instances of the specified char from the end of the qstring.
Definition pro.h:3713
DECLARE_COMPARISONS(_qstring)
Definition pro.h:3304
void clear(void)
Clear qstring and free memory.
Definition pro.h:3242
bool ends_with(const qchar *ptr, ssize_t len=-1) const
Definition pro.h:3341
_qstring & operator+=(qchar c)
Append a char using '+='.
Definition pro.h:3288
Vector of bytes (use for dynamic memory)
Definition pro.h:3850
void clear_bits(const bytevec_t &b)
For each bit that is set in 'b', the clear the corresponding bit in this bytevec.
Definition pro.h:4072
void pack_bytevec(const bytevec_t &b)
Pack an object of size 'len' and append the result to the bytevec.
Definition pro.h:3954
bool fromhex(const qstring &str)
Initialize from a hexadecimal string It returns 'false' if the string is invalid.
Definition pro.h:4027
void tohex(qstring *out, bool upper_case=true) const
Append the hexadecimal representation of bytes to the string.
Definition pro.h:4004
void pack_eavec(ea_t ea, const eavec_t &vec)
Pack an eavec and append the result to the bytevec.
Definition pro.h:3969
void pack_buf(const void *buf, size_t len)
Pack an object of size 'len' and append the result to the bytevec.
Definition pro.h:3945
bool test_bit(size_t bit) const
Is the specified bit set in the bytevec?
Definition pro.h:4043
bytevec_t()
Constructor.
Definition pro.h:3853
void pack_str(const qstring &s)
Pack a string (zero-terminated) and append the result to the bytevec.
Definition pro.h:3936
bool all_zeros() const
Are all bits cleared?
Definition pro.h:4053
void set_bits(const bytevec_t &b)
For each bit that is set in 'b', set the corresponding bit in this bytevec.
Definition pro.h:4061
void clear_bits(size_t low, size_t high)
Clear each bit between [low, high)
Definition pro.h:4080
bytevec_t & growfill(size_t sz, uchar filler=0)
Grow the bytevec and fill with a value.
Definition pro.h:3985
void pack_ea(ea_t x)
Pack an ea value and append the result to the bytevec.
Definition pro.h:3896
void inject(void *buf, size_t len)
See qvector::inject(T *, size_t)
Definition pro.h:3998
void pack_db(uint8 x)
Pack a byte and append the result to the bytevec.
Definition pro.h:3873
void set_bit(size_t bit)
Set the specified bit.
Definition pro.h:4045
void clear_bit(size_t bit)
Clear the specified bit.
Definition pro.h:4047
void set_all_bits(size_t nbits)
See set_all_bits(uchar *, size_t)
Definition pro.h:4049
void pack_dd(uint32 x)
Pack a dword and append the result to the bytevec.
Definition pro.h:3882
void set_bits(size_t low, size_t high)
Set each bit between [low, high)
Definition pro.h:4070
qstring tohex(bool upper_case=true) const
Produce a hexadecimal representation of bytes.
Definition pro.h:4018
void clear_all_bits(size_t nbits)
See clear_all_bits(uchar *, size_t)
Definition pro.h:4051
bytevec_t(const void *buf, size_t sz)
Constructor - fill bytevec with 'sz' bytes from 'buf'.
Definition pro.h:3855
void pack_dw(uint16 x)
Pack a word and append the result to the bytevec.
Definition pro.h:3875
bytevec_t & append(const void *buf, size_t sz)
Append bytes to the bytevec.
Definition pro.h:3859
void pack_ds(const char *x)
Pack a string (length+contents) and append the result to the bytevec.
Definition pro.h:3916
void pack_dq(uint64 x)
Pack a quadword and append the result to the bytevec.
Definition pro.h:3889
void pack_str(const char *str)
Pack a string (zero-terminated) and append the result to the bytevec.
Definition pro.h:3928
void pack_ea64(ea64_t ea)
Pack an ea value (64bits) and append the result to the bytevec We pass ea_t as a 64-bit quantity (to ...
Definition pro.h:3907
pool_allocator_t(const pool_allocator_t &)
Definition pro.h:2915
T * allocate(size_t n)
Definition pro.h:2922
pool_allocator_t(const pool_allocator_t< U > &)
Definition pro.h:2914
pool_allocator_t & operator=(const pool_allocator_t &)
Definition pro.h:2916
bool operator==(const pool_allocator_t &r) const
Definition pro.h:2919
T value_type
Definition pro.h:2906
void deallocate(T *ptr, size_t n)
Definition pro.h:2945
pool_allocator_t & operator=(pool_allocator_t &&)=default
const T * const_pointer
Definition pro.h:2908
pool_allocator_t(pool_allocator_t &&)=default
T * pointer
Definition pro.h:2907
pool_allocator_t()
Definition pro.h:2913
const T & const_reference
Definition pro.h:2910
size_t size_type
Definition pro.h:2911
T & reference
Definition pro.h:2909
ptrdiff_t difference_type
Definition pro.h:2912
Interface class for iterator types.
Definition pro.h:3060
virtual T idaapi operator*(void)=0
source_item_ptr value_type
Definition pro.h:3062
virtual bool idaapi next(void)=0
virtual T get(void) new api
Definition pro.h:3066
virtual bool idaapi first(void)=0
Linked list Note: linked list is not movable!
Definition pro.h:4115
~qlist(void)
Destructor.
Definition pro.h:4232
const
Definition pro.h:4194
DEFINE_REVERSE_ITERATOR(reverse_iterator, iterator) DEFINE_REVERSE_ITERATOR(const_reverse_iterator
DEFINE_LIST_ITERATOR(iterator,, friend class const_iterator;) DEFINE_LIST_ITERATOR(const_iterator
qlist(qlist &&x)
Constructor - moves the data from x
Definition pro.h:4226
const_iterator(const iterator &x)
Definition pro.h:4194
cinsn_t value_type
Definition pro.h:4151
const_iterator qlist(void)
Constructor.
Definition pro.h:4218
qlist(const qlist< T > &x)
Constructor - creates a qlist identical to 'x'.
Definition pro.h:4220
~qmutex_locker_t(void)
Definition pro.h:5578
qmutex_locker_t(qmutex_t _lock)
Definition pro.h:5577
virtual void idaapi release(void)=0
Call destructor.
int refcnt
counter
Definition pro.h:3046
qrefcnt_obj_t(void)
Constructor.
Definition pro.h:3048
void reset(void)
Definition pro.h:3022
qrefcnt_t & operator=(const qrefcnt_t &r)
Definition pro.h:3010
T & operator*() const
Definition pro.h:3035
qrefcnt_t(T *p)
Definition pro.h:3004
T * operator->() const
Definition pro.h:3031
~qrefcnt_t(void)
Definition pro.h:3018
qrefcnt_t(const qrefcnt_t &r)
Definition pro.h:3005
Reimplementation of stack class from STL.
Definition pro.h:2848
T pop(void)
Definition pro.h:2851
void push(const T &v)
Definition pro.h:2862
const T & top(void) const
Definition pro.h:2857
T & top(void)
Definition pro.h:2861
Reimplementation of vector class from STL.
Definition pro.h:2262
void reserve(size_t cnt)
Increase the capacity of the qvector.
Definition pro.h:2605
void clear(void)
Destroy all elements and free memory.
Definition pro.h:2510
DEFINE_MEMORY_ALLOCATION_FUNCS() void push_back(const T &x)
Append a new element to the end the qvector.
Definition pro.h:2420
void inject(T *s, size_t len)
Populate the qvector with dynamic memory.
Definition pro.h:2661
void resize_noinit(size_t _newsize)
Definition pro.h:2581
iterator erase(iterator first, iterator last)
Remove a subset of the qvector.
Definition pro.h:2764
const compiled_binpat_t * const_iterator
Definition pro.h:2681
bool del(const T &x)
Find an element and remove it.
Definition pro.h:2823
const T & operator[](size_t _idx) const
Allows use of typical c-style array indexing for qvectors.
Definition pro.h:2496
void emplace_back(Args &&... args)
Construct and append a new element to the end the qvector with a forwarding semantics.
Definition pro.h:2461
T & at(size_t _idx)
Get element at index '_idx'.
Definition pro.h:2499
~qvector(void)
Destructor.
Definition pro.h:2412
void swap(qvector< T > &r) noexcept
Replace all attributes of this qvector with that of 'r', and vice versa.
Definition pro.h:2634
void truncate(void)
Shrink the capacity down to the current number of elements.
Definition pro.h:2627
const_iterator find(const T &x) const
Find an element in the qvector.
Definition pro.h:2787
qvector(const qvector< T > &x)
Constructor - creates a new qvector identical to 'x'.
Definition pro.h:2376
bool empty(void) const
Does the qvector have 0 elements?
Definition pro.h:2495
iterator erase(iterator it)
Remove an element from the qvector.
Definition pro.h:2752
void qclear(void)
Destroy all elements but do not free memory.
Definition pro.h:2505
iterator end(void)
Get an iterator that points to the end of the qvector (NOT the last element)
Definition pro.h:2684
T & operator[](size_t _idx)
Allows use of typical c-style array indexing for qvectors.
Definition pro.h:2497
compiled_binpat_t value_type
Definition pro.h:2372
bool operator!=(const qvector< T > &r) const
Allow ability to test equality of two qvectors using '!='.
Definition pro.h:2678
iterator insert(iterator it, const T &x)
Insert an element into the qvector at a specified position.
Definition pro.h:2691
iterator insert(iterator it, T &&x)
Insert an element into the qvector with a move semantics.
Definition pro.h:2708
const_iterator begin(void) const
Get a const iterator that points to the first element in the qvector.
Definition pro.h:2685
void resize(size_t _newsize, const T &x)
Resize to the given size.
Definition pro.h:2540
const char * dstr(void) const
qvector< T > & operator=(const qvector< T > &x)
Allow assignment of one qvector to another using '='.
Definition pro.h:2519
const T & at(size_t _idx) const
Get element at index '_idx'.
Definition pro.h:2498
void add(T &&x)
Definition pro.h:2806
void add(const T &x)
Add an element to the end of the qvector.
Definition pro.h:2805
const T & back(void) const
Get the last element in the qvector.
Definition pro.h:2502
qvector(std::initializer_list< T > l)
Initializer list constructor.
Definition pro.h:2386
iterator find(const T &x)
Find an element in the qvector.
Definition pro.h:2777
qvector(void)
Constructor.
Definition pro.h:2374
T & back(void)
Get the last element in the qvector.
Definition pro.h:2503
T * extract(void)
Empty the qvector and return a pointer to it's contents.
Definition pro.h:2650
void grow(const T &x=T())
Add an element to the end of the qvector, which will be a new T() if x is not given.
Definition pro.h:2590
const T & front(void) const
Get the first element in the qvector.
Definition pro.h:2500
bool operator==(const qvector< T > &r) const
Allow ability to test the equality of two qvectors using '=='.
Definition pro.h:2668
void pop_back(void)
Remove the last element in the qvector.
Definition pro.h:2482
iterator insert(iterator it, it2 first, it2 last)
Insert a several elements to the qvector at a specified position.
Definition pro.h:2729
T & push_back(void)
Append a new empty element to the end of the qvector.
Definition pro.h:2473
compiled_binpat_t * iterator
Definition pro.h:2680
iterator begin(void)
Get an iterator that points to the first element in the qvector.
Definition pro.h:2683
void push_back(compiled_binpat_t &&x)
Definition pro.h:2432
T & front(void)
Get the first element in the qvector.
Definition pro.h:2501
const_iterator end(void) const
Get a const iterator that points to the end of the qvector (NOT the last element)
Definition pro.h:2686
friend void *ida_export qvector_reserve(void *vec, void *old, size_t cnt, size_t elsize)
Change capacity of given qvector.
size_t capacity(void) const
Get the number of elements that this qvector can contain - not the same as the number of elements cur...
Definition pro.h:2602
void resize(size_t _newsize)
Same as resize(size_t, const T &), but extra space is filled with empty elements.
Definition pro.h:2556
size_t size(void) const
Get the number of elements in the qvector.
Definition pro.h:2494
ssize_t index(const T &x) const
Find index of the specified value or return -1.
Definition pro.h:2797
bool add_unique(const T &x)
Add an element to the end of the qvector - only if it isn't already present.
Definition pro.h:2813
qvector(qvector< T > &&x) noexcept
Move constructor.
Definition pro.h:2379
bool has(const T &x) const
Does the qvector contain x?
Definition pro.h:2809
qvector< T > & operator=(qvector< T > &&x) noexcept
Move assignment operator.
Definition pro.h:2526
CASSERT(sizeof(mapping_coords_t)==sizeof(int))
idaman THREAD_SAFE char *ida_export user2str(char *dst, const char *src, size_t dstsize)
Make an internal representation.
idaman THREAD_SAFE char *ida_export str2user(char *dst, const char *src, size_t dstsize)
Make a user representation.
idaman THREAD_SAFE void ida_export user2qstr(qstring *dst, const qstring &src)
see user2str()
idaman THREAD_SAFE char ida_export back_char(const char **p)
Translate char after '\'.
idaman THREAD_SAFE void ida_export qstr2user(qstring *dst, const char *src, int nsyms=-1)
see str2user()
INLINE THREAD_SAFE bool ida_local qislower(char c)
Definition pro.h:946
INLINE THREAD_SAFE bool ida_local qisupper(char c)
Definition pro.h:947
INLINE THREAD_SAFE bool ida_local qisdigit(char c)
Definition pro.h:949
INLINE THREAD_SAFE bool ida_local qisalnum(char c)
Definition pro.h:944
INLINE THREAD_SAFE bool ida_local qispunct(char c)
Definition pro.h:945
INLINE THREAD_SAFE bool ida_local qisalpha(char c)
Definition pro.h:943
INLINE THREAD_SAFE bool ida_local qisxdigit(char c)
Definition pro.h:950
INLINE THREAD_SAFE bool ida_local qisascii(char c)
Definition pro.h:941
INLINE THREAD_SAFE bool ida_local qisprint(char c)
Definition pro.h:948
INLINE THREAD_SAFE bool ida_local qisspace(char c)
Definition pro.h:942
idaman THREAD_SAFE va_list va
See qsscanf()
Definition err.h:21
idaman THREAD_SAFE AS_SCANF(2, 0) int ida_export qvfscanf(FILE *fp
idaman AS_PRINTF(3, 4) THREAD_SAFE int ida_export qsnprintf(char *buffer
va_end(va)
idaman THREAD_SAFE const char * format
Definition fpro.h:78
idaman THREAD_SAFE AS_PRINTF(1, 0) void ida_export vqperror(const char *format
Print error message to stderr (analog of perror)
THREAD_SAFE va_start(va, format)
idaman const char * end
Definition pro.h:1004
int code
Definition fpro.h:88
idaman size_t n
Definition pro.h:1000
THREAD_SAFE bool unpack_sleb128(T *res, const uchar **pptr, const uchar *end)
Definition pro.h:1964
THREAD_SAFE bool unpack_uleb128(T *res, const uchar **pptr, const uchar *end)
Definition pro.h:1957
GCC_DIAG_OFF(format-nonliteral)
cexpr_t * e
Definition hexrays.hpp:7705
const tinfo_t & type
Definition hexrays.hpp:7698
carglist_t * args
Definition hexrays.hpp:7720
idaman int64 size_t count
Definition kernwin.hpp:1399
int nbytes
Definition kernwin.hpp:3037
uval_t uval_t
Definition kernwin.hpp:1926
idaman int64 pos
Definition kernwin.hpp:1398
idaman callui_t ida_export_data(idaapi *callui)(ui_notification_t what
Pointer to the user-interface dispatcher function.
idaman size_t len
Definition kernwin.hpp:1389
asize_t size
Definition kernwin.hpp:6701
void(idaapi *range_marker)(ea_t ea
Pointer to range marker function (for idaviews and hexviews) This pointer is initialized by setup_ran...
bool result
Definition kernwin.hpp:8332
constexpr uint32 low(const uint64 &x)
Definition llong.hpp:24
unsigned __int64 uint64
Definition llong.hpp:13
constexpr uint64 make_uint64(uint32 ll, int32 hh)
Definition llong.hpp:23
constexpr uint32 high(const uint64 &x)
Definition llong.hpp:25
__int64 int64
Definition llong.hpp:14
ea_t ea64_t
Definition lumina.hpp:121
qvector< qstring > qstrvec_t
Definition lumina.hpp:831
Functions to work with intervals.
Definition pro.h:1455
THREAD_SAFE constexpr bool contains(uval_t off1, asize_t s1, uval_t off)
Does (off1,s1) contain off?
Definition pro.h:1472
THREAD_SAFE constexpr uval_t last(uval_t off, asize_t s)
max offset of the interval (assume s != 0)
Definition pro.h:1457
THREAD_SAFE constexpr bool includes(uval_t off1, asize_t s1, uval_t off2, asize_t s2)
Does (off1,s1) include (off2,s2)?
Definition pro.h:1467
THREAD_SAFE constexpr bool overlap(uval_t off1, asize_t s1, uval_t off2, asize_t s2)
Do (off1,s1) and (off2,s2) overlap?
Definition pro.h:1462
Definition pro.h:3781
idaman size_t const char time_t t
Definition pro.h:606
INLINE THREAD_SAFE bool qlocaltime64(struct tm *_tm, qtime64_t t)
Same as qlocaltime(struct tm *, time_t), but accepts a 64-bit time value.
Definition pro.h:564
THREAD_SAFE size_t idaapi qstrlen(const char *s)
Definition pro.h:3074
idaman THREAD_SAFE qtime64_t ida_export qtime64(void)
Get the current time with microsecond resolution (in fact the resolution is worse on windows)
idaman THREAD_SAFE int ida_export get_logical_core_count()
Get the total CPU logical core count.
idaman THREAD_SAFE char *ida_export unpack_ds(const uchar **pptr, const uchar *end, bool empty_null)
Unpack a string.
THREAD_SAFE void * extract_obj(T &v, void *destbuf, size_t destsize)
Definition pro.h:2012
idaman THREAD_SAFE int ida_export memicmp(const void *x, const void *y, size_t size)
idaman THREAD_SAFE void *ida_export qvector_reserve(void *vec, void *old, size_t cnt, size_t elsize)
Change capacity of given qvector.
THREAD_SAFE uchar extract_db(T &v)
Definition pro.h:2004
THREAD_SAFE bool idaapi has_file_ext(const char *file)
Does the given file name have an extension?
Definition pro.h:1168
unsigned short uint16
unsigned 16 bit value
Definition pro.h:350
idaman THREAD_SAFE int ida_export qstat(const char *path, struct qstatbuf *buf)
Get file status.
idaman THREAD_SAFE void *ida_export launch_process(const launch_process_params_t &lpp, qstring *errbuf=nullptr)
Launch the specified process in parallel.
idaman THREAD_SAFE enum tty_control_t ida_export is_control_tty(int fd)
Check if the current process is the owner of the TTY specified by 'fd' (typically an opened descripto...
idaman THREAD_SAFE uint64 ida_export get_nsec_stamp(void)
High resolution timer.
idaman int ida_export bitcountr_zero(uint64 x)
count the number of consecutive trailing zero bits (like C++20 std::countr_zero())
idaman THREAD_SAFE bool ida_export qsetenv(const char *varname, const char *value)
Thread safe function to work with the environment.
idaman THREAD_SAFE int ida_export qchsize(int h, uint64 fsize)
Change file size.
INLINE int nowarn_qsnprintf(char *buf, size_t size, const char *format,...)
Definition pro.h:1013
idaman THREAD_SAFE bool ida_export is_valid_utf8(const char *in)
Does byte sequence consist of valid UTF-8-encoded codepoints?
idaman THREAD_SAFE uchar *ida_export pack_ds(uchar *ptr, uchar *end, const char *x, size_t len=0)
Pack a string.
int bool
Definition pro.h:333
unsigned int uint32
unsigned 32 bit value
Definition pro.h:352
THREAD_SAFE constexpr uint32 swap32(uint32 x)
Definition pro.h:1653
T qrotr(T value, size_t count)
Rotate right.
Definition pro.h:1512
idaman size_t ida_export round_up_power2(size_t x)
round up or down to a power of 2
idaman THREAD_SAFE bool ida_export is_main_thread(void)
Are we running in the main thread?
qvector< int > intvec_t
vector of integers
Definition pro.h:2839
idaman void ida_export build_plugin_options(qstring *out, const plugin_options_t &opts, const char *optname=nullptr)
Build the plugin options, suitable for IDA command line of the form <name1>=<value1>:....
signed char sint8
signed 8 bit value
Definition pro.h:347
idaman THREAD_SAFE bool ida_export qctime(char *buf, size_t bufsize, qtime32_t t)
Converts calendar time into a string.
idaman THREAD_SAFE int ida_export qcreate(const char *file, int stat)
Create new file with O_RDWR, sets qerrno.
idaman THREAD_SAFE const char *ida_export qbasename(const char *path)
Get the file name part of the given path.
idaman THREAD_SAFE char *ida_export vqmakepath(char *buf, size_t bufsize, const char *s1, va_list)
See qmakepath()
idaman THREAD_SAFE bool ida_export qustrncpy(char *dst, const char *utf8, size_t dstsize)
A safer strncpy - makes sure that there is a terminating zero.
idaman THREAD_SAFE bool ida_export qgetenv(const char *varname, DEFARG(qstring *buf, nullptr))
Thread safe function to work with the environment.
constexpr bool is_tail_surrogate(wchar32_t wch)
Definition pro.h:4863
constexpr bool is_utf8_head(char in)
Does this byte correspond to the head of a UTF-8 byte sequence?
Definition pro.h:4824
char ** expand_argv(int *p_argc, int argc, const char *const argv[])
Copy and expand command line arguments.
idaman THREAD_SAFE int ida_export get_physical_core_count()
Get the total CPU physical core count.
idaman THREAD_SAFE char *ida_export qstpncpy(char *dst, const char *src, size_t dstsize)
A safer stpncpy - returns pointer to the end of the destination nb: ssize_t(dstsize) must be > 0.
bool is_sdiv_ok(T a, T b)
Check that signed division is permissible.
Definition pro.h:1562
idaman THREAD_SAFE bool ida_export sanitize_file_name(char *name, size_t namesize)
Sanitize the file name.
T round_down(T val, T base)
Definition pro.h:1446
idaman int ida_export regex_match(const char *str, const char *pattern, bool sense_case)
Match a string with a regular expression.
idaman THREAD_SAFE char *ida_export qmake_full_path(char *dst, size_t dstsize, const char *src)
Convert relative path to absolute path.
uint64 asize_t
Definition pro.h:427
idaman THREAD_SAFE void ida_export qdetach_tty(void)
If the current terminal is the controlling terminal of the calling process, give up this controlling ...
THREAD_SAFE void * extract_buf(T &v, size_t size)
Definition pro.h:2060
idaman THREAD_SAFE int ida_export qwait_timed(int *status, int child, int flags, int timeout_ms)
Wait for state changes in a child process (UNIX only).
idaman THREAD_SAFE int ida_export term_process(void *handle)
Forcibly terminate a running process.
idaman THREAD_SAFE int ida_export qwait_for_handles(int *idx, const qhandle_t *handles, int n, uint32 write_bitmask, int timeout_ms)
Wait for file/socket/pipe handles.
idaman THREAD_SAFE bool ida_export qsem_post(qsemaphore_t sem)
Unlock a semaphore.
idaman THREAD_SAFE const char *ida_export get_file_ext(const char *file)
Get pointer to extension of file name.
idaman THREAD_SAFE size_t ida_export parse_command_line(qstrvec_t *args, channel_redirs_t *redirs, const char *cmdline, int flags)
Parse a space separated string (escaping with backslash is supported).
idaman THREAD_SAFE uint32 ida_export calc_crc32(uint32 crc, const void *buf, size_t len)
Calculate CRC32 (polynom 0xEDB88320, zlib compatible).
idaman THREAD_SAFE size_t ida_export skip_utf8(const char **putf8, size_t n)
Advance by n codepoints into the UTF-8 buffer.
T * qalloc_array(size_t n)
Use this class to avoid integer overflows when allocating arrays.
Definition pro.h:788
constexpr T make_mask(int count)
Make a mask of 'count' bits.
Definition pro.h:1524
INLINE THREAD_SAFE int ida_local qtolower(char c)
Get lowercase equivalent of given char.
Definition pro.h:954
T align_up(T val, int elsize)
Align element up to nearest boundary.
Definition pro.h:4721
uint64 ea64_t
64-bit address, regardless of IDA bitness.
Definition pro.h:457
void shift_up(T *dst, T *src, size_t cnt)
Move data up in memory.
Definition pro.h:2232
idaman THREAD_SAFE char *ida_export qstrtok(char *s, const char *delim, char **save_ptr)
Thread-safe version of strtok.
THREAD_SAFE constexpr int dd_size(uchar first_byte)
Definition pro.h:1991
uint32 ea32_t
32-bit address, regardless of IDA bitness.
Definition pro.h:454
idaman THREAD_SAFE bool ida_export get_login_name(qstring *out)
Get the user name for the current desktop session.
int32 qtime32_t
we use our own time type because time_t can be 32-bit or 64-bit depending on the compiler
Definition pro.h:501
qvector< uval_t > uvalvec_t
vector of unsigned values
Definition pro.h:2836
uint32 wchar32_t
Definition pro.h:375
THREAD_SAFE uchar idaapi unpack_db(const uchar **pptr, const uchar *end)
Unpack a byte from a character string, pack_db()
Definition pro.h:1763
idaman THREAD_SAFE void *ida_export qcalloc(size_t nitems, size_t itemsize)
System independent calloc.
idaman THREAD_SAFE char *ida_export qstrupr(char *str)
Convert the string to uppercase.
THREAD_SAFE void *idaapi unpack_obj(void *destbuf, size_t destsize, const uchar **pptr, const uchar *end)
Unpack an object of a known size.
Definition pro.h:1817
constexpr T right_sshift(const T &value, int shift)
Shift by the amount exceeding the operand size*8 is undefined by the standard.
Definition pro.h:1494
bool is_mul_ok(T count, T elsize)
Check that unsigned multiplication does not overflow.
Definition pro.h:1539
idaman THREAD_SAFE bool ida_export base64_encode(qstring *output, const void *input, size_t size)
Encode base64.
uint32 bgcolor_t
background color in RGB
Definition pro.h:5109
THREAD_SAFE char *idaapi make_file_ext(char *buf, size_t bufsize, const char *file, const char *ext)
Set file name extension if none exists.
Definition pro.h:1183
qvector< size_t > sizevec_t
vector of sizes
Definition pro.h:2841
uint8 op_dtype_t
Definition pro.h:464
adiff_t sval_t
signed value used by the processor.
Definition pro.h:450
idaman THREAD_SAFE bool ida_export qctime_utc(char *buf, size_t bufsize, qtime32_t t)
Converts calendar time into a string using Coordinated Universal Time (UTC).
short int16
signed 16 bit value
Definition pro.h:349
idaman THREAD_SAFE void ida_export swap_value(void *dst, const void *src, int size)
Swap endianness of a given value in memory.
THREAD_SAFE constexpr ushort swap16(ushort x)
Definition pro.h:1657
idaman THREAD_SAFE char *ida_export qstrncpy(char *dst, const char *src, size_t dstsize)
A safer strncpy - makes sure that there is a terminating zero.
T qabs(T x)
Definition pro.h:1360
idaman THREAD_SAFE void *ida_export qrealloc(void *alloc, size_t newsize)
System independent realloc.
idaman THREAD_SAFE void ida_export reloc_value(void *value, int size, adiff_t delta, bool mf)
idaman THREAD_SAFE bool ida_export set_interr_throws(bool enable)
THREAD_SAFE void unpack_eavec(eavec_t *vec, ea_t ea, const uchar **ptr, const uchar *end)
Unpack a vector of ea values.
Definition pro.h:4435
idaman THREAD_SAFE bool ida_export qfileexist(const char *file)
Does the given file exist?
idaman THREAD_SAFE int ida_export read2bytes(int h, uint16 *res, bool mf)
Read a 2 byte entity from a file.
THREAD_SAFE uchar * pack_ea(uchar *ptr, uchar *end, ea_t ea)
Pack an ea value into a character string, see pack_dd()/pack_dq()
Definition pro.h:1782
int64 adiff_t
Definition pro.h:428
idaman AS_STRFTIME(3) THREAD_SAFE size_t ida_export qstrftime(char *buf
Get string representation of a time_t (local time) Copies into 'buf' the content of 'format',...
NORETURN void __debugbreak(void)
idaman THREAD_SAFE void ida_export qsleep(int milliseconds)
Suspend execution for given number of milliseconds.
uint64 ea_t
Definition pro.h:425
idaman THREAD_SAFE NORETURN void ida_export qexit(int code)
Call qatexit functions, shut down UI and kernel, and exit.
THREAD_SAFE const void *idaapi unpack_obj_inplace(const uchar **pptr, const uchar *end, size_t objsize)
In-place version of unpack_obj().
Definition pro.h:1863
constexpr T right_ushift(const T &value, int shift)
Shift by the amount exceeding the operand size*8 is undefined by the standard.
Definition pro.h:1489
uint32 flags_t
32-bit flags for each address
Definition pro.h:5105
THREAD_SAFE uint32 extract_dd(T &v)
Definition pro.h:2031
int int32
signed 32 bit value
Definition pro.h:351
idaman int ida_export bitcount(uint64 x)
count the number of non-zero bits (the population count)
idaman THREAD_SAFE uint64 ida_export unpack_dq(const uchar **pptr, const uchar *end)
unpack a quadword, see unpack_db()
GCC_DIAG_ON(format-nonliteral)
idaman THREAD_SAFE bool ida_export qsem_free(qsemaphore_t sem)
Free a semaphore.
T qrotl(T value, size_t count)
Rotate left.
Definition pro.h:1500
idaman THREAD_SAFE void ida_export qcontrol_tty(void)
Make the current terminal the controlling terminal of the calling process.
idaman THREAD_SAFE bool ida_export qthread_same(qthread_t q)
Is the current thread the same as 'q'?
uint64 qtime64_t
64-bit time value expressed as seconds and microseconds since the Epoch
Definition pro.h:503
wchar_t wchar16_t
Definition pro.h:374
idaman bool ida_export_data under_debugger
is IDA running under a debugger?
Definition pro.h:739
THREAD_SAFE bool unpack_bytevec(bytevec_t *out, const uchar **pptr, const uchar *end)
Definition pro.h:4451
std::unique_ptr< T, qfree_deleter_t< T > > qalloc_janitor_t
Definition pro.h:4595
idaman THREAD_SAFE bool ida_export qthread_equal(qthread_t q1, qthread_t q2)
Are two threads equal?
idaman THREAD_SAFE void *ida_export qalloc_or_throw(size_t size)
qalloc() 'size' bytes, and throw a "not enough memory" error if failed
idaman time_t ida_export qtimegm(const struct tm *ptm)
idaman THREAD_SAFE int ida_export writebytes(int h, uint32 l, int size, bool mf)
Write at most 4 bytes to file.
unsigned char uchar
unsigned 8 bit value
Definition pro.h:341
tty_control_t
Teletype control.
Definition pro.h:5461
@ TCT_NOT_OWNER
Definition pro.h:5464
@ TCT_OWNER
Definition pro.h:5463
@ TCT_UNKNOWN
Definition pro.h:5462
INLINE THREAD_SAFE qtime64_t make_qtime64(uint32 secs, DEFARG(int32 usecs, 0))
Get a qtime64_t instance from a seconds value and microseconds value.
Definition pro.h:526
const qhandle_t NULL_PIPE_HANDLE
Definition pro.h:5587
qvector< bool > boolvec_t
vector of bools
Definition pro.h:2840
idaman THREAD_SAFE void ida_export qfree(void *alloc)
System independent free.
idaman THREAD_SAFE ushort ida_export unpack_dw(const uchar **pptr, const uchar *end)
unpack a word, see unpack_db()
idaman THREAD_SAFE uint64 ida_export qfilesize(const char *fname)
Get the file size.
int lexcompare_vectors(const T &a, const T &b)
Lexical comparison of two vectors.
Definition pro.h:2979
THREAD_SAFE void qswap(T &a, T &b)
Swap 2 objects of the same type using memory copies.
Definition pro.h:1728
idaman THREAD_SAFE bool ida_export prev_utf8_char(wchar32_t *out_cp, const char **p, const char *begin)
Get the UTF-8 character from string, before 'p'.
idaman THREAD_SAFE void ida_export del_qatexit(void(idaapi *func)(void))
Remove a previously added exit-time function.
idaman THREAD_SAFE char *ida_export strrpl(char *str, int char1, int char2)
Replace all occurrences of a character within a string.
THREAD_SAFE int idaapi qstrncmp(const char *s1, const char *s2, size_t len)
Definition pro.h:3100
idaman THREAD_SAFE char *ida_export qstrdup(const char *string)
System independent strdup.
THREAD_SAFE constexpr int dw_size(uchar first_byte)
Definition pro.h:1983
idaman bool ida_export parse_dbgopts(struct instant_dbgopts_t *ido, const char *r_switch)
Parse the -r command line switch (for instant debugging).
THREAD_SAFE bool unpack_ds_to_buf(char *dst, size_t dstsize, const uchar **pptr, const uchar *end)
Unpack a string.
Definition pro.h:1924
idaman size_t bufsize
Definition pro.h:604
INLINE THREAD_SAFE uint32 get_secs(qtime64_t t)
Get the 'seconds since the epoch' part of a qtime64_t.
Definition pro.h:508
idaman THREAD_SAFE bool ida_export qmutex_unlock(qmutex_t m)
Unlock a mutex.
T * qrealloc_array(T *ptr, size_t n)
Use this class to avoid integer overflows when allocating arrays.
Definition pro.h:795
uint64 sel_t
Definition pro.h:426
idaman THREAD_SAFE size_t ida_export qustrlen(const char *utf8)
idaman THREAD_SAFE qsemaphore_t ida_export qsem_create(const char *name, int init_count)
Create a new semaphore.
const char * unpack_str(const uchar **pptr, const uchar *end)
Definition pro.h:2078
qvector< channel_redir_t > channel_redirs_t
vector of channel_redir_t objects
Definition pro.h:5139
idaman THREAD_SAFE char *ida_export qmakefile(char *buf, size_t bufsize, const char *base, const char *ext)
Construct filename from base name and extension.
THREAD_SAFE char *idaapi qstrchr(char *s1, char c)
Definition pro.h:3118
idaman THREAD_SAFE void *ida_export qrealloc_or_throw(void *ptr, size_t size)
qrealloc() 'ptr' by 'size', and throw a "not enough memory" error if failed
_qstring< uchar > qtype
type string
Definition pro.h:3772
idaman THREAD_SAFE int ida_export readbytes(int h, uint32 *res, int size, bool mf)
Read up to 4 bytes (1, 2, or 4) from file.
idaman THREAD_SAFE int ida_export qread(int h, void *buf, size_t n)
Works the same as its counterpart from C library.
void shift_down(T *dst, T *src, size_t cnt)
Move data down in memory.
Definition pro.h:2209
qvector< plugin_option_t > plugin_option_vec_t
Definition pro.h:5285
idaman THREAD_SAFE bool ida_export search_path(char *buf, size_t bufsize, const char *file, bool search_cwd)
Search for a file in the PATH environment variable or the current directory.
INLINE THREAD_SAFE void idaapi set_bit(uchar *bitmap, size_t bit)
Set 'bit' in 'bitmap'.
Definition pro.h:1372
idaman size_t ida_export round_down_power2(size_t x)
idaman bool ida_export is_cvt64()
is IDA converting IDB into I64?
idaman THREAD_SAFE uint32 ida_export unpack_dd(const uchar **pptr, const uchar *end)
unpack a double word, see unpack_db()
bool is_add_ok(U x, T y)
Check that unsigned or unsigned+signed addition does not overflow.
Definition pro.h:1548
idaman THREAD_SAFE bool ida_export qpipe_read_n(qhandle_t handle, bytevec_t *out_bytes, size_t n)
Read a specific amount of bytes from a pipe.
int idaapi qthread_cb_t(void *ud)
THREADS.
Definition pro.h:5492
idaman THREAD_SAFE int ida_export qfstat(int fd, struct qstatbuf *buf)
idaman THREAD_SAFE bool ida_export qmutex_free(qmutex_t m)
Free a mutex.
idaman THREAD_SAFE bool ida_export qmutex_lock(qmutex_t m)
Lock a mutex.
idaman THREAD_SAFE wchar32_t ida_export get_utf8_char(const char **pptr)
Read one UTF-8 character from string. if error, return BADCP.
INLINE THREAD_SAFE void idaapi clear_bits(uchar *bitmap, size_t low, size_t high)
Clear bits between [low, high) in 'bitmap'.
Definition pro.h:1391
THREAD_SAFE uint64 extract_dq(T &v)
Definition pro.h:2042
constexpr bool is_lead_surrogate(wchar32_t wch)
Definition pro.h:4862
bool wildcard_path_match(const char *name, const char *_pattern, int flags=0)
Match a path against a pattern.
idaman int ida_export qchdir(const char *path)
Change the current working directory.
unsigned int uint
unsigned 32 bit value
Definition pro.h:343
idaman THREAD_SAFE int ida_export qwrite(int h, const void *buf, size_t n)
Works the same as its counterpart from C library.
idaman THREAD_SAFE ssize_t ida_export put_utf8_char(char *out, wchar32_t cp)
Encode the codepoint into a UTF-8 byte sequence, and add terminating zero.
idaman THREAD_SAFE uint64 ida_export qfilelength(int h)
Get file length in bytes.
THREAD_SAFE uchar *idaapi pack_db(uchar *ptr, uchar *end, uchar x)
Pack a byte into a character string.
Definition pro.h:1753
idaman THREAD_SAFE bool ida_export gen_rand_buf(void *buffer, size_t bufsz)
Generate a random buffer.
idaman THREAD_SAFE int ida_export qmkdir(const char *file, int mode)
Create an empty directory.
THREAD_SAFE uint16 extract_dw(T &v)
Definition pro.h:2020
idaman THREAD_SAFE uchar *ida_export pack_dq(uchar *ptr, uchar *end, uint64 x)
pack a quadword, see pack_db()
size_t diffpos_t
Definition pro.h:483
idaman THREAD_SAFE uint32 ida_export calc_file_crc32(class linput_t *fp)
Calculate an input source CRC32.
idaman THREAD_SAFE bool ida_export qisdir(const char *file)
Does the given path specify a directory?
idaman THREAD_SAFE qoff64_t ida_export qseek(int h, int64 offset, int whence)
Works the same as its counterpart from C library.
THREAD_SAFE const void *idaapi unpack_buf_inplace(const uchar **pptr, const uchar *end)
In-place version of unpack_buf().
Definition pro.h:1881
int error_t
Error code (errno)
Definition pro.h:462
INLINE THREAD_SAFE int ida_local qtoupper(char c)
Get uppercase equivalent of given char.
Definition pro.h:956
int lexcompare(const T &a, const T &b)
Standard lexical comparison.
Definition pro.h:2964
qvector< ea_t > eavec_t
vector of addresses
Definition pro.h:2838
uval_t inode_t
The inode_t type is the specialization specific inode number.
Definition pro.h:468
uint64 flags64_t
64-bit flags for each address
Definition pro.h:5106
void qvoid_t
Definition pro.h:4602
idaman THREAD_SAFE bool ida_export qlocaltime(struct tm *_tm, time_t t)
Converts a time value to a tm structure (local time)
bool wildcard_match(const char *name, const char *pattern)
Match a name against a pattern.
THREAD_SAFE char *idaapi qstrstr(char *s1, const char *s2)
Definition pro.h:3109
idaman THREAD_SAFE bool ida_export qthread_join(qthread_t q)
Wait a thread until it terminates.
INLINE void free_argv(int argc, char **argv)
Free 'argc' elements of 'argv'.
Definition pro.h:5177
idaman THREAD_SAFE qmutex_t ida_export qmutex_create(void)
Create a new mutex.
idaman THREAD_SAFE int ida_export qfsync(int h)
Works the same as its counterpart from C library.
void * qhandle_t
MS Windows HANDLE.
Definition pro.h:5586
idaman THREAD_SAFE error_t ida_export set_qerrno(error_t code)
Set qerrno.
void cliopt_handler_t(const char *value, void *ud)
Definition pro.h:5199
idaman THREAD_SAFE int ida_export check_process_exit(void *handle, int *exit_code, DEFARG(int msecs,-1))
Check whether process has terminated or not.
_qstring< wchar16_t > qwstring
unicode string
Definition pro.h:3773
THREAD_SAFE constexpr wchar16_t utf8_wchar16(uchar b0, uchar b1)
Definition pro.h:4910
T round_up(T val, T base)
round up or down to an arbitrary number
Definition pro.h:1441
qvector< sval_t > svalvec_t
vector of signed values
Definition pro.h:2837
DECLARE_TYPE_AS_MOVABLE(cliopt_t)
INLINE THREAD_SAFE void idaapi clear_bit(uchar *bitmap, size_t bit)
Clear 'bit' in 'bitmap'.
Definition pro.h:1378
idaman THREAD_SAFE char *ida_export qstrlwr(char *str)
Convert the string to lowercase.
INLINE THREAD_SAFE bool acp_utf8(qstring *out, const char *in)
Definition pro.h:4899
idaman THREAD_SAFE char *ida_export qmakepath(char *buf, size_t bufsize, const char *s1,...)
Construct a path from a null-terminated sequence of strings.
idaman THREAD_SAFE bool ida_export base64_decode(bytevec_t *output, const char *input, size_t size)
Decode base64.
THREAD_SAFE const char *idaapi qstrrchr(const char *s1, char c)
Definition pro.h:3131
idaman THREAD_SAFE char *ida_export qsplitfile(char *file, char **base, char **ext)
Split filename into base name and extension.
INLINE THREAD_SAFE bool qgmtime64(struct tm *_tm, qtime64_t t)
Same as qgmtime(struct tm *, time_t), but accepts a 64-bit time value.
Definition pro.h:580
INLINE THREAD_SAFE void idaapi set_all_bits(uchar *bitmap, size_t nbits)
Set first 'nbits' of 'bitmap'.
Definition pro.h:1398
bool is_udiv_ok(T, T b)
Check that unsigned division is permissible.
Definition pro.h:1555
ptrdiff_t ssize_t
Signed size_t - used to check for size overflows when the counter becomes negative.
Definition pro.h:385
idaman uint64 ida_export extend_sign(uint64 v, int nbytes, bool sign_extend)
Sign or zero-extend the value 'v' to occupy 64 bits.
constexpr diffpos_t BADDIFF
Definition pro.h:484
INLINE THREAD_SAFE bool idaapi test_bit(const uchar *bitmap, size_t bit)
Test if 'bit' is set in 'bitmap'.
Definition pro.h:1367
THREAD_SAFE ea_t extract_ea(T &v)
Definition pro.h:2050
unsigned short ushort
unsigned 16 bit value
Definition pro.h:342
idaman THREAD_SAFE ssize_t ida_export qpipe_read(qhandle_t handle, void *buf, size_t size)
Read from a pipe.
T align_down(T val, int elsize)
Align element down to nearest boundary.
Definition pro.h:4731
INLINE THREAD_SAFE uint32 get_usecs(qtime64_t t)
Get the microseconds part of a qtime64_t.
Definition pro.h:516
idaman THREAD_SAFE int ida_export qdup(int h)
Works the same as its counterpart from C library.
idaman THREAD_SAFE bool ida_export replace_tabs(qstring *out, const char *str, int tabsize)
Convert tabulations to spaces.
idaman bool ida_export parse_plugin_options(plugin_options_t *opts, const char *optstring)
Parse plugin options from IDA command line specified by -O<plugin_name>:<optstring> Note such options...
THREAD_SAFE int qwait(int *status, int child, int flags)
Definition pro.h:5435
idaman THREAD_SAFE bool ida_export idb_utf8(qstring *out, const char *in, int nsyms=-1, int flags=0)
IDB default C string encoding -> UTF-8.
idaman THREAD_SAFE uchar *ida_export pack_dd(uchar *ptr, uchar *end, uint32 x)
pack a double word, see pack_db()
idaman THREAD_SAFE bool ida_export change_codepage(qstring *out, const char *in, int incp, int outcp)
Definition pro.h:4904
OPAQUE_HANDLE(qthread_t)
idaman THREAD_SAFE const char *ida_export stristr(const char *s1, const char *s2)
Find one string in another (Case insensitive analog of strstr()).
idaman bool ida_export quote_cmdline_arg(qstring *arg)
Quote a command line argument if it contains escape characters.
idaman THREAD_SAFE bool ida_export qsem_wait(qsemaphore_t sem, int timeout_ms)
Lock and decrement a semaphore. timeout = -1 means block indefinitely.
idaman THREAD_SAFE int ida_export qopen_shared(const char *file, int mode, int share_mode)
Open file with given sharing_mode (use O_RDONLY, O_WRONLY, O_RDWR flags), sets qerrno.
idaman THREAD_SAFE bool ida_export qthread_kill(qthread_t q)
Forcefully kill a thread (calls pthread_cancel under unix)
idaman THREAD_SAFE uval_t ida_export rotate_left(uval_t x, int count, size_t bits, size_t offset)
Rotate left - can be used to rotate a value to the right if the count is negative.
idaman THREAD_SAFE void *ida_export qalloc(size_t size)
System independent malloc.
idaman THREAD_SAFE int ida_export qpipe_create(qhandle_t handles[2])
Create a pipe.
idaman THREAD_SAFE int ida_export get_available_core_count()
Get the number of logical CPU cores available to the current process if supported by the OS.
DEFINE_PLUGIN_OPTION_T_HELPERS(idaman) struct plugin_option_t
Named option, supports two kinds of options: string option: <name>=bool option: <name>=[on|off].
Definition pro.h:5256
idaman void *ida_export pipe_process(qhandle_t *read_handle, qhandle_t *write_handle, launch_process_params_t *lpp, qstring *errbuf=nullptr)
Launch a process and establish 2-way comminucation with it.
INLINE THREAD_SAFE void idaapi set_bits(uchar *bitmap, size_t low, size_t high)
Set bits between [low, high) in 'bitmap'.
Definition pro.h:1384
THREAD_SAFE void * extract_array(T &v, size_t *sz, size_t maxsize)
Definition pro.h:2069
idaman THREAD_SAFE int ida_export qclose(int h)
Works the same as its counterpart from C library.
void idaapi setflag(T &where, U bit, bool cnd)
Set a 'bit' in 'where' if 'value' is not zero.
Definition pro.h:1530
ea_t tid_t
type id (for enums, structs, etc)
Definition pro.h:5107
idaman THREAD_SAFE bool ida_export utf16_utf8(qstring *out, const wchar16_t *in, int nsyms=-1)
UTF-16 -> UTF-8.
idaman THREAD_SAFE bool ida_export relocate_relobj(struct relobj_t *_relobj, ea_t ea, bool mf)
idaman THREAD_SAFE void *ida_export memrev(void *buf, ssize_t size)
Reverse memory block.
idaman THREAD_SAFE int ida_export qopen(const char *file, int mode)
Works the same as its counterpart from C library.
idaman THREAD_SAFE void ida_export qatexit(void(idaapi *func)(void))
Add a function to be called at exit time.
idaman THREAD_SAFE char *ida_export qstrncat(char *dst, const char *src, size_t dstsize)
A safer strncat - accepts the size of the 'dst' as 'dstsize' and returns dst nb: ssize_t(dstsize) mus...
INLINE int64 qatoll(const char *nptr)
Definition pro.h:359
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:4648
THREAD_SAFE void *idaapi unpack_buf(const uchar **pptr, const uchar *end)
Unpack an object of an unknown size (packed with append_buf()).
Definition pro.h:1840
unsigned char uint8
unsigned 8 bit value
Definition pro.h:348
THREAD_SAFE ea64_t unpack_ea64(const uchar **ptr, const uchar *end)
Unpack an ea value (always use 64-bit, use delta 1)
Definition pro.h:1803
idaman THREAD_SAFE qthread_t ida_export qthread_self(void)
Get current thread. Must call qthread_free() to free it!
idaman THREAD_SAFE bool ida_export utf8_utf16(qwstring *out, const char *in, int nsyms=-1)
UTF-8 -> UTF-16.
constexpr bool is_utf8_tail(char in)
Does this byte correspond to the tail of a UTF-8 byte sequence?
Definition pro.h:4832
THREAD_SAFE int ds_packed_size(const char *s)
Definition pro.h:1980
THREAD_SAFE int idaapi qstrcmp(const char *s1, const char *s2)
Definition pro.h:3087
idaman THREAD_SAFE bool ida_export qdirname(char *buf, size_t bufsize, const char *path)
Get the directory part of the path.
idaman THREAD_SAFE ssize_t ida_export qpipe_write(qhandle_t handle, const void *buf, size_t size)
Write to a pipe.
char int8
signed 8 bit value
Definition pro.h:346
constexpr bool is_pow2(T val)
is power of 2? (or zero)
Definition pro.h:1435
INLINE THREAD_SAFE void idaapi clear_all_bits(uchar *bitmap, size_t nbits)
Clear first 'nbits' of 'bitmap'.
Definition pro.h:1408
idaman ssize_t ida_export convert_encoding(bytevec_t *out, const char *fromcode, const char *tocode, const uchar *indata, ssize_t insize, DEFARG(int flags, 0))
Convert data from encoding fromcode into tocode.
idaman THREAD_SAFE NORETURN void ida_export interr(int code)
Show internal error message and terminate execution.
idaman THREAD_SAFE int ida_export qtouchfile(const char *file_name)
touch: set access and modification times of the file to the current time
idaman THREAD_SAFE uchar *ida_export pack_dw(uchar *ptr, uchar *end, uint16 x)
pack a word, see pack_db()
idaman THREAD_SAFE qthread_t ida_export qthread_create(qthread_cb_t *thread_cb, void *ud)
Create a thread and return a thread handle. Must call qthread_free() to free it!
idaman THREAD_SAFE bool ida_export unpack_xleb128(void *res, int nbits, bool is_signed, const uchar **pptr, const uchar *end)
Unpack an LEB128 encoded (DWARF-3 style) signed/unsigned value.
constexpr T left_shift(const T &value, int shift)
Shift by the amount exceeding the operand size*8 is undefined by the standard.
Definition pro.h:1484
_qstring< char > qstring
regular string
Definition pro.h:3771
INLINE THREAD_SAFE char * tail(char *str)
Get tail of a string.
Definition pro.h:883
idaman THREAD_SAFE qoff64_t ida_export qtell(int h)
Works the same as its counterpart from C library.
idaman THREAD_SAFE error_t ida_export get_qerrno(void)
Get qerrno.
idaman void ida_export qgetcwd(char *buf, size_t bufsize)
Get the current working directory.
idaman THREAD_SAFE bool ida_export is_cp_graphical(wchar32_t cp)
Is the provided codepoint graphical?
idaman int ida_export log2ceil(uint64 d64)
calculate ceil(log2(d64)) or floor(log2(d64)), it returns 0 if d64 == 0
constexpr wchar32_t utf16_surrogates_to_cp(wchar16_t lead_surrogate, wchar16_t tail_surrogate)
Definition pro.h:4864
idaman THREAD_SAFE bool ida_export qisabspath(const char *file)
Is the file name absolute (not relative to the current dir?)
qvector< qwstring > qwstrvec_t
vector of unicode strings
Definition pro.h:3775
idaman THREAD_SAFE int ida_export qpipe_close(qhandle_t handle)
Close a pipe.
THREAD_SAFE constexpr wchar32_t utf8_wchar32(uchar b0, uchar b1, uchar b2, uchar b3)
Definition pro.h:4924
int compare(const T &a, const T &b)
Definition pro.h:4607
idaman THREAD_SAFE int ida_export qrmdir(const char *file)
Delete a directory.
THREAD_SAFE ea_t unpack_ea(const uchar **ptr, const uchar *end)
Unpack an ea value, see unpack_dd()/unpack_dq()
Definition pro.h:1793
void cliopt_poly_handler_t(int argc, const char **argv, void *ud)
Definition pro.h:5200
idaman bool ida_export qgmtime(struct tm *_tm, time_t t)
Converts a time value to a tm structure (UTC time)
idaman THREAD_SAFE char *ida_export set_file_ext(char *outbuf, size_t bufsize, const char *file, const char *ext)
Set file name extension unconditionally.
idaman int ida_export log2floor(uint64 d64)
idaman THREAD_SAFE void ida_export qthread_free(qthread_t q)
Free a thread resource (does not kill the thread) (calls pthread_detach under unix)
THREAD_SAFE constexpr T extend_sign_bits(T v, int nbits)
Sign, or zero-extend V depending on the high bit of V.
Definition pro.h:1572
unsigned int
Definition pronet.h:99
constexpr bool operator!=(qpair< F, S > const &a, qpair< F, S > const &b)
Definition qpair.hpp:103
void swap(qpair< F, S > &a, qpair< F, S > &b) noexcept(noexcept(a.swap(b)))
Definition qpair.hpp:78
constexpr bool operator==(qpair< F, S > const &a, qpair< F, S > const &b)
Definition qpair.hpp:98
Tools for command line parsing.
Definition pro.h:5119
qstring file
file name to redirect to/from.
Definition pro.h:5121
int flags
i/o redirection flags
Definition pro.h:5123
int fd
channel number
Definition pro.h:5120
int start
begin of the redirection string in the command line
Definition pro.h:5136
bool is_append(void) const
Definition pro.h:5134
bool is_quoted(void) const
Definition pro.h:5135
bool is_input(void) const
Definition pro.h:5132
int length
length of the redirection string in the command line
Definition pro.h:5137
bool is_output(void) const
Definition pro.h:5133
Definition pro.h:5202
int nargs
Definition pro.h:5207
const char * longname
Definition pro.h:5204
const char * help
Definition pro.h:5205
cliopt_handler_t * handler
Definition pro.h:5206
char shortname
Definition pro.h:5203
Template to compare any 2 values of the same type. Returns -1/0/1.
Definition pro.h:4600
Definition pro.h:1720
static constexpr bool value
Definition pro.h:1721
Options for instant debugging.
Definition pro.h:5333
int event_id
event to trigger upon attaching
Definition pro.h:5340
qstring debmod
name of debugger module
Definition pro.h:5334
int pid
process to attach to (-1: ask the user)
Definition pro.h:5339
qstring host
remote hostname (if remote debugging)
Definition pro.h:5336
bool attach
should attach to a process?
Definition pro.h:5341
int port
port number for the remote debugger server
Definition pro.h:5338
qstring pass
password for the remote debugger server
Definition pro.h:5337
qstring env
config variables for debmod. example: DEFAULT_CPU=13;MAXPACKETSIZE=-1
Definition pro.h:5335
interr_exc_t(int _code)
Definition pro.h:764
int code
Definition pro.h:763
linput_t *& resource
Definition pro.h:4584
~janitor_t()
We provide no implementation for this function, you should provide specialized implementation yoursel...
janitor_t(T &r)
Constructor.
Definition pro.h:4580
Information for launching a process with IDA API Note: all string data such as paths (e....
Definition pro.h:5362
const char * args
command line arguments
Definition pro.h:5384
void * info
os specific info (on windows it points to PROCESS_INFORMATION) on unix, not used
Definition pro.h:5393
const char * path
file to run
Definition pro.h:5383
int flags
Launch process flags
Definition pro.h:5364
ssize_t in_handle
handle for stdin or -1
Definition pro.h:5385
char * env
zero separated environment variables that will be appended to the existing environment block (existin...
Definition pro.h:5388
ssize_t err_handle
handle for stderr or -1
Definition pro.h:5387
size_t cb
size of this structure
Definition pro.h:5363
const char * startdir
current directory for the new process
Definition pro.h:5392
ssize_t out_handle
handle for stdout or -1
Definition pro.h:5386
ea_t unpack_ea()
Definition pro.h:4490
void unpack(qvector< T > *out)
Definition pro.h:4537
bool unpack_ds_to_buf(char *buf, size_t bufsize)
Definition pro.h:4501
bool empty() const
Definition pro.h:4483
const uchar * ptr
Definition pro.h:4476
bool eof() const
Definition pro.h:4547
uint64 unpack_dq()
Definition pro.h:4489
const void * unpack_buf_inplace()
Definition pro.h:4509
const uchar * end
Definition pro.h:4477
ssize_t read(void *obj, size_t objsize)
Definition pro.h:4546
void unpack_eavec(eavec_t *vec, ea_t ea)
Definition pro.h:4521
uint16 unpack_dw()
Definition pro.h:4487
memory_deserializer_t(const uchar *p, const uchar *e)
Definition pro.h:4481
bool unpack_str(qstring *out)
Definition pro.h:4494
memory_deserializer_t(const bytevec_t &b)
Definition pro.h:4480
const void * unpack_obj_inplace(size_t objsize)
Definition pro.h:4505
const void * unpack_obj(void *obj, size_t objsize)
Definition pro.h:4513
uint8 unpack_db()
Definition pro.h:4486
void unpack(T *out)
Definition pro.h:4530
uint32 unpack_dd()
Definition pro.h:4488
bool advance(size_t s)
Definition pro.h:4485
memory_deserializer_t(const void *p, size_t s)
Definition pro.h:4482
void unpack(qstring *out)
Definition pro.h:4535
bool unpack_bytevec(bytevec_t *out)
Definition pro.h:4525
const void * unpack_buf()
Definition pro.h:4517
ea64_t unpack_ea64()
Definition pro.h:4491
size_t size() const
Definition pro.h:4484
const char * unpack_str()
Definition pro.h:4493
memory_deserializer_t(const qstring &s)
Definition pro.h:4479
char * unpack_ds(bool empty_null=false)
Definition pro.h:4496
Definition pro.h:4554
void pack(T value)
Definition pro.h:4556
void pack(const qstring &value)
Definition pro.h:4561
void pack(const qvector< T > &value)
Definition pro.h:4563
Definition pro.h:5288
const plugin_option_t * find(const qstring &name) const
Definition pro.h:5289
bool erase(const char *name)
Definition pro.h:5297
Definition pro.h:4590
void operator()(T *ptr)
Definition pro.h:4591
Definition pro.h:812
Definition pro.h:810
static is_array check_type(const void *, const void *)
static is_pointer check_type(const T *, const T *const *)
Describes miscellaneous file attributes.
Definition pro.h:648
qtime64_t qst_ctime
time of last status change
Definition pro.h:661
uint32 qst_nlink
number of hard links
Definition pro.h:652
uint32 qst_gid
group ID of owner
Definition pro.h:654
qtime64_t qst_atime
time of last access
Definition pro.h:659
uint32 qst_mode
protection
Definition pro.h:651
qtime64_t qst_mtime
time of last modification
Definition pro.h:660
int32 qst_blocks
number of 512B blocks allocated
Definition pro.h:658
qoff64_t qst_size
total size, in bytes
Definition pro.h:656
uint64 qst_rdev
device ID (if special file)
Definition pro.h:655
uint32 qst_ino
inode number
Definition pro.h:650
int32 qst_blksize
blocksize for file system I/O
Definition pro.h:657
uint32 qst_uid
user ID of owner
Definition pro.h:653
uint64 qst_dev
ID of device containing file.
Definition pro.h:649
Relocatable object.
Definition pro.h:4103
ea_t base
current base
Definition pro.h:4104
relobj_t(void)
Definition pro.h:4107
reloc_info_t ri
relocation info
Definition pro.h:4105
bool relocate(ea_t ea, bool mf)
mf=1:big endian
Definition pro.h:4108
Relocation information (relocatable objects - see relobj_t)
Definition pro.h:4085
size_t operator()(const _qstring< T > &str) const noexcept
Definition pro.h:3785