diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2024-07-31 21:09:06 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2024-07-31 21:09:06 +0200 |
commit | 378e17cdd8d36a08fe65041f96de5a80dabf2ce5 (patch) | |
tree | 4c5e43f69aac0e73450bfb3db5f7a18f0bfa14e0 | |
parent | 194f3f6cbad70c3a880736bca70e98a2bffe32c4 (diff) | |
download | bxgen-378e17cdd8d36a08fe65041f96de5a80dabf2ce5.zip |
Map elf header segment
-rwxr-xr-x | bxgen.c | 191 |
1 files changed, 130 insertions, 61 deletions
@@ -84,7 +84,7 @@ #/ #/ Bugs #/ -#/ - ... +#/ - Segfault at 0x4018ff #/ #/ Done features #/ @@ -2653,12 +2653,12 @@ i64 unit_write_in_memory( i64 program_offset = bx_align(ELF_HEADER_SIZE + ELF_PROGRAM_HEADER_SIZE * num_program_headers, X86_64_ALIGNMENT); i64 base_address = X86_64_BASE_ADDRESS; - i64 rotext_address = base_address + program_offset; - i64 entry = rotext_address + codegen->entry_point; + i64 rxcode_address = base_address + program_offset; + i64 entry = rxcode_address + codegen->entry_point; LOG(VERBOSE, "Entry point: 0x%llx (%lld)", entry, entry); - i64 rotext_size = codegen->offset_code; + i64 rxcode_size = codegen->offset_code; i64 rwzval_size = 0; i64 rwdata_size = 0; i64 rodata_size = codegen->offset_rodata; @@ -2688,9 +2688,9 @@ i64 unit_write_in_memory( continue; if (section.exec) { - linker->section_offsets[num_sections_total] = rotext_size; - linker->section_addresses[num_sections_total] = rotext_size; - rotext_size += bx_align(section.data.size, X86_64_ALIGNMENT); + linker->section_offsets[num_sections_total] = rxcode_size; + linker->section_addresses[num_sections_total] = rxcode_size; + rxcode_size += bx_align(section.data.size, X86_64_ALIGNMENT); } else if (section.write && section.type == SEC_NOBITS) { linker->section_addresses[num_sections_total] = rwzval_size; rwzval_size += bx_align(section.data.size, X86_64_ALIGNMENT); @@ -2709,17 +2709,17 @@ i64 unit_write_in_memory( } } - rotext_size = bx_align(rotext_size, X86_64_PAGE_SIZE); + rxcode_size = bx_align(rxcode_size, X86_64_PAGE_SIZE); rwzval_size = bx_align(rwzval_size, X86_64_PAGE_SIZE); rwdata_size = bx_align(rwdata_size, X86_64_PAGE_SIZE); rodata_size = bx_align(rodata_size, X86_64_PAGE_SIZE); - i64 rwzval_address = rotext_address + rotext_size; + i64 rwzval_address = rxcode_address + rxcode_size; i64 rwdata_address = rwzval_address + rwzval_size; i64 rodata_address = rwdata_address + rwdata_size; - i64 rotext_offset = program_offset; - i64 rwdata_offset = rotext_offset + rotext_size; + i64 rxcode_offset = program_offset; + i64 rwdata_offset = rxcode_offset + rxcode_size; i64 rodata_offset = rwdata_offset + rwdata_size; for (i64 elf_index = 0, sec_index_global = 0; elf_index < linker->num_obj_files; ++elf_index) { @@ -2735,8 +2735,8 @@ i64 unit_write_in_memory( continue; if (section.exec) { - linker->section_offsets[sec_index_global] += rotext_offset + codegen->offset_code; - linker->section_addresses[sec_index_global] += rotext_address + codegen->offset_code; + linker->section_offsets[sec_index_global] += rxcode_offset + codegen->offset_code; + linker->section_addresses[sec_index_global] += rxcode_address + codegen->offset_code; } else if (section.write && section.type == SEC_NOBITS) { linker->section_addresses[sec_index_global] += rwzval_address; } else if (section.write) { @@ -2817,8 +2817,8 @@ i64 unit_write_in_memory( // _Unwind_GetCFA // // _init - // _end // _fini + // _end // _dl_rtld_map // __ehdr_start // __pthread_initialize_minimal @@ -2954,6 +2954,60 @@ i64 unit_write_in_memory( // LOG(VERBOSE, "--"); switch (relx.type) { + #define SKIP_(x) \ + if (relx.symbol.name.size == sizeof(#x) - 1 && \ + mem_eq(sym_name, #x, sizeof(#x) - 1)) \ + break; + + case R_X86_64_64: + case R_X86_64_PC32: + case R_X86_64_PLT32: + case R_X86_64_GOTTPOFF: + case R_X86_64_TPOFF32: + + SKIP_(_DYNAMIC); + + SKIP_(__preinit_array_start); + SKIP_(__preinit_array_end); + SKIP_(__init_array_start); + SKIP_(__init_array_end); + SKIP_(__fini_array_start); + SKIP_(__fini_array_end); + SKIP_(__gcc_personality_v0); + SKIP_(__pthread_initialize_minimal); + + SKIP_(_init); + SKIP_(_fini); + + SKIP_(_end); + SKIP_(_Unwind_Resume); + SKIP_(_Unwind_Backtrace); + SKIP_(_Unwind_ForcedUnwind); + SKIP_(_Unwind_GetIP); + SKIP_(_Unwind_GetCFA); + + SKIP_(__addtf3); + SKIP_(__subtf3); + SKIP_(__multf3); + SKIP_(__divtf3); + SKIP_(__eqtf2); + SKIP_(__lttf2); + SKIP_(__letf2); + SKIP_(__gttf2); + SKIP_(__getf2); + SKIP_(__unordtf2); + + if (S == 0) + LOG(VERBOSE, "Check symbol: %s", sym_name); + CHECK(S != 0, "Symbol address is 0", 0); + break; + + #undef SKIP_ + + default:; + } + + switch (relx.type) { #define ADD_(BITS, OP) \ do { \ i64 x_ = read_i##BITS(LE, dst, buf.end) + (OP); \ @@ -3028,7 +3082,7 @@ i64 unit_write_in_memory( switch (rel.type) { case REL_ADD_INSTRUCTION_ADDRESS: { CHECK(rel.size == 8, "Not implemented", 0); - i64 value = rel.value + rotext_address + rel.offset; + i64 value = rel.value + rxcode_address + rel.offset; write_i64(LE, value, begin, end); } break; @@ -3063,7 +3117,7 @@ i64 unit_write_in_memory( Proc *p = &pool->entities[rel.proc].proc; CHECK(p->codegen.emit_done, "No proc address", 0); - i64 value = rel.value + rotext_address + p->codegen.offset; + i64 value = rel.value + rxcode_address + p->codegen.offset; write_i64(LE, value, begin, end); found = 1; @@ -3083,7 +3137,7 @@ i64 unit_write_in_memory( // Writing the ELF executable // - i64 output_size = bx_align(program_offset + rotext_size + rwzval_size + rwdata_size + rodata_size, X86_64_ALIGNMENT); + i64 output_size = bx_align(program_offset + rxcode_size + rwzval_size + rwdata_size + rodata_size, X86_64_ALIGNMENT); CHECK(output_size <= linker->max_output_size, "Out of memory",); @@ -3091,7 +3145,7 @@ i64 unit_write_in_memory( LOG(VERBOSE, "Total %lld symbols", num_symbols); LOG(VERBOSE, "Total size"); - LOG(VERBOSE, ".rotext - %7lld bytes", rotext_size); + LOG(VERBOSE, ".rxcode - %7lld bytes", rxcode_size); LOG(VERBOSE, ".rwzval - %7lld bytes", rwzval_size); LOG(VERBOSE, ".rwdata - %7lld bytes", rwdata_size); LOG(VERBOSE, ".rodata - %7lld bytes", rodata_size); @@ -3130,56 +3184,71 @@ i64 unit_write_in_memory( // Program headers // - CHECK(rotext_offset % X86_64_PAGE_SIZE == rotext_address % X86_64_PAGE_SIZE, "Invalid alignment",); + CHECK(rxcode_offset % X86_64_PAGE_SIZE == rxcode_address % X86_64_PAGE_SIZE, "Invalid alignment",); CHECK(rwdata_offset % X86_64_PAGE_SIZE == rwdata_address % X86_64_PAGE_SIZE, "Invalid alignment",); CHECK(rodata_offset % X86_64_PAGE_SIZE == rodata_address % X86_64_PAGE_SIZE, "Invalid alignment",); - // .rotext - write_u32(LE, 1, o + 64, o_end); // type (PT_LOAD) - write_u32(LE, 5, o + 68, o_end); // flags (PF_X | PF_R) - write_i64(LE, rotext_offset, o + 72, o_end); - write_i64(LE, rotext_address, o + 80, o_end); // virtual address - write_i64(LE, rotext_address, o + 88, o_end); // phisical address - write_i64(LE, rotext_size, o + 96, o_end); // size in file - write_i64(LE, rotext_size, o + 104, o_end); // size in memory - write_i64(LE, X86_64_ALIGNMENT, o + 112, o_end); - - // .rwzval - write_u32(LE, 1, o + 120, o_end); // type (PT_LOAD) - write_u32(LE, 6, o + 124, o_end); // flags (PF_R | PF_W) - write_i64(LE, rwdata_offset, o + 128, o_end); - write_i64(LE, rwzval_address, o + 136, o_end); // virtual address - write_i64(LE, rwzval_address, o + 144, o_end); // phisical address - write_i64(LE, 0, o + 152, o_end); // size in file - write_i64(LE, rwzval_size, o + 160, o_end); // size in memory - write_i64(LE, X86_64_ALIGNMENT, o + 168, o_end); - - // .rwdata - write_u32(LE, 1, o + 176, o_end); // type (PT_LOAD) - write_u32(LE, 6, o + 180, o_end); // flags (PF_R | PF_W) - write_i64(LE, rwdata_offset, o + 184, o_end); - write_i64(LE, rwdata_address, o + 192, o_end); // virtual address - write_i64(LE, rwdata_address, o + 200, o_end); // phisical address - write_i64(LE, rwdata_size, o + 208, o_end); // size in file - write_i64(LE, rwdata_size, o + 216, o_end); // size in memory - write_i64(LE, X86_64_ALIGNMENT, o + 224, o_end); - - // .rodata - write_u32(LE, 1, o + 232, o_end); // type (PT_LOAD) - write_u32(LE, 4, o + 236, o_end); // flags (PF_R) - write_i64(LE, rodata_offset, o + 240, o_end); - write_i64(LE, rodata_address, o + 248, o_end); // virtual address - write_i64(LE, rodata_address, o + 256, o_end); // phisical address - write_i64(LE, rodata_size, o + 264, o_end); // size in file - write_i64(LE, rodata_size, o + 272, o_end); // size in memory - write_i64(LE, X86_64_ALIGNMENT, o + 280, o_end); - - CHECK(rotext_offset >= 288, "Sanity",); + // r/o elf header + u8 *h = o + ELF_HEADER_SIZE; + write_u32(LE, 1, h, o_end); // type (PT_LOAD) + write_u32(LE, 4, h + 4, o_end); // flags (PF_R) + write_i64(LE, 0, h + 8, o_end); + write_i64(LE, base_address, h + 16, o_end); // virtual address + write_i64(LE, base_address, h + 24, o_end); // phisical address + write_i64(LE, ELF_HEADER_SIZE, h + 32, o_end); // size in file + write_i64(LE, ELF_HEADER_SIZE, h + 40, o_end); // size in memory + write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end); + + // r/x code + h += ELF_PROGRAM_HEADER_SIZE; + write_u32(LE, 1, h, o_end); // type (PT_LOAD) + write_u32(LE, 5, h + 4, o_end); // flags (PF_X | PF_R) + write_i64(LE, rxcode_offset, h + 8, o_end); + write_i64(LE, rxcode_address, h + 16, o_end); // virtual address + write_i64(LE, rxcode_address, h + 24, o_end); // phisical address + write_i64(LE, rxcode_size, h + 32, o_end); // size in file + write_i64(LE, rxcode_size, h + 40, o_end); // size in memory + write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end); + + // r/w zero values + h += ELF_PROGRAM_HEADER_SIZE; + write_u32(LE, 1, h, o_end); // type (PT_LOAD) + write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W) + write_i64(LE, rwdata_offset, h + 8, o_end); + write_i64(LE, rwzval_address, h + 16, o_end); // virtual address + write_i64(LE, rwzval_address, h + 24, o_end); // phisical address + write_i64(LE, 0, h + 32, o_end); // size in file + write_i64(LE, rwzval_size, h + 40, o_end); // size in memory + write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end); + + // r/w data + h += ELF_PROGRAM_HEADER_SIZE; + write_u32(LE, 1, h, o_end); // type (PT_LOAD) + write_u32(LE, 6, h + 4, o_end); // flags (PF_R | PF_W) + write_i64(LE, rwdata_offset, h + 8, o_end); + write_i64(LE, rwdata_address, h + 16, o_end); // virtual address + write_i64(LE, rwdata_address, h + 24, o_end); // phisical address + write_i64(LE, rwdata_size, h + 32, o_end); // size in file + write_i64(LE, rwdata_size, h + 40, o_end); // size in memory + write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end); + + // r/o data + h += ELF_PROGRAM_HEADER_SIZE; + write_u32(LE, 1, h, o_end); // type (PT_LOAD) + write_u32(LE, 4, h + 4, o_end); // flags (PF_R) + write_i64(LE, rodata_offset, h + 8, o_end); + write_i64(LE, rodata_address, h + 16, o_end); // virtual address + write_i64(LE, rodata_address, h + 24, o_end); // phisical address + write_i64(LE, rodata_size, h + 32, o_end); // size in file + write_i64(LE, rodata_size, h + 40, o_end); // size in memory + write_i64(LE, X86_64_ALIGNMENT, h + 48, o_end); + + CHECK(rxcode_offset >= 288, "Sanity",); // Code // - mem_cpy(o + rotext_offset, codegen->buffer_code, codegen->offset_code); + mem_cpy(o + rxcode_offset, codegen->buffer_code, codegen->offset_code); mem_cpy(o + rodata_offset, codegen->buffer_rodata, codegen->offset_rodata); // ============================================================== |