pass-lang/src/format.h

68 lines
2.4 KiB
C

#ifndef FORMAT_H
#define FORMAT_H
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
typedef uint32_t symbol;
/// Begin a new ELF executable.
void elf_executable(void);
/// All definitions are complete. Finish processing the executable.
void finish_executable(symbol entry_point);
/// Create a new symbol. You will later have to define this with
/// `define_executable_symbol`, `define_readonly_symbol`,
/// or import it from an external library.
symbol new_symbol(void);
void define_executable_symbol(symbol sym);
void define_readonly_symbol(symbol sym);
void append_data(size_t size, const void* buf);
void append_u8(uint8_t x);
void append_u32(uint32_t x);
void append_u64(uint64_t x);
/// Assuming the symbol is located in the same segment as this code,
/// insert a 32-bit offset for the symbol relative to the virtual address
/// of the current address (Program Counter (PC)).
///
/// This is used for generating relative jumps.
///
/// If the symbol is defined in this object, then it will be computed
/// at compile-time and not emitted as an actual relocation in the executable.
void relocate_pc32(symbol sym);
/// Like pc32 for DIY relocations. This returns INT32_MAX if the symbol
/// has not been defined yet. This exists so that the assembler can manually
/// emit 8-bit short jumps when the distance is short enough.
///
/// The offset exists to account for the offset being relative to the
/// *end* of an instruction, whereas the symbol offset is computed
/// relative to `here`. This makes bounds-checking slightly easier.
int32_t symbol_offset(symbol sym, int8_t offset);
/// If the symbol is not in the same segment as this code,
/// for example when linking against a dynamic library or accessing read-only data,
/// then a 32-bit offset may not be sufficient to access a symbol with pc32.
/// This necessitates a Global Offset Table (GOT) which contains the 64-bit
/// absolute addresses of the symbols which *is* located in this segment.
/// Thus, this relocation inserts a 32-bit PC-relative address which points
/// into the location in the GOT which contains the 64-bit absolute address
/// of the symbol.
///
/// This is used for generating jumps to dynamic library code
/// and for accessing data in a different segment (e.g. read-only symbols).
void relocate_gotpcrel(symbol sym);
/// Insert the 32-bit truncated size of a symbol.
void relocate_size32(symbol sym);
/// Insert the 64-bit size of a symbol.
void relocate_size64(symbol sym);
#endif