Skip to content

Commit c6fc12b

Browse files
authored
Add xtensa AOT support and fix build issue of alios (#223)
* Clean compiling warnings of zephyr samples * Support xtensa AOT and fix build issue of alios
1 parent c1a0e6d commit c6fc12b

File tree

20 files changed

+762
-68
lines changed

20 files changed

+762
-68
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Execute following commands to build **wamrc** compiler:
5353

5454
```shell
5555
cd wamr-compiler
56-
./build_llvm.sh
56+
./build_llvm.sh (use build_llvm_xtensa.sh instead to support xtensa target)
5757
mkdir build && cd build
5858
cmake ..
5959
make

core/iwasm/aot/aot_loader.c

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -985,14 +985,21 @@ load_text_section(const uint8 *buf, const uint8 *buf_end,
985985
return false;
986986
}
987987

988-
module->code = (void*)buf;
989-
module->code_size = (uint32)(buf_end - buf);
988+
read_uint32(buf, buf_end, module->literal_size);
989+
990+
/* literal data is at begining of the text section */
991+
module->literal = (uint8*)buf;
992+
module->code = (void*)(buf + module->literal_size);
993+
module->code_size = (uint32)(buf_end - (uint8*)module->code);
990994

991995
if (module->code_size > 0) {
992996
plt_base = (uint8*)buf_end - get_plt_table_size();
993997
init_plt_table(plt_base);
994998
}
995999
return true;
1000+
1001+
fail:
1002+
return false;
9961003
}
9971004

9981005
static bool
@@ -1184,13 +1191,20 @@ resolve_target_sym(const char *symbol, int32 *p_index)
11841191
return NULL;
11851192
}
11861193

1194+
static bool
1195+
is_literal_relocation(const char *reloc_sec_name)
1196+
{
1197+
return !strcmp(reloc_sec_name, ".rela.literal");
1198+
}
1199+
11871200
static bool
11881201
do_text_relocation(AOTModule *module,
11891202
AOTRelocationGroup *group,
11901203
char *error_buf, uint32 error_buf_size)
11911204
{
1192-
uint8 *aot_text = module->code;
1193-
uint32 aot_text_size = module->code_size;
1205+
bool is_literal = is_literal_relocation(group->section_name);
1206+
uint8 *aot_text = is_literal ? module->literal : module->code;
1207+
uint32 aot_text_size = is_literal ? module->literal_size : module->code_size;
11941208
uint32 i, func_index, symbol_len;
11951209
char symbol_buf[128] = { 0 }, *symbol, *p;
11961210
void *symbol_addr;
@@ -1248,6 +1262,9 @@ do_text_relocation(AOTModule *module,
12481262
goto check_symbol_fail;
12491263
}
12501264
}
1265+
else if (!strcmp(symbol, ".literal")) {
1266+
symbol_addr = module->literal;
1267+
}
12511268
else if (!(symbol_addr = resolve_target_sym(symbol, &symbol_index))) {
12521269
if (error_buf != NULL)
12531270
snprintf(error_buf, error_buf_size,
@@ -1495,7 +1512,8 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
14951512
}
14961513

14971514
if (!strcmp(group->section_name, ".rel.text")
1498-
|| !strcmp(group->section_name, ".rela.text")) {
1515+
|| !strcmp(group->section_name, ".rela.text")
1516+
|| !strcmp(group->section_name, ".rela.literal")) {
14991517
if (!do_text_relocation(module, group, error_buf, error_buf_size))
15001518
return false;
15011519
}
@@ -2079,8 +2097,11 @@ aot_unload(AOTModule *module)
20792097
if (module->const_str_set)
20802098
bh_hash_map_destroy(module->const_str_set);
20812099

2082-
if (module->code)
2083-
os_munmap(module->code, module->code_size);
2100+
if (module->code) {
2101+
uint8 *mmap_addr = module->literal - sizeof(module->literal_size);
2102+
uint32 total_size = sizeof(module->literal_size) + module->literal_size + module->code_size;
2103+
os_munmap(mmap_addr, total_size);
2104+
}
20842105

20852106
if (module->data_sections)
20862107
destroy_object_data_sections(module->data_sections,

core/iwasm/aot/aot_runtime.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ typedef struct AOTModule {
125125
void *code;
126126
uint32 code_size;
127127

128+
/* literal for AOTed code, NULL for JIT mode */
129+
uint8 *literal;
130+
uint32 literal_size;
131+
128132
/* data sections in AOT object file, including .data, .rodata
129133
* and .rodata.cstN. NULL for JIT mode. */
130134
AOTObjectDataSection *data_sections;

core/iwasm/aot/arch/aot_reloc_xtensa.c

Lines changed: 169 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,50 @@
55

66
#include "aot_reloc.h"
77

8+
#define R_XTENSA_32 1 /* Direct 32 bit */
9+
#define R_XTENSA_SLOT0_OP 20 /* PC relative */
10+
11+
/* for soft-float */
12+
void __floatsidf();
13+
void __divdf3();
14+
void __ltdf2();
15+
16+
/* for mul32 */
17+
void __mulsi3();
18+
void __muldi3();
19+
20+
void __modsi3();
21+
22+
void __divdi3();
23+
824
static SymbolMap target_sym_map[] = {
9-
REG_COMMON_SYMBOLS
25+
REG_COMMON_SYMBOLS,
26+
27+
/* API's for soft-float */
28+
/* TODO: only register these symbols when Floating-Point Coprocessor
29+
* Option is not enabled */
30+
REG_SYM(__floatsidf),
31+
REG_SYM(__divdf3),
32+
REG_SYM(__ltdf2),
33+
34+
/* API's for 32-bit integer multiply */
35+
/* TODO: only register these symbols when 32-bit Integer Multiply Option
36+
* is not enabled */
37+
REG_SYM(__mulsi3),
38+
REG_SYM(__muldi3),
39+
40+
REG_SYM(__modsi3),
41+
42+
REG_SYM(__divdi3),
1043
};
1144

45+
static void
46+
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
47+
{
48+
if (error_buf != NULL)
49+
snprintf(error_buf, error_buf_size, "%s", string);
50+
}
51+
1252
SymbolMap *
1353
get_target_symbol_map(uint32 *sym_num)
1454
{
@@ -40,6 +80,67 @@ get_plt_table_size()
4080
return get_plt_item_size() * (sizeof(target_sym_map) / sizeof(SymbolMap));
4181
}
4282

83+
static bool
84+
check_reloc_offset(uint32 target_section_size,
85+
uint64 reloc_offset, uint32 reloc_data_size,
86+
char *error_buf, uint32 error_buf_size)
87+
{
88+
if (!(reloc_offset < (uint64)target_section_size
89+
&& reloc_offset + reloc_data_size <= (uint64)target_section_size)) {
90+
set_error_buf(error_buf, error_buf_size,
91+
"AOT module load failed: invalid relocation offset.");
92+
return false;
93+
}
94+
return true;
95+
}
96+
97+
/*
98+
* CPU like esp32 can read and write data through the instruction bus, but only
99+
* in a word aligned manner; non-word-aligned access will cause a CPU exception.
100+
* This function uses a world aligned manner to write 16bit value to instruction
101+
* addreess.
102+
*/
103+
static void
104+
put_imm16_to_addr(int16 imm16, int16 *addr)
105+
{
106+
int8 bytes[8];
107+
int32 *addr_aligned1, *addr_aligned2;
108+
109+
addr_aligned1 = (int32*)((intptr_t)addr & ~3);
110+
111+
if ((intptr_t)addr % 4 != 3) {
112+
*(int32*)bytes = *addr_aligned1;
113+
*(int16*)(bytes + ((intptr_t)addr % 4)) = imm16;
114+
memcpy(addr_aligned1, bytes, 4);
115+
}
116+
else {
117+
addr_aligned2 = (int32*)(((intptr_t)addr + 3) & ~3);
118+
*(int32*)bytes = *addr_aligned1;
119+
*(int32*)(bytes + 4) = *addr_aligned2;
120+
*(int16*)(bytes + 3) = imm16;
121+
memcpy(addr_aligned1, bytes, 8);
122+
}
123+
}
124+
125+
static union {
126+
int a;
127+
char b;
128+
} __ue = { .a = 1 };
129+
130+
#define is_little_endian() (__ue.b == 1)
131+
132+
typedef union {
133+
struct l32r_le {
134+
int8 other;
135+
int16 imm16;
136+
} __packed l;
137+
138+
struct l32r_be {
139+
int16 imm16;
140+
int8 other;
141+
} __packed b;
142+
} l32r_insn_t;
143+
43144
bool
44145
apply_relocation(AOTModule *module,
45146
uint8 *target_section_addr, uint32 target_section_size,
@@ -48,7 +149,73 @@ apply_relocation(AOTModule *module,
48149
char *error_buf, uint32 error_buf_size)
49150
{
50151
switch (reloc_type) {
51-
/* TODO: implement relocation for xtensa */
152+
case R_XTENSA_32:
153+
{
154+
uint8 *insn_addr = target_section_addr + reloc_offset;
155+
int32 initial_addend;
156+
/* (S + A) */
157+
if ((intptr_t)insn_addr & 3) {
158+
set_error_buf(error_buf, error_buf_size,
159+
"AOT module load failed: "
160+
"instruction address unaligned.");
161+
return false;
162+
}
163+
CHECK_RELOC_OFFSET(4);
164+
initial_addend = *(int32*)insn_addr;
165+
*(uint8**)insn_addr
166+
= (uint8*)symbol_addr + initial_addend + reloc_addend;
167+
break;
168+
}
169+
170+
case R_XTENSA_SLOT0_OP:
171+
{
172+
uint8 *insn_addr = target_section_addr + reloc_offset;
173+
/* Currently only l32r instruction generates R_XTENSA_SLOT0_OP relocation */
174+
l32r_insn_t *l32r_insn = (l32r_insn_t *)insn_addr;
175+
uint8 *reloc_addr;
176+
int32 relative_offset/*, initial_addend */;
177+
int16 imm16;
178+
179+
CHECK_RELOC_OFFSET(3); /* size of l32r instruction */
180+
181+
/*
182+
imm16 = is_little_endian() ?
183+
l32r_insn->l.imm16 : l32r_insn->b.imm16;
184+
initial_addend = (int32)imm16 << 2;
185+
*/
186+
187+
reloc_addr = (uint8*)symbol_addr + reloc_addend;
188+
189+
if ((intptr_t)reloc_addr & 3) {
190+
set_error_buf(error_buf, error_buf_size,
191+
"AOT module load failed: "
192+
"relocation address unaligned.");
193+
return false;
194+
}
195+
196+
relative_offset = (int32)
197+
((intptr_t)reloc_addr -
198+
(((intptr_t)insn_addr + 3) & ~(intptr_t)3));
199+
/* relative_offset += initial_addend; */
200+
201+
/* check relative offset boundary */
202+
if (relative_offset < -256 * BH_KB || relative_offset > -4) {
203+
set_error_buf(error_buf, error_buf_size,
204+
"AOT module load failed: "
205+
"target address out of range.");
206+
return false;
207+
}
208+
209+
imm16 = (int16)(relative_offset >> 2);
210+
211+
/* write back the imm16 to the l32r instruction */
212+
if (is_little_endian())
213+
put_imm16_to_addr(imm16, &l32r_insn->l.imm16);
214+
else
215+
put_imm16_to_addr(imm16, &l32r_insn->b.imm16);
216+
217+
break;
218+
}
52219

53220
default:
54221
if (error_buf != NULL)

core/iwasm/compilation/aot_emit_aot_file.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ typedef struct AOTObjectData {
4949
void *text;
5050
uint32 text_size;
5151

52+
/* literal data and size */
53+
void *literal;
54+
uint32 literal_size;
55+
5256
AOTObjectDataSection *data_sections;
5357
uint32 data_sections_count;
5458

@@ -379,7 +383,7 @@ get_init_data_section_size(AOTCompData *comp_data, AOTObjectData *obj_data)
379383
static uint32
380384
get_text_section_size(AOTObjectData *obj_data)
381385
{
382-
return obj_data->text_size;
386+
return (sizeof(uint32) + obj_data->literal_size + obj_data->text_size + 3) & ~3;
383387
}
384388

385389
static uint32
@@ -1118,13 +1122,20 @@ aot_emit_text_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
11181122
{
11191123
uint32 section_size = get_text_section_size(obj_data);
11201124
uint32 offset = *p_offset;
1125+
uint8 placeholder = 0;
11211126

11221127
*p_offset = offset = align_uint(offset, 4);
11231128

11241129
EMIT_U32(AOT_SECTION_TYPE_TEXT);
11251130
EMIT_U32(section_size);
1131+
EMIT_U32(obj_data->literal_size);
1132+
if (obj_data->literal_size > 0)
1133+
EMIT_BUF(obj_data->literal, obj_data->literal_size);
11261134
EMIT_BUF(obj_data->text, obj_data->text_size);
11271135

1136+
while (offset & 3)
1137+
EMIT_BUF(&placeholder, 1);
1138+
11281139
if (offset - *p_offset != section_size + sizeof(uint32) * 2) {
11291140
aot_set_last_error("emit text section failed.");
11301141
return false;
@@ -1449,6 +1460,29 @@ aot_resolve_text(AOTObjectData *obj_data)
14491460
return true;
14501461
}
14511462

1463+
static bool
1464+
aot_resolve_literal(AOTObjectData *obj_data)
1465+
{
1466+
LLVMSectionIteratorRef sec_itr;
1467+
char *name;
1468+
1469+
if (!(sec_itr = LLVMObjectFileCopySectionIterator(obj_data->binary))) {
1470+
aot_set_last_error("llvm get section iterator failed.");
1471+
return false;
1472+
}
1473+
while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
1474+
if ((name = (char *)LLVMGetSectionName(sec_itr)) && !strcmp(name, ".literal")) {
1475+
obj_data->literal = (char *)LLVMGetSectionContents(sec_itr);
1476+
obj_data->literal_size = (uint32)LLVMGetSectionSize(sec_itr);
1477+
break;
1478+
}
1479+
LLVMMoveToNextSection(sec_itr);
1480+
}
1481+
LLVMDisposeSectionIterator(sec_itr);
1482+
1483+
return true;
1484+
}
1485+
14521486
static bool
14531487
is_data_section(char *section_name)
14541488
{
@@ -1701,6 +1735,7 @@ is_relocation_section(char *section_name)
17011735
{
17021736
return (!strcmp(section_name, ".rela.text")
17031737
|| !strcmp(section_name, ".rel.text")
1738+
|| !strcmp(section_name, ".rela.literal")
17041739
|| !strcmp(section_name, ".rela.data")
17051740
|| !strcmp(section_name, ".rel.data")
17061741
|| !strcmp(section_name, ".rela.rodata")
@@ -1873,6 +1908,7 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
18731908
/* resolve target info/text/relocations/functions */
18741909
if (!aot_resolve_target_info(comp_ctx, obj_data)
18751910
|| !aot_resolve_text(obj_data)
1911+
|| !aot_resolve_literal(obj_data)
18761912
|| !aot_resolve_object_data_sections(obj_data)
18771913
|| !aot_resolve_object_relocation_groups(obj_data)
18781914
|| !aot_resolve_functions(comp_ctx, obj_data))

0 commit comments

Comments
 (0)