eliminate separate path layer, merge into base strings layer

This commit is contained in:
Ryan Fleury
2025-06-19 07:38:34 -07:00
parent f2dc9a7d4a
commit f590e9b6d5
15 changed files with 402 additions and 410 deletions
+222
View File
@@ -1497,6 +1497,228 @@ str8_txt_pt_pair_from_string(String8 string)
return pair;
}
////////////////////////////////
//~ rjf: Relative <-> Absolute Path
internal String8
path_relative_dst_from_absolute_dst_src(Arena *arena, String8 dst, String8 src)
{
Temp scratch = scratch_begin(&arena, 1);
// rjf: gather path parts
String8 dst_name = str8_skip_last_slash(dst);
String8 src_folder = src;
String8 dst_folder = str8_chop_last_slash(dst);
String8List src_folders = str8_split_path(scratch.arena, src_folder);
String8List dst_folders = str8_split_path(scratch.arena, dst_folder);
// rjf: count # of backtracks to get from src -> dest
U64 num_backtracks = src_folders.node_count;
for(String8Node *src_n = src_folders.first, *bp_n = dst_folders.first;
src_n != 0 && bp_n != 0;
src_n = src_n->next, bp_n = bp_n->next)
{
if(str8_match(src_n->string, bp_n->string, path_match_flags_from_os(operating_system_from_context())))
{
num_backtracks -= 1;
}
else
{
break;
}
}
// rjf: only build relative string if # of backtracks is not the entire `src`.
// if getting to `dst` from `src` requires erasing the entire `src`, then the
// only possible way to get to `dst` from `src` is via absolute path.
String8 dst_path = {0};
if(num_backtracks >= src_folders.node_count)
{
dst_path = dst;
}
else
{
// rjf: build backtrack parts
String8List dst_path_strs = {0};
for(U64 idx = 0; idx < num_backtracks; idx += 1)
{
str8_list_push(scratch.arena, &dst_path_strs, str8_lit(".."));
}
// rjf: build parts of dst which are unique from src
{
B32 unique_from_src = 0;
for(String8Node *src_n = src_folders.first, *bp_n = dst_folders.first;
bp_n != 0;
bp_n = bp_n->next)
{
if(!unique_from_src && (src_n == 0 || !str8_match(src_n->string, bp_n->string, path_match_flags_from_os(operating_system_from_context()))))
{
unique_from_src = 1;
}
if(unique_from_src)
{
str8_list_push(scratch.arena, &dst_path_strs, bp_n->string);
}
if(src_n != 0)
{
src_n = src_n->next;
}
}
}
// rjf: build file name
str8_list_push(scratch.arena, &dst_path_strs, dst_name);
// rjf: join
StringJoin join = {0};
{
join.sep = str8_lit("/");
}
dst_path = str8_list_join(arena, &dst_path_strs, &join);
}
scratch_end(scratch);
return dst_path;
}
internal String8
path_absolute_dst_from_relative_dst_src(Arena *arena, String8 dst, String8 src)
{
String8 result = dst;
PathStyle dst_style = path_style_from_str8(dst);
if(dst.size != 0 && dst_style == PathStyle_Relative)
{
Temp scratch = scratch_begin(&arena, 1);
String8 dst_from_src_absolute = push_str8f(scratch.arena, "%S/%S", src, dst);
String8List dst_from_src_absolute_parts = str8_split_path(scratch.arena, dst_from_src_absolute);
PathStyle dst_from_src_absolute_style = path_style_from_str8(src);
str8_path_list_resolve_dots_in_place(&dst_from_src_absolute_parts, dst_from_src_absolute_style);
result = str8_path_list_join_by_style(arena, &dst_from_src_absolute_parts, dst_from_src_absolute_style);
scratch_end(scratch);
}
return result;
}
////////////////////////////////
//~ rjf: Path Normalization
internal String8List
path_normalized_list_from_string(Arena *arena, String8 path_string, PathStyle *style_out)
{
// rjf: analyze path
PathStyle path_style = path_style_from_str8(path_string);
String8List path = str8_split_path(arena, path_string);
// rjf: resolve dots
str8_path_list_resolve_dots_in_place(&path, path_style);
// rjf: return
if(style_out != 0)
{
*style_out = path_style;
}
return path;
}
internal String8
path_normalized_from_string(Arena *arena, String8 path_string)
{
Temp scratch = scratch_begin(&arena, 1);
PathStyle style = PathStyle_Relative;
String8List path = path_normalized_list_from_string(scratch.arena, path_string, &style);
String8 result = str8_path_list_join_by_style(arena, &path, style);
scratch_end(scratch);
return result;
}
internal B32
path_match_normalized(String8 left, String8 right)
{
Temp scratch = scratch_begin(0, 0);
String8 left_normalized = path_normalized_from_string(scratch.arena, left);
String8 right_normalized = path_normalized_from_string(scratch.arena, right);
B32 result = str8_match(left_normalized, right_normalized, StringMatchFlag_CaseInsensitive);
scratch_end(scratch);
return result;
}
////////////////////////////////
//~ rjf: Misc. Path Helpers
internal PathStyle
path_style_from_string(String8 string)
{
for (U64 i = 0; i < ArrayCount(g_path_style_map); ++i)
{
if(str8_match(g_path_style_map[i].string, string, StringMatchFlag_CaseInsensitive))
{
return g_path_style_map[i].path_style;
}
}
return PathStyle_Null;
}
internal String8
string_from_path_style(PathStyle style)
{
Assert(style < ArrayCount(g_path_style_map));
return g_path_style_map[style].string;
}
internal String8
path_separator_string_from_style(PathStyle style)
{
String8 result = str8_zero();
switch (style)
{
case PathStyle_Null: break;
case PathStyle_Relative: break;
case PathStyle_WindowsAbsolute: result = str8_lit("\\"); break;
case PathStyle_UnixAbsolute: result = str8_lit("/"); break;
}
return result;
}
internal StringMatchFlags
path_match_flags_from_os(OperatingSystem os)
{
StringMatchFlags flags = StringMatchFlag_SlashInsensitive;
switch(os)
{
default:{}break;
case OperatingSystem_Windows:
{
flags |= StringMatchFlag_CaseInsensitive;
}break;
case OperatingSystem_Linux:
case OperatingSystem_Mac:
{
// NOTE(rjf): no-op
}break;
}
return flags;
}
internal String8
path_convert_slashes(Arena *arena, String8 path, PathStyle path_style)
{
Temp scratch = scratch_begin(&arena, 1);
String8List list = str8_split_path(scratch.arena, path);
StringJoin join = {0};
join.sep = path_separator_string_from_style(path_style);
String8 result = str8_list_join(arena, &list, &join);
scratch_end(scratch);
return result;
}
internal String8
path_replace_file_extension(Arena *arena, String8 file_name, String8 ext)
{
String8 file_name_no_ext = str8_chop_last_dot(file_name);
String8 result = push_str8f(arena, "%S.%S", file_name_no_ext, ext);
return result;
}
////////////////////////////////
//~ rjf: UTF-8 & UTF-16 Decoding/Encoding
+23
View File
@@ -328,6 +328,29 @@ internal String8 str8_path_list_join_by_style(Arena *arena, String8List *pat
internal String8TxtPtPair str8_txt_pt_pair_from_string(String8 string);
////////////////////////////////
//~ rjf: Relative <-> Absolute Path
internal String8 path_relative_dst_from_absolute_dst_src(Arena *arena, String8 dst, String8 src);
internal String8 path_absolute_dst_from_relative_dst_src(Arena *arena, String8 dst, String8 src);
////////////////////////////////
//~ rjf: Path Normalization
internal String8List path_normalized_list_from_string(Arena *arena, String8 path, PathStyle *style_out);
internal String8 path_normalized_from_string(Arena *arena, String8 path);
internal B32 path_match_normalized(String8 left, String8 right);
////////////////////////////////
//~ rjf: Misc. Path Helpers
internal PathStyle path_style_from_string(String8 string);
internal String8 string_from_path_style(PathStyle style);
internal String8 path_separator_string_from_style(PathStyle style);
internal StringMatchFlags path_match_flags_from_os(OperatingSystem os);
internal String8 path_convert_slashes(Arena *arena, String8 path, PathStyle path_style);
internal String8 path_replace_file_extension(Arena *arena, String8 file_name, String8 ext);
////////////////////////////////
//~ rjf: UTF-8 & UTF-16 Decoding/Encoding
+1 -1
View File
@@ -6,7 +6,7 @@ dw_string_from_reg_off(Arena *arena, Arch arch, U64 reg_idx, S64 reg_off)
{
Temp scratch = scratch_begin(&arena, 1);
String8 reg_str = dw_string_from_register(scratch.arena, arch, reg_idx);
String8 result = rd_string_from_reg_off(arena, reg_str, reg_off);
String8 result = push_str8f(arena, "%S%+lld", reg_str, reg_off);
scratch_end(scratch);
return result;
}
+10
View File
@@ -0,0 +1,10 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "dwarf/dwarf.c"
#include "dwarf/dwarf_expr.c"
#include "dwarf/dwarf_parse.c"
#include "dwarf/dwarf_coff.c"
#include "dwarf/dwarf_elf.c"
#include "dwarf/dwarf_unwind.c"
#include "dwarf/dwarf_dump.c"
+15
View File
@@ -0,0 +1,15 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DWARF_INC_H
#define DWARF_INC_H
#include "dwarf/dwarf.h"
#include "dwarf/dwarf_expr.h"
#include "dwarf/dwarf_parse.h"
#include "dwarf/dwarf_coff.h"
#include "dwarf/dwarf_elf.h"
#include "dwarf/dwarf_unwind.h"
#include "dwarf/dwarf_dump.h"
#endif // DWARF_INC_H
-2
View File
@@ -33,7 +33,6 @@
#include "base/base_inc.h"
#include "os/os_inc.h"
#include "path/path.h"
#include "coff/coff.h"
#include "coff/coff_parse.h"
#include "pe/pe.h"
@@ -46,7 +45,6 @@
#include "base/base_inc.c"
#include "os/os_inc.c"
#include "path/path.c"
#include "coff/coff.c"
#include "coff/coff_parse.c"
#include "pe/pe.c"
-224
View File
@@ -1,224 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Relative <-> Absolute Path
internal String8
path_relative_dst_from_absolute_dst_src(Arena *arena, String8 dst, String8 src)
{
Temp scratch = scratch_begin(&arena, 1);
// rjf: gather path parts
String8 dst_name = str8_skip_last_slash(dst);
String8 src_folder = src;
String8 dst_folder = str8_chop_last_slash(dst);
String8List src_folders = str8_split_path(scratch.arena, src_folder);
String8List dst_folders = str8_split_path(scratch.arena, dst_folder);
// rjf: count # of backtracks to get from src -> dest
U64 num_backtracks = src_folders.node_count;
for(String8Node *src_n = src_folders.first, *bp_n = dst_folders.first;
src_n != 0 && bp_n != 0;
src_n = src_n->next, bp_n = bp_n->next)
{
if(str8_match(src_n->string, bp_n->string, path_match_flags_from_os(operating_system_from_context())))
{
num_backtracks -= 1;
}
else
{
break;
}
}
// rjf: only build relative string if # of backtracks is not the entire `src`.
// if getting to `dst` from `src` requires erasing the entire `src`, then the
// only possible way to get to `dst` from `src` is via absolute path.
String8 dst_path = {0};
if(num_backtracks >= src_folders.node_count)
{
dst_path = dst;
}
else
{
// rjf: build backtrack parts
String8List dst_path_strs = {0};
for(U64 idx = 0; idx < num_backtracks; idx += 1)
{
str8_list_push(scratch.arena, &dst_path_strs, str8_lit(".."));
}
// rjf: build parts of dst which are unique from src
{
B32 unique_from_src = 0;
for(String8Node *src_n = src_folders.first, *bp_n = dst_folders.first;
bp_n != 0;
bp_n = bp_n->next)
{
if(!unique_from_src && (src_n == 0 || !str8_match(src_n->string, bp_n->string, path_match_flags_from_os(operating_system_from_context()))))
{
unique_from_src = 1;
}
if(unique_from_src)
{
str8_list_push(scratch.arena, &dst_path_strs, bp_n->string);
}
if(src_n != 0)
{
src_n = src_n->next;
}
}
}
// rjf: build file name
str8_list_push(scratch.arena, &dst_path_strs, dst_name);
// rjf: join
StringJoin join = {0};
{
join.sep = str8_lit("/");
}
dst_path = str8_list_join(arena, &dst_path_strs, &join);
}
scratch_end(scratch);
return dst_path;
}
internal String8
path_absolute_dst_from_relative_dst_src(Arena *arena, String8 dst, String8 src)
{
String8 result = dst;
PathStyle dst_style = path_style_from_str8(dst);
if(dst.size != 0 && dst_style == PathStyle_Relative)
{
Temp scratch = scratch_begin(&arena, 1);
String8 dst_from_src_absolute = push_str8f(scratch.arena, "%S/%S", src, dst);
String8List dst_from_src_absolute_parts = str8_split_path(scratch.arena, dst_from_src_absolute);
PathStyle dst_from_src_absolute_style = path_style_from_str8(src);
str8_path_list_resolve_dots_in_place(&dst_from_src_absolute_parts, dst_from_src_absolute_style);
result = str8_path_list_join_by_style(arena, &dst_from_src_absolute_parts, dst_from_src_absolute_style);
scratch_end(scratch);
}
return result;
}
////////////////////////////////
//~ rjf: Path Normalization
internal String8List
path_normalized_list_from_string(Arena *arena, String8 path_string, PathStyle *style_out)
{
// rjf: analyze path
PathStyle path_style = path_style_from_str8(path_string);
String8List path = str8_split_path(arena, path_string);
// rjf: resolve dots
str8_path_list_resolve_dots_in_place(&path, path_style);
// rjf: return
if(style_out != 0)
{
*style_out = path_style;
}
return path;
}
internal String8
path_normalized_from_string(Arena *arena, String8 path_string)
{
Temp scratch = scratch_begin(&arena, 1);
PathStyle style = PathStyle_Relative;
String8List path = path_normalized_list_from_string(scratch.arena, path_string, &style);
String8 result = str8_path_list_join_by_style(arena, &path, style);
scratch_end(scratch);
return result;
}
internal B32
path_match_normalized(String8 left, String8 right)
{
Temp scratch = scratch_begin(0, 0);
String8 left_normalized = path_normalized_from_string(scratch.arena, left);
String8 right_normalized = path_normalized_from_string(scratch.arena, right);
B32 result = str8_match(left_normalized, right_normalized, StringMatchFlag_CaseInsensitive);
scratch_end(scratch);
return result;
}
////////////////////////////////
//~ rjf: Basic Helpers
internal PathStyle
path_style_from_string(String8 string)
{
for (U64 i = 0; i < ArrayCount(g_path_style_map); ++i)
{
if(str8_match(g_path_style_map[i].string, string, StringMatchFlag_CaseInsensitive))
{
return g_path_style_map[i].path_style;
}
}
return PathStyle_Null;
}
internal String8
string_from_path_style(PathStyle style)
{
Assert(style < ArrayCount(g_path_style_map));
return g_path_style_map[style].string;
}
internal String8
path_separator_string_from_style(PathStyle style)
{
String8 result = str8_zero();
switch (style)
{
case PathStyle_Null: break;
case PathStyle_Relative: break;
case PathStyle_WindowsAbsolute: result = str8_lit("\\"); break;
case PathStyle_UnixAbsolute: result = str8_lit("/"); break;
}
return result;
}
internal StringMatchFlags
path_match_flags_from_os(OperatingSystem os)
{
StringMatchFlags flags = StringMatchFlag_SlashInsensitive;
switch(os)
{
default:{}break;
case OperatingSystem_Windows:
{
flags |= StringMatchFlag_CaseInsensitive;
}break;
case OperatingSystem_Linux:
case OperatingSystem_Mac:
{
// NOTE(rjf): no-op
}break;
}
return flags;
}
internal String8
path_convert_slashes(Arena *arena, String8 path, PathStyle path_style)
{
Temp scratch = scratch_begin(&arena, 1);
String8List list = str8_split_path(scratch.arena, path);
StringJoin join = {0};
join.sep = path_separator_string_from_style(path_style);
String8 result = str8_list_join(arena, &list, &join);
scratch_end(scratch);
return result;
}
internal String8
path_replace_file_extension(Arena *arena, String8 file_name, String8 ext)
{
String8 file_name_no_ext = str8_chop_last_dot(file_name);
String8 result = push_str8f(arena, "%S.%S", file_name_no_ext, ext);
return result;
}
-30
View File
@@ -1,30 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef PATH_H
#define PATH_H
////////////////////////////////
//~ rjf: Relative <-> Absolute Path
internal String8 path_relative_dst_from_absolute_dst_src(Arena *arena, String8 dst, String8 src);
internal String8 path_absolute_dst_from_relative_dst_src(Arena *arena, String8 dst, String8 src);
////////////////////////////////
//~ rjf: Path Normalization
internal String8List path_normalized_list_from_string(Arena *arena, String8 path, PathStyle *style_out);
internal String8 path_normalized_from_string(Arena *arena, String8 path);
internal B32 path_match_normalized(String8 left, String8 right);
////////////////////////////////
//~ rjf: Basic Helpers
internal PathStyle path_style_from_string(String8 string);
internal String8 string_from_path_style(PathStyle style);
internal String8 path_separator_string_from_style(PathStyle style);
internal StringMatchFlags path_match_flags_from_os(OperatingSystem os);
internal String8 path_convert_slashes(Arena *arena, String8 path, PathStyle path_style);
internal String8 path_replace_file_extension(Arena *arena, String8 file_name, String8 ext);
#endif //PATH_H
+2 -12
View File
@@ -18,7 +18,6 @@
#include "base/base_inc.h"
#include "linker/hash_table.h"
#include "os/os_inc.h"
#include "path/path.h"
#include "async/async.h"
#include "rdi_format/rdi_format_local.h"
#include "rdi_make/rdi_make_local.h"
@@ -29,11 +28,7 @@
#include "elf/elf_parse.h"
#include "codeview/codeview.h"
#include "codeview/codeview_parse.h"
#include "dwarf/dwarf.h"
#include "dwarf/dwarf_parse.h"
#include "dwarf/dwarf_coff.h"
#include "dwarf/dwarf_elf.h"
// #include "dwarf/dwarf_dump.h"
#include "dwarf/dwarf_inc.h"
#include "msf/msf.h"
#include "msf/msf_parse.h"
#include "pdb/pdb.h"
@@ -50,7 +45,6 @@
#include "base/base_inc.c"
#include "linker/hash_table.c"
#include "os/os_inc.c"
#include "path/path.c"
#include "async/async.c"
#include "rdi_format/rdi_format_local.c"
#include "rdi_make/rdi_make_local.c"
@@ -61,11 +55,7 @@
#include "elf/elf_parse.c"
#include "codeview/codeview.c"
#include "codeview/codeview_parse.c"
#include "dwarf/dwarf.c"
#include "dwarf/dwarf_parse.c"
#include "dwarf/dwarf_coff.c"
#include "dwarf/dwarf_elf.c"
// #include "dwarf/dwarf_dump.c"
#include "dwarf/dwarf_inc.c"
#include "msf/msf.c"
#include "msf/msf_parse.c"
#include "pdb/pdb.c"
-2
View File
@@ -28,7 +28,6 @@
#include "base/base_inc.h"
#include "os/os_inc.h"
#include "async/async.h"
#include "path/path.h"
#include "rdi_make/rdi_make_local.h"
#include "linker/hash_table.h"
#include "coff/coff.h"
@@ -60,7 +59,6 @@
#include "base/base_inc.c"
#include "os/os_inc.c"
#include "async/async.c"
#include "path/path.c"
#include "rdi_make/rdi_make_local.c"
#include "linker/hash_table.c"
#include "coff/coff.c"
-2
View File
@@ -218,7 +218,6 @@
#include "file_stream/file_stream.h"
#include "text_cache/text_cache.h"
#include "mutable_text/mutable_text.h"
#include "path/path.h"
#include "coff/coff.h"
#include "coff/coff_parse.h"
#include "pe/pe.h"
@@ -272,7 +271,6 @@
#include "file_stream/file_stream.c"
#include "text_cache/text_cache.c"
#include "mutable_text/mutable_text.c"
#include "path/path.c"
#include "coff/coff.c"
#include "coff/coff_parse.c"
#include "pe/pe.c"
-2
View File
@@ -28,7 +28,6 @@
#include "async/async.h"
#include "rdi_format/rdi_format_local.h"
#include "rdi_make/rdi_make_local.h"
#include "path/path.h"
#include "linker/hash_table.h"
#include "coff/coff.h"
#include "coff/coff_parse.h"
@@ -61,7 +60,6 @@
#include "async/async.c"
#include "rdi_format/rdi_format_local.c"
#include "rdi_make/rdi_make_local.c"
#include "path/path.c"
#include "linker/hash_table.c"
#include "coff/coff.c"
#include "coff/coff_parse.c"
-2
View File
@@ -16,7 +16,6 @@
//- rjf: [h]
#include "base/base_inc.h"
#include "os/os_inc.h"
#include "path/path.h"
#include "async/async.h"
#include "rdi_format/rdi_format_local.h"
#include "dbgi/dbgi.h"
@@ -24,7 +23,6 @@
//- rjf: [c]
#include "base/base_inc.c"
#include "os/os_inc.c"
#include "path/path.c"
#include "async/async.c"
#include "rdi_format/rdi_format_local.c"
#include "dbgi/dbgi.c"
+129 -131
View File
@@ -32,13 +32,11 @@
#include "third_party/xxHash/xxhash.h"
#include "linker/base_ext/base_inc.h"
#include "linker/path_ext/path.h"
#include "linker/hash_table.h"
#include "linker/thread_pool/thread_pool.h"
#include "linker/codeview_ext/codeview.h"
#include "linker/base_ext/base_inc.c"
#include "linker/path_ext/path.c"
#include "linker/hash_table.c"
#include "linker/thread_pool/thread_pool.c"
#include "linker/codeview_ext/codeview.c"
@@ -48,96 +46,96 @@ print_inline_binary_annotations(String8 binary_annots)
{
U32 code_offset = 0;
S32 line_offset = 0;
for (U64 cursor = 0; cursor < binary_annots.size; ) {
U64 op_offset = cursor;
CV_InlineBinaryAnnotation op = CV_InlineBinaryAnnotation_Null;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &op);
fprintf(stdout, "\t\t[%04llX] ", op_offset);
switch (op) {
case CV_InlineBinaryAnnotation_Null: {
fprintf(stdout, "End");
cursor = binary_annots.size;
} break;
case CV_InlineBinaryAnnotation_CodeOffset: {
U32 value = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &value);
code_offset += value;
fprintf(stdout, "CodeOffset: 0x%X; Code 0x%X", value, code_offset);
} break;
case CV_InlineBinaryAnnotation_ChangeCodeOffsetBase: {
U32 delta;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &delta);
code_offset += delta;
fprintf(stdout, "ChangeCodeOffsetBase: 0x%X; Code 0x%X", delta, code_offset);
} break;
case CV_InlineBinaryAnnotation_ChangeCodeOffset: {
U32 delta = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &delta);
code_offset += delta;
fprintf(stdout, "ChangeCodeOffset: 0x%X; Code 0x%X", delta, code_offset);
} break;
case CV_InlineBinaryAnnotation_ChangeCodeLength: {
U32 delta = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &delta);
code_offset += delta;
fprintf(stdout, "ChangeCodeLength: 0x%X; Code End 0x%X", delta, code_offset);
} break;
case CV_InlineBinaryAnnotation_ChangeFile: {
U32 file_id = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &file_id);
fprintf(stdout, "ChangeFile: 0x%X", file_id);
} break;
case CV_InlineBinaryAnnotation_ChangeLineOffset: {
S32 delta = 0;
cursor += cv_decode_inline_annot_s32(binary_annots, cursor, &delta);
line_offset += delta;
fprintf(stdout, "ChangeLineOffset: %d; Line %d", delta, line_offset);
} break;
case CV_InlineBinaryAnnotation_ChangeLineEndDelta: {
S32 end_delta = 0;
cursor += cv_decode_inline_annot_s32(binary_annots, cursor, &end_delta);
line_offset += end_delta;
fprintf(stdout, "ChangeLineEndDelta: %d; Line %d", end_delta, line_offset);
} break;
case CV_InlineBinaryAnnotation_ChangeRangeKind: {
CV_InlineRangeKind range_kind = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &range_kind);
String8 range_kind_str = cv_string_from_inline_range_kind(range_kind);
fprintf(stdout, "ChangeRangeKind: %.*s (%u)", str8_varg(range_kind_str), range_kind);
} break;
case CV_InlineBinaryAnnotation_ChangeColumnStart: {
S32 delta = 0;
cursor += cv_decode_inline_annot_s32(binary_annots, cursor, &delta);
fprintf(stdout, "ChangeColumnStart: %d", delta);
} break;
case CV_InlineBinaryAnnotation_ChangeCodeOffsetAndLineOffset: {
U32 code_offset_and_line_offset = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &code_offset_and_line_offset);
S32 line_delta = cv_inline_annot_signed_from_unsigned_operand(code_offset_and_line_offset >> 4);
U32 code_delta = code_offset_and_line_offset & 0xF;
line_offset += line_delta;
code_offset += code_delta;
fprintf(stdout, "ChnageCodeOffsetAndLineOffset: 0x%X %d; Code 0x%X Line %d", code_delta, line_delta, code_offset, line_offset);
} break;
case CV_InlineBinaryAnnotation_ChangeCodeLengthAndCodeOffset: {
U32 code_length_delta = 0;
U32 code_offset_delta = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &code_length_delta);
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &code_offset_delta);
code_offset += code_offset_delta;
fprintf(stdout, "ChangeCodeLengthAndCodeOffset: %u 0x%X; Code 0x%X Code End 0x%X", code_length_delta, code_offset_delta, code_offset, code_offset + code_length_delta);
code_offset += code_length_delta;
} break;
case CV_InlineBinaryAnnotation_ChangeColumnEnd: {
U32 column_end = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &column_end);
fprintf(stdout, "ChangeColumnEnd: %u", column_end);
} break;
default: {
fprintf(stdout, "Unknown Inline Binary Annotation Op Code: 0x%X", op);
} break;
case CV_InlineBinaryAnnotation_Null: {
fprintf(stdout, "End");
cursor = binary_annots.size;
} break;
case CV_InlineBinaryAnnotation_CodeOffset: {
U32 value = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &value);
code_offset += value;
fprintf(stdout, "CodeOffset: 0x%X; Code 0x%X", value, code_offset);
} break;
case CV_InlineBinaryAnnotation_ChangeCodeOffsetBase: {
U32 delta;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &delta);
code_offset += delta;
fprintf(stdout, "ChangeCodeOffsetBase: 0x%X; Code 0x%X", delta, code_offset);
} break;
case CV_InlineBinaryAnnotation_ChangeCodeOffset: {
U32 delta = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &delta);
code_offset += delta;
fprintf(stdout, "ChangeCodeOffset: 0x%X; Code 0x%X", delta, code_offset);
} break;
case CV_InlineBinaryAnnotation_ChangeCodeLength: {
U32 delta = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &delta);
code_offset += delta;
fprintf(stdout, "ChangeCodeLength: 0x%X; Code End 0x%X", delta, code_offset);
} break;
case CV_InlineBinaryAnnotation_ChangeFile: {
U32 file_id = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &file_id);
fprintf(stdout, "ChangeFile: 0x%X", file_id);
} break;
case CV_InlineBinaryAnnotation_ChangeLineOffset: {
S32 delta = 0;
cursor += cv_decode_inline_annot_s32(binary_annots, cursor, &delta);
line_offset += delta;
fprintf(stdout, "ChangeLineOffset: %d; Line %d", delta, line_offset);
} break;
case CV_InlineBinaryAnnotation_ChangeLineEndDelta: {
S32 end_delta = 0;
cursor += cv_decode_inline_annot_s32(binary_annots, cursor, &end_delta);
line_offset += end_delta;
fprintf(stdout, "ChangeLineEndDelta: %d; Line %d", end_delta, line_offset);
} break;
case CV_InlineBinaryAnnotation_ChangeRangeKind: {
CV_InlineRangeKind range_kind = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &range_kind);
String8 range_kind_str = cv_string_from_inline_range_kind(range_kind);
fprintf(stdout, "ChangeRangeKind: %.*s (%u)", str8_varg(range_kind_str), range_kind);
} break;
case CV_InlineBinaryAnnotation_ChangeColumnStart: {
S32 delta = 0;
cursor += cv_decode_inline_annot_s32(binary_annots, cursor, &delta);
fprintf(stdout, "ChangeColumnStart: %d", delta);
} break;
case CV_InlineBinaryAnnotation_ChangeCodeOffsetAndLineOffset: {
U32 code_offset_and_line_offset = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &code_offset_and_line_offset);
S32 line_delta = cv_inline_annot_signed_from_unsigned_operand(code_offset_and_line_offset >> 4);
U32 code_delta = code_offset_and_line_offset & 0xF;
line_offset += line_delta;
code_offset += code_delta;
fprintf(stdout, "ChnageCodeOffsetAndLineOffset: 0x%X %d; Code 0x%X Line %d", code_delta, line_delta, code_offset, line_offset);
} break;
case CV_InlineBinaryAnnotation_ChangeCodeLengthAndCodeOffset: {
U32 code_length_delta = 0;
U32 code_offset_delta = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &code_length_delta);
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &code_offset_delta);
code_offset += code_offset_delta;
fprintf(stdout, "ChangeCodeLengthAndCodeOffset: %u 0x%X; Code 0x%X Code End 0x%X", code_length_delta, code_offset_delta, code_offset, code_offset + code_length_delta);
code_offset += code_length_delta;
} break;
case CV_InlineBinaryAnnotation_ChangeColumnEnd: {
U32 column_end = 0;
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &column_end);
fprintf(stdout, "ChangeColumnEnd: %u", column_end);
} break;
default: {
fprintf(stdout, "Unknown Inline Binary Annotation Op Code: 0x%X", op);
} break;
}
fprintf(stdout, "\n");
}
@@ -147,10 +145,10 @@ internal void
entry_point(CmdLine *cmdl)
{
Arena *arena = arena_alloc();
B32 do_help = cmd_line_has_flag(cmdl, str8_lit("help")) ||
cmd_line_has_flag(cmdl, str8_lit("h")) ||
(cmdl->inputs.node_count == 0 && cmdl->options.count == 0);
cmd_line_has_flag(cmdl, str8_lit("h")) ||
(cmdl->inputs.node_count == 0 && cmdl->options.count == 0);
if (do_help) {
fprintf(stdout,
"Parse Inline Sites\n"
@@ -160,7 +158,7 @@ entry_point(CmdLine *cmdl)
"\t-help\n");
return;
}
// -comp_unit
U64 single_comp_unit_idx = max_U64;
B32 single_comp_unit_mode = cmd_line_has_argument(cmdl, str8_lit("comp_unit"));
@@ -171,12 +169,12 @@ entry_point(CmdLine *cmdl)
return;
}
}
// -base_addr
U64 base_addr = 0;
String8 base_str = cmd_line_string(cmdl, str8_lit("base_addr"));
try_u64_from_str8_c_rules(base_str, &base_addr);
// -pdb
String8 pdb_name;
if (cmd_line_has_argument(cmdl, str8_lit("pdb"))) {
@@ -196,21 +194,21 @@ entry_point(CmdLine *cmdl)
return;
}
}
// read PDB from disk
String8 pdb_data = os_data_from_file_path(arena, pdb_name);
if (pdb_data.size == 0) {
fprintf(stderr, "ERROR: unable to load %.*s from disk\n", str8_varg(pdb_name));
return;
}
// parse msf
MSF_Parsed *msf = msf_parsed_from_data(arena, pdb_data);
if (!msf) {
fprintf(stderr, "ERROR: unable to parse MSF\n");
return;
}
// find dbi
String8 dbi_data = msf_data_from_stream(msf, PDB_FixedStream_Dbi);
PDB_DbiParsed *dbi = pdb_dbi_from_data(arena, dbi_data);
@@ -218,21 +216,21 @@ entry_point(CmdLine *cmdl)
fprintf(stderr, "ERROR: unable to parse DBI\n");
return;
}
// find info stream
String8 info_data = msf_data_from_stream(msf, PDB_FixedStream_Info);
PDB_Info *info = pdb_info_from_data(arena, info_data);
if (!info) {
fprintf(stderr, "ERROR: unable to parse INFO\n");
}
// parse named streams
PDB_NamedStreamTable *named_streams = pdb_named_stream_table_from_info(arena, info);
if (!named_streams) {
fprintf(stderr, "ERROR: unable to parse named streams\n");
return;
}
// find string table
MSF_StreamNumber strtbl_sn = named_streams->sn[PDB_NamedStream_StringTable];
String8 strtbl_data = msf_data_from_stream(msf, strtbl_sn);
@@ -241,29 +239,29 @@ entry_point(CmdLine *cmdl)
fprintf(stderr, "ERROR: unable to parse string table\n");
return;
}
// find IPI
String8 ipi_data = msf_data_from_stream(msf, PDB_FixedStream_Ipi);
PDB_TpiParsed *ipi = pdb_tpi_from_data(arena, ipi_data);
String8 ipi_leaf_data = pdb_leaf_data_from_tpi(ipi);
CV_LeafParsed *ipi_leaf_parsed = cv_leaf_from_data(arena, ipi_leaf_data, ipi->itype_first);
// find sections
MSF_StreamNumber section_stream = dbi->dbg_streams[PDB_DbiStream_SECTION_HEADER];
String8 section_data = msf_data_from_stream(msf, section_stream);
COFF_SectionHeaderArray sections = pdb_coff_section_array_from_data(arena, section_data);
// find comp units
String8 comp_units_data = pdb_data_from_dbi_range(dbi, PDB_DbiRange_ModuleInfo);
PDB_CompUnitArray *comp_units = pdb_comp_unit_array_from_data(arena, comp_units_data);
if (single_comp_unit_mode) {
if (single_comp_unit_idx >= comp_units->count) {
fprintf(stderr, "comp unit idx %llu is out of bounds, PDB has %llu comp unit(s)\n", single_comp_unit_idx, comp_units->count);
return;
}
}
#if 0
// print run info
DateTime now_time_universal = os_now_universal_time();
@@ -274,7 +272,7 @@ entry_point(CmdLine *cmdl)
fprintf(stdout, "Size: %llu (bytes)\n", pdb_data.size);
fprintf(stdout, "\n");
#endif
// prepare iterator
U64 comp_unit_idx;
U64 comp_unit_count;
@@ -285,42 +283,42 @@ entry_point(CmdLine *cmdl)
comp_unit_idx = 0;
comp_unit_count = comp_units->count;
}
for (; comp_unit_idx < comp_unit_count; ++comp_unit_idx) {
PDB_CompUnit *comp_unit = comp_units->units[comp_unit_idx];
String8 symbol_data = pdb_data_from_unit_range(msf, comp_unit, PDB_DbiCompUnitRange_Symbols);
String8 c13_data = pdb_data_from_unit_range(msf, comp_unit, PDB_DbiCompUnitRange_C13);
// parse $$
CV_DebugS debug_s = cv_parse_debug_s_c13(arena, c13_data);
// find $$FILE_CKSMS
String8 file_chksms = cv_file_chksms_from_debug_s(debug_s);
// parse $$INLINEE_LINES
String8List ss_inlinee_lines = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_InlineeLines);
CV_C13InlineeLinesParsedList inlinee_lines_parsed = cv_c13_inlinee_lines_from_sub_sections(arena, ss_inlinee_lines);
// parse $$LINES
U64 c13_lines_count = 0;
CV_LineArray *c13_lines = 0;
{
String8List raw_lines_list = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_Lines);
for (String8Node *raw_lines_node = raw_lines_list.first; raw_lines_node != 0; raw_lines_node = raw_lines_node->next) {
Temp temp = temp_begin(arena);
CV_C13LinesHeaderList parsed_list = cv_c13_lines_from_sub_sections(temp.arena, raw_lines_node->string, rng_1u64(0, raw_lines_node->string.size));
c13_lines_count += parsed_list.count;
temp_end(temp);
}
c13_lines = push_array_no_zero(arena, CV_LineArray, c13_lines_count);
U64 c13_lines_idx = 0;
for (String8Node *raw_lines_node = raw_lines_list.first; raw_lines_node != 0; raw_lines_node = raw_lines_node->next) {
String8 raw_lines = raw_lines_node->string;
CV_C13LinesHeaderList parsed_list = cv_c13_lines_from_sub_sections(arena, raw_lines, rng_1u64(0, raw_lines.size));
for(CV_C13LinesHeaderNode *header_node = parsed_list.first; header_node != 0; header_node = header_node->next) {
if (0 < header_node->v.sec_idx && header_node->v.sec_idx <= sections.count) {
Assert(c13_lines_idx < c13_lines_count);
@@ -332,32 +330,32 @@ entry_point(CmdLine *cmdl)
}
}
}
String8List raw_inlinee_lines = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_InlineeLines);
CV_C13InlineeLinesParsedList inlinee_lines = cv_c13_inlinee_lines_from_sub_sections(arena, raw_inlinee_lines);
CV_InlineeLinesAccel *inlinee_lines_accel = cv_c13_make_inlinee_lines_accel(arena, inlinee_lines);
CV_LinesAccel *lines_accel = cv_c13_make_lines_accel(arena, c13_lines_count, c13_lines);
fprintf(stdout, "[%llu] %.*s\n", comp_unit_idx, str8_varg(comp_unit->obj_name));
U64 scope_level = 0;
U64 parent_voff = 0;
String8 parent_name = str8_lit("???");
CV_SymbolList symbol_list = {0};
cv_parse_symbol_sub_section(arena, &symbol_list, 0, symbol_data, CV_SymbolAlign);
for (CV_SymbolNode *symbol_n = symbol_list.first; symbol_n != 0; symbol_n = symbol_n->next) {
CV_Symbol symbol = symbol_n->data;
void *rec_raw = symbol.data.str;
void *rec_opl = symbol.data.str + symbol.data.size;
if (symbol.kind == CV_SymKind_LPROC32 || symbol.kind == CV_SymKind_GPROC32) {
CV_SymProc32 *proc32 = rec_raw;
parent_voff = sections.v[proc32->sec-1].voff + proc32->off;
parent_name = str8_cstring_capped(proc32+1, rec_opl);
scope_level += 1;
} else if (symbol.kind == CV_SymKind_BLOCK32) {
scope_level += 1;
@@ -375,7 +373,7 @@ entry_point(CmdLine *cmdl)
String8 binary_annots = str8_skip(symbol.data, sizeof(*inline_site));
CV_C13InlineeLinesParsed *inlinee_parsed = cv_c13_inlinee_lines_accel_find(inlinee_lines_accel, inline_site->inlinee);
CV_InlineBinaryAnnotsParsed binary_annots_parse = cv_c13_parse_inline_binary_annots(arena, parent_voff, inlinee_parsed, binary_annots);
String8 inlinee_name = str8_lit("???");
if (ipi->itype_first <= inline_site->inlinee && inline_site->inlinee < ipi->itype_opl) {
@@ -390,15 +388,15 @@ entry_point(CmdLine *cmdl)
inlinee_name = str8_cstring_capped(func_id + 1, leaf_opl);
}
}
String8 first_ln = str8_lit("???");
String8 file_off = str8_lit("???");
if (inlinee_parsed) {
first_ln = push_str8f(arena, "%u", inlinee_parsed->first_source_ln);
file_off = push_str8f(arena, "0x%X", inlinee_parsed->file_off);
}
fprintf(stdout, "\tInline site @ %06llX, Parent VOFF: 0x%llX (%.*s), Inlinee: 0x%X (%.*s), First LN: %.*s, File Off: %.*s\n",
(symbol.offset + sizeof(symbol.kind)),
parent_voff,
@@ -407,20 +405,20 @@ entry_point(CmdLine *cmdl)
str8_varg(inlinee_name),
str8_varg(first_ln),
str8_varg(file_off));
fprintf(stdout, "\t\tOpcodes:\n");
print_inline_binary_annotations(binary_annots);
fprintf(stdout, "\n");
fprintf(stdout, "\t\tLines:\n");
for (U64 lines_idx = 0; lines_idx < binary_annots_parse.lines_count; lines_idx += 1) {
CV_LineArray lines = binary_annots_parse.lines[lines_idx];
CV_C13Checksum checksum = {0};
str8_deserial_read_struct(file_chksms, lines.file_off, &checksum);
String8 file_name = pdb_strtbl_string_from_off(strtbl, checksum.name_off);
fprintf(stdout, "\t\t%.*s\n", str8_varg(file_name));
for (U64 line_idx = 0; line_idx < lines.line_count; ++line_idx) {
char *pre = (line_idx % 4) == 0 ? "\t\t\t" : "\t";
@@ -429,7 +427,7 @@ entry_point(CmdLine *cmdl)
}
}
fprintf(stdout, "\n");
fprintf(stdout, "\t\tCode Ranges:\n");
U64 range_idx = 0;
for (Rng1U64Node *range_n = binary_annots_parse.code_ranges.first; range_n != 0; range_n = range_n->next, ++range_idx) {
-2
View File
@@ -14,7 +14,6 @@
//- rjf: [h]
#include "base/base_inc.h"
#include "os/os_inc.h"
#include "path/path.h"
#include "hash_store/hash_store.h"
#include "rdi_format/rdi_format_local.h"
#include "regs/regs.h"
@@ -24,7 +23,6 @@
//- rjf: [c]
#include "base/base_inc.c"
#include "os/os_inc.c"
#include "path/path.c"
#include "hash_store/hash_store.c"
#include "rdi_format/rdi_format_local.c"
#include "regs/regs.c"