Skip to content
Empty file modified build.sh
100644 → 100755
Empty file.
91 changes: 66 additions & 25 deletions src/dbg_info/dbg_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,48 @@ di_async_tick(void)
}
else
{
rdi_path = str8f(scratch.arena, "%S.rdi", str8_chop_last_dot(og_path));
// by default, write rdi next to original. but if original lives in
// a typically read-only system location, redirect to user cache dir.
B32 use_user_cache = 0;
#if OS_LINUX
local_persist read_only String8 system_prefixes[] =
{
str8_lit_comp("/usr/"),
str8_lit_comp("/lib/"),
str8_lit_comp("/lib64/"),
str8_lit_comp("/lib32/"),
str8_lit_comp("/opt/"),
str8_lit_comp("/bin/"),
str8_lit_comp("/sbin/"),
str8_lit_comp("/etc/"),
};
for EachElement(idx, system_prefixes)
{
if(str8_match(str8_prefix(og_path, system_prefixes[idx].size), system_prefixes[idx], 0))
{
use_user_cache = 1;
break;
}
}
#endif
if(use_user_cache)
{
String8 user_data = os_get_process_info()->user_program_data_path;
String8 cache_dir = push_str8f(scratch.arena, "%S/raddbg/rdi-cache", user_data);
os_make_directory(cache_dir);
Temp esc_scratch = temp_begin(scratch.arena);
String8 escaped = push_str8_copy(esc_scratch.arena, og_path);
for(U64 i = 0; i < escaped.size; i += 1)
{
if(escaped.str[i] == '/') { escaped.str[i] = '_'; }
}
rdi_path = push_str8f(scratch.arena, "%S/%S.rdi", cache_dir, str8_chop_last_dot(escaped));
temp_end(esc_scratch);
}
else
{
rdi_path = str8f(scratch.arena, "%S.rdi", str8_chop_last_dot(og_path));
}
}
}

Expand Down Expand Up @@ -1151,8 +1192,8 @@ di_search_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *
U64 element_count = 0;
void *table_base = rdi_section_raw_table_from_kind(rdi, section_kind, &element_count);
U64 element_size = rdi_section_element_size_table[section_kind];

// rjf: do search
// rjf: do search
Rng1U64 range = lane_range(element_count);
for EachInRange(idx, range)
{
Expand All @@ -1170,7 +1211,7 @@ di_search_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *
case RDI_SectionKind_UDTs:
{
RDI_UDT *udt = (RDI_UDT *)element;
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx);
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx);
name = fully_qualified_from_rdi_string_and_container(arena, rdi, type_node->user_defined.name_string_idx, udt->container_idx, udt->container_flags);
}break;
case RDI_SectionKind_SourceFiles:
Expand All @@ -1192,9 +1233,9 @@ di_search_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *
scratch_end(scratch);
}break;
default:
{
RDI_Symbol *symbol = (RDI_Symbol *)element;
name = fully_qualified_str8_from_rdi_symbol(arena, rdi, symbol);
{
RDI_Symbol *symbol = (RDI_Symbol *)element;
name = fully_qualified_str8_from_rdi_symbol(arena, rdi, symbol);
}break;
}
if(name.size == 0) { continue; }
Expand Down Expand Up @@ -1496,12 +1537,12 @@ di_match_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *g
Temp scratch = scratch_begin(0, 0);

//- rjf: unpack key
U64 index = 0;
U64 index = 0;
String8 name = {0};
DI_Key preferred_key = {0};
{
U64 key_read_off = 0;
key_read_off += str8_deserial_read_struct(key, key_read_off, &index);
key_read_off += str8_deserial_read_struct(key, key_read_off, &index);
key_read_off += str8_deserial_read_struct(key, key_read_off, &preferred_key);
key_read_off += str8_deserial_read_struct(key, key_read_off, &name.size);
name.str = push_array_no_zero(scratch.arena, U8, name.size);
Expand Down Expand Up @@ -1634,14 +1675,14 @@ di_match_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *g
RDI_NameMapNode *map_node = rdi_name_map_lookup(rdi, &parsed_name_map, leaf_part_of_name.str, leaf_part_of_name.size);
U32 matches_count = 0;
U32 *matches = rdi_matches_from_map_node(rdi, map_node, &matches_count);

// rjf: do we have a container? -> filter matches according to container string also
// rjf: do we have a container? -> filter matches according to container string also
U32 *filtered_matches = matches;
U32 filtered_matches_count = matches_count;
U32 filtered_matches_count = matches_count;
if(container_part_of_name.size != 0)
{
filtered_matches = push_array(scratch.arena, U32, matches_count);
filtered_matches_count = 0;
{
filtered_matches = push_array(scratch.arena, U32, matches_count);
filtered_matches_count = 0;
for EachIndex(match_idx, matches_count)
{
Temp scratch = scratch_begin(0, 0);
Expand Down Expand Up @@ -1678,16 +1719,16 @@ di_match_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *g
}
scratch_end(scratch);
}
}

// rjf: do we have a specific unit queried? -> filter matches according to containing unit
#if 0
if(target_unit_index != 0)
{

}
#endif

}
// rjf: do we have a specific unit queried? -> filter matches according to containing unit
#if 0
if(target_unit_index != 0)
{
}
#endif
// rjf: given matches, pick selected & return as result
if(filtered_matches_count != 0)
{
Expand Down
60 changes: 57 additions & 3 deletions src/demon/linux/demon_core_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,10 +424,64 @@ dmn_lnx_rdebug_vaddr_from_memory(int memory_fd, U64 loader_vbase, B32 is_rebased
Assert(0 && "failed to read hash table's chain count out of HASH");
}
}
else
else if(dynamic_info.gnu_hash_vaddr)
{
// TODO: extract count from GNU_HASH
NotImplemented;
// GNU_HASH header: u32 nbuckets, u32 symoffset, u32 bloom_size, u32 bloom_shift,
// followed by bloom[bloom_size] (word size = 4 on 32-bit ELF, 8 on 64-bit),
// buckets[nbuckets] (u32), chains[...] (u32, terminated by entry w/ LSB set).
U32 gnu_header[4] = {0};
if(dmn_lnx_read(memory_fd, r1u64(dynamic_info.gnu_hash_vaddr, dynamic_info.gnu_hash_vaddr + sizeof(gnu_header)), gnu_header) == sizeof(gnu_header))
{
U32 nbuckets = gnu_header[0];
U32 symoffset = gnu_header[1];
U32 bloom_size = gnu_header[2];
U64 bloom_word = (elf_class == ELF_Class_64) ? 8 : 4;
U64 buckets_vaddr = dynamic_info.gnu_hash_vaddr + sizeof(gnu_header) + bloom_size * bloom_word;
U64 chain_vaddr = buckets_vaddr + (U64)nbuckets * sizeof(U32);

// find largest symbol index referenced by any bucket
U32 max_bucket = 0;
for(U32 b = 0; b < nbuckets; b += 1)
{
U32 entry = 0;
if(dmn_lnx_read(memory_fd, r1u64(buckets_vaddr + b*sizeof(U32), buckets_vaddr + (b+1)*sizeof(U32)), &entry) != sizeof(U32))
{
break;
}
if(entry > max_bucket) { max_bucket = entry; }
}

if(max_bucket < symoffset)
{
// no symbols in hash; total count is symoffset
symbol_count = symoffset;
}
else
{
// walk chain from max_bucket until terminator (entry w/ LSB set)
U64 idx = max_bucket;
for(;;)
{
U32 chain_entry = 0;
U64 entry_vaddr = chain_vaddr + (idx - symoffset) * sizeof(U32);
if(dmn_lnx_read(memory_fd, r1u64(entry_vaddr, entry_vaddr + sizeof(U32)), &chain_entry) != sizeof(U32))
{
break;
}
if(chain_entry & 1)
{
symbol_count = idx + 1;
break;
}
idx += 1;
if(idx - max_bucket > (1u<<24))
{
// sanity bound: don't loop forever on a corrupt chain
break;
}
}
}
}
}

// scan symbol table for the rendezvous symbol
Expand Down
42 changes: 27 additions & 15 deletions src/dwarf/dwarf_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -2696,34 +2696,46 @@ dw_path_from_file(Arena *arena, String8Array dir_table, DW_LineFile *file)
Assert(dir_table.count > 0);

// find directory and file name associated with the file index
String8 dir = dir_table.v[file->dir_idx];
String8 path = file->path;

// infer path style if directory is empty use file name
PathStyle style = path_style_from_str8(dir);
String8 dir = dir_table.v[file->dir_idx];
String8 comp_dir = dir_table.v[0];

// DWARFv5 sec 6.2.4: dir 0 is the current directory of the compilation;
// each additional dir entry is either a full path or is relative to dir 0.
// prepend dir 0 only when the chosen dir is non-zero and not absolute.
PathStyle dir_style = path_style_from_str8(dir);
PathStyle comp_dir_style = path_style_from_str8(comp_dir);
B32 dir_is_relative = (dir_style == PathStyle_Null || dir_style == PathStyle_Relative);
B32 prepend_comp_dir = (file->dir_idx != 0 && dir_is_relative);

PathStyle style = dir_style;
if (prepend_comp_dir) {
style = comp_dir_style;
}
if (style == PathStyle_Null || style == PathStyle_Relative) {
style = path_style_from_str8(file->path);
PathStyle file_style = path_style_from_str8(file->path);
if (file_style != PathStyle_Null && file_style != PathStyle_Relative) {
style = file_style;
}
}

String8List path_list = {0};
{
// directories that start with ".." are relative to the compile unit directory
if (str8_match_lit("..", dir, StringMatchFlag_RightSideSloppy)) {
String8List comp_dir = str8_split_path(scratch.arena, dir_table.v[0]);
str8_list_concat_in_place(&path_list, &comp_dir);
if (prepend_comp_dir) {
String8List comp_dir_list = str8_split_path(scratch.arena, comp_dir);
str8_list_concat_in_place(&path_list, &comp_dir_list);
}

// push directory
String8List dir_list = str8_split_path(scratch.arena, dir);
str8_list_concat_in_place(&path_list, &dir_list);

// push file name
str8_list_push(scratch.arena, &path_list, file->path);

// resolve dots in the path
str8_path_list_resolve_dots_in_place(&path_list, style);
}

// join path
String8 result = str8_path_list_join_by_style(arena, &path_list, style);

Expand Down
47 changes: 40 additions & 7 deletions src/eval/eval_interpret.c
Original file line number Diff line number Diff line change
Expand Up @@ -936,19 +936,52 @@ e_interpret(String8 bytecode)
}
}break;

case RDI_EvalOp_PushCfa:
case RDI_EvalOp_CallSiteValue:
{
nval.u64 = e_interpret_ctx->cfa;
// DW_OP_entry_value: requires evaluating the embedded sub-bytecode
// in this frame's entry-time register state (i.e. caller's state
// at the call instruction). that state is not currently plumbed
// into the eval context. interpreting in the current ctx gives
// wrong values for spilled args, so report BadOp instead.
// skip past the embedded sub-bytecode in the outer stream so the
// bytes are not interpreted as outer ops on resume.
U32 sub_size = imm.u32;
if(ptr + sub_size <= opl)
{
ptr += sub_size;
}
result.code = E_InterpretationCode_BadOp;
goto done;
}break;

case RDI_EvalOp_CallSiteValue:

case RDI_EvalOp_PartialValue:
{
// DW_OP_piece marker: top-of-stack is a piece of a composite value.
// we do not assemble composites; for single-piece expressions the
// value already on the stack is the result. for multi-piece, only
// the first piece is returned (stack[0] is the final result).
}break;

case RDI_EvalOp_PartialValueBit:
{
// DW_OP_bit_piece marker. same caveat as PartialValue.
}break;

case RDI_EvalOp_Swap:
{
// TODO(rjf)
result.code = E_InterpretationCode_BadOp;
goto done;
if(stack_count + 2 > stack_cap)
{
result.code = E_InterpretationCode_InsufficientStackSpace;
goto done;
}
stack[stack_count + 0] = svals[1];
stack[stack_count + 1] = svals[0];
stack_count += 2;
}break;

case RDI_EvalOp_PushCfa:
{
nval.u64 = e_interpret_ctx->cfa;
}break;
}

Expand Down
28 changes: 23 additions & 5 deletions src/os/gfx/linux/os_gfx_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,32 @@ os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title)
DLLPushBack(os_lnx_gfx_state->first_window, os_lnx_gfx_state->last_window, w);

//- rjf: create window & equip with x11 info
Visual *visual = os_lnx_gfx_state->window_visual;
int depth = os_lnx_gfx_state->window_depth;
Colormap colormap = os_lnx_gfx_state->window_colormap;
unsigned long attr_mask = 0;
XSetWindowAttributes window_attribs = {0};
if(visual == 0)
{
visual = (Visual *)CopyFromParent;
depth = CopyFromParent;
}
else
{
window_attribs.background_pixmap = None;
window_attribs.border_pixel = 0;
window_attribs.colormap = colormap;
attr_mask = CWBackPixmap|CWBorderPixel|CWColormap;
}
w->window = XCreateWindow(os_lnx_gfx_state->display,
XDefaultRootWindow(os_lnx_gfx_state->display),
0, 0, resolution.x, resolution.y,
0,
CopyFromParent,
depth,
InputOutput,
CopyFromParent,
0,
0);
visual,
attr_mask,
&window_attribs);
XSelectInput(os_lnx_gfx_state->display, w->window,
ExposureMask|
PointerMotionMask|
Expand Down Expand Up @@ -159,7 +176,7 @@ os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title)
String8 title_copy = push_str8_copy(scratch.arena, title);
XStoreName(os_lnx_gfx_state->display, w->window, (char *)title_copy.str);
scratch_end(scratch);

//- rjf: convert to handle & return
OS_Handle handle = {(U64)w};
return handle;
Expand Down Expand Up @@ -190,6 +207,7 @@ os_window_first_paint(OS_Handle handle)
if(os_handle_match(handle, os_handle_zero())) {return;}
OS_LNX_Window *w = (OS_LNX_Window *)handle.u64[0];
XMapWindow(os_lnx_gfx_state->display, w->window);
XFlush(os_lnx_gfx_state->display);
}

internal void
Expand Down
3 changes: 3 additions & 0 deletions src/os/gfx/linux/os_gfx_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ struct OS_LNX_GfxState
Cursor cursors[OS_Cursor_COUNT];
OS_Cursor last_set_cursor;
OS_GfxInfo gfx_info;
Visual *window_visual;
int window_depth;
Colormap window_colormap;
};

////////////////////////////////
Expand Down
Loading