217 lines
6.4 KiB
C
217 lines
6.4 KiB
C
#if !defined(SY__H)
|
|
#define SY__H
|
|
|
|
#include "symbol_set.base.h"
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
~~~~~~~~~~~~~~~~~~~~~~~~ Copy-Pastable Setup ~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
~~ To define a Symbol Set:
|
|
~~ copy the code below
|
|
~~ replace ZZZ: to name the symbol set
|
|
~~ replace Typezz: to set the type of the symbol set
|
|
~~ replace secz: to name of the data section of the symbol set
|
|
~~ pick and complete the sections with "..."s
|
|
*/
|
|
|
|
#if 0
|
|
|
|
#define SYMBOL_SET_DEFINE ZZZ
|
|
#define ZZZ_Type Typezz
|
|
#define ZZZ_section ".sy.secz"
|
|
#define ZZZ_marker secz
|
|
#include "symbol_set.define.h"
|
|
|
|
// basic struct def with a name
|
|
#define ZZZ_DEF(N,...) SyDefine(ZZZ, N) = { ... }
|
|
|
|
// def with attached function body
|
|
// replace funczz: to prefix namespace unique functions
|
|
// fill ... sections appropriately
|
|
#define ZZZ_DEF(N,...) \
|
|
static void funczz##N(void*); \
|
|
SyDefine(ZZZ, N) = { funczz##N, ... }; \
|
|
static void funczz##N(void *ptr)
|
|
|
|
// nameless def
|
|
#define ZZZ_DEF(...) SyDefineUnnamed(ZZZ) = { ... }
|
|
|
|
#endif
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
~~~~~~~~~~~~~~~~~~ Loop Boilerplates ~~~~~~~~~~~~~~~~~*/
|
|
|
|
#if 0
|
|
{
|
|
for (SyEach(ZZZ, zzz_ptr)){
|
|
zzz_ptr->
|
|
}
|
|
}
|
|
{
|
|
for (SyEachID(ZZZ, zzz_id)){
|
|
[zzz_id]
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
~~~~~~~~~~~~~~~~~~~~~~~~ User Primitives ~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
#define SyType(S) SY__GLUE(S,_Type)
|
|
|
|
#define SyDeclare(S,N) SY__ALIGN_AS_LIT(8) SY__SEC_RW(S##_section) SyType(S) SY__SYMBOL(S,N)
|
|
#define SyDefine(S,N) SY__DO_NOT_ELIMINATE(SY__SYMBOL(S,N)) SyDeclare(S,N)
|
|
#define SyDefineUnnamed(S) SyDefine(S,SY__GLUE(unnamed,__COUNTER__))
|
|
|
|
#define SyAddress(S,N) (&SY__SYMBOL(S,N))
|
|
#define SyID(S,N) SyIDFromAddress_Unchecked(S,SyAddress(S,N))
|
|
#define SyRaw(S,N) (SY__UAddr)(SyAddress(S,N))
|
|
|
|
#if SY__OS_WINDOWS
|
|
# define SyFirst(S) SY__FIRST(S)
|
|
# define SyOpl(S) SY__OPL(S)
|
|
#elif SY__OS_LINUX
|
|
# define SyFirst(S) (&SY__FIRST(S))
|
|
# define SyOpl(S) (&SY__OPL(S))
|
|
#else
|
|
# error missing implementation set locator for this OS
|
|
#endif
|
|
|
|
#define SyStride(S) SY__ROUND_UP_POW2(sizeof(SyType(S)), 8)
|
|
|
|
#define SyCount(S) (((SY__U8*)SyOpl(S) - (SY__U8*)SyFirst(S))/SyStride(S))
|
|
#define SyNext(S,addr) (SyType(S)*)((SY__U8*)addr + SyStride(S))
|
|
|
|
#define SyEach(S,var) SyType(S)*var=SyFirst(S); var<SyOpl(S); var=SyNext(S,var)
|
|
#define SyEachID(S,var) SY__U32 var=1; var<=SyCount(S); var+=1
|
|
|
|
#define SyIDFromAddress(S,addr) (SyAddressCheck(S,addr)?SyIDFromAddress_Unchecked(S,addr):0)
|
|
#define SyAddressFromID(S,id) (SyIDCheck(S,id)?SyAddressFromID_Unchecked(S,id):0)
|
|
|
|
#define SyAddressCheck(S,addr) (SyFirst(S) <= (addr) && (addr) <= SyOpl(S))
|
|
#define SyIDCheck(S,id) (1 <= (id) && (id) <= SyCount(S))
|
|
|
|
#define SyIDFromAddress_Unchecked(S,addr) ((SY__U32)(1 + ((SY__U8*)(addr) - (SY__U8*)SyFirst(S))/SyStride(S)))
|
|
#define SyAddressFromID_Unchecked(S,id) ((SyType(S)*)((SY__U8*)SyFirst(S) + ((id) - 1)*SyStride(S)))
|
|
|
|
#define SyIDFromRaw(S,raw) SyIDFromAddress(S,(SyType(S)*)(raw))
|
|
#define SyIDFromRaw_Unchecked(S,raw) SyIDFromAddress_Unchecked(S,(SyType(S)*)(raw))
|
|
|
|
#define SyFlag(S,N) (1llu << (SyID(S,N) - 1))
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
~~~~~~~~~~~~~~~~~~~ Internal ~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
#define SY__SYMBOL(S,N) SY__GLUE(S,SY__GLUE(__,N))
|
|
|
|
#define SY__FIRST_(S) SY__GLUE(syfirst__, S##_marker)
|
|
#define SY__OPL_(S) SY__GLUE(syopl__, S##_marker)
|
|
|
|
#define SY__FIRST(S) SY__FIRST_(S)
|
|
#define SY__OPL(S) SY__OPL_(S)
|
|
|
|
#if SY__OS_WINDOWS
|
|
void sy__section_init(char *name, SY__U32 name_size, void **first_out, void **opl_out);
|
|
#endif
|
|
|
|
// I dropped this here so that if you copy paste any of the
|
|
// above and forget to replace Typezz, you'll get auto-int like
|
|
// behavior from your error messages.
|
|
#define Typezz int
|
|
|
|
#endif //SY__H
|
|
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
~~~~~~~~~~~~~~~~~~~~~ Function Definitions ~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
#if SY__MAIN && !defined(SY__MAIN_DEFINITIONS)
|
|
#define SY__MAIN_DEFINITIONS 1
|
|
|
|
#if SY__OS_WINDOWS
|
|
|
|
#define SY__PE_MSDOS_MAGIC 0x5A4D
|
|
struct SY__PE_DosHeader{
|
|
SY__U16 magic;
|
|
SY__U16 last_page_size;
|
|
SY__U16 page_count;
|
|
SY__U16 reloc_count;
|
|
SY__U16 paragraph_header_size;
|
|
SY__U16 min_paragraph;
|
|
SY__U16 max_paragraph;
|
|
SY__U16 init_ss;
|
|
SY__U16 init_sp;
|
|
SY__U16 checksum;
|
|
SY__U16 init_ip;
|
|
SY__U16 init_cs;
|
|
SY__U16 reloc_table_file_off;
|
|
SY__U16 overlay_number;
|
|
SY__U16 reserved[4];
|
|
SY__U16 oem_id;
|
|
SY__U16 oem_info;
|
|
SY__U16 reserved2[10];
|
|
SY__U32 coff_file_offset;
|
|
};
|
|
#define SY__PE_SIGNATURE 0x00004550
|
|
struct SY__PE_CoffHeader{
|
|
SY__U16 machine_type;
|
|
SY__U16 section_count;
|
|
SY__U32 time_stamp;
|
|
SY__U32 symbol_table_foff;
|
|
SY__U32 symbol_count;
|
|
SY__U16 optional_header_size;
|
|
SY__U16 flags;
|
|
};
|
|
struct SY__PE_SectionHeader{
|
|
SY__U8 name[8];
|
|
SY__U32 vsize;
|
|
SY__U32 voff;
|
|
SY__U32 fsize;
|
|
SY__U32 foff;
|
|
SY__U32 relocations_foff;
|
|
SY__U32 line_numbers_foff;
|
|
SY__U16 relocation_count;
|
|
SY__U16 line_number_count;
|
|
SY__U32 flags;
|
|
};
|
|
|
|
void
|
|
sy__section_init(char *name, SY__U32 name_size,
|
|
void **first_out, void **opl_out){
|
|
if (name_size <= 8){
|
|
extern SY__U8 __ImageBase[];
|
|
SY__U8 *base = __ImageBase;
|
|
struct SY__PE_DosHeader *dos = (struct SY__PE_DosHeader*)base;
|
|
if (dos->magic == SY__PE_MSDOS_MAGIC){
|
|
SY__U32 *pe_signature = (SY__U32*)(base + dos->coff_file_offset);
|
|
if (*pe_signature == SY__PE_SIGNATURE){
|
|
struct SY__PE_CoffHeader *coff = (struct SY__PE_CoffHeader*)(pe_signature + 1);
|
|
SY__U32 sections_offset = (dos->coff_file_offset + sizeof(*pe_signature) +
|
|
sizeof(*coff) + coff->optional_header_size);
|
|
SY__U32 section_count = coff->section_count;
|
|
struct SY__PE_SectionHeader*
|
|
section = (struct SY__PE_SectionHeader*)(base + sections_offset);
|
|
for (SY__U32 i = 0; i < section_count; i += 1, section += 1){
|
|
SY__B32 match = 1;
|
|
for (SY__U32 j = 0; j < 8; j += 1){
|
|
if (name[j] != section->name[j]){
|
|
match = 0;
|
|
break;
|
|
}
|
|
if (name[j] == 0){
|
|
break;
|
|
}
|
|
}
|
|
if (match){
|
|
*first_out = base + section->voff;
|
|
*opl_out = base + section->voff + section->vsize;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif /* SY__OS_WINDOWS */
|
|
|
|
#endif //SY__MAIN_DEFINITIONS
|