summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-07-31 21:09:06 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-07-31 21:09:06 +0200
commit378e17cdd8d36a08fe65041f96de5a80dabf2ce5 (patch)
tree4c5e43f69aac0e73450bfb3db5f7a18f0bfa14e0
parent194f3f6cbad70c3a880736bca70e98a2bffe32c4 (diff)
downloadbxgen-378e17cdd8d36a08fe65041f96de5a80dabf2ce5.zip
Map elf header segment
-rwxr-xr-xbxgen.c191
1 files changed, 130 insertions, 61 deletions
diff --git a/bxgen.c b/bxgen.c
index 0f6da1c..24c1f4e 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -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);
// ==============================================================