diff --git a/code/duffle/dsl.h b/code/duffle/dsl.h index d7445a8..0a19561 100644 --- a/code/duffle/dsl.h +++ b/code/duffle/dsl.h @@ -67,8 +67,8 @@ Standard: c23 #define T_ typeof // #define T_same(a,b) _Generic((a), typeof((b)): 1, default: 0) -#define R_ restrict -#define V_ volatile +#define R_ restrict +#define V_ volatile // R_ (restrict) establishes an "Eigen" or "Proprius" mapping. // Unlike volatile (V_), which assumes the memory can be changed by anything, diff --git a/code/duffle/encoding.h b/code/duffle/encoding.h index 5766b5d..5654941 100644 --- a/code/duffle/encoding.h +++ b/code/duffle/encoding.h @@ -16,7 +16,7 @@ FI_ void u64_to_hex(U8 val, char* buf, S4 chars) { for(S1 i = chars - 1; i >= 0; --i) { buf[i] = hex_chars[val & 0xF]; val >>= 4; } } -internal UnicodeDecode +I_ UnicodeDecode utf8_decode(U1* str, U1 max) { UnicodeDecode result = {1, Max_U4}; U1 byte = str[0]; diff --git a/code/duffle/files.h b/code/duffle/files.h index d786cf8..a839d0e 100644 --- a/code/duffle/files.h +++ b/code/duffle/files.h @@ -50,7 +50,7 @@ os_layer File file_open(FArena* scratch, AccessFlags flags, Str8 path); os_layer FileProperties properties_from_file(File file); os_layer U8 file_read(File file, R1_U8 rng, U1* out_data); -internal Slice_U1 +I_ Slice_U1 data_from_file_range(FArena* arena, File file, R1_U8 range) { U8 pre_pos = farena_save(arena[0]); U8 len = span_r1u8(range); diff --git a/code/duffle/win32.h b/code/duffle/win32.h index f3d37c2..9457b6f 100644 --- a/code/duffle/win32.h +++ b/code/duffle/win32.h @@ -2,6 +2,7 @@ # pragma once # include "dsl.h" # include "memory.h" +# include "files.h" #endif WinAPI void ms_exit_process(U4 uExitCode) asm("ExitProcess"); // Kernel 32 @@ -245,7 +246,7 @@ w32_date_time_from_system_time(DateTime* out, MS_SYSTEMTIME* in) { I_ void w32_dense_time_from_file_time(DenseTime* out, MS_FILETIME* in) { MS_SYSTEMTIME systime = {0}; ms_filetime_to_systemtime(in, &systime); DateTime date_time = {0}; - w32_date_time_from_system_time(&date_time, &systime); *out = dense_time_from_date_time(date_time); + w32_date_time_from_system_time(&date_time, &systime); out[0] = dense_time_from_date_time(date_time); } I_ FilePropertyFlags diff --git a/code/part_1/sim_8086.c b/code/part_1/sim_8086.c index d292cc1..d967cf2 100644 --- a/code/part_1/sim_8086.c +++ b/code/part_1/sim_8086.c @@ -10,6 +10,8 @@ #include "duffle/win32.h" +// #include "8086/decoder.h" + typedef Struct_(U2_HL) { U1 Low; U1 High; }; #define bitmask_(pos) (1 << pos) @@ -54,9 +56,6 @@ I_ Str8 binary_as_str8(Slice_U1 data, FArena* str8_mem) { Str8 result = {0}; jret: return result; } -typedef Enum_(U4, x86_Op) { - x86_mov -}; enum { diff --git a/scripts/build.ps1 b/scripts/build.ps1 index b66773b..c817b6e 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -18,6 +18,7 @@ if ((test-path $path_build) -eq $false) { $compiler = "clang" $linker = 'lld-link.exe' $objcopy = 'llvm-objcopy' +$objdump = 'llvm-objdump' $archiver = 'llvm-ar' # --- Compiler Flags: General / Compilation Mode --- @@ -59,23 +60,23 @@ $f_charset_utf8 = '-utf-8' # Source charset = UTF-8 # --- Compiler Flags: Warnings --- # https://clang.llvm.org/docs/DiagnosticsReference.html -$f_wall = '-Wall' -$f_wextra = '-Wextra' -$f_werror = '-Werror' -$f_warnings_as_errors = '-Werror' -$f_wno_attributes = '-Wno-attributes' -$f_warnings_ignore = '-Wno-' # Prefix; usage: $f_warnings_ignore + 'unused' -$f_wno_unused_function = '-Wno-unused-function' -$f_wno_unused_variable = '-Wno-unused-variable' -$f_wno_switch = '-Wno-switch' -$f_wno_uninitialized = '-Wno-uninitialized' +$f_wall = '-Wall' +$f_wextra = '-Wextra' +$f_werror = '-Werror' +$f_warnings_as_errors = '-Werror' +$f_wno_attributes = '-Wno-attributes' +$f_warnings_ignore = '-Wno-' # Prefix; usage: $f_warnings_ignore + 'unused' +$f_wno_unused_function = '-Wno-unused-function' +$f_wno_unused_variable = '-Wno-unused-variable' +$f_wno_switch = '-Wno-switch' +$f_wno_uninitialized = '-Wno-uninitialized' $f_wno_implicit_function_declaration = '-Wno-implicit-function-declaration' -$f_wno_ms_include = '-Wno-microsoft-include' -$f_wno_return_type_c_linkage = '-Wno-return-type-c-linkage' -$f_wno_main_return_type = '-Wno-main-return-type' -$f_warning = '-W' # Prefix; usage: $f_warning + 'switch' -$f_pedantic = '-Wpedantic' -$f_doc_warnings = '-Wdocumentation' +$f_wno_ms_include = '-Wno-microsoft-include' +$f_wno_return_type_c_linkage = '-Wno-return-type-c-linkage' +$f_wno_main_return_type = '-Wno-main-return-type' +$f_warning = '-W' # Prefix; usage: $f_warning + 'switch' +$f_pedantic = '-Wpedantic' +$f_doc_warnings = '-Wdocumentation' # --- Compiler Flags: Optimization --- $f_optimize_none = '-O0' # No optimization (debug default) @@ -91,48 +92,48 @@ $f_lto = '-flto' # Link-time optimization $f_lto_thin = '-flto=thin' # --- Compiler Flags: Debug / Profile --- -$f_debug = '-g' # Debug info (default DWARF) -$f_debug_codeview = '-gcodeview' # CodeView debug format (MS tools) -$f_debug_dwarf_4 = '-gdwarf-4' # Specific DWARF version -$f_debug_dwarf_5 = '-gdwarf-5' +$f_debug = '-g' # Debug info (default DWARF) +$f_debug_codeview = '-gcodeview' # CodeView debug format (MS tools) +$f_debug_dwarf_4 = '-gdwarf-4' # Specific DWARF version +$f_debug_dwarf_5 = '-gdwarf-5' $f_debug_line_tables_only = '-gline-tables-only' -$f_profiling_debug = '-fdebug-info-for-profiling' -$f_time_trace = '-ftime-trace' # Emit Chrome trace JSON -$f_coverage_generate = '-fprofile-instr-generate' -$f_coverage_use = '-fprofile-instr-use=' +$f_profiling_debug = '-fdebug-info-for-profiling' +$f_time_trace = '-ftime-trace' # Emit Chrome trace JSON +$f_coverage_generate = '-fprofile-instr-generate' +$f_coverage_use = '-fprofile-instr-use=' # --- Compiler Flags: Code Generation --- -$f_no_color_diagnostics = '-fno-color-diagnostics' -$f_color_diagnostics = '-fcolor-diagnostics' -$f_diagnostics_absolute = '-fdiagnostics-absolute-paths' -$f_exceptions_disabled = '-fno-exceptions' -$f_exceptions_enabled = '-fexceptions' -$f_RTTI_disabled = '-fno-rtti' -$f_RTTI_enabled = '-frtti' -$f_section_data = '-fdata-sections' -$f_section_functions = '-ffunction-sections' -$f_no_strict_alias = '-fno-strict-aliasing' -$f_strict_aliasing = '-fstrict-aliasing' -$f_signed_char = '-fsigned-char' -$f_unsigned_char = '-funsigned-char' -$f_pic = '-fPIC' # Position-independent code -$f_pie = '-fPIE' # Position-independent executable -$f_no_pic = '-fno-pic' -$f_no_pie = '-fno-pie' -$f_visible_hidden = '-fvisibility=hidden' -$f_visible_default = '-fvisibility=default' -$f_align_functions = '-falign-functions=' -$f_align_loops = '-falign-loops=' -$f_ms_extensions = '-fms-extensions' # Allow MSVC language extensions -$f_ms_compatibility = '-fms-compatibility' -$f_ms_runtime_lib_none = '-fno-ms-runtime' +$f_no_color_diagnostics = '-fno-color-diagnostics' +$f_color_diagnostics = '-fcolor-diagnostics' +$f_diagnostics_absolute = '-fdiagnostics-absolute-paths' +$f_exceptions_disabled = '-fno-exceptions' +$f_exceptions_enabled = '-fexceptions' +$f_RTTI_disabled = '-fno-rtti' +$f_RTTI_enabled = '-frtti' +$f_section_data = '-fdata-sections' +$f_section_functions = '-ffunction-sections' +$f_no_strict_alias = '-fno-strict-aliasing' +$f_strict_aliasing = '-fstrict-aliasing' +$f_signed_char = '-fsigned-char' +$f_unsigned_char = '-funsigned-char' +$f_pic = '-fPIC' # Position-independent code +$f_pie = '-fPIE' # Position-independent executable +$f_no_pic = '-fno-pic' +$f_no_pie = '-fno-pie' +$f_visible_hidden = '-fvisibility=hidden' +$f_visible_default = '-fvisibility=default' +$f_align_functions = '-falign-functions=' +$f_align_loops = '-falign-loops=' +$f_ms_extensions = '-fms-extensions' # Allow MSVC language extensions +$f_ms_compatibility = '-fms-compatibility' +$f_ms_runtime_lib_none = '-fno-ms-runtime' $f_preprocess_non_integrated = '-no-integrated-cpp' -$f_stack_protector = '-fstack-protector' -$f_stack_protector_strong = '-fstack-protector-strong' -$f_stack_protector_all = '-fstack-protector-all' -$f_vptr = '-fvirtual-function-elimination' -$f_vectorize = '-vectorize-loops' -$f_vectorize_slp = '-vectorize-slp' +$f_stack_protector = '-fstack-protector' +$f_stack_protector_strong = '-fstack-protector-strong' +$f_stack_protector_all = '-fstack-protector-all' +$f_vptr = '-fvirtual-function-elimination' +$f_vectorize = '-vectorize-loops' +$f_vectorize_slp = '-vectorize-slp' # --- Compiler Flags: Sanitizers --- $f_sanitize_address = '-fsanitize=address' @@ -163,24 +164,6 @@ $f_verbose = '-v' $f_set_stack_size = '-stack=' # Stack size (linker-side, but accepted by clang) $f_symbol_prefix = '-femit-all-decls' -# --- Compiler Flags: MIPS Architecture (catalog parity with ps1/build_psyq.ps1) --- -# Used by the PS1 cross-compile path (C:\projects\Pikuma\ps1). Not used by -# the current Win32 build. Kept here so the catalog is complete. -$f_arch_mips1 = '-march=mips1' -$f_arch_mips2 = '-march=mips2' -$f_arch_mips3 = '-march=mips3' -$f_arch_abi32 = '-mabi=32' -$f_arch_abi64 = '-mabi=64' -$f_arch_little_endian = '-EL' -$f_arch_big_endian = '-EB' -$f_arch_fp32 = '-mfp32' -$f_arch_no_pic = '-fno-pic' -$f_arch_no_shared = '-mno-shared' -$f_arch_no_abicalls = '-mno-abicalls' -$f_arch_no_llsc = '-mno-llsc' -$f_arch_no_gpopt = '-mno-gpopt' -$f_arch_no_stack_prot = '-fno-stack-protector' - # --- Linker Flags (passed via -Wl, to clang; or directly to gcc-style linkers) --- # These are GNU ld-style flags. When invoking lld-link.exe directly, prefer # the Win32-flavored flags below. @@ -207,72 +190,82 @@ $f_link_no_as_needed = '--no-as-needed' # --- Linker Flags (Win32 lld-link, used directly) --- # https://lld.llvm.org/windows_support.html -$f_nologo = '/NOLOGO' -$f_link_win_no_incremental = '/INCREMENTAL:NO' -$f_link_win_no_default_lib = '/NODEFAULTLIB' -$f_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE' -$f_link_win_subsystem_windows = '/SUBSYSTEM:WINDOWS' -$f_link_win_subsystem_efi_app = '/SUBSYSTEM:EFI_APPLICATION' -$f_link_win_subsystem_native = '/SUBSYSTEM:NATIVE' -$f_link_win_machine_32 = '/MACHINE:X86' -$f_link_win_machine_64 = '/MACHINE:X64' -$f_link_win_machine_arm = '/MACHINE:ARM' -$f_link_win_machine_arm64 = '/MACHINE:ARM64' -$f_link_win_debug = '/DEBUG' -$f_link_win_pdb = '/PDB:' -$f_link_win_path_output = '/OUT:' -$f_link_win_map = '/MAP:' -$f_link_win_entry = '/ENTRY:' -$f_link_win_lib_path = '/LIBPATH:' -$f_link_win_default_lib = '/DEFAULTLIB:' -$f_link_win_dll = '/DLL' -$f_link_win_optimize_ref = '/OPT:REF' # Eliminate unreferenced data/functions -$f_link_win_optimize_no_icf = '/OPT:NOICF' # Disable identical COMDAT folding -$f_link_win_optimize_no_ref = '/OPT:NOREF' # Disable dead-strip -$f_link_win_stack = '/STACK:' -$f_link_win_heap = '/HEAP:' -$f_link_win_merge = '/MERGE:' -$f_link_win_align = '/ALIGN:' -$f_link_win_base = '/BASE:' -$f_link_win_version = '/VERSION:' -$f_link_win_dynamic_base = '/DYNAMICBASE' -$f_link_win_release = '/RELEASE' -$f_link_win_force = '/FORCE' -$f_link_win_verbose = '/VERBOSE' -$f_link_win_wholearchive = '/WHOLEARCHIVE:' -$f_link_win_export = '/EXPORT:' -$f_link_win_delay_load = '/DELAYLOAD:' -$f_link_win_import = '/IMPORT:' -$f_link_win_def = '/DEF:' -$f_link_win_manifest = '/MANIFEST' -$f_link_win_manifest_no = '/MANIFEST:NO' -$f_link_win_manifest_uac = '/MANIFESTUAC:' -$f_link_win_manifest_input = '/MANIFESTINPUT:' -$f_link_win_section = '/SECTION:' -$f_link_win_swaprun = '/SWAPRUN' -$f_link_win_driver = '/DRIVER' +$f_nologo = '/NOLOGO' +$f_link_win_no_incremental = '/INCREMENTAL:NO' +$f_link_win_no_default_lib = '/NODEFAULTLIB' +$f_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE' +$f_link_win_subsystem_windows = '/SUBSYSTEM:WINDOWS' +$f_link_win_subsystem_efi_app = '/SUBSYSTEM:EFI_APPLICATION' +$f_link_win_subsystem_native = '/SUBSYSTEM:NATIVE' +$f_link_win_machine_32 = '/MACHINE:X86' +$f_link_win_machine_64 = '/MACHINE:X64' +$f_link_win_machine_arm = '/MACHINE:ARM' +$f_link_win_machine_arm64 = '/MACHINE:ARM64' +$f_link_win_debug = '/DEBUG' +$f_link_win_pdb = '/PDB:' +$f_link_win_path_output = '/OUT:' +$f_link_win_map = '/MAP:' +$f_link_win_entry = '/ENTRY:' +$f_link_win_lib_path = '/LIBPATH:' +$f_link_win_default_lib = '/DEFAULTLIB:' +$f_link_win_dll = '/DLL' +$f_link_win_optimize_ref = '/OPT:REF' # Eliminate unreferenced data/functions +$f_link_win_optimize_no_icf = '/OPT:NOICF' # Disable identical COMDAT folding +$f_link_win_optimize_no_ref = '/OPT:NOREF' # Disable dead-strip +$f_link_win_stack = '/STACK:' +$f_link_win_heap = '/HEAP:' +$f_link_win_merge = '/MERGE:' +$f_link_win_align = '/ALIGN:' +$f_link_win_base = '/BASE:' +$f_link_win_version = '/VERSION:' +$f_link_win_dynamic_base = '/DYNAMICBASE' +$f_link_win_release = '/RELEASE' +$f_link_win_force = '/FORCE' +$f_link_win_verbose = '/VERBOSE' +$f_link_win_wholearchive = '/WHOLEARCHIVE:' +$f_link_win_export = '/EXPORT:' +$f_link_win_delay_load = '/DELAYLOAD:' +$f_link_win_import = '/IMPORT:' +$f_link_win_def = '/DEF:' +$f_link_win_manifest = '/MANIFEST' +$f_link_win_manifest_no = '/MANIFEST:NO' +$f_link_win_manifest_uac = '/MANIFESTUAC:' +$f_link_win_manifest_input = '/MANIFESTINPUT:' +$f_link_win_section = '/SECTION:' +$f_link_win_swaprun = '/SWAPRUN' +$f_link_win_driver = '/DRIVER' $f_link_win_large_address_aware = '/LARGEADDRESSAWARE' -$f_link_win_fail_if_mismatch = '/FAILIFMISMATCH' -$f_link_win_through = '/THREADOPT' -$f_link_win_error_report = '/ERRORREPORT' -$f_link_win_repro = '/BREPRO' -$f_link_win_safeseh = '/SAFESEH' -$f_link_win_guard_cf = '/GUARD:CF' -$f_link_win_guard_no_cf = '/GUARD:NOCF' -$f_link_win_pgo_run = '/USEPROFILE' -$f_link_win_pgo_gen = '/PROFILE' -$f_link_win_idl = '/IDLOUT:' -$f_link_win_delay_unload = '/DELAY:UNLOAD' -$f_link_win_compat_property = '/CETCOMPAT' -$f_link_win_debug_fastlink = '/DEBUG:FASTLINK' -$f_link_win_lib_list = '/LIB' +$f_link_win_fail_if_mismatch = '/FAILIFMISMATCH' +$f_link_win_through = '/THREADOPT' +$f_link_win_error_report = '/ERRORREPORT' +$f_link_win_repro = '/BREPRO' +$f_link_win_safeseh = '/SAFESEH' +$f_link_win_guard_cf = '/GUARD:CF' +$f_link_win_guard_no_cf = '/GUARD:NOCF' +$f_link_win_pgo_run = '/USEPROFILE' +$f_link_win_pgo_gen = '/PROFILE' +$f_link_win_idl = '/IDLOUT:' +$f_link_win_delay_unload = '/DELAY:UNLOAD' +$f_link_win_compat_property = '/CETCOMPAT' +$f_link_win_debug_fastlink = '/DEBUG:FASTLINK' +$f_link_win_lib_list = '/LIB' # --- Objcopy Flags --- -$f_objcopy_format = '-O' # Output format -$f_objcopy_add_section = '--add-section' -$f_objcopy_update_section = '--update-section' +$f_objcopy_format = '-O' # Output format +$f_objcopy_add_section = '--add-section' +$f_objcopy_update_section = '--update-section' $f_objcopy_set_section_flags = '--set-section-flags' +# --- Objdump Flags --- +$f_objdump_disassemble = '-d' # Disassemble all executable sections +$f_objdump_machine = '-M' # Usage: $f_objdump_machine + 'intel' +$f_objdump_source_lines = '-l' # Interleave source lines (requires -g) +$f_objdump_no_raw_insn = '--no-show-raw-insn' # Omit hex bytes +$f_objdump_reloc = '-r' # Inline relocations +$f_objdump_symbols = '--disassemble-symbols=' # Usage: $f_objdump_symbols + 'main' +$f_objdump_headers = '-x' # All headers + sections (verbose) +$f_objdump_section_contents = '-s' # Raw section contents (hex dump) + # --- Baseline Libraries (lld-link, Win32) --- $libraries_win32 = @( 'kernel32.lib' @@ -283,8 +276,7 @@ $libraries_win32 = @( # --- Functions --- -function compile-unit { - param( +function compile-unit { param( [string] $unit, [string] $link_module, [string[]] $include_paths, @@ -313,8 +305,7 @@ function compile-unit { if ($LASTEXITCODE -ne 0) { write-error "Compilation failed for $unit. Aborting."; exit 1 } } -function link-modules { - param( +function link-modules { param( [string[]] $link_modules, [string] $module, [string] $pdb, @@ -348,6 +339,28 @@ function link-modules { if ($LASTEXITCODE -ne 0) { write-error "Linking failed. Aborting."; exit 1 } } +function dump-disassembly { param([string] $obj, [string] $exe) + $base = [System.IO.Path]::GetFileNameWithoutExtension($exe) + $asm_obj = join-path $path_build "$base.obj.asm" + $asm_exe = join-path $path_build "$base.exe.asm" + + $objdump_args = @() + $objdump_args += $f_objdump_disassemble + $objdump_args += ($f_objdump_machine + 'intel') + $objdump_args += $f_objdump_source_lines + $objdump_args += $f_objdump_no_raw_insn + + write-host "Dumping object disassembly -> '$asm_obj'" -ForegroundColor DarkCyan + $time_to_objdump = Measure-Command { & $objdump $objdump_args $obj | Out-File -FilePath $asm_obj -Encoding utf8 } + write-host "Object disassembly took $($time_to_objdump.TotalMilliseconds)ms" + if ($LASTEXITCODE -ne 0) { write-error "objdump failed for $obj. Aborting."; exit 1 } + + write-host "Dumping executable disassembly -> '$asm_exe'" -ForegroundColor DarkCyan + $time_to_objdump = Measure-Command { & $objdump $objdump_args $exe | Out-File -FilePath $asm_exe -Encoding utf8 } + write-host "Executable disassembly took $($time_to_objdump.TotalMilliseconds)ms" + if ($LASTEXITCODE -ne 0) { write-error "objdump failed for $exe. Aborting."; exit 1 } +} + function build-part_1 { # The base lib uses subdir-prefixed includes (e.g. "duffle/dsl.h"), # so the include root is , not /duffle. @@ -370,6 +383,8 @@ function build-part_1 { $exe = join-path $path_build 'sim_8086.exe' link-modules $module_c $exe $pdb @() + + dump-disassembly $module_c $exe } build-part_1