mirror of
				https://github.com/bytecodealliance/wasm-micro-runtime.git
				synced 2025-10-31 05:11:19 +00:00 
			
		
		
		
	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
This commit is contained in:
		
							parent
							
								
									c1a0e6d877
								
							
						
					
					
						commit
						c6fc12b7b6
					
				|  | @ -53,7 +53,7 @@ Execute following commands to build **wamrc** compiler: | |||
| 
 | ||||
| ```shell | ||||
| cd wamr-compiler | ||||
| ./build_llvm.sh | ||||
| ./build_llvm.sh (use build_llvm_xtensa.sh instead to support xtensa target) | ||||
| mkdir build && cd build | ||||
| cmake .. | ||||
| make | ||||
|  |  | |||
|  | @ -985,14 +985,21 @@ load_text_section(const uint8 *buf, const uint8 *buf_end, | |||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     module->code = (void*)buf; | ||||
|     module->code_size = (uint32)(buf_end - buf); | ||||
|     read_uint32(buf, buf_end, module->literal_size); | ||||
| 
 | ||||
|     /* literal data is at begining of the text section */ | ||||
|     module->literal = (uint8*)buf; | ||||
|     module->code = (void*)(buf + module->literal_size); | ||||
|     module->code_size = (uint32)(buf_end - (uint8*)module->code); | ||||
| 
 | ||||
|     if (module->code_size > 0) { | ||||
|         plt_base = (uint8*)buf_end - get_plt_table_size(); | ||||
|         init_plt_table(plt_base); | ||||
|     } | ||||
|     return true; | ||||
| 
 | ||||
| fail: | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
|  | @ -1184,13 +1191,20 @@ resolve_target_sym(const char *symbol, int32 *p_index) | |||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| is_literal_relocation(const char *reloc_sec_name) | ||||
| { | ||||
|     return !strcmp(reloc_sec_name, ".rela.literal"); | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| do_text_relocation(AOTModule *module, | ||||
|                    AOTRelocationGroup *group, | ||||
|                    char *error_buf, uint32 error_buf_size) | ||||
| { | ||||
|     uint8 *aot_text = module->code; | ||||
|     uint32 aot_text_size = module->code_size; | ||||
|     bool is_literal = is_literal_relocation(group->section_name); | ||||
|     uint8 *aot_text = is_literal ? module->literal : module->code; | ||||
|     uint32 aot_text_size = is_literal ? module->literal_size : module->code_size; | ||||
|     uint32 i, func_index, symbol_len; | ||||
|     char symbol_buf[128]  = { 0 }, *symbol, *p; | ||||
|     void *symbol_addr; | ||||
|  | @ -1248,6 +1262,9 @@ do_text_relocation(AOTModule *module, | |||
|                 goto check_symbol_fail; | ||||
|             } | ||||
|         } | ||||
|         else if (!strcmp(symbol, ".literal")) { | ||||
|             symbol_addr = module->literal; | ||||
|         } | ||||
|         else if (!(symbol_addr = resolve_target_sym(symbol, &symbol_index))) { | ||||
|             if (error_buf != NULL) | ||||
|                 snprintf(error_buf, error_buf_size, | ||||
|  | @ -1495,7 +1512,8 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end, | |||
|         } | ||||
| 
 | ||||
|         if (!strcmp(group->section_name, ".rel.text") | ||||
|             || !strcmp(group->section_name, ".rela.text")) { | ||||
|             || !strcmp(group->section_name, ".rela.text") | ||||
|             || !strcmp(group->section_name, ".rela.literal")) { | ||||
|             if (!do_text_relocation(module, group, error_buf, error_buf_size)) | ||||
|                 return false; | ||||
|         } | ||||
|  | @ -2079,8 +2097,11 @@ aot_unload(AOTModule *module) | |||
|     if (module->const_str_set) | ||||
|         bh_hash_map_destroy(module->const_str_set); | ||||
| 
 | ||||
|     if (module->code) | ||||
|         os_munmap(module->code, module->code_size); | ||||
|     if (module->code) { | ||||
|         uint8 *mmap_addr = module->literal - sizeof(module->literal_size); | ||||
|         uint32 total_size = sizeof(module->literal_size) + module->literal_size + module->code_size; | ||||
|         os_munmap(mmap_addr, total_size); | ||||
|     } | ||||
| 
 | ||||
|     if (module->data_sections) | ||||
|         destroy_object_data_sections(module->data_sections, | ||||
|  |  | |||
|  | @ -125,6 +125,10 @@ typedef struct AOTModule { | |||
|     void *code; | ||||
|     uint32 code_size; | ||||
| 
 | ||||
|     /* literal for AOTed code, NULL for JIT mode */ | ||||
|     uint8 *literal; | ||||
|     uint32 literal_size; | ||||
| 
 | ||||
|     /* data sections in AOT object file, including .data, .rodata
 | ||||
|      * and .rodata.cstN. NULL for JIT mode. */ | ||||
|     AOTObjectDataSection *data_sections; | ||||
|  |  | |||
|  | @ -5,10 +5,50 @@ | |||
| 
 | ||||
| #include "aot_reloc.h" | ||||
| 
 | ||||
| #define R_XTENSA_32        1   /* Direct 32 bit */ | ||||
| #define R_XTENSA_SLOT0_OP  20  /* PC relative */ | ||||
| 
 | ||||
| /* for soft-float */ | ||||
| void __floatsidf(); | ||||
| void __divdf3(); | ||||
| void __ltdf2(); | ||||
| 
 | ||||
| /* for mul32 */ | ||||
| void __mulsi3(); | ||||
| void __muldi3(); | ||||
| 
 | ||||
| void __modsi3(); | ||||
| 
 | ||||
| void __divdi3(); | ||||
| 
 | ||||
| static SymbolMap target_sym_map[] = { | ||||
|     REG_COMMON_SYMBOLS | ||||
|     REG_COMMON_SYMBOLS, | ||||
| 
 | ||||
|     /* API's for soft-float */ | ||||
|     /* TODO: only register these symbols when Floating-Point Coprocessor
 | ||||
|      * Option is not enabled */ | ||||
|     REG_SYM(__floatsidf), | ||||
|     REG_SYM(__divdf3), | ||||
|     REG_SYM(__ltdf2), | ||||
| 
 | ||||
|     /* API's for 32-bit integer multiply */ | ||||
|     /* TODO: only register these symbols when 32-bit Integer Multiply Option
 | ||||
|      * is not enabled */ | ||||
|     REG_SYM(__mulsi3), | ||||
|     REG_SYM(__muldi3), | ||||
| 
 | ||||
|     REG_SYM(__modsi3), | ||||
| 
 | ||||
|     REG_SYM(__divdi3), | ||||
| }; | ||||
| 
 | ||||
| static void | ||||
| set_error_buf(char *error_buf, uint32 error_buf_size, const char *string) | ||||
| { | ||||
|     if (error_buf != NULL) | ||||
|         snprintf(error_buf, error_buf_size, "%s", string); | ||||
| } | ||||
| 
 | ||||
| SymbolMap * | ||||
| get_target_symbol_map(uint32 *sym_num) | ||||
| { | ||||
|  | @ -40,6 +80,67 @@ get_plt_table_size() | |||
|     return get_plt_item_size() * (sizeof(target_sym_map) / sizeof(SymbolMap)); | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| check_reloc_offset(uint32 target_section_size, | ||||
|                    uint64 reloc_offset, uint32 reloc_data_size, | ||||
|                    char *error_buf, uint32 error_buf_size) | ||||
| { | ||||
|     if (!(reloc_offset < (uint64)target_section_size | ||||
|           && reloc_offset + reloc_data_size <= (uint64)target_section_size)) { | ||||
|         set_error_buf(error_buf, error_buf_size, | ||||
|                       "AOT module load failed: invalid relocation offset."); | ||||
|         return false; | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * CPU like esp32 can read and write data through the instruction bus, but only | ||||
|  * in a word aligned manner; non-word-aligned access will cause a CPU exception. | ||||
|  * This function uses a world aligned manner to write 16bit value to instruction | ||||
|  * addreess. | ||||
|  */ | ||||
| static void | ||||
| put_imm16_to_addr(int16 imm16, int16 *addr) | ||||
| { | ||||
|     int8 bytes[8]; | ||||
|     int32 *addr_aligned1, *addr_aligned2; | ||||
| 
 | ||||
|     addr_aligned1 = (int32*)((intptr_t)addr & ~3); | ||||
| 
 | ||||
|     if ((intptr_t)addr % 4 != 3) { | ||||
|         *(int32*)bytes = *addr_aligned1; | ||||
|         *(int16*)(bytes + ((intptr_t)addr % 4)) = imm16; | ||||
|         memcpy(addr_aligned1, bytes, 4); | ||||
|     } | ||||
|     else { | ||||
|         addr_aligned2 = (int32*)(((intptr_t)addr + 3) & ~3); | ||||
|         *(int32*)bytes = *addr_aligned1; | ||||
|         *(int32*)(bytes + 4) = *addr_aligned2; | ||||
|         *(int16*)(bytes + 3) = imm16; | ||||
|         memcpy(addr_aligned1, bytes, 8); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static union { | ||||
|     int a; | ||||
|     char b; | ||||
| } __ue = { .a = 1 }; | ||||
| 
 | ||||
| #define is_little_endian() (__ue.b == 1) | ||||
| 
 | ||||
| typedef union { | ||||
|     struct l32r_le { | ||||
|         int8 other; | ||||
|         int16 imm16; | ||||
|     } __packed l; | ||||
| 
 | ||||
|     struct l32r_be { | ||||
|         int16 imm16; | ||||
|         int8 other; | ||||
|     } __packed b; | ||||
| } l32r_insn_t; | ||||
| 
 | ||||
| bool | ||||
| apply_relocation(AOTModule *module, | ||||
|                  uint8 *target_section_addr, uint32 target_section_size, | ||||
|  | @ -48,7 +149,73 @@ apply_relocation(AOTModule *module, | |||
|                  char *error_buf, uint32 error_buf_size) | ||||
| { | ||||
|     switch (reloc_type) { | ||||
|         /* TODO: implement relocation for xtensa */ | ||||
|         case R_XTENSA_32: | ||||
|         { | ||||
|             uint8 *insn_addr = target_section_addr + reloc_offset; | ||||
|             int32 initial_addend; | ||||
|             /* (S + A) */ | ||||
|             if ((intptr_t)insn_addr & 3) { | ||||
|                 set_error_buf(error_buf, error_buf_size, | ||||
|                               "AOT module load failed: " | ||||
|                               "instruction address unaligned."); | ||||
|                 return false; | ||||
|             } | ||||
|             CHECK_RELOC_OFFSET(4); | ||||
|             initial_addend = *(int32*)insn_addr; | ||||
|             *(uint8**)insn_addr | ||||
|                 = (uint8*)symbol_addr + initial_addend + reloc_addend; | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         case R_XTENSA_SLOT0_OP: | ||||
|         { | ||||
|             uint8 *insn_addr = target_section_addr + reloc_offset; | ||||
|             /* Currently only l32r instruction generates R_XTENSA_SLOT0_OP relocation */ | ||||
|             l32r_insn_t *l32r_insn = (l32r_insn_t *)insn_addr; | ||||
|             uint8 *reloc_addr; | ||||
|             int32 relative_offset/*, initial_addend */; | ||||
|             int16 imm16; | ||||
| 
 | ||||
|             CHECK_RELOC_OFFSET(3); /* size of l32r instruction */ | ||||
| 
 | ||||
|             /*
 | ||||
|             imm16 = is_little_endian() ? | ||||
|                     l32r_insn->l.imm16 : l32r_insn->b.imm16; | ||||
|             initial_addend = (int32)imm16 << 2; | ||||
|             */ | ||||
| 
 | ||||
|             reloc_addr = (uint8*)symbol_addr + reloc_addend; | ||||
| 
 | ||||
|             if ((intptr_t)reloc_addr & 3) { | ||||
|                 set_error_buf(error_buf, error_buf_size, | ||||
|                               "AOT module load failed: " | ||||
|                               "relocation address unaligned."); | ||||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|             relative_offset = (int32) | ||||
|                               ((intptr_t)reloc_addr - | ||||
|                                (((intptr_t)insn_addr + 3) & ~(intptr_t)3)); | ||||
|             /* relative_offset += initial_addend; */ | ||||
| 
 | ||||
|             /* check relative offset boundary */ | ||||
|             if (relative_offset < -256 * BH_KB || relative_offset > -4) { | ||||
|                 set_error_buf(error_buf, error_buf_size, | ||||
|                               "AOT module load failed: " | ||||
|                               "target address out of range."); | ||||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|             imm16 = (int16)(relative_offset >> 2); | ||||
| 
 | ||||
|             /* write back the imm16 to the l32r instruction */ | ||||
|             if (is_little_endian()) | ||||
|                 put_imm16_to_addr(imm16, &l32r_insn->l.imm16); | ||||
|             else | ||||
|                 put_imm16_to_addr(imm16, &l32r_insn->b.imm16); | ||||
| 
 | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         default: | ||||
|             if (error_buf != NULL) | ||||
|  |  | |||
|  | @ -49,6 +49,10 @@ typedef struct AOTObjectData { | |||
|     void *text; | ||||
|     uint32 text_size; | ||||
| 
 | ||||
|     /* literal data and size */ | ||||
|     void *literal; | ||||
|     uint32 literal_size; | ||||
| 
 | ||||
|     AOTObjectDataSection *data_sections; | ||||
|     uint32 data_sections_count; | ||||
| 
 | ||||
|  | @ -379,7 +383,7 @@ get_init_data_section_size(AOTCompData *comp_data, AOTObjectData *obj_data) | |||
| static uint32 | ||||
| get_text_section_size(AOTObjectData *obj_data) | ||||
| { | ||||
|     return obj_data->text_size; | ||||
|     return (sizeof(uint32) + obj_data->literal_size + obj_data->text_size + 3) & ~3; | ||||
| } | ||||
| 
 | ||||
| static uint32 | ||||
|  | @ -1118,13 +1122,20 @@ aot_emit_text_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset, | |||
| { | ||||
|     uint32 section_size = get_text_section_size(obj_data); | ||||
|     uint32 offset = *p_offset; | ||||
|     uint8 placeholder = 0; | ||||
| 
 | ||||
|     *p_offset = offset = align_uint(offset, 4); | ||||
| 
 | ||||
|     EMIT_U32(AOT_SECTION_TYPE_TEXT); | ||||
|     EMIT_U32(section_size); | ||||
|     EMIT_U32(obj_data->literal_size); | ||||
|     if (obj_data->literal_size > 0) | ||||
|         EMIT_BUF(obj_data->literal, obj_data->literal_size); | ||||
|     EMIT_BUF(obj_data->text, obj_data->text_size); | ||||
| 
 | ||||
|     while (offset & 3) | ||||
|         EMIT_BUF(&placeholder, 1); | ||||
| 
 | ||||
|     if (offset - *p_offset != section_size + sizeof(uint32) * 2) { | ||||
|         aot_set_last_error("emit text section failed."); | ||||
|         return false; | ||||
|  | @ -1449,6 +1460,29 @@ aot_resolve_text(AOTObjectData *obj_data) | |||
|     return true; | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| aot_resolve_literal(AOTObjectData *obj_data) | ||||
| { | ||||
|     LLVMSectionIteratorRef sec_itr; | ||||
|     char *name; | ||||
| 
 | ||||
|     if (!(sec_itr = LLVMObjectFileCopySectionIterator(obj_data->binary))) { | ||||
|         aot_set_last_error("llvm get section iterator failed."); | ||||
|         return false; | ||||
|     } | ||||
|     while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) { | ||||
|         if ((name = (char *)LLVMGetSectionName(sec_itr)) && !strcmp(name, ".literal")) { | ||||
|             obj_data->literal = (char *)LLVMGetSectionContents(sec_itr); | ||||
|             obj_data->literal_size = (uint32)LLVMGetSectionSize(sec_itr); | ||||
|             break; | ||||
|         } | ||||
|         LLVMMoveToNextSection(sec_itr); | ||||
|     } | ||||
|     LLVMDisposeSectionIterator(sec_itr); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| is_data_section(char *section_name) | ||||
| { | ||||
|  | @ -1701,6 +1735,7 @@ is_relocation_section(char *section_name) | |||
| { | ||||
|     return (!strcmp(section_name, ".rela.text") | ||||
|             || !strcmp(section_name, ".rel.text") | ||||
|             || !strcmp(section_name, ".rela.literal") | ||||
|             || !strcmp(section_name, ".rela.data") | ||||
|             || !strcmp(section_name, ".rel.data") | ||||
|             || !strcmp(section_name, ".rela.rodata") | ||||
|  | @ -1873,6 +1908,7 @@ aot_obj_data_create(AOTCompContext *comp_ctx) | |||
|     /* resolve target info/text/relocations/functions */ | ||||
|     if (!aot_resolve_target_info(comp_ctx, obj_data) | ||||
|         || !aot_resolve_text(obj_data) | ||||
|         || !aot_resolve_literal(obj_data) | ||||
|         || !aot_resolve_object_data_sections(obj_data) | ||||
|         || !aot_resolve_object_relocation_groups(obj_data) | ||||
|         || !aot_resolve_functions(comp_ctx, obj_data)) | ||||
|  |  | |||
|  | @ -858,18 +858,63 @@ fail: | |||
| } | ||||
| 
 | ||||
| static bool | ||||
| is_targeting_soft_float(LLVMTargetMachineRef target_machine) | ||||
| is_target_arm(AOTCompContext *comp_ctx) | ||||
| { | ||||
|     return !strncmp(comp_ctx->target_arch, "arm", 3) || | ||||
|            !strncmp(comp_ctx->target_arch, "thumb", 5); | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| is_target_x86(AOTCompContext *comp_ctx) | ||||
| { | ||||
|     return !strncmp(comp_ctx->target_arch, "x86_64", 6) || | ||||
|            !strncmp(comp_ctx->target_arch, "i386", 4); | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| is_target_xtensa(AOTCompContext *comp_ctx) | ||||
| { | ||||
|     return !strncmp(comp_ctx->target_arch, "xtensa", 6); | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| is_target_mips(AOTCompContext *comp_ctx) | ||||
| { | ||||
|     return !strncmp(comp_ctx->target_arch, "mips", 4); | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| is_targeting_soft_float(AOTCompContext *comp_ctx, bool is_f32) | ||||
| { | ||||
|     bool ret = false; | ||||
|     char *feature_string; | ||||
| 
 | ||||
|     if (!(feature_string = | ||||
|                 LLVMGetTargetMachineFeatureString(target_machine))) { | ||||
|                 LLVMGetTargetMachineFeatureString(comp_ctx->target_machine))) { | ||||
|         aot_set_last_error("llvm get target machine feature string fail."); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     ret = strstr(feature_string, "+soft-float") ? true : false; | ||||
|     /* Note:
 | ||||
|      * LLVM CodeGen uses FPU Coprocessor registers by default, | ||||
|      * so user must specify '--cpu-features=+soft-float' to wamrc if the target | ||||
|      * doesn't have or enable FPU on arm, x86 or mips. */ | ||||
|     if (is_target_arm(comp_ctx) || | ||||
|         is_target_x86(comp_ctx) || | ||||
|         is_target_mips(comp_ctx)) | ||||
|         ret = strstr(feature_string, "+soft-float") ? true : false; | ||||
|     else if (is_target_xtensa(comp_ctx)) | ||||
|         /* Note:
 | ||||
|          * 1. The Floating-Point Coprocessor Option of xtensa only support | ||||
|          * single-precision floating-point operations, so must use soft-float | ||||
|          * for f64(i.e. double). | ||||
|          * 2. LLVM CodeGen uses Floating-Point Coprocessor registers by default, | ||||
|          * so user must specify '--cpu-features=-fp' to wamrc if the target | ||||
|          * doesn't have or enable Floating-Point Coprocessor Option on xtensa. */ | ||||
|         ret = (!is_f32 || strstr(feature_string, "-fp")) ? true : false; | ||||
|     else | ||||
|         ret = true; | ||||
| 
 | ||||
|     LLVMDisposeMessage(feature_string); | ||||
|     return ret; | ||||
| } | ||||
|  | @ -880,7 +925,7 @@ compile_op_float_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | |||
| { | ||||
|     switch (arith_op) { | ||||
|         case FLOAT_ADD: | ||||
|             if (is_targeting_soft_float(comp_ctx->target_machine)) | ||||
|             if (is_targeting_soft_float(comp_ctx, is_f32)) | ||||
|                 DEF_FP_BINARY_OP(LLVMBuildFAdd(comp_ctx->builder, left, right, "fadd"), | ||||
|                                  "llvm build fadd fail."); | ||||
|             else | ||||
|  | @ -897,7 +942,7 @@ compile_op_float_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | |||
|                                  NULL); | ||||
|             return true; | ||||
|         case FLOAT_SUB: | ||||
|             if (is_targeting_soft_float(comp_ctx->target_machine)) | ||||
|             if (is_targeting_soft_float(comp_ctx, is_f32)) | ||||
|                 DEF_FP_BINARY_OP(LLVMBuildFSub(comp_ctx->builder, left, right, "fsub"), | ||||
|                                  "llvm build fsub fail."); | ||||
|             else | ||||
|  | @ -914,7 +959,7 @@ compile_op_float_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | |||
|                                  NULL); | ||||
|             return true; | ||||
|         case FLOAT_MUL: | ||||
|             if (is_targeting_soft_float(comp_ctx->target_machine)) | ||||
|             if (is_targeting_soft_float(comp_ctx, is_f32)) | ||||
|                 DEF_FP_BINARY_OP(LLVMBuildFMul(comp_ctx->builder, left, right, "fmul"), | ||||
|                                  "llvm build fmul fail."); | ||||
|             else | ||||
|  | @ -931,7 +976,7 @@ compile_op_float_arithmetic(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | |||
|                                  NULL); | ||||
|             return true; | ||||
|         case FLOAT_DIV: | ||||
|             if (is_targeting_soft_float(comp_ctx->target_machine)) | ||||
|             if (is_targeting_soft_float(comp_ctx, is_f32)) | ||||
|                 DEF_FP_BINARY_OP(LLVMBuildFDiv(comp_ctx->builder, left, right, "fdiv"), | ||||
|                                  "llvm build fdiv fail."); | ||||
|             else | ||||
|  | @ -1050,7 +1095,7 @@ compile_op_float_math(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, | |||
|                             NULL); | ||||
|             return true; | ||||
|         case FLOAT_SQRT: | ||||
|             if (is_targeting_soft_float(comp_ctx->target_machine)) | ||||
|             if (is_targeting_soft_float(comp_ctx, is_f32)) | ||||
|                 DEF_FP_UNARY_OP(call_llvm_float_math_intrinsic(comp_ctx, | ||||
|                                                    is_f32 ? "llvm.sqrt.f32" : | ||||
|                                                             "llvm.sqrt.f64", | ||||
|  |  | |||
|  | @ -740,6 +740,7 @@ typedef struct ArchItem { | |||
| static ArchItem valid_archs[] = { | ||||
|     { "x86_64", false }, | ||||
|     { "i386", false }, | ||||
|     { "xtensa", false}, | ||||
|     { "mips", true }, | ||||
|     { "aarch64v8", false }, | ||||
|     { "aarch64v8.1", false }, | ||||
|  |  | |||
|  | @ -77,4 +77,24 @@ unsigned long long int strtoull(const char *nptr, char **endptr, int base); | |||
| double strtod(const char *nptr, char **endptr); | ||||
| float strtof(const char *nptr, char **endptr); | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Allocate executable memroy | ||||
|  * | ||||
|  * @param size size of the memory to be allocated | ||||
|  * | ||||
|  * @return the address of the allocated memory if not NULL | ||||
|  */ | ||||
| typedef void* (*exec_mem_alloc_func_t)(unsigned int size); | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Release executable memroy | ||||
|  * | ||||
|  * @param the address of the executable memory to be released | ||||
|  */ | ||||
| typedef void (*exec_mem_free_func_t)(void *addr); | ||||
| 
 | ||||
| /* Below function are called by external project to set related function pointers that
 | ||||
|  * will be used to malloc/free executable memory. Otherwise default mechanise will be used. */ | ||||
| void set_exec_mem_alloc_func(exec_mem_alloc_func_t alloc_func, exec_mem_free_func_t free_func); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -6,6 +6,10 @@ | |||
| #include "platform_api_vmcore.h" | ||||
| #include "platform_api_extension.h" | ||||
| 
 | ||||
| /* function pointers for executable memory management */ | ||||
| static exec_mem_alloc_func_t exec_mem_alloc_func = NULL; | ||||
| static exec_mem_free_func_t exec_mem_free_func = NULL; | ||||
| 
 | ||||
| #if WASM_ENABLE_AOT != 0 | ||||
| #ifdef CONFIG_ARM_MPU | ||||
| /**
 | ||||
|  | @ -108,13 +112,19 @@ os_vprintf(const char *fmt, va_list ap) | |||
| void * | ||||
| os_mmap(void *hint, unsigned int size, int prot, int flags) | ||||
| { | ||||
|     return BH_MALLOC(size); | ||||
|     if (exec_mem_alloc_func) | ||||
|         return exec_mem_alloc_func(size); | ||||
|     else | ||||
|         return BH_MALLOC(size); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| os_munmap(void *addr, uint32 size) | ||||
| { | ||||
|     return BH_FREE(addr); | ||||
|     if (exec_mem_free_func) | ||||
|         exec_mem_free_func(addr); | ||||
|     else | ||||
|         BH_FREE(addr); | ||||
| } | ||||
| 
 | ||||
| int | ||||
|  | @ -133,3 +143,11 @@ os_dcache_flush() | |||
|     irq_unlock(key); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void set_exec_mem_alloc_func(exec_mem_alloc_func_t alloc_func, | ||||
|                              exec_mem_free_func_t free_func) | ||||
| { | ||||
|     exec_mem_alloc_func = alloc_func; | ||||
|     exec_mem_free_func = free_func; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -277,14 +277,13 @@ AliOS-Things | |||
|    aos make | ||||
|    ./out/helloworld@linuxhost/binary/helloworld@linuxhost.elf | ||||
|    ``` | ||||
| ``` | ||||
|     | ||||
| 
 | ||||
|    For developerkit: | ||||
|    Modify file middleware/iwasm/aos.mk, patch as: | ||||
|     | ||||
|    ``` C | ||||
| WAMR_BUILD_TARGET := THUMBV7M | ||||
| ``` | ||||
|    WAMR_BUILD_TARGET := THUMBV7M | ||||
|    ``` | ||||
| 
 | ||||
|    ``` Bash | ||||
|    aos make helloworld@developerkit -c config | ||||
|  |  | |||
|  | @ -90,7 +90,7 @@ wamrc supports a number of compilation options through the command line argument | |||
| wamrc --help | ||||
| Usage: wamrc [options] -o output_file wasm_file | ||||
|   --target=<arch-name>      Set the target arch, which has the general format: <arch><sub> | ||||
|                             <arch> = x86_64, i386, arm, thumb, mips. | ||||
|                             <arch> = x86_64, i386, aarch64, arm, thumb, xtensa, mips. | ||||
|                               Default is host arch, e.g. x86_64 | ||||
|                             <sub> = for ex. on arm or thumb: v5, v6m, v7a, v7m, etc. | ||||
|                             Use --target=help to list supported targets | ||||
|  |  | |||
|  | @ -92,6 +92,7 @@ $(NAME)_SOURCES := ${SHARED_ROOT}/platform/alios/alios_platform.c \ | |||
|                    ${SHARED_ROOT}/utils/bh_log.c \
 | ||||
|                    ${SHARED_ROOT}/utils/bh_queue.c \
 | ||||
|                    ${SHARED_ROOT}/utils/bh_vector.c \
 | ||||
|                    ${SHARED_ROOT}/utils/runtime_timer.c \
 | ||||
|                    ${IWASM_ROOT}/libraries/libc-builtin/libc_builtin_wrapper.c \
 | ||||
|                    ${IWASM_ROOT}/common/wasm_runtime_common.c \
 | ||||
|                    ${IWASM_ROOT}/common/wasm_native.c \
 | ||||
|  |  | |||
|  | @ -37,48 +37,10 @@ if (NOT DEFINED WAMR_BUILD_LIBC_WASI) | |||
| endif () | ||||
| 
 | ||||
| set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/wamr) | ||||
| set (SHARED_DIR ${WAMR_ROOT_DIR}/core/shared) | ||||
| set (IWASM_DIR ${WAMR_ROOT_DIR}/core/iwasm) | ||||
| set (APP_FRAMEWORK_DIR ${WAMR_ROOT_DIR}/core/app-framework) | ||||
| 
 | ||||
| # include the build config template makefile | ||||
| include (${WAMR_ROOT_DIR}/build-scripts/config_common.cmake) | ||||
| 
 | ||||
| include_directories (${SHARED_DIR}/include | ||||
|                      ${IWASM_DIR}/include) | ||||
| 
 | ||||
| include (${SHARED_DIR}/platform/${WAMR_BUILD_PLATFORM}/shared_platform.cmake) | ||||
| include (${SHARED_DIR}/mem-alloc/mem_alloc.cmake) | ||||
| include (${SHARED_DIR}/utils/shared_utils.cmake) | ||||
| if (WAMR_BUILD_LIBC_BUILTIN EQUAL 1) | ||||
|   include (${IWASM_DIR}/libraries/libc-builtin/libc_builtin.cmake) | ||||
| endif () | ||||
| if (WAMR_BUILD_LIBC_WASI EQUAL 1) | ||||
|   include (${IWASM_DIR}/libraries/libc-wasi/libc_wasi.cmake) | ||||
| endif () | ||||
| 
 | ||||
| include (${IWASM_DIR}/common/iwasm_common.cmake) | ||||
| 
 | ||||
| if (WAMR_BUILD_INTERP EQUAL 1 OR WAMR_BUILD_JIT EQUAL 1) | ||||
|   include (${IWASM_DIR}/interpreter/iwasm_interp.cmake) | ||||
| endif() | ||||
| 
 | ||||
| if (WAMR_BUILD_AOT EQUAL 1) | ||||
|   include (${IWASM_DIR}/aot/iwasm_aot.cmake) | ||||
| endif () | ||||
| 
 | ||||
| set (VM_LIB_SRCS | ||||
|      ${PLATFORM_SHARED_SOURCE} | ||||
|      ${MEM_ALLOC_SHARED_SOURCE} | ||||
|      ${UTILS_SHARED_SOURCE} | ||||
|      ${LIBC_BUILTIN_SOURCE} | ||||
|      ${LIBC_WASI_SOURCE} | ||||
|      ${IWASM_COMMON_SOURCE} | ||||
|      ${IWASM_INTERP_SOURCE} | ||||
|      ${IWASM_AOT_SOURCE} | ||||
|      ${IWASM_COMPL_SOURCE}) | ||||
| include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) | ||||
| 
 | ||||
| target_sources(app PRIVATE | ||||
|                ${VM_LIB_SRCS} | ||||
|                ${WAMR_RUNTIME_LIB_SOURCE} | ||||
|                src/main.c) | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,14 +6,18 @@ | |||
| X86_TARGET="x86" | ||||
| STM32_TARGET="stm32" | ||||
| QEMU_CORTEX_A53="qemu_cortex_a53" | ||||
| XTENSA_QEMU_TARGET="xtensa-qemu" | ||||
| ESP32_TARGET="esp32" | ||||
| 
 | ||||
| if [ $# != 1 ] ; then | ||||
|         echo "USAGE:" | ||||
|         echo "$0 $X86_TARGET|$STM32_TARGET|$QEMU_CORTEX_A53" | ||||
|         echo "$0 $X86_TARGET|$STM32_TARGET|$QEMU_CORTEX_A53|$XTENSA_QEMU_TARGET|$ESP32_TARGET" | ||||
|         echo "Example:" | ||||
|         echo "        $0 $X86_TARGET" | ||||
|         echo "        $0 $STM32_TARGET" | ||||
|         echo "        $0 $QEMU_CORTEX_A53" | ||||
|         echo "        $0 $XTENSA_QEMU_TARGET" | ||||
|         echo "        $0 $ESP32_TARGET" | ||||
|         exit 1 | ||||
| fi | ||||
| 
 | ||||
|  | @ -31,6 +35,21 @@ elif [ "$TARGET" = "$STM32_TARGET" ] ; then | |||
|         cmake -GNinja -DBOARD=nucleo_f767zi -DWAMR_BUILD_TARGET=THUMBV7 .. | ||||
|         ninja | ||||
|         ninja flash | ||||
| elif [ "$TARGET" = "$XTENSA_QEMU_TARGET" ] ; then | ||||
|         cp prj_qemu_xtensa.conf prj.conf | ||||
|         rm -fr build && mkdir build && cd build | ||||
|         cmake -GNinja -DBOARD=qemu_xtensa -DWAMR_BUILD_TARGET=XTENSA .. | ||||
|         ninja | ||||
|         ninja run | ||||
| elif [ "$TARGET" = "$ESP32_TARGET" ] ; then | ||||
|         # suppose you have set environment variable ESP_IDF_PATH | ||||
|         west build -b esp32 . -p always -- \ | ||||
|                 -DESP_IDF_PATH=$ESP_IDF_PATH \ | ||||
|                 -DCONF_FILE=prj_esp32.conf \ | ||||
|                 -DWAMR_BUILD_TARGET=XTENSA | ||||
|         # suppose the serial port is /dev/ttyUSB1 and you should change to | ||||
|         # the real name accordingly | ||||
|         west flash -d ./build --skip-rebuild --esp-device /dev/ttyUSB1 | ||||
| elif [ "$TARGET" = "$QEMU_CORTEX_A53" ] ; then | ||||
|         cp prj_qemu_cortex_a53.conf prj.conf | ||||
|         rm -fr build && mkdir build && cd build | ||||
|  |  | |||
							
								
								
									
										274
									
								
								product-mini/platforms/zephyr/simple/esp32_custom_linker.ld
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								product-mini/platforms/zephyr/simple/esp32_custom_linker.ld
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,274 @@ | |||
| /* | ||||
|  * Copyright (c) 2016 Cadence Design Systems, Inc. | ||||
|  * Copyright (c) 2017 Intel Corporation | ||||
|  * SPDX-License-Identifier: Apache-2.0 | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * @file | ||||
|  * @brief Linker command/script file | ||||
|  * | ||||
|  * Linker script for the Xtensa platform. | ||||
|  */ | ||||
| 
 | ||||
| #include <devicetree.h> | ||||
| #include <autoconf.h> | ||||
| #include <linker/sections.h> | ||||
| #include <linker/linker-defs.h> | ||||
| #include <linker/linker-tool.h> | ||||
| 
 | ||||
| #define RAMABLE_REGION dram0_0_seg :dram0_0_phdr | ||||
| #define RAMABLE_REGION1 dram0_1_seg :dram0_0_phdr | ||||
| #define ROMABLE_REGION iram0_0_seg :iram0_0_phdr | ||||
| 
 | ||||
| PROVIDE ( __stack = 0x3ffe3f20 ); | ||||
| 
 | ||||
| PROVIDE ( esp32_rom_uart_tx_one_char = 0x40009200 ); | ||||
| PROVIDE ( esp32_rom_uart_rx_one_char = 0x400092d0 ); | ||||
| PROVIDE ( esp32_rom_uart_attach = 0x40008fd0 ); | ||||
| PROVIDE ( esp32_rom_intr_matrix_set = 0x4000681c ); | ||||
| PROVIDE ( esp32_rom_gpio_matrix_in = 0x40009edc ); | ||||
| PROVIDE ( esp32_rom_gpio_matrix_out = 0x40009f0c ); | ||||
| PROVIDE ( esp32_rom_Cache_Flush = 0x40009a14 ); | ||||
| PROVIDE ( esp32_rom_Cache_Read_Enable = 0x40009a84 ); | ||||
| PROVIDE ( esp32_rom_ets_set_appcpu_boot_addr = 0x4000689c ); | ||||
| 
 | ||||
| MEMORY | ||||
| { | ||||
|   iram0_0_seg(RX): org = 0x40080000, len = 0x20000 | ||||
|   iram0_2_seg(RX): org = 0x400D0018, len = 0x330000 | ||||
|   dram0_0_seg(RW): org = 0x3FFB0000, len = 0x30000 | ||||
|   dram0_1_seg(RWX):org = 0x400A0000, len = 0x20000 | ||||
|   drom0_0_seg(R): org = 0x3F400010, len = 0x800000 | ||||
|   rtc_iram_seg(RWX): org = 0x400C0000, len = 0x2000 | ||||
|   rtc_slow_seg(RW): org = 0x50000000, len = 0x1000 | ||||
| #ifdef CONFIG_GEN_ISR_TABLES | ||||
|   IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000 | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| PHDRS | ||||
| { | ||||
|   iram0_0_phdr PT_LOAD; | ||||
|   dram0_0_phdr PT_LOAD; | ||||
| } | ||||
| 
 | ||||
| /*  Default entry point:  */ | ||||
| PROVIDE ( _ResetVector = 0x40000400 ); | ||||
| ENTRY(CONFIG_KERNEL_ENTRY) | ||||
| 
 | ||||
| _rom_store_table = 0; | ||||
| 
 | ||||
| PROVIDE(_memmap_vecbase_reset = 0x40000450); | ||||
| PROVIDE(_memmap_reset_vector = 0x40000400); | ||||
| 
 | ||||
| SECTIONS | ||||
| { | ||||
| 
 | ||||
| #include <linker/rel-sections.ld> | ||||
| 
 | ||||
|   /* RTC fast memory holds RTC wake stub code, | ||||
|      including from any source file named rtc_wake_stub*.c | ||||
|   */ | ||||
|   .rtc.text : | ||||
|   { | ||||
|     . = ALIGN(4); | ||||
|     *(.rtc.literal .rtc.text) | ||||
|     *rtc_wake_stub*.o(.literal .text .literal.* .text.*) | ||||
|   } >rtc_iram_seg | ||||
| 
 | ||||
|   /* RTC slow memory holds RTC wake stub | ||||
|      data/rodata, including from any source file | ||||
|      named rtc_wake_stub*.c | ||||
|   */ | ||||
|   .rtc.data : | ||||
|   { | ||||
|     _rtc_data_start = ABSOLUTE(.); | ||||
|     *(.rtc.data) | ||||
|     *(.rtc.rodata) | ||||
|     *rtc_wake_stub*.o(.data .rodata .data.* .rodata.* .bss .bss.*) | ||||
|     _rtc_data_end = ABSOLUTE(.); | ||||
|   } > rtc_slow_seg | ||||
| 
 | ||||
|   /* RTC bss, from any source file named rtc_wake_stub*.c */ | ||||
|   .rtc.bss (NOLOAD) : | ||||
|   { | ||||
|     _rtc_bss_start = ABSOLUTE(.); | ||||
|     *rtc_wake_stub*.o(.bss .bss.*) | ||||
|     *rtc_wake_stub*.o(COMMON) | ||||
|     _rtc_bss_end = ABSOLUTE(.); | ||||
|   } > rtc_slow_seg | ||||
| 
 | ||||
|   /* Send .iram0 code to iram */ | ||||
|   .iram0.vectors : ALIGN(4) | ||||
|   { | ||||
|     /* Vectors go to IRAM */ | ||||
|     _init_start = ABSOLUTE(.); | ||||
|     /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */ | ||||
|     . = 0x0; | ||||
|     KEEP(*(.WindowVectors.text)); | ||||
|     . = 0x180; | ||||
|     KEEP(*(.Level2InterruptVector.text)); | ||||
|     . = 0x1c0; | ||||
|     KEEP(*(.Level3InterruptVector.text)); | ||||
|     . = 0x200; | ||||
|     KEEP(*(.Level4InterruptVector.text)); | ||||
|     . = 0x240; | ||||
|     KEEP(*(.Level5InterruptVector.text)); | ||||
|     . = 0x280; | ||||
|     KEEP(*(.DebugExceptionVector.text)); | ||||
|     . = 0x2c0; | ||||
|     KEEP(*(.NMIExceptionVector.text)); | ||||
|     . = 0x300; | ||||
|     KEEP(*(.KernelExceptionVector.text)); | ||||
|     . = 0x340; | ||||
|     KEEP(*(.UserExceptionVector.text)); | ||||
|     . = 0x3C0; | ||||
|     KEEP(*(.DoubleExceptionVector.text)); | ||||
|     . = 0x400; | ||||
|     *(.*Vector.literal) | ||||
| 
 | ||||
|     *(.UserEnter.literal); | ||||
|     *(.UserEnter.text); | ||||
|     . = ALIGN (16); | ||||
|     *(.entry.text) | ||||
|     *(.init.literal) | ||||
|     *(.init) | ||||
|     _init_end = ABSOLUTE(.); | ||||
| 
 | ||||
|     /* This goes here, not at top of linker script, so addr2line finds it last, | ||||
|        and uses it in preference to the first symbol in IRAM */ | ||||
|     _iram_start = ABSOLUTE(0); | ||||
|   } GROUP_LINK_IN(ROMABLE_REGION) | ||||
| 
 | ||||
| #include <linker/common-ram.ld> | ||||
| #include <linker/common-rom.ld> | ||||
| 
 | ||||
|   SECTION_PROLOGUE(_TEXT_SECTION_NAME, , ALIGN(4)) | ||||
|   { | ||||
|     /* Code marked as running out of IRAM */ | ||||
|     _iram_text_start = ABSOLUTE(.); | ||||
|     *(.iram1 .iram1.*) | ||||
|     *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) | ||||
|     *(.literal .text .literal.* .text.*) | ||||
|     _iram_text_end = ABSOLUTE(.); | ||||
|   } GROUP_LINK_IN(ROMABLE_REGION) | ||||
| 
 | ||||
|   .dram0.text : | ||||
|   { | ||||
|     _data_start = ABSOLUTE(.); | ||||
|     *(.aot_code_buf) | ||||
|     _data_end = ABSOLUTE(.); | ||||
|     . = ALIGN(4); | ||||
|   } GROUP_LINK_IN(RAMABLE_REGION1) | ||||
| 
 | ||||
| 
 | ||||
|   .dram0.data : | ||||
|   { | ||||
|     _data_start = ABSOLUTE(.); | ||||
|     *(.data) | ||||
|     *(.data.*) | ||||
|     *(.gnu.linkonce.d.*) | ||||
|     *(.data1) | ||||
|     *(.sdata) | ||||
|     *(.sdata.*) | ||||
|     *(.gnu.linkonce.s.*) | ||||
|     *(.sdata2) | ||||
|     *(.sdata2.*) | ||||
|     *(.gnu.linkonce.s2.*) | ||||
|     KEEP(*(.jcr)) | ||||
|     *(.dram1 .dram1.*) | ||||
|     _data_end = ABSOLUTE(.); | ||||
|     . = ALIGN(4); | ||||
|   } GROUP_LINK_IN(RAMABLE_REGION) | ||||
| 
 | ||||
|   SECTION_PROLOGUE(_RODATA_SECTION_NAME,,ALIGN(4)) | ||||
|   { | ||||
|     _rodata_start = ABSOLUTE(.); | ||||
|     *(.rodata) | ||||
|     *(.rodata.*) | ||||
|     *(.gnu.linkonce.r.*) | ||||
|     *(.rodata1) | ||||
|     __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); | ||||
|     KEEP (*(.xt_except_table)) | ||||
|     KEEP (*(.gcc_except_table .gcc_except_table.*)) | ||||
|     *(.gnu.linkonce.e.*) | ||||
|     *(.gnu.version_r) | ||||
|     KEEP (*(.eh_frame)) | ||||
|     /*  C++ constructor and destructor tables, properly ordered:  */ | ||||
|     KEEP (*crtbegin.o(.ctors)) | ||||
|     KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) | ||||
|     KEEP (*(SORT(.ctors.*))) | ||||
|     KEEP (*(.ctors)) | ||||
|     KEEP (*crtbegin.o(.dtors)) | ||||
|     KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) | ||||
|     KEEP (*(SORT(.dtors.*))) | ||||
|     KEEP (*(.dtors)) | ||||
|     /*  C++ exception handlers table:  */ | ||||
|     __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); | ||||
|     *(.xt_except_desc) | ||||
|     *(.gnu.linkonce.h.*) | ||||
|     __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); | ||||
|     *(.xt_except_desc_end) | ||||
|     *(.dynamic) | ||||
|     *(.gnu.version_d) | ||||
|     . = ALIGN(4);               /* this table MUST be 4-byte aligned */ | ||||
|     _rodata_end = ABSOLUTE(.); | ||||
|   } GROUP_LINK_IN(RAMABLE_REGION) | ||||
| 
 | ||||
| 
 | ||||
|   /* Shared RAM */ | ||||
|   SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) | ||||
|   { | ||||
|     . = ALIGN (8); | ||||
|     _bss_start = ABSOLUTE(.); | ||||
|     *(.dynsbss) | ||||
|     *(.sbss) | ||||
|     *(.sbss.*) | ||||
|     *(.gnu.linkonce.sb.*) | ||||
|     *(.scommon) | ||||
|     *(.sbss2) | ||||
|     *(.sbss2.*) | ||||
|     *(.gnu.linkonce.sb2.*) | ||||
|     *(.dynbss) | ||||
|     *(.bss) | ||||
|     *(.bss.*) | ||||
|     *(.share.mem) | ||||
|     *(.gnu.linkonce.b.*) | ||||
|     *(COMMON) | ||||
|     . = ALIGN (8); | ||||
|     _bss_end = ABSOLUTE(.); | ||||
|   } GROUP_LINK_IN(RAMABLE_REGION) | ||||
| 
 | ||||
| 
 | ||||
|    SECTION_DATA_PROLOGUE(_APP_NOINIT_SECTION_NAME, (NOLOAD),) | ||||
|    { | ||||
|      . = ALIGN (8); | ||||
|      *(.app_noinit) | ||||
|      *("app_noinit.*") | ||||
|      . = ALIGN (8); | ||||
|     _app_end = ABSOLUTE(.); | ||||
|   } GROUP_LINK_IN(RAMABLE_REGION) | ||||
| 
 | ||||
| 
 | ||||
|   SECTION_DATA_PROLOGUE(_NOINIT_SECTION_NAME, (NOLOAD),) | ||||
|   { | ||||
|     . = ALIGN (8); | ||||
|     *(.noinit) | ||||
|     *(".noinit.*") | ||||
|     . = ALIGN (8); | ||||
|     _heap_start = ABSOLUTE(.); | ||||
|   } GROUP_LINK_IN(RAMABLE_REGION) | ||||
| 
 | ||||
| #ifdef CONFIG_GEN_ISR_TABLES | ||||
| #include <linker/intlist.ld> | ||||
| #endif | ||||
| 
 | ||||
| #include <linker/debug-sections.ld> | ||||
| 
 | ||||
|   SECTION_PROLOGUE(.xtensa.info, 0,) | ||||
|   { | ||||
|     *(.xtensa.info) | ||||
|   } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										8
									
								
								product-mini/platforms/zephyr/simple/prj_esp32.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								product-mini/platforms/zephyr/simple/prj_esp32.conf
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| # Copyright (C) 2019 Intel Corporation.  All rights reserved. | ||||
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||
| 
 | ||||
| CONFIG_STACK_SENTINEL=y | ||||
| CONFIG_PRINTK=y | ||||
| CONFIG_LOG=y | ||||
| CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y | ||||
| CONFIG_CUSTOM_LINKER_SCRIPT="esp32_custom_linker.ld" | ||||
|  | @ -0,0 +1,6 @@ | |||
| # Copyright (C) 2019 Intel Corporation.  All rights reserved. | ||||
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||
| 
 | ||||
| CONFIG_STACK_SENTINEL=y | ||||
| CONFIG_PRINTK=y | ||||
| CONFIG_LOG=y | ||||
|  | @ -54,6 +54,54 @@ app_instance_main(wasm_module_inst_t module_inst) | |||
| 
 | ||||
| static char global_heap_buf[CONFIG_GLOBAL_HEAP_BUF_SIZE] = { 0 }; | ||||
| 
 | ||||
| #ifdef CONFIG_BOARD_ESP32 | ||||
| #include "mem_alloc.h" | ||||
| /*
 | ||||
| esp32_technical_reference_manual: | ||||
| " | ||||
| The capacity of Internal SRAM 1 is 128 KB. Either CPU can read and write this memory at addresses | ||||
| 0x3FFE_0000 ~ 0x3FFF_FFFF of the data bus, and also at addresses 0x400A_0000 ~ 0x400B_FFFF of the | ||||
| instruction bus. | ||||
| " | ||||
| 
 | ||||
| The custom linker script defines dram0_1_seg and map it to 0x400A_0000 ~ 0x400B_FFFF for instruction bus access. | ||||
| Here we define the buffer that will be placed to dram0_1_seg. | ||||
| */ | ||||
| static char esp32_executable_memory_buf[100 * 1024] __attribute__((section (".aot_code_buf"))) = { 0 }; | ||||
| 
 | ||||
| /* the poll allocator for executable memory */ | ||||
| static mem_allocator_t esp32_exec_mem_pool_allocator; | ||||
| 
 | ||||
| static int | ||||
| esp32_exec_mem_init() | ||||
| { | ||||
|     if (!(esp32_exec_mem_pool_allocator = | ||||
|                 mem_allocator_create(esp32_executable_memory_buf, | ||||
|                                      sizeof(esp32_executable_memory_buf)))) | ||||
|         return -1; | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| esp32_exec_mem_destroy() | ||||
| { | ||||
|     mem_allocator_destroy(esp32_exec_mem_pool_allocator); | ||||
| } | ||||
| 
 | ||||
| static void * | ||||
| esp32_exec_mem_alloc(unsigned int size) | ||||
| { | ||||
|     return mem_allocator_malloc(esp32_exec_mem_pool_allocator, size); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| esp32_exec_mem_free(void *addr) | ||||
| { | ||||
|     mem_allocator_free(esp32_exec_mem_pool_allocator, addr); | ||||
| } | ||||
| #endif /* end of #ifdef CONFIG_BOARD_ESP32 */ | ||||
| 
 | ||||
| void iwasm_main(void *arg1, void *arg2, void *arg3) | ||||
| { | ||||
|     int start, end; | ||||
|  | @ -72,6 +120,7 @@ void iwasm_main(void *arg1, void *arg2, void *arg3) | |||
|     (void) arg2; | ||||
|     (void) arg3; | ||||
| 
 | ||||
| 
 | ||||
|     memset(&init_args, 0, sizeof(RuntimeInitArgs)); | ||||
| 
 | ||||
|     init_args.mem_alloc_type = Alloc_With_Pool; | ||||
|  | @ -84,6 +133,16 @@ void iwasm_main(void *arg1, void *arg2, void *arg3) | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
| #ifdef CONFIG_BOARD_ESP32 | ||||
|     /* Initialize executable memory */ | ||||
|     if (esp32_exec_mem_init() != 0) { | ||||
|         printf("Init executable memory failed.\n"); | ||||
|         goto fail1; | ||||
|     } | ||||
|     /* Set hook functions for executable memory management */ | ||||
|     set_exec_mem_alloc_func(esp32_exec_mem_alloc, esp32_exec_mem_free); | ||||
| #endif | ||||
| 
 | ||||
| #if WASM_ENABLE_LOG != 0 | ||||
|     bh_log_set_verbose_level(log_verbose_level); | ||||
| #endif | ||||
|  | @ -96,7 +155,11 @@ void iwasm_main(void *arg1, void *arg2, void *arg3) | |||
|     if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, | ||||
|                                           error_buf, sizeof(error_buf)))) { | ||||
|         printf("%s\n", error_buf); | ||||
| #ifdef CONFIG_BOARD_ESP32 | ||||
|         goto fail1_1; | ||||
| #else | ||||
|         goto fail1; | ||||
| #endif | ||||
|     } | ||||
| 
 | ||||
|     /* instantiate the module */ | ||||
|  | @ -119,6 +182,12 @@ fail2: | |||
|     /* unload the module */ | ||||
|     wasm_runtime_unload(wasm_module); | ||||
| 
 | ||||
| #ifdef CONFIG_BOARD_ESP32 | ||||
| fail1_1: | ||||
|     /* destroy executable memory */ | ||||
|     esp32_exec_mem_destroy(); | ||||
| #endif | ||||
| 
 | ||||
| fail1: | ||||
|     /* destroy runtime environment */ | ||||
|     wasm_runtime_destroy(); | ||||
|  |  | |||
							
								
								
									
										44
									
								
								wamr-compiler/build_llvm_xtensa.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										44
									
								
								wamr-compiler/build_llvm_xtensa.sh
									
									
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| #!/bin/sh | ||||
| 
 | ||||
| # Copyright (C) 2019 Intel Corporation. All rights reserved. | ||||
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||
| 
 | ||||
| DEPS_DIR=${PWD}/../core/deps | ||||
| 
 | ||||
| cd ${DEPS_DIR} | ||||
| if [ ! -d "llvm" ]; then | ||||
|   echo "Clone llvm Xtensa to core/deps/ .." | ||||
|   git clone https://github.com/espressif/llvm-project.git llvm | ||||
| fi | ||||
| 
 | ||||
| cd llvm | ||||
| mkdir -p build | ||||
| cd build | ||||
| 
 | ||||
| if [ ! -f bin/llvm-lto ]; then | ||||
| 
 | ||||
|   CORE_NUM=$(nproc --all) | ||||
|   if [ -z "${CORE_NUM}" ]; then | ||||
|     CORE_NUM=1 | ||||
|   fi | ||||
| 
 | ||||
|   echo "Build llvm with" ${CORE_NUM} "cores" | ||||
| 
 | ||||
|   cmake ../llvm \ | ||||
|           -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ | ||||
|           -DCMAKE_BUILD_TYPE:STRING="Release" \ | ||||
|           -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD:STRING="Xtensa" \ | ||||
|           -DLLVM_BUILD_LLVM_DYLIB:BOOL=OFF \ | ||||
|           -DLLVM_OPTIMIZED_TABLEGEN:BOOL=ON \ | ||||
|           -DLLVM_INCLUDE_EXAMPLES:BOOL=OFF \ | ||||
|           -DLLVM_INCLUDE_TESTS:BOOL=OFF \ | ||||
|           -DLLVM_INCLUDE_BENCHMARKS:BOOL=OFF \ | ||||
|           -DLLVM_APPEND_VC_REV:BOOL=OFF | ||||
|   make -j ${CORE_NUM} | ||||
| 
 | ||||
| else | ||||
|   echo "llvm has already been built" | ||||
| fi | ||||
| 
 | ||||
| cd ${PWD} | ||||
| 
 | ||||
|  | @ -14,7 +14,7 @@ print_help() | |||
| { | ||||
|   printf("Usage: wamrc [options] -o output_file wasm_file\n"); | ||||
|   printf("  --target=<arch-name>      Set the target arch, which has the general format: <arch><sub>\n"); | ||||
|   printf("                            <arch> = x86_64, i386, aarch64, arm, thumb, mips.\n"); | ||||
|   printf("                            <arch> = x86_64, i386, aarch64, arm, thumb, xtensa, mips.\n"); | ||||
|   printf("                              Default is host arch, e.g. x86_64\n"); | ||||
|   printf("                            <sub> = for ex. on arm or thumb: v5, v6m, v7a, v7m, etc.\n"); | ||||
|   printf("                            Use --target=help to list supported targets\n"); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Weining
						Weining