Files
Odin/src/tilde/tb_formats.h
T
gingerBill d7af6de9b9 Add tilde
2023-07-08 11:54:44 +01:00

133 lines
3.1 KiB
C

// This handles the generalized executable/object format parsing stuff
#ifndef TB_OBJECT_H
#define TB_OBJECT_H
#include <stdint.h>
#include <stddef.h>
typedef enum {
TB_OBJECT_RELOC_NONE, // how?
// Target independent
TB_OBJECT_RELOC_ADDR32,
TB_OBJECT_RELOC_ADDR64, // unsupported on 32bit platforms
TB_OBJECT_RELOC_SECREL,
TB_OBJECT_RELOC_SECTION,
// COFF only
TB_OBJECT_RELOC_ADDR32NB, // Relative virtual address
// x64 only
TB_OBJECT_RELOC_REL32, // relative 32bit displacement
// Aarch64 only
TB_OBJECT_RELOC_BRANCH26, // 26bit displacement for B and BL instructions
TB_OBJECT_RELOC_REL21, // for ADR instructions
// TODO(NeGate): fill in the rest of this later
} TB_ObjectRelocType;
typedef struct {
TB_ObjectRelocType type;
uint32_t symbol_index;
size_t virtual_address;
size_t addend;
} TB_ObjectReloc;
typedef enum {
TB_OBJECT_SYMBOL_UNKNOWN,
TB_OBJECT_SYMBOL_EXTERN, // exported
TB_OBJECT_SYMBOL_WEAK_EXTERN, // weak
TB_OBJECT_SYMBOL_IMPORT, // forward decl
TB_OBJECT_SYMBOL_STATIC, // local
TB_OBJECT_SYMBOL_SECTION, // local
} TB_ObjectSymbolType;
typedef struct {
TB_ObjectSymbolType type;
int section_num;
uint32_t ordinal;
uint32_t value;
TB_Slice name;
// for COFF, this is the auxillary
void* extra;
// this is zeroed out by the loader and left for the user to do crap with
void* user_data;
} TB_ObjectSymbol;
typedef struct {
TB_Slice name;
uint32_t flags;
size_t virtual_address;
size_t virtual_size;
// You can have a virtual size without having a raw
// data size, that's how the BSS section works
TB_Slice raw_data;
size_t relocation_count;
TB_ObjectReloc* relocations;
// this is zeroed out by the loader and left for the user to do crap with
void* user_data;
} TB_ObjectSection;
typedef enum {
TB_OBJECT_FILE_UNKNOWN,
TB_OBJECT_FILE_COFF,
TB_OBJECT_FILE_ELF64
} TB_ObjectFileType;
typedef struct {
TB_ObjectFileType type;
TB_Arch arch;
TB_Slice name;
TB_Slice ar_name;
size_t symbol_count;
TB_ObjectSymbol* symbols;
size_t section_count;
TB_ObjectSection sections[];
} TB_ObjectFile;
////////////////////////////////
// Archive parser
////////////////////////////////
typedef struct {
TB_Slice name;
// if import_name is empty, we're dealing with an object file
TB_Slice import_name;
uint16_t ordinal;
TB_Slice content;
} TB_ArchiveEntry;
typedef struct {
TB_Slice file;
size_t pos;
size_t member_count;
uint32_t* members;
size_t symbol_count;
uint16_t* symbols;
TB_Slice strtbl;
} TB_ArchiveFileParser;
// We do this to parse the header
bool tb_archive_parse(TB_Slice file, TB_ArchiveFileParser* restrict out_parser);
// After that we can enumerate any symbol entries to resolve imports
size_t tb_archive_parse_entries(TB_ArchiveFileParser* restrict parser, size_t i, size_t count, TB_ArchiveEntry* out_entry);
#endif // TB_OBJECT_H