1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
#ifndef __CPU_ASM_H
#define __CPU_ASM_H
#include <stddef.h>
#include <libmcpu.h>
/* 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
|