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-2025 Hex-Rays
4 * ALL RIGHTS RESERVED.
5 *
6 */
7
8#ifndef _PRO_H
9#define _PRO_H
10
34
36#define IDA_SDK_VERSION 920
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#define __UNIX__
54#endif
55
57#ifndef __X86__
58#define BADMEMSIZE 0x7FFFFFFFFFFFFFFFull
59#else
60#define BADMEMSIZE 0x7FFFFFFFu
61#endif
62
64#define ENUM_SIZE(t) : t
65
66// this is necessary to have S_IFMT, S_IFREG and S_IFDIR defined in windows
67// in order to define S_ISDIR and S_ISREG
68#define _CRT_DECLARE_NONSTDC_NAMES 1
69#ifndef SWIG
70#include <stdlib.h> /* size_t, nullptr, memory */
71#include <stdarg.h>
72#include <stddef.h>
73#include <stdio.h>
74#include <assert.h>
75#include <limits.h>
76#include <ctype.h>
77#include <time.h>
78#include <stdint.h>
79#ifdef __cplusplus
80#include <memory>
81#include <new>
82#include <string>
83#endif
84#if defined(__NT__)
85# include <malloc.h>
86#endif
87
89#if defined(_MSC_VER)
90# define WIN32_LEAN_AND_MEAN
91# include <string.h>
92# include <io.h>
93# include <direct.h>
94#else
95# include <wchar.h>
96# include <string.h>
97# include <unistd.h>
98# include <sys/stat.h>
99# include <errno.h>
100#endif
101#ifdef __cplusplus
102# include <set>
103# include <map>
104# include <algorithm>
105#endif
106#include <fcntl.h>
107#include <sys/types.h>
108#include <sys/stat.h>
109
110#endif // SWIG
111
112#define STL_SUPPORT_PRESENT
113
114//---------------------------------------------------------------------------
119#if defined(__cplusplus) || defined(SWIG)
120#define EXTERNC extern "C"
121#define C_INCLUDE EXTERNC \
122 {
123
124#define C_INCLUDE_END }
125#define INLINE inline
126#else
127#define EXTERNC
128#define C_INCLUDE
129#define C_INCLUDE_END
130#define INLINE __inline
131#endif
132
133//---------------------------------------------------------------------------
134#ifndef MAXSTR
135#define MAXSTR 1024
136#endif
137
138#define SMAXSTR QSTRINGIZE(MAXSTR)
139
141#ifdef __NT__
142#define NT_CDECL __cdecl
143#else
144#define NT_CDECL
145#endif
146
154#if defined(SWIG)
155#define constexpr
156#define DEPRECATED
157#define NORETURN
158#define PACKED
159#define PACKED_ALIGNED(al)
160#define AS_STRFTIME(format_idx)
161#define AS_PRINTF(format_idx, varg_idx)
162#define AS_SCANF(format_idx, varg_idx)
163#define WARN_UNUSED_RESULT
164#elif defined(__GNUC__)
165#define DEPRECATED __attribute__((deprecated))
166#define NORETURN __attribute__((noreturn))
167#define PACKED __attribute__((__packed__))
168#define PACKED_ALIGNED(al) __attribute__((__packed__)) __attribute__((__aligned__(al)))
169#define AS_STRFTIME(format_idx) __attribute__((format(strftime, format_idx, 0)))
170#define AS_PRINTF(format_idx, varg_idx) __attribute__((format(printf, format_idx, varg_idx)))
171#define AS_SCANF(format_idx, varg_idx) __attribute__((format(scanf, format_idx, varg_idx)))
172#define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
173#else
174#define DEPRECATED __declspec(deprecated)
175#define NORETURN __declspec(noreturn)
176#define PACKED
177#define PACKED_ALIGNED(al)
178#define AS_STRFTIME(format_idx)
179#define AS_PRINTF(format_idx, varg_idx)
180#define AS_SCANF(format_idx, varg_idx)
181#define WARN_UNUSED_RESULT _Check_return_
182#endif
183
186#if defined(__GNUC__) && !defined(SWIG) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402
187#define GCC_DIAG_JOINSTR(x,y) _QSTRINGIZE(x ## y)
188# define GCC_DIAG_DO_PRAGMA(x) _Pragma (#x)
189# define GCC_DIAG_PRAGMA(x) GCC_DIAG_DO_PRAGMA(GCC diagnostic x)
190# if (((__GNUC__ * 100) + __GNUC_MINOR__) >= 406) || defined(__clang__)
191# define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(push) \
192 GCC_DIAG_PRAGMA(ignored GCC_DIAG_JOINSTR(-W,x))
193# define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(pop)
194# else
195# define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(ignored GCC_DIAG_JOINSTR(-W,x))
196# define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(warning GCC_DIAG_JOINSTR(-W,x))
197# endif
198#else
199# define GCC_DIAG_OFF(x)
200# define GCC_DIAG_ON(x)
201#endif
202
203#if defined(_MSC_VER) && !defined(SWIG)
204# define MSC_DIAG_OFF(x) __pragma(warning(push)) \
205 __pragma(warning(disable : x))
206# define MSC_DIAG_ON(x) __pragma(warning(pop))
207#else
208# define MSC_DIAG_OFF(x)
209# define MSC_DIAG_ON(x)
210#endif
211
212// A function attribute to disable ASAN
213#if defined(__clang__) || defined (__GNUC__)
214# define DISABLE_ASAN __attribute__((no_sanitize_address))
215#else
216# define DISABLE_ASAN
217#endif
218
219#if defined(DONT_DEPRECATE)
220#undef DEPRECATED
221#define DEPRECATED
222#endif
223
224//---------------------------------------------------------------------------
225
226#define __MF__ 0
229
230//---------------------------------------------------------------------------
232#define qnotused(x) (void)x
233
234#ifdef __clang__
235# define NONNULL _Nonnull
236#else
237# define NONNULL
238#endif
239
240// this macro can be used as a suffix for declarations/definitions instead of qnotused()
241#if defined(__clang__) || defined(__GNUC__)
242# define QUNUSED __attribute__((unused))
243#else
244# define QUNUSED
245#endif
246
248#ifdef __GNUC__
249#define va_argi(va, type) ((type)va_arg(va, int))
250#else
251#define va_argi(va, type) va_arg(va, type)
252#endif
253
254//---------------------------------------------------------------------------
255#define CONST_CAST(x) const_cast<x>
256#define _QSTRINGIZE(x) #x
257#define QSTRINGIZE(x) _QSTRINGIZE(x)
258
259//---------------------------------------------------------------------------
260
267#if defined(SWIG) // for SWIG
268 #define idaapi
269 #define idaman
270 #define ida_export
271 #define ida_export_data
272 #define ida_module_data
273 #define __fastcall
274 #define ida_local
275#elif defined(APIDEF) // for API DEF files
276 #define idaapi
277 #define idaman
278 #define ida_export ida_export
279 #define ida_export_data ida_export_data
280 #define ida_module_data
281 #define __fastcall
282 #define ida_local
283#elif defined(__NT__) // MS Windows
284 #define idaapi __stdcall
285 #define ida_export idaapi
286 #ifdef __CODE_CHECKER__
287 // tell lint that this function will be exported
288 #define idaman EXTERNC __declspec(dllexport)
289 #else
290 #define idaman EXTERNC
291 #endif
292 #if defined(__KERNEL__) // kernel
293 #define ida_export_data
294 #define ida_module_data
295 #else // modules
296 #define ida_export_data __declspec(dllimport)
297 #define ida_module_data __declspec(dllexport)
298 #endif
299 #define ida_local
300#elif defined(__UNIX__) // for unix
301 #define idaapi
302 #if defined(__MAC__)
303 #define idaman EXTERNC __attribute__((visibility("default")))
304 #define ida_local __attribute__((visibility("hidden")))
305 #else
306 #if __GNUC__ >= 4
307 #define idaman EXTERNC __attribute__ ((visibility("default")))
308 #define ida_local __attribute__((visibility("hidden")))
309 #else
310 #define idaman EXTERNC
311 #define ida_local
312 #endif
313 #endif
314 #define ida_export
315 #define ida_export_data
316 #define ida_module_data
317 #define __fastcall
318#endif
319
321#define THREAD_SAFE
322
325#define newapi
326
327//---------------------------------------------------------------------------
328#ifndef __cplusplus
329typedef int bool;
330#define false 0
331#define true 1
332#endif
333
334//---------------------------------------------------------------------------
335// Linux C mode compiler already has these types defined
336#if !defined(__LINUX__) || defined(__cplusplus)
337typedef unsigned char uchar;
338typedef unsigned short ushort;
339typedef unsigned int uint;
340#endif
341
342typedef char int8;
343typedef signed char sint8;
344typedef unsigned char uint8;
345typedef short int16;
346typedef unsigned short uint16;
347typedef int int32;
348typedef unsigned int uint32;
349
350#include <llong.hpp>
351
352
354#if defined(__UNIX__)
355INLINE int64 qatoll(const char *nptr) { return nptr != nullptr ? atoll(nptr) :0; }
356#elif defined(_MSC_VER)
357INLINE int64 qatoll(const char *nptr) { return nptr != nullptr ? _atoi64(nptr) :0; }
358#else
359INLINE int64 qatoll(const char *nptr) { return nptr != nullptr ? atol(nptr) : 0; }
360#endif
361
362// VS2010 lacks strtoull
363#ifdef _MSC_VER
364#define strtoull _strtoui64
365#endif
366
369#if defined(_MSC_VER)
370typedef wchar_t wchar16_t;
372#elif defined(__GNUC__)
373typedef uint16 wchar16_t;
374typedef uint32 wchar32_t;
375#endif
376
380#if !defined(_SSIZE_T_DEFINED) && !defined(__ssize_t_defined) && !defined(__GNUC__)
381typedef ptrdiff_t ssize_t;
382#endif
383
388#if defined(__GNUC__) && !defined(__MINGW32__)
389 #define FMT_64 "ll"
390 #define FMT_Z "zu"
391 #define FMT_ZX "zX"
392 #define FMT_ZS "zd"
393#elif defined(_MSC_VER) && _MSC_VER >= 1900
394 #define FMT_64 "I64"
395 #define FMT_Z "zu"
396 #define FMT_ZX "zX"
397 #define FMT_ZS "td"
398#elif defined(_MSC_VER) || defined(__MINGW32__)
399 #define FMT_64 "I64"
400 #ifndef __X86__
401 #define FMT_Z "I64u"
402 #define FMT_ZX "I64X"
403 #define FMT_ZS "I64d"
404 #else
405 #define FMT_Z "u"
406 #define FMT_ZX "X"
407 #define FMT_ZS "d"
408 #endif
409#elif !defined(SWIG)
410 #error "unknown compiler"
411#endif
412
420#ifdef __EA64__
421 typedef uint64 ea_t;
422 typedef uint64 sel_t;
424 typedef int64 adiff_t;
425 #define FMT_EA FMT_64
426 #ifdef __GNUC__
427 #define SVAL_MIN LLONG_MIN
428 #define SVAL_MAX LLONG_MAX
429 #else
430 #define SVAL_MIN _I64_MIN
431 #define SVAL_MAX _I64_MAX
432 #endif
433#else
434 typedef uint32 ea_t;
435 typedef uint32 sel_t;
436 typedef uint32 asize_t;
437 typedef int32 adiff_t;
438 #define SVAL_MIN INT_MIN
439 #define SVAL_MAX INT_MAX
440 #define FMT_EA ""
441#endif
442
449
450typedef uint32 ea32_t;
453typedef uint64 ea64_t;
456
458typedef int error_t;
459
461
465
466// A position in the difference source.
467// This is an abstract value that depends on the difference source.
468// It should be something that can be used to conveniently retrieve information
469// from a difference source. For example, for the name list it can be the index
470// in the name list. For structure view it can be the position in the list of structs.
471// Please note that this is not necessarily an address. However, for the purpose
472// of comparing the contents of the disassembly listing it can be an address.
473//
474// diffpos_t instances must have the following property: adding or removing
475// items to diff_source_t should not invalidate the existing diffpos_t instances.
476// They must stay valid after adding or removing items to diff_source_t.
477// Naturally, deleting an item pointed by diffpos_t may render it incorrect,
478// this is acceptable and expected.
479typedef size_t diffpos_t;
481
482#ifdef __cplusplus
483#define DEFARG(decl, val) decl = val
484#else
485#define DEFARG(decl, val) decl
486#endif
487
488#ifndef SWIG
489#define BADADDR ea_t(-1)
490#define BADSEL sel_t(-1)
491#define BADADDR32 ea32_t(-1)
492#define BADADDR64 ea64_t(-1)
493
494//-------------------------------------------------------------------------
495// Time related functions
496
501
503
504INLINE THREAD_SAFE uint32 get_secs(qtime64_t t)
505{
506 return (uint32)(t>>32);
507}
508
509
511
512INLINE THREAD_SAFE uint32 get_usecs(qtime64_t t)
513{
514 return (uint32)(t);
515}
516
517
521
522INLINE THREAD_SAFE qtime64_t make_qtime64(uint32 secs, DEFARG(int32 usecs, 0))
523{
524 return ((qtime64_t)(secs) << 32) | usecs;
525}
526
527
535
536idaman THREAD_SAFE bool ida_export qctime(char *buf, size_t bufsize, qtime32_t t);
537
538
546
547idaman THREAD_SAFE bool ida_export qctime_utc(char *buf, size_t bufsize, qtime32_t t);
548
549
554
555idaman THREAD_SAFE bool ida_export qlocaltime(struct tm *_tm, time_t t);
556
557
559
560INLINE THREAD_SAFE bool qlocaltime64(struct tm *_tm, qtime64_t t)
561{
562 return qlocaltime(_tm, get_secs(t));
563}
564
565
570
571idaman bool ida_export qgmtime(struct tm *_tm, time_t t);
572
573
575
576INLINE THREAD_SAFE bool qgmtime64(struct tm *_tm, qtime64_t t)
577{
578 return qgmtime(_tm, get_secs(t));
579}
580
581
582// Inverse of qgmtime()
583
584idaman time_t ida_export qtimegm(const struct tm *ptm);
585
586
597
598idaman AS_STRFTIME(3) THREAD_SAFE size_t ida_export qstrftime(
599 char *buf,
600 size_t bufsize,
601 const char *format,
602 time_t t);
603
604
606
607idaman AS_STRFTIME(3) THREAD_SAFE size_t ida_export qstrftime64(
608 char *buf,
609 size_t bufsize,
610 const char *format,
611 qtime64_t t);
612
613
615
616idaman THREAD_SAFE void ida_export qsleep(int milliseconds);
617
618
623
624idaman THREAD_SAFE uint64 ida_export get_nsec_stamp(void);
625
628
629idaman THREAD_SAFE qtime64_t ida_export qtime64(void);
630
631
636
637idaman THREAD_SAFE bool ida_export gen_rand_buf(void *buffer, size_t bufsz);
638
639
640#define qoff64_t int64
641
659
660// non standard functions are missing:
661#ifdef _MSC_VER
662#if _MSC_VER <= 1200
663# define for if(0); else for
664#else
665# pragma warning(disable : 4200)
666# if _MSC_VER >= 1921 && _MSC_VER < 1924 // avoid compiler bug:
667# pragma function(memmove) // https://developercommunity.visualstudio.com/content/problem/583227/vs-2019-cl-1921277022-memmove-instrinsic-optimizat.html
668# endif
669#endif
673#define chdir _chdir
674#define fileno _fileno
675#define getcwd _getcwd
676#define memicmp _memicmp
677# define F_OK 0
678# define W_OK 2
679# define R_OK 4
681#endif
682
683//---------------------------------------------------------------------------
684/* error codes */
685/*--------------------------------------------------*/
686
687#define eOk 0
688#define eOS 1
689#define eDiskFull 2
690#define eReadError 3
691#define eFileTooLarge 4
692
693
695
696idaman THREAD_SAFE error_t ida_export set_qerrno(error_t code);
697
698
700
701idaman THREAD_SAFE error_t ida_export get_qerrno(void);
702
703//---------------------------------------------------------------------------
704// debugging macros
707#define ZZZ msg("%s:%d\n", __FILE__, __LINE__)
708#if defined(__GNUC__)
709# define BPT __builtin_trap()
710#elif defined(_MSC_VER) // Visual C++
711# define BPT __debugbreak()
712# ifdef __CODE_CHECKER__
713 NORETURN void __debugbreak(void);
714# endif
715#endif
716
718#ifdef __CODE_CHECKER__
719#define CASSERT(cnd) static_assert((cnd), "")
720#else
721#define CASSERT(cnd) static_assert((cnd), QSTRINGIZE(cnd))
722#endif
723
727#ifdef __CODE_CHECKER__
728#define INTERR(code) interr(code)
729#else
730#define INTERR(code) do { if ( under_debugger ) BPT; interr(code); } while(1)
731#endif
732
733#define QASSERT(code, cond) do if ( !(cond) ) INTERR(code); while (0)
734#define QBUFCHECK(buf, size, src) ida_fill_buffer(buf, size, src, __FILE__, __LINE__)
736
737#ifdef TESTABLE_BUILD
738# define TB_QASSERT(Code, Expr) QASSERT(Code, Expr)
739# define TB_INTERR(Code) INTERR(Code)
740# define TB_CCHECK(expr) if ( !(expr) ) warning("Coherency check failed at %s:%d: " #expr, __FILE__, __LINE__)
741# define TB_INTERR_OR_RETURN(code, ...) INTERR(code)
742#else
743# define TB_QASSERT(Code, Expr)
744# define TB_INTERR(Code)
745# define TB_CCHECK(expr) if ( !(expr) ) msg("Coherency check failed: " #expr "\n")
746# define TB_INTERR_OR_RETURN(code, ...) return __VA_ARGS__
747#endif
748
749#define INTERR_EXC_FMT "Internal error %d occurred when running a script. Either\n" \
750 " - the script misused the IDA API, or\n" \
751 " - there is a logic error in IDA\n" \
752 "Please check the script first.\n" \
753 "If it appears correct, send a bug report to <support@hex-rays.com>.\n" \
754 "In any case we strongly recommend you to restart IDA as soon as possible."
755
756#ifdef __cplusplus
757struct interr_exc_t : public std::exception
758{
759 int code;
760 interr_exc_t(int _code) : code(_code) {}
761};
762#endif // __cplusplus
763idaman THREAD_SAFE NORETURN void ida_export interr(int code);
764
765// set the behavior of 'interr()'
769idaman THREAD_SAFE bool ida_export set_interr_throws(bool enable);
770
771//---------------------------------------------------------------------------
772idaman THREAD_SAFE void *ida_export qalloc(size_t size);
773idaman THREAD_SAFE void *ida_export qrealloc(void *alloc, size_t newsize);
774idaman THREAD_SAFE void *ida_export qcalloc(size_t nitems, size_t itemsize);
775idaman THREAD_SAFE void ida_export qfree(void *alloc);
776idaman THREAD_SAFE char *ida_export qstrdup(const char *string);
777#define qnew(t) ((t*)qalloc(sizeof(t)))
779#define qnewarray(t,n) use_qalloc_array
780
782#ifdef __cplusplus
783template <class T>
784T *qalloc_array(size_t n)
785{
786 return (T *)qcalloc(n, sizeof(T));
787}
788
790template <class T>
791T *qrealloc_array(T *ptr, size_t n)
792{
793 size_t nbytes = n * sizeof(T);
794 if ( nbytes < n )
795 return nullptr; // integer overflow
796 return (T *)qrealloc(ptr, nbytes);
797}
798
800#ifdef __GNUC__
801# define qnumber(arr) ( \
802 0 * sizeof(reinterpret_cast<const ::qnumber_check_type *>(arr)) \
803 + 0 * sizeof(::qnumber_check_type::check_type((arr), &(arr))) \
804 + sizeof(arr) / sizeof((arr)[0]) )
806 {
807 struct is_pointer;
808 struct is_array {};
809 template <typename T>
810 static is_pointer check_type(const T *, const T *const *);
811 static is_array check_type(const void *, const void *);
812 };
813#elif defined(_MSC_VER) && !defined(__CODE_CHECKER__)
814# define qnumber(array) _countof(array)
815#else // poor man's implementation for other compilers and lint
816# define qnumber(array) (sizeof(array)/sizeof(array[0]))
817#endif
818#endif // __cplusplus
819
820#define qoffsetof offsetof
821
824#if defined(__GNUC__) && !defined(__X86__) && !(defined(__clang__) && defined(__ARM__))
825 // gcc64 and clang x86_64 use special array-type va_list, so we have to resort to tricks like these
826 #define set_vva(va2, vp) va_copy(va2, *(va_list*)va_arg(vp, void*))
827#else
828 #ifndef va_copy
829 #define va_copy(dst, src) dst = src
830 #endif
831 #if defined(__clang__)
832 #define set_vva(va2, vp) va2 = va_arg(vp, va_list)
833 #else
834 #define set_vva(va2, vp) va_copy(va2, va_arg(vp, va_list))
835 #endif
836#endif
837
838#if defined(__LINUX__) && defined(__ARM__)
839# define NULL_VA_LIST() va_list()
840#else
841# define NULL_VA_LIST() nullptr
842#endif
843
849
850idaman THREAD_SAFE void *ida_export memrev(void *buf, ssize_t size);
851
852#if defined(__GNUC__) && !defined(_WIN32)
853idaman THREAD_SAFE int ida_export memicmp(const void *x, const void *y, size_t size);
854#endif
855
856//---------------------------------------------------------------------------
857/* strings */
860#ifdef __GNUC__
861#define strnicmp strncasecmp
862#define stricmp strcasecmp
863#elif defined(_MSC_VER)
864#define strnicmp _strnicmp
865#define stricmp _stricmp
866#endif
867
868
874
875idaman THREAD_SAFE char *ida_export strrpl(char *str, int char1, int char2);
876
877
879INLINE THREAD_SAFE char *tail(char *str) { return strchr(str, '\0'); }
880#ifdef __cplusplus
882inline THREAD_SAFE const char *tail(const char *str) { return strchr(str, '\0'); }
883#endif
884
885
889
890idaman THREAD_SAFE char *ida_export qstrncpy(char *dst, const char *src, size_t dstsize);
891
892
895
896idaman THREAD_SAFE char *ida_export qstpncpy(char *dst, const char *src, size_t dstsize);
897
898
901
902idaman THREAD_SAFE char *ida_export qstrncat(char *dst, const char *src, size_t dstsize);
903
904
906
907idaman THREAD_SAFE char *ida_export qstrtok(char *s, const char *delim, char **save_ptr);
908
909
911
912idaman THREAD_SAFE char *ida_export qstrlwr(char *str);
913
914
916
917idaman THREAD_SAFE char *ida_export qstrupr(char *str);
918
919
924
925idaman THREAD_SAFE const char *ida_export stristr(const char *s1, const char *s2);
926
927
928#ifdef __cplusplus
930inline char *idaapi stristr(char *s1, const char *s2) { return CONST_CAST(char *)(stristr((const char *)s1, s2)); }
931#endif
932
937INLINE THREAD_SAFE bool ida_local qisascii(char c) { return (c & ~0x7f) == 0; }
938INLINE THREAD_SAFE bool ida_local qisspace(char c) { return qisascii(c) && isspace((uchar)(c)) != 0; }
939INLINE THREAD_SAFE bool ida_local qisalpha(char c) { return qisascii(c) && isalpha((uchar)(c)) != 0; }
940INLINE THREAD_SAFE bool ida_local qisalnum(char c) { return qisascii(c) && isalnum((uchar)(c)) != 0; }
941INLINE THREAD_SAFE bool ida_local qispunct(char c) { return qisascii(c) && ispunct((uchar)(c)) != 0; }
942INLINE THREAD_SAFE bool ida_local qislower(char c) { return qisascii(c) && islower((uchar)(c)) != 0; }
943INLINE THREAD_SAFE bool ida_local qisupper(char c) { return qisascii(c) && isupper((uchar)(c)) != 0; }
944INLINE THREAD_SAFE bool ida_local qisprint(char c) { return qisascii(c) && isprint((uchar)(c)) != 0; }
945INLINE THREAD_SAFE bool ida_local qisdigit(char c) { return qisascii(c) && isdigit((uchar)(c)) != 0; }
946INLINE THREAD_SAFE bool ida_local qisxdigit(char c) { return qisascii(c) && isxdigit((uchar)(c)) != 0; }
948
950INLINE THREAD_SAFE int ida_local qtolower(char c) { return tolower((uchar)(c)); }
952INLINE THREAD_SAFE int ida_local qtoupper(char c) { return toupper((uchar)(c)); }
953
954// We forbid using dangerous functions in IDA
955#if !defined(USE_DANGEROUS_FUNCTIONS) && !defined(__CODE_CHECKER__)
956#undef strcpy
957#define strcpy dont_use_strcpy
958#define stpcpy dont_use_stpcpy
959#define strncpy dont_use_strncpy
960#define strcat dont_use_strcat
961#define strncat dont_use_strncat
962#define gets dont_use_gets
963#define sprintf dont_use_sprintf
964#define snprintf dont_use_snprintf
965#define wsprintfA dont_use_wsprintf
966#undef strcmpi
967#undef strncmpi
968#define strcmpi dont_use_strcmpi
969#define strncmpi dont_use_strncmpi
970#define getenv dont_use_getenv
971#define setenv dont_use_setenv
972#define putenv dont_use_putenv
973#define strtok dont_use_strrok
974#undef strlwr
975#undef strupr
976#define strlwr dont_use_strlwr
977#define strupr dont_use_strupr
978#define waitid dont_use_waitid
979#define waitpid dont_use_waitpid
980#define wait dont_use_wait
981#endif
982
983//---------------------------------------------------------------------------
997idaman AS_PRINTF(3, 4) THREAD_SAFE int ida_export qsnprintf(char *buffer, size_t n, const char *format, ...);
998idaman AS_SCANF (2, 3) THREAD_SAFE int ida_export qsscanf(const char *input, const char *format, ...);
999idaman AS_PRINTF(3, 0) THREAD_SAFE int ida_export qvsnprintf(char *buffer, size_t n, const char *format, va_list va);
1000idaman AS_SCANF (2, 0) THREAD_SAFE int ida_export qvsscanf(const char *input, const char *format, va_list va);
1001idaman AS_PRINTF(3, 4) THREAD_SAFE int ida_export append_snprintf(char *buf, const char *end, const char *format, ...);
1003
1004//---------------------------------------------------------------------------
1010INLINE int nowarn_qsnprintf(char *buf, size_t size, const char *format, ...)
1011{
1012 va_list va;
1013 int code;
1014 va_start(va, format);
1015#ifdef __cplusplus
1016 code = ::qvsnprintf(buf, size, format, va);
1017#else
1018 code = qvsnprintf(buf, size, format, va);
1019#endif
1020 va_end(va);
1021 return code;
1022}
1024
1025//---------------------------------------------------------------------------
1028#if defined(__NT__)
1029#define QMAXPATH 260
1030#define QMAXFILE 260
1031#else
1032#define QMAXPATH PATH_MAX
1033#define QMAXFILE PATH_MAX
1034#endif
1035
1036idaman THREAD_SAFE char *ida_export vqmakepath(char *buf, size_t bufsize, const char *s1, va_list);
1037
1038
1045
1046idaman THREAD_SAFE char *ida_export qmakepath(char *buf, size_t bufsize, const char *s1, ...);
1047
1048
1053
1054idaman void ida_export qgetcwd(char *buf, size_t bufsize);
1055
1056
1060
1061idaman int ida_export qchdir(const char *path);
1062
1063
1072
1073idaman THREAD_SAFE bool ida_export qdirname(char *buf, size_t bufsize, const char *path);
1074
1075
1082
1083idaman THREAD_SAFE char *ida_export qmakefile(
1084 char *buf,
1085 size_t bufsize,
1086 const char *base,
1087 const char *ext);
1088
1089
1095
1096idaman THREAD_SAFE char *ida_export qsplitfile(char *file, char **base, char **ext);
1097
1098
1100
1101idaman THREAD_SAFE bool ida_export qisabspath(const char *file);
1102
1103
1106
1107idaman THREAD_SAFE const char *ida_export qbasename(const char *path);
1108
1109#ifdef __cplusplus
1111inline char *qbasename(char *path) { return CONST_CAST(char *)(qbasename((const char *)path)); }
1112#endif
1113
1114
1116
1117idaman THREAD_SAFE char *ida_export qmake_full_path(char *dst, size_t dstsize, const char *src);
1118
1119
1127
1128idaman THREAD_SAFE bool ida_export search_path(
1129 char *buf,
1130 size_t bufsize,
1131 const char *file,
1132 bool search_cwd);
1133
1135#if defined(__UNIX__)
1136#define DELIMITER ":"
1137#else
1138#define DELIMITER ";"
1139#endif
1140
1141
1149
1150idaman THREAD_SAFE char *ida_export set_file_ext(
1151 char *outbuf,
1152 size_t bufsize,
1153 const char *file,
1154 const char *ext);
1155
1156
1160
1161idaman THREAD_SAFE const char *ida_export get_file_ext(const char *file);
1162
1164#ifdef __cplusplus
1165inline THREAD_SAFE bool idaapi has_file_ext(const char *file)
1166 { return get_file_ext(file) != nullptr; }
1167#endif
1168
1169
1178
1179#ifdef __cplusplus
1180inline THREAD_SAFE char *idaapi make_file_ext(
1181 char *buf,
1182 size_t bufsize,
1183 const char *file,
1184 const char *ext)
1185{
1186 if ( has_file_ext(file) )
1187 return ::qstrncpy(buf, file, bufsize);
1188 else
1189 return set_file_ext(buf, bufsize, file, ext);
1190}
1191#endif
1192
1193
1199
1200idaman THREAD_SAFE bool ida_export sanitize_file_name(char *name, size_t namesize);
1201
1202
1208
1209bool wildcard_match(const char *name, const char *pattern);
1210
1211
1218
1219bool wildcard_path_match(const char *name, const char *_pattern, int flags=0);
1220
1221#define WPM_EXPLICIT_DOT 0x01 // match dots at the beginning of a path component explicitly
1222 // example: with this bit set,
1223 // * does not match .hidden
1224 // .* matches .hidden
1225 // * matches file.ext
1226
1231
1232idaman int ida_export regex_match(const char *str, const char *pattern, bool sense_case);
1233
1234
1235//---------------------------------------------------------------------------
1236/* input/output */
1237/*--------------------------------------------------*/
1238#if !defined(__NT__) && !defined(_MSC_VER)
1239#define O_BINARY 0
1240#endif
1241
1242#ifndef SEEK_SET
1243# define SEEK_SET 0
1244# define SEEK_CUR 1
1245# define SEEK_END 2
1246#endif
1247
1248#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
1249 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
1250#endif
1251#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
1252 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
1253#endif
1254
1255/*--------------------------------------------------*/
1256/* you should use these functions for file i/o */
1257
1260
1261idaman THREAD_SAFE int ida_export qopen(const char *file, int mode);
1262
1263
1265
1266idaman THREAD_SAFE int ida_export qopen_shared(const char *file, int mode, int share_mode);
1267
1268
1270
1271idaman THREAD_SAFE int ida_export qcreate(const char *file, int stat);
1272
1273idaman THREAD_SAFE int ida_export qread(int h, void *buf, size_t n);
1274idaman THREAD_SAFE int ida_export qwrite(int h, const void *buf, size_t n);
1275idaman THREAD_SAFE qoff64_t ida_export qtell(int h);
1276idaman THREAD_SAFE qoff64_t ida_export qseek(int h, int64 offset, int whence);
1277idaman THREAD_SAFE int ida_export qclose(int h);
1278idaman THREAD_SAFE int ida_export qdup(int h);
1279idaman THREAD_SAFE int ida_export qfsync(int h);
1280
1281
1284
1285idaman THREAD_SAFE uint64 ida_export qfilesize(const char *fname);
1286
1290
1291idaman THREAD_SAFE uint64 ida_export qfilelength(int h);
1292
1298
1299idaman THREAD_SAFE int ida_export qchsize(int h, uint64 fsize);
1300
1307
1308idaman THREAD_SAFE int ida_export qmkdir(const char *file, int mode);
1309
1315
1316idaman THREAD_SAFE int ida_export qrmdir(const char *file);
1317
1319
1320idaman THREAD_SAFE bool ida_export qfileexist(const char *file);
1321
1322
1324
1325idaman THREAD_SAFE bool ida_export qisdir(const char *file);
1326
1328idaman THREAD_SAFE int ida_export qstat(const char *path, struct qstatbuf *buf);
1329idaman THREAD_SAFE int ida_export qfstat(int fd, struct qstatbuf *buf);
1330
1332
1333idaman THREAD_SAFE int ida_export qtouchfile(const char *file_name);
1334
1335//---------------------------------------------------------------------------
1337
1338idaman THREAD_SAFE void ida_export qatexit(void (idaapi *func)(void));
1339
1340
1342
1343idaman THREAD_SAFE void ida_export del_qatexit(void (idaapi*func)(void));
1344
1345#endif // SWIG
1346
1347
1350
1351idaman THREAD_SAFE NORETURN void ida_export qexit(int code);
1352
1353//---------------------------------------------------------------------------
1354#define qmin(a,b) ((a) < (b)? (a): (b))
1355#define qmax(a,b) ((a) > (b)? (a): (b))
1356#ifdef __cplusplus
1357template <class T> T qabs(T x) { return x < 0 ? -x : x; }
1358#else
1359int qabs(int x) { return x < 0 ? -x : x; }
1360#endif
1361
1362//----------------------------------------------------------------------
1364INLINE THREAD_SAFE bool idaapi test_bit(const uchar *bitmap, size_t bit)
1365{
1366 return (bitmap[bit/8] & (1<<(bit&7))) != 0;
1367}
1368
1369INLINE THREAD_SAFE void idaapi set_bit(uchar *bitmap, size_t bit)
1370{
1371 uchar *p = bitmap + bit/8;
1372 *p = (uchar)(*p | (1<<(bit&7)));
1373}
1374
1375INLINE THREAD_SAFE void idaapi clear_bit(uchar *bitmap, size_t bit)
1376{
1377 uchar *p = bitmap + bit/8;
1378 *p = (uchar)(*p & ~(1<<(bit&7)));
1379}
1380
1381INLINE THREAD_SAFE void idaapi set_bits(uchar *bitmap, size_t low, size_t high)
1382{
1383 size_t bit;
1384 for ( bit = low; bit < high; ++bit )
1385 set_bit(bitmap, bit);
1386}
1387
1388INLINE THREAD_SAFE void idaapi clear_bits(uchar *bitmap, size_t low, size_t high)
1389{
1390 size_t bit;
1391 for ( bit = low; bit < high; ++bit )
1392 clear_bit(bitmap, bit);
1393}
1394
1395INLINE THREAD_SAFE void idaapi set_all_bits(uchar *bitmap, size_t nbits)
1396{
1397 memset(bitmap, 0xFF, nbits/8);
1398 if ( (nbits & 7) != 0 )
1399 {
1400 uchar *p = bitmap + nbits/8;
1401 *p |= ((1 << (nbits&7))-1);
1402 }
1403}
1404
1405INLINE THREAD_SAFE void idaapi clear_all_bits(uchar *bitmap, size_t nbits)
1406{
1407 memset(bitmap, 0, nbits/8);
1408 if ( (nbits & 7) != 0 )
1409 {
1410 uchar *p = bitmap + nbits/8;
1411 *p &= ~((1 << (nbits&7))-1);
1412 }
1413}
1414
1417idaman int ida_export log2ceil(uint64 d64);
1418idaman int ida_export log2floor(uint64 d64);
1419
1421idaman int ida_export bitcount(uint64 x);
1422
1425idaman int ida_export bitcountr_zero(uint64 x);
1426
1428idaman uint32 ida_export round_up_power2(uint32 x);
1429idaman uint32 ida_export round_down_power2(uint32 x);
1430
1432template <class T> constexpr bool is_pow2(T val)
1433{
1434 return ((val - 1) & val) == 0;
1435}
1436
1438template <class T> T round_up(T val, T base)
1439{
1440 T r = val % base;
1441 return r != 0 ? val + base - r : val;
1442}
1443template <class T> T round_down(T val, T base)
1444{
1445 return val - val % base;
1446}
1447
1448#ifdef __cplusplus
1449//----------------------------------------------------------------------
1451namespace interval
1452{
1454 inline THREAD_SAFE constexpr uval_t last(uval_t off, asize_t s)
1455 {
1456 return off + s - 1;
1457 }
1458
1459 inline THREAD_SAFE constexpr bool overlap(uval_t off1, asize_t s1, uval_t off2, asize_t s2)
1460 {
1461 return s1 != 0 && s2 != 0 && off2 <= last(off1, s1) && off1 <= last(off2, s2);
1462 }
1463
1464 inline THREAD_SAFE constexpr bool includes(uval_t off1, asize_t s1, uval_t off2, asize_t s2)
1465 {
1466 return s1 != 0 && off2 >= off1 && last(off2, s2) <= last(off1, s1);
1467 }
1468
1469 inline THREAD_SAFE constexpr bool contains(uval_t off1, asize_t s1, uval_t off)
1470 {
1471 return s1 != 0 && off >= off1 && off <= last(off1, s1);
1472 }
1473}
1474#endif
1475
1476//----------------------------------------------------------------------
1477#ifdef __cplusplus
1481template <class T> constexpr T left_shift(const T &value, int shift)
1482{
1483 return shift >= sizeof(T)*8 ? 0 : (value << shift);
1484}
1485
1486template <class T> constexpr T right_ushift(const T &value, int shift)
1487{
1488 return shift >= sizeof(T)*8 ? 0 : (value >> shift);
1489}
1490
1491template <class T> constexpr T right_sshift(const T &value, int shift)
1492{
1493 return shift >= sizeof(T)*8 ? (value >= 0 ? 0 : -1) : (value >> shift);
1494}
1495
1497template<class T> T qrotl(T value, size_t count)
1498{
1499 const size_t nbits = sizeof(T) * 8;
1500 count %= nbits;
1501
1502 T high = value >> (nbits - count);
1503 value <<= count;
1504 value |= high;
1505 return value;
1506}
1507
1509template<class T> T qrotr(T value, size_t count)
1510{
1511 const size_t nbits = sizeof(T) * 8;
1512 count %= nbits;
1513
1514 T low = value << (nbits - count);
1515 value >>= count;
1516 value |= low;
1517 return value;
1518}
1519
1521template <class T> constexpr T make_mask(int count)
1522{
1523 return left_shift<T>(1, count) - 1;
1524}
1525
1527template<class T, class U> void idaapi setflag(T &where, U bit, bool cnd)
1528{
1529 if ( cnd )
1530 where = T(where | bit);
1531 else
1532 where = T(where & ~T(bit));
1533}
1534
1536template<class T> bool is_mul_ok(T count, T elsize)
1537{
1538 CASSERT((T)(-1) > 0); // make sure T is unsigned
1539 if ( elsize == 0 || count == 0 )
1540 return true;
1541 return count <= ((T)(-1)) / elsize;
1542}
1543
1545template<class U, class T> bool is_add_ok(U x, T y)
1546{
1547 CASSERT((U)(-1) > 0); // make sure U is unsigned
1548 return y >= 0 ? y <= ((U)(-1)) - x : (0-y) <= x;
1549}
1550
1552template <class T> bool is_udiv_ok(T, T b)
1553{
1554 CASSERT((T)(-1) > 0); // make sure T is unsigned
1555 return b != 0; // forbid x/0
1556}
1557
1559template <class T> bool is_sdiv_ok(T a, T b)
1560{
1561 CASSERT((T)(-1) < 0); // make sure T is signed
1562 T minval = left_shift((T)1, sizeof(T)*8-1);
1563 return b != 0 && !(a == minval && b == -1); // forbid x/0, MINVAL/-1
1564}
1565
1568template <typename T>
1569inline THREAD_SAFE constexpr T extend_sign_bits(T v, int nbits)
1570{
1571 if ( nbits <= 0 )
1572 return 0;
1573 if ( nbits >= sizeof(T) * 8 )
1574 return v;
1575 T signbit = T(1) << (nbits - 1);
1576 T mask = (signbit << 1) - 1;
1577 if ( (v & signbit) != 0 )
1578 v |= ~mask;
1579 else
1580 v &= mask;
1581 return v;
1582}
1583
1587#ifdef __GNUC__
1588# define OPERATOR_NEW(type, count) (is_mul_ok(size_t(count), sizeof(type)) \
1589 ? new type[count] \
1590 : (type *)qalloc_or_throw(BADMEMSIZE))
1591#else
1592# define OPERATOR_NEW(type, count) new type[count]
1593#endif
1594
1595#endif // __cplusplus
1596
1597//-------------------------------------------------------------------------
1600
1601idaman uint64 ida_export extend_sign(uint64 v, int nbytes, bool sign_extend);
1602
1603
1605#define MC2(c1, c2) ushort(((c2)<<8)|c1)
1606#define MC3(c1, c2, c3) uint32(((((c3)<<8)|(c2))<<8)|c1)
1607#define MC4(c1, c2, c3, c4) uint32(((((((c4)<<8)|(c3))<<8)|(c2))<<8)|c1)
1608
1609
1610//---------------------------------------------------------------------------
1617
1618idaman THREAD_SAFE int ida_export readbytes(int h, uint32 *res, int size, bool mf);
1619
1620
1627
1628idaman THREAD_SAFE int ida_export writebytes(int h, uint32 l, int size, bool mf);
1629
1630
1636
1637idaman THREAD_SAFE int ida_export read2bytes(int h, uint16 *res, bool mf);
1638
1639#define read4bytes(h, res, mf) readbytes(h, res, 4, mf)
1640#define write2bytes(h, l, mf) writebytes(h, l, 2, mf)
1641#define write4bytes(h, l, mf) writebytes(h, l, 4, mf)
1642
1643//---------------------------------------------------------------------------
1648#ifdef __cplusplus
1649# ifndef swap32
1650inline THREAD_SAFE constexpr uint32 swap32(uint32 x)
1651 { return (x>>24) | (x<<24) | ((x>>8) & 0x0000FF00) | ((x<<8) & 0x00FF0000); }
1652# endif
1653# ifndef swap16
1654inline THREAD_SAFE constexpr ushort swap16(ushort x)
1655 { return ushort((x<<8) | (x>>8)); }
1656# endif
1657#else
1658# ifndef swap32
1659# define swap32(x) uint32((x>>24) | (x<<24) | ((x>>8) & 0x0000FF00) | ((x<<8) & 0x00FF0000))
1660# endif
1661# ifndef swap16
1662# define swap16(x) ushort((x<<8) | (x>>8))
1663# endif
1664#endif
1665
1667#ifdef __EA64__
1668#define swapea swap64
1669#else
1670#define swapea swap32
1671#endif
1672
1677#if __MF__
1678#define qhtonl(x) (x)
1679#define qntohl(x) (x)
1680#define qhtons(x) (x)
1681#define qntohs(x) (x)
1682#else
1683#define qhtons(x) swap16(x)
1684#define qntohs(x) swap16(x)
1685#define qhtonl(x) swap32(x)
1686#define qntohl(x) swap32(x)
1687#endif
1688
1689
1695
1696idaman THREAD_SAFE void ida_export swap_value(void *dst, const void *src, int size);
1697
1698
1699idaman THREAD_SAFE void ida_export reloc_value(void *value, int size, adiff_t delta, bool mf);
1700
1701
1709
1710idaman THREAD_SAFE uval_t ida_export rotate_left(uval_t x, int count, size_t bits, size_t offset);
1711
1712
1713#ifdef __cplusplus
1715template <class T> inline THREAD_SAFE void qswap(T &a, T &b)
1716{
1717 char temp[sizeof(T)];
1718 memcpy(&temp, &a, sizeof(T));
1719 memcpy(&a, &b, sizeof(T));
1720 memcpy(&b, &temp, sizeof(T));
1721}
1722
1723//---------------------------------------------------------------------------
1724#ifndef SWIG
1727//{
1728
1736
1737THREAD_SAFE inline uchar *idaapi pack_db(uchar *ptr, uchar *end, uchar x)
1738{
1739 if ( ptr < end )
1740 *ptr++ = x;
1741 return ptr;
1742}
1743
1744
1746
1747THREAD_SAFE inline uchar idaapi unpack_db(const uchar **pptr, const uchar *end)
1748{
1749 const uchar *ptr = *pptr;
1750 uchar x = 0;
1751 if ( ptr < end )
1752 x = *ptr++;
1753 *pptr = ptr;
1754 return x;
1755}
1756
1757idaman THREAD_SAFE uchar *ida_export pack_dw(uchar *ptr, uchar *end, uint16 x);
1758idaman THREAD_SAFE uchar *ida_export pack_dd(uchar *ptr, uchar *end, uint32 x);
1759idaman THREAD_SAFE uchar *ida_export pack_dq(uchar *ptr, uchar *end, uint64 x);
1760idaman THREAD_SAFE ushort ida_export unpack_dw(const uchar **pptr, const uchar *end);
1761idaman THREAD_SAFE uint32 ida_export unpack_dd(const uchar **pptr, const uchar *end);
1762idaman THREAD_SAFE uint64 ida_export unpack_dq(const uchar **pptr, const uchar *end);
1763
1765
1766THREAD_SAFE inline uchar *pack_ea(uchar *ptr, uchar *end, ea_t ea)
1767{
1768#ifdef __EA64__
1769 return pack_dq(ptr, end, ea);
1770#else
1771 return pack_dd(ptr, end, ea);
1772#endif
1773}
1774
1776
1777THREAD_SAFE inline ea_t unpack_ea(const uchar **ptr, const uchar *end)
1778{
1779#ifdef __EA64__
1780 return unpack_dq(ptr, end);
1781#else
1782 return unpack_dd(ptr, end);
1783#endif
1784}
1785
1787THREAD_SAFE inline ea64_t unpack_ea64(const uchar **ptr, const uchar *end)
1788{
1789 return unpack_dq(ptr, end) - 1;
1790}
1791
1792
1800
1801THREAD_SAFE inline void *idaapi unpack_obj(
1802 void *destbuf,
1803 size_t destsize,
1804 const uchar **pptr,
1805 const uchar *end)
1806{
1807 const uchar *src = *pptr;
1808 const uchar *send = src + destsize;
1809 if ( send < src || send > end )
1810 return nullptr;
1811 *pptr = send;
1812 return memcpy(destbuf, src, destsize);
1813}
1814
1815
1823
1824THREAD_SAFE inline void *idaapi unpack_buf(const uchar **pptr, const uchar *end)
1825{
1826 size_t size = unpack_dd(pptr, end);
1827 if ( size == 0 )
1828 return nullptr;
1829 const uchar *src = *pptr;
1830 const uchar *srcend = src + size;
1831 if ( srcend < src || srcend > end )
1832 return nullptr;
1833 void *dst = qalloc(size);
1834 if ( dst != nullptr )
1835 {
1836 memcpy(dst, src, size);
1837 *pptr = srcend;
1838 }
1839 return dst;
1840}
1841
1842
1846
1847THREAD_SAFE inline const void *idaapi unpack_obj_inplace(
1848 const uchar **pptr,
1849 const uchar *end,
1850 size_t objsize)
1851{
1852 const uchar *ret = *pptr;
1853 const uchar *rend = ret + objsize;
1854 if ( rend < ret || rend > end )
1855 return nullptr;
1856 *pptr = rend;
1857 return ret;
1858}
1859
1860
1864
1865THREAD_SAFE inline const void *idaapi unpack_buf_inplace(
1866 const uchar **pptr,
1867 const uchar *end)
1868{
1869 size_t objsize = unpack_dd(pptr, end);
1870 return unpack_obj_inplace(pptr, end, objsize);
1871}
1872
1873
1880
1881idaman THREAD_SAFE uchar *ida_export pack_ds(
1882 uchar *ptr,
1883 uchar *end,
1884 const char *x,
1885 size_t len=0);
1886
1887
1896
1897idaman THREAD_SAFE char *ida_export unpack_ds(
1898 const uchar **pptr,
1899 const uchar *end,
1900 bool empty_null);
1901
1908THREAD_SAFE inline bool unpack_ds_to_buf(
1909 char *dst,
1910 size_t dstsize,
1911 const uchar **pptr,
1912 const uchar *end)
1913{
1914 const void *buf = unpack_buf_inplace(pptr, end);
1915 if ( buf == nullptr )
1916 return false;
1917 size_t size = *pptr - (const uchar *)buf;
1918 if ( size >= dstsize )
1919 size = dstsize - 1;
1920 memcpy(dst, buf, size);
1921 dst[size] = '\0';
1922 return true;
1923}
1924
1925
1928
1929idaman THREAD_SAFE bool ida_export unpack_xleb128(
1930 void *res,
1931 int nbits,
1932 bool is_signed,
1933 const uchar **pptr,
1934 const uchar *end);
1935
1939
1940template <class T>
1941inline THREAD_SAFE bool unpack_uleb128(T *res, const uchar **pptr, const uchar *end)
1942{
1943 CASSERT((T)(-1) > 0); // make sure T is unsigned
1944 return unpack_xleb128(res, sizeof(T)*8, false, pptr, end);
1945}
1946
1947template <class T>
1948inline THREAD_SAFE bool unpack_sleb128(T *res, const uchar **pptr, const uchar *end)
1949{
1950 CASSERT((T)(-1) < 0); // make sure T is signed
1951 return unpack_xleb128(res, sizeof(T)*8, true, pptr, end);
1952}
1953
1955
1956// packed sizes
1958static constexpr int ea_packed_size = sizeof(ea_t) + sizeof(ea_t)/4; // 5 or 10 bytes
1959static constexpr int dq_packed_size = 10;
1960static constexpr int dd_packed_size = 5;
1961static constexpr int dw_packed_size = 3;
1963
1964inline THREAD_SAFE int ds_packed_size(const char *s) { return s ? int(strlen(s)+dd_packed_size) : 1; }
1965
1966//----------------------------------------------------------------------------
1967inline THREAD_SAFE constexpr int dw_size(uchar first_byte)
1968{
1969 return (first_byte & 0x80) == 0 ? 1
1970 : (first_byte & 0xC0) == 0xC0 ? 3
1971 : 2;
1972}
1973
1974//----------------------------------------------------------------------------
1975inline THREAD_SAFE constexpr int dd_size(uchar first_byte)
1976{
1977 return (first_byte & 0x80) == 0x00 ? 1
1978 : (first_byte & 0xC0) != 0xC0 ? 2
1979 : (first_byte & 0xE0) == 0xE0 ? 5
1980 : 4;
1981}
1982
1983//----------------------------------------------------------------------------
1984// unpack data from an object which must have the following functions:
1985// ssize_t read(void *buf, size_t count)
1986// bool eof() - return true if there is no more data to read
1987template <class T>
1988inline THREAD_SAFE uchar extract_db(T &v)
1989{
1990 uchar x = 0;
1991 v.read(&x, 1);
1992 return x;
1993}
1994
1995template <class T>
1996inline THREAD_SAFE void *extract_obj(T &v, void *destbuf, size_t destsize)
1997{
1998 if ( destsize == 0 )
1999 return nullptr;
2000 return v.read(destbuf, destsize) == destsize ? destbuf : nullptr;
2001}
2002
2003template <class T>
2004inline THREAD_SAFE uint16 extract_dw(T &v)
2005{
2006 uchar packed[dw_packed_size];
2007 packed[0] = extract_db(v);
2008 int psize = dw_size(packed[0]);
2009 extract_obj(v, &packed[1], psize-1);
2010 const uchar *ptr = packed;
2011 return unpack_dw(&ptr, packed + psize);
2012}
2013
2014template <class T>
2015inline THREAD_SAFE uint32 extract_dd(T &v)
2016{
2017 uchar packed[dd_packed_size];
2018 packed[0] = extract_db(v);
2019 int psize = dd_size(packed[0]);
2020 extract_obj(v, &packed[1], psize-1);
2021 const uchar *ptr = packed;
2022 return unpack_dd(&ptr, packed + psize);
2023}
2024
2025template <class T>
2026inline THREAD_SAFE uint64 extract_dq(T &v)
2027{
2028 uint32 l = extract_dd(v);
2029 uint32 h = extract_dd(v);
2030 return make_uint64(l, h);
2031}
2032
2033template <class T>
2034inline THREAD_SAFE ea_t extract_ea(T &v)
2035{
2036#ifdef __EA64__
2037 return extract_dq(v);
2038#else
2039 return extract_dd(v);
2040#endif
2041}
2042
2043template <class T>
2044inline THREAD_SAFE void *extract_buf(T &v, size_t size)
2045{
2046 void *buf = qalloc(size);
2047 if ( buf == nullptr )
2048 return nullptr;
2049 return extract_obj(v, buf, size);
2050}
2051
2052template <class T>
2053inline THREAD_SAFE void *extract_array(T &v, size_t *sz, size_t maxsize)
2054{
2055 size_t size = extract_dd(v);
2056 if ( size == 0 || size > maxsize )
2057 return nullptr;
2058 *sz = size;
2059 return extract_buf(v, size);
2060}
2061
2062inline const char *unpack_str(const uchar **pptr, const uchar *end)
2063{ // zero terminated string, return inplace ptr
2064 const uchar *ptr = *pptr;
2065 const uchar *str = ptr;
2066 do
2067 if ( ptr >= end )
2068 return nullptr; // no terminating zero?
2069 while ( *ptr++ != '\0' );
2070 *pptr = ptr;
2071 return (char*)str;
2072}
2073
2075#endif // SWIG
2076#endif // cplusplus
2077
2083#define APPCHAR(buf, end, chr) \
2084 do \
2085 { \
2086 char __chr = (chr); \
2087 QASSERT(518, (buf) < (end)); \
2088 *(buf)++ = __chr; \
2089 if ( (buf) >= (end) ) \
2090 { \
2091 (buf) = (end)-1; \
2092 (buf)[0] = '\0'; \
2093 } \
2094 } while (0)
2095
2098#define APPZERO(buf, end) \
2099 do \
2100 { \
2101 QASSERT(519, (buf) < (end)); \
2102 *(buf) = '\0'; \
2103 } while (0)
2104
2106#define APPEND(buf, end, name) \
2107 do \
2108 { \
2109 QASSERT(520, (buf) < (end)); \
2110 const char *__ida_in = (name); \
2111 while ( true ) \
2112 { \
2113 if ( (buf) == (end)-1 ) \
2114 { \
2115 (buf)[0] = '\0'; \
2116 break; \
2117 } \
2118 if ( (*(buf) = *__ida_in++) == '\0' ) \
2119 break; \
2120 (buf)++; \
2121 } \
2122 } while ( 0 )
2124
2126
2127idaman THREAD_SAFE void *ida_export qalloc_or_throw(size_t size);
2128
2129
2131
2132idaman THREAD_SAFE void *ida_export qrealloc_or_throw(void *ptr, size_t size);
2133
2134
2141
2142idaman THREAD_SAFE void *ida_export qvector_reserve(void *vec, void *old, size_t cnt, size_t elsize);
2143
2144#if defined(__cplusplus)
2149 #if defined(SWIG)
2150 #define DEFINE_MEMORY_ALLOCATION_FUNCS()
2151 #else
2152 #define PLACEMENT_DELETE void operator delete(void *, void *) {}
2153 #define DEFINE_MEMORY_ALLOCATION_FUNCS() \
2154 void *operator new (size_t _s) { return qalloc_or_throw(_s); } \
2155 void *operator new[](size_t _s) { return qalloc_or_throw(_s); } \
2156 void *operator new(size_t /*size*/, void *_v) { return _v; } \
2157 void operator delete (void *_blk) { qfree(_blk); } \
2158 void operator delete[](void *_blk) { qfree(_blk); } \
2159 PLACEMENT_DELETE
2160 #endif
2161
2163#define DECLARE_COMPARISON_OPERATORS(type) \
2164 bool operator==(const type &r) const { return compare(r) == 0; } \
2165 bool operator!=(const type &r) const { return compare(r) != 0; } \
2166 bool operator< (const type &r) const { return compare(r) < 0; } \
2167 bool operator> (const type &r) const { return compare(r) > 0; } \
2168 bool operator<=(const type &r) const { return compare(r) <= 0; } \
2169 bool operator>=(const type &r) const { return compare(r) >= 0; }
2170
2173#define DECLARE_COMPARISONS(type) \
2174 DECLARE_COMPARISON_OPERATORS(type) \
2175 int compare(const type &r) const
2176
2177// Internal declarations to detect movable types
2179// Can we move around objects of type T using simple memcpy/memmove?.
2180// This class can be specialized for any type T to improve qvector's behavior.
2181template <class T> struct ida_movable_type
2182{
2183 static constexpr bool value = std::is_pod<T>::value;
2184};
2185#define DECLARE_TYPE_AS_MOVABLE(T) template <> struct ida_movable_type<T> { static constexpr bool value = true; }
2186template <class T> inline constexpr THREAD_SAFE bool may_move_bytes(void)
2187{
2188 return ida_movable_type<T>::value;
2189}
2191
2196template<class T>
2197inline void shift_down(T *dst, T *src, size_t cnt)
2198{
2199 if ( may_move_bytes<T>() )
2200 {
2201 memmove(dst, src, cnt*sizeof(T));
2202 }
2203 else
2204 {
2205 ssize_t s = cnt;
2206 while ( --s >= 0 )
2207 {
2208 new(dst) T(std::move(*src));
2209 src->~T();
2210 ++src;
2211 ++dst;
2212 }
2213 }
2214}
2215
2219template<class T>
2220inline void shift_up(T *dst, T *src, size_t cnt)
2221{
2222 if ( may_move_bytes<T>() )
2223 {
2224 memmove(dst, src, cnt*sizeof(T));
2225 }
2226 else
2227 {
2228 ssize_t s = cnt;
2229 dst += s;
2230 src += s;
2231 while ( --s >= 0 )
2232 {
2233 --src;
2234 --dst;
2235 new(dst) T(std::move(*src));
2236 src->~T();
2237 }
2238 }
2239}
2240
2241
2242//---------------------------------------------------------------------------
2249template <class T> class qvector
2250{
2251 T *array;
2252 size_t n, alloc;
2253 friend void *ida_export qvector_reserve(void *vec, void *old, size_t cnt, size_t elsize);
2255 qvector<T> &assign(const qvector<T> &x)
2256 {
2257 size_t _newsize = x.n;
2258 if ( _newsize > 0 )
2259 {
2260 array = (T*)qalloc_or_throw(_newsize * sizeof(T));
2261 alloc = _newsize;
2262 copy_range(x, 0, _newsize);
2263 }
2264 return *this;
2265 }
2267 void copy_range(const qvector<T> &x, size_t from, size_t _newsize)
2268 {
2269 if ( std::is_trivially_copyable<T>::value )
2270 {
2271 memcpy(array + from, x.array + from, (_newsize-from)*sizeof(T));
2272 }
2273 else
2274 {
2275 for ( size_t i = from; i < _newsize; i++ )
2276 new(array+i) T(x.array[i]);
2277 }
2278 n = _newsize;
2279 }
2280 void free_memory()
2281 {
2282 qfree(array);
2283 array = nullptr;
2284 alloc = 0;
2285 }
2287 void resize_less(size_t _newsize)
2288 {
2289 if ( !std::is_trivially_destructible<T>::value )
2290 {
2291 size_t _size = n;
2292 for ( size_t i = _newsize; i < _size; i++ )
2293 array[i].~T();
2294 }
2295 n = _newsize;
2296#ifdef TESTABLE_BUILD
2298 if ( n == 0 )
2299 free_memory();
2300#endif
2301 }
2304 void resize_more_trivial(size_t _newsize)
2305 {
2306 reserve(_newsize);
2307 memset(array+n, 0, (_newsize-n)*sizeof(T));
2308 n = _newsize;
2309 }
2311 void resize_more(size_t _newsize, const T &x)
2312 {
2313 reserve(_newsize);
2314 for ( size_t i = n; i < _newsize; i++ )
2315 new(array+i) T(x);
2316 n = _newsize;
2317 }
2318
2319 bool ref_within_range(const T &x) const
2320 {
2321 const T *const p = &x;
2322 return p >= array && p < array + alloc;
2323 }
2324
2325public:
2326 typedef T value_type;
2328 qvector(void) : array(nullptr), n(0), alloc(0) {}
2330 qvector(const qvector<T> &x) : array(nullptr), n(0), alloc(0) { assign(x); }
2331#ifndef SWIG
2333 qvector(qvector<T> &&x) noexcept
2334 {
2335 array = x.array; x.array = nullptr;
2336 n = x.n; x.n = 0;
2337 alloc = x.alloc; x.alloc = 0;
2338 }
2339#endif
2342 {
2343 if ( array != nullptr )
2344 {
2345 resize_less(0);
2346 free_memory();
2347 }
2348 }
2351 void push_back(const T &x)
2352 {
2353 TB_QASSERT(1907, !ref_within_range(x));
2354 T val(x);
2355 reserve(n+1);
2356 new (array+n) T(std::move(val));
2357 ++n;
2358 }
2359#ifndef SWIG
2361 void push_back(T &&x)
2362 {
2363 bool aliasing = ref_within_range(x);
2364 TB_QASSERT(1977, !aliasing);
2365 if ( aliasing )
2366 {
2367 // If x aliases an element inside the same container and
2368 // reserve triggers a reallocation, the reference x becomes
2369 // dangling immediately. Any attempt to read/move from x
2370 // after reserve would be UB.
2371 // Therefore, we capture the value first while x still refers
2372 // to a valid object.
2373 T val(std::move(x));
2374 reserve(n+1);
2375 new (array+n) T(std::move(val));
2376 }
2377 else
2378 {
2379 reserve(n+1);
2380 new (array+n) T(std::move(x));
2381 }
2382 ++n;
2383 }
2384#endif
2385
2386#ifndef SWIG
2389 template <typename... Args>
2390 void emplace_back(Args && ... args)
2391 {
2392 // If any args... are references to elements inside this same container,
2393 // and reserve reallocates, those references dangle before we use them.
2394 reserve(n+1);
2395 new (array+n) T(std::forward<Args>(args)...);
2396 ++n;
2397 }
2398#endif
2399
2402 T &push_back(void)
2403 {
2404 reserve(n+1);
2405 T *ptr = array + n;
2406 new (ptr) T;
2407 ++n;
2408 return *ptr;
2409 }
2410
2411 void pop_back(void)
2412 {
2413 if ( n > 0 )
2414 {
2415 array[--n].~T();
2416#ifdef TESTABLE_BUILD
2418 if ( n == 0 )
2419 free_memory();
2420#endif
2421 }
2422 }
2423 size_t size(void) const { return n; }
2424 bool empty(void) const { return n == 0; }
2425 const T &operator[](size_t _idx) const { return array[_idx]; }
2426 T &operator[](size_t _idx) { return array[_idx]; }
2427 const T &at(size_t _idx) const { return array[_idx]; }
2428 T &at(size_t _idx) { return array[_idx]; }
2429 const T &front(void) const { return array[0]; }
2430 T &front(void) { return array[0]; }
2431 const T &back(void) const { return array[n-1]; }
2432 T &back(void) { return array[n-1]; }
2434 void qclear(void)
2435 {
2436 resize_less(0);
2437 }
2438
2439 void clear(void)
2440 {
2441 if ( array != nullptr )
2442 {
2443 qclear();
2444 free_memory();
2445 }
2446 }
2447
2449 {
2450 qvector<T> copy(x);
2451 return operator=(std::move(copy));
2452 }
2453#ifndef SWIG
2456 {
2457 qvector<T> m(std::forward<qvector<T>>(x));
2458 clear();
2459 array = m.array; m.array = nullptr;
2460 n = m.n; m.n = 0;
2461 alloc = m.alloc; m.alloc = 0;
2462 return *this;
2463 }
2464#endif
2469 void resize(size_t _newsize, const T &x)
2470 {
2471#ifdef TESTABLE_BUILD
2472 QASSERT(1908, !ref_within_range(x));
2473#endif
2474 if ( _newsize < n )
2475 resize_less(_newsize);
2476 else if ( _newsize > n )
2477 {
2478 if ( ref_within_range(x) )
2479 resize_more(_newsize, T(x));
2480 else
2481 resize_more(_newsize, x);
2482 }
2483 }
2484
2485 void resize(size_t _newsize)
2486 {
2487 if ( std::is_trivially_constructible<T>::value && _newsize > n )
2488 resize_more_trivial(_newsize);
2489 else if ( _newsize == n )
2490 return;
2491#if __cplusplus >= 201703
2492 else if constexpr ( std::is_default_constructible<T>::value )
2493 resize(_newsize, T());
2494 else if ( _newsize < n )
2495 resize_less(_newsize);
2496 else
2497 QASSERT(3396, false);
2498#else
2499 resize(_newsize, T());
2500#endif
2501 }
2502#ifndef SWIG
2503 // Resize the array but do not initialize elements
2504 void resize_noinit(size_t _newsize)
2505 {
2506 CASSERT(std::is_trivially_constructible<T>::value);
2507 CASSERT(std::is_trivially_destructible<T>::value);
2508 reserve(_newsize);
2509 n = _newsize;
2510 }
2511#endif
2513 void grow(const T &x=T())
2514 {
2515#ifdef TESTABLE_BUILD
2516 QASSERT(1909, !ref_within_range(x));
2517#endif
2518 T val(x);
2519 reserve(n+1);
2520 new(array+n) T(std::move(val));
2521 ++n;
2522 }
2523
2525 size_t capacity(void) const { return alloc; }
2528 void reserve(size_t cnt)
2529 {
2530 if ( cnt > alloc )
2531 {
2532 if ( may_move_bytes<T>() )
2533 {
2534 array = (T *)qvector_reserve(this, array, cnt, sizeof(T));
2535 }
2536 else
2537 {
2538 size_t old_alloc = alloc;
2539 T *new_array = (T *)qvector_reserve(this, nullptr, cnt, sizeof(T));
2540 size_t new_alloc = alloc;
2541 alloc = old_alloc;
2542 shift_down(new_array, array, n);
2543 qfree(array);
2544 array = new_array;
2545 alloc = new_alloc;
2546 }
2547 }
2548 }
2549
2550 void truncate(void)
2551 {
2552 if ( alloc > n )
2553 {
2554 array = (T*)qrealloc(array, n*sizeof(T)); // should not fail
2555 alloc = n;
2556 }
2557 }
2558
2560 void swap(qvector<T> &r) noexcept
2561 {
2562 T *array2 = array;
2563 size_t n2 = n;
2564 size_t alloc2 = alloc;
2565
2566 array = r.array;
2567 n = r.n;
2568 alloc = r.alloc;
2569
2570 r.array = array2;
2571 r.n = n2;
2572 r.alloc = alloc2;
2573 }
2574
2576 T *extract(void)
2577 {
2578 truncate();
2579 alloc = 0;
2580 n = 0;
2581 T *res = array;
2582 array = nullptr;
2583 return res;
2584 }
2585
2587 void inject(T *s, size_t len)
2588 {
2589 array = s;
2590 alloc = len;
2591 n = len;
2592 }
2593
2594 bool operator == (const qvector<T> &r) const
2595 {
2596 if ( n != r.n )
2597 return false;
2598 for ( size_t i=0; i < n; i++ )
2599 if ( array[i] != r[i] )
2600 return false;
2601 return true;
2602 }
2603
2604 bool operator != (const qvector<T> &r) const { return !(*this == r); }
2605
2606 typedef T *iterator;
2607 typedef const T *const_iterator;
2608
2609 iterator begin(void) { return array; }
2610 iterator end(void) { return array + n; }
2611 const_iterator begin(void) const { return array; }
2612 const_iterator end(void) const { return array + n; }
2617 iterator insert(iterator it, const T &x)
2618 {
2619#ifdef TESTABLE_BUILD
2620 QASSERT(1910, !ref_within_range(x));
2621#endif
2622 T val(x);
2623 size_t idx = it - array;
2624 reserve(n+1);
2625 T *p = array + idx;
2626 size_t rest = end() - p;
2627 shift_up(p+1, p, rest);
2628 new(p) T(std::move(val));
2629 n++;
2630 return iterator(p);
2631 }
2632#ifndef SWIG
2635 {
2636#ifdef TESTABLE_BUILD
2637 QASSERT(1978, !ref_within_range(x));
2638#endif
2639 T val(std::forward<T>(x));
2640 size_t idx = it - array;
2641 reserve(n+1);
2642 T *p = array + idx;
2643 size_t rest = end() - p;
2644 shift_up(p+1, p, rest);
2645 new(p) T(std::move(val));
2646 n++;
2647 return iterator(p);
2648 }
2649#endif
2655 template <class it2> iterator insert(iterator it, it2 first, it2 last)
2656 {
2657 size_t cnt = last - first;
2658 if ( cnt == 0 )
2659 return it;
2660
2661 size_t idx = it - array;
2662 reserve(n+cnt);
2663 T *p = array + idx;
2664 size_t rest = end() - p;
2665 shift_up(p+cnt, p, rest);
2666 while ( first != last )
2667 {
2668 new(p) T(*first);
2669 ++p;
2670 ++first;
2671 }
2672 n += cnt;
2673 return iterator(array+idx);
2674 }
2675
2679 {
2680 it->~T();
2681 size_t rest = end() - it - 1;
2682 shift_down(it, it+1, rest);
2683 n--;
2684 return it;
2685 }
2686
2691 {
2692 for ( T *p=first; p != last; ++p )
2693 p->~T();
2694 size_t rest = end() - last;
2695 shift_down(first, last, rest);
2696 n -= last - first;
2697 return first;
2698 }
2699 // non-standard extensions:
2703 iterator find(const T &x)
2704 {
2705 iterator p;
2707 for ( p=begin(), e=end(); p != e; ++p )
2708 if ( x == *p )
2709 break;
2710 return p;
2711 }
2712
2713 const_iterator find(const T &x) const
2714 {
2715 const_iterator p, e;
2716 for ( p=begin(), e=end(); p != e; ++p )
2717 if ( x == *p )
2718 break;
2719 return p;
2720 }
2721#ifndef SWIG
2723 ssize_t index(const T &x) const
2724 {
2725 for ( const_iterator p=begin(), e=end(); p != e; ++p )
2726 if ( x == *p )
2727 return p - begin();
2728 return -1;
2729 }
2730
2731 void add(const T &x) { push_back(x); }
2732 void add(T &&x) { push_back(x); }
2733#endif
2735 bool has(const T &x) const { return find(x) != end(); }
2739 bool add_unique(const T &x)
2740 {
2741 if ( has(x) )
2742 return false;
2743 push_back(x);
2744 return true;
2745 }
2746
2749 bool del(const T &x)
2750 {
2751 iterator p = find(x);
2752 if ( p == end() )
2753 return false;
2754 erase(p);
2755 return true;
2756 }
2757#ifndef SWIG
2758 const char *dstr(void) const; // debug print
2759#endif
2760};
2761
2768
2772template<class T>
2773class qstack : public qvector<T>
2774{
2775 typedef qvector<T> inherited;
2776public:
2777 T pop(void)
2778 {
2779 T v = inherited::back();
2781 return v;
2782 }
2783 const T &top(void) const
2784 {
2785 return inherited::back();
2786 }
2787 T &top(void) { return CONST_CAST(T&)(CONST_CAST(const qstack<T>*)(this)->top()); }
2788 void push(const T &v)
2789 {
2791 }
2792};
2793
2794//---------------------------------------------------------------------------
2797template<typename T>
2799{
2800 // allocate 4MB at once. this way for 16GB we would use 4096 pools.
2801 enum
2802 {
2803 pool_size = 4*1024*1024,
2804 pool_nelems = pool_size / sizeof(T),
2805 };
2806 // we will reuse the freed space to maintain a list of free slots.
2807 // for this we need the slot size to be big enough to hold a pointer.
2808 // also, pool elements must be smaller than the pool size.
2809 CASSERT(sizeof(T) >= sizeof(void *) && pool_nelems > 0);
2810
2811 qvector<T *> pools;
2812 T *free_list = nullptr; // singly linked list
2813 T *pool_ptr = nullptr;
2814 T *pool_end = nullptr;
2815 size_t live_objects = 0;
2816
2817 //---------------------------------------------------------------------------
2818 void free_entire_pool()
2819 {
2820 for ( T *p : pools )
2821 qfree(p);
2822 pools.clear();
2823 free_list = nullptr;
2824 pool_ptr = nullptr;
2825 pool_end = nullptr;
2826 }
2827
2828public:
2829 // boilerplate definitions that are required for allocators:
2830 typedef T value_type;
2831 typedef T *pointer;
2832 typedef const T *const_pointer;
2833 typedef T &reference;
2834 typedef const T &const_reference;
2835 typedef size_t size_type;
2836 typedef ptrdiff_t difference_type;
2838 template<typename U> pool_allocator_t(const pool_allocator_t<U> &) {}
2840 pool_allocator_t &operator=(const pool_allocator_t &) { return *this; }
2843 bool operator==(const pool_allocator_t &r) const { return this == &r; }
2844
2845 //---------------------------------------------------------------------------
2846 T *allocate(size_t n)
2847 {
2848 if ( n != 1 )
2849 return (T*)qalloc_or_throw(n*sizeof(T));
2850
2851 live_objects++;
2852 if ( free_list != nullptr )
2853 {
2854 T *ptr = free_list;
2855 free_list = *(T**)ptr;
2856 return ptr;
2857 }
2858
2859 if ( pool_ptr == pool_end )
2860 {
2861 pool_ptr = (T*)qalloc_or_throw(pool_nelems*sizeof(T));
2862 pool_end = pool_ptr + pool_nelems;
2863 pools.push_back(pool_ptr);
2864 }
2865 return pool_ptr++;
2866 }
2867
2868 //---------------------------------------------------------------------------
2869 void deallocate(T *ptr, size_t n)
2870 {
2871 if ( n != 1 )
2872 {
2873 qfree(ptr);
2874 }
2875 else
2876 {
2877 *(T**)ptr = free_list;
2878 free_list = ptr;
2879 if ( --live_objects == 0 )
2880 free_entire_pool();
2881 }
2882 }
2883};
2884
2885//---------------------------------------------------------------------------
2888template <class T> int lexcompare(const T &a, const T &b)
2889{
2890 if ( a < b )
2891 return -1;
2892 if ( a > b )
2893 return 1;
2894 return 0;
2895}
2896
2897//---------------------------------------------------------------------------
2903template <class T> int lexcompare_vectors(const T &a, const T &b)
2904{
2905 if ( a.size() != b.size() )
2906 return a.size() > b.size() ? 1 : -1;
2907 for ( int i=0; i < a.size(); i++ )
2908 {
2909 int code = lexcompare(a[i], b[i]);
2910 if ( code != 0 )
2911 return code;
2912 }
2913 return 0;
2914}
2915
2916//---------------------------------------------------------------------------
2918template <class T>
2920{
2921 T *ptr;
2922 void delref(void)
2923 {
2924 if ( ptr != nullptr && --ptr->refcnt == 0 )
2925 ptr->release();
2926 }
2927public:
2928 explicit qrefcnt_t(T *p) : ptr(p) {}
2929 qrefcnt_t(const qrefcnt_t &r) : ptr(r.ptr)
2930 {
2931 if ( ptr != nullptr )
2932 ptr->refcnt++;
2933 }
2935 {
2936 delref();
2937 ptr = r.ptr;
2938 if ( ptr != nullptr )
2939 ptr->refcnt++;
2940 return *this;
2941 }
2943 {
2944 delref();
2945 }
2946 void reset(void)
2947 {
2948 delref();
2949 ptr = nullptr;
2950 }
2951 operator T *() const
2952 {
2953 return ptr;
2954 }
2955 T *operator ->() const
2956 {
2957 return ptr;
2958 }
2959 T &operator *() const
2960 {
2961 return *ptr;
2962 }
2963};
2964
2965//---------------------------------------------------------------------------
2968{
2969public:
2972 qrefcnt_obj_t(void) : refcnt(1) {}
2977 virtual void idaapi release(void) = 0;
2978};
2979
2980//---------------------------------------------------------------------------
2982template <class T>
2984{
2985public:
2986 typedef T value_type;
2987 virtual bool idaapi first(void) = 0;
2988 virtual bool idaapi next(void) = 0;
2989 virtual T idaapi operator *(void) = 0;
2990 virtual T get(void) newapi { return this->operator*(); }
2991};
2992
2993
2994//---------------------------------------------------------------------------
2998inline THREAD_SAFE size_t idaapi qstrlen(const char *s) { return strlen(s); }
2999inline THREAD_SAFE size_t idaapi qstrlen(const uchar *s) { return strlen((const char *)s); }
3000idaman THREAD_SAFE size_t ida_export qstrlen(const wchar16_t *s);
3002
3011inline THREAD_SAFE int idaapi qstrcmp(const char *s1, const char *s2) { return strcmp(s1, s2); }
3012inline THREAD_SAFE int idaapi qstrcmp(const uchar *s1, const uchar *s2) { return strcmp((const char *)s1, (const char *)s2); }
3013idaman THREAD_SAFE int ida_export qstrcmp(const wchar16_t *s1, const wchar16_t *s2);
3015
3024inline THREAD_SAFE int idaapi qstrncmp(const char *s1, const char *s2, size_t len) { return strncmp(s1, s2, len); }
3025inline THREAD_SAFE int idaapi qstrncmp(const uchar *s1, const uchar *s2, size_t len) { return strncmp((const char *)s1, (const char *)s2, len); }
3026idaman THREAD_SAFE int ida_export qstrncmp(const wchar16_t *s1, const wchar16_t *s2, size_t len);
3028
3033inline THREAD_SAFE char *idaapi qstrstr(char *s1, const char *s2) { return strstr(s1, s2); }
3034inline THREAD_SAFE const char *idaapi qstrstr(const char *s1, const char *s2) { return strstr(s1, s2); }
3035inline THREAD_SAFE const uchar *idaapi qstrstr(const uchar *s1, const uchar *s2) { return (const uchar *)strstr((const char *)s1, (const char *)s2); }
3037
3042inline THREAD_SAFE char *idaapi qstrchr(char *s1, char c) { return strchr(s1, c); }
3043inline THREAD_SAFE const char *idaapi qstrchr(const char *s1, char c) { return strchr(s1, c); }
3044inline THREAD_SAFE uchar *idaapi qstrchr(uchar *s1, uchar c) { return (uchar *)strchr((char *)s1, c); }
3045inline THREAD_SAFE const uchar *idaapi qstrchr(const uchar *s1, uchar c) { return (const uchar *)strchr((const char *)s1, c); }
3046idaman THREAD_SAFE const wchar16_t *ida_export qstrchr(const wchar16_t *s1, wchar16_t c);
3047inline THREAD_SAFE wchar16_t *idaapi qstrchr(wchar16_t *s1, wchar16_t c)
3048 { return (wchar16_t *)qstrchr((const wchar16_t *)s1, c); }
3049
3050
3055inline THREAD_SAFE const char *idaapi qstrrchr(const char *s1, char c) { return strrchr(s1, c); }
3056inline THREAD_SAFE char *idaapi qstrrchr(char *s1, char c) { return strrchr(s1, c); }
3057inline THREAD_SAFE const uchar *idaapi qstrrchr(const uchar *s1, uchar c) { return (const uchar *)strrchr((const char *)s1, c); }
3058inline THREAD_SAFE uchar *idaapi qstrrchr(uchar *s1, uchar c) { return (uchar *)strrchr((const char *)s1, c); }
3059idaman THREAD_SAFE const wchar16_t *ida_export qstrrchr(const wchar16_t *s1, wchar16_t c);
3060inline THREAD_SAFE wchar16_t *idaapi qstrrchr(wchar16_t *s1, wchar16_t c)
3061 { return (wchar16_t *)qstrrchr((const wchar16_t *)s1, c); }
3062
3063
3066#define SSF_DROP_EMPTY 0x1
3068
3069//---------------------------------------------------------------------------
3070#define streq(s1, s2) (::qstrcmp((s1), (s2)) == 0)
3071#define strneq(s1, s2, count) (::qstrncmp((s1), (s2), (count)) == 0)
3072#define strieq(s1, s2) (stricmp((s1), (s2)) == 0)
3073#define strnieq(s1, s2, count) (strnicmp((s1), (s2), (count)) == 0)
3074
3075//---------------------------------------------------------------------------
3080template<class qchar>
3082{
3083 qvector<qchar> body;
3084 void assign(const qchar *ptr, size_t len)
3085 {
3086 body.resize_noinit(len+1);
3087 memmove(body.begin(), ptr, len*sizeof(qchar));
3088 body[len] = '\0';
3089 }
3090public:
3091 using value_type = qchar;
3092
3094 _qstring(void) {}
3096 _qstring(const qchar *ptr)
3097 {
3098 if ( ptr != nullptr )
3099 assign(ptr, ::qstrlen(ptr));
3100 }
3101
3102 _qstring(const qchar *ptr, size_t len)
3103 {
3104 if ( len > 0 )
3105 assign(ptr, len);
3106 }
3107
3108 _qstring(size_t count, qchar ch)
3109 {
3110 if ( count > 0 )
3111 {
3112 body.resize(count+1, ch);
3113 body[count] = 0; // ensure the terminating zero
3114 }
3115 }
3116#ifndef SWIG
3118 _qstring(_qstring &&x) : body(std::move(x.body)) {}
3120 _qstring(const _qstring &r) : body(r.body) {}
3121#endif
3122 void swap(_qstring<qchar> &r) { body.swap(r.body); }
3123 size_t length(void) const { size_t l = body.size(); return l ? l - 1 : 0; }
3124 size_t size(void) const { return body.size(); }
3125 size_t capacity(void) const { return body.capacity(); }
3126
3131 void resize(size_t s, qchar c)
3132 {
3133 size_t oldsize = body.size();
3134 if ( oldsize != 0 && s >= oldsize )
3135 body[oldsize-1] = c; // erase the terminating zero
3136 body.resize(s+1, c);
3137 body[s] = 0; // ensure the terminating zero
3138 }
3139
3140 void resize(size_t s)
3141 {
3142 if ( s == 0 )
3143 {
3144 body.clear();
3145 }
3146 else
3147 {
3148 body.resize(s+1);
3149 body[s] = 0; // ensure the terminating zero
3150 }
3151 }
3152 void remove_last(int cnt=1)
3153 {
3154 ssize_t len = body.size() - cnt;
3155 if ( len <= 1 )
3156 {
3157 body.clear();
3158 }
3159 else
3160 {
3161 body.resize_noinit(len);
3162 body[len-1] = 0;
3163 }
3164 }
3165 void reserve(size_t cnt) { body.reserve(cnt); }
3166 void clear(void) { body.clear(); }
3167 void qclear(void) { body.qclear(); }
3168 bool empty(void) const { return body.size() <= 1; }
3170 const qchar *c_str(void) const
3171 {
3172 static const qchar nullstr[] = { 0 };
3173 return body.empty() ? nullstr : &body[0];
3174 }
3175 typedef qchar *iterator;
3176 typedef const qchar *const_iterator;
3177 iterator begin(void) { return body.begin(); }
3178 const_iterator begin(void) const { return body.begin(); }
3179 iterator end(void) { return body.end(); }
3180 const_iterator end(void) const { return body.end(); }
3182 _qstring &operator=(const qchar *str)
3183 {
3184 size_t len = str == nullptr ? 0 : ::qstrlen(str);
3185 if ( len > 0 )
3186 assign(str, len);
3187 else
3188 qclear();
3189 return *this;
3190 }
3192 {
3193 if ( this != &qstr )
3194 {
3195 size_t len = qstr.length();
3196 if ( len > 0 )
3197 assign(qstr.begin(), len);
3198 else
3199 qclear();
3200 }
3201 return *this;
3202 }
3203#ifndef SWIG
3206 {
3207 body = std::move(x.body);
3208 return *this;
3209 }
3210#endif
3213 {
3214 return append(c);
3215 }
3216
3218 {
3219 return append(r);
3220 }
3221
3223 {
3224 _qstring s = *this;
3225 s += r;
3226 return s;
3227 }
3229 {
3230 return ::qstrcmp(c_str(), r.c_str());
3231 }
3232
3233 bool operator==(const qchar *r) const
3234 {
3235 return ::qstrcmp(c_str(), r) == 0;
3236 }
3237 bool operator!=(const qchar *r) const { return !(*this == r); }
3239 bool operator<(const qchar *r) const
3240 {
3241 return ::qstrcmp(c_str(), r) < 0;
3242 }
3243
3244 bool starts_with(const _qstring &str) const
3245 {
3246 return starts_with(str.begin(), str.length());
3247 }
3248 bool starts_with(const qchar *ptr, ssize_t len = -1) const
3249 {
3250 if ( ptr == nullptr )
3251 return true;
3252 if ( len == -1 )
3253 len = ::qstrlen(ptr);
3254 if ( len == 0 )
3255 return true;
3256 if ( length() < len )
3257 return false;
3258 return strneq(begin(), ptr, len);
3259 }
3260
3261 bool ends_with(const _qstring &str) const
3262 {
3263 return ends_with(str.begin(), str.length());
3264 }
3265 bool ends_with(const qchar *ptr, ssize_t len = -1) const
3266 {
3267 if ( ptr == nullptr )
3268 return true;
3269 if ( len == -1 )
3270 len = ::qstrlen(ptr);
3271 if ( len == 0 )
3272 return true;
3273 size_t l = length();
3274 if ( l < len )
3275 return false;
3276 return strneq(begin() + l - len, ptr, len);
3277 }
3278
3279 const qchar &operator[](size_t idx) const
3280 {
3281 if ( !body.empty() || idx )
3282 return body[idx];
3283 static const qchar nullstr[] = { 0 };
3284 return nullstr[0];
3285 }
3286
3287 qchar &operator[](size_t idx)
3288 {
3289 if ( !body.empty() || idx )
3290 return body[idx];
3291 static qchar nullstr[] = { 0 };
3292 return nullstr[0];
3293 }
3294 const qchar &at(size_t idx) const { return body.at(idx); }
3295 qchar &at(size_t idx) { return body.at(idx); }
3297 qchar *extract(void) { return body.extract(); }
3300 void inject(qchar *s, size_t len)
3301 {
3302 body.inject(s, len);
3303 }
3304
3305 void inject(qchar *s)
3306 {
3307 if ( s != nullptr )
3308 {
3309 size_t len = ::qstrlen(s) + 1;
3310 body.inject(s, len);
3311 }
3312 }
3313
3314 qchar last(void) const
3315 {
3316 size_t len = length();
3317 return len == 0 ? '\0' : body[len-1];
3318 }
3319
3323 size_t find(const qchar *str, size_t pos=0) const
3324 {
3325 if ( pos <= length() )
3326 {
3327 const qchar *beg = c_str();
3328 const qchar *ptr = ::qstrstr(beg+pos, str);
3329 if ( ptr != nullptr )
3330 return ptr - beg;
3331 }
3332 return npos;
3333 }
3334
3336 bool replace(const qchar *what, const qchar *with)
3337 {
3339 size_t len_what = ::qstrlen(what);
3340 const qchar *_start = c_str();
3341 const qchar *last_pos = _start;
3342 while ( true )
3343 {
3344 const qchar *pos = ::qstrstr(last_pos, what);
3345 if ( pos == nullptr )
3346 break;
3347 size_t n = pos - last_pos;
3348 if ( n > 0 )
3349 result.append(last_pos, n);
3350 result.append(with);
3351 last_pos = pos + len_what;
3352 }
3353 // no match at all?
3354 if ( last_pos == _start )
3355 return false;
3356 // any pending characters?
3357 if ( *last_pos )
3358 result.append(last_pos);
3359 swap(result);
3360 return true;
3361 }
3362
3363 size_t find(const _qstring &str, size_t pos=0) const { return find(str.c_str(), pos); }
3368 size_t find(qchar c, size_t pos=0) const
3369 {
3370 if ( pos <= length() )
3371 {
3372 const qchar *beg = c_str();
3373 const qchar *ptr = qstrchr(beg+pos, c);
3374 if ( ptr != nullptr )
3375 return ptr - beg;
3376 }
3377 return npos;
3378 }
3379
3383 size_t rfind(qchar c, size_t pos=0) const
3384 {
3385 if ( pos <= length() )
3386 {
3387 const qchar *beg = c_str();
3388 const qchar *ptr = qstrrchr(beg+pos, c);
3389 if ( ptr != nullptr )
3390 return ptr - beg;
3391 }
3392 return npos;
3393 }
3394
3398 _qstring<qchar> substr(size_t pos=0, size_t n=npos) const
3399 {
3400 size_t endp = qmin(length(), n);
3401 if ( pos >= endp )
3402 pos = endp;
3403 return _qstring<qchar>(c_str()+pos, endp-pos);
3404 }
3405
3408 _qstring &remove(size_t idx, size_t cnt)
3409 {
3410 size_t len = length();
3411 if ( idx < len && cnt != 0 )
3412 {
3413 cnt += idx;
3414 if ( cnt < len )
3415 {
3416 iterator p1 = body.begin() + cnt;
3417 iterator p2 = body.begin() + idx;
3418 memmove(p2, p1, (len-cnt)*sizeof(qchar));
3419 idx += len - cnt;
3420 }
3421 body.resize_noinit(idx+1);
3422 body[idx] = '\0';
3423 }
3424 return *this;
3425 }
3426
3429 _qstring &insert(size_t idx, qchar c)
3430 {
3431 size_t len = length();
3432 body.resize_noinit(len+2);
3433 body[len+1] = '\0';
3434 if ( idx < len )
3435 {
3436 iterator p1 = body.begin() + idx;
3437 memmove(p1+1, p1, (len-idx)*sizeof(qchar));
3438 len = idx;
3439 }
3440 body[len] = c;
3441 return *this;
3442 }
3443
3447 _qstring &insert(size_t idx, const qchar *str, size_t addlen)
3448 {
3449 size_t len = length();
3450 body.resize_noinit(len+addlen+1);
3451 body[len+addlen] = '\0';
3452 if ( idx < len )
3453 {
3454 iterator p1 = body.begin() + idx;
3455 iterator p2 = p1 + addlen;
3456 memmove(p2, p1, (len-idx)*sizeof(qchar));
3457 len = idx;
3458 }
3459 memmove(body.begin()+len, str, addlen*sizeof(qchar));
3460 return *this;
3461 }
3462
3463 _qstring &insert(size_t idx, const qchar *str)
3464 {
3465 if ( str != nullptr )
3466 {
3467 size_t addlen = ::qstrlen(str);
3468 insert(idx, str, addlen);
3469 }
3470 return *this;
3471 }
3472
3473 _qstring &insert(size_t idx, const _qstring &qstr)
3474 {
3475 size_t len = length();
3476 size_t add = qstr.length();
3477 body.resize_noinit(len+add+1);
3478 body[len+add] = '\0';
3479 if ( idx < len )
3480 {
3481 iterator p1 = body.begin() + idx;
3482 iterator p2 = p1 + add;
3483 memmove(p2, p1, (len-idx)*sizeof(qchar));
3484 len = idx;
3485 }
3486 memcpy(body.begin()+len, qstr.begin(), add*sizeof(qchar));
3487 return *this;
3488 }
3489 _qstring &insert(qchar c) { return insert(0, c); }
3490 _qstring &insert(const qchar *str) { return insert(0, str); }
3491 _qstring &insert(const _qstring &qstr) { return insert(0, qstr); }
3494 {
3495 size_t len = length();
3496 body.resize_noinit(len+2);
3497 body[len] = c;
3498 body[len+1] = '\0';
3499 return *this;
3500 }
3501
3504 _qstring &append(const qchar *str, size_t addlen)
3505 {
3506 size_t len = length();
3507 body.resize_noinit(len+addlen+1);
3508 body[len+addlen] = '\0';
3509 memmove(body.begin()+len, str, addlen*sizeof(qchar));
3510 return *this;
3511 }
3512
3513 _qstring &append(const qchar *str)
3514 {
3515 if ( str != nullptr )
3516 {
3517 size_t addlen = ::qstrlen(str);
3518 append(str, addlen);
3519 }
3520 return *this;
3521 }
3522
3524 {
3525 size_t add = qstr.length();
3526 if ( add != 0 )
3527 {
3528 size_t len = length();
3529 body.resize_noinit(len+add+1);
3530 body[len+add] = '\0';
3531 memcpy(body.begin()+len, qstr.begin(), add*sizeof(qchar));
3532 }
3533 return *this;
3534 }
3535
3536 AS_PRINTF(2, 0) _qstring &cat_vsprnt(const char *format, va_list va)
3537 { // since gcc64 forbids reuse of va_list, we make a copy for the second call:
3538 va_list copy;
3539 va_copy(copy, va);
3540 size_t add = ::qvsnprintf(nullptr, 0, format, va);
3541 if ( add != 0 )
3542 {
3543 size_t len = length();
3544 body.resize_noinit(len+add+1);
3545 ::qvsnprintf(body.begin()+len, add+1, format, copy);
3546 }
3547 va_end(copy);
3548 return *this;
3549 }
3551 AS_PRINTF(2, 0) _qstring &vsprnt(const char *format, va_list va)
3552 { // since gcc64 forbids reuse of va_list, we make a copy for the second call:
3553 va_list copy;
3554 va_copy(copy, va);
3555 body.clear();
3556 size_t add = ::qvsnprintf(nullptr, 0, format, va);
3557 if ( add != 0 )
3558 {
3559 body.resize_noinit(add+1);
3560 ::qvsnprintf(body.begin(), add+1, format, copy);
3561 }
3562 va_end(copy);
3563 return *this;
3564 }
3566 AS_PRINTF(2, 3) _qstring &cat_sprnt(const char *format, ...)
3567 {
3568 va_list va;
3572 return *this;
3573 }
3575 AS_PRINTF(2, 3) _qstring &sprnt(const char *format, ...)
3576 {
3577 va_list va;
3581 return *this;
3582 }
3586 _qstring &nowarn_sprnt(const char *format, ...)
3587 {
3588 va_list va;
3589 va_start(va, format);
3590 vsprnt(format, va);
3591 va_end(va);
3592 return *this;
3593 }
3594 GCC_DIAG_ON(format-nonliteral);
3600 _qstring &fill(size_t pos, qchar c, size_t len)
3601 {
3602 size_t endp = pos + len + 1;
3603 if ( body.size() < endp )
3604 {
3605 body.resize_noinit(endp);
3606 body[endp-1] = '\0';
3607 }
3608 memset(body.begin()+pos, c, len);
3609 return *this;
3610 }
3611
3612 _qstring &fill(qchar c, size_t len)
3613 {
3614 body.qclear();
3615 if ( len > 0 )
3616 resize(len, c);
3617 return *this;
3618 }
3619
3620 _qstring &ltrim(qchar blank = ' ')
3621 {
3622 if ( !empty() )
3623 {
3624 iterator b = body.begin();
3625 iterator e = body.end()-1;
3626 while ( b < e && *b == blank )
3627 b++;
3628 if ( b > body.begin() )
3629 {
3630 memmove(body.begin(), b, sizeof(qchar)*(e-b+1));
3631 resize(e-b);
3632 }
3633 }
3634 return *this;
3635 }
3636
3637 _qstring &rtrim(qchar blank, size_t minlen = 0)
3638 {
3639 if ( size() > minlen + 1 )
3640 {
3641 iterator b = body.begin() + minlen;
3642 iterator e = body.end() - 1;
3643 // assert: e > b
3644 while ( e > b && *(e-1) == blank )
3645 e--;
3646 resize(e - body.begin());
3647 }
3648 return *this;
3649 }
3650
3652 {
3653 if ( !empty() )
3654 {
3655 iterator b = body.begin();
3656 iterator e = body.end() - 1;
3657 while ( e > b && qisspace(e[-1]) )
3658 --e;
3659 resize(e - b);
3660 }
3661 return *this;
3662 }
3663
3664 _qstring &trim2(qchar blank = ' ')
3665 {
3666 rtrim(blank);
3667 ltrim(blank);
3668 return *this;
3669 }
3670
3671 // Pushes the character 'c' into the qstring
3672 // This adds support for functions from <algorithm>
3673 void push_back(qchar c)
3674 {
3675 append(c);
3676 }
3677
3682 void split(qvector<_qstring<qchar> > *out, const qchar *sep, uint32 flags=0) const;
3683
3689 static _qstring<qchar> join(const qvector<_qstring<qchar> > &parts, const qchar *sep);
3690
3692 static constexpr size_t npos = (size_t) -1;
3693};
3699
3700#ifndef SWIG // avoid "Warning 317: Specialization of non-template 'hash'."
3701
3702// allow qstring in hashed containers
3703namespace std
3704{
3705 template<class T>
3706 struct hash<_qstring<T>>
3707 {
3708 size_t operator()(const _qstring<T> &str) const noexcept
3709 {
3710 // FNV-1a, as per Wikipedia
3711#ifdef __X86__
3712 const size_t FNV_BASIS = 0x811c9dc5;
3713 const size_t FNV_PRIME = 0x01000193;
3714#else
3715 const size_t FNV_BASIS = 0xcbf29ce484222325;
3716 const size_t FNV_PRIME = 0x100000001b3;
3717#endif
3718 size_t sum = FNV_BASIS;
3719 for ( T c : str )
3720 {
3721 sum ^= c;
3722 sum *= FNV_PRIME;
3723 }
3724 return sum;
3725 }
3726 };
3727}
3728#endif
3729
3730template <> inline
3731void qstring::split(qstrvec_t *out, const char *sep, uint32 flags) const
3732{
3733 size_t seplen = ::qstrlen(sep);
3734 const char *p = begin();
3735 const char *const end = p + length();
3736 while ( p < end )
3737 {
3738 const char *psep = ::qstrstr(p, sep);
3739 size_t rem = (psep != nullptr ? psep : end) - p;
3740 if ( rem > 0 || (flags & SSF_DROP_EMPTY) == 0 )
3741 out->push_back().append(p, rem);
3742 p = psep != nullptr ? psep + seplen : end;
3743 }
3744 // Account for trailing separator sequence
3745 if ( ends_with(sep, seplen) && (flags & SSF_DROP_EMPTY) == 0 )
3746 out->push_back(); // add an empty string
3747}
3748
3749template <> inline
3750qstring qstring::join(const qstrvec_t &parts, const char *sep)
3751{
3752 qstring buf;
3753 size_t nparts = parts.size();
3754 if ( nparts > 0 )
3755 {
3756 size_t seplen = ::qstrlen(sep);
3757 size_t total = (nparts - 1) * seplen; // separators
3758 for ( const auto &one : parts )
3759 total += one.length();
3760 buf.reserve(total);
3761 for ( const auto &one : parts )
3762 {
3763 if ( !buf.empty() )
3764 buf.append(sep, seplen);
3765 buf.append(one);
3766 }
3767 }
3768 return buf;
3769}
3770
3772class bytevec_t: public qvector<uchar>
3773{
3774public:
3778 bytevec_t(const void *buf, size_t sz) { append(buf, sz); }
3782 bytevec_t &append(const void *buf, size_t sz)
3783 {
3784 if ( sz > 0 )
3785 {
3786 size_t cur_sz = size();
3787 size_t new_sz = cur_sz + sz;
3788 if ( new_sz < cur_sz )
3789 new_sz = BADMEMSIZE; // integer overflow, ask too much and it will throw
3790 resize(new_sz);
3791 memcpy(begin() + cur_sz, buf, sz);
3792 }
3793 return *this;
3794 }
3795
3796 void pack_db(uint8 x) { push_back(x); }
3799 {
3800 uchar packed[dw_packed_size];
3801 size_t len = ::pack_dw(packed, packed+sizeof(packed), x) - packed;
3802 append(packed, len);
3803 }
3804
3806 {
3807 uchar packed[dd_packed_size];
3808 size_t len = ::pack_dd(packed, packed+sizeof(packed), x) - packed;
3809 append(packed, len);
3810 }
3811
3813 {
3814 uchar packed[dq_packed_size];
3815 size_t len = ::pack_dq(packed, packed+sizeof(packed), x) - packed;
3816 append(packed, len);
3817 }
3818
3820 {
3821 uchar packed[ea_packed_size];
3822 size_t len = ::pack_ea(packed, packed+sizeof(packed), x) - packed;
3823 append(packed, len);
3824 }
3825
3831 {
3832#ifdef __X86__
3833 if ( ea == BADADDR )
3834 ea = 0xFFFFFFFFFFFFFFFFULL;
3835#endif
3836 return pack_dq(ea+1);
3837 }
3838
3839 void pack_ds(const char *x)
3840 {
3841 if ( x == nullptr )
3842 x = "";
3843 size_t len = strlen(x);
3844#ifndef __X86__
3845 QASSERT(4, len <= 0xFFFFFFFF);
3846#endif
3847 pack_dd(len);
3848 append(x, len);
3849 }
3850
3851 void pack_str(const char *str)
3852 {
3853 if ( str == nullptr )
3854 str = "";
3855 size_t len = strlen(str) + 1;
3856 append(str, len);
3857 }
3858
3859 void pack_str(const qstring &s)
3860 {
3861 // the opposite operation is 'unpack_str()' which gets the length
3862 // when it encounters a terminating '\0'. Since we don't store the
3863 // string length, we cannot store zeroes that 's' might contain
3864 // and thus we cannot rely on its length().
3865 pack_str(s.c_str());
3866 }
3867
3868 void pack_buf(const void *buf, size_t len)
3869 {
3870#ifndef __X86__
3871 QASSERT(5, len <= 0xFFFFFFFF);
3872#endif
3873 pack_dd(len);
3874 append(buf, len);
3875 }
3876
3878 {
3879 pack_buf(b.begin(), b.size());
3880 }
3881
3892 void pack_eavec(ea_t ea, const eavec_t &vec)
3893 {
3894 int nelems = vec.size();
3895 pack_dw(nelems); // 16bits, fixme!
3896 ea_t old = ea;
3897 for ( int i=0; i < nelems; i++ )
3898 {
3899 ea_t nea = vec[i];
3900 pack_ea(nea-old);
3901 old = nea;
3902 }
3903 }
3904
3908 bytevec_t &growfill(size_t sz, uchar filler=0)
3909 {
3910 if ( sz > 0 )
3911 {
3912 size_t cur_sz = size();
3913 size_t new_sz = cur_sz + sz;
3914 if ( new_sz < cur_sz )
3915 new_sz = BADMEMSIZE; // integer overflow, ask too much and it will throw
3916 resize(new_sz, filler);
3917 }
3918 return *this;
3919 }
3920
3921 void inject(void *buf, size_t len)
3922 {
3924 }
3925
3927 void tohex(qstring *out, bool upper_case=true) const
3928 {
3929 size_t len = out->length();
3930 out->resize(len + size() * 2);
3931 char *p = out->begin() + len;
3932 char *end = out->end();
3933 for ( uchar c: *this )
3934 {
3935 ::qsnprintf(p, end - p, upper_case ? "%02X" : "%02x", c);
3936 p += 2;
3937 }
3938 }
3939
3941 qstring tohex(bool upper_case=true) const
3942 {
3943 qstring buf;
3944 tohex(&buf, upper_case);
3945 return buf;
3946 }
3947
3950 bool fromhex(const qstring &str)
3951 {
3952 resize(str.length() / 2);
3953 const char *p = str.begin();
3954 for ( uchar &c: *this )
3955 {
3956 uint b = 0;
3957 if ( ::qsscanf(p, "%02X", &b) != 1 || b > 0xFF )
3958 break;
3959 c = uchar(b);
3960 p += 2;
3961 }
3962 return p == str.begin() + str.length();
3963 }
3964
3966 bool test_bit(size_t bit) const { return ::test_bit(begin(), bit); }
3968 void set_bit(size_t bit) { ::set_bit(begin(), bit); }
3970 void clear_bit(size_t bit) { ::clear_bit(begin(), bit); }
3976 bool all_zeros() const
3977 {
3978 for ( size_t i = 0; i < size(); ++i )
3979 if ( at(i) != 0 )
3980 return false;
3981 return true;
3982 }
3983
3984 void set_bits(const bytevec_t &b)
3985 {
3986 size_t nbytes = b.size();
3987 if ( size() < nbytes )
3988 resize(nbytes);
3989 for ( size_t i=0; i < nbytes; i++ )
3990 at(i) |= b[i];
3991 }
3992
3993 void set_bits(size_t low, size_t high) { ::set_bits(begin(), low, high); }
3995 void clear_bits(const bytevec_t &b)
3996 {
3997 size_t nbytes = qmin(size(), b.size());
3998 iterator p = begin();
3999 for ( size_t i=0; i < nbytes; i++, ++p )
4000 *p = (uchar)(*p & ~b[i]);
4001 }
4002
4003 void clear_bits(size_t low, size_t high) { ::clear_bits(begin(), low, high); }
4004};
4005
4008{
4012#define RELOBJ_MASK 0xF
4013#define RELSIZE_1 0
4014#define RELSIZE_2 1
4015#define RELSIZE_4 2
4016#define RELSIZE_8 3
4017#define RELSIZE_CUST 15
4018#define RELOBJ_CNT 0x80
4020};
4021
4022idaman THREAD_SAFE bool ida_export relocate_relobj(struct relobj_t *_relobj, ea_t ea, bool mf);
4023
4025struct relobj_t : public bytevec_t
4026{
4029
4030 relobj_t(void) : base(0) {}
4031 bool relocate(ea_t ea, bool mf) { return relocate_relobj(this, ea, mf); }
4032};
4033
4034#define QLIST_DEFINED
4037template <class T> class qlist
4038{
4039 struct listnode_t
4040 {
4041 listnode_t *next;
4042 listnode_t *prev;
4043 void fix_links(size_t len)
4044 {
4045 if ( len == 0 )
4046 {
4047 next = this;
4048 prev = this;
4049 }
4050 else
4051 {
4052 next->prev = this;
4053 prev->next = this;
4054 }
4055 }
4056 };
4057
4058 struct datanode_t : public listnode_t
4059 {
4060 T data;
4061 };
4062
4063 listnode_t node;
4064 size_t length;
4065
4066 void init(void)
4067 {
4068 node.next = &node;
4069 node.prev = &node;
4070 length = 0;
4071 }
4072
4073public:
4074 typedef T value_type;
4075 class const_iterator;
4077#define DEFINE_LIST_ITERATOR(iter, constness, cstr) \
4078 class iter \
4079 { \
4080 friend class qlist<T>; \
4081 constness listnode_t *cur; \
4082 iter(constness listnode_t *x) : cur(x) {} \
4083 public: \
4084 typedef constness T value_type; \
4085 iter(void) : cur(nullptr) {} \
4086 iter(const iter &x) : cur(x.cur) {} \
4087 cstr \
4088 iter &operator=(const iter &x) { cur = x.cur; return *this; } \
4089 bool operator==(const iter &x) const { return cur == x.cur; } \
4090 bool operator!=(const iter &x) const { return cur != x.cur; } \
4091 constness T &operator*(void) const { return ((datanode_t*)cur)->data; } \
4092 constness T *operator->(void) const { return &(operator*()); } \
4093 iter &operator++(void) /* prefix ++ */ \
4094 { \
4095 cur = cur->next; \
4096 return *this; \
4097 } \
4098 iter operator++(int) /* postfix ++ */ \
4099 { \
4100 iter tmp = *this; \
4101 ++(*this); \
4102 return tmp; \
4103 } \
4104 iter &operator--(void) /* prefix -- */ \
4105 { \
4106 cur = cur->prev; \
4107 return *this; \
4108 } \
4109 iter operator--(int) /* postfix -- */ \
4110 { \
4111 iter tmp = *this; \
4112 --(*this); \
4113 return tmp; \
4114 } \
4115 };
4116 DEFINE_LIST_ITERATOR(iterator,, friend class const_iterator; )
4117 DEFINE_LIST_ITERATOR(const_iterator, const, const_iterator(const iterator &x) : cur(x.cur) {} )
4118
4120#define DEFINE_REVERSE_ITERATOR(riter, iter) \
4121 class riter \
4122 { \
4123 iter p; \
4124 public: \
4125 riter(void) {} \
4126 riter(const iter &x) : p(x) {} \
4127 typename iter::value_type &operator*(void) const { iter q=p; return *--q; } \
4128 typename iter::value_type *operator->(void) const { return &(operator*()); } \
4129 riter &operator++(void) { --p; return *this; } \
4130 riter operator++(int) { iter q=p; --p; return q; } \
4131 riter &operator--(void) { ++p; return *this; } \
4132 riter operator--(int) { iter q=p; ++p; return q; } \
4133 bool operator==(const riter &x) const { return p == x.p; } \
4134 bool operator!=(const riter &x) const { return p != x.p; } \
4135 };
4136 DEFINE_REVERSE_ITERATOR(reverse_iterator, iterator)
4137 DEFINE_REVERSE_ITERATOR(const_reverse_iterator, const_iterator)
4138#undef DEFINE_LIST_ITERATOR
4139#undef DEFINE_REVERSE_ITERATOR
4141 qlist(void) { init(); }
4143 qlist(const qlist<T> &x)
4144 {
4145 init();
4146 insert(begin(), x.begin(), x.end());
4147 }
4148
4150 {
4151 clear();
4152 }
4153 DEFINE_MEMORY_ALLOCATION_FUNCS()
4154
4155
4156 qlist<T> &operator=(const qlist<T> &x)
4157 {
4158 if ( this != &x )
4159 {
4160 iterator first1 = begin();
4161 iterator last1 = end();
4162 const_iterator first2 = x.begin();
4163 const_iterator last2 = x.end();
4164 while ( first1 != last1 && first2 != last2 )
4165 *first1++ = *first2++;
4166 if ( first2 == last2 )
4167 erase(first1, last1);
4168 else
4169 insert(last1, first2, last2);
4170 }
4171 return *this;
4172 }
4174 void swap(qlist<T> &x)
4175 {
4176 std::swap(node, x.node);
4177 std::swap(length, x.length);
4178 node.fix_links(length);
4179 x.node.fix_links(x.length);
4180 }
4181
4182 iterator begin(void) { return node.next; }
4183 iterator end(void) { return &node; }
4184 bool empty(void) const { return length == 0; }
4185 size_t size(void) const { return length; }
4186 T &front(void) { return *begin(); }
4187 T &back(void) { return *(--end()); }
4188
4189 const_iterator begin(void) const { return node.next; }
4190 const_iterator end(void) const { return &node; }
4191 const T&front(void) const { return *begin(); }
4192 const T&back(void) const { return *(--end()); }
4193
4194 reverse_iterator rbegin() { return reverse_iterator(end()); }
4195 reverse_iterator rend() { return reverse_iterator(begin()); }
4196 const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
4197 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
4198
4203 iterator insert(iterator p, const T &x)
4204 {
4205 datanode_t *tmp = (datanode_t*)qalloc_or_throw(sizeof(datanode_t));
4206 new (&(tmp->data)) T(x);
4207 linkin(p, tmp);
4208 return tmp;
4209 }
4213 iterator insert(iterator p)
4214 {
4215 datanode_t *tmp = (datanode_t*)qalloc_or_throw(sizeof(datanode_t));
4216 new (&(tmp->data)) T();
4217 linkin(p, tmp);
4218 return tmp;
4219 }
4222 template <class it2> void insert(iterator p, it2 first, it2 last)
4223 {
4224 while ( first != last )
4225 insert(p, *first++);
4226 }
4228 void push_front(const T &x) { insert(begin(), x); }
4230 void push_back(const T &x) { insert(end(), x); }
4232 T &push_back(void)
4233 {
4234 iterator p = insert(end());
4235 return ((datanode_t *)p.cur)->data;
4236 }
4238 iterator erase(iterator p)
4239 {
4240 listnode_t *q = p.cur->next;
4241 p.cur->prev->next = p.cur->next;
4242 p.cur->next->prev = p.cur->prev;
4243 ((datanode_t*)p.cur)->data.~T();
4244 qfree(p.cur);
4245 --length;
4246 return q;
4247 }
4249 void erase(iterator p1, iterator p2)
4250 {
4251 while ( p1 != p2 )
4252 p1 = erase(p1);
4253 }
4255 void clear(void) { erase(begin(), end()); }
4257 void pop_front(void) { erase(begin()); }
4259 void pop_back(void) { iterator tmp = end(); erase(--tmp); }
4261 void splice(iterator pos, qlist<T> &other, iterator first, iterator last)
4262 {
4263 // Nothing to do for empty range
4264 if ( first == last )
4265 return;
4266
4267 listnode_t *first_node = first.cur;
4268 listnode_t *last_node = last.cur->prev;
4269
4270 // Compute the length of the other list
4271 size_t sublength = 1;
4272
4273 // Special case: the range is the entire other list
4274 if ( first == other.begin() && last == other.end() )
4275 {
4276 sublength = other.length;
4277 }
4278 else // Otherwise, count the size of the range
4279 {
4280 listnode_t *curr_node = first_node;
4281 while ( curr_node != last_node )
4282 {
4283 curr_node = curr_node->next;
4284 ++sublength;
4285 }
4286 }
4287
4288 // Detach [first, last) from the other list (update links and length)
4289 first_node->prev->next = last_node->next;
4290 last_node->next->prev = first_node->prev;
4291 other.length -= sublength;
4292
4293 // Attach [first, last) to the current list at pos (update links and length)
4294 listnode_t *pos_node = pos.cur;
4295 listnode_t *before_pos = pos_node->prev;
4296 before_pos->next = first_node;
4297 first_node->prev = before_pos;
4298 last_node->next = pos_node;
4299 pos_node->prev = last_node;
4300 length += sublength;
4301 }
4303 bool operator==(const qlist<T> &x) const
4304 {
4305 if ( length != x.length )
4306 return false;
4307 const_iterator q=x.begin();
4308 for ( const_iterator p=begin(), e=end(); p != e; ++p,++q )
4309 if ( *p != *q )
4310 return false;
4311 return true;
4312 }
4314 bool operator!=(const qlist<T> &x) const { return !(*this == x); }
4315private:
4316 void linkin(iterator p, listnode_t *tmp)
4317 {
4318 tmp->next = p.cur;
4319 tmp->prev = p.cur->prev;
4320 p.cur->prev->next = tmp;
4321 p.cur->prev = tmp;
4322 ++length;
4323 }
4324};
4325
4326// Our containers do not care about their addresses. They can be moved around with simple memcpy
4328template <class T> struct ida_movable_type<qvector<T> > { static constexpr bool value = true; };
4329template <class T> struct ida_movable_type<_qstring<T> > { static constexpr bool value = true; };
4330template <class T> struct ida_movable_type<qlist<T> > { static constexpr bool value = false; };
4331template <class T> struct ida_movable_type<qiterator<T> > { static constexpr bool value = true; };
4333
4334//----------------------------------------------------------------------------
4335#ifndef SWIG
4341
4342THREAD_SAFE inline void unpack_eavec(
4343 eavec_t *vec,
4344 ea_t ea,
4345 const uchar **ptr,
4346 const uchar *end)
4347{
4348 ea_t old = ea;
4349 int n = unpack_dw(ptr, end);
4350 vec->resize_noinit(n);
4351 for ( int i=0; i < n; i++ )
4352 {
4353 old += unpack_ea(ptr, end);
4354 vec->at(i) = old;
4355 }
4356}
4357
4358THREAD_SAFE inline bool unpack_bytevec(
4359 bytevec_t *out,
4360 const uchar **pptr,
4361 const uchar *end)
4362{
4363 uint32 nbytes = unpack_dd(pptr, end);
4364 if ( nbytes == 0 )
4365 return true;
4366 const size_t old_size = out->size();
4367 out->resize_noinit(old_size + nbytes);
4368 return unpack_obj(out->begin() + old_size, nbytes, pptr, end) != nullptr;
4369}
4370
4371inline bool unpack_str(qstring *out, const uchar **pptr, const uchar *end)
4372{ // zero terminated string, append to qstring
4373 const char *str = unpack_str(pptr, end);
4374 if ( str == nullptr )
4375 return false;
4376 out->append(str, ((char*)*pptr-str) - 1);
4377 return true;
4378}
4379
4380// Convenience struct for unpacking a data stream
4381THREAD_SAFE struct memory_deserializer_t
4382{
4383 const uchar *ptr;
4384 const uchar *end;
4385
4386 memory_deserializer_t(const qstring &s) : ptr((uchar*)s.begin()), end(ptr+s.size()) {}
4387 memory_deserializer_t(const bytevec_t &b) : ptr(b.begin()), end(b.end()) {}
4388 memory_deserializer_t(const uchar *p, const uchar *e) : ptr(p), end(e) {}
4389 memory_deserializer_t(const void *p, size_t s) : ptr((uchar*)p), end(ptr+s) {}
4390 bool empty() const { return ptr >= end; }
4391 size_t size() const { return end-ptr; }
4392 bool advance(size_t s) { if ( size() < s ) return false; ptr += s; return true; }
4393 uint8 unpack_db() { return ::unpack_db(&ptr, end); }
4394 uint16 unpack_dw() { return ::unpack_dw(&ptr, end); }
4395 uint32 unpack_dd() { return ::unpack_dd(&ptr, end); }
4396 uint64 unpack_dq() { return ::unpack_dq(&ptr, end); }
4397 ea_t unpack_ea() { return ::unpack_ea(&ptr, end); }
4398 ea64_t unpack_ea64() { return ::unpack_ea64(&ptr, end); }
4399 // unpack zero terminated string
4400 const char *unpack_str() { return ::unpack_str(&ptr, end); }
4401 bool unpack_str(qstring *out) { return ::unpack_str(out, &ptr, end); }
4402 // string with length prefix (dd), return string allocated in the heap
4403 char *unpack_ds(bool empty_null=false)
4404 {
4405 return ::unpack_ds(&ptr, end, empty_null);
4406 }
4407 // string with length prefix (dd), return in the specified buffer
4408 bool unpack_ds_to_buf(char *buf, size_t bufsize)
4409 {
4410 return ::unpack_ds_to_buf(buf, bufsize, &ptr, end);
4411 }
4412 const void *unpack_obj_inplace(size_t objsize)
4413 {
4414 return ::unpack_obj_inplace(&ptr, end, objsize);
4415 }
4417 {
4418 return ::unpack_buf_inplace(&ptr, end);
4419 }
4420 const void *unpack_obj(void *obj, size_t objsize)
4421 {
4422 return ::unpack_obj(obj, objsize, &ptr, end);
4423 }
4424 const void *unpack_buf()
4425 {
4426 return ::unpack_buf(&ptr, end);
4427 }
4429 {
4430 ::unpack_eavec(vec, ea, &ptr, end);
4431 }
4433 {
4434 return ::unpack_bytevec(out, &ptr, end);
4435 }
4436 #define SCALAR_TYPE(n) class T, typename std::enable_if<std::is_scalar<T>::value && sizeof(T) == n, int>::type = 0
4437 template <SCALAR_TYPE(1)> void unpack(T *out) { *out = (T)unpack_db(); }
4438 template <SCALAR_TYPE(2)> void unpack(T *out) { *out = unpack_dw(); }
4439 template <SCALAR_TYPE(4)> void unpack(T *out) { *out = unpack_dd(); }
4440 template <SCALAR_TYPE(8)> void unpack(T *out) { *out = unpack_dq(); }
4441 #undef SCALAR_TYPE
4442 void unpack(qstring *out) { *out = unpack_str(); }
4443 template <class T>
4445 {
4446 uint32 cnt = unpack_dd();
4447 out->qclear();
4448 out->reserve(cnt);
4449 for ( size_t i = 0; i < cnt; i++ )
4450 unpack(&out->push_back());
4451 }
4452 // linput_t like interface
4453 ssize_t read(void *obj, size_t objsize) { return unpack_obj(obj, objsize) ? objsize : -1; }
4454 bool eof() const { return empty(); }
4455};
4456#define DECLARE_MEMORY_DESERIALIZER(name) \
4457 name(const void *p, size_t s) : memory_deserializer_t(p, s) {} \
4458 using memory_deserializer_t::unpack; \
4459
4461{
4462 #define SCALAR_TYPE(n) class T, typename std::enable_if<std::is_scalar<T>::value && sizeof(T) == n, int>::type = 0
4463 template <SCALAR_TYPE(1)> void pack(T value) { pack_db(value); }
4464 template <SCALAR_TYPE(2)> void pack(T value) { pack_dw(value); }
4465 template <SCALAR_TYPE(4)> void pack(T value) { pack_dd(value); }
4466 template <SCALAR_TYPE(8)> void pack(T value) { pack_dq(value); }
4467 #undef SCALAR_TYPE
4468 void pack(const qstring &value) { pack_str(value); }
4469 template <class T>
4470 void pack(const qvector<T> &value)
4471 {
4472 pack_dd(value.size());
4473 for ( const auto &item: value )
4474 pack(item);
4475 }
4476};
4477#define DECLARE_MEMORY_SERIALIZER(name) \
4478 using memory_serializer_t::pack; \
4479
4480#endif // SWIG
4481
4482//-------------------------------------------------------------------------
4484template <typename T>
4486{
4487 janitor_t(T &r) : resource(r) {}
4490protected:
4492};
4493
4494// Custom deleter to be used with std::unique_ptr which calls qfree
4495template <typename T>
4497{
4498 void operator() ( T *ptr ) { qfree(ptr); }
4499};
4500
4501template <typename T>
4502using qalloc_janitor_t = std::unique_ptr<T, qfree_deleter_t<T>>;
4503#ifndef SWIG
4504//-------------------------------------------------------------------------
4506template <typename, typename = void>
4507struct has_compare_method : std::false_type {};
4508// std::void_t is from c++17, so we declare it ourselves
4509template< class... > using qvoid_t = void;
4510template <typename T>
4511struct has_compare_method<T, qvoid_t<decltype(std::declval<T>().compare(std::declval<T>()))>>
4512 : std::true_type {};
4513template <class T, typename std::enable_if<has_compare_method<T>::value, int>::type = 0>
4514int compare(const T &a, const T &b)
4515{
4516 return a.compare(b);
4517}
4518template <class T, typename std::enable_if<!has_compare_method<T>::value, int>::type = 0>
4519int compare(const T &a, const T &b)
4520{
4521 if ( a < b )
4522 return -1;
4523 if ( a > b )
4524 return 1;
4525 return 0;
4526}
4527
4528//-------------------------------------------------------------------------
4529template <class T>
4530int compare(const qvector<T> &a, const qvector<T> &b)
4531{
4532 return compare_containers(a, b);
4533}
4534
4535//-------------------------------------------------------------------------
4536template <class T>
4537int compare(const qlist<T> &a, const qlist<T> &b)
4538{
4539 return compare_containers(a, b);
4540}
4541
4542//-------------------------------------------------------------------------
4543template <class T, class U>
4544int compare(const std::pair<T, U> &a, const std::pair<T, U> &b)
4545{
4546 int code = compare(a.first, b.first);
4547 if ( code != 0 )
4548 return code;
4549 return compare(a.second, b.second);
4550}
4551
4552//-------------------------------------------------------------------------
4554template <class T>
4555int compare_containers(const T &l, const T &r)
4556{
4557 auto p = std::begin(l);
4558 auto pe = std::end(l);
4559 auto q = std::begin(r);
4560 auto qe = std::end(r);
4561 for ( ; p != pe && q != qe; ++p,++q )
4562 {
4563 int code = compare(*p, *q);
4564 if ( code != 0 )
4565 return code;
4566 }
4567 if ( p == pe && q != qe )
4568 return -1;
4569 if ( p != pe && q == qe )
4570 return 1;
4571 return 0;
4572}
4573
4574#define COMPARE_POINTERS2(ptr, cmp) \
4575 do \
4576 { \
4577 if ( ptr != nullptr && r.ptr != nullptr ) \
4578 { \
4579 int _code = cmp(*ptr, *r.ptr); \
4580 if ( _code != 0 ) \
4581 return _code; \
4582 } \
4583 else if ( r.ptr != nullptr ) \
4584 { \
4585 return -1; \
4586 } \
4587 else if ( ptr != nullptr ) \
4588 { \
4589 return 1; \
4590 } \
4591 } while (0)
4592
4593#define COMPARE_POINTERS(ptr) COMPARE_POINTERS2(ptr, ::compare)
4594
4595#define COMPARE_FIELDS(fld) \
4596 do \
4597 { \
4598 int _code = ::compare(fld, r.fld); \
4599 if ( _code != 0 ) \
4600 return _code; \
4601 } while (0)
4602
4603// reverse order
4604#define COMPARE_FIELDS_REV(fld) \
4605 do \
4606 { \
4607 int _code = ::compare(r.fld, fld); \
4608 if ( _code != 0 ) \
4609 return _code; \
4610 } while (0)
4611
4612template <class T, class U>
4613int compare(const std::map<T, U> &a, const std::map<T, U> &b)
4614{
4615 return compare_containers(a, b);
4616}
4617
4618template <class T>
4619int compare(const std::set<T> &a, const std::set<T> &b)
4620{
4621 return compare_containers(a, b);
4622}
4623
4624#endif
4625
4626//-------------------------------------------------------------------------
4628template <class T> T align_up(T val, int elsize)
4629{
4630 int mask = elsize - 1;
4631 val += mask;
4632 val &= ~mask;
4633 return val;
4634}
4635
4636//-------------------------------------------------------------------------
4638template <class T> T align_down(T val, int elsize)
4639{
4640 int mask = elsize - 1;
4641 val &= ~mask;
4642 return val;
4643}
4644
4645//-------------------------------------------------------------------------
4649#define DECLARE_UNCOPYABLE(T) T &operator=(const T &); T(const T &);
4650
4651#ifndef SWIG
4652//-------------------------------------------------------------------------
4653// check the variable type
4655#define IS_QSTRING(v) (std::is_base_of<qstring, std::remove_reference<decltype(v)>::type>::value)
4656#define IS_SIZEVEC_T(v) (std::is_base_of<sizevec_t, std::remove_reference<decltype(v)>::type>::value)
4657#define IS_QSTRVEC_T(v) (std::is_base_of<qstrvec_t, std::remove_reference<decltype(v)>::type>::value)
4658
4660#endif
4661
4662#endif // __cplusplus
4663
4664#ifndef __cplusplus
4665typedef struct bytevec_tag bytevec_t;
4666typedef struct qstring_tag qstring;
4667typedef struct qwstring_tag qwstring;
4668#endif
4669
4670//----------------------------------------------------------------------------
4671
4674
4675idaman THREAD_SAFE uint32 ida_export calc_crc32(uint32 crc, const void *buf, size_t len);
4676
4677
4679
4680idaman THREAD_SAFE uint32 ida_export calc_file_crc32(class linput_t *fp);
4681
4682
4684
4685idaman THREAD_SAFE bool ida_export base64_encode(qstring *output, const void *input, size_t size);
4686
4688
4689idaman THREAD_SAFE bool ida_export base64_decode(bytevec_t *output, const char *input, size_t size);
4690
4691
4697
4698idaman THREAD_SAFE bool ida_export replace_tabs(qstring *out, const char *str, int tabsize);
4699
4700
4704idaman THREAD_SAFE char *ida_export str2user(char *dst, const char *src, size_t dstsize);
4705idaman THREAD_SAFE char *ida_export user2str(char *dst, const char *src, size_t dstsize);
4706idaman THREAD_SAFE char ida_export back_char(const char **p);
4707#ifdef __cplusplus
4708idaman THREAD_SAFE void ida_export qstr2user(qstring *dst, const char *src, int nsyms=-1);
4709inline THREAD_SAFE void qstr2user(qstring *dst, const qstring &src) { qstr2user(dst, src.c_str(), src.length()); }
4710idaman THREAD_SAFE void ida_export user2qstr(qstring *dst, const qstring &src);
4711#else
4712idaman THREAD_SAFE void ida_export qstr2user(qstring *dst, const qstring *src);
4713idaman THREAD_SAFE void ida_export user2qstr(qstring *dst, const qstring *src);
4714#endif
4716
4717
4726
4727inline constexpr bool is_utf8_head(char in) { return (in & 0xC0) != 0x80; }
4728
4729
4734
4735inline constexpr bool is_utf8_tail(char in) { return !is_utf8_head(in); }
4736
4737
4741
4742idaman THREAD_SAFE bool ida_export is_valid_utf8(const char *in);
4743
4744
4745#ifdef __cplusplus
4746
4752idaman THREAD_SAFE bool ida_export utf8_utf16(qwstring *out, const char *in, int nsyms=-1);
4753
4754
4762idaman THREAD_SAFE bool ida_export utf16_utf8(qstring *out, const wchar16_t *in, int nsyms=-1);
4763
4764
4765inline constexpr bool is_lead_surrogate(wchar32_t wch) { return 0xD800 <= wch && wch < 0xDC00; }
4766inline constexpr bool is_tail_surrogate(wchar32_t wch) { return 0xDC00 <= wch && wch <= 0xDFFF; }
4767inline constexpr wchar32_t utf16_surrogates_to_cp(wchar16_t lead_surrogate, wchar16_t tail_surrogate)
4768{
4769 return (0x10000 + (wchar32_t(lead_surrogate & 0x3FF) << 10)) | (tail_surrogate & 0x3FF);
4770}
4771
4772
4776#define IDBDEC_ESCAPE 0x00000001
4778
4781
4782idaman THREAD_SAFE bool ida_export idb_utf8(qstring *out, const char *in, int nsyms=-1, int flags=0);
4783
4784
4785#ifdef __NT__
4786// These are typically used in the text UI (TUI), and
4787// also to convert argv to UTF-8 at startup.
4788idaman THREAD_SAFE bool ida_export change_codepage(
4789 qstring *out,
4790 const char *in,
4791 int incp,
4792 int outcp);
4793#ifndef CP_ACP
4794#define CP_ACP 0
4795#endif
4796#ifndef CP_OEM
4797#define CP_OEM 1
4798#endif
4799#ifndef CP_UTF8
4800#define CP_UTF8 65001
4801#endif
4802INLINE THREAD_SAFE bool acp_utf8(qstring *out, const char *in)
4803{
4804 return change_codepage(out, in, CP_ACP, CP_UTF8);
4805}
4806#else // !__NT__
4807INLINE THREAD_SAFE bool idaapi change_codepage(qstring *, const char *, int, int) { return false; }
4808#endif // __NT__
4809
4810
4811//-------------------------------------------------------------------------
4812// helpers to compose 16/32-bit wchar's from [M]UTF-8-encoded data
4813inline THREAD_SAFE constexpr wchar16_t utf8_wchar16(uchar b0, uchar b1)
4814{
4815 return (wchar16_t(b0 & 0x1f) << 6) | (b1 & 0x3f);
4816}
4817
4818//-------------------------------------------------------------------------
4819inline THREAD_SAFE constexpr wchar16_t utf8_wchar16(uchar b0, uchar b1, uchar b2)
4820{
4821 return (wchar16_t(b0 & 0x0f) << 12)
4822 | (wchar16_t(b1 & 0x3f) << 6)
4823 | (b2 & 0x3f);
4824}
4825
4826//-------------------------------------------------------------------------
4827inline THREAD_SAFE constexpr wchar32_t utf8_wchar32(uchar b0, uchar b1, uchar b2, uchar b3)
4828{
4829 return (wchar32_t(b0 & 0x07) << 18)
4830 | (wchar32_t(b1 & 0x3f) << 12)
4831 | (wchar32_t(b2 & 0x3f) << 6)
4832 | (b3 & 0x3f);
4833}
4834
4835#endif // __cplusplus
4836
4837
4838#define BADCP wchar32_t(-1)
4839
4841
4842idaman THREAD_SAFE wchar32_t ida_export get_utf8_char(const char **pptr);
4843
4844
4851
4852idaman THREAD_SAFE bool ida_export prev_utf8_char(wchar32_t *out_cp, const char **p, const char *begin);
4853
4854
4865
4866idaman THREAD_SAFE size_t ida_export skip_utf8(const char **putf8, size_t n);
4867
4868
4874
4875idaman THREAD_SAFE ssize_t ida_export put_utf8_char(char *out, wchar32_t cp);
4876
4877
4879
4880idaman THREAD_SAFE bool ida_export is_cp_graphical(wchar32_t cp);
4881
4882
4883// Get number of codepoints in UTF-8 string. Any 'bad' byte
4884// (i.e., can't be decoded) counts for 1 codepoint.
4885
4886idaman THREAD_SAFE size_t ida_export qustrlen(const char *utf8);
4887
4888
4893
4894idaman THREAD_SAFE bool ida_export qustrncpy(char *dst, const char *utf8, size_t dstsize);
4895
4896
4897// A few Unicode-related helpful defines
4898
4899#define CP_BOM 0xFEFF
4900#define UTF8_BOM "\xEF\xBB\xBF"
4901#define UTF8_BOM_SZ (sizeof(UTF8_BOM) - 1)
4902
4903#define UTF16LE_BOM "\xFF\xFE"
4904#define UTF16BE_BOM "\xFE\xFF"
4905#define UTF16_BOM_SZ (sizeof(UTF16LE_BOM) - 1)
4906
4907#define UTF32LE_BOM "\xFF\xFE\x00\x00"
4908#define UTF32BE_BOM "\x00\x00\xFE\xFF"
4909#define UTF32_BOM_SZ (sizeof(UTF32LE_BOM) - 1)
4910
4911#define CP_ELLIPSIS 0x2026
4912#define UTF8_ELLIPSIS "\xE2\x80\xA6"
4913#define UTF8_ELLIPSIS_SZ (sizeof(UTF8_ELLIPSIS) - 1)
4914
4915#define CP_REPLCHAR 0xFFFD
4916#define UTF8_REPLCHAR "\xEF\xBF\xBD"
4917#define UTF8_REPLCHAR_SZ (sizeof(UTF8_REPLCHAR) - 1)
4918
4919
4920// To cover unicode, 4 bytes is enough. Still, from the UTF-8 spec at
4921// https://tools.ietf.org/html/rfc3629:
4922// "Another security issue occurs when encoding to UTF-8: the ISO/IEC
4923// 10646 description of UTF-8 allows encoding character numbers up to
4924// U+7FFFFFFF, yielding sequences of up to 6 bytes. There is therefore
4925// a risk of buffer overflow if the range of character numbers is not
4926// explicitly limited to U+10FFFF or if buffer sizing doesn't take into
4927// account the possibility of 5- and 6-byte sequences."
4928// Furthermore, since buffers holding UTF-8 sequences are usually placed
4929// onto the stack, it's probably not a bad thing to make them 8-bytes
4930// aligned -- and keep room for a terminating zero, too.
4931#define MAX_UTF8_SEQ_LEN (6 + 1 + 1)
4932
4933//------------------------------------------------------------------------
4935idaman bool ida_export is_cvt64();
4936
4937
4938
4942#define CEF_RETERR 0x1 // return -1 if iconv() returns -1
4944
4955
4956idaman ssize_t ida_export convert_encoding(
4957 bytevec_t *out,
4958 const char *fromcode,
4959 const char *tocode,
4960 const uchar *indata,
4961 ssize_t insize,
4962 DEFARG(int flags,0));
4963
4964#ifdef __cplusplus
4966 bytevec_t *out,
4967 const char *fromcode,
4968 const char *tocode,
4969 const bytevec_t *indata,
4970 DEFARG(int flags,0))
4971{
4972 QASSERT(1451, ssize_t(indata->size()) >= 0);
4973 return convert_encoding(out, fromcode, tocode, indata->begin(), indata->size(), flags);
4974}
4975#endif
4976
4977#define ENC_WIN1252 "windows-1252"
4978#define ENC_UTF8 "UTF-8"
4979#define ENC_MUTF8 "MUTF-8" // modified UTF-8, used by Dalvik and Java (https://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8)
4980#define ENC_UTF16 "UTF-16"
4981#define ENC_UTF16LE "UTF-16LE"
4982#define ENC_UTF16BE "UTF-16BE"
4983#define ENC_UTF32 "UTF-32"
4984#define ENC_UTF32LE "UTF-32LE"
4985#define ENC_UTF32BE "UTF-32BE"
4986
4987
4988
4989#ifndef CP_UTF8
4990#define CP_UTF8 65001
4991#endif
4992
4993#ifndef CP_UTF16
4994#define CP_UTF16 1200
4995#endif
4996
4997#ifdef __NT__
4998# ifndef INVALID_FILE_ATTRIBUTES
4999# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
5000# endif
5001# ifndef BELOW_NORMAL_PRIORITY_CLASS
5002# define BELOW_NORMAL_PRIORITY_CLASS 0x00004000
5003# endif
5004#endif
5005
5006#define SUBSTCHAR '_'
5007
5010typedef ea_t tid_t;
5011
5013#define DEFCOLOR bgcolor_t(-1)
5014
5015//-------------------------------------------------------------------------
5016// Command line
5017//-------------------------------------------------------------------------
5018
5019#ifdef __cplusplus
5022{
5023 int fd;
5026 int flags;
5030#define IOREDIR_INPUT 0x01
5031#define IOREDIR_OUTPUT 0x02
5032#define IOREDIR_APPEND 0x04
5033#define IOREDIR_QUOTED 0x08
5035 bool is_input(void) const { return (flags & IOREDIR_INPUT) != 0; }
5036 bool is_output(void) const { return (flags & IOREDIR_OUTPUT) != 0; }
5037 bool is_append(void) const { return (flags & IOREDIR_APPEND) != 0; }
5038 bool is_quoted(void) const { return (flags & IOREDIR_QUOTED) != 0; }
5039 int start;
5041};
5043#else
5044typedef struct channel_redirs_tag channel_redirs_t;
5045typedef struct qstrvec_tag qstrvec_t;
5046#endif
5047
5056
5057idaman THREAD_SAFE size_t ida_export parse_command_line(
5058 qstrvec_t *args,
5059 channel_redirs_t *redirs,
5060 const char *cmdline,
5061 int flags);
5062
5063
5074
5075char **expand_argv(int *p_argc, int argc, const char *const argv[]);
5076
5077
5079
5080INLINE void free_argv(int argc, char **argv)
5081{
5082 int i;
5083 if ( argv != nullptr )
5084 {
5085 for ( i = 0; i < argc; i++ )
5086 qfree(argv[i]);
5087 qfree(argv);
5088 }
5089}
5090
5091
5096
5097idaman bool ida_export quote_cmdline_arg(qstring *arg);
5098
5099//-------------------------------------------------------------------------
5100// Command-line tools
5101//-------------------------------------------------------------------------
5102typedef void cliopt_handler_t(const char *value, void *ud);
5103typedef void cliopt_poly_handler_t(int argc, const char **argv, void *ud);
5105{
5107 const char *longname;
5108 const char *help;
5110 int nargs; // number of arguments. Can be 0, 1 or -1.
5111 // If '-1', it means 'poly_handler' will be used
5112};
5114
5115struct cliopts_t;
5116#ifndef SWIG
5117# define DEFINE_CLIOPTS_T_HELPERS(decl) \
5118 decl void ida_export cliopts_t_add(cliopts_t &, const cliopt_t *, size_t); \
5119 decl int ida_export cliopts_t_apply(cliopts_t &, int, const char *[], void *); \
5120 decl const cliopt_t *ida_export cliopts_t_find_short(const cliopts_t &, char); \
5121 decl const cliopt_t *ida_export cliopts_t_find_long(const cliopts_t &, const char *); \
5122 decl NORETURN void ida_export cliopts_t_usage(const cliopts_t &, bool);
5123#else
5124# define DEFINE_CLIOPTS_T_HELPERS(decl)
5125#endif // SWIG
5126DEFINE_CLIOPTS_T_HELPERS(idaman)
5127
5128struct cliopts_t : public qvector<cliopt_t>
5129{
5130 qstring prog_name;
5131 qstring epilog;
5132 typedef AS_PRINTF(1, 2) int usage_printer_t(const char *format, ...);
5133 usage_printer_t *printer;
5134 bool print_usage;
5135
5136 cliopts_t(usage_printer_t *_printer, bool _print_usage = true)
5137 : printer(_printer)
5138 , print_usage(_print_usage)
5139 {}
5140
5141 void add(const cliopt_t *opts, size_t nopts) { cliopts_t_add(*this, opts, nopts); }
5142 int apply(int argc, const char *argv[], void *ud=nullptr) { return cliopts_t_apply(*this, argc, argv, ud); }
5143 const cliopt_t *find_short(char shortname) const { return cliopts_t_find_short(*this, shortname); }
5144 const cliopt_t *find_long(const char *longname) const { return cliopts_t_find_long(*this, longname); }
5145 void usage(bool is_error=true) const { return cliopts_t_usage(*this, is_error); }
5146
5147private:
5148 DEFINE_CLIOPTS_T_HELPERS(friend);
5149};
5150
5151struct plugin_option_t;
5152#ifndef SWIG
5153# define DEFINE_PLUGIN_OPTION_T_HELPERS(decl) \
5154 decl bool ida_export plugin_option_t_get_bool(const plugin_option_t *, bool *, const char *, bool);
5155#else
5156# define DEFINE_PLUGIN_OPTION_T_HELPERS(decl)
5157#endif // SWIG
5158
5163struct plugin_option_t
5164{
5165 qstring name;
5166 qstring value;
5167 const char *get_value(const char *default_value) const
5168 {
5169 return value.empty() ? default_value : value.c_str();
5170 }
5171 bool get_string(qstring *out, const char *desired_name, const char *default_value) const
5172 {
5173 if ( name != desired_name )
5174 return false;
5175 if ( out != nullptr )
5176 *out = get_value(default_value);
5177 return true;
5178 }
5179 bool get_bool(bool *out, const char *desired_name, bool default_value) const
5180 {
5181 return plugin_option_t_get_bool(this, out, desired_name, default_value);
5182 }
5183
5184private:
5186};
5189
5191{
5192 const plugin_option_t *find(const qstring &name) const
5193 {
5194 for ( const auto &one : *this )
5195 if ( one.name == name )
5196 return &one;
5197 return nullptr;
5198 }
5199
5200 bool erase(const char *name)
5201 {
5202 for ( size_t i = 0; i < size(); ++i )
5203 {
5204 if ( at(i).name == name )
5205 {
5206 qvector::erase(begin() + i);
5207 return true;
5208 }
5209 }
5210 return false;
5211 }
5212};
5213
5220idaman bool ida_export parse_plugin_options(plugin_options_t *opts, const char *optstring);
5221
5227idaman void ida_export build_plugin_options(qstring *out, const plugin_options_t &opts, const char *optname=nullptr);
5228
5229//-------------------------------------------------------------------------
5230// INSTANT DEBUGGING
5231//-------------------------------------------------------------------------
5232
5233#ifdef __cplusplus
5246#else
5247struct instant_dbgopts_t;
5248#endif
5249
5253
5254idaman bool ida_export parse_dbgopts(struct instant_dbgopts_t *ido, const char *r_switch);
5255
5256
5257//-------------------------------------------------------------------------
5258// PROCESSES
5259//-------------------------------------------------------------------------
5260
5265{
5266 size_t cb = sizeof(*this);
5267 int flags = 0;
5271#define LP_NEW_CONSOLE 0x0001
5272#define LP_TRACE 0x0002
5273#define LP_PATH_WITH_ARGS 0x0004
5274#define LP_USE_SHELL 0x0008
5276#define LP_LAUNCH_32_BIT 0x0010
5277#define LP_LAUNCH_64_BIT 0x0020
5279#define LP_NO_ASLR 0x0040
5280#define LP_DETACH_TTY 0x0080
5281#define LP_HIDE_WINDOW 0x0100
5282#define LP_SUSPENDED 0x0200
5283#define LP_DETACHED 0x0400
5284#define LP_REPLACE_ENV 0x0800
5286 const char *path = nullptr;
5287 const char *args = nullptr;
5291 char *env = nullptr;
5295 const char *startdir = nullptr;
5296 void *info = nullptr;
5298};
5299
5302
5303#ifdef __cplusplus
5304idaman THREAD_SAFE void *ida_export launch_process(
5305 const launch_process_params_t &lpp,
5306 qstring *errbuf=nullptr);
5307#else
5308idaman THREAD_SAFE void *ida_export launch_process(
5309 const struct launch_process_params_t *lpp,
5310 qstring *errbuf);
5311#endif
5312
5313
5316
5317idaman THREAD_SAFE int ida_export term_process(void *handle);
5318
5319
5324
5325idaman THREAD_SAFE int ida_export qwait_timed(int *status, int child, int flags, int timeout_ms);
5326
5327#if defined(__UNIX__)
5328# ifdef WCONTINUED
5329# define QWCONTINUED WCONTINUED
5330# else
5331# define QWCONTINUED 8
5332# endif
5333# ifdef WNOHANG
5334# define QWNOHANG WNOHANG
5335# else
5336# define QWNOHANG 1
5337# endif
5338inline THREAD_SAFE int qwait(int *status, int child, int flags)
5339{
5340 return qwait_timed(status, child, flags, (flags & QWNOHANG) != 0 ? 0 : -1);
5341}
5342#endif
5343
5344
5356
5357idaman THREAD_SAFE int ida_export check_process_exit(
5358 void *handle,
5359 int *exit_code,
5360 DEFARG(int msecs,-1));
5361
5369
5370
5373
5374idaman THREAD_SAFE enum tty_control_t ida_export is_control_tty(int fd);
5375
5376
5380
5381idaman THREAD_SAFE void ida_export qdetach_tty(void);
5382
5383
5387
5388idaman THREAD_SAFE void ida_export qcontrol_tty(void);
5389
5390//-------------------------------------------------------------------------
5392//-------------------------------------------------------------------------
5393
5395typedef int idaapi qthread_cb_t(void *ud);
5396
5398#ifdef __cplusplus
5399#define OPAQUE_HANDLE(n) typedef struct __ ## n {} *n
5400#else
5401#define OPAQUE_HANDLE(n) typedef struct __ ## n { char __dummy; } *n
5402#endif
5403OPAQUE_HANDLE(qthread_t);
5404
5405
5407
5408idaman THREAD_SAFE qthread_t ida_export qthread_create(qthread_cb_t *thread_cb, void *ud);
5409
5410
5413
5414idaman THREAD_SAFE void ida_export qthread_free(qthread_t q);
5415
5416
5418
5419idaman THREAD_SAFE bool ida_export qthread_join(qthread_t q);
5420
5421
5423
5424idaman THREAD_SAFE bool ida_export qthread_kill(qthread_t q);
5425
5426
5428
5429idaman THREAD_SAFE qthread_t ida_export qthread_self(void);
5430
5431
5433
5434idaman THREAD_SAFE bool ida_export qthread_same(qthread_t q);
5435
5436
5438
5439idaman THREAD_SAFE bool ida_export qthread_equal(qthread_t q1, qthread_t q2);
5440
5441
5443
5444idaman THREAD_SAFE bool ida_export is_main_thread(void);
5445
5446
5448
5449idaman THREAD_SAFE bool ida_export qsetenv(const char *varname, const char *value);
5450idaman THREAD_SAFE bool ida_export qgetenv(const char *varname, DEFARG(qstring *buf, nullptr));
5451
5452
5453//-------------------------------------------------------------------------
5456//-------------------------------------------------------------------------
5457OPAQUE_HANDLE(qsemaphore_t);
5458
5459idaman THREAD_SAFE qsemaphore_t ida_export qsem_create(const char *name, int init_count);
5460idaman THREAD_SAFE bool ida_export qsem_free(qsemaphore_t sem);
5461idaman THREAD_SAFE bool ida_export qsem_post(qsemaphore_t sem);
5462idaman THREAD_SAFE bool ida_export qsem_wait(qsemaphore_t sem, int timeout_ms);
5463
5464//-------------------------------------------------------------------------
5466//-------------------------------------------------------------------------
5468idaman THREAD_SAFE bool ida_export qmutex_free(qmutex_t m);
5469idaman THREAD_SAFE qmutex_t ida_export qmutex_create(void);
5470idaman THREAD_SAFE bool ida_export qmutex_lock(qmutex_t m);
5471idaman THREAD_SAFE bool ida_export qmutex_unlock(qmutex_t m);
5472
5473
5474#ifdef __cplusplus
5477{
5478 qmutex_t lock;
5479public:
5480 qmutex_locker_t(qmutex_t _lock) : lock(_lock) { qmutex_lock(lock); }
5482};
5483#endif
5484
5485//-------------------------------------------------------------------------
5486// PIPES
5487//-------------------------------------------------------------------------
5488#ifdef __NT__
5489typedef void *qhandle_t;
5491#else
5492typedef int qhandle_t;
5493const qhandle_t NULL_PIPE_HANDLE = -1;
5494#endif
5495
5496
5502
5503idaman THREAD_SAFE int ida_export qpipe_create(qhandle_t handles[2]);
5504
5505
5507
5508idaman THREAD_SAFE ssize_t ida_export qpipe_read(qhandle_t handle, void *buf, size_t size);
5509
5515
5516idaman THREAD_SAFE bool ida_export qpipe_read_n(qhandle_t handle, bytevec_t *out_bytes, size_t n);
5517
5519
5520idaman THREAD_SAFE ssize_t ida_export qpipe_write(qhandle_t handle, const void *buf, size_t size);
5521
5522
5524
5525idaman THREAD_SAFE int ida_export qpipe_close(qhandle_t handle);
5526
5527
5535
5536idaman void *ida_export pipe_process(
5537 qhandle_t *read_handle,
5538 qhandle_t *write_handle,
5540 qstring *errbuf=nullptr);
5541
5542
5553
5554idaman THREAD_SAFE int ida_export qwait_for_handles(
5555 int *idx,
5556 const qhandle_t *handles,
5557 int n,
5558 uint32 write_bitmask,
5559 int timeout_ms);
5560
5564
5565idaman THREAD_SAFE bool ida_export get_login_name(qstring *out);
5566
5569
5570idaman THREAD_SAFE int ida_export get_physical_core_count();
5571
5574
5575idaman THREAD_SAFE int ida_export get_logical_core_count();
5576
5580
5581idaman THREAD_SAFE int ida_export get_available_core_count();
5582
5583
5584#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:3082
va_end(copy)
void inject(qchar *s, size_t len)
Assign this qstring to an existing char *.
Definition pro.h:3300
_qstring & insert(size_t idx, const qchar *str, size_t addlen)
Insert a string into the qstring.
Definition pro.h:3447
_qstring & insert(size_t idx, const _qstring &qstr)
Same as insert(size_t, const qchar *), but takes a qstring parameter.
Definition pro.h:3473
void swap(_qstring< qchar > &r)
Swap contents of two qstrings. see qvector::swap()
Definition pro.h:3122
_qstring & append(const qchar *str, size_t addlen)
Append a string to the qstring.
Definition pro.h:3504
_qstring & operator+=(const _qstring &r)
Append another qstring using '+='.
Definition pro.h:3217
const qchar * const_iterator
Definition pro.h:3176
bool empty(void) const
Does the qstring have 0 non-null elements?
Definition pro.h:3168
_qstring & operator=(const qchar *str)
Allow assignment of qstrings using '='.
Definition pro.h:3182
_qstring(const qchar *ptr)
Constructor - creates a new qstring from an existing char *.
Definition pro.h:3096
_qstring operator+(const _qstring &r) const
Get result of appending two qstrings using '+'.
Definition pro.h:3222
_qstring & insert(const qchar *str)
Prepend the qstring with 'str'.
Definition pro.h:3490
_qstring & fill(qchar c, size_t len)
Clear contents of qstring and fill with 'c'.
Definition pro.h:3612
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:3102
size_t rfind(qchar c, size_t pos=0) const
Search backwards for a character in the qstring.
Definition pro.h:3383
size_t find(qchar c, size_t pos=0) const
Find a character in the qstring.
Definition pro.h:3368
const_iterator begin(void) const
Get a const pointer to the beginning of the qstring.
Definition pro.h:3178
_qstring & insert(const _qstring &qstr)
Prepend the qstring with 'qstr'.
Definition pro.h:3491
_qstring & nowarn_sprnt(const char *format,...)
Definition pro.h:3586
_qstring & operator=(_qstring &&x) noexcept
Move assignment operator.
Definition pro.h:3205
void resize(size_t s, qchar c)
Resize to the given size.
Definition pro.h:3131
qchar * extract(void)
Extract C string from _qstring. Must qfree() it.
Definition pro.h:3297
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:3180
bool starts_with(const _qstring &str) const
Does the string start with the specified prefix?
Definition pro.h:3244
va_start(va, format)
_qstring(_qstring &&x)
Move constructor.
Definition pro.h:3118
bool ends_with(const _qstring &str) const
Does the string end with the specified suffix?
Definition pro.h:3261
size_t size(void) const
Get number of chars in this qstring (including terminating zero)
Definition pro.h:3124
void qclear(void)
Clear qstring but do not free memory yet.
Definition pro.h:3167
iterator begin(void)
Get a pointer to the beginning of the qstring.
Definition pro.h:3177
_qstring & rtrim()
Remove all whitespace from the end of the qstring.
Definition pro.h:3651
GCC_DIAG_ON(format-nonliteral)
static constexpr size_t npos
Definition pro.h:3692
void push_back(qchar c)
Definition pro.h:3673
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:3600
qchar & at(size_t idx)
Retrieve char at index 'idx'.
Definition pro.h:3295
size_t capacity(void) const
Get number of chars this qstring can contain (including terminating zero)
Definition pro.h:3125
void remove_last(int cnt=1)
Definition pro.h:3152
_qstring< qchar > substr(size_t pos=0, size_t n=npos) const
Get a substring.
Definition pro.h:3398
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:3363
_qstring & operator=(const _qstring &qstr)
Definition pro.h:3191
const qchar & operator[](size_t idx) const
Retrieve char at index 'idx' using '[]'.
Definition pro.h:3279
size_t length(void) const
Get number of chars in this qstring (not including terminating zero)
Definition pro.h:3123
_qstring & insert(qchar c)
Prepend the qstring with 'c'.
Definition pro.h:3489
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:3287
_qstring(void)
Constructor.
Definition pro.h:3094
va_list va
Definition pro.h:3537
qchar * iterator
Definition pro.h:3175
size_t find(const qchar *str, size_t pos=0) const
Find a substring.
Definition pro.h:3323
_qstring & remove(size_t idx, size_t cnt)
Remove characters from the qstring.
Definition pro.h:3408
bool operator<(const qchar *r) const
Compare two qstrings using '<'. see qstrcmp()
Definition pro.h:3239
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:3179
_qstring & ltrim(qchar blank=' ')
Remove all instances of the specified char from the beginning of the qstring.
Definition pro.h:3620
_qstring & append(qchar c)
Append c to the end of the qstring.
Definition pro.h:3493
void reserve(size_t cnt)
Increase capacity the qstring. see qvector::reserve()
Definition pro.h:3165
void inject(qchar *s)
Same as to inject(qchar *, size_t), with len = strlen(s)
Definition pro.h:3305
_qstring & insert(size_t idx, qchar c)
Insert a character into the qstring.
Definition pro.h:3429
qchar value_type
Definition pro.h:3091
_qstring(const _qstring &r)
Copy constructor (if not declared, move constructor causes it to be deleted)
Definition pro.h:3120
_qstring & append(const qchar *str)
Same as append(const qchar *, size_t), but all chars in 'str' are appended.
Definition pro.h:3513
qchar last(void) const
Get the last qchar in the string (for concatenation checks)
Definition pro.h:3314
size_t add
Definition pro.h:3540
_qstring & trim2(qchar blank=' ')
Remove all instances of the specified char from both ends of the qstring.
Definition pro.h:3664
bool replace(const qchar *what, const qchar *with)
Replace all occurrences of 'what' with 'with'.
Definition pro.h:3336
void resize(size_t s)
Similar to resize(size_t, qchar) - but any extra space is filled with zeroes.
Definition pro.h:3140
bool operator!=(const qchar *r) const
Test equality of a qstring and a const char* with '!='.
Definition pro.h:3237
_qstring(size_t count, qchar ch)
Constructor - constructs the string with 'count' copies of character 'ch'.
Definition pro.h:3108
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:3294
_qstring & append(const _qstring &qstr)
Same as append(const qchar *), but takes a qstring argument.
Definition pro.h:3523
bool starts_with(const qchar *ptr, ssize_t len=-1) const
Definition pro.h:3248
const qchar * c_str(void) const
Convert the qstring to a char *.
Definition pro.h:3170
bool operator==(const qchar *r) const
Test equality of a qstring and a const char* using '=='.
Definition pro.h:3233
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:3463
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:3637
DECLARE_COMPARISONS(_qstring)
Definition pro.h:3228
void clear(void)
Clear qstring and free memory.
Definition pro.h:3166
bool ends_with(const qchar *ptr, ssize_t len=-1) const
Definition pro.h:3265
_qstring & operator+=(qchar c)
Append a char using '+='.
Definition pro.h:3212
Vector of bytes (use for dynamic memory)
Definition pro.h:3773
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:3995
void pack_bytevec(const bytevec_t &b)
Pack an object of size 'len' and append the result to the bytevec.
Definition pro.h:3877
bool fromhex(const qstring &str)
Initialize from a hexadecimal string It returns 'false' if the string is invalid.
Definition pro.h:3950
void tohex(qstring *out, bool upper_case=true) const
Append the hexadecimal representation of bytes to the string.
Definition pro.h:3927
void pack_eavec(ea_t ea, const eavec_t &vec)
Pack an eavec and append the result to the bytevec.
Definition pro.h:3892
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:3868
bool test_bit(size_t bit) const
Is the specified bit set in the bytevec?
Definition pro.h:3966
bytevec_t()
Constructor.
Definition pro.h:3776
void pack_str(const qstring &s)
Pack a string (zero-terminated) and append the result to the bytevec.
Definition pro.h:3859
bool all_zeros() const
Are all bits cleared?
Definition pro.h:3976
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:3984
void clear_bits(size_t low, size_t high)
Clear each bit between [low, high)
Definition pro.h:4003
bytevec_t & growfill(size_t sz, uchar filler=0)
Grow the bytevec and fill with a value.
Definition pro.h:3908
void pack_ea(ea_t x)
Pack an ea value and append the result to the bytevec.
Definition pro.h:3819
void inject(void *buf, size_t len)
See qvector::inject(T *, size_t)
Definition pro.h:3921
void pack_db(uint8 x)
Pack a byte and append the result to the bytevec.
Definition pro.h:3796
void set_bit(size_t bit)
Set the specified bit.
Definition pro.h:3968
void clear_bit(size_t bit)
Clear the specified bit.
Definition pro.h:3970
void set_all_bits(size_t nbits)
See set_all_bits(uchar *, size_t)
Definition pro.h:3972
void pack_dd(uint32 x)
Pack a dword and append the result to the bytevec.
Definition pro.h:3805
void set_bits(size_t low, size_t high)
Set each bit between [low, high)
Definition pro.h:3993
qstring tohex(bool upper_case=true) const
Produce a hexadecimal representation of bytes.
Definition pro.h:3941
void clear_all_bits(size_t nbits)
See clear_all_bits(uchar *, size_t)
Definition pro.h:3974
bytevec_t(const void *buf, size_t sz)
Constructor - fill bytevec with 'sz' bytes from 'buf'.
Definition pro.h:3778
void pack_dw(uint16 x)
Pack a word and append the result to the bytevec.
Definition pro.h:3798
bytevec_t & append(const void *buf, size_t sz)
Append bytes to the bytevec.
Definition pro.h:3782
void pack_ds(const char *x)
Pack a string (length+contents) and append the result to the bytevec.
Definition pro.h:3839
void pack_dq(uint64 x)
Pack a quadword and append the result to the bytevec.
Definition pro.h:3812
void pack_str(const char *str)
Pack a string (zero-terminated) and append the result to the bytevec.
Definition pro.h:3851
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:3830
pool_allocator_t(const pool_allocator_t &)
Definition pro.h:2839
T * allocate(size_t n)
Definition pro.h:2846
pool_allocator_t(const pool_allocator_t< U > &)
Definition pro.h:2838
pool_allocator_t & operator=(const pool_allocator_t &)
Definition pro.h:2840
bool operator==(const pool_allocator_t &r) const
Definition pro.h:2843
T value_type
Definition pro.h:2830
void deallocate(T *ptr, size_t n)
Definition pro.h:2869
pool_allocator_t & operator=(pool_allocator_t &&)=default
const T * const_pointer
Definition pro.h:2832
pool_allocator_t(pool_allocator_t &&)=default
T * pointer
Definition pro.h:2831
pool_allocator_t()
Definition pro.h:2837
const T & const_reference
Definition pro.h:2834
size_t size_type
Definition pro.h:2835
T & reference
Definition pro.h:2833
ptrdiff_t difference_type
Definition pro.h:2836
Interface class for iterator types.
Definition pro.h:2984
virtual T idaapi operator*(void)=0
source_item_ptr value_type
Definition pro.h:2986
virtual bool idaapi next(void)=0
virtual T get(void) new api
Definition pro.h:2990
virtual bool idaapi first(void)=0
Linked list Note: linked list is not movable!
Definition pro.h:4038
~qlist(void)
Destructor.
Definition pro.h:4149
const
Definition pro.h:4117
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
const_iterator(const iterator &x)
Definition pro.h:4117
cinsn_t value_type
Definition pro.h:4074
const_iterator qlist(void)
Constructor.
Definition pro.h:4141
qlist(const qlist< T > &x)
Constructor - creates a qlist identical to 'x'.
Definition pro.h:4143
~qmutex_locker_t(void)
Definition pro.h:5481
qmutex_locker_t(qmutex_t _lock)
Definition pro.h:5480
virtual void idaapi release(void)=0
Call destructor.
int refcnt
counter
Definition pro.h:2970
qrefcnt_obj_t(void)
Constructor.
Definition pro.h:2972
void reset(void)
Definition pro.h:2946
qrefcnt_t & operator=(const qrefcnt_t &r)
Definition pro.h:2934
T & operator*() const
Definition pro.h:2959
qrefcnt_t(T *p)
Definition pro.h:2928
T * operator->() const
Definition pro.h:2955
~qrefcnt_t(void)
Definition pro.h:2942
qrefcnt_t(const qrefcnt_t &r)
Definition pro.h:2929
Reimplementation of stack class from STL.
Definition pro.h:2774
T pop(void)
Definition pro.h:2777
void push(const T &v)
Definition pro.h:2788
const T & top(void) const
Definition pro.h:2783
T & top(void)
Definition pro.h:2787
Reimplementation of vector class from STL.
Definition pro.h:2250
void reserve(size_t cnt)
Increase the capacity of the qvector.
Definition pro.h:2528
void clear(void)
Destroy all elements and free memory.
Definition pro.h:2439
DEFINE_MEMORY_ALLOCATION_FUNCS() void push_back(const T &x)
Append a new element to the end the qvector.
Definition pro.h:2349
void inject(T *s, size_t len)
Populate the qvector with dynamic memory.
Definition pro.h:2587
void resize_noinit(size_t _newsize)
Definition pro.h:2504
iterator erase(iterator first, iterator last)
Remove a subset of the qvector.
Definition pro.h:2690
const compiled_binpat_t * const_iterator
Definition pro.h:2607
bool del(const T &x)
Find an element and remove it.
Definition pro.h:2749
const T & operator[](size_t _idx) const
Allows use of typical c-style array indexing for qvectors.
Definition pro.h:2425
void emplace_back(Args &&... args)
Construct and append a new element to the end the qvector with a forwarding semantics.
Definition pro.h:2390
T & at(size_t _idx)
Get element at index '_idx'.
Definition pro.h:2428
~qvector(void)
Destructor.
Definition pro.h:2341
void swap(qvector< T > &r) noexcept
Replace all attributes of this qvector with that of 'r', and vice versa.
Definition pro.h:2560
void truncate(void)
Shrink the capacity down to the current number of elements.
Definition pro.h:2550
const_iterator find(const T &x) const
Find an element in the qvector.
Definition pro.h:2713
qvector(const qvector< T > &x)
Constructor - creates a new qvector identical to 'x'.
Definition pro.h:2330
bool empty(void) const
Does the qvector have 0 elements?
Definition pro.h:2424
iterator erase(iterator it)
Remove an element from the qvector.
Definition pro.h:2678
void qclear(void)
Destroy all elements but do not free memory.
Definition pro.h:2434
iterator end(void)
Get an iterator that points to the end of the qvector (NOT the last element)
Definition pro.h:2610
T & operator[](size_t _idx)
Allows use of typical c-style array indexing for qvectors.
Definition pro.h:2426
compiled_binpat_t value_type
Definition pro.h:2326
bool operator!=(const qvector< T > &r) const
Allow ability to test equality of two qvectors using '!='.
Definition pro.h:2604
iterator insert(iterator it, const T &x)
Insert an element into the qvector at a specified position.
Definition pro.h:2617
iterator insert(iterator it, T &&x)
Insert an element into the qvector with a move semantics.
Definition pro.h:2634
const_iterator begin(void) const
Get a const iterator that points to the first element in the qvector.
Definition pro.h:2611
void resize(size_t _newsize, const T &x)
Resize to the given size.
Definition pro.h:2469
const char * dstr(void) const
qvector< T > & operator=(const qvector< T > &x)
Allow assignment of one qvector to another using '='.
Definition pro.h:2448
const T & at(size_t _idx) const
Get element at index '_idx'.
Definition pro.h:2427
void add(T &&x)
Definition pro.h:2732
void add(const T &x)
Add an element to the end of the qvector.
Definition pro.h:2731
const T & back(void) const
Get the last element in the qvector.
Definition pro.h:2431
iterator find(const T &x)
Find an element in the qvector.
Definition pro.h:2703
qvector(void)
Constructor.
Definition pro.h:2328
T & back(void)
Get the last element in the qvector.
Definition pro.h:2432
T * extract(void)
Empty the qvector and return a pointer to it's contents.
Definition pro.h:2576
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:2513
const T & front(void) const
Get the first element in the qvector.
Definition pro.h:2429
bool operator==(const qvector< T > &r) const
Allow ability to test the equality of two qvectors using '=='.
Definition pro.h:2594
void pop_back(void)
Remove the last element in the qvector.
Definition pro.h:2411
iterator insert(iterator it, it2 first, it2 last)
Insert a several elements to the qvector at a specified position.
Definition pro.h:2655
T & push_back(void)
Append a new empty element to the end of the qvector.
Definition pro.h:2402
compiled_binpat_t * iterator
Definition pro.h:2606
iterator begin(void)
Get an iterator that points to the first element in the qvector.
Definition pro.h:2609
void push_back(compiled_binpat_t &&x)
Definition pro.h:2361
T & front(void)
Get the first element in the qvector.
Definition pro.h:2430
const_iterator end(void) const
Get a const iterator that points to the end of the qvector (NOT the last element)
Definition pro.h:2612
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:2525
void resize(size_t _newsize)
Same as resize(size_t, const T &), but extra space is filled with empty elements.
Definition pro.h:2485
size_t size(void) const
Get the number of elements in the qvector.
Definition pro.h:2423
ssize_t index(const T &x) const
Find index of the specified value or return -1.
Definition pro.h:2723
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:2739
qvector(qvector< T > &&x) noexcept
Move constructor.
Definition pro.h:2333
bool has(const T &x) const
Does the qvector contain x?
Definition pro.h:2735
qvector< T > & operator=(qvector< T > &&x) noexcept
Move assignment operator.
Definition pro.h:2455
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:942
INLINE THREAD_SAFE bool ida_local qisupper(char c)
Definition pro.h:943
INLINE THREAD_SAFE bool ida_local qisdigit(char c)
Definition pro.h:945
INLINE THREAD_SAFE bool ida_local qisalnum(char c)
Definition pro.h:940
INLINE THREAD_SAFE bool ida_local qispunct(char c)
Definition pro.h:941
INLINE THREAD_SAFE bool ida_local qisalpha(char c)
Definition pro.h:939
INLINE THREAD_SAFE bool ida_local qisxdigit(char c)
Definition pro.h:946
INLINE THREAD_SAFE bool ida_local qisascii(char c)
Definition pro.h:937
INLINE THREAD_SAFE bool ida_local qisprint(char c)
Definition pro.h:944
INLINE THREAD_SAFE bool ida_local qisspace(char c)
Definition pro.h:938
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:1001
int code
Definition fpro.h:88
idaman size_t n
Definition pro.h:997
THREAD_SAFE bool unpack_sleb128(T *res, const uchar **pptr, const uchar *end)
Definition pro.h:1948
THREAD_SAFE bool unpack_uleb128(T *res, const uchar **pptr, const uchar *end)
Definition pro.h:1941
GCC_DIAG_OFF(format-nonliteral)
cexpr_t * e
Definition hexrays.hpp:7308
const tinfo_t & type
Definition hexrays.hpp:7301
carglist_t * args
Definition hexrays.hpp:7323
CASSERT(sizeof(asm_t)==416)
idaman int64 size_t count
Definition kernwin.hpp:1366
int nbytes
Definition kernwin.hpp:2861
uval_t uval_t
Definition kernwin.hpp:1878
idaman int64 pos
Definition kernwin.hpp:1365
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:1356
asize_t size
Definition kernwin.hpp:6339
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:7890
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
Functions to work with intervals.
Definition pro.h:1452
THREAD_SAFE constexpr bool contains(uval_t off1, asize_t s1, uval_t off)
Does (off1,s1) contain off?
Definition pro.h:1469
THREAD_SAFE constexpr uval_t last(uval_t off, asize_t s)
max offset of the interval (assume s != 0)
Definition pro.h:1454
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:1464
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:1459
Definition pro.h:3704
idaman size_t const char time_t t
Definition pro.h:602
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:560
THREAD_SAFE size_t idaapi qstrlen(const char *s)
Definition pro.h:2998
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:1996
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:1988
THREAD_SAFE bool idaapi has_file_ext(const char *file)
Does the given file name have an extension?
Definition pro.h:1165
unsigned short uint16
unsigned 16 bit value
Definition pro.h:346
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 (line 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:1010
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:329
unsigned int uint32
unsigned 32 bit value
Definition pro.h:348
THREAD_SAFE constexpr uint32 swap32(uint32 x)
Definition pro.h:1650
T qrotr(T value, size_t count)
Rotate right.
Definition pro.h:1509
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:2765
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:343
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:4766
constexpr bool is_utf8_head(char in)
Does this byte correspond to the head of a UTF-8 byte sequence?
Definition pro.h:4727
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:1559
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:1443
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:423
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:2044
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:784
constexpr T make_mask(int count)
Make a mask of 'count' bits.
Definition pro.h:1521
INLINE THREAD_SAFE int ida_local qtolower(char c)
Get lowercase equivalent of given char.
Definition pro.h:950
T align_up(T val, int elsize)
Align element up to nearest boundary.
Definition pro.h:4628
uint64 ea64_t
64-bit address, regardless of IDA bitness.
Definition pro.h:453
void shift_up(T *dst, T *src, size_t cnt)
Move data up in memory.
Definition pro.h:2220
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:1975
uint32 ea32_t
32-bit address, regardless of IDA bitness.
Definition pro.h:450
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:497
qvector< uval_t > uvalvec_t
vector of unsigned values
Definition pro.h:2762
uint32 wchar32_t
Definition pro.h:371
THREAD_SAFE uchar idaapi unpack_db(const uchar **pptr, const uchar *end)
Unpack a byte from a character string, pack_db()
Definition pro.h:1747
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:1801
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:1491
bool is_mul_ok(T count, T elsize)
Check that unsigned multiplication does not overflow.
Definition pro.h:1536
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:5012
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:1180
qvector< size_t > sizevec_t
vector of sizes
Definition pro.h:2767
uint8 op_dtype_t
Definition pro.h:460
adiff_t sval_t
signed value used by the processor.
Definition pro.h:446
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:345
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:1654
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:1357
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:4342
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:1766
int64 adiff_t
Definition pro.h:424
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:421
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:1847
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:1486
uint32 flags_t
32-bit flags for each address
Definition pro.h:5008
THREAD_SAFE uint32 extract_dd(T &v)
Definition pro.h:2015
int int32
signed 32 bit value
Definition pro.h:347
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:1497
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:499
wchar_t wchar16_t
Definition pro.h:370
idaman bool ida_export_data under_debugger
is IDA running under a debugger?
Definition pro.h:735
THREAD_SAFE bool unpack_bytevec(bytevec_t *out, const uchar **pptr, const uchar *end)
Definition pro.h:4358
std::unique_ptr< T, qfree_deleter_t< T > > qalloc_janitor_t
Definition pro.h:4502
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:337
tty_control_t
Teletype control.
Definition pro.h:5364
@ TCT_NOT_OWNER
Definition pro.h:5367
@ TCT_OWNER
Definition pro.h:5366
@ TCT_UNKNOWN
Definition pro.h:5365
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:522
const qhandle_t NULL_PIPE_HANDLE
Definition pro.h:5490
qvector< bool > boolvec_t
vector of bools
Definition pro.h:2766
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:2903
THREAD_SAFE void qswap(T &a, T &b)
Swap 2 objects of the same type using memory copies.
Definition pro.h:1715
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:3024
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:1967
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:1908
idaman size_t bufsize
Definition pro.h:600
INLINE THREAD_SAFE uint32 get_secs(qtime64_t t)
Get the 'seconds since the epoch' part of a qtime64_t.
Definition pro.h:504
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:791
uint64 sel_t
Definition pro.h:422
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:2062
qvector< channel_redir_t > channel_redirs_t
vector of channel_redir_t objects
Definition pro.h:5042
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:3042
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:3695
idaman THREAD_SAFE int ida_export readbytes(int h, uint32 *res, int size, bool mf)
Read at most 4 bytes from file.
idaman THREAD_SAFE int ida_export qread(int h, void *buf, size_t n)
Works the same as it's counterpart from Clib.
void shift_down(T *dst, T *src, size_t cnt)
Move data down in memory.
Definition pro.h:2197
qvector< plugin_option_t > plugin_option_vec_t
Definition pro.h:5188
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:1369
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:1545
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:5395
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:1388
THREAD_SAFE uint64 extract_dq(T &v)
Definition pro.h:2026
constexpr bool is_lead_surrogate(wchar32_t wch)
Definition pro.h:4765
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:339
idaman THREAD_SAFE int ida_export qwrite(int h, const void *buf, size_t n)
Works the same as it's counterpart from Clib.
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:1737
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:2004
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:479
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 it's counterpart from Clib.
THREAD_SAFE const void *idaapi unpack_buf_inplace(const uchar **pptr, const uchar *end)
In-place version of unpack_buf().
Definition pro.h:1865
int error_t
Error code (errno)
Definition pro.h:458
INLINE THREAD_SAFE int ida_local qtoupper(char c)
Get uppercase equivalent of given char.
Definition pro.h:952
int lexcompare(const T &a, const T &b)
Standard lexical comparison.
Definition pro.h:2888
qvector< ea_t > eavec_t
vector of addresses
Definition pro.h:2764
uval_t inode_t
The inode_t type is the specialization specific inode number.
Definition pro.h:464
uint64 flags64_t
64-bit flags for each address
Definition pro.h:5009
void qvoid_t
Definition pro.h:4509
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:3033
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:5080
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 it's counterpart from Clib.
void * qhandle_t
MS Windows HANDLE.
Definition pro.h:5489
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:5102
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:3696
idaman uint32 ida_export round_down_power2(uint32 x)
THREAD_SAFE constexpr wchar16_t utf8_wchar16(uchar b0, uchar b1)
Definition pro.h:4813
T round_up(T val, T base)
round up or down to an arbitrary number
Definition pro.h:1438
qvector< sval_t > svalvec_t
vector of signed values
Definition pro.h:2763
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:1375
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:4802
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:3055
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:576
INLINE THREAD_SAFE void idaapi set_all_bits(uchar *bitmap, size_t nbits)
Set first 'nbits' of 'bitmap'.
Definition pro.h:1395
bool is_udiv_ok(T, T b)
Check that unsigned division is permissible.
Definition pro.h:1552
ptrdiff_t ssize_t
Signed size_t - used to check for size overflows when the counter becomes negative.
Definition pro.h:381
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:480
INLINE THREAD_SAFE bool idaapi test_bit(const uchar *bitmap, size_t bit)
Test if 'bit' is set in 'bitmap'.
Definition pro.h:1364
THREAD_SAFE ea_t extract_ea(T &v)
Definition pro.h:2034
unsigned short ushort
unsigned 16 bit value
Definition pro.h:338
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:4638
INLINE THREAD_SAFE uint32 get_usecs(qtime64_t t)
Get the microseconds part of a qtime64_t.
Definition pro.h:512
idaman THREAD_SAFE int ida_export qdup(int h)
Works the same as it's counterpart from Clib.
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:5338
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:4807
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:5159
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:1381
THREAD_SAFE void * extract_array(T &v, size_t *sz, size_t maxsize)
Definition pro.h:2053
idaman uint32 ida_export round_up_power2(uint32 x)
round up or down to a power of 2
idaman THREAD_SAFE int ida_export qclose(int h)
Works the same as it's counterpart from Clib.
void idaapi setflag(T &where, U bit, bool cnd)
Set a 'bit' in 'where' if 'value' if not zero.
Definition pro.h:1527
ea_t tid_t
type id (for enums, structs, etc)
Definition pro.h:5010
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 it's counterpart from Clib.
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:355
int compare_containers(const T &l, const T &r)
Template to compare any 2 containers of the same type. Returns -1/0/1.
Definition pro.h:4555
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:1824
unsigned char uint8
unsigned 8 bit value
Definition pro.h:344
THREAD_SAFE ea64_t unpack_ea64(const uchar **ptr, const uchar *end)
Unpack an ea value (always use 64bit, use delta 1)
Definition pro.h:1787
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:4735
THREAD_SAFE int ds_packed_size(const char *s)
Definition pro.h:1964
THREAD_SAFE int idaapi qstrcmp(const char *s1, const char *s2)
Definition pro.h:3011
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:342
constexpr bool is_pow2(T val)
is power of 2? (or zero)
Definition pro.h:1432
INLINE THREAD_SAFE void idaapi clear_all_bits(uchar *bitmap, size_t nbits)
Clear first 'nbits' of 'bitmap'.
Definition pro.h:1405
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.
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:1481
_qstring< char > qstring
regular string
Definition pro.h:3694
INLINE THREAD_SAFE char * tail(char *str)
Get tail of a string.
Definition pro.h:879
idaman THREAD_SAFE qoff64_t ida_export qtell(int h)
Works the same as it's counterpart from Clib.
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:4767
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:3698
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:4827
int compare(const T &a, const T &b)
Definition pro.h:4514
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:1777
void cliopt_poly_handler_t(int argc, const char **argv, void *ud)
Definition pro.h:5103
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.
qvector< qstring > qstrvec_t
vector of strings
Definition pro.h:3697
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:1569
Tools for command line parsing.
Definition pro.h:5022
qstring file
file name to redirect to/from.
Definition pro.h:5024
int flags
i/o redirection flags
Definition pro.h:5026
int fd
channel number
Definition pro.h:5023
int start
begin of the redirection string in the command line
Definition pro.h:5039
bool is_append(void) const
Definition pro.h:5037
bool is_quoted(void) const
Definition pro.h:5038
bool is_input(void) const
Definition pro.h:5035
int length
length of the redirection string in the command line
Definition pro.h:5040
bool is_output(void) const
Definition pro.h:5036
Definition pro.h:5105
int nargs
Definition pro.h:5110
const char * longname
Definition pro.h:5107
const char * help
Definition pro.h:5108
cliopt_handler_t * handler
Definition pro.h:5109
char shortname
Definition pro.h:5106
Template to compare any 2 values of the same type. Returns -1/0/1.
Definition pro.h:4507
Options for instant debugging.
Definition pro.h:5236
int event_id
event to trigger upon attaching
Definition pro.h:5243
qstring debmod
name of debugger module
Definition pro.h:5237
int pid
process to attach to (-1: ask the user)
Definition pro.h:5242
qstring host
remote hostname (if remote debugging)
Definition pro.h:5239
bool attach
should attach to a process?
Definition pro.h:5244
int port
port number for the remote debugger server
Definition pro.h:5241
qstring pass
password for the remote debugger server
Definition pro.h:5240
qstring env
config variables for debmod. example: DEFAULT_CPU=13;MAXPACKETSIZE=-1
Definition pro.h:5238
interr_exc_t(int _code)
Definition pro.h:760
int code
Definition pro.h:759
linput_t *& resource
Definition pro.h:4491
~janitor_t()
We provide no implementation for this function, you should provide specialized implementation yoursel...
janitor_t(T &r)
Constructor.
Definition pro.h:4487
Information for launching a process with IDA API Note: all string data such as paths (e....
Definition pro.h:5265
const char * args
command line arguments
Definition pro.h:5287
void * info
os specific info (on windows it points to PROCESS_INFORMATION) on unix, not used
Definition pro.h:5296
const char * path
file to run
Definition pro.h:5286
int flags
Launch process flags
Definition pro.h:5267
ssize_t in_handle
handle for stdin or -1
Definition pro.h:5288
char * env
zero separated environment variables that will be appended to the existing environment block (existin...
Definition pro.h:5291
ssize_t err_handle
handle for stderr or -1
Definition pro.h:5290
size_t cb
size of this structure
Definition pro.h:5266
const char * startdir
current directory for the new process
Definition pro.h:5295
ssize_t out_handle
handle for stdout or -1
Definition pro.h:5289
ea_t unpack_ea()
Definition pro.h:4397
void unpack(qvector< T > *out)
Definition pro.h:4444
bool unpack_ds_to_buf(char *buf, size_t bufsize)
Definition pro.h:4408
bool empty() const
Definition pro.h:4390
const uchar * ptr
Definition pro.h:4383
bool eof() const
Definition pro.h:4454
uint64 unpack_dq()
Definition pro.h:4396
const void * unpack_buf_inplace()
Definition pro.h:4416
const uchar * end
Definition pro.h:4384
ssize_t read(void *obj, size_t objsize)
Definition pro.h:4453
void unpack_eavec(eavec_t *vec, ea_t ea)
Definition pro.h:4428
uint16 unpack_dw()
Definition pro.h:4394
memory_deserializer_t(const uchar *p, const uchar *e)
Definition pro.h:4388
bool unpack_str(qstring *out)
Definition pro.h:4401
memory_deserializer_t(const bytevec_t &b)
Definition pro.h:4387
const void * unpack_obj_inplace(size_t objsize)
Definition pro.h:4412
const void * unpack_obj(void *obj, size_t objsize)
Definition pro.h:4420
uint8 unpack_db()
Definition pro.h:4393
void unpack(T *out)
Definition pro.h:4437
uint32 unpack_dd()
Definition pro.h:4395
bool advance(size_t s)
Definition pro.h:4392
memory_deserializer_t(const void *p, size_t s)
Definition pro.h:4389
void unpack(qstring *out)
Definition pro.h:4442
bool unpack_bytevec(bytevec_t *out)
Definition pro.h:4432
const void * unpack_buf()
Definition pro.h:4424
ea64_t unpack_ea64()
Definition pro.h:4398
size_t size() const
Definition pro.h:4391
const char * unpack_str()
Definition pro.h:4400
memory_deserializer_t(const qstring &s)
Definition pro.h:4386
char * unpack_ds(bool empty_null=false)
Definition pro.h:4403
Definition pro.h:4461
void pack(T value)
Definition pro.h:4463
void pack(const qstring &value)
Definition pro.h:4468
void pack(const qvector< T > &value)
Definition pro.h:4470
Definition pro.h:5191
const plugin_option_t * find(const qstring &name) const
Definition pro.h:5192
bool erase(const char *name)
Definition pro.h:5200
Definition pro.h:4497
void operator()(T *ptr)
Definition pro.h:4498
Definition pro.h:808
Definition pro.h:806
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:644
qtime64_t qst_ctime
time of last status change
Definition pro.h:657
uint32 qst_nlink
number of hard links
Definition pro.h:648
uint32 qst_gid
group ID of owner
Definition pro.h:650
qtime64_t qst_atime
time of last access
Definition pro.h:655
uint32 qst_mode
protection
Definition pro.h:647
qtime64_t qst_mtime
time of last modification
Definition pro.h:656
int32 qst_blocks
number of 512B blocks allocated
Definition pro.h:654
qoff64_t qst_size
total size, in bytes
Definition pro.h:652
uint64 qst_rdev
device ID (if special file)
Definition pro.h:651
uint32 qst_ino
inode number
Definition pro.h:646
int32 qst_blksize
blocksize for file system I/O
Definition pro.h:653
uint32 qst_uid
user ID of owner
Definition pro.h:649
uint64 qst_dev
ID of device containing file.
Definition pro.h:645
Relocatable object.
Definition pro.h:4026
ea_t base
current base
Definition pro.h:4027
relobj_t(void)
Definition pro.h:4030
reloc_info_t ri
relocation info
Definition pro.h:4028
bool relocate(ea_t ea, bool mf)
mf=1:big endian
Definition pro.h:4031
Relocation information (relocatable objects - see relobj_t)
Definition pro.h:4008
size_t operator()(const _qstring< T > &str) const noexcept
Definition pro.h:3708