#ifndef __CPU_ASM_H #define __CPU_ASM_H #include #include /* Runtime dynamic-link metadata carried by ABI-v2/ABI-v3 ET_EXEC/ET_DYN images. */ typedef struct cpu_dyn_symbol { char *name; unsigned int section; /* logical output section, or CPU_OBJ_SEC_UNDEF */ unsigned int binding; /* GLOBAL/WEAK */ unsigned int type; /* NOTYPE/OBJECT/FUNC */ __mpu_uint64_t value; /* output-section-relative byte offset */ __mpu_uint64_t size; } cpu_dyn_symbol; typedef struct cpu_dyn_reloc { unsigned int section; /* logical output section containing field */ unsigned int type; size_t symbol_index; /* index in cpu_asm_image.dyn_symbols */ __mpu_uint64_t offset; /* output-section-relative field offset */ __mpu_int64_t addend; } cpu_dyn_reloc; /* Final linked/runtime image used internally by mcpu-ld. */ typedef struct cpu_asm_image { __mpu_UNIT_t *code; size_t code_size; __mpu_UNIT_t *data; size_t data_size; size_t data_mem_size; __mpu_UNIT_t *control; size_t control_size; __mpu_UNIT_t *input; size_t input_size; __mpu_UNIT_t *output; size_t output_size; __mpu_UNIT_t *trace; size_t trace_size; int has_start; int has_init; int has_life; int has_fini; __mpu_uint64_t start_entry; __mpu_uint64_t init_entry; __mpu_uint64_t life_entry; __mpu_uint64_t fini_entry; /* Final PROGRAM subsection placement. */ int init_present; __mpu_uint64_t init_offset, init_size, init_align; int text_present; __mpu_uint64_t text_offset, text_size, text_align; int fini_present; __mpu_uint64_t fini_offset, fini_size, fini_align; /* Final data-like section placement in its architectural segment. */ int data_present; __mpu_uint64_t data_offset, data_section_size, data_align; int bss_present; __mpu_uint64_t bss_offset, bss_size, bss_align; int control_present; __mpu_uint64_t control_offset, control_section_size, control_align; int input_present; __mpu_uint64_t input_offset, input_section_size, input_align; int output_present; __mpu_uint64_t output_offset, output_section_size, output_align; int trace_present; __mpu_uint64_t trace_offset, trace_section_size, trace_align; /* ABI-v2/ABI-v3 startup dynamic-link metadata. */ cpu_dyn_symbol *dyn_symbols; size_t dyn_symbol_count; cpu_dyn_reloc *dyn_relocs; size_t dyn_reloc_count; } cpu_asm_image; /* Logical input-section identifiers used between assembler, MELF reader and static linker. Data-like values intentionally match PTR64 selectors. PROGRAM subsections use private non-selector IDs so .init/.text/.fini stay distinct until the final PROGRAM layout is assigned by mcpu-ld. */ #define CPU_OBJ_SEC_DATA CPU_PTR_SEG_DATA #define CPU_OBJ_SEC_CONTROL CPU_PTR_SEG_CONTROL #define CPU_OBJ_SEC_INPUT CPU_PTR_SEG_INPUT #define CPU_OBJ_SEC_OUTPUT CPU_PTR_SEG_OUTPUT #define CPU_OBJ_SEC_TRACE CPU_PTR_SEG_TRACE #define CPU_OBJ_SEC_INIT 0x20U #define CPU_OBJ_SEC_TEXT 0x21U #define CPU_OBJ_SEC_FINI 0x22U #define CPU_OBJ_SEC_BSS 0x23U #define CPU_OBJ_SEC_UNDEF 0xffU static inline int cpu_obj_sec_is_program( unsigned s ) { return( s == CPU_OBJ_SEC_INIT || s == CPU_OBJ_SEC_TEXT || s == CPU_OBJ_SEC_FINI ); } static inline unsigned cpu_obj_sec_segment( unsigned s ) { if( cpu_obj_sec_is_program( s ) ) return( CPU_PTR_SEG_PROGRAM ); if( s == CPU_OBJ_SEC_BSS ) return( CPU_PTR_SEG_DATA ); return( s ); } #define CPU_OBJ_BIND_LOCAL 0U #define CPU_OBJ_BIND_GLOBAL 1U #define CPU_OBJ_BIND_WEAK 2U #define CPU_OBJ_TYPE_NOTYPE 0U #define CPU_OBJ_TYPE_OBJECT 1U #define CPU_OBJ_TYPE_FUNC 2U typedef enum cpu_reloc_type { CPU_RELOC_CODE64 = 1, CPU_RELOC_DATA64 = 2, CPU_RELOC_PTR64_CODE = 3, CPU_RELOC_PTR64_DATA = 4, CPU_RELOC_CPTR64_DATA = 5 } cpu_reloc_type; typedef struct cpu_asm_symbol { char *name; unsigned int section; unsigned int binding; unsigned int type; __mpu_uint64_t value; /* section-relative byte offset */ __mpu_uint64_t size; /* zero when unknown */ } cpu_asm_symbol; typedef struct cpu_asm_reloc { unsigned int section; /* logical source section */ unsigned int type; size_t symbol_index; __mpu_uint64_t offset; /* source-section-relative field offset */ __mpu_int64_t addend; } cpu_asm_reloc; typedef struct cpu_asm_object { __mpu_UNIT_t *init; size_t init_size; __mpu_uint64_t init_align; int has_init; __mpu_UNIT_t *text; size_t text_size; __mpu_uint64_t text_align; int has_text; __mpu_UNIT_t *fini; size_t fini_size; __mpu_uint64_t fini_align; int has_fini; __mpu_UNIT_t *data; size_t data_size; __mpu_uint64_t data_align; int has_data; size_t bss_size; __mpu_uint64_t bss_align; int has_bss; __mpu_UNIT_t *control; size_t control_size; __mpu_uint64_t control_align; int has_control; __mpu_UNIT_t *input; size_t input_size; __mpu_uint64_t input_align; int has_input; __mpu_UNIT_t *output; size_t output_size; __mpu_uint64_t output_align; int has_output; __mpu_UNIT_t *trace; size_t trace_size; __mpu_uint64_t trace_align; int has_trace; /* Compatibility concatenation for legacy in-process assembler tests only. It is never serialized as a MELF section. */ __mpu_UNIT_t *code; size_t code_size; __mpu_uint64_t code_align; cpu_asm_symbol *symbols; size_t symbol_count; cpu_asm_reloc *relocs; size_t reloc_count; } cpu_asm_object; int cpu_assemble_text( const char *source, cpu_asm_image *image, char *err, size_t errsz ); void cpu_asm_image_free( cpu_asm_image *image ); int cpu_assemble_object( const char *source, cpu_asm_object *object, char *err, size_t errsz ); void cpu_asm_object_free( cpu_asm_object *object ); #endif