Last active
May 21, 2025 04:22
-
-
Save leroycep/e18893f1aa58aeffc1699b6fbda6734b to your computer and use it in GitHub Desktop.
A script to set the symbols from zig's compiler_rt symbols to hidden to fix issues with dynamic libraries
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| zig build-exe ./hide_compiler_rt.zig | |
| ./hide_compiler_rt path/to/input_lib.so path/to/output_lib.so |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pub fn main() !void { | |
| var debug_allocator = std.heap.GeneralPurposeAllocator(.{}){}; | |
| defer _ = debug_allocator.deinit(); | |
| const gpa = debug_allocator.allocator(); | |
| const input = std.mem.span(std.os.argv[1]); | |
| const output = std.mem.span(std.os.argv[2]); | |
| const input_contents = try std.fs.cwd().readFileAlloc(gpa, input, 50_000_000); | |
| defer gpa.free(input_contents); | |
| var fbs = std.io.fixedBufferStream(input_contents); | |
| const elf_header = try std.elf.Header.read(&fbs); | |
| std.log.debug("elf header = {}", .{elf_header}); | |
| const dynamic_table_header = (try getDynamicTable(elf_header, input_contents)) orelse { | |
| std.debug.print("No dynamic table program header found.", .{}); | |
| std.process.exit(1); | |
| }; | |
| const dynamic_table_values = (try getSymbolTable(elf_header, input_contents, dynamic_table_header)) orelse { | |
| std.debug.print("No dynamic symbol table found.", .{}); | |
| std.process.exit(1); | |
| }; | |
| var symbols_to_hide_map = std.StringArrayHashMapUnmanaged(void){}; | |
| defer symbols_to_hide_map.deinit(gpa); | |
| try symbols_to_hide_map.ensureUnusedCapacity(gpa, compiler_rt_symbols.len); | |
| for (compiler_rt_symbols) |symbol_name| { | |
| std.log.debug("hiding symbol {s}", .{symbol_name}); | |
| symbols_to_hide_map.putAssumeCapacityNoClobber(symbol_name, {}); | |
| } | |
| const string_table_file_slice = fileSliceFromVirtualAddress(elf_header, input_contents, dynamic_table_values.string_table_virtual_address, dynamic_table_values.string_table_size) orelse return error.ElfStringSectionNotFound; | |
| const string_table: []const u8 = input_contents[string_table_file_slice.offset..][0..string_table_file_slice.size]; | |
| const output_bytes = try gpa.dupe(u8, input_contents); | |
| defer gpa.free(output_bytes); | |
| var symbol_bytes = input_contents[dynamic_table_values.symbol_table_offset..]; | |
| var i: u64 = 0; | |
| while (i + @sizeOf(std.elf.Elf64_Sym) < symbol_bytes.len) : (i += @sizeOf(std.elf.Elf64_Sym)) { | |
| const symbol = std.mem.bytesAsValue(std.elf.Elf64_Sym, symbol_bytes[i..][0..@sizeOf(std.elf.Elf64_Sym)]); | |
| if (symbol.st_name > string_table.len) { | |
| std.log.debug("symbol 0x{x} = {}", .{ symbol.st_name, symbol }); | |
| break; | |
| } | |
| const name = std.mem.span(@as([*:0]const u8, @ptrCast(string_table[symbol.st_name..].ptr))); | |
| std.log.debug("symbol \"{}\" = {}", .{ std.zig.fmtEscapes(name), symbol }); | |
| if (symbols_to_hide_map.contains(name)) { | |
| const out_symbol = std.mem.bytesAsValue(std.elf.Elf64_Sym, output_bytes[dynamic_table_values.symbol_table_offset..][i..][0..@sizeOf(std.elf.Elf64_Sym)]); | |
| out_symbol.st_other = @intFromEnum(std.elf.STV.HIDDEN); | |
| } | |
| } | |
| // TODO: write modified file to output | |
| try std.fs.cwd().writeFile(.{ | |
| .sub_path = output, | |
| .data = output_bytes, | |
| }); | |
| } | |
| const symbol_names_to_hide_array = [_][:0]const u8{ | |
| // compiler_rt/count0bits | |
| "__clzsi2", | |
| "__clzdi2", | |
| "__clzti2", | |
| "__ctzsi2", | |
| "__ctzdi2", | |
| "__ctzti2", | |
| "__ffssi2", | |
| "__ffsdi2", | |
| "__ffsti2", | |
| // compiler_rt/ceil | |
| "__ceilh", | |
| "ceilf", | |
| "ceil", | |
| "__ceilx", | |
| "ceilf128", | |
| "ceilq", | |
| "ceill", | |
| // compiler_rt/cos | |
| "__cosh", | |
| "cosf", | |
| "cos", | |
| "__cosx", | |
| "cosf128", | |
| "cosq", | |
| "cosl", | |
| // compiler_rt/sin | |
| "__sinh", | |
| "sinf", | |
| "sin", | |
| "__sinx", | |
| "sinf128", | |
| "sinq", | |
| "sinl", | |
| // compiler_rt/sincos | |
| "__sincosh", | |
| "sincosf", | |
| "sincos", | |
| "__sincosx", | |
| "sincosf128", | |
| "sincosq", | |
| "sincosl", | |
| // symbols that are loaded from zig's compiler_rt before the segfault happens | |
| "__zig_probe_stack", | |
| "memset", | |
| "__ubsan_handle_add_overflow", | |
| "__ubsan_handle_mul_overflow", | |
| "__ubsan_handle_sub_overflow", | |
| "__ubsan_handle_alignment_assumption", | |
| "__ubsan_handle_divrem_overflow", | |
| "__ubsan_handle_float_cast_overflow", | |
| "__ubsan_handle_invalid_builtin", | |
| "__ubsan_handle_load_invalid_value", | |
| "__ubsan_handle_negate_overflow", | |
| "__ubsan_handle_nonnull_arg", | |
| "__ubsan_handle_nonnull_return_v1", | |
| "__ubsan_handle_out_of_bounds", | |
| "__ubsan_handle_pointer_overflow", | |
| "__ubsan_handle_shift_out_of_bounds", | |
| "__ubsan_handle_type_mismatch_v1", | |
| "__ubsan_handle_vla_bound_not_positive", | |
| "memcpy", | |
| "__extenddftf2", | |
| "__extendxftf2", | |
| "__umodti3", | |
| "__udivti3", | |
| "__udivmoddi4", | |
| "__extendhfsf2", | |
| "__gnu_f2h_ieee", | |
| "__fixhfti", | |
| "__fixsfti", | |
| "__fixdfti", | |
| "__fixxfti", | |
| "__fixunshfti", | |
| "__fixunssfti", | |
| "__fixunsdfti", | |
| "__fixunsxfti", | |
| "__floattihf", | |
| "__floattisf", | |
| "__floattidf", | |
| "__floattixf", | |
| "__floatuntihf", | |
| "__floatuntisf", | |
| "__floatuntidf", | |
| "__floatuntixf", | |
| "__cmphf2", | |
| "__cmpsf2", | |
| "__cmpdf2", | |
| "__cmptf2", | |
| "__cmpxf2", | |
| "__gehf2", | |
| "__gesf2", | |
| "__gedf2", | |
| "__gexf2", | |
| "__getf2", | |
| "__addtf3", | |
| "__subtf3", | |
| "__multf3", | |
| "__divsf3", | |
| "__divtf3", | |
| "__eqtf2", | |
| "__netf2", | |
| // "__ceilx", | |
| // "ceilq", | |
| // "cosf", | |
| }; | |
| const compiler_rt_symbols = [_][]const u8{ | |
| "__floatsixf", | |
| "_alloca", | |
| "___chkstk_ms", | |
| "__chkstk", | |
| "_chkstk", | |
| "__zig_probe_stack", | |
| "__aarch64_cas1_relax", | |
| "__aarch64_swp1_relax", | |
| "__aarch64_ldadd1_relax", | |
| "__aarch64_ldclr1_relax", | |
| "__aarch64_ldeor1_relax", | |
| "__aarch64_ldset1_relax", | |
| "__aarch64_cas1_acq", | |
| "__aarch64_swp1_acq", | |
| "__aarch64_ldadd1_acq", | |
| "__aarch64_ldclr1_acq", | |
| "__aarch64_ldeor1_acq", | |
| "__aarch64_ldset1_acq", | |
| "__aarch64_cas1_rel", | |
| "__aarch64_swp1_rel", | |
| "__aarch64_ldadd1_rel", | |
| "__aarch64_ldclr1_rel", | |
| "__aarch64_ldeor1_rel", | |
| "__aarch64_ldset1_rel", | |
| "__aarch64_cas1_acq_rel", | |
| "__aarch64_swp1_acq_rel", | |
| "__aarch64_ldadd1_acq_rel", | |
| "__aarch64_ldclr1_acq_rel", | |
| "__aarch64_ldeor1_acq_rel", | |
| "__aarch64_ldset1_acq_rel", | |
| "__aarch64_cas2_relax", | |
| "__aarch64_swp2_relax", | |
| "__aarch64_ldadd2_relax", | |
| "__aarch64_ldclr2_relax", | |
| "__aarch64_ldeor2_relax", | |
| "__aarch64_ldset2_relax", | |
| "__aarch64_cas2_acq", | |
| "__aarch64_swp2_acq", | |
| "__aarch64_ldadd2_acq", | |
| "__aarch64_ldclr2_acq", | |
| "__aarch64_ldeor2_acq", | |
| "__aarch64_ldset2_acq", | |
| "__aarch64_cas2_rel", | |
| "__aarch64_swp2_rel", | |
| "__aarch64_ldadd2_rel", | |
| "__aarch64_ldclr2_rel", | |
| "__aarch64_ldeor2_rel", | |
| "__aarch64_ldset2_rel", | |
| "__aarch64_cas2_acq_rel", | |
| "__aarch64_swp2_acq_rel", | |
| "__aarch64_ldadd2_acq_rel", | |
| "__aarch64_ldclr2_acq_rel", | |
| "__aarch64_ldeor2_acq_rel", | |
| "__aarch64_ldset2_acq_rel", | |
| "__aarch64_cas4_relax", | |
| "__aarch64_swp4_relax", | |
| "__aarch64_ldadd4_relax", | |
| "__aarch64_ldclr4_relax", | |
| "__aarch64_ldeor4_relax", | |
| "__aarch64_ldset4_relax", | |
| "__aarch64_cas4_acq", | |
| "__aarch64_swp4_acq", | |
| "__aarch64_ldadd4_acq", | |
| "__aarch64_ldclr4_acq", | |
| "__aarch64_ldeor4_acq", | |
| "__aarch64_ldset4_acq", | |
| "__aarch64_cas4_rel", | |
| "__aarch64_swp4_rel", | |
| "__aarch64_ldadd4_rel", | |
| "__aarch64_ldclr4_rel", | |
| "__aarch64_ldeor4_rel", | |
| "__aarch64_ldset4_rel", | |
| "__aarch64_cas4_acq_rel", | |
| "__aarch64_swp4_acq_rel", | |
| "__aarch64_ldadd4_acq_rel", | |
| "__aarch64_ldclr4_acq_rel", | |
| "__aarch64_ldeor4_acq_rel", | |
| "__aarch64_ldset4_acq_rel", | |
| "__aarch64_cas8_relax", | |
| "__aarch64_swp8_relax", | |
| "__aarch64_ldadd8_relax", | |
| "__aarch64_ldclr8_relax", | |
| "__aarch64_ldeor8_relax", | |
| "__aarch64_ldset8_relax", | |
| "__aarch64_cas8_acq", | |
| "__aarch64_swp8_acq", | |
| "__aarch64_ldadd8_acq", | |
| "__aarch64_ldclr8_acq", | |
| "__aarch64_ldeor8_acq", | |
| "__aarch64_ldset8_acq", | |
| "__aarch64_cas8_rel", | |
| "__aarch64_swp8_rel", | |
| "__aarch64_ldadd8_rel", | |
| "__aarch64_ldclr8_rel", | |
| "__aarch64_ldeor8_rel", | |
| "__aarch64_ldset8_rel", | |
| "__aarch64_cas8_acq_rel", | |
| "__aarch64_swp8_acq_rel", | |
| "__aarch64_ldadd8_acq_rel", | |
| "__aarch64_ldclr8_acq_rel", | |
| "__aarch64_ldeor8_acq_rel", | |
| "__aarch64_ldset8_acq_rel", | |
| "__aarch64_cas16_relax", | |
| "__aarch64_cas16_acq", | |
| "__aarch64_cas16_rel", | |
| "__aarch64_cas16_acq_rel", | |
| "__logh", | |
| "logf", | |
| "log", | |
| "__logx", | |
| "logf128", | |
| "logq", | |
| "logl", | |
| "__divsc3", | |
| "__subhf3", | |
| "__exp2h", | |
| "exp2f", | |
| "exp2", | |
| "__exp2x", | |
| "exp2f128", | |
| "exp2q", | |
| "exp2l", | |
| "__muldc3", | |
| "__sinh", | |
| "sinf", | |
| "sin", | |
| "__sinx", | |
| "sinf128", | |
| "sinq", | |
| "sinl", | |
| "__extendsfkf2", | |
| "_Qp_stoq", | |
| "__extendsftf2", | |
| "__trunckfsf2", | |
| "_Qp_qtos", | |
| "__trunctfsf2", | |
| "__extenddfkf2", | |
| "_Qp_dtoq", | |
| "__extenddftf2", | |
| "__aeabi_d2iz", | |
| "__fixdfsi", | |
| "__ashlsi3", | |
| "__ashrsi3", | |
| "__lshrsi3", | |
| "__ashlti3", | |
| "__ashrti3", | |
| "__lshrti3", | |
| "__aeabi_llsl", | |
| "__aeabi_lasr", | |
| "__aeabi_llsr", | |
| "__ashldi3", | |
| "__ashrdi3", | |
| "__lshrdi3", | |
| "__mulkf3", | |
| "_Qp_mul", | |
| "__multf3", | |
| "__fixkfdi", | |
| "_Qp_qtox", | |
| "__fixtfdi", | |
| "__aeabi_dsub", | |
| "__subdf3", | |
| "__absvdi2", | |
| "__aeabi_fsub", | |
| "__subsf3", | |
| "__floatunsihf", | |
| "__eqkf2", | |
| "__nekf2", | |
| "__ltkf2", | |
| "__lekf2", | |
| "_Qp_cmp", | |
| "_Qp_feq", | |
| "_Qp_fne", | |
| "_Qp_flt", | |
| "_Qp_fle", | |
| "_Qp_fgt", | |
| "_Qp_fge", | |
| "__eqtf2", | |
| "__netf2", | |
| "__letf2", | |
| "__cmptf2", | |
| "__lttf2", | |
| "__divxf3", | |
| "__aeabi_fcmpge", | |
| "__aeabi_fcmpgt", | |
| "__gesf2", | |
| "__gtsf2", | |
| "__subkf3", | |
| "_Qp_sub", | |
| "__subtf3", | |
| "__negkf2", | |
| "__negtf2", | |
| "__aeabi_dcmpun", | |
| "__unorddf2", | |
| "__floatundihf", | |
| "__unordhf2", | |
| "__sqrth", | |
| "sqrtf", | |
| "sqrt", | |
| "__sqrtx", | |
| "sqrtf128", | |
| "sqrtq", | |
| "sqrtl", | |
| "__aeabi_l2f", | |
| "__floatdisf", | |
| "\x01__allrem", | |
| "\x01__aullrem", | |
| "__aeabi_f2d", | |
| "__extendsfdf2", | |
| "__fixdfti", | |
| "__fixkfsi", | |
| "_Qp_qtoi", | |
| "__fixtfsi", | |
| "__tanh", | |
| "tanf", | |
| "tan", | |
| "__tanx", | |
| "tanf128", | |
| "tanq", | |
| "tanl", | |
| "__fixunskfsi", | |
| "_Qp_qtoui", | |
| "__fixunstfsi", | |
| "\x01__alldiv", | |
| "\x01__aulldiv", | |
| "__mulxf3", | |
| "memmove", | |
| "__gexf2", | |
| "__gtxf2", | |
| "__unordkf2", | |
| "__unordtf2", | |
| "__fixsfti", | |
| "__mulhc3", | |
| "__floatuntihf", | |
| "__aeabi_fadd", | |
| "__addsf3", | |
| "__fixunsdfti", | |
| "__aeabi_f2lz", | |
| "__fixsfdi", | |
| "__floatuntisf", | |
| "__aeabi_dcmpeq", | |
| "__aeabi_dcmplt", | |
| "__aeabi_dcmple", | |
| "__eqdf2", | |
| "__nedf2", | |
| "__ledf2", | |
| "__cmpdf2", | |
| "__ltdf2", | |
| "__fixhfsi", | |
| "__fixhfdi", | |
| "__trunctfhf2", | |
| "__aeabi_fdiv", | |
| "__divsf3", | |
| "bcmp", | |
| "__unordxf2", | |
| "__floattitf", | |
| "__floattikf", | |
| "__negxf2", | |
| "__udivei4", | |
| "__umodei4", | |
| "__aeabi_d2f", | |
| "__truncdfsf2", | |
| "__aeabi_fmul", | |
| "__mulsf3", | |
| "__aeabi_i2d", | |
| "__floatsidf", | |
| "__aeabi_ul2d", | |
| "__floatundidf", | |
| "__aeabi_dneg", | |
| "__negdf2", | |
| "__addosi4", | |
| "__addodi4", | |
| "__addoti4", | |
| "__roundh", | |
| "roundf", | |
| "round", | |
| "__roundx", | |
| "roundf128", | |
| "roundq", | |
| "roundl", | |
| "__extenddfxf2", | |
| "__floattidf", | |
| "__udivti3", | |
| "__floatdikf", | |
| "_Qp_xtoq", | |
| "__floatditf", | |
| "memset", | |
| "__memset", | |
| "__aeabi_ui2f", | |
| "__floatunsisf", | |
| "__extendxftf2", | |
| "__sincosh", | |
| "sincosf", | |
| "sincos", | |
| "__sincosx", | |
| "sincosf128", | |
| "sincosq", | |
| "sincosl", | |
| "__paritysi2", | |
| "__paritydi2", | |
| "__parityti2", | |
| "__fixunshfsi", | |
| "__fixxfsi", | |
| "__cmpsi2", | |
| "__cmpdi2", | |
| "__cmpti2", | |
| "__ucmpsi2", | |
| "__ucmpdi2", | |
| "__ucmpti2", | |
| "__gnu_f2h_ieee", | |
| "__aeabi_f2h", | |
| "__truncsfhf2", | |
| "__fixunsxfsi", | |
| "__powihf2", | |
| "__powisf2", | |
| "__powidf2", | |
| "__powikf2", | |
| "__powitf2", | |
| "__powixf2", | |
| "__divkf3", | |
| "_Qp_div", | |
| "__divtf3", | |
| "__aeabi_i2f", | |
| "__floatsisf", | |
| "__aeabi_f2ulz", | |
| "__fixunssfdi", | |
| "__floatsihf", | |
| "__eqhf2", | |
| "__nehf2", | |
| "__lehf2", | |
| "__cmphf2", | |
| "__lthf2", | |
| "__addxf3", | |
| "__mulhf3", | |
| "__fixxfdi", | |
| "__log10h", | |
| "log10f", | |
| "log10", | |
| "__log10x", | |
| "log10f128", | |
| "log10q", | |
| "log10l", | |
| "__fixunshfdi", | |
| "__aeabi_d2lz", | |
| "__fixdfdi", | |
| "__floattisf", | |
| "__gehf2", | |
| "__gthf2", | |
| "__fixunshfti", | |
| "__fminh", | |
| "fminf", | |
| "fmin", | |
| "__fminx", | |
| "fminf128", | |
| "fminq", | |
| "fminl", | |
| "__truncxfdf2", | |
| "__divxc3", | |
| "__udivmodti4", | |
| "__atomic_load", | |
| "__atomic_store", | |
| "__atomic_exchange", | |
| "__atomic_compare_exchange", | |
| "__atomic_fetch_add_1", | |
| "__atomic_fetch_add_2", | |
| "__atomic_fetch_add_4", | |
| "__atomic_fetch_add_8", | |
| "__atomic_fetch_add_16", | |
| "__atomic_fetch_sub_1", | |
| "__atomic_fetch_sub_2", | |
| "__atomic_fetch_sub_4", | |
| "__atomic_fetch_sub_8", | |
| "__atomic_fetch_sub_16", | |
| "__atomic_fetch_and_1", | |
| "__atomic_fetch_and_2", | |
| "__atomic_fetch_and_4", | |
| "__atomic_fetch_and_8", | |
| "__atomic_fetch_and_16", | |
| "__atomic_fetch_or_1", | |
| "__atomic_fetch_or_2", | |
| "__atomic_fetch_or_4", | |
| "__atomic_fetch_or_8", | |
| "__atomic_fetch_or_16", | |
| "__atomic_fetch_xor_1", | |
| "__atomic_fetch_xor_2", | |
| "__atomic_fetch_xor_4", | |
| "__atomic_fetch_xor_8", | |
| "__atomic_fetch_xor_16", | |
| "__atomic_fetch_nand_1", | |
| "__atomic_fetch_nand_2", | |
| "__atomic_fetch_nand_4", | |
| "__atomic_fetch_nand_8", | |
| "__atomic_fetch_nand_16", | |
| "__atomic_fetch_umax_1", | |
| "__atomic_fetch_umax_2", | |
| "__atomic_fetch_umax_4", | |
| "__atomic_fetch_umax_8", | |
| "__atomic_fetch_umax_16", | |
| "__atomic_fetch_umin_1", | |
| "__atomic_fetch_umin_2", | |
| "__atomic_fetch_umin_4", | |
| "__atomic_fetch_umin_8", | |
| "__atomic_fetch_umin_16", | |
| "__atomic_load_1", | |
| "__atomic_load_2", | |
| "__atomic_load_4", | |
| "__atomic_load_8", | |
| "__atomic_load_16", | |
| "__atomic_store_1", | |
| "__atomic_store_2", | |
| "__atomic_store_4", | |
| "__atomic_store_8", | |
| "__atomic_store_16", | |
| "__atomic_exchange_1", | |
| "__atomic_exchange_2", | |
| "__atomic_exchange_4", | |
| "__atomic_exchange_8", | |
| "__atomic_exchange_16", | |
| "__atomic_compare_exchange_1", | |
| "__atomic_compare_exchange_2", | |
| "__atomic_compare_exchange_4", | |
| "__atomic_compare_exchange_8", | |
| "__atomic_compare_exchange_16", | |
| "__fmaxh", | |
| "fmaxf", | |
| "fmax", | |
| "__fmaxx", | |
| "fmaxf128", | |
| "fmaxq", | |
| "fmaxl", | |
| "__aeabi_fcmpeq", | |
| "__aeabi_fcmplt", | |
| "__aeabi_fcmple", | |
| "__eqsf2", | |
| "__nesf2", | |
| "__lesf2", | |
| "__cmpsf2", | |
| "__ltsf2", | |
| "__negvsi2", | |
| "__negvdi2", | |
| "__negvti2", | |
| "__aeabi_d2ulz", | |
| "__fixunsdfdi", | |
| "__mulsi3", | |
| "__aeabi_lmul", | |
| "__muldi3", | |
| "__multi3", | |
| "__bswapsi2", | |
| "__bswapdi2", | |
| "__bswapti2", | |
| "__divdc3", | |
| "__aeabi_ul2f", | |
| "__floatundisf", | |
| "__log2h", | |
| "log2f", | |
| "log2", | |
| "__log2x", | |
| "log2f128", | |
| "log2q", | |
| "log2l", | |
| "__fixxfti", | |
| "__floattihf", | |
| "__fixunssfti", | |
| "__divhf3", | |
| "__divhc3", | |
| "__modti3", | |
| "__fixunstfti", | |
| "__fixunskfti", | |
| "__fixunskfdi", | |
| "_Qp_qtoux", | |
| "__fixunstfdi", | |
| "__addhf3", | |
| "__mulkc3", | |
| "__multc3", | |
| "__fmodh", | |
| "fmodf", | |
| "fmod", | |
| "__fmodx", | |
| "fmodf128", | |
| "fmodq", | |
| "fmodl", | |
| "__floatuntitf", | |
| "__floatuntikf", | |
| "__aeabi_unwind_cpp_pr0", | |
| "__aeabi_unwind_cpp_pr1", | |
| "__aeabi_unwind_cpp_pr2", | |
| "__aeabi_ldivmod", | |
| "__aeabi_uldivmod", | |
| "__aeabi_idivmod", | |
| "__aeabi_uidivmod", | |
| "__aeabi_memcpy", | |
| "__aeabi_memcpy4", | |
| "__aeabi_memcpy8", | |
| "__aeabi_memmove", | |
| "__aeabi_memmove4", | |
| "__aeabi_memmove8", | |
| "__aeabi_memset", | |
| "__aeabi_memset4", | |
| "__aeabi_memset8", | |
| "__aeabi_memclr", | |
| "__aeabi_memclr4", | |
| "__aeabi_memclr8", | |
| "__aeabi_read_tp", | |
| "__aeabi_frsub", | |
| "__aeabi_drsub", | |
| "__emutls_get_address", | |
| "__extendsfxf2", | |
| "__mulxc3", | |
| "__floorh", | |
| "floorf", | |
| "floor", | |
| "__floorx", | |
| "floorf128", | |
| "floorq", | |
| "floorl", | |
| "__floatuntidf", | |
| "__ceilh", | |
| "ceilf", | |
| "ceil", | |
| "__ceilx", | |
| "ceilf128", | |
| "ceilq", | |
| "ceill", | |
| "__subosi4", | |
| "__subodi4", | |
| "__suboti4", | |
| "__mulosi4", | |
| "__mulodi4", | |
| "__muloti4", | |
| "__gnu_h2f_ieee", | |
| "__aeabi_h2f", | |
| "__extendhfsf2", | |
| "__umodti3", | |
| "__addkf3", | |
| "_Qp_add", | |
| "__addtf3", | |
| "__aeabi_d2h", | |
| "__truncdfhf2", | |
| "__cosh", | |
| "cosf", | |
| "cos", | |
| "__cosx", | |
| "cosf128", | |
| "cosq", | |
| "cosl", | |
| "__truncxfhf2", | |
| "__fixunsxfdi", | |
| "__floatdihf", | |
| "__floatundikf", | |
| "_Qp_uxtoq", | |
| "__floatunditf", | |
| "__exph", | |
| "expf", | |
| "exp", | |
| "__expx", | |
| "expf128", | |
| "expq", | |
| "expl", | |
| "__fixunsxfti", | |
| "__clzsi2", | |
| "__clzdi2", | |
| "__clzti2", | |
| "__ctzsi2", | |
| "__ctzdi2", | |
| "__ctzti2", | |
| "__ffssi2", | |
| "__ffsdi2", | |
| "__ffsti2", | |
| "__divti3", | |
| "__aeabi_ddiv", | |
| "__divdf3", | |
| "__fmah", | |
| "fmaf", | |
| "fma", | |
| "__fmax", | |
| "fmaf128", | |
| "fmaq", | |
| "fmal", | |
| "__fixhfti", | |
| "__isPlatformVersionAtLeast", | |
| "__aeabi_dmul", | |
| "__muldf3", | |
| "__eqxf2", | |
| "__nexf2", | |
| "__lexf2", | |
| "__cmpxf2", | |
| "__ltxf2", | |
| "__fabsh", | |
| "fabsf", | |
| "fabs", | |
| "__fabsx", | |
| "fabsf128", | |
| "fabsq", | |
| "fabsl", | |
| "__aeabi_f2uiz", | |
| "__fixunssfsi", | |
| "__clear_cache", | |
| "memcpy", | |
| "__absvti2", | |
| "__aeabi_fneg", | |
| "__negsf2", | |
| "__aeabi_fcmpun", | |
| "__unordsf2", | |
| "__extendhfdf2", | |
| "__floatsikf", | |
| "_Qp_itoq", | |
| "__floatsitf", | |
| "__popcountsi2", | |
| "__popcountdi2", | |
| "__popcountti2", | |
| "__gekf2", | |
| "__gtkf2", | |
| "__getf2", | |
| "__gttf2", | |
| "__floatdixf", | |
| "__floatundixf", | |
| "__extendhftf2", | |
| "__trunctfxf2", | |
| "__mulsc3", | |
| "__aeabi_f2iz", | |
| "__fixsfsi", | |
| "__floatunsikf", | |
| "_Qp_uitoq", | |
| "__floatunsitf", | |
| "__trunckfdf2", | |
| "_Qp_qtod", | |
| "__trunctfdf2", | |
| "__absvsi2", | |
| "__aeabi_l2d", | |
| "__floatdidf", | |
| "__aeabi_dcmpge", | |
| "__aeabi_dcmpgt", | |
| "__gedf2", | |
| "__gtdf2", | |
| "memcmp", | |
| "__aeabi_d2uiz", | |
| "__fixunsdfsi", | |
| "__extendhfxf2", | |
| "__truncxfsf2", | |
| "__subxf3", | |
| "__fixtfti", | |
| "__fixkfti", | |
| "__neghf2", | |
| "__floattixf", | |
| "__divmodti4", | |
| "__udivmoddi4", | |
| "__divmoddi4", | |
| "__aeabi_idiv", | |
| "__aeabi_uidiv", | |
| "__divsi3", | |
| "__udivsi3", | |
| "__divdi3", | |
| "__udivdi3", | |
| "__modsi3", | |
| "__moddi3", | |
| "__umodsi3", | |
| "__umoddi3", | |
| "__divmodsi4", | |
| "__udivmodsi4", | |
| "__aeabi_ui2d", | |
| "__floatunsidf", | |
| "__trunch", | |
| "truncf", | |
| "trunc", | |
| "__truncx", | |
| "truncf128", | |
| "truncq", | |
| "truncl", | |
| "__stack_chk_fail", | |
| "__chk_fail", | |
| "__stack_chk_guard", | |
| "__strcpy_chk", | |
| "__strncpy_chk", | |
| "__strcat_chk", | |
| "__strncat_chk", | |
| "__memcpy_chk", | |
| "__memmove_chk", | |
| "__memset_chk", | |
| "__aeabi_dadd", | |
| "__adddf3", | |
| "__floatunsixf", | |
| "__floatuntixf", | |
| "__negsi2", | |
| "__negdi2", | |
| "__negti2", | |
| "__divkc3", | |
| "__divtc3", | |
| }; | |
| fn getDynamicTable(elf_header: std.elf.Header, elf_bytes: []const u8) !?Elf64_Phdr { | |
| const program_headers_len = @as(u64, elf_header.phentsize) * elf_header.phoff; | |
| var program_header_bytes = elf_bytes[elf_header.phoff..][0..program_headers_len]; | |
| var program_header_offset: u64 = 0; | |
| while (program_header_offset < program_header_bytes.len) : (program_header_offset += elf_header.phentsize) { | |
| if (elf_header.is_64) { | |
| std.debug.assert(elf_header.endian == builtin.cpu.arch.endian()); | |
| const program_header = std.mem.bytesAsValue(Elf64_Phdr, program_header_bytes[program_header_offset..][0..@sizeOf(elf.Elf64_Phdr)]); | |
| std.log.debug("program header = {}", .{program_header}); | |
| switch (program_header.type) { | |
| .dynamic => return program_header.*, | |
| else => {}, | |
| } | |
| } else { | |
| const program_header = std.mem.bytesAsValue(elf.Elf32_Phdr, program_header_bytes[program_header_offset..][0..@sizeOf(elf.Elf32_Phdr)]); | |
| _ = program_header; | |
| @panic("TODO: unimplemented"); | |
| } | |
| } | |
| return null; | |
| } | |
| const DynamicTableValues = struct { | |
| string_table_virtual_address: u64, | |
| string_table_size: u64, | |
| symbol_table_offset: u64, | |
| }; | |
| fn getSymbolTable(elf_header: std.elf.Header, elf_bytes: []const u8, dynamic_table: Elf64_Phdr) !?DynamicTableValues { | |
| std.debug.assert(elf_header.endian == builtin.cpu.arch.endian()); | |
| std.debug.assert(elf_header.is_64); | |
| const dynv = std.mem.bytesAsSlice(u64, elf_bytes[dynamic_table.p_offset..][0..dynamic_table.p_filesz]); | |
| var string_table_virtual_address: ?u64 = null; | |
| var strings_size_opt: ?u64 = null; | |
| var symbol_table_offset_opt: ?u64 = null; | |
| var i: usize = 0; | |
| while (dynv[i] != 0) : (i += 2) { | |
| const dt_type: DynamicTableType = @enumFromInt(dynv[i]); | |
| const value = dynv[i + 1]; | |
| switch (dt_type) { | |
| .null => break, | |
| .strtab => string_table_virtual_address = value, | |
| .strsz => strings_size_opt = value, | |
| .symtab => symbol_table_offset_opt = value, | |
| else => if (std.enums.tagName(DynamicTableType, dt_type)) |tag_name| { | |
| std.log.debug("dt {s} (0x{x}) = {}", .{ tag_name, @intFromEnum(dt_type), value }); | |
| } else { | |
| std.log.debug("dt unknown (0x{x}) = {}", .{ @intFromEnum(dt_type), value }); | |
| }, | |
| } | |
| } | |
| return .{ | |
| .string_table_virtual_address = string_table_virtual_address orelse return null, | |
| .string_table_size = strings_size_opt orelse return null, | |
| .symbol_table_offset = symbol_table_offset_opt orelse return null, | |
| }; | |
| } | |
| pub const Elf64_Phdr = extern struct { | |
| type: Type, | |
| p_flags: u32, | |
| p_offset: std.elf.Elf64_Off, | |
| p_vaddr: std.elf.Elf64_Addr, | |
| p_paddr: std.elf.Elf64_Addr, | |
| p_filesz: std.elf.Elf64_Xword, | |
| p_memsz: std.elf.Elf64_Xword, | |
| p_align: std.elf.Elf64_Xword, | |
| pub const Type = enum(u32) { | |
| /// Program header table entry unused | |
| null = 0, | |
| /// Loadable program segment | |
| load = 1, | |
| /// Dynamic linking information | |
| dynamic = 2, | |
| /// Program interpreter | |
| interp = 3, | |
| /// Auxiliary information | |
| note = 4, | |
| /// Reserved | |
| shlib = 5, | |
| /// Entry for header table itself | |
| phdr = 6, | |
| /// Thread-local storage segment | |
| tls = 7, | |
| /// Number of defined types | |
| num = 8, | |
| _, | |
| /// Start of OS-specific | |
| pub const loos = 0x60000000; | |
| /// GCC .eh_frame_hdr segment | |
| pub const gnu_eh_frame = 0x6474e550; | |
| /// Indicates stack executability | |
| pub const gnu_stack = 0x6474e551; | |
| /// Read-only after relocation | |
| pub const gnu_relro = 0x6474e552; | |
| pub const losunw = 0x6ffffffa; | |
| /// Sun specific segment | |
| pub const sunwbss = 0x6ffffffa; | |
| /// Stack segment | |
| pub const sunwstack = 0x6ffffffb; | |
| pub const hisunw = 0x6fffffff; | |
| /// End of OS-specific | |
| pub const hios = 0x6fffffff; | |
| /// Start of processor-specific | |
| pub const loproc = 0x70000000; | |
| /// End of processor-specific | |
| pub const hiproc = 0x7fffffff; | |
| }; | |
| }; | |
| pub const DynamicTableType = enum(u32) { | |
| null = 0, | |
| needed = 1, | |
| pltrelsz = 2, | |
| pltgot = 3, | |
| hash = 4, | |
| strtab = 5, | |
| symtab = 6, | |
| rela = 7, | |
| relasz = 8, | |
| relaent = 9, | |
| strsz = 10, | |
| syment = 11, | |
| init = 12, | |
| fini = 13, | |
| soname = 14, | |
| rpath = 15, | |
| symbolic = 16, | |
| rel = 17, | |
| relsz = 18, | |
| relent = 19, | |
| pltrel = 20, | |
| debug = 21, | |
| textrel = 22, | |
| jmprel = 23, | |
| bind_now = 24, | |
| init_array = 25, | |
| fini_array = 26, | |
| init_arraysz = 27, | |
| fini_arraysz = 28, | |
| runpath = 29, | |
| flags = 30, | |
| preinit_array = 32, | |
| preinit_arraysz = 33, | |
| symtab_shndx = 34, | |
| relrsz = 35, | |
| relr = 36, | |
| relrent = 37, | |
| num = 38, | |
| gnu_hash = 0x6ffffef5, | |
| versym = 0x6ffffff0, | |
| relacount = 0x6ffffff9, | |
| relcount = 0x6ffffffa, | |
| flags_1 = 0x6ffffffb, | |
| verdef = 0x6ffffffc, | |
| verdefnum = 0x6ffffffd, | |
| verneed = 0x6ffffffe, | |
| verneednum = 0x6fffffff, | |
| _, | |
| pub const encoding: @This() = @enumFromInt(32); | |
| pub const loos = 0x6000000d; | |
| pub const hios = 0x6ffff000; | |
| pub const loproc = 0x70000000; | |
| pub const hiproc = 0x7fffffff; | |
| pub const procnum = DT_MIPS_NUM; | |
| pub const DT_VALRNGLO = 0x6ffffd00; | |
| pub const DT_GNU_PRELINKED = 0x6ffffdf5; | |
| pub const DT_GNU_CONFLICTSZ = 0x6ffffdf6; | |
| pub const DT_GNU_LIBLISTSZ = 0x6ffffdf7; | |
| pub const DT_CHECKSUM = 0x6ffffdf8; | |
| pub const DT_PLTPADSZ = 0x6ffffdf9; | |
| pub const DT_MOVEENT = 0x6ffffdfa; | |
| pub const DT_MOVESZ = 0x6ffffdfb; | |
| pub const DT_FEATURE_1 = 0x6ffffdfc; | |
| pub const DT_POSFLAG_1 = 0x6ffffdfd; | |
| pub const DT_SYMINSZ = 0x6ffffdfe; | |
| pub const DT_SYMINENT = 0x6ffffdff; | |
| pub const DT_VALRNGHI = 0x6ffffdff; | |
| pub const DT_VALNUM = 12; | |
| pub const DT_ADDRRNGLO = 0x6ffffe00; | |
| pub const DT_GNU_HASH = 0x6ffffef5; | |
| pub const DT_TLSDESC_PLT = 0x6ffffef6; | |
| pub const DT_TLSDESC_GOT = 0x6ffffef7; | |
| pub const DT_GNU_CONFLICT = 0x6ffffef8; | |
| pub const DT_GNU_LIBLIST = 0x6ffffef9; | |
| pub const DT_CONFIG = 0x6ffffefa; | |
| pub const DT_DEPAUDIT = 0x6ffffefb; | |
| pub const DT_AUDIT = 0x6ffffefc; | |
| pub const DT_PLTPAD = 0x6ffffefd; | |
| pub const DT_MOVETAB = 0x6ffffefe; | |
| pub const DT_SYMINFO = 0x6ffffeff; | |
| pub const DT_ADDRRNGHI = 0x6ffffeff; | |
| pub const DT_ADDRNUM = 11; | |
| pub const DT_VERSIONTAGNUM = 16; | |
| pub const DT_AUXILIARY = 0x7ffffffd; | |
| pub const DT_FILTER = 0x7fffffff; | |
| pub const DT_EXTRANUM = 3; | |
| pub const DT_SPARC_REGISTER = 0x70000001; | |
| pub const DT_SPARC_NUM = 2; | |
| pub const DT_MIPS_RLD_VERSION = 0x70000001; | |
| pub const DT_MIPS_TIME_STAMP = 0x70000002; | |
| pub const DT_MIPS_ICHECKSUM = 0x70000003; | |
| pub const DT_MIPS_IVERSION = 0x70000004; | |
| pub const DT_MIPS_FLAGS = 0x70000005; | |
| pub const DT_MIPS_BASE_ADDRESS = 0x70000006; | |
| pub const DT_MIPS_MSYM = 0x70000007; | |
| pub const DT_MIPS_CONFLICT = 0x70000008; | |
| pub const DT_MIPS_LIBLIST = 0x70000009; | |
| pub const DT_MIPS_LOCAL_GOTNO = 0x7000000a; | |
| pub const DT_MIPS_CONFLICTNO = 0x7000000b; | |
| pub const DT_MIPS_LIBLISTNO = 0x70000010; | |
| pub const DT_MIPS_SYMTABNO = 0x70000011; | |
| pub const DT_MIPS_UNREFEXTNO = 0x70000012; | |
| pub const DT_MIPS_GOTSYM = 0x70000013; | |
| pub const DT_MIPS_HIPAGENO = 0x70000014; | |
| pub const DT_MIPS_RLD_MAP = 0x70000016; | |
| pub const DT_MIPS_DELTA_CLASS = 0x70000017; | |
| pub const DT_MIPS_DELTA_CLASS_NO = 0x70000018; | |
| pub const DT_MIPS_DELTA_INSTANCE = 0x70000019; | |
| pub const DT_MIPS_DELTA_INSTANCE_NO = 0x7000001a; | |
| pub const DT_MIPS_DELTA_RELOC = 0x7000001b; | |
| pub const DT_MIPS_DELTA_RELOC_NO = 0x7000001c; | |
| pub const DT_MIPS_DELTA_SYM = 0x7000001d; | |
| pub const DT_MIPS_DELTA_SYM_NO = 0x7000001e; | |
| pub const DT_MIPS_DELTA_CLASSSYM = 0x70000020; | |
| pub const DT_MIPS_DELTA_CLASSSYM_NO = 0x70000021; | |
| pub const DT_MIPS_CXX_FLAGS = 0x70000022; | |
| pub const DT_MIPS_PIXIE_INIT = 0x70000023; | |
| pub const DT_MIPS_SYMBOL_LIB = 0x70000024; | |
| pub const DT_MIPS_LOCALPAGE_GOTIDX = 0x70000025; | |
| pub const DT_MIPS_LOCAL_GOTIDX = 0x70000026; | |
| pub const DT_MIPS_HIDDEN_GOTIDX = 0x70000027; | |
| pub const DT_MIPS_PROTECTED_GOTIDX = 0x70000028; | |
| pub const DT_MIPS_OPTIONS = 0x70000029; | |
| pub const DT_MIPS_INTERFACE = 0x7000002a; | |
| pub const DT_MIPS_DYNSTR_ALIGN = 0x7000002b; | |
| pub const DT_MIPS_INTERFACE_SIZE = 0x7000002c; | |
| pub const DT_MIPS_RLD_TEXT_RESOLVE_ADDR = 0x7000002d; | |
| pub const DT_MIPS_PERF_SUFFIX = 0x7000002e; | |
| pub const DT_MIPS_COMPACT_SIZE = 0x7000002f; | |
| pub const DT_MIPS_GP_VALUE = 0x70000030; | |
| pub const DT_MIPS_AUX_DYNAMIC = 0x70000031; | |
| pub const DT_MIPS_PLTGOT = 0x70000032; | |
| pub const DT_MIPS_RWPLT = 0x70000034; | |
| pub const DT_MIPS_RLD_MAP_REL = 0x70000035; | |
| pub const DT_MIPS_NUM = 0x36; | |
| pub const DT_ALPHA_PLTRO = (loproc + 0); | |
| pub const DT_ALPHA_NUM = 1; | |
| pub const DT_PPC_GOT = (loproc + 0); | |
| pub const DT_PPC_OPT = (loproc + 1); | |
| pub const DT_PPC_NUM = 2; | |
| pub const DT_PPC64_GLINK = (loproc + 0); | |
| pub const DT_PPC64_OPD = (loproc + 1); | |
| pub const DT_PPC64_OPDSZ = (loproc + 2); | |
| pub const DT_PPC64_OPT = (loproc + 3); | |
| pub const DT_PPC64_NUM = 4; | |
| pub const DT_IA_64_PLT_RESERVE = (loproc + 0); | |
| pub const DT_IA_64_NUM = 1; | |
| pub const DT_NIOS2_GP = 0x70000002; | |
| }; | |
| const FileSlice = struct { | |
| offset: u64, | |
| size: u64, | |
| }; | |
| fn fileSliceFromVirtualAddress(elf_header: std.elf.Header, elf_bytes: []const u8, virtual_address: u64, virtual_address_size: u64) ?FileSlice { | |
| const program_headers_len = @as(u64, elf_header.phentsize) * elf_header.phoff; | |
| var program_header_bytes = elf_bytes[elf_header.phoff..][0..program_headers_len]; | |
| var program_header_offset: u64 = 0; | |
| while (program_header_offset < program_header_bytes.len) : (program_header_offset += elf_header.phentsize) { | |
| if (elf_header.is_64) { | |
| std.debug.assert(elf_header.endian == builtin.cpu.arch.endian()); | |
| const program_header = std.mem.bytesAsValue(Elf64_Phdr, program_header_bytes[program_header_offset..][0..@sizeOf(elf.Elf64_Phdr)]); | |
| if (virtual_address > program_header.p_vaddr and virtual_address < program_header.p_vaddr + program_header.p_filesz) { | |
| return .{ | |
| .offset = virtual_address - program_header.p_vaddr + program_header.p_offset, | |
| .size = virtual_address_size, | |
| }; | |
| } | |
| } else { | |
| const program_header = std.mem.bytesAsValue(elf.Elf32_Phdr, program_header_bytes[program_header_offset..][0..@sizeOf(elf.Elf32_Phdr)]); | |
| _ = program_header; | |
| @panic("TODO: unimplemented"); | |
| } | |
| } | |
| return null; | |
| } | |
| const elf = std.elf; | |
| const mem = std.mem; | |
| const posix = std.posix; | |
| const builtin = @import("builtin"); | |
| const std = @import("std"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment