6 #if __x86_64__ || __i386__ || __arm__ || __arm64__
8 #include <sys/ptrace.h>
9 #include <asm/ptrace.h>
14 #if __x86_64__ || __arm64__
20 typedef ut32 elf_offset_t;
21 #elif __i386__ || __arm__
27 typedef ut64 elf_offset_t;
30 #define fmt_addr "%08lx-%08lx"
31 #define ELF_HDR_SIZE sizeof(elf_hdr_t)
34 #define round_up(a) ((((a) + (4) - (1)) / (4)) * (4))
35 #define sizeof_round_up(b) round_up(sizeof(b))
40 static bool is_a_kernel_mapping(
const char *
name) {
41 return !(
name && strcmp(
name,
"[vdso]") && strcmp(
name,
"[vsyscall]") && strcmp(
name,
"[vvar]") && strcmp(
name,
"[heap]") && strcmp(
name,
"[vectors]") && strncmp(
name,
"[stack", strlen(
"[stack")));
44 static char *prpsinfo_get_psargs(
char *
buffer,
int len) {
45 char paux[ELF_PRARGSZ];
51 bytes_left = strlen(
buffer);
58 for (
i = 0;
i + bytes_left <
len &&
i + bytes_left < ELF_PRARGSZ - 1;
i++) {
65 strncat(
p, paux,
len - bytes_left - 1);
70 const char *prog_states =
"RSDTZW";
79 eprintf(
"Couldn't allocate memory for prpsinfo_t\n");
97 strncpy(
p->pr_fname,
basename,
sizeof(
p->pr_fname) - 1);
98 p->pr_fname[
sizeof(
p->pr_fname) - 1] = 0;
99 ppsargs = prpsinfo_get_psargs(
buffer, (
int)
len);
104 strncpy(
p->pr_psargs, ppsargs,
sizeof(
p->pr_psargs) - 1);
105 p->pr_psargs[
sizeof(
p->pr_psargs) - 1] = 0;
109 p->pr_sname = proc_data->
s_name;
110 p->pr_zomb = (
p->pr_sname ==
'Z') ? 1 : 0;
111 p->pr_state = strchr(prog_states,
p->pr_sname) - prog_states;
112 p->pr_ppid = proc_data->
ppid;
113 p->pr_pgrp = proc_data->
pgrp;
114 p->pr_sid = proc_data->
sid;
115 p->pr_flag = proc_data->
flag;
116 p->pr_nice = proc_data->
nice;
117 p->pr_uid = proc_data->
uid;
118 p->pr_gid = proc_data->
gid;
129 char *temp_p_sigpend, *temp_p_sighold, *p_sigpend, *p_sighold;
145 long unsigned int no_lui;
149 sscanf(buff,
"%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu"
151 &no_num, no_str, &no_char, &no_num, &no_num, &no_num,
152 &no_num, &no_num, &no_ui, &no_lui, &no_lui, &no_lui,
165 temp_p_sigpend = strstr(buff,
"SigPnd");
166 temp_p_sighold = strstr(buff,
"SigBlk");
167 if (!temp_p_sigpend || !temp_p_sighold) {
175 p_sigpend = temp_p_sigpend - 1;
179 p_sigpend[temp_p_sigpend - p_sigpend - 1] =
'\0';
183 p_sighold = temp_p_sighold - 1;
187 p_sighold[temp_p_sighold - p_sighold - 1] =
'\0';
206 p->pr_cursig =
p->pr_info.si_signo = signr;
223 perror(
"PTRACE_GETREGS");
233 static elf_fpregset_t *linux_get_fp_regset(
RzDebug *
dbg,
int pid) {
234 elf_fpregset_t *
p =
RZ_NEW0(elf_fpregset_t);
237 perror(
"PTRACE_GETFPREGS");
247 siginfo_t *siginfo =
RZ_NEW0(siginfo_t);
251 int ret = rz_debug_ptrace(
dbg, PTRACE_GETSIGINFO,
pid, 0, (rz_ptrace_data_t)(
size_t)siginfo);
252 if (ret == -1 || !siginfo->si_signo) {
253 perror(
"PTRACE_GETSIGINFO");
260 static bool has_map_deleted_part(
char *
name) {
262 const char deleted_str[] =
"(deleted)";
263 int len_name = strlen(
name);
264 int len_suffx = strlen(deleted_str);
265 return !strncmp(
name + len_name - len_suffx, deleted_str, len_suffx);
270 static bool getAnonymousValue(
char *keyw) {
274 keyw = strchr(keyw,
' ');
281 return *keyw && *keyw !=
'0';
284 static char *isAnonymousKeyword(
const char *pp) {
288 char *keyw = strstr(pp,
"Anonymous:");
290 keyw = strstr(pp,
"AnonHugePages:");
295 static bool has_map_anonymous_content(
char *buff_smaps,
unsigned long start_addr,
unsigned long end_addr) {
296 char *pp, *extern_tok =
NULL, *keyw =
NULL;
297 char *identity =
rz_str_newf(fmt_addr, start_addr, end_addr);
299 char *
p = strtok_r(
str,
"\n", &extern_tok);
300 for (;
p;
p = strtok_r(
NULL,
"\n", &extern_tok)) {
301 if (strstr(
p, identity)) {
302 pp = strtok_r(
NULL,
"\n", &extern_tok);
303 for (; pp; pp = strtok_r(
NULL,
"\n", &extern_tok)) {
304 if ((keyw = isAnonymousKeyword(pp))) {
305 bool is_anonymous = getAnonymousValue(keyw);
319 char *
p, *pp, *ppp, *extern_tok, *flags_str =
NULL;
323 ut8 vmflags = 0, perms =
entry->perms;
339 pp = strtok_r(aux,
"\n", &extern_tok);
340 for (; pp; pp = strtok_r(
NULL,
"\n", &extern_tok)) {
341 if (strstr(pp, identity)) {
342 ppp = strtok_r(
NULL,
"\n", &extern_tok);
343 for (; ppp; ppp = strtok_r(
NULL,
"\n", &extern_tok)) {
344 if ((flags_str = strstr(ppp,
"VmFlags:"))) {
352 if (
entry->file_backed) {
361 if (!flags_str || !
found) {
363 if (
entry->kernel_mapping) {
367 if (perms & !
entry->shared) {
376 if (perms &
entry->shared) {
386 flags_str = strchr(flags_str,
' ');
390 while (*flags_str++ ==
' ') {
394 p = strtok(flags_str,
" ");
396 if (!strncmp(
p,
"sh", 2)) {
399 if (!strncmp(
p,
"io", 2)) {
402 if (!strncmp(
p,
"ht", 2)) {
405 if (!strncmp(
p,
"dd", 2)) {
408 p = strtok(
NULL,
" ");
420 if (
entry->kernel_mapping) {
475 bool is_anonymous =
false, is_deleted =
false, ret = 0;
477 size_t size_file = 0;
505 pmentry->
name = strncmp(
map->name,
"unk", strlen(
"unk"))
512 if (pmentry->
name && is_a_kernel_mapping(pmentry->
name)) {
516 is_anonymous = has_map_anonymous_content(buff_smaps, pmentry->
start_addr, pmentry->
end_addr);
517 if (!is_anonymous && pmentry->
name) {
518 is_anonymous = is_deleted = has_map_deleted_part(pmentry->
name);
525 pmentry->
dumpeable = dump_this_map(buff_smaps, pmentry, filter_flags);
526 eprintf(fmt_addr
" - anonymous: %d, kernel_mapping: %d, file_backed: %d, dumpeable: %d\n",
536 mapping_file.
count++;
541 mapping_file.
size +=
sizeof(
unsigned long) * 2;
566 auxv_entries =
size /
sizeof(elf_auxv_t);
567 if (auxv_entries > 0) {
585 static elf_hdr_t *build_elf_hdr(
int n_segments) {
594 ph_offset = ELF_HDR_SIZE;
595 ph_size =
sizeof(elf_phdr_t);
600 #if __x86_64__ || __arm64__
602 #elif __i386__ || __arm__
611 h->e_ident[pad_byte] =
'\0';
625 h->e_ehsize = ELF_HDR_SIZE;
626 h->e_phoff = ph_offset;
627 h->e_phentsize = ph_size;
633 h->e_shentsize = 0x0;
642 for (n_entries = 0,
p = me_head;
p;
p =
p->n) {
645 *maps_size +=
p->end_addr -
p->start_addr;
652 static bool dump_elf_header(
RzBuffer *
dest, elf_hdr_t *hdr) {
657 char *maps_data, *pp;
659 unsigned long n_pag, n_segments;
665 n_segments = mapping_file.
count;
671 memcpy(maps_data, &n_segments,
sizeof(n_segments));
672 memcpy(maps_data +
sizeof(n_segments), &n_pag,
sizeof(n_pag));
673 pp +=
sizeof(n_segments) +
sizeof(n_pag);
676 if (
p->file_backed && !is_a_kernel_mapping(
p->name)) {
677 memcpy(pp, &
p->start_addr,
sizeof(
p->start_addr));
678 pp +=
sizeof(
p->start_addr);
679 memcpy(pp, &
p->end_addr,
sizeof(
p->end_addr));
680 pp +=
sizeof(
p->end_addr);
681 memcpy(pp, &
p->offset,
sizeof(
p->offset));
682 pp +=
sizeof(
p->offset);
686 if (
p->file_backed && !is_a_kernel_mapping(
p->name)) {
687 strncpy(pp,
p->name,
size - (pp - maps_data));
688 pp += strlen(
p->name) + 1;
696 elf_offset_t offset_to_next;
706 phdr.p_filesz = note_section_size;
714 offset_to_next = *
offset + note_section_size;
717 for (me_p =
maps; me_p; me_p = me_p->
n) {
722 phdr.p_flags = me_p->
perms;
726 phdr.p_filesz = me_p->
dumpeable == 0 ? 0 : phdr.p_memsz;
727 phdr.p_offset = offset_to_next;
729 offset_to_next += phdr.p_filesz == 0 ? 0 : phdr.p_filesz;
734 memset(&phdr,
'\0',
sizeof(elf_phdr_t));
741 static bool dump_elf_note(
RzBuffer *
dest,
void *note_data,
size_t note_section_size) {
751 eprintf(
"dump_elf_map_content starting\n\n");
757 size =
p->end_addr -
p->start_addr;
768 eprintf(
"rz_buf_append_bytes - failed\n");
773 eprintf(
"dump_elf_map_content - done\n");
779 char *temp_p_uid, *temp_p_gid, *p_uid, *p_gid;
780 ut16 filter_flags, default_filter_flags = 0x33;
800 long unsigned int no_lui;
803 sscanf(buff,
"%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu"
804 "%lu %lu %ld %ld %ld %ld %ld",
805 &
p->pid, no_str, &
p->s_name, &
p->ppid, &
p->pgrp, &no_num,
806 &no_num, &
p->sid, &
p->flag, &no_lui, &no_lui, &no_lui,
807 &no_lui, &no_lui, &no_lui, &no_li, &no_li,
808 &no_li, &
p->nice, &
p->num_threads);
811 if (!
p->num_threads ||
p->num_threads < 1) {
813 eprintf(
"Warning: number of threads is < 1\n");
822 temp_p_uid = strstr(buff,
"Uid:");
823 temp_p_gid = strstr(buff,
"Gid:");
829 p_uid = temp_p_uid - 1;
833 p_uid[temp_p_uid - p_uid - 1] =
'\0';
837 p->uid = p_uid ? atoi(p_uid) : 0;
844 p_gid = temp_p_gid - 1;
848 p_gid[temp_p_gid - p_gid - 1] =
'\0';
852 p->gid = p_gid ? atoi(p_gid) : 0;
859 sscanf(buff,
"%hx", &filter_flags);
860 p->coredump_filter = filter_flags;
864 p->coredump_filter = default_filter_flags;
872 clean_maps(elf_proc_note->
maps);
880 static elf_shdr_t *get_extra_sectionhdr(elf_hdr_t *elf_hdr,
st64 offset,
int n_segments) {
881 elf_shdr_t *shdr =
RZ_NEW0(elf_shdr_t);
885 elf_hdr->e_shoff =
offset;
886 elf_hdr->e_shentsize =
sizeof(elf_shdr_t);
887 elf_hdr->e_shnum = 1;
890 shdr->sh_size = elf_hdr->e_shnum;
891 shdr->sh_link = elf_hdr->e_shstrndx;
892 shdr->sh_info = n_segments + 1;
896 static bool dump_elf_sheader_pxnum(
RzBuffer *
dest, elf_shdr_t *shdr) {
901 static elf_fpxregset_t *linux_get_fpx_regset(
RzDebug *
dbg,
int tid) {
902 #ifdef PTRACE_GETREGSET
903 struct iovec transfer;
904 elf_fpxregset_t *fpxregset =
RZ_NEW0(elf_fpxregset_t);
906 transfer.iov_base = fpxregset;
907 transfer.iov_len =
sizeof(elf_fpxregset_t);
908 if (rz_debug_ptrace(
dbg, PTRACE_GETREGSET, tid, (
void *)
NT_PRXFPREG, &transfer) < 0) {
909 perror(
"linux_get_fpx_regset");
920 #if __i386__ || __x86_64__
922 #ifdef PTRACE_GETREGSET
923 struct iovec transfer;
928 transfer.iov_base = xsave_data;
929 transfer.iov_len =
size;
941 #if __arm__ || __arm64__
942 void *linux_get_arm_vfp_data(
RzDebug *
dbg,
int tid) {
943 #ifdef PTRACE_GETVFPREGS
944 char *vfp_data =
calloc(ARM_VFPREGS_SIZE + 1, 1);
949 if (rz_debug_ptrace(
dbg, PTRACE_GETVFPREGS, tid, 0, vfp_data) < 0) {
950 perror(
"linux_get_arm_vfp_data");
963 static size_t size_note_hdr =
sizeof(elf_nhdr_t);
969 nhdr.n_descsz = note_info[
type].
size;
973 nhdr.n_descsz = note_info[
type].
size;
977 nhdr.n_descsz = note_info[
type].
size;
981 nhdr.n_descsz = note_info[
type].
size;
985 nhdr.n_descsz = note_info[
type].
size;
990 nhdr.n_descsz = note_info[
type].
size;
995 nhdr.n_descsz = note_info[
type].
size;
997 #if __i386__ || __x86_64__
998 case NT_X86_XSTATE_T:
1000 nhdr.n_descsz = note_info[
type].
size;
1002 #elif __arm__ || __arm64__
1005 nhdr.n_descsz = note_info[
type].
size;
1010 memset(*note_data, 0, size_note_hdr);
1014 nhdr.n_type = note_type;
1016 nhdr.n_namesz =
sizeof(
"LINUX");
1018 nhdr.n_namesz =
sizeof(
"CORE");
1021 memcpy(*note_data, (
void *)&nhdr, size_note_hdr);
1022 *note_data += size_note_hdr;
1025 static int *get_unique_thread_id(
RzDebug *
dbg,
int n_threads) {
1029 int *thread_id =
NULL;
1038 thread_id =
calloc(
sizeof(
int), n_threads);
1042 rz_list_foreach (
list, it, th) {
1045 for (j = 0; j <
i && !
found; j++) {
1046 if (th->
pid == thread_id[j]) {
1053 thread_id[
i] = th->
pid;
1057 perror(
"Could not attach to thread");
1070 void detach_threads(
RzDebug *
dbg,
int *thread_id,
int n_threads) {
1072 for (
i = 0;
i < n_threads;
i++) {
1073 if (
dbg->
pid != thread_id[
i]) {
1075 perror(
"PTRACE_DETACH");
1082 ut8 *note_data, *pnote_data;
1084 int i, n_notes = 0, *thread_id;
1088 bool fpx_flag =
false;
1090 #if __i386__ || __x86_64__
1091 bool xsave_flag =
false;
1092 #elif __arm__ || __arm64__
1093 bool vfp_flag =
false;
1096 maps_data = get_ntfile_data(elf_proc_note->
maps);
1101 thread_id = get_unique_thread_id(
dbg, elf_proc_note->
n_threads);
1139 type = NT_PRXFPREG_T;
1147 #if __i386__ || __x86_64__
1148 type = NT_X86_XSTATE_T;
1156 #if __arm__ || __arm64__
1157 type = NT_ARM_VFP_T;
1166 size += round_up(n_notes *
sizeof(elf_nhdr_t));
1167 *section_size =
size;
1176 pnote_data = note_data;
1179 write_note_hdr(
type, ¬e_data);
1197 thread_id[
i], proc_data,
1208 elf_proc_note->
thread_note->fpx_regset = linux_get_fpx_regset(
dbg, thread_id[
i]);
1214 #if __i386__ || __x86_64__
1216 elf_proc_note->
thread_note->xsave_data = linux_get_xsave_data(
dbg, thread_id[
i],
1217 note_info[NT_X86_XSTATE_T].
size);
1222 #elif __arm__ || __arm64__
1224 elf_proc_note->
thread_note->arm_vfp_data = linux_get_arm_vfp_data(
dbg, thread_id[
i]);
1231 write_note_hdr(
type, ¬e_data);
1238 write_note_hdr(
type, ¬e_data);
1245 type = NT_PRXFPREG_T;
1246 write_note_hdr(
type, ¬e_data);
1255 write_note_hdr(
type, ¬e_data);
1261 #if __arm__ || __arm64
1263 type = NT_ARM_VFP_T;
1264 write_note_hdr(
type, ¬e_data);
1273 #if __i386__ || __x86_64__
1275 type = NT_X86_XSTATE_T;
1276 write_note_hdr(
type, ¬e_data);
1291 write_note_hdr(
type, ¬e_data);
1298 write_note_hdr(
type, ¬e_data);
1304 detach_threads(
dbg, thread_id, elf_proc_note->
n_threads);
1316 #if __i386__ || __x86_64__
1318 #elif __arm__ || __arm64__
1328 #if __i386__ || __x86_64__
1330 #ifdef PTRACE_GETREGSET
1332 unsigned long xstate_hdr[XSTATE_HDR_SIZE /
sizeof(
unsigned long)];
1337 local.iov_base = xstate_hdr;
1338 local.iov_len =
sizeof(xstate_hdr);
1343 xcr0 = xstate_hdr[XCR0_OFFSET /
sizeof(
unsigned long)];
1345 case XSTATE_SSE_MASK:
1346 return XSTATE_SSE_SIZE;
1347 case XSTATE_AVX_MASK:
1348 return XSTATE_AVX_SIZE;
1349 case XSTATE_MPX_MASK:
1350 return XSTATE_MPX_SIZE;
1351 case XSTATE_AVX512_MASK:
1352 return XSTATE_FULL_SIZE;
1363 static int get_i386_fpx_size(
void) {
1364 #ifdef PTRACE_GETREGSET
1365 return sizeof(elf_fpxregset_t);
1372 #if __arm__ || __arm64__
1373 static int get_arm_vfpregs_size(
void) {
1374 #ifdef PTRACE_GETVFPREGS
1375 return ARM_VFPREGS_SIZE;
1382 static void init_note_info_structure(
RzDebug *
dbg,
int pid,
size_t auxv_size) {
1384 int len_name_core = round_up(strlen(
"CORE") + 1);
1385 int len_name_linux = round_up(strlen(
"LINUX") + 1);
1389 note_info[
type].
size =
sizeof(prpsinfo_t);
1407 note_info[
type].
size =
sizeof(prstatus_t);
1413 note_info[
type].
size =
sizeof(siginfo_t);
1419 note_info[
type].
size =
sizeof(elf_fpregset_t);
1424 type = NT_PRXFPREG_T;
1425 note_info[
type].
size = get_i386_fpx_size();
1431 #if __x86_64__ || __i386__
1433 type = NT_X86_XSTATE_T;
1438 #elif __arm__ || __arm64__
1440 type = NT_ARM_VFP_T;
1441 note_info[
type].
size = get_arm_vfpregs_size();
1451 elf_shdr_t *shdr_pxnum =
NULL;
1452 elf_hdr_t *elf_hdr =
NULL;
1453 void *note_data =
NULL;
1455 size_t note_section_size, maps_size = 0;
1461 if (!elf_proc_note) {
1466 free(elf_proc_note);
1471 free(elf_proc_note);
1485 elf_proc_note->
auxv = linux_get_auxv(
dbg);
1486 if (!elf_proc_note->
auxv) {
1492 if (!elf_proc_note->
maps) {
1496 n_segments = get_info_mappings(elf_proc_note->
maps, &maps_size);
1499 note_data = build_note_section(
dbg, elf_proc_note, proc_data, ¬e_section_size);
1505 elf_hdr = build_elf_hdr(n_segments);
1513 if (elf_hdr->e_phnum ==
PN_XNUM) {
1514 elf_offset_t offset_shdr;
1517 offset_shdr = hdr_size + (elf_hdr->e_phnum * elf_hdr->e_phentsize) + note_section_size + maps_size;
1518 shdr_pxnum = get_extra_sectionhdr(elf_hdr, offset_shdr, n_segments);
1520 (void)dump_elf_header(
dest, elf_hdr);
1522 offset = hdr_size + (elf_hdr->e_phnum * elf_hdr->e_phentsize);
1525 (void)dump_elf_pheaders(
dest, elf_proc_note->
maps, &
offset, note_section_size);
1526 (void)dump_elf_note(
dest, note_data, note_section_size);
1528 if (elf_hdr->e_phnum ==
PN_XNUM) {
1529 (void)dump_elf_sheader_pxnum(
dest, shdr_pxnum);
1532 may_clean_all(elf_proc_note, proc_data, elf_hdr);
static RzList * maps(RzBinFile *bf)
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags long
RZ_API bool rz_debug_map_sync(RzDebug *dbg)
size_t map(int syms, int left, int len)
RZ_API char * sdb_fmt(const char *fmt,...)
RZ_API void Ht_() free(HtName_(Ht) *ht)
RZ_API const KEY_TYPE bool * found
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static void list(RzEgg *egg)
void * malloc(size_t size)
void * calloc(size_t number, size_t size)
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc pid
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
bool linux_generate_corefile(RzDebug *dbg, RzBuffer *dest)
#define SIZE_NT_FILE_DESCSZ
long rz_debug_ptrace_get_x86_xstate(RzDebug *dbg, pid_t pid, struct iovec *iov)
RZ_API bool rz_buf_append_bytes(RZ_NONNULL RzBuffer *b, RZ_NONNULL const ut8 *buf, ut64 len)
Append an array of bytes to the buffer.
RZ_API const char * rz_file_basename(const char *path)
RZ_API RZ_OWN char * rz_file_slurp(const char *str, RZ_NULLABLE size_t *usz)
RZ_API void * rz_mem_dup(const void *s, int l)
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
struct linux_map_entry * n
proc_per_process_t * per_process
proc_per_thread_t * per_thread
thread_elf_note_t * thread_note
unsigned char coredump_filter
RzList *(* threads)(RzDebug *dbg, int pid)
struct rz_debug_plugin_t * cur
elf_fpregset_t * fp_regset
void error(const char *msg)
if(dbg->bits==RZ_SYS_BITS_64)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()