mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-11-14 02:03:27 -08:00
linux/demon flattening / clean-up checkpoint - eliminate redundant helpers, single-use functions, obsolete code
This commit is contained in:
1 parent
7388b757d1
commit
8c2efc5adf
9 files changed
+1078
-1112
No files matched your search
@@ -0,0 +1,54 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
internal LNX_DMN_Process *
|
||||
lnx_dmn_event_attach(Arena *arena, DMN_EventList *events, pid_t pid)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
|
||||
// create process
|
||||
LNX_DMN_Process *process = lnx_dmn_event_create_process(arena, events, pid, 0, LNX_DMN_CreateProcessFlag_DebugSubprocesses|LNX_DMN_CreateProcessFlag_Rebased);
|
||||
|
||||
// extract threads from /proc/pid/task
|
||||
{
|
||||
String8 task_path = str8f(scratch.arena, "/proc/%d/task", pid);
|
||||
DIR *task_dirp = opendir((char *)task_path.str);
|
||||
if(task_dirp)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
struct dirent *dirent = readdir(task_dirp);
|
||||
if(dirent == 0) { break; }
|
||||
|
||||
String8 tid_str = str8_cstring_capped(dirent->d_name, dirent->d_name + NAME_MAX);
|
||||
if(str8_match(tid_str, str8_lit(".."), 0) || str8_match(tid_str, str8_lit("."), 0)) { continue; }
|
||||
U64 tid_64 = u64_from_str8(tid_str, 10);
|
||||
pid_t tid = (pid_t)tid_64;
|
||||
AssertAlways(tid == tid_64);
|
||||
|
||||
if(tid == pid) { continue; } // main thread was created during create process sequence
|
||||
lnx_dmn_event_create_thread(arena, events, process, tid);
|
||||
}
|
||||
|
||||
LNX_RETRY_ON_EINTR(closedir(task_dirp));
|
||||
}
|
||||
}
|
||||
|
||||
// extract modules from r_debug
|
||||
{
|
||||
B32 is_64bit = process->ctx->dl_class == ELF_Class_64;
|
||||
GNU_RDebugInfoList rdebug_list = gnu_parse_rdebug(scratch.arena, is_64bit, process->ctx->rdebug_vaddr, lnx_dmn_machine_op_mem_read, &process->fd);
|
||||
U64 name_space_id = 0;
|
||||
for EachNode(rdebug_n, GNU_RDebugInfoNode, rdebug_list.first)
|
||||
{
|
||||
lnx_dmn_event_load_module(arena, events, process->first_thread, name_space_id, rdebug_n->v.r_map);
|
||||
name_space_id += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// handshake complete
|
||||
lnx_dmn_push_event_handshake_complete(arena, events, process);
|
||||
|
||||
scratch_end(scratch);
|
||||
return process;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
//- GENERATED CODE
|
||||
|
||||
C_LINKAGE_BEGIN
|
||||
U8 lnx_dmn_probe_kind_args_count_table[12] =
|
||||
{
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
3,
|
||||
2,
|
||||
3,
|
||||
2,
|
||||
2,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
};
|
||||
|
||||
String8 lnx_dmn_probe_kind_string_table[12] =
|
||||
{
|
||||
{0},
|
||||
str8_lit_comp("init_start"),
|
||||
str8_lit_comp("init_complete"),
|
||||
str8_lit_comp("reloc_start"),
|
||||
str8_lit_comp("reloc_complete"),
|
||||
str8_lit_comp("map_start"),
|
||||
str8_lit_comp("map_complete"),
|
||||
str8_lit_comp("unmap_start"),
|
||||
str8_lit_comp("unmap_complete"),
|
||||
str8_lit_comp("longjmp"),
|
||||
str8_lit_comp("longjmp_target"),
|
||||
str8_lit_comp("setjmp"),
|
||||
};
|
||||
|
||||
C_LINKAGE_END
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
//- GENERATED CODE
|
||||
|
||||
#ifndef LINUX_DEMON_META_H
|
||||
#define LINUX_DEMON_META_H
|
||||
|
||||
typedef enum LNX_DMN_ProbeKind
|
||||
{
|
||||
LNX_DMN_ProbeKind_Null,
|
||||
LNX_DMN_ProbeKind_InitStart,
|
||||
LNX_DMN_ProbeKind_InitComplete,
|
||||
LNX_DMN_ProbeKind_RelocStart,
|
||||
LNX_DMN_ProbeKind_RelocComplete,
|
||||
LNX_DMN_ProbeKind_MapStart,
|
||||
LNX_DMN_ProbeKind_MapComplete,
|
||||
LNX_DMN_ProbeKind_UnmapStart,
|
||||
LNX_DMN_ProbeKind_UnmapComplete,
|
||||
LNX_DMN_ProbeKind_LongJmp,
|
||||
LNX_DMN_ProbeKind_LongJmpTarget,
|
||||
LNX_DMN_ProbeKind_SetJmp,
|
||||
LNX_DMN_ProbeKind_COUNT,
|
||||
} LNX_DMN_ProbeKind;
|
||||
|
||||
C_LINKAGE_BEGIN
|
||||
extern U8 lnx_dmn_probe_kind_args_count_table[12];
|
||||
extern String8 lnx_dmn_probe_kind_string_table[12];
|
||||
|
||||
C_LINKAGE_END
|
||||
|
||||
#endif // LINUX_DEMON_META_H
|
||||
+778
-951
File diff suppressed because it is too large.
Load diff
+117
-141
@@ -4,6 +4,18 @@
|
||||
#ifndef LINUX_DEMON_H
|
||||
#define LINUX_DEMON_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Linux Includes
|
||||
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/uio.h>
|
||||
#include <elf.h>
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Generated Code
|
||||
|
||||
#include "generated/linux_demon.meta.h"
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Register Layouts
|
||||
//
|
||||
@@ -62,22 +74,25 @@ struct LNX_DMN_UserX64
|
||||
U8 u_comm[32];
|
||||
U64 u_debugreg[8];
|
||||
};
|
||||
|
||||
StaticAssert(sizeof(LNX_DMN_UserX64) == 912, lnx_user_x64_size_check);
|
||||
|
||||
////////////////////////////////
|
||||
//~ TLS
|
||||
//~ rjf: TLS Descriptions
|
||||
|
||||
typedef struct LNX_DMN_DbDesc
|
||||
typedef struct LNX_DMN_DbDesc LNX_DMN_DbDesc;
|
||||
struct LNX_DMN_DbDesc
|
||||
{
|
||||
U32 bit_size;
|
||||
U32 count;
|
||||
U32 offset;
|
||||
} LNX_DMN_DbDesc;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ SDT Probes
|
||||
//~ rjf: SDT (Statically-Defined Tracing) Probes
|
||||
|
||||
typedef struct LNX_DMN_Probe
|
||||
typedef struct LNX_DMN_Probe LNX_DMN_Probe;
|
||||
struct LNX_DMN_Probe
|
||||
{
|
||||
String8 provider;
|
||||
String8 name;
|
||||
@@ -85,47 +100,28 @@ typedef struct LNX_DMN_Probe
|
||||
STAP_ArgArray args;
|
||||
U64 pc;
|
||||
U64 semaphore;
|
||||
} LNX_DMN_Probe;
|
||||
};
|
||||
|
||||
typedef struct LNX_DMN_ProbeNode
|
||||
typedef struct LNX_DMN_ProbeNode LNX_DMN_ProbeNode;
|
||||
struct LNX_DMN_ProbeNode
|
||||
{
|
||||
LNX_DMN_ProbeNode *next;
|
||||
LNX_DMN_Probe v;
|
||||
struct LNX_DMN_ProbeNode *next;
|
||||
} LNX_DMN_ProbeNode;
|
||||
};
|
||||
|
||||
typedef struct LNX_DMN_ProbeList
|
||||
typedef struct LNX_DMN_ProbeList LNX_DMN_ProbeList;
|
||||
struct LNX_DMN_ProbeList
|
||||
{
|
||||
U64 count;
|
||||
LNX_DMN_ProbeNode *first;
|
||||
LNX_DMN_ProbeNode *last;
|
||||
} LNX_DMN_ProbeList;
|
||||
|
||||
#define LNX_DMN_Probe_XList \
|
||||
X(InitStart, 2, "init_start") \
|
||||
X(InitComplete, 2, "init_complete") \
|
||||
X(RelocStart, 2, "reloc_start") \
|
||||
X(RelocComplete, 3, "reloc_complete") \
|
||||
X(MapStart, 2, "map_start") \
|
||||
X(MapComplete, 3, "map_complete") \
|
||||
X(UnmapStart, 2, "unmap_start") \
|
||||
X(UnmapComplete, 2, "unmap_complete") \
|
||||
X(LongJmp, 3, "longjmp") \
|
||||
X(LongJmpTarget, 3, "longjmp_target") \
|
||||
X(SetJmp, 3, "setjmp")
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LNX_DMN_ProbeType_Null,
|
||||
#define X(_N,...) LNX_DMN_ProbeType_##_N,
|
||||
LNX_DMN_Probe_XList
|
||||
#undef X
|
||||
LNX_DMN_ProbeType_Count,
|
||||
} LNX_DMN_ProbeType;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ Process Info
|
||||
//~ rjf: Process Info
|
||||
|
||||
typedef struct LNX_DMN_Auxv
|
||||
typedef struct LNX_DMN_Auxv LNX_DMN_Auxv;
|
||||
struct LNX_DMN_Auxv
|
||||
{
|
||||
U64 base;
|
||||
U64 phnum;
|
||||
@@ -133,9 +129,10 @@ typedef struct LNX_DMN_Auxv
|
||||
U64 phdr;
|
||||
U64 execfn;
|
||||
U64 pagesz;
|
||||
} LNX_DMN_Auxv;
|
||||
};
|
||||
|
||||
typedef struct LNX_DMN_DynamicInfo
|
||||
typedef struct LNX_DMN_DynamicInfo LNX_DMN_DynamicInfo;
|
||||
struct LNX_DMN_DynamicInfo
|
||||
{
|
||||
U64 hash_vaddr;
|
||||
U64 gnu_hash_vaddr;
|
||||
@@ -143,10 +140,10 @@ typedef struct LNX_DMN_DynamicInfo
|
||||
U64 strtab_size;
|
||||
U64 symtab_vaddr;
|
||||
U64 symtab_entry_size;
|
||||
} LNX_DMN_DynamicInfo;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ Entities
|
||||
//~ rjf: Entities
|
||||
|
||||
typedef enum LNX_DMN_EntityKind
|
||||
{
|
||||
@@ -155,7 +152,8 @@ typedef enum LNX_DMN_EntityKind
|
||||
LNX_DMN_EntityKind_ProcessCtx,
|
||||
LNX_DMN_EntityKind_Thread,
|
||||
LNX_DMN_EntityKind_Module,
|
||||
} LNX_DMN_EntityKind;
|
||||
}
|
||||
LNX_DMN_EntityKind;
|
||||
|
||||
typedef enum LNX_DMN_ThreadState
|
||||
{
|
||||
@@ -164,10 +162,14 @@ typedef enum LNX_DMN_ThreadState
|
||||
LNX_DMN_ThreadState_Stopped,
|
||||
LNX_DMN_ThreadState_Exited,
|
||||
LNX_DMN_ThreadState_PendingCreation,
|
||||
} LNX_DMN_ThreadState;
|
||||
}
|
||||
LNX_DMN_ThreadState;
|
||||
|
||||
typedef struct LNX_DMN_Thread
|
||||
typedef struct LNX_DMN_Thread LNX_DMN_Thread;
|
||||
struct LNX_DMN_Thread
|
||||
{
|
||||
LNX_DMN_Thread *next;
|
||||
LNX_DMN_Thread *prev;
|
||||
pid_t tid;
|
||||
LNX_DMN_ThreadState state;
|
||||
struct LNX_DMN_Process *process;
|
||||
@@ -177,27 +179,29 @@ typedef struct LNX_DMN_Thread
|
||||
U64 pass_through_signo;
|
||||
U64 orig_rax;
|
||||
U64 dtv_base_vaddr;
|
||||
};
|
||||
|
||||
struct LNX_DMN_Thread *next;
|
||||
struct LNX_DMN_Thread *prev;
|
||||
} LNX_DMN_Thread;
|
||||
|
||||
typedef struct LNX_DMN_ThreadPtrNode
|
||||
typedef struct LNX_DMN_ThreadPtrNode LNX_DMN_ThreadPtrNode;
|
||||
struct LNX_DMN_ThreadPtrNode
|
||||
{
|
||||
LNX_DMN_ThreadPtrNode *next;
|
||||
LNX_DMN_ThreadPtrNode *prev;
|
||||
LNX_DMN_Thread *v;
|
||||
struct LNX_DMN_ThreadPtrNode *next;
|
||||
struct LNX_DMN_ThreadPtrNode *prev;
|
||||
} LNX_DMN_ThreadPtrNode;
|
||||
};
|
||||
|
||||
typedef struct LNX_DMN_ThreadPtrList
|
||||
typedef struct LNX_DMN_ThreadPtrList LNX_DMN_ThreadPtrList;
|
||||
struct LNX_DMN_ThreadPtrList
|
||||
{
|
||||
U64 count;
|
||||
LNX_DMN_ThreadPtrNode *first;
|
||||
LNX_DMN_ThreadPtrNode *last;
|
||||
} LNX_DMN_ThreadPtrList;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct LNX_DMN_Module
|
||||
typedef struct LNX_DMN_Module LNX_DMN_Module;
|
||||
struct LNX_DMN_Module
|
||||
{
|
||||
LNX_DMN_Module *next;
|
||||
LNX_DMN_Module *prev;
|
||||
U64 name_vaddr;
|
||||
U64 base_vaddr;
|
||||
U64 name_space_id;
|
||||
@@ -209,25 +213,24 @@ typedef struct LNX_DMN_Module
|
||||
U64 tls_offset;
|
||||
B8 is_live;
|
||||
B8 is_main;
|
||||
};
|
||||
|
||||
struct LNX_DMN_Module *next;
|
||||
struct LNX_DMN_Module *prev;
|
||||
} LNX_DMN_Module;
|
||||
|
||||
typedef struct LNX_DMN_ModulePtrNode
|
||||
typedef struct LNX_DMN_ModulePtrNode LNX_DMN_ModulePtrNode;
|
||||
struct LNX_DMN_ModulePtrNode
|
||||
{
|
||||
LNX_DMN_ModulePtrNode *next;
|
||||
LNX_DMN_Module *v;
|
||||
struct LNX_DMN_ModulePtrNode *next;
|
||||
} LNX_DMN_ModulePtrNode;
|
||||
};
|
||||
|
||||
typedef struct LNX_DMN_ModulePtrList
|
||||
typedef struct LNX_DMN_ModulePtrList LNX_DMN_ModulePtrList;
|
||||
struct LNX_DMN_ModulePtrList
|
||||
{
|
||||
U64 count;
|
||||
LNX_DMN_ModulePtrNode *first;
|
||||
LNX_DMN_ModulePtrNode *last;
|
||||
} LNX_DMN_ModulePtrList;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
typedef enum LNX_DMN_ProcessState
|
||||
{
|
||||
LNX_DMN_ProcessState_Null,
|
||||
LNX_DMN_ProcessState_Launch,
|
||||
@@ -235,18 +238,25 @@ typedef enum
|
||||
LNX_DMN_ProcessState_WaitForExec,
|
||||
LNX_DMN_ProcessState_ExecFailedDoExit,
|
||||
LNX_DMN_ProcessState_Normal,
|
||||
} LNX_DMN_ProcessState;
|
||||
}
|
||||
LNX_DMN_ProcessState;
|
||||
|
||||
typedef enum
|
||||
typedef enum LNX_DMN_CreateProcessFlags
|
||||
{
|
||||
LNX_DMN_CreateProcessFlag_DebugSubprocesses = (1 << 0),
|
||||
LNX_DMN_CreateProcessFlag_Rebased = (1 << 1),
|
||||
LNX_DMN_CreateProcessFlag_Cow = (1 << 2),
|
||||
LNX_DMN_CreateProcessFlag_ClonedMemory = (1 << 3),
|
||||
} LNX_DMN_CreateProcessFlags;
|
||||
}
|
||||
LNX_DMN_CreateProcessFlags;
|
||||
|
||||
typedef struct LNX_DMN_Process
|
||||
typedef struct LNX_DMN_Process LNX_DMN_Process;
|
||||
struct LNX_DMN_Process
|
||||
{
|
||||
LNX_DMN_Process *parent_process;
|
||||
struct LNX_DMN_ProcessCtx *ctx;
|
||||
LNX_DMN_Process *next;
|
||||
LNX_DMN_Process *prev;
|
||||
pid_t pid;
|
||||
int fd;
|
||||
LNX_DMN_ProcessState state;
|
||||
@@ -257,26 +267,22 @@ typedef struct LNX_DMN_Process
|
||||
LNX_DMN_Thread *first_thread;
|
||||
LNX_DMN_Thread *last_thread;
|
||||
U64 main_thread_exit_code;
|
||||
struct LNX_DMN_Process *parent_process;
|
||||
struct LNX_DMN_ProcessCtx *ctx;
|
||||
};
|
||||
|
||||
|
||||
struct LNX_DMN_Process *next;
|
||||
struct LNX_DMN_Process *prev;
|
||||
} LNX_DMN_Process;
|
||||
|
||||
typedef struct LNX_DMN_ProcessPtrNode
|
||||
typedef struct LNX_DMN_ProcessPtrNode LNX_DMN_ProcessPtrNode;
|
||||
struct LNX_DMN_ProcessPtrNode
|
||||
{
|
||||
LNX_DMN_ProcessPtrNode *next;
|
||||
LNX_DMN_Process *v;
|
||||
struct LNX_DMN_ProcessPtrNode *next;
|
||||
} LNX_DMN_ProcessPtrNode;
|
||||
};
|
||||
|
||||
typedef struct LNX_DMN_ProcessPtrList
|
||||
typedef struct LNX_DMN_ProcessPtrList LNX_DMN_ProcessPtrList;
|
||||
struct LNX_DMN_ProcessPtrList
|
||||
{
|
||||
U64 count;
|
||||
LNX_DMN_ProcessPtrNode *first;
|
||||
LNX_DMN_ProcessPtrNode *last;
|
||||
} LNX_DMN_ProcessPtrList;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct LNX_DMN_ActiveTrap LNX_DMN_ActiveTrap;
|
||||
struct LNX_DMN_ActiveTrap
|
||||
@@ -287,7 +293,8 @@ struct LNX_DMN_ActiveTrap
|
||||
String8 swap_bytes;
|
||||
};
|
||||
|
||||
typedef struct LNX_DMN_ProcessCtx
|
||||
typedef struct LNX_DMN_ProcessCtx LNX_DMN_ProcessCtx;
|
||||
struct LNX_DMN_ProcessCtx
|
||||
{
|
||||
Arena *arena;
|
||||
Arch arch;
|
||||
@@ -301,7 +308,6 @@ typedef struct LNX_DMN_ProcessCtx
|
||||
LNX_DMN_Module *last_module;
|
||||
U64 module_count;
|
||||
U64 ref_count;
|
||||
|
||||
String8List free_reg_blocks;
|
||||
String8List free_reg_block_nodes;
|
||||
|
||||
@@ -309,9 +315,10 @@ typedef struct LNX_DMN_ProcessCtx
|
||||
U64 xcr0;
|
||||
U64 xsave_size;
|
||||
X64_XSaveLayout xsave_layout;
|
||||
} LNX_DMN_ProcessCtx;
|
||||
};
|
||||
|
||||
typedef struct LNX_DMN_Entity
|
||||
typedef struct LNX_DMN_Entity LNX_DMN_Entity;
|
||||
struct LNX_DMN_Entity
|
||||
{
|
||||
union
|
||||
{
|
||||
@@ -319,32 +326,32 @@ typedef struct LNX_DMN_Entity
|
||||
LNX_DMN_ProcessCtx process_ctx;
|
||||
LNX_DMN_Thread thread;
|
||||
LNX_DMN_Module module;
|
||||
struct
|
||||
{
|
||||
struct LNX_DMN_Entity *next;
|
||||
};
|
||||
LNX_DMN_Entity *next;
|
||||
};
|
||||
U32 gen;
|
||||
LNX_DMN_EntityKind kind;
|
||||
} LNX_DMN_Entity;
|
||||
};
|
||||
|
||||
typedef struct LNX_DMN_EntityNode
|
||||
typedef struct LNX_DMN_EntityNode LNX_DMN_EntityNode;
|
||||
struct LNX_DMN_EntityNode
|
||||
{
|
||||
LNX_DMN_EntityNode *next;
|
||||
LNX_DMN_Entity *v;
|
||||
struct LNX_DMN_EntityNode *next;
|
||||
} LNX_DMN_EntityNode;
|
||||
};
|
||||
|
||||
typedef struct LNX_DMN_EntityList
|
||||
typedef struct LNX_DMN_EntityList LNX_DMN_EntityList;
|
||||
struct LNX_DMN_EntityList
|
||||
{
|
||||
U64 count;
|
||||
LNX_DMN_EntityNode *first;
|
||||
LNX_DMN_EntityNode *last;
|
||||
} LNX_DMN_EntityList;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ Global State
|
||||
//~ rjf: Top-Level State Bundle
|
||||
|
||||
typedef struct LNX_DMN_State
|
||||
typedef struct LNX_DMN_State LNX_DMN_State;
|
||||
struct LNX_DMN_State
|
||||
{
|
||||
Arena *arena;
|
||||
|
||||
@@ -381,17 +388,18 @@ typedef struct LNX_DMN_State
|
||||
B32 is_tls_detected;
|
||||
LNX_DMN_DbDesc tls_modid_desc;
|
||||
LNX_DMN_DbDesc tls_offset_desc;
|
||||
} LNX_DMN_State;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ Globals
|
||||
//~ rjf: Globals
|
||||
|
||||
global B32 lnx_dmn_ctrl_thread;
|
||||
global LNX_DMN_State *lnx_dmn_state;
|
||||
global LNX_DMN_State *lnx_dmn_state = 0;
|
||||
thread_static B32 lnx_dmn_ctrl_thread = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Memory R/W
|
||||
//~ rjf: Memory R/W Helpers
|
||||
|
||||
internal U64 lnx_dmn_size_from_fd(int memory_fd, U64 cap);
|
||||
internal U64 lnx_dmn_read(int memory_fd, Rng1U64 range, void *dst);
|
||||
internal B32 lnx_dmn_write(int memory_fd, Rng1U64 range, void *src);
|
||||
internal String8 lnx_dmn_read_string_capped(Arena *arena, int memory_fd, U64 base_vaddr, U64 cap_size);
|
||||
@@ -408,16 +416,14 @@ internal LNX_DMN_ActiveTrap *lnx_dmn_set_trap(Arena *arena, DMN_Trap *trap);
|
||||
//~ ELF/GNU info
|
||||
|
||||
internal Rng1U64 lnx_dmn_compute_image_vrange(int memory_fd, ELF_Class elf_class, U64 rebase, U64 e_phaddr, U64 e_phentsize, U64 e_phnum);
|
||||
internal LNX_DMN_DynamicInfo lnx_dmn_dynamic_info_from_memory(int memory_fd, ELF_Class elf_Class, U64 rebase, U64 dynamic_vaddr);
|
||||
internal U64 lnx_dmn_rdebug_vaddr_from_memory(int memory_fd, U64 loader_vaddr, B32 is_rebased);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Process Info
|
||||
//~ rjf: Process Info Parsing Functions
|
||||
|
||||
internal String8 lnx_dmn_exe_path_from_pid(Arena *arena, pid_t pid);
|
||||
internal String8 lnx_dmn_dl_path_from_pid(Arena *arena, pid_t pid, U64 auxv_base);
|
||||
internal ELF_Hdr64 lnx_dmn_ehdr_from_pid(pid_t pid);
|
||||
internal LNX_DMN_Auxv lnx_dmn_auxv_from_pid(pid_t pid, ELF_Class elf_class);
|
||||
|
||||
internal LNX_DMN_Thread * lnx_dmn_thread_from_pid(pid_t pid);
|
||||
internal LNX_DMN_Process * lnx_dmn_process_from_pid(pid_t pid);
|
||||
|
||||
@@ -427,19 +433,17 @@ internal LNX_DMN_Process * lnx_dmn_process_from_pid(pid_t pid);
|
||||
internal DMN_ModuleInfo *lnx_dmn_module_info_from_process_module(Arena *arena, pid_t pid, int memory_fd, U64 base_vaddr, U64 link_map_vaddr, B32 is_main);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Entity
|
||||
//~ rjf: Entity Functions
|
||||
|
||||
// alloc
|
||||
internal LNX_DMN_Entity * lnx_dmn_entity_alloc(LNX_DMN_EntityKind kind);
|
||||
internal LNX_DMN_Process * lnx_dmn_process_alloc(pid_t pid, LNX_DMN_ProcessState state, LNX_DMN_Process *parent_process, B32 debug_subprocess, B32 is_cow);
|
||||
internal LNX_DMN_ProcessCtx * lnx_dmn_process_ctx_alloc(LNX_DMN_Process *process, B32 is_rebased);
|
||||
internal LNX_DMN_Thread * lnx_dmn_thread_alloc(LNX_DMN_Process *process, LNX_DMN_ThreadState thread_state, pid_t tid);
|
||||
internal LNX_DMN_Module * lnx_dmn_module_alloc(LNX_DMN_ProcessCtx *ctx, int memory_fd, U64 base_vaddr, U64 name_vaddr, U64 name_space_id, B32 is_main);
|
||||
|
||||
// release
|
||||
internal void lnx_dmn_entity_release(LNX_DMN_Entity *entity);
|
||||
internal void lnx_dmn_process_release(LNX_DMN_Process *process);
|
||||
internal void lnx_dmn_process_ctx_release(LNX_DMN_ProcessCtx *process_ctx);
|
||||
internal void lnx_dmn_thread_release(LNX_DMN_Thread *thread);
|
||||
internal void lnx_dmn_module_release(LNX_DMN_ProcessCtx *ctx, LNX_DMN_Module *module);
|
||||
|
||||
@@ -450,30 +454,20 @@ internal LNX_DMN_Module * lnx_dmn_module_clone(LNX_DMN_ProcessCtx *process_c
|
||||
// entity -> handle
|
||||
internal DMN_Handle lnx_dmn_handle_from_entity(LNX_DMN_Entity *entity);
|
||||
internal DMN_Handle lnx_dmn_handle_from_process(LNX_DMN_Process *process);
|
||||
internal DMN_Handle lnx_dmn_handle_from_process_ctx(LNX_DMN_ProcessCtx *process_ctx);
|
||||
internal DMN_Handle lnx_dmn_handle_from_thread(LNX_DMN_Thread *thread);
|
||||
internal DMN_Handle lnx_dmn_handle_from_module(LNX_DMN_Module *module);
|
||||
|
||||
// handle -> entity
|
||||
internal LNX_DMN_Entity * lnx_dmn_entity_from_handle(DMN_Handle handle, LNX_DMN_EntityKind expected_kind);
|
||||
internal LNX_DMN_Process * lnx_dmn_process_from_handle(DMN_Handle process_handle);
|
||||
internal LNX_DMN_ProcessCtx * lnx_dmn_process_ctx_from_handle(DMN_Handle process_ctx_handle);
|
||||
internal LNX_DMN_Thread * lnx_dmn_thread_from_handle(DMN_Handle thread_handle);
|
||||
internal LNX_DMN_Module * lnx_dmn_module_from_handle(DMN_Handle module_handle);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Process Helpers
|
||||
|
||||
internal void lnx_dmn_process_trap_probes(LNX_DMN_Process *process);
|
||||
internal void lnx_dmn_process_untrap_probes(LNX_DMN_Process *process);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Thread Helpers
|
||||
|
||||
internal U64 lnx_dmn_thread_read_ip(LNX_DMN_Thread *thread);
|
||||
internal U64 lnx_dmn_thread_read_sp(LNX_DMN_Thread *thread);
|
||||
internal void lnx_dmn_thread_write_ip(LNX_DMN_Thread *thread, U64 ip);
|
||||
internal void lnx_dmn_thread_write_sp(LNX_DMN_Thread *thread, U64 sp);
|
||||
internal B32 lnx_dmn_thread_read_reg_block(LNX_DMN_Thread *thread);
|
||||
internal B32 lnx_dmn_thread_write_reg_block(LNX_DMN_Thread *thread);
|
||||
internal B32 lnx_dmn_set_single_step_flag(LNX_DMN_Thread *thread, B32 is_on);
|
||||
@@ -484,39 +478,21 @@ internal U64 lnx_dmn_tls_root_vaddr_from_reg_block(int fd, Arch arch, void *reg
|
||||
|
||||
internal void lnx_dmn_thread_ptr_list_push_node(LNX_DMN_ThreadPtrList *list, LNX_DMN_ThreadPtrNode *n);
|
||||
internal LNX_DMN_ThreadPtrNode * lnx_dmn_thread_ptr_list_push(Arena *arena, LNX_DMN_ThreadPtrList *list, LNX_DMN_Thread *v);
|
||||
internal void lnx_dmn_thread_ptr_list_remove(LNX_DMN_ThreadPtrList *list, LNX_DMN_ThreadPtrNode *n);
|
||||
internal LNX_DMN_ModulePtrNode * lnx_dmn_module_ptr_list_push(Arena *arena, LNX_DMN_ModulePtrList *list, LNX_DMN_Module *v);
|
||||
internal LNX_DMN_ProcessPtrNode * lnx_dmn_process_ptr_list_push(Arena *arena, LNX_DMN_ProcessPtrList *list, LNX_DMN_Process *v);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Debug Event Pushers
|
||||
|
||||
internal void lnx_dmn_push_event_create_process(Arena *arena, DMN_EventList *events, LNX_DMN_Process *process);
|
||||
internal void lnx_dmn_push_event_exit_process(Arena *arena, DMN_EventList *events, LNX_DMN_Process *process);
|
||||
internal void lnx_dmn_push_event_create_thread(Arena *arena, DMN_EventList *events, LNX_DMN_Thread *thread);
|
||||
internal void lnx_dmn_push_event_exit_thread(Arena *arena, DMN_EventList *events, LNX_DMN_Thread *thread, U64 exit_code);
|
||||
internal void lnx_dmn_push_event_load_module(Arena *arena, DMN_EventList *events, LNX_DMN_Thread *thread, LNX_DMN_Module *module);
|
||||
internal void lnx_dmn_push_event_unload_module(Arena *arena, DMN_EventList *events, LNX_DMN_Process *process, LNX_DMN_Module *module);
|
||||
internal void lnx_dmn_push_event_handshake_complete(Arena *arena, DMN_EventList *events, LNX_DMN_Process *process);
|
||||
internal void lnx_dmn_push_event_breakpoint(Arena *arena, DMN_EventList *events, LNX_DMN_Thread *thread, U64 address);
|
||||
internal void lnx_dmn_push_event_single_step(Arena *arena, DMN_EventList *events, LNX_DMN_Thread *thread);
|
||||
internal void lnx_dmn_push_event_exception(Arena *arena, DMN_EventList *events, LNX_DMN_Thread *thread, U64 signo);
|
||||
internal void lnx_dmn_push_event_halt(Arena *arena, DMN_EventList *events);
|
||||
internal void lnx_dmn_push_event_not_attached(Arena *arena, DMN_EventList *events);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Debug Event
|
||||
|
||||
internal LNX_DMN_Thread * lnx_dmn_event_create_thread(Arena *arena, DMN_EventList *events, LNX_DMN_Process *process, pid_t tid);
|
||||
internal void lnx_dmn_event_exit_thread(Arena *arena, DMN_EventList *events, pid_t tid, U64 exit_code);
|
||||
internal LNX_DMN_Process * lnx_dmn_event_create_process(Arena *arena, DMN_EventList *events, pid_t pid, LNX_DMN_Process *parent_process, LNX_DMN_CreateProcessFlags flags);
|
||||
internal void lnx_dmn_event_exit_process(Arena *arena, DMN_EventList *events, pid_t pid);
|
||||
internal void lnx_dmn_event_load_module(Arena *arena, DMN_EventList *events, LNX_DMN_Thread *thread, U64 name_space_id, U64 new_link_map_vaddr);
|
||||
internal void lnx_dmn_event_unload_module(Arena *arena, DMN_EventList *events, LNX_DMN_Process *process, U64 rdebug_vaddr);
|
||||
internal void lnx_dmn_event_breakpoint(Arena *arena, DMN_EventList *events, LNX_DMN_ActiveTrap *user_traps, pid_t tid);
|
||||
internal void lnx_dmn_event_data_breakpoint(Arena *arena, DMN_EventList *events, pid_t tid);
|
||||
internal void lnx_dmn_event_halt(Arena *arena, DMN_EventList *events);
|
||||
internal void lnx_dmn_event_single_step(Arena *arena, DMN_EventList *events, pid_t tid);
|
||||
internal void lnx_dmn_event_exception(Arena *arena, DMN_EventList *events, pid_t tid, U64 signo);
|
||||
internal LNX_DMN_Process * lnx_dmn_event_attach(Arena *arena, DMN_EventList *events, pid_t pid);
|
||||
|
||||
#endif // LINUX_DEMON_H
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
@table(name args_count string}
|
||||
LNX_DMN_ProbeTable:
|
||||
{
|
||||
{InitStart 2 "init_start"}
|
||||
{InitComplete 2 "init_complete"}
|
||||
{RelocStart 2 "reloc_start"}
|
||||
{RelocComplete 3 "reloc_complete"}
|
||||
{MapStart 2 "map_start"}
|
||||
{MapComplete 3 "map_complete"}
|
||||
{UnmapStart 2 "unmap_start"}
|
||||
{UnmapComplete 2 "unmap_complete"}
|
||||
{LongJmp 3 "longjmp"}
|
||||
{LongJmpTarget 3 "longjmp_target"}
|
||||
{SetJmp 3 "setjmp"}
|
||||
}
|
||||
|
||||
@enum LNX_DMN_ProbeKind:
|
||||
{
|
||||
Null
|
||||
@expand(LNX_DMN_ProbeTable row) `$(row.name)`
|
||||
COUNT
|
||||
}
|
||||
|
||||
@data(U8) lnx_dmn_probe_kind_args_count_table:
|
||||
{
|
||||
0,
|
||||
@expand(LNX_DMN_ProbeTable row) `$(row.args_count)`
|
||||
}
|
||||
|
||||
@data(String8) lnx_dmn_probe_kind_string_table:
|
||||
{
|
||||
`{0}`,
|
||||
@expand(LNX_DMN_ProbeTable row) `str8_lit_comp("$(row.string)")`
|
||||
}
|
||||
@@ -235,7 +235,7 @@ stap_parse_args_x64(String8 string, STAP_Arg *arg_out)
|
||||
}
|
||||
|
||||
// fill out memory ref portion
|
||||
arg.type = STAP_ArgType_MemoryRef;
|
||||
arg.kind = STAP_ArgKind_MemoryRef;
|
||||
arg.memory_ref.disp = disp;
|
||||
arg.memory_ref.base.reg_code = base_reg_code;
|
||||
arg.memory_ref.index.reg_code = index_reg_code;
|
||||
@@ -274,7 +274,7 @@ stap_parse_args_x64(String8 string, STAP_Arg *arg_out)
|
||||
goto operand_parse_exit;
|
||||
}
|
||||
|
||||
arg.type = STAP_ArgType_Imm;
|
||||
arg.kind = STAP_ArgKind_Imm;
|
||||
arg.imm = imm;
|
||||
}
|
||||
// %reg
|
||||
@@ -291,7 +291,7 @@ stap_parse_args_x64(String8 string, STAP_Arg *arg_out)
|
||||
goto operand_parse_exit;
|
||||
}
|
||||
|
||||
arg.type = STAP_ArgType_Reg;
|
||||
arg.kind = STAP_ArgKind_Reg;
|
||||
arg.reg.reg_code = reg_code;
|
||||
} else {
|
||||
goto operand_parse_exit;
|
||||
@@ -353,21 +353,21 @@ stap_read_arg(STAP_Arg arg,
|
||||
AssertAlways(arg.value_size <= 8);
|
||||
ARCH_Info *arch_info = arch_info_from_arch(arch);
|
||||
B32 is_value_read = 0;
|
||||
switch(arg.type)
|
||||
switch(arg.kind)
|
||||
{
|
||||
default:{}break;
|
||||
case STAP_ArgType_Null:{}break;
|
||||
case STAP_ArgType_Imm:
|
||||
case STAP_ArgKind_Null:{}break;
|
||||
case STAP_ArgKind_Imm:
|
||||
{
|
||||
MemoryCopy(raw_value, &arg.imm, arg.value_size);
|
||||
is_value_read = 1;
|
||||
}break;
|
||||
case STAP_ArgType_Reg:
|
||||
case STAP_ArgKind_Reg:
|
||||
if(0 < arg.reg.reg_code && arg.reg.reg_code < arch_info->reg_code_count)
|
||||
{
|
||||
is_value_read = arch_reg_block_read_range(arch_info, reg_block, arch_info->reg_code_rng_table[arg.reg.reg_code], raw_value);
|
||||
}break;
|
||||
case STAP_ArgType_MemoryRef:
|
||||
case STAP_ArgKind_MemoryRef:
|
||||
{
|
||||
U64 base = 0;
|
||||
if(0 < arg.memory_ref.base.reg_code && arg.memory_ref.base.reg_code < arch_info->reg_code_count)
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
#ifndef STAP_PARSE_H
|
||||
#define STAP_PARSE_H
|
||||
|
||||
typedef enum STAP_ArgType
|
||||
typedef enum STAP_ArgKind
|
||||
{
|
||||
STAP_ArgType_Null,
|
||||
STAP_ArgType_Imm,
|
||||
STAP_ArgType_Reg,
|
||||
STAP_ArgType_MemoryRef,
|
||||
} STAP_ArgType;
|
||||
STAP_ArgKind_Null,
|
||||
STAP_ArgKind_Imm,
|
||||
STAP_ArgKind_Reg,
|
||||
STAP_ArgKind_MemoryRef,
|
||||
} STAP_ArgKind;
|
||||
|
||||
typedef enum STAP_ArgValueType
|
||||
{
|
||||
@@ -24,7 +24,7 @@ typedef struct STAP_Arg
|
||||
{
|
||||
STAP_ArgValueType value_type;
|
||||
U64 value_size;
|
||||
STAP_ArgType type;
|
||||
STAP_ArgKind kind;
|
||||
union {
|
||||
U64 imm;
|
||||
struct {
|
||||
|
||||
@@ -25,7 +25,7 @@ entry_point(CmdLine *cmd_line)
|
||||
if (error.size != 0) { goto exit; }
|
||||
AssertAlways(arg.value_type == STAP_ArgValueType_S);
|
||||
AssertAlways(arg.value_size == 2);
|
||||
AssertAlways(arg.type == STAP_ArgType_Imm);
|
||||
AssertAlways(arg.type == STAP_ArgKind_Imm);
|
||||
AssertAlways((S64)arg.imm == -123);
|
||||
|
||||
string = str8_lit("1@$43");
|
||||
@@ -33,7 +33,7 @@ entry_point(CmdLine *cmd_line)
|
||||
if (error.size != 0) { goto exit; }
|
||||
AssertAlways(arg.value_type == STAP_ArgValueType_U);
|
||||
AssertAlways(arg.value_size == 1);
|
||||
AssertAlways(arg.type == STAP_ArgType_Imm);
|
||||
AssertAlways(arg.type == STAP_ArgKind_Imm);
|
||||
AssertAlways((S64)arg.imm == 43);
|
||||
|
||||
string = str8_lit("4f@%eax");
|
||||
@@ -41,7 +41,7 @@ entry_point(CmdLine *cmd_line)
|
||||
if (error.size != 0) { goto exit; }
|
||||
AssertAlways(arg.value_type == STAP_ArgValueType_F);
|
||||
AssertAlways(arg.value_size == 4);
|
||||
AssertAlways(arg.type == STAP_ArgType_Reg);
|
||||
AssertAlways(arg.type == STAP_ArgKind_Reg);
|
||||
AssertAlways(arg.reg.is_alias == 1);
|
||||
AssertAlways(arg.reg.reg_code == REGS_AliasCodeX64_eax);
|
||||
|
||||
@@ -50,7 +50,7 @@ entry_point(CmdLine *cmd_line)
|
||||
if (error.size != 0) { goto exit; }
|
||||
AssertAlways(arg.value_size == 4);
|
||||
AssertAlways(arg.value_type == STAP_ArgValueType_U);
|
||||
AssertAlways(arg.type == STAP_ArgType_MemoryRef);
|
||||
AssertAlways(arg.type == STAP_ArgKind_MemoryRef);
|
||||
AssertAlways(arg.memory_ref.disp == 0);
|
||||
AssertAlways(arg.memory_ref.base.reg_code == REGS_RegCodeX64_rdi);
|
||||
AssertAlways(!arg.memory_ref.base.is_alias);
|
||||
@@ -63,7 +63,7 @@ entry_point(CmdLine *cmd_line)
|
||||
if (error.size != 0) { goto exit; }
|
||||
AssertAlways(arg.value_size == 4);
|
||||
AssertAlways(arg.value_type == STAP_ArgValueType_U);
|
||||
AssertAlways(arg.type == STAP_ArgType_MemoryRef);
|
||||
AssertAlways(arg.type == STAP_ArgKind_MemoryRef);
|
||||
AssertAlways(arg.memory_ref.disp == -22);
|
||||
AssertAlways(arg.memory_ref.base.reg_code == REGS_RegCodeX64_rdi);
|
||||
AssertAlways(!arg.memory_ref.base.is_alias);
|
||||
|
||||
Reference in new issue
Block a user