Understand .gnu.version_r
This commit is contained in:
parent
b0a6e65d42
commit
da5d5d11c6
@ -1610,13 +1610,29 @@ may_be_unused fn void calibrate_cpu_timer()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
fn u8* os_reserve(u64 size)
|
STRUCT(OSReserveProtectionFlags)
|
||||||
|
{
|
||||||
|
u32 read:1;
|
||||||
|
u32 write:1;
|
||||||
|
u32 execute:1;
|
||||||
|
u32 reserved:29;
|
||||||
|
};
|
||||||
|
|
||||||
|
STRUCT(OSReserveMapFlags)
|
||||||
|
{
|
||||||
|
u32 priv:1;
|
||||||
|
u32 anon:1;
|
||||||
|
u32 noreserve:1;
|
||||||
|
u32 reserved:29;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn u8* os_reserve(u64 base, u64 size, OSReserveProtectionFlags protection, OSReserveMapFlags map)
|
||||||
{
|
{
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
return (u8*)VirtualAlloc(0, size, MEM_RESERVE, PAGE_READWRITE);
|
return (u8*)VirtualAlloc(0, size, MEM_RESERVE, PAGE_READWRITE);
|
||||||
#else
|
#else
|
||||||
int protection_flags = PROT_NONE;
|
int protection_flags = (protection.read * PROT_READ) | (protection.write * PROT_WRITE) | (protection.execute * PROT_EXEC);
|
||||||
int map_flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE;
|
int map_flags = (map.anon * MAP_ANONYMOUS) | (map.priv * MAP_PRIVATE) | (map.noreserve * MAP_NORESERVE);
|
||||||
u8* result = (u8*)posix_mmap(0, size, protection_flags, map_flags, -1, 0);
|
u8* result = (u8*)posix_mmap(0, size, protection_flags, map_flags, -1, 0);
|
||||||
assert(result != MAP_FAILED);
|
assert(result != MAP_FAILED);
|
||||||
return result;
|
return result;
|
||||||
@ -1640,6 +1656,12 @@ fn u64 align_forward(u64 value, u64 alignment)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn u64 align_backward(u64 value, u64 alignment)
|
||||||
|
{
|
||||||
|
u64 result = value & ~(alignment - 1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
fn u32 format_hexadecimal(String buffer, u64 hexadecimal)
|
fn u32 format_hexadecimal(String buffer, u64 hexadecimal)
|
||||||
{
|
{
|
||||||
u64 value = hexadecimal;
|
u64 value = hexadecimal;
|
||||||
@ -2791,7 +2813,13 @@ static_assert(sizeof(Arena) == 64);
|
|||||||
|
|
||||||
fn Arena* arena_init(u64 reserved_size, u64 granularity, u64 initial_size)
|
fn Arena* arena_init(u64 reserved_size, u64 granularity, u64 initial_size)
|
||||||
{
|
{
|
||||||
Arena* arena = (Arena*)os_reserve(reserved_size);
|
Arena* arena = (Arena*)os_reserve(0, reserved_size,
|
||||||
|
(OSReserveProtectionFlags) {},
|
||||||
|
(OSReserveMapFlags) {
|
||||||
|
.priv = 1,
|
||||||
|
.anon = 1,
|
||||||
|
.noreserve = 1,
|
||||||
|
});
|
||||||
commit(arena, initial_size);
|
commit(arena, initial_size);
|
||||||
*arena = (Arena){
|
*arena = (Arena){
|
||||||
.reserved_size = reserved_size,
|
.reserved_size = reserved_size,
|
||||||
@ -2954,6 +2982,7 @@ decl_vb(u8);
|
|||||||
decl_vbp(u8);
|
decl_vbp(u8);
|
||||||
decl_vb(s32);
|
decl_vb(s32);
|
||||||
decl_vb(u32);
|
decl_vb(u32);
|
||||||
|
decl_vb(String);
|
||||||
|
|
||||||
fn void vb_generic_ensure_capacity(VirtualBuffer(u8)* vb, u32 item_size, u32 item_count)
|
fn void vb_generic_ensure_capacity(VirtualBuffer(u8)* vb, u32 item_size, u32 item_count)
|
||||||
{
|
{
|
||||||
@ -2964,7 +2993,7 @@ fn void vb_generic_ensure_capacity(VirtualBuffer(u8)* vb, u32 item_size, u32 ite
|
|||||||
{
|
{
|
||||||
if (old_capacity == 0)
|
if (old_capacity == 0)
|
||||||
{
|
{
|
||||||
vb->pointer = os_reserve(item_size * UINT32_MAX);
|
vb->pointer = os_reserve(0, item_size * UINT32_MAX, (OSReserveProtectionFlags) {}, (OSReserveMapFlags) { .priv = 1, .anon = 1, .noreserve = 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 old_page_capacity = cast(u32, u64, align_forward(old_capacity * item_size, minimum_granularity));
|
u32 old_page_capacity = cast(u32, u64, align_forward(old_capacity * item_size, minimum_granularity));
|
||||||
|
121
bootstrap/main.c
121
bootstrap/main.c
@ -35,26 +35,34 @@ fn String file_read(Arena* arena, String path)
|
|||||||
{
|
{
|
||||||
String result = {};
|
String result = {};
|
||||||
int file_descriptor = syscall_open(string_to_c(path), 0, 0);
|
int file_descriptor = syscall_open(string_to_c(path), 0, 0);
|
||||||
assert(file_descriptor != -1);
|
if (file_descriptor >= 0)
|
||||||
|
{
|
||||||
|
struct stat stat_buffer;
|
||||||
|
int stat_result = syscall_fstat(file_descriptor, &stat_buffer);
|
||||||
|
assert(stat_result == 0);
|
||||||
|
|
||||||
struct stat stat_buffer;
|
auto file_size = cast(u64, s64, stat_buffer.st_size);
|
||||||
int stat_result = syscall_fstat(file_descriptor, &stat_buffer);
|
if (file_size > 0)
|
||||||
assert(stat_result == 0);
|
{
|
||||||
|
result = (String){
|
||||||
|
.pointer = arena_allocate_bytes(arena, file_size, 64),
|
||||||
|
.length = file_size,
|
||||||
|
};
|
||||||
|
|
||||||
auto file_size = cast(u64, s64, stat_buffer.st_size);
|
// TODO: big files
|
||||||
|
ssize_t read_result = syscall_read(file_descriptor, result.pointer, result.length);
|
||||||
|
assert(read_result >= 0);
|
||||||
|
assert((u64)read_result == file_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.pointer = (u8*)&result;
|
||||||
|
}
|
||||||
|
|
||||||
result = (String){
|
auto close_result = syscall_close(file_descriptor);
|
||||||
.pointer = arena_allocate_bytes(arena, file_size, 64),
|
assert(close_result == 0);
|
||||||
.length = file_size,
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: big files
|
|
||||||
ssize_t read_result = syscall_read(file_descriptor, result.pointer, result.length);
|
|
||||||
assert(read_result >= 0);
|
|
||||||
assert((u64)read_result == file_size);
|
|
||||||
|
|
||||||
auto close_result = syscall_close(file_descriptor);
|
|
||||||
assert(close_result == 0);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -428,6 +436,41 @@ typedef enum ELFSectionIndex : u16
|
|||||||
COMMON = 0xfff2,
|
COMMON = 0xfff2,
|
||||||
} ELFSectionIndex;
|
} ELFSectionIndex;
|
||||||
|
|
||||||
|
STRUCT(ELFVersionRequirement)
|
||||||
|
{
|
||||||
|
u16 version;
|
||||||
|
u16 count;
|
||||||
|
u32 name_offset;
|
||||||
|
u32 aux_offset;
|
||||||
|
u32 next;
|
||||||
|
};
|
||||||
|
|
||||||
|
STRUCT(ELFVersionRequirementEntry)
|
||||||
|
{
|
||||||
|
u32 hash;
|
||||||
|
u16 flags;
|
||||||
|
u16 other;
|
||||||
|
u32 name_offset;
|
||||||
|
u32 next;
|
||||||
|
};
|
||||||
|
|
||||||
|
STRUCT(ELFVersionDefinition)
|
||||||
|
{
|
||||||
|
u16 version;
|
||||||
|
u16 flags;
|
||||||
|
u16 index;
|
||||||
|
u16 count;
|
||||||
|
u32 hash;
|
||||||
|
u32 aux_offset;
|
||||||
|
u32 next;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(ELFVersionDefinition) == 20);
|
||||||
|
STRUCT(ELFVersionDefinitionEntry)
|
||||||
|
{
|
||||||
|
u32 name_offset;
|
||||||
|
u32 next;
|
||||||
|
};
|
||||||
|
|
||||||
STRUCT(ELFHeader)
|
STRUCT(ELFHeader)
|
||||||
{
|
{
|
||||||
u8 identifier[4];
|
u8 identifier[4];
|
||||||
@ -6968,7 +7011,7 @@ fn void thread_init(Thread* thread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Actually make the syscall
|
// Actually make the syscall
|
||||||
auto* ptr = os_reserve(total_size);
|
auto* ptr = os_reserve(0, total_size, (OSReserveProtectionFlags) {}, (OSReserveMapFlags) { .priv = 1, .anon = 1, .noreserve = 1 });
|
||||||
assert(ptr);
|
assert(ptr);
|
||||||
|
|
||||||
auto* buffer_it = (VirtualBuffer(u8)*)&thread->buffer;
|
auto* buffer_it = (VirtualBuffer(u8)*)&thread->buffer;
|
||||||
@ -7555,17 +7598,6 @@ STRUCT(ELFNoteHeader)
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(ELFNoteHeader) == 12);
|
static_assert(sizeof(ELFNoteHeader) == 12);
|
||||||
|
|
||||||
STRUCT(ELFVersionDefinition)
|
|
||||||
{
|
|
||||||
u16 version;
|
|
||||||
u16 flags;
|
|
||||||
u16 index;
|
|
||||||
u16 count;
|
|
||||||
u32 hash;
|
|
||||||
u32 aux;
|
|
||||||
u32 next;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(ELFVersionDefinition) == 20);
|
|
||||||
|
|
||||||
#define elf_eh_frame_absptr 0x00
|
#define elf_eh_frame_absptr 0x00
|
||||||
#define elf_eh_frame_udata4 0x03
|
#define elf_eh_frame_udata4 0x03
|
||||||
@ -8418,16 +8450,35 @@ may_be_unused fn void write_elf(Thread* thread, const ObjectOptions* const restr
|
|||||||
|
|
||||||
auto name = elf_get_section_name(builder, strlit(".gnu.version_r"));
|
auto name = elf_get_section_name(builder, strlit(".gnu.version_r"));
|
||||||
|
|
||||||
// TODO: figure out
|
ELFVersionRequirement first_requirement = {
|
||||||
u8 blob[] = {
|
.version = 1,
|
||||||
0x01, 0x00, 0x02, 0x00, 0x22, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
.count = 2,
|
||||||
0x75, 0x1A, 0x69, 0x09, 0x00, 0x00, 0x03, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
.name_offset = libcso6,
|
||||||
0xB4, 0x91, 0x96, 0x06, 0x00, 0x00, 0x02, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
.aux_offset = sizeof(ELFVersionRequirement),
|
||||||
|
.next = 0,
|
||||||
|
};
|
||||||
|
*vb_add_struct(&builder->file, ELFVersionRequirement) = first_requirement;
|
||||||
|
|
||||||
|
ELFVersionRequirementEntry entries[] = {
|
||||||
|
{
|
||||||
|
.hash = 0x9691a75,
|
||||||
|
.flags = 0,
|
||||||
|
.other = 3,
|
||||||
|
.name_offset = 0x2c,
|
||||||
|
.next = 0x10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.hash = 0x69691b4,
|
||||||
|
.flags = 0,
|
||||||
|
.other = 2,
|
||||||
|
.name_offset = 0x38,
|
||||||
|
.next = 0,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
auto size = sizeof(blob);
|
memcpy(vb_add(&builder->file, sizeof(entries)), entries, sizeof(entries));
|
||||||
|
|
||||||
memcpy(vb_add(&builder->file, size), blob, size);
|
auto size = builder->file.length - offset;
|
||||||
|
|
||||||
*section_header = (ELFSectionHeader) {
|
*section_header = (ELFSectionHeader) {
|
||||||
.name_offset = name,
|
.name_offset = name,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user