aot_emit_aot_file.c 91 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "aot_compiler.h"
  6. #include "../aot/aot_runtime.h"
  7. #define PUT_U64_TO_ADDR(addr, value) \
  8. do { \
  9. union { \
  10. uint64 val; \
  11. uint32 parts[2]; \
  12. } u; \
  13. u.val = (value); \
  14. ((uint32 *)(addr))[0] = u.parts[0]; \
  15. ((uint32 *)(addr))[1] = u.parts[1]; \
  16. } while (0)
  17. #define CHECK_SIZE(size) \
  18. do { \
  19. if (size == (uint32)-1) { \
  20. aot_set_last_error("get symbol size failed."); \
  21. return (uint32)-1; \
  22. } \
  23. } while (0)
  24. static bool
  25. check_utf8_str(const uint8 *str, uint32 len)
  26. {
  27. /* The valid ranges are taken from page 125, below link
  28. https://www.unicode.org/versions/Unicode9.0.0/ch03.pdf */
  29. const uint8 *p = str, *p_end = str + len;
  30. uint8 chr;
  31. while (p < p_end) {
  32. chr = *p;
  33. if (chr < 0x80) {
  34. p++;
  35. }
  36. else if (chr >= 0xC2 && chr <= 0xDF && p + 1 < p_end) {
  37. if (p[1] < 0x80 || p[1] > 0xBF) {
  38. return false;
  39. }
  40. p += 2;
  41. }
  42. else if (chr >= 0xE0 && chr <= 0xEF && p + 2 < p_end) {
  43. if (chr == 0xE0) {
  44. if (p[1] < 0xA0 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF) {
  45. return false;
  46. }
  47. }
  48. else if (chr == 0xED) {
  49. if (p[1] < 0x80 || p[1] > 0x9F || p[2] < 0x80 || p[2] > 0xBF) {
  50. return false;
  51. }
  52. }
  53. else if (chr >= 0xE1 && chr <= 0xEF) {
  54. if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF) {
  55. return false;
  56. }
  57. }
  58. p += 3;
  59. }
  60. else if (chr >= 0xF0 && chr <= 0xF4 && p + 3 < p_end) {
  61. if (chr == 0xF0) {
  62. if (p[1] < 0x90 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF
  63. || p[3] < 0x80 || p[3] > 0xBF) {
  64. return false;
  65. }
  66. }
  67. else if (chr >= 0xF1 && chr <= 0xF3) {
  68. if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF
  69. || p[3] < 0x80 || p[3] > 0xBF) {
  70. return false;
  71. }
  72. }
  73. else if (chr == 0xF4) {
  74. if (p[1] < 0x80 || p[1] > 0x8F || p[2] < 0x80 || p[2] > 0xBF
  75. || p[3] < 0x80 || p[3] > 0xBF) {
  76. return false;
  77. }
  78. }
  79. p += 4;
  80. }
  81. else {
  82. return false;
  83. }
  84. }
  85. return (p == p_end);
  86. }
  87. /* Internal function in object file */
  88. typedef struct AOTObjectFunc {
  89. char *func_name;
  90. uint64 text_offset;
  91. } AOTObjectFunc;
  92. /* Symbol table list node */
  93. typedef struct AOTSymbolNode {
  94. struct AOTSymbolNode *next;
  95. uint32 str_len;
  96. char *symbol;
  97. } AOTSymbolNode;
  98. typedef struct AOTSymbolList {
  99. AOTSymbolNode *head;
  100. AOTSymbolNode *end;
  101. uint32 len;
  102. } AOTSymbolList;
  103. /* AOT object data */
  104. typedef struct AOTObjectData {
  105. LLVMMemoryBufferRef mem_buf;
  106. LLVMBinaryRef binary;
  107. AOTTargetInfo target_info;
  108. void *text;
  109. uint32 text_size;
  110. /* literal data and size */
  111. void *literal;
  112. uint32 literal_size;
  113. AOTObjectDataSection *data_sections;
  114. uint32 data_sections_count;
  115. AOTObjectFunc *funcs;
  116. uint32 func_count;
  117. AOTSymbolList symbol_list;
  118. AOTRelocationGroup *relocation_groups;
  119. uint32 relocation_group_count;
  120. } AOTObjectData;
  121. #if 0
  122. static void dump_buf(uint8 *buf, uint32 size, char *title)
  123. {
  124. int i;
  125. printf("------ %s -------", title);
  126. for (i = 0; i < size; i++) {
  127. if ((i % 16) == 0)
  128. printf("\n");
  129. printf("%02x ", (unsigned char)buf[i]);
  130. }
  131. printf("\n\n");
  132. }
  133. #endif
  134. static bool
  135. is_32bit_binary(const AOTObjectData *obj_data)
  136. {
  137. /* bit 1: 0 is 32-bit, 1 is 64-bit */
  138. return obj_data->target_info.bin_type & 2 ? false : true;
  139. }
  140. static bool
  141. is_little_endian_binary(const AOTObjectData *obj_data)
  142. {
  143. /* bit 0: 0 is little-endian, 1 is big-endian */
  144. return obj_data->target_info.bin_type & 1 ? false : true;
  145. }
  146. static bool
  147. str_starts_with(const char *str, const char *prefix)
  148. {
  149. size_t len_pre = strlen(prefix), len_str = strlen(str);
  150. return (len_str >= len_pre) && !memcmp(str, prefix, len_pre);
  151. }
  152. static uint32
  153. get_file_header_size()
  154. {
  155. /* magic number (4 bytes) + version (4 bytes) */
  156. return sizeof(uint32) + sizeof(uint32);
  157. }
  158. static uint32
  159. get_string_size(AOTCompContext *comp_ctx, const char *s)
  160. {
  161. /* string size (2 bytes) + string content */
  162. return (uint32)sizeof(uint16) + (uint32)strlen(s) +
  163. /* emit string with '\0' only in XIP mode */
  164. (comp_ctx->is_indirect_mode ? 1 : 0);
  165. }
  166. static uint32
  167. get_target_info_section_size()
  168. {
  169. return sizeof(AOTTargetInfo);
  170. }
  171. static uint32
  172. get_mem_init_data_size(AOTMemInitData *mem_init_data)
  173. {
  174. /* init expr type (4 bytes) + init expr value (8 bytes)
  175. + byte count (4 bytes) + bytes */
  176. uint32 total_size = (uint32)(sizeof(uint32) + sizeof(uint64)
  177. + sizeof(uint32) + mem_init_data->byte_count);
  178. /* bulk_memory enabled:
  179. is_passive (4 bytes) + memory_index (4 bytes)
  180. bulk memory disabled:
  181. placeholder (4 bytes) + placeholder (4 bytes)
  182. */
  183. total_size += (sizeof(uint32) + sizeof(uint32));
  184. return total_size;
  185. }
  186. static uint32
  187. get_mem_init_data_list_size(AOTMemInitData **mem_init_data_list,
  188. uint32 mem_init_data_count)
  189. {
  190. AOTMemInitData **mem_init_data = mem_init_data_list;
  191. uint32 size = 0, i;
  192. for (i = 0; i < mem_init_data_count; i++, mem_init_data++) {
  193. size = align_uint(size, 4);
  194. size += get_mem_init_data_size(*mem_init_data);
  195. }
  196. return size;
  197. }
  198. static uint32
  199. get_import_memory_size(AOTCompData *comp_data)
  200. {
  201. /* currently we only emit import_memory_count = 0 */
  202. return sizeof(uint32);
  203. }
  204. static uint32
  205. get_memory_size(AOTCompData *comp_data)
  206. {
  207. /* memory_count + count * (memory_flags + num_bytes_per_page +
  208. init_page_count + max_page_count) */
  209. return (uint32)(sizeof(uint32)
  210. + comp_data->memory_count * sizeof(uint32) * 4);
  211. }
  212. static uint32
  213. get_mem_info_size(AOTCompData *comp_data)
  214. {
  215. /* import_memory_size + memory_size
  216. + init_data_count + init_data_list */
  217. return get_import_memory_size(comp_data) + get_memory_size(comp_data)
  218. + (uint32)sizeof(uint32)
  219. + get_mem_init_data_list_size(comp_data->mem_init_data_list,
  220. comp_data->mem_init_data_count);
  221. }
  222. static uint32
  223. get_table_init_data_size(AOTTableInitData *table_init_data)
  224. {
  225. /*
  226. * mode (4 bytes), elem_type (4 bytes), do not need is_dropped field
  227. *
  228. * table_index(4 bytes) + init expr type (4 bytes) + init expr value (8
  229. * bytes)
  230. * + func index count (4 bytes) + func indexes
  231. */
  232. return (uint32)(sizeof(uint32) * 2 + sizeof(uint32) + sizeof(uint32)
  233. + sizeof(uint64) + sizeof(uint32)
  234. + sizeof(uint32) * table_init_data->func_index_count);
  235. }
  236. static uint32
  237. get_table_init_data_list_size(AOTTableInitData **table_init_data_list,
  238. uint32 table_init_data_count)
  239. {
  240. /*
  241. * ------------------------------
  242. * | table_init_data_count
  243. * ------------------------------
  244. * | | U32 mode
  245. * | AOTTableInitData[N] | U32 elem_type
  246. * | | U32 table_index
  247. * | | U32 offset.init_expr_type
  248. * | | U64 offset.u.i64
  249. * | | U32 func_index_count
  250. * | | U32[func_index_count]
  251. * ------------------------------
  252. */
  253. AOTTableInitData **table_init_data = table_init_data_list;
  254. uint32 size = 0, i;
  255. size = (uint32)sizeof(uint32);
  256. for (i = 0; i < table_init_data_count; i++, table_init_data++) {
  257. size = align_uint(size, 4);
  258. size += get_table_init_data_size(*table_init_data);
  259. }
  260. return size;
  261. }
  262. static uint32
  263. get_import_table_size(AOTCompData *comp_data)
  264. {
  265. /*
  266. * ------------------------------
  267. * | import_table_count
  268. * ------------------------------
  269. * | | U32 table_init_size
  270. * | | ----------------------
  271. * | AOTImpotTable[N] | U32 table_init_size
  272. * | | ----------------------
  273. * | | U32 possible_grow (convenient than U8)
  274. * ------------------------------
  275. */
  276. return (uint32)(sizeof(uint32)
  277. + comp_data->import_table_count * (sizeof(uint32) * 3));
  278. }
  279. static uint32
  280. get_table_size(AOTCompData *comp_data)
  281. {
  282. /*
  283. * ------------------------------
  284. * | table_count
  285. * ------------------------------
  286. * | | U32 elem_type
  287. * | AOTTable[N] | U32 table_flags
  288. * | | U32 table_init_size
  289. * | | U32 table_max_size
  290. * | | U32 possible_grow (convenient than U8)
  291. * ------------------------------
  292. */
  293. return (uint32)(sizeof(uint32)
  294. + comp_data->table_count * (sizeof(uint32) * 5));
  295. }
  296. static uint32
  297. get_table_info_size(AOTCompData *comp_data)
  298. {
  299. /*
  300. * ------------------------------
  301. * | import_table_count
  302. * ------------------------------
  303. * |
  304. * | AOTImportTable[import_table_count]
  305. * |
  306. * ------------------------------
  307. * | table_count
  308. * ------------------------------
  309. * |
  310. * | AOTTable[table_count]
  311. * |
  312. * ------------------------------
  313. * | table_init_data_count
  314. * ------------------------------
  315. * |
  316. * | AOTTableInitData*[table_init_data_count]
  317. * |
  318. * ------------------------------
  319. */
  320. return get_import_table_size(comp_data) + get_table_size(comp_data)
  321. + get_table_init_data_list_size(comp_data->table_init_data_list,
  322. comp_data->table_init_data_count);
  323. }
  324. static uint32
  325. get_func_type_size(AOTFuncType *func_type)
  326. {
  327. /* param count + result count + types */
  328. return (uint32)sizeof(uint32) * 2 + func_type->param_count
  329. + func_type->result_count;
  330. }
  331. static uint32
  332. get_func_types_size(AOTFuncType **func_types, uint32 func_type_count)
  333. {
  334. AOTFuncType **func_type = func_types;
  335. uint32 size = 0, i;
  336. for (i = 0; i < func_type_count; i++, func_type++) {
  337. size = align_uint(size, 4);
  338. size += get_func_type_size(*func_type);
  339. }
  340. return size;
  341. }
  342. static uint32
  343. get_func_type_info_size(AOTCompData *comp_data)
  344. {
  345. /* func type count + func type list */
  346. return (uint32)sizeof(uint32)
  347. + get_func_types_size(comp_data->func_types,
  348. comp_data->func_type_count);
  349. }
  350. static uint32
  351. get_import_global_size(AOTCompContext *comp_ctx, AOTImportGlobal *import_global)
  352. {
  353. /* type (1 byte) + is_mutable (1 byte) + module_name + global_name */
  354. uint32 size = (uint32)sizeof(uint8) * 2
  355. + get_string_size(comp_ctx, import_global->module_name);
  356. size = align_uint(size, 2);
  357. size += get_string_size(comp_ctx, import_global->global_name);
  358. return size;
  359. }
  360. static uint32
  361. get_import_globals_size(AOTCompContext *comp_ctx,
  362. AOTImportGlobal *import_globals,
  363. uint32 import_global_count)
  364. {
  365. AOTImportGlobal *import_global = import_globals;
  366. uint32 size = 0, i;
  367. for (i = 0; i < import_global_count; i++, import_global++) {
  368. size = align_uint(size, 2);
  369. size += get_import_global_size(comp_ctx, import_global);
  370. }
  371. return size;
  372. }
  373. static uint32
  374. get_import_global_info_size(AOTCompContext *comp_ctx, AOTCompData *comp_data)
  375. {
  376. /* import global count + import globals */
  377. return (uint32)sizeof(uint32)
  378. + get_import_globals_size(comp_ctx, comp_data->import_globals,
  379. comp_data->import_global_count);
  380. }
  381. static uint32
  382. get_global_size(AOTGlobal *global)
  383. {
  384. if (global->init_expr.init_expr_type != INIT_EXPR_TYPE_V128_CONST)
  385. /* type (1 byte) + is_mutable (1 byte)
  386. + init expr type (2 byes) + init expr value (8 byes) */
  387. return sizeof(uint8) * 2 + sizeof(uint16) + sizeof(uint64);
  388. else
  389. /* type (1 byte) + is_mutable (1 byte)
  390. + init expr type (2 byes) + v128 value (16 byes) */
  391. return sizeof(uint8) * 2 + sizeof(uint16) + sizeof(uint64) * 2;
  392. }
  393. static uint32
  394. get_globals_size(AOTGlobal *globals, uint32 global_count)
  395. {
  396. AOTGlobal *global = globals;
  397. uint32 size = 0, i;
  398. for (i = 0; i < global_count; i++, global++) {
  399. size = align_uint(size, 4);
  400. size += get_global_size(global);
  401. }
  402. return size;
  403. }
  404. static uint32
  405. get_global_info_size(AOTCompData *comp_data)
  406. {
  407. /* global count + globals */
  408. return (uint32)sizeof(uint32)
  409. + get_globals_size(comp_data->globals, comp_data->global_count);
  410. }
  411. static uint32
  412. get_import_func_size(AOTCompContext *comp_ctx, AOTImportFunc *import_func)
  413. {
  414. /* type index (2 bytes) + module_name + func_name */
  415. uint32 size = (uint32)sizeof(uint16)
  416. + get_string_size(comp_ctx, import_func->module_name);
  417. size = align_uint(size, 2);
  418. size += get_string_size(comp_ctx, import_func->func_name);
  419. return size;
  420. }
  421. static uint32
  422. get_import_funcs_size(AOTCompContext *comp_ctx, AOTImportFunc *import_funcs,
  423. uint32 import_func_count)
  424. {
  425. AOTImportFunc *import_func = import_funcs;
  426. uint32 size = 0, i;
  427. for (i = 0; i < import_func_count; i++, import_func++) {
  428. size = align_uint(size, 2);
  429. size += get_import_func_size(comp_ctx, import_func);
  430. }
  431. return size;
  432. }
  433. static uint32
  434. get_import_func_info_size(AOTCompContext *comp_ctx, AOTCompData *comp_data)
  435. {
  436. /* import func count + import funcs */
  437. return (uint32)sizeof(uint32)
  438. + get_import_funcs_size(comp_ctx, comp_data->import_funcs,
  439. comp_data->import_func_count);
  440. }
  441. static uint32
  442. get_object_data_sections_size(AOTCompContext *comp_ctx,
  443. AOTObjectDataSection *data_sections,
  444. uint32 data_sections_count)
  445. {
  446. AOTObjectDataSection *data_section = data_sections;
  447. uint32 size = 0, i;
  448. for (i = 0; i < data_sections_count; i++, data_section++) {
  449. /* name + size + data */
  450. size = align_uint(size, 2);
  451. size += get_string_size(comp_ctx, data_section->name);
  452. size = align_uint(size, 4);
  453. size += (uint32)sizeof(uint32);
  454. size += data_section->size;
  455. }
  456. return size;
  457. }
  458. static uint32
  459. get_object_data_section_info_size(AOTCompContext *comp_ctx,
  460. AOTObjectData *obj_data)
  461. {
  462. /* data sections count + data sections */
  463. return (uint32)sizeof(uint32)
  464. + get_object_data_sections_size(comp_ctx, obj_data->data_sections,
  465. obj_data->data_sections_count);
  466. }
  467. static uint32
  468. get_init_data_section_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
  469. AOTObjectData *obj_data)
  470. {
  471. uint32 size = 0;
  472. size += get_mem_info_size(comp_data);
  473. size = align_uint(size, 4);
  474. size += get_table_info_size(comp_data);
  475. size = align_uint(size, 4);
  476. size += get_func_type_info_size(comp_data);
  477. size = align_uint(size, 4);
  478. size += get_import_global_info_size(comp_ctx, comp_data);
  479. size = align_uint(size, 4);
  480. size += get_global_info_size(comp_data);
  481. size = align_uint(size, 4);
  482. size += get_import_func_info_size(comp_ctx, comp_data);
  483. /* func count + start func index */
  484. size = align_uint(size, 4);
  485. size += (uint32)sizeof(uint32) * 2;
  486. /* aux data/heap/stack data */
  487. size += sizeof(uint32) * 7;
  488. size += get_object_data_section_info_size(comp_ctx, obj_data);
  489. return size;
  490. }
  491. static uint32
  492. get_text_section_size(AOTObjectData *obj_data)
  493. {
  494. return (sizeof(uint32) + obj_data->literal_size + obj_data->text_size + 3)
  495. & ~3;
  496. }
  497. static uint32
  498. get_func_section_size(AOTCompData *comp_data, AOTObjectData *obj_data)
  499. {
  500. /* text offsets + function type indexs */
  501. uint32 size = 0;
  502. if (is_32bit_binary(obj_data))
  503. size = (uint32)sizeof(uint32) * comp_data->func_count;
  504. else
  505. size = (uint32)sizeof(uint64) * comp_data->func_count;
  506. size += (uint32)sizeof(uint32) * comp_data->func_count;
  507. return size;
  508. }
  509. static uint32
  510. get_export_size(AOTCompContext *comp_ctx, AOTExport *export)
  511. {
  512. /* export index + export kind + 1 byte padding + export name */
  513. return (uint32)sizeof(uint32) + sizeof(uint8) + 1
  514. + get_string_size(comp_ctx, export->name);
  515. }
  516. static uint32
  517. get_exports_size(AOTCompContext *comp_ctx, AOTExport *exports,
  518. uint32 export_count)
  519. {
  520. AOTExport *export = exports;
  521. uint32 size = 0, i;
  522. for (i = 0; i < export_count; i++, export ++) {
  523. size = align_uint(size, 4);
  524. size += get_export_size(comp_ctx, export);
  525. }
  526. return size;
  527. }
  528. static uint32
  529. get_export_section_size(AOTCompContext *comp_ctx, AOTCompData *comp_data)
  530. {
  531. /* export count + exports */
  532. return (uint32)sizeof(uint32)
  533. + get_exports_size(comp_ctx, comp_data->wasm_module->exports,
  534. comp_data->wasm_module->export_count);
  535. }
  536. static uint32
  537. get_relocation_size(AOTRelocation *relocation, bool is_32bin)
  538. {
  539. /* offset + addend + relocation type + symbol name */
  540. uint32 size = 0;
  541. if (is_32bin)
  542. size = sizeof(uint32) * 2; /* offset and addend */
  543. else
  544. size = sizeof(uint64) * 2; /* offset and addend */
  545. size += (uint32)sizeof(uint32); /* relocation type */
  546. size += (uint32)sizeof(uint32); /* symbol name index */
  547. return size;
  548. }
  549. static uint32
  550. get_relocations_size(AOTRelocation *relocations, uint32 relocation_count,
  551. bool is_32bin)
  552. {
  553. AOTRelocation *relocation = relocations;
  554. uint32 size = 0, i;
  555. for (i = 0; i < relocation_count; i++, relocation++) {
  556. size = align_uint(size, 4);
  557. size += get_relocation_size(relocation, is_32bin);
  558. }
  559. return size;
  560. }
  561. static uint32
  562. get_relocation_group_size(AOTRelocationGroup *relocation_group, bool is_32bin)
  563. {
  564. uint32 size = 0;
  565. /* section name index + relocation count + relocations */
  566. size += (uint32)sizeof(uint32);
  567. size += (uint32)sizeof(uint32);
  568. size += get_relocations_size(relocation_group->relocations,
  569. relocation_group->relocation_count, is_32bin);
  570. return size;
  571. }
  572. static uint32
  573. get_relocation_groups_size(AOTRelocationGroup *relocation_groups,
  574. uint32 relocation_group_count, bool is_32bin)
  575. {
  576. AOTRelocationGroup *relocation_group = relocation_groups;
  577. uint32 size = 0, i;
  578. for (i = 0; i < relocation_group_count; i++, relocation_group++) {
  579. size = align_uint(size, 4);
  580. size += get_relocation_group_size(relocation_group, is_32bin);
  581. }
  582. return size;
  583. }
  584. /* return the index (in order of insertion) of the symbol,
  585. create if not exits, -1 if failed */
  586. static uint32
  587. get_relocation_symbol_index(const char *symbol_name, bool *is_new,
  588. AOTSymbolList *symbol_list)
  589. {
  590. AOTSymbolNode *sym;
  591. uint32 index = 0;
  592. sym = symbol_list->head;
  593. while (sym) {
  594. if (!strcmp(sym->symbol, symbol_name)) {
  595. if (is_new)
  596. *is_new = false;
  597. return index;
  598. }
  599. sym = sym->next;
  600. index++;
  601. }
  602. /* Not found in symbol_list, add it */
  603. sym = wasm_runtime_malloc(sizeof(AOTSymbolNode));
  604. if (!sym) {
  605. return (uint32)-1;
  606. }
  607. memset(sym, 0, sizeof(AOTSymbolNode));
  608. sym->symbol = (char *)symbol_name;
  609. sym->str_len = (uint32)strlen(symbol_name);
  610. if (!symbol_list->head) {
  611. symbol_list->head = symbol_list->end = sym;
  612. }
  613. else {
  614. symbol_list->end->next = sym;
  615. symbol_list->end = sym;
  616. }
  617. symbol_list->len++;
  618. if (is_new)
  619. *is_new = true;
  620. return index;
  621. }
  622. static uint32
  623. get_relocation_symbol_size(AOTCompContext *comp_ctx, AOTRelocation *relocation,
  624. AOTSymbolList *symbol_list)
  625. {
  626. uint32 size = 0, index = 0;
  627. bool is_new = false;
  628. index = get_relocation_symbol_index(relocation->symbol_name, &is_new,
  629. symbol_list);
  630. CHECK_SIZE(index);
  631. if (is_new) {
  632. size += get_string_size(comp_ctx, relocation->symbol_name);
  633. size = align_uint(size, 2);
  634. }
  635. relocation->symbol_index = index;
  636. return size;
  637. }
  638. static uint32
  639. get_relocations_symbol_size(AOTCompContext *comp_ctx,
  640. AOTRelocation *relocations, uint32 relocation_count,
  641. AOTSymbolList *symbol_list)
  642. {
  643. AOTRelocation *relocation = relocations;
  644. uint32 size = 0, curr_size, i;
  645. for (i = 0; i < relocation_count; i++, relocation++) {
  646. curr_size =
  647. get_relocation_symbol_size(comp_ctx, relocation, symbol_list);
  648. CHECK_SIZE(curr_size);
  649. size += curr_size;
  650. }
  651. return size;
  652. }
  653. static uint32
  654. get_relocation_group_symbol_size(AOTCompContext *comp_ctx,
  655. AOTRelocationGroup *relocation_group,
  656. AOTSymbolList *symbol_list)
  657. {
  658. uint32 size = 0, index = 0, curr_size;
  659. bool is_new = false;
  660. index = get_relocation_symbol_index(relocation_group->section_name, &is_new,
  661. symbol_list);
  662. CHECK_SIZE(index);
  663. if (is_new) {
  664. size += get_string_size(comp_ctx, relocation_group->section_name);
  665. size = align_uint(size, 2);
  666. }
  667. relocation_group->name_index = index;
  668. curr_size = get_relocations_symbol_size(
  669. comp_ctx, relocation_group->relocations,
  670. relocation_group->relocation_count, symbol_list);
  671. CHECK_SIZE(curr_size);
  672. size += curr_size;
  673. return size;
  674. }
  675. static uint32
  676. get_relocation_groups_symbol_size(AOTCompContext *comp_ctx,
  677. AOTRelocationGroup *relocation_groups,
  678. uint32 relocation_group_count,
  679. AOTSymbolList *symbol_list)
  680. {
  681. AOTRelocationGroup *relocation_group = relocation_groups;
  682. uint32 size = 0, curr_size, i;
  683. for (i = 0; i < relocation_group_count; i++, relocation_group++) {
  684. curr_size = get_relocation_group_symbol_size(comp_ctx, relocation_group,
  685. symbol_list);
  686. CHECK_SIZE(curr_size);
  687. size += curr_size;
  688. }
  689. return size;
  690. }
  691. static uint32
  692. get_symbol_size_from_symbol_list(AOTCompContext *comp_ctx,
  693. AOTSymbolList *symbol_list)
  694. {
  695. AOTSymbolNode *sym;
  696. uint32 size = 0;
  697. sym = symbol_list->head;
  698. while (sym) {
  699. /* (uint16)str_len + str */
  700. size += get_string_size(comp_ctx, sym->symbol);
  701. size = align_uint(size, 2);
  702. sym = sym->next;
  703. }
  704. return size;
  705. }
  706. static uint32
  707. get_relocation_section_symbol_size(AOTCompContext *comp_ctx,
  708. AOTObjectData *obj_data)
  709. {
  710. AOTRelocationGroup *relocation_groups = obj_data->relocation_groups;
  711. uint32 relocation_group_count = obj_data->relocation_group_count;
  712. uint32 string_count = 0, symbol_table_size = 0;
  713. /* section size will be calculated twice,
  714. get symbol size from symbol list directly in the second calculation */
  715. if (obj_data->symbol_list.len > 0) {
  716. symbol_table_size =
  717. get_symbol_size_from_symbol_list(comp_ctx, &obj_data->symbol_list);
  718. }
  719. else {
  720. symbol_table_size = get_relocation_groups_symbol_size(
  721. comp_ctx, relocation_groups, relocation_group_count,
  722. &obj_data->symbol_list);
  723. }
  724. CHECK_SIZE(symbol_table_size);
  725. string_count = obj_data->symbol_list.len;
  726. /* string_count + string_offsets + total_string_len
  727. + [str (string_len + str)] */
  728. return (uint32)(sizeof(uint32) + sizeof(uint32) * string_count
  729. + sizeof(uint32) + symbol_table_size);
  730. }
  731. static uint32
  732. get_relocation_section_size(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
  733. {
  734. AOTRelocationGroup *relocation_groups = obj_data->relocation_groups;
  735. uint32 relocation_group_count = obj_data->relocation_group_count;
  736. uint32 symbol_table_size = 0;
  737. symbol_table_size = get_relocation_section_symbol_size(comp_ctx, obj_data);
  738. CHECK_SIZE(symbol_table_size);
  739. symbol_table_size = align_uint(symbol_table_size, 4);
  740. /* relocation group count + symbol_table + relocation groups */
  741. return (uint32)sizeof(uint32) + symbol_table_size
  742. + get_relocation_groups_size(relocation_groups,
  743. relocation_group_count,
  744. is_32bit_binary(obj_data));
  745. }
  746. static uint32
  747. get_native_symbol_list_size(AOTCompContext *comp_ctx)
  748. {
  749. uint32 len = 0;
  750. AOTNativeSymbol *sym = NULL;
  751. sym = bh_list_first_elem(&comp_ctx->native_symbols);
  752. while (sym) {
  753. len = align_uint(len, 2);
  754. len += get_string_size(comp_ctx, sym->symbol);
  755. sym = bh_list_elem_next(sym);
  756. }
  757. return len;
  758. }
  759. static uint32
  760. get_name_section_size(AOTCompData *comp_data);
  761. static uint32
  762. get_custom_sections_size(AOTCompContext *comp_ctx, AOTCompData *comp_data);
  763. static uint32
  764. get_aot_file_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
  765. AOTObjectData *obj_data)
  766. {
  767. uint32 size = 0;
  768. uint32 size_custom_section = 0;
  769. /* aot file header */
  770. size += get_file_header_size();
  771. /* target info section */
  772. size = align_uint(size, 4);
  773. /* section id + section size */
  774. size += (uint32)sizeof(uint32) * 2;
  775. size += get_target_info_section_size();
  776. /* init data section */
  777. size = align_uint(size, 4);
  778. /* section id + section size */
  779. size += (uint32)sizeof(uint32) * 2;
  780. size += get_init_data_section_size(comp_ctx, comp_data, obj_data);
  781. /* text section */
  782. size = align_uint(size, 4);
  783. /* section id + section size */
  784. size += (uint32)sizeof(uint32) * 2;
  785. size += get_text_section_size(obj_data);
  786. /* function section */
  787. size = align_uint(size, 4);
  788. /* section id + section size */
  789. size += (uint32)sizeof(uint32) * 2;
  790. size += get_func_section_size(comp_data, obj_data);
  791. /* export section */
  792. size = align_uint(size, 4);
  793. /* section id + section size */
  794. size += (uint32)sizeof(uint32) * 2;
  795. size += get_export_section_size(comp_ctx, comp_data);
  796. /* relocation section */
  797. size = align_uint(size, 4);
  798. /* section id + section size */
  799. size += (uint32)sizeof(uint32) * 2;
  800. size += get_relocation_section_size(comp_ctx, obj_data);
  801. if (get_native_symbol_list_size(comp_ctx) > 0) {
  802. /* emit only when there are native symbols */
  803. size = align_uint(size, 4);
  804. /* section id + section size + sub section id + symbol count */
  805. size += (uint32)sizeof(uint32) * 4;
  806. size += get_native_symbol_list_size(comp_ctx);
  807. }
  808. if (comp_ctx->enable_aux_stack_frame) {
  809. /* custom name section */
  810. size = align_uint(size, 4);
  811. /* section id + section size + sub section id */
  812. size += (uint32)sizeof(uint32) * 3;
  813. size += (comp_data->aot_name_section_size =
  814. get_name_section_size(comp_data));
  815. }
  816. size_custom_section = get_custom_sections_size(comp_ctx, comp_data);
  817. if (size_custom_section > 0) {
  818. size = align_uint(size, 4);
  819. size += size_custom_section;
  820. }
  821. return size;
  822. }
  823. #define exchange_uint8(p_data) (void)0
  824. static void
  825. exchange_uint16(uint8 *p_data)
  826. {
  827. uint8 value = *p_data;
  828. *p_data = *(p_data + 1);
  829. *(p_data + 1) = value;
  830. }
  831. static void
  832. exchange_uint32(uint8 *p_data)
  833. {
  834. uint8 value = *p_data;
  835. *p_data = *(p_data + 3);
  836. *(p_data + 3) = value;
  837. value = *(p_data + 1);
  838. *(p_data + 1) = *(p_data + 2);
  839. *(p_data + 2) = value;
  840. }
  841. static void
  842. exchange_uint64(uint8 *pData)
  843. {
  844. uint32 value;
  845. value = *(uint32 *)pData;
  846. *(uint32 *)pData = *(uint32 *)(pData + 4);
  847. *(uint32 *)(pData + 4) = value;
  848. exchange_uint32(pData);
  849. exchange_uint32(pData + 4);
  850. }
  851. static void
  852. exchange_uint128(uint8 *pData)
  853. {
  854. /* swap high 64bit and low 64bit */
  855. uint64 value = *(uint64 *)pData;
  856. *(uint64 *)pData = *(uint64 *)(pData + 8);
  857. *(uint64 *)(pData + 8) = value;
  858. /* exchange high 64bit */
  859. exchange_uint64(pData);
  860. /* exchange low 64bit */
  861. exchange_uint64(pData + 8);
  862. }
  863. static union {
  864. int a;
  865. char b;
  866. } __ue = { .a = 1 };
  867. #define is_little_endian() (__ue.b == 1)
  868. #define CHECK_BUF(length) \
  869. do { \
  870. if (buf + offset + length > buf_end) { \
  871. aot_set_last_error("buf overflow"); \
  872. return false; \
  873. } \
  874. } while (0)
  875. #define EMIT_U8(v) \
  876. do { \
  877. CHECK_BUF(1); \
  878. *(uint8 *)(buf + offset) = (uint8)v; \
  879. offset++; \
  880. } while (0)
  881. #define EMIT_U16(v) \
  882. do { \
  883. uint16 t = (uint16)v; \
  884. CHECK_BUF(2); \
  885. if (!is_little_endian()) \
  886. exchange_uint16((uint8 *)&t); \
  887. *(uint16 *)(buf + offset) = t; \
  888. offset += (uint32)sizeof(uint16); \
  889. } while (0)
  890. #define EMIT_U32(v) \
  891. do { \
  892. uint32 t = (uint32)v; \
  893. CHECK_BUF(4); \
  894. if (!is_little_endian()) \
  895. exchange_uint32((uint8 *)&t); \
  896. *(uint32 *)(buf + offset) = t; \
  897. offset += (uint32)sizeof(uint32); \
  898. } while (0)
  899. #define EMIT_U64(v) \
  900. do { \
  901. uint64 t = (uint64)v; \
  902. CHECK_BUF(8); \
  903. if (!is_little_endian()) \
  904. exchange_uint64((uint8 *)&t); \
  905. PUT_U64_TO_ADDR(buf + offset, t); \
  906. offset += (uint32)sizeof(uint64); \
  907. } while (0)
  908. #define EMIT_V128(v) \
  909. do { \
  910. uint64 *t = (uint64 *)v.i64x2; \
  911. CHECK_BUF(16); \
  912. if (!is_little_endian()) \
  913. exchange_uint128((uint8 *)t); \
  914. PUT_U64_TO_ADDR(buf + offset, t[0]); \
  915. offset += (uint32)sizeof(uint64); \
  916. PUT_U64_TO_ADDR(buf + offset, t[1]); \
  917. offset += (uint32)sizeof(uint64); \
  918. } while (0)
  919. #define EMIT_BUF(v, len) \
  920. do { \
  921. CHECK_BUF(len); \
  922. memcpy(buf + offset, v, len); \
  923. offset += len; \
  924. } while (0)
  925. #define EMIT_STR(s) \
  926. do { \
  927. uint32 str_len = (uint32)strlen(s); \
  928. if (str_len > INT16_MAX) { \
  929. aot_set_last_error("emit string failed: " \
  930. "string too long"); \
  931. return false; \
  932. } \
  933. if (comp_ctx->is_indirect_mode) \
  934. /* emit '\0' only in XIP mode */ \
  935. str_len++; \
  936. EMIT_U16(str_len); \
  937. EMIT_BUF(s, str_len); \
  938. } while (0)
  939. static bool
  940. read_leb(uint8 **p_buf, const uint8 *buf_end, uint32 maxbits, bool sign,
  941. uint64 *p_result)
  942. {
  943. const uint8 *buf = *p_buf;
  944. uint64 result = 0;
  945. uint32 shift = 0;
  946. uint32 offset = 0, bcnt = 0;
  947. uint64 byte;
  948. while (true) {
  949. /* uN or SN must not exceed ceil(N/7) bytes */
  950. if (bcnt + 1 > (maxbits + 6) / 7) {
  951. aot_set_last_error("integer representation too long");
  952. return false;
  953. }
  954. if (buf + offset + 1 > buf_end) {
  955. aot_set_last_error("unexpected end of section or function");
  956. return false;
  957. }
  958. byte = buf[offset];
  959. offset += 1;
  960. result |= ((byte & 0x7f) << shift);
  961. shift += 7;
  962. bcnt += 1;
  963. if ((byte & 0x80) == 0) {
  964. break;
  965. }
  966. }
  967. if (!sign && maxbits == 32 && shift >= maxbits) {
  968. /* The top bits set represent values > 32 bits */
  969. if (((uint8)byte) & 0xf0)
  970. goto fail_integer_too_large;
  971. }
  972. else if (sign && maxbits == 32) {
  973. if (shift < maxbits) {
  974. /* Sign extend, second highest bit is the sign bit */
  975. if ((uint8)byte & 0x40)
  976. result |= (~((uint64)0)) << shift;
  977. }
  978. else {
  979. /* The top bits should be a sign-extension of the sign bit */
  980. bool sign_bit_set = ((uint8)byte) & 0x8;
  981. int top_bits = ((uint8)byte) & 0xf0;
  982. if ((sign_bit_set && top_bits != 0x70)
  983. || (!sign_bit_set && top_bits != 0))
  984. goto fail_integer_too_large;
  985. }
  986. }
  987. else if (sign && maxbits == 64) {
  988. if (shift < maxbits) {
  989. /* Sign extend, second highest bit is the sign bit */
  990. if ((uint8)byte & 0x40)
  991. result |= (~((uint64)0)) << shift;
  992. }
  993. else {
  994. /* The top bits should be a sign-extension of the sign bit */
  995. bool sign_bit_set = ((uint8)byte) & 0x1;
  996. int top_bits = ((uint8)byte) & 0xfe;
  997. if ((sign_bit_set && top_bits != 0x7e)
  998. || (!sign_bit_set && top_bits != 0))
  999. goto fail_integer_too_large;
  1000. }
  1001. }
  1002. *p_buf += offset;
  1003. *p_result = result;
  1004. return true;
  1005. fail_integer_too_large:
  1006. aot_set_last_error("integer too large");
  1007. return false;
  1008. }
  1009. #define read_leb_uint32(p, p_end, res) \
  1010. do { \
  1011. uint64 res64; \
  1012. if (!read_leb((uint8 **)&p, p_end, 32, false, &res64)) \
  1013. goto fail; \
  1014. res = (uint32)res64; \
  1015. } while (0)
  1016. static uint32
  1017. get_name_section_size(AOTCompData *comp_data)
  1018. {
  1019. const uint8 *p = comp_data->name_section_buf,
  1020. *p_end = comp_data->name_section_buf_end;
  1021. uint8 *buf, *buf_end;
  1022. uint32 name_type, subsection_size;
  1023. uint32 previous_name_type = 0;
  1024. uint32 num_func_name;
  1025. uint32 func_index;
  1026. uint32 previous_func_index = ~0U;
  1027. uint32 func_name_len;
  1028. uint32 name_index;
  1029. int i = 0;
  1030. uint32 name_len;
  1031. uint32 offset = 0;
  1032. uint32 max_aot_buf_size = 0;
  1033. if (p >= p_end) {
  1034. aot_set_last_error("unexpected end");
  1035. return 0;
  1036. }
  1037. max_aot_buf_size = 4 * (uint32)(p_end - p);
  1038. if (!(buf = comp_data->aot_name_section_buf =
  1039. wasm_runtime_malloc(max_aot_buf_size))) {
  1040. aot_set_last_error("allocate memory for custom name section failed.");
  1041. return 0;
  1042. }
  1043. buf_end = buf + max_aot_buf_size;
  1044. read_leb_uint32(p, p_end, name_len);
  1045. offset = align_uint(offset, 4);
  1046. EMIT_U32(name_len);
  1047. if (name_len == 0 || p + name_len > p_end) {
  1048. aot_set_last_error("unexpected end");
  1049. return 0;
  1050. }
  1051. if (!check_utf8_str(p, name_len)) {
  1052. aot_set_last_error("invalid UTF-8 encoding");
  1053. return 0;
  1054. }
  1055. if (memcmp(p, "name", 4) != 0) {
  1056. aot_set_last_error("invalid custom name section");
  1057. return 0;
  1058. }
  1059. EMIT_BUF(p, name_len);
  1060. p += name_len;
  1061. while (p < p_end) {
  1062. read_leb_uint32(p, p_end, name_type);
  1063. if (i != 0) {
  1064. if (name_type == previous_name_type) {
  1065. aot_set_last_error("duplicate sub-section");
  1066. return 0;
  1067. }
  1068. if (name_type < previous_name_type) {
  1069. aot_set_last_error("out-of-order sub-section");
  1070. return 0;
  1071. }
  1072. }
  1073. previous_name_type = name_type;
  1074. read_leb_uint32(p, p_end, subsection_size);
  1075. switch (name_type) {
  1076. case SUB_SECTION_TYPE_FUNC:
  1077. if (subsection_size) {
  1078. offset = align_uint(offset, 4);
  1079. EMIT_U32(name_type);
  1080. EMIT_U32(subsection_size);
  1081. read_leb_uint32(p, p_end, num_func_name);
  1082. EMIT_U32(num_func_name);
  1083. for (name_index = 0; name_index < num_func_name;
  1084. name_index++) {
  1085. read_leb_uint32(p, p_end, func_index);
  1086. offset = align_uint(offset, 4);
  1087. EMIT_U32(func_index);
  1088. if (func_index == previous_func_index) {
  1089. aot_set_last_error("duplicate function name");
  1090. return 0;
  1091. }
  1092. if (func_index < previous_func_index
  1093. && previous_func_index != ~0U) {
  1094. aot_set_last_error("out-of-order function index ");
  1095. return 0;
  1096. }
  1097. previous_func_index = func_index;
  1098. read_leb_uint32(p, p_end, func_name_len);
  1099. offset = align_uint(offset, 2);
  1100. EMIT_U16(func_name_len);
  1101. EMIT_BUF(p, func_name_len);
  1102. p += func_name_len;
  1103. }
  1104. }
  1105. break;
  1106. case SUB_SECTION_TYPE_MODULE: /* TODO: Parse for module subsection
  1107. */
  1108. case SUB_SECTION_TYPE_LOCAL: /* TODO: Parse for local subsection */
  1109. default:
  1110. p = p + subsection_size;
  1111. break;
  1112. }
  1113. i++;
  1114. }
  1115. return offset;
  1116. fail:
  1117. return 0;
  1118. }
  1119. static uint32
  1120. get_custom_sections_size(AOTCompContext *comp_ctx, AOTCompData *comp_data)
  1121. {
  1122. #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
  1123. uint32 size = 0, i;
  1124. for (i = 0; i < comp_ctx->custom_sections_count; i++) {
  1125. const char *section_name = comp_ctx->custom_sections_wp[i];
  1126. const uint8 *content = NULL;
  1127. uint32 length = 0;
  1128. content = wasm_loader_get_custom_section(comp_data->wasm_module,
  1129. section_name, &length);
  1130. if (!content) {
  1131. LOG_WARNING("Can't find custom section [%s], ignore it",
  1132. section_name);
  1133. continue;
  1134. }
  1135. size = align_uint(size, 4);
  1136. /* section id + section size + sub section id */
  1137. size += (uint32)sizeof(uint32) * 3;
  1138. /* section name and len */
  1139. size += get_string_size(comp_ctx, section_name);
  1140. /* section content */
  1141. size += length;
  1142. }
  1143. return size;
  1144. #else
  1145. return 0;
  1146. #endif
  1147. }
  1148. static bool
  1149. aot_emit_file_header(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1150. AOTCompData *comp_data, AOTObjectData *obj_data)
  1151. {
  1152. uint32 offset = *p_offset;
  1153. uint32 aot_curr_version = AOT_CURRENT_VERSION;
  1154. EMIT_U8('\0');
  1155. EMIT_U8('a');
  1156. EMIT_U8('o');
  1157. EMIT_U8('t');
  1158. EMIT_U32(aot_curr_version);
  1159. *p_offset = offset;
  1160. return true;
  1161. }
  1162. static bool
  1163. aot_emit_target_info_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1164. AOTCompData *comp_data, AOTObjectData *obj_data)
  1165. {
  1166. uint32 offset = *p_offset;
  1167. uint32 section_size = get_target_info_section_size();
  1168. AOTTargetInfo *target_info = &obj_data->target_info;
  1169. *p_offset = offset = align_uint(offset, 4);
  1170. EMIT_U32(AOT_SECTION_TYPE_TARGET_INFO);
  1171. EMIT_U32(section_size);
  1172. EMIT_U16(target_info->bin_type);
  1173. EMIT_U16(target_info->abi_type);
  1174. EMIT_U16(target_info->e_type);
  1175. EMIT_U16(target_info->e_machine);
  1176. EMIT_U32(target_info->e_version);
  1177. EMIT_U32(target_info->e_flags);
  1178. EMIT_U32(target_info->reserved);
  1179. EMIT_BUF(target_info->arch, sizeof(target_info->arch));
  1180. if (offset - *p_offset != section_size + sizeof(uint32) * 2) {
  1181. aot_set_last_error("emit target info failed.");
  1182. return false;
  1183. }
  1184. *p_offset = offset;
  1185. return true;
  1186. }
  1187. static bool
  1188. aot_emit_mem_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1189. AOTCompContext *comp_ctx, AOTCompData *comp_data,
  1190. AOTObjectData *obj_data)
  1191. {
  1192. uint32 offset = *p_offset, i;
  1193. AOTMemInitData **init_datas = comp_data->mem_init_data_list;
  1194. *p_offset = offset = align_uint(offset, 4);
  1195. /* Emit import memory count, only emit 0 currently.
  1196. TODO: emit the actual import memory count and
  1197. the full import memory info. */
  1198. EMIT_U32(0);
  1199. /* Emit memory count */
  1200. EMIT_U32(comp_data->memory_count);
  1201. /* Emit memory items */
  1202. for (i = 0; i < comp_data->memory_count; i++) {
  1203. EMIT_U32(comp_data->memories[i].memory_flags);
  1204. EMIT_U32(comp_data->memories[i].num_bytes_per_page);
  1205. EMIT_U32(comp_data->memories[i].mem_init_page_count);
  1206. EMIT_U32(comp_data->memories[i].mem_max_page_count);
  1207. }
  1208. /* Emit mem init data count */
  1209. EMIT_U32(comp_data->mem_init_data_count);
  1210. /* Emit mem init data items */
  1211. for (i = 0; i < comp_data->mem_init_data_count; i++) {
  1212. offset = align_uint(offset, 4);
  1213. #if WASM_ENABLE_BULK_MEMORY != 0
  1214. if (comp_ctx->enable_bulk_memory) {
  1215. EMIT_U32(init_datas[i]->is_passive);
  1216. EMIT_U32(init_datas[i]->memory_index);
  1217. }
  1218. else
  1219. #endif
  1220. {
  1221. /* emit two placeholder to keep the same size */
  1222. EMIT_U32(0);
  1223. EMIT_U32(0);
  1224. }
  1225. EMIT_U32(init_datas[i]->offset.init_expr_type);
  1226. EMIT_U64(init_datas[i]->offset.u.i64);
  1227. EMIT_U32(init_datas[i]->byte_count);
  1228. EMIT_BUF(init_datas[i]->bytes, init_datas[i]->byte_count);
  1229. }
  1230. if (offset - *p_offset != get_mem_info_size(comp_data)) {
  1231. aot_set_last_error("emit memory info failed.");
  1232. return false;
  1233. }
  1234. *p_offset = offset;
  1235. return true;
  1236. }
  1237. static bool
  1238. aot_emit_table_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1239. AOTCompContext *comp_ctx, AOTCompData *comp_data,
  1240. AOTObjectData *obj_data)
  1241. {
  1242. uint32 offset = *p_offset, i, j;
  1243. AOTTableInitData **init_datas = comp_data->table_init_data_list;
  1244. *p_offset = offset = align_uint(offset, 4);
  1245. /* Emit import table count */
  1246. EMIT_U32(comp_data->import_table_count);
  1247. /* Emit table items */
  1248. for (i = 0; i < comp_data->import_table_count; i++) {
  1249. /* TODO:
  1250. * EMIT_STR(comp_data->import_tables[i].module_name );
  1251. * EMIT_STR(comp_data->import_tables[i].table_name);
  1252. */
  1253. EMIT_U32(comp_data->import_tables[i].elem_type);
  1254. EMIT_U32(comp_data->import_tables[i].table_init_size);
  1255. EMIT_U32(comp_data->import_tables[i].table_max_size);
  1256. EMIT_U32(comp_data->import_tables[i].possible_grow & 0x000000FF);
  1257. }
  1258. /* Emit table count */
  1259. EMIT_U32(comp_data->table_count);
  1260. /* Emit table items */
  1261. for (i = 0; i < comp_data->table_count; i++) {
  1262. EMIT_U32(comp_data->tables[i].elem_type);
  1263. EMIT_U32(comp_data->tables[i].table_flags);
  1264. EMIT_U32(comp_data->tables[i].table_init_size);
  1265. EMIT_U32(comp_data->tables[i].table_max_size);
  1266. EMIT_U32(comp_data->tables[i].possible_grow & 0x000000FF);
  1267. }
  1268. /* Emit table init data count */
  1269. EMIT_U32(comp_data->table_init_data_count);
  1270. /* Emit table init data items */
  1271. for (i = 0; i < comp_data->table_init_data_count; i++) {
  1272. offset = align_uint(offset, 4);
  1273. EMIT_U32(init_datas[i]->mode);
  1274. EMIT_U32(init_datas[i]->elem_type);
  1275. EMIT_U32(init_datas[i]->table_index);
  1276. EMIT_U32(init_datas[i]->offset.init_expr_type);
  1277. EMIT_U64(init_datas[i]->offset.u.i64);
  1278. EMIT_U32(init_datas[i]->func_index_count);
  1279. for (j = 0; j < init_datas[i]->func_index_count; j++)
  1280. EMIT_U32(init_datas[i]->func_indexes[j]);
  1281. }
  1282. if (offset - *p_offset != get_table_info_size(comp_data)) {
  1283. aot_set_last_error("emit table info failed.");
  1284. return false;
  1285. }
  1286. *p_offset = offset;
  1287. return true;
  1288. }
  1289. static bool
  1290. aot_emit_func_type_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1291. AOTCompData *comp_data, AOTObjectData *obj_data)
  1292. {
  1293. uint32 offset = *p_offset, i;
  1294. AOTFuncType **func_types = comp_data->func_types;
  1295. *p_offset = offset = align_uint(offset, 4);
  1296. EMIT_U32(comp_data->func_type_count);
  1297. for (i = 0; i < comp_data->func_type_count; i++) {
  1298. offset = align_uint(offset, 4);
  1299. EMIT_U32(func_types[i]->param_count);
  1300. EMIT_U32(func_types[i]->result_count);
  1301. EMIT_BUF(func_types[i]->types,
  1302. func_types[i]->param_count + func_types[i]->result_count);
  1303. }
  1304. if (offset - *p_offset != get_func_type_info_size(comp_data)) {
  1305. aot_set_last_error("emit function type info failed.");
  1306. return false;
  1307. }
  1308. *p_offset = offset;
  1309. return true;
  1310. }
  1311. static bool
  1312. aot_emit_import_global_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1313. AOTCompContext *comp_ctx, AOTCompData *comp_data,
  1314. AOTObjectData *obj_data)
  1315. {
  1316. uint32 offset = *p_offset, i;
  1317. AOTImportGlobal *import_global = comp_data->import_globals;
  1318. *p_offset = offset = align_uint(offset, 4);
  1319. EMIT_U32(comp_data->import_global_count);
  1320. for (i = 0; i < comp_data->import_global_count; i++, import_global++) {
  1321. offset = align_uint(offset, 2);
  1322. EMIT_U8(import_global->type);
  1323. EMIT_U8(import_global->is_mutable);
  1324. EMIT_STR(import_global->module_name);
  1325. offset = align_uint(offset, 2);
  1326. EMIT_STR(import_global->global_name);
  1327. }
  1328. if (offset - *p_offset
  1329. != get_import_global_info_size(comp_ctx, comp_data)) {
  1330. aot_set_last_error("emit import global info failed.");
  1331. return false;
  1332. }
  1333. *p_offset = offset;
  1334. return true;
  1335. }
  1336. static bool
  1337. aot_emit_global_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1338. AOTCompData *comp_data, AOTObjectData *obj_data)
  1339. {
  1340. uint32 offset = *p_offset, i;
  1341. AOTGlobal *global = comp_data->globals;
  1342. *p_offset = offset = align_uint(offset, 4);
  1343. EMIT_U32(comp_data->global_count);
  1344. for (i = 0; i < comp_data->global_count; i++, global++) {
  1345. offset = align_uint(offset, 4);
  1346. EMIT_U8(global->type);
  1347. EMIT_U8(global->is_mutable);
  1348. EMIT_U16(global->init_expr.init_expr_type);
  1349. if (global->init_expr.init_expr_type != INIT_EXPR_TYPE_V128_CONST)
  1350. EMIT_U64(global->init_expr.u.i64);
  1351. else
  1352. EMIT_V128(global->init_expr.u.v128);
  1353. }
  1354. if (offset - *p_offset != get_global_info_size(comp_data)) {
  1355. aot_set_last_error("emit global info failed.");
  1356. return false;
  1357. }
  1358. *p_offset = offset;
  1359. return true;
  1360. }
  1361. static bool
  1362. aot_emit_import_func_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1363. AOTCompContext *comp_ctx, AOTCompData *comp_data,
  1364. AOTObjectData *obj_data)
  1365. {
  1366. uint32 offset = *p_offset, i;
  1367. AOTImportFunc *import_func = comp_data->import_funcs;
  1368. *p_offset = offset = align_uint(offset, 4);
  1369. EMIT_U32(comp_data->import_func_count);
  1370. for (i = 0; i < comp_data->import_func_count; i++, import_func++) {
  1371. offset = align_uint(offset, 2);
  1372. EMIT_U16(import_func->func_type_index);
  1373. EMIT_STR(import_func->module_name);
  1374. offset = align_uint(offset, 2);
  1375. EMIT_STR(import_func->func_name);
  1376. }
  1377. if (offset - *p_offset != get_import_func_info_size(comp_ctx, comp_data)) {
  1378. aot_set_last_error("emit import function info failed.");
  1379. return false;
  1380. }
  1381. *p_offset = offset;
  1382. return true;
  1383. }
  1384. static bool
  1385. aot_emit_object_data_section_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1386. AOTCompContext *comp_ctx,
  1387. AOTObjectData *obj_data)
  1388. {
  1389. uint32 offset = *p_offset, i;
  1390. AOTObjectDataSection *data_section = obj_data->data_sections;
  1391. *p_offset = offset = align_uint(offset, 4);
  1392. EMIT_U32(obj_data->data_sections_count);
  1393. for (i = 0; i < obj_data->data_sections_count; i++, data_section++) {
  1394. offset = align_uint(offset, 2);
  1395. EMIT_STR(data_section->name);
  1396. offset = align_uint(offset, 4);
  1397. EMIT_U32(data_section->size);
  1398. EMIT_BUF(data_section->data, data_section->size);
  1399. }
  1400. if (offset - *p_offset
  1401. != get_object_data_section_info_size(comp_ctx, obj_data)) {
  1402. aot_set_last_error("emit object data section info failed.");
  1403. return false;
  1404. }
  1405. *p_offset = offset;
  1406. return true;
  1407. }
  1408. static bool
  1409. aot_emit_init_data_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1410. AOTCompContext *comp_ctx, AOTCompData *comp_data,
  1411. AOTObjectData *obj_data)
  1412. {
  1413. uint32 section_size =
  1414. get_init_data_section_size(comp_ctx, comp_data, obj_data);
  1415. uint32 offset = *p_offset;
  1416. *p_offset = offset = align_uint(offset, 4);
  1417. EMIT_U32(AOT_SECTION_TYPE_INIT_DATA);
  1418. EMIT_U32(section_size);
  1419. if (!aot_emit_mem_info(buf, buf_end, &offset, comp_ctx, comp_data, obj_data)
  1420. || !aot_emit_table_info(buf, buf_end, &offset, comp_ctx, comp_data,
  1421. obj_data)
  1422. || !aot_emit_func_type_info(buf, buf_end, &offset, comp_data, obj_data)
  1423. || !aot_emit_import_global_info(buf, buf_end, &offset, comp_ctx,
  1424. comp_data, obj_data)
  1425. || !aot_emit_global_info(buf, buf_end, &offset, comp_data, obj_data)
  1426. || !aot_emit_import_func_info(buf, buf_end, &offset, comp_ctx,
  1427. comp_data, obj_data))
  1428. return false;
  1429. offset = align_uint(offset, 4);
  1430. EMIT_U32(comp_data->func_count);
  1431. EMIT_U32(comp_data->start_func_index);
  1432. EMIT_U32(comp_data->aux_data_end_global_index);
  1433. EMIT_U32(comp_data->aux_data_end);
  1434. EMIT_U32(comp_data->aux_heap_base_global_index);
  1435. EMIT_U32(comp_data->aux_heap_base);
  1436. EMIT_U32(comp_data->aux_stack_top_global_index);
  1437. EMIT_U32(comp_data->aux_stack_bottom);
  1438. EMIT_U32(comp_data->aux_stack_size);
  1439. if (!aot_emit_object_data_section_info(buf, buf_end, &offset, comp_ctx,
  1440. obj_data))
  1441. return false;
  1442. if (offset - *p_offset != section_size + sizeof(uint32) * 2) {
  1443. aot_set_last_error("emit init data section failed.");
  1444. return false;
  1445. }
  1446. *p_offset = offset;
  1447. return true;
  1448. }
  1449. static bool
  1450. aot_emit_text_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1451. AOTCompData *comp_data, AOTObjectData *obj_data)
  1452. {
  1453. uint32 section_size = get_text_section_size(obj_data);
  1454. uint32 offset = *p_offset;
  1455. uint8 placeholder = 0;
  1456. *p_offset = offset = align_uint(offset, 4);
  1457. EMIT_U32(AOT_SECTION_TYPE_TEXT);
  1458. EMIT_U32(section_size);
  1459. EMIT_U32(obj_data->literal_size);
  1460. if (obj_data->literal_size > 0)
  1461. EMIT_BUF(obj_data->literal, obj_data->literal_size);
  1462. EMIT_BUF(obj_data->text, obj_data->text_size);
  1463. while (offset & 3)
  1464. EMIT_BUF(&placeholder, 1);
  1465. if (offset - *p_offset != section_size + sizeof(uint32) * 2) {
  1466. aot_set_last_error("emit text section failed.");
  1467. return false;
  1468. }
  1469. *p_offset = offset;
  1470. return true;
  1471. }
  1472. static bool
  1473. aot_emit_func_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1474. AOTCompData *comp_data, AOTObjectData *obj_data)
  1475. {
  1476. uint32 section_size = get_func_section_size(comp_data, obj_data);
  1477. uint32 i, offset = *p_offset;
  1478. AOTObjectFunc *func = obj_data->funcs;
  1479. AOTFunc **funcs = comp_data->funcs;
  1480. *p_offset = offset = align_uint(offset, 4);
  1481. EMIT_U32(AOT_SECTION_TYPE_FUNCTION);
  1482. EMIT_U32(section_size);
  1483. for (i = 0; i < obj_data->func_count; i++, func++) {
  1484. if (is_32bit_binary(obj_data))
  1485. EMIT_U32(func->text_offset);
  1486. else
  1487. EMIT_U64(func->text_offset);
  1488. }
  1489. for (i = 0; i < comp_data->func_count; i++)
  1490. EMIT_U32(funcs[i]->func_type_index);
  1491. if (offset - *p_offset != section_size + sizeof(uint32) * 2) {
  1492. aot_set_last_error("emit function section failed.");
  1493. return false;
  1494. }
  1495. *p_offset = offset;
  1496. return true;
  1497. }
  1498. static bool
  1499. aot_emit_export_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1500. AOTCompContext *comp_ctx, AOTCompData *comp_data,
  1501. AOTObjectData *obj_data)
  1502. {
  1503. uint32 section_size = get_export_section_size(comp_ctx, comp_data);
  1504. AOTExport *export = comp_data->wasm_module->exports;
  1505. uint32 export_count = comp_data->wasm_module->export_count;
  1506. uint32 i, offset = *p_offset;
  1507. *p_offset = offset = align_uint(offset, 4);
  1508. EMIT_U32(AOT_SECTION_TYPE_EXPORT);
  1509. EMIT_U32(section_size);
  1510. EMIT_U32(export_count);
  1511. for (i = 0; i < export_count; i++, export ++) {
  1512. offset = align_uint(offset, 4);
  1513. EMIT_U32(export->index);
  1514. EMIT_U8(export->kind);
  1515. EMIT_U8(0);
  1516. EMIT_STR(export->name);
  1517. }
  1518. if (offset - *p_offset != section_size + sizeof(uint32) * 2) {
  1519. aot_set_last_error("emit export section failed.");
  1520. return false;
  1521. }
  1522. *p_offset = offset;
  1523. return true;
  1524. }
  1525. static bool
  1526. aot_emit_relocation_symbol_table(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1527. AOTCompContext *comp_ctx,
  1528. AOTCompData *comp_data,
  1529. AOTObjectData *obj_data)
  1530. {
  1531. uint32 symbol_offset = 0, total_string_len = 0;
  1532. uint32 offset = *p_offset;
  1533. AOTSymbolNode *sym;
  1534. EMIT_U32(obj_data->symbol_list.len);
  1535. /* emit symbol offsets */
  1536. sym = (AOTSymbolNode *)(obj_data->symbol_list.head);
  1537. while (sym) {
  1538. EMIT_U32(symbol_offset);
  1539. /* string_len + str[0 .. string_len - 1] */
  1540. symbol_offset += get_string_size(comp_ctx, sym->symbol);
  1541. symbol_offset = align_uint(symbol_offset, 2);
  1542. sym = sym->next;
  1543. }
  1544. /* emit total string len */
  1545. total_string_len = symbol_offset;
  1546. EMIT_U32(total_string_len);
  1547. /* emit symbols */
  1548. sym = (AOTSymbolNode *)(obj_data->symbol_list.head);
  1549. while (sym) {
  1550. EMIT_STR(sym->symbol);
  1551. offset = align_uint(offset, 2);
  1552. sym = sym->next;
  1553. }
  1554. *p_offset = offset;
  1555. return true;
  1556. }
  1557. static bool
  1558. aot_emit_relocation_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1559. AOTCompContext *comp_ctx, AOTCompData *comp_data,
  1560. AOTObjectData *obj_data)
  1561. {
  1562. uint32 section_size = get_relocation_section_size(comp_ctx, obj_data);
  1563. uint32 i, offset = *p_offset;
  1564. AOTRelocationGroup *relocation_group = obj_data->relocation_groups;
  1565. if (section_size == (uint32)-1)
  1566. return false;
  1567. *p_offset = offset = align_uint(offset, 4);
  1568. EMIT_U32(AOT_SECTION_TYPE_RELOCATION);
  1569. EMIT_U32(section_size);
  1570. aot_emit_relocation_symbol_table(buf, buf_end, &offset, comp_ctx, comp_data,
  1571. obj_data);
  1572. offset = align_uint(offset, 4);
  1573. EMIT_U32(obj_data->relocation_group_count);
  1574. /* emit each relocation group */
  1575. for (i = 0; i < obj_data->relocation_group_count; i++, relocation_group++) {
  1576. AOTRelocation *relocation = relocation_group->relocations;
  1577. uint32 j;
  1578. offset = align_uint(offset, 4);
  1579. EMIT_U32(relocation_group->name_index);
  1580. offset = align_uint(offset, 4);
  1581. EMIT_U32(relocation_group->relocation_count);
  1582. /* emit each relocation */
  1583. for (j = 0; j < relocation_group->relocation_count; j++, relocation++) {
  1584. offset = align_uint(offset, 4);
  1585. if (is_32bit_binary(obj_data)) {
  1586. EMIT_U32(relocation->relocation_offset);
  1587. EMIT_U32(relocation->relocation_addend);
  1588. }
  1589. else {
  1590. EMIT_U64(relocation->relocation_offset);
  1591. EMIT_U64(relocation->relocation_addend);
  1592. }
  1593. EMIT_U32(relocation->relocation_type);
  1594. EMIT_U32(relocation->symbol_index);
  1595. }
  1596. }
  1597. if (offset - *p_offset != section_size + sizeof(uint32) * 2) {
  1598. aot_set_last_error("emit relocation section failed.");
  1599. return false;
  1600. }
  1601. *p_offset = offset;
  1602. return true;
  1603. }
  1604. static bool
  1605. aot_emit_native_symbol(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1606. AOTCompContext *comp_ctx)
  1607. {
  1608. uint32 offset = *p_offset;
  1609. AOTNativeSymbol *sym = NULL;
  1610. if (bh_list_length(&comp_ctx->native_symbols) == 0)
  1611. /* emit only when there are native symbols */
  1612. return true;
  1613. *p_offset = offset = align_uint(offset, 4);
  1614. EMIT_U32(AOT_SECTION_TYPE_CUSTOM);
  1615. /* sub section id + symbol count + symbol list */
  1616. EMIT_U32(sizeof(uint32) * 2 + get_native_symbol_list_size(comp_ctx));
  1617. EMIT_U32(AOT_CUSTOM_SECTION_NATIVE_SYMBOL);
  1618. EMIT_U32(bh_list_length(&comp_ctx->native_symbols));
  1619. sym = bh_list_first_elem(&comp_ctx->native_symbols);
  1620. while (sym) {
  1621. offset = align_uint(offset, 2);
  1622. EMIT_STR(sym->symbol);
  1623. sym = bh_list_elem_next(sym);
  1624. }
  1625. *p_offset = offset;
  1626. return true;
  1627. }
  1628. static bool
  1629. aot_emit_name_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1630. AOTCompData *comp_data, AOTCompContext *comp_ctx)
  1631. {
  1632. if (comp_ctx->enable_aux_stack_frame) {
  1633. uint32 offset = *p_offset;
  1634. *p_offset = offset = align_uint(offset, 4);
  1635. EMIT_U32(AOT_SECTION_TYPE_CUSTOM);
  1636. /* sub section id + name section size */
  1637. EMIT_U32(sizeof(uint32) * 1 + comp_data->aot_name_section_size);
  1638. EMIT_U32(AOT_CUSTOM_SECTION_NAME);
  1639. bh_memcpy_s((uint8 *)(buf + offset), (uint32)(buf_end - buf),
  1640. comp_data->aot_name_section_buf,
  1641. (uint32)comp_data->aot_name_section_size);
  1642. offset += comp_data->aot_name_section_size;
  1643. *p_offset = offset;
  1644. }
  1645. return true;
  1646. }
  1647. static bool
  1648. aot_emit_custom_sections(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
  1649. AOTCompData *comp_data, AOTCompContext *comp_ctx)
  1650. {
  1651. #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
  1652. uint32 offset = *p_offset, i;
  1653. for (i = 0; i < comp_ctx->custom_sections_count; i++) {
  1654. const char *section_name = comp_ctx->custom_sections_wp[i];
  1655. const uint8 *content = NULL;
  1656. uint32 length = 0;
  1657. content = wasm_loader_get_custom_section(comp_data->wasm_module,
  1658. section_name, &length);
  1659. if (!content) {
  1660. /* Warning has been reported during calculating size */
  1661. continue;
  1662. }
  1663. offset = align_uint(offset, 4);
  1664. EMIT_U32(AOT_SECTION_TYPE_CUSTOM);
  1665. /* sub section id + content */
  1666. EMIT_U32(sizeof(uint32) * 1 + get_string_size(comp_ctx, section_name)
  1667. + length);
  1668. EMIT_U32(AOT_CUSTOM_SECTION_RAW);
  1669. EMIT_STR(section_name);
  1670. bh_memcpy_s((uint8 *)(buf + offset), (uint32)(buf_end - buf), content,
  1671. length);
  1672. offset += length;
  1673. }
  1674. *p_offset = offset;
  1675. #endif
  1676. return true;
  1677. }
  1678. typedef uint32 U32;
  1679. typedef int32 I32;
  1680. typedef uint16 U16;
  1681. typedef uint8 U8;
  1682. struct coff_hdr {
  1683. U16 u16Machine;
  1684. U16 u16NumSections;
  1685. U32 u32DateTimeStamp;
  1686. U32 u32SymTblPtr;
  1687. U32 u32NumSymbols;
  1688. U16 u16PeHdrSize;
  1689. U16 u16Characs;
  1690. };
  1691. #define E_TYPE_REL 1
  1692. #define E_TYPE_XIP 4
  1693. #define IMAGE_FILE_MACHINE_AMD64 0x8664
  1694. #define IMAGE_FILE_MACHINE_I386 0x014c
  1695. #define IMAGE_FILE_MACHINE_IA64 0x0200
  1696. #define AOT_COFF32_BIN_TYPE 4 /* 32-bit little endian */
  1697. #define AOT_COFF64_BIN_TYPE 6 /* 64-bit little endian */
  1698. #define EI_NIDENT 16
  1699. typedef uint32 elf32_word;
  1700. typedef int32 elf32_sword;
  1701. typedef uint16 elf32_half;
  1702. typedef uint32 elf32_off;
  1703. typedef uint32 elf32_addr;
  1704. struct elf32_ehdr {
  1705. unsigned char e_ident[EI_NIDENT]; /* ident bytes */
  1706. elf32_half e_type; /* file type */
  1707. elf32_half e_machine; /* target machine */
  1708. elf32_word e_version; /* file version */
  1709. elf32_addr e_entry; /* start address */
  1710. elf32_off e_phoff; /* phdr file offset */
  1711. elf32_off e_shoff; /* shdr file offset */
  1712. elf32_word e_flags; /* file flags */
  1713. elf32_half e_ehsize; /* sizeof ehdr */
  1714. elf32_half e_phentsize; /* sizeof phdr */
  1715. elf32_half e_phnum; /* number phdrs */
  1716. elf32_half e_shentsize; /* sizeof shdr */
  1717. elf32_half e_shnum; /* number shdrs */
  1718. elf32_half e_shstrndx; /* shdr string index */
  1719. };
  1720. struct elf32_rel {
  1721. elf32_addr r_offset;
  1722. elf32_word r_info;
  1723. } elf32_rel;
  1724. struct elf32_rela {
  1725. elf32_addr r_offset;
  1726. elf32_word r_info;
  1727. elf32_sword r_addend;
  1728. } elf32_rela;
  1729. typedef uint32 elf64_word;
  1730. typedef int32 elf64_sword;
  1731. typedef uint64 elf64_xword;
  1732. typedef int64 elf64_sxword;
  1733. typedef uint16 elf64_half;
  1734. typedef uint64 elf64_off;
  1735. typedef uint64 elf64_addr;
  1736. struct elf64_ehdr {
  1737. unsigned char e_ident[EI_NIDENT]; /* ident bytes */
  1738. elf64_half e_type; /* file type */
  1739. elf64_half e_machine; /* target machine */
  1740. elf64_word e_version; /* file version */
  1741. elf64_addr e_entry; /* start address */
  1742. elf64_off e_phoff; /* phdr file offset */
  1743. elf64_off e_shoff; /* shdr file offset */
  1744. elf64_word e_flags; /* file flags */
  1745. elf64_half e_ehsize; /* sizeof ehdr */
  1746. elf64_half e_phentsize; /* sizeof phdr */
  1747. elf64_half e_phnum; /* number phdrs */
  1748. elf64_half e_shentsize; /* sizeof shdr */
  1749. elf64_half e_shnum; /* number shdrs */
  1750. elf64_half e_shstrndx; /* shdr string index */
  1751. };
  1752. typedef struct elf64_rel {
  1753. elf64_addr r_offset;
  1754. elf64_xword r_info;
  1755. } elf64_rel;
  1756. typedef struct elf64_rela {
  1757. elf64_addr r_offset;
  1758. elf64_xword r_info;
  1759. elf64_sxword r_addend;
  1760. } elf64_rela;
  1761. #define SET_TARGET_INFO(f, v, type, little) \
  1762. do { \
  1763. type tmp = elf_header->v; \
  1764. if ((little && !is_little_endian()) \
  1765. || (!little && is_little_endian())) \
  1766. exchange_##type((uint8 *)&tmp); \
  1767. obj_data->target_info.f = tmp; \
  1768. } while (0)
  1769. static bool
  1770. aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
  1771. {
  1772. LLVMBinaryType bin_type = LLVMBinaryGetType(obj_data->binary);
  1773. const uint8 *elf_buf = (uint8 *)LLVMGetBufferStart(obj_data->mem_buf);
  1774. uint32 elf_size = (uint32)LLVMGetBufferSize(obj_data->mem_buf);
  1775. if (bin_type != LLVMBinaryTypeCOFF && bin_type != LLVMBinaryTypeELF32L
  1776. && bin_type != LLVMBinaryTypeELF32B && bin_type != LLVMBinaryTypeELF64L
  1777. && bin_type != LLVMBinaryTypeELF64B
  1778. && bin_type != LLVMBinaryTypeMachO32L
  1779. && bin_type != LLVMBinaryTypeMachO32B
  1780. && bin_type != LLVMBinaryTypeMachO64L
  1781. && bin_type != LLVMBinaryTypeMachO64B) {
  1782. aot_set_last_error("invaid llvm binary bin_type.");
  1783. return false;
  1784. }
  1785. obj_data->target_info.bin_type = bin_type - LLVMBinaryTypeELF32L;
  1786. if (bin_type == LLVMBinaryTypeCOFF) {
  1787. struct coff_hdr *coff_header;
  1788. if (!elf_buf || elf_size < sizeof(struct coff_hdr)) {
  1789. aot_set_last_error("invalid coff_hdr buffer.");
  1790. return false;
  1791. }
  1792. coff_header = (struct coff_hdr *)elf_buf;
  1793. /* Emit eXecute In Place file type while in indirect mode */
  1794. if (comp_ctx->is_indirect_mode)
  1795. obj_data->target_info.e_type = E_TYPE_XIP;
  1796. else
  1797. obj_data->target_info.e_type = E_TYPE_REL;
  1798. obj_data->target_info.e_machine = coff_header->u16Machine;
  1799. obj_data->target_info.e_version = 1;
  1800. obj_data->target_info.e_flags = 0;
  1801. if (coff_header->u16Machine == IMAGE_FILE_MACHINE_AMD64
  1802. || coff_header->u16Machine == IMAGE_FILE_MACHINE_IA64)
  1803. obj_data->target_info.bin_type = AOT_COFF64_BIN_TYPE;
  1804. else if (coff_header->u16Machine == IMAGE_FILE_MACHINE_I386)
  1805. obj_data->target_info.bin_type = AOT_COFF32_BIN_TYPE;
  1806. }
  1807. else if (bin_type == LLVMBinaryTypeELF32L
  1808. || bin_type == LLVMBinaryTypeELF32B) {
  1809. struct elf32_ehdr *elf_header;
  1810. bool is_little_bin = bin_type == LLVMBinaryTypeELF32L;
  1811. if (!elf_buf || elf_size < sizeof(struct elf32_ehdr)) {
  1812. aot_set_last_error("invalid elf32 buffer.");
  1813. return false;
  1814. }
  1815. elf_header = (struct elf32_ehdr *)elf_buf;
  1816. /* Emit eXecute In Place file type while in indirect mode */
  1817. if (comp_ctx->is_indirect_mode)
  1818. elf_header->e_type = E_TYPE_XIP;
  1819. SET_TARGET_INFO(e_type, e_type, uint16, is_little_bin);
  1820. SET_TARGET_INFO(e_machine, e_machine, uint16, is_little_bin);
  1821. SET_TARGET_INFO(e_version, e_version, uint32, is_little_bin);
  1822. SET_TARGET_INFO(e_flags, e_flags, uint32, is_little_bin);
  1823. }
  1824. else if (bin_type == LLVMBinaryTypeELF64L
  1825. || bin_type == LLVMBinaryTypeELF64B) {
  1826. struct elf64_ehdr *elf_header;
  1827. bool is_little_bin = bin_type == LLVMBinaryTypeELF64L;
  1828. if (!elf_buf || elf_size < sizeof(struct elf64_ehdr)) {
  1829. aot_set_last_error("invalid elf64 buffer.");
  1830. return false;
  1831. }
  1832. elf_header = (struct elf64_ehdr *)elf_buf;
  1833. /* Emit eXecute In Place file type while in indirect mode */
  1834. if (comp_ctx->is_indirect_mode)
  1835. elf_header->e_type = E_TYPE_XIP;
  1836. SET_TARGET_INFO(e_type, e_type, uint16, is_little_bin);
  1837. SET_TARGET_INFO(e_machine, e_machine, uint16, is_little_bin);
  1838. SET_TARGET_INFO(e_version, e_version, uint32, is_little_bin);
  1839. SET_TARGET_INFO(e_flags, e_flags, uint32, is_little_bin);
  1840. }
  1841. else if (bin_type == LLVMBinaryTypeMachO32L
  1842. || bin_type == LLVMBinaryTypeMachO32B) {
  1843. /* TODO: parse file type of Mach-O 32 */
  1844. aot_set_last_error("invaid llvm binary bin_type.");
  1845. return false;
  1846. }
  1847. else if (bin_type == LLVMBinaryTypeMachO64L
  1848. || bin_type == LLVMBinaryTypeMachO64B) {
  1849. /* TODO: parse file type of Mach-O 64 */
  1850. aot_set_last_error("invaid llvm binary bin_type.");
  1851. return false;
  1852. }
  1853. bh_assert(sizeof(obj_data->target_info.arch)
  1854. == sizeof(comp_ctx->target_arch));
  1855. bh_memcpy_s(obj_data->target_info.arch, sizeof(obj_data->target_info.arch),
  1856. comp_ctx->target_arch, sizeof(comp_ctx->target_arch));
  1857. return true;
  1858. }
  1859. static bool
  1860. aot_resolve_text(AOTObjectData *obj_data)
  1861. {
  1862. #if WASM_ENABLE_DEBUG_AOT != 0
  1863. LLVMBinaryType bin_type = LLVMBinaryGetType(obj_data->binary);
  1864. if (bin_type == LLVMBinaryTypeELF32L || bin_type == LLVMBinaryTypeELF64L) {
  1865. obj_data->text = (char *)LLVMGetBufferStart(obj_data->mem_buf);
  1866. obj_data->text_size = (uint32)LLVMGetBufferSize(obj_data->mem_buf);
  1867. }
  1868. else
  1869. #endif
  1870. {
  1871. LLVMSectionIteratorRef sec_itr;
  1872. char *name;
  1873. if (!(sec_itr = LLVMObjectFileCopySectionIterator(obj_data->binary))) {
  1874. aot_set_last_error("llvm get section iterator failed.");
  1875. return false;
  1876. }
  1877. while (
  1878. !LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
  1879. if ((name = (char *)LLVMGetSectionName(sec_itr))
  1880. && !strcmp(name, ".text")) {
  1881. obj_data->text = (char *)LLVMGetSectionContents(sec_itr);
  1882. obj_data->text_size = (uint32)LLVMGetSectionSize(sec_itr);
  1883. break;
  1884. }
  1885. LLVMMoveToNextSection(sec_itr);
  1886. }
  1887. LLVMDisposeSectionIterator(sec_itr);
  1888. }
  1889. return true;
  1890. }
  1891. static bool
  1892. aot_resolve_literal(AOTObjectData *obj_data)
  1893. {
  1894. LLVMSectionIteratorRef sec_itr;
  1895. char *name;
  1896. if (!(sec_itr = LLVMObjectFileCopySectionIterator(obj_data->binary))) {
  1897. aot_set_last_error("llvm get section iterator failed.");
  1898. return false;
  1899. }
  1900. while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
  1901. if ((name = (char *)LLVMGetSectionName(sec_itr))
  1902. && !strcmp(name, ".literal")) {
  1903. obj_data->literal = (char *)LLVMGetSectionContents(sec_itr);
  1904. obj_data->literal_size = (uint32)LLVMGetSectionSize(sec_itr);
  1905. break;
  1906. }
  1907. LLVMMoveToNextSection(sec_itr);
  1908. }
  1909. LLVMDisposeSectionIterator(sec_itr);
  1910. return true;
  1911. }
  1912. static bool
  1913. get_relocations_count(LLVMSectionIteratorRef sec_itr, uint32 *p_count);
  1914. static bool
  1915. is_data_section(LLVMSectionIteratorRef sec_itr, char *section_name)
  1916. {
  1917. uint32 relocation_count = 0;
  1918. return (!strcmp(section_name, ".data") || !strcmp(section_name, ".sdata")
  1919. || !strcmp(section_name, ".rodata")
  1920. /* ".rodata.cst4/8/16/.." */
  1921. || !strncmp(section_name, ".rodata.cst", strlen(".rodata.cst"))
  1922. /* ".rodata.strn.m" */
  1923. || !strncmp(section_name, ".rodata.str", strlen(".rodata.str"))
  1924. || (!strcmp(section_name, ".rdata")
  1925. && get_relocations_count(sec_itr, &relocation_count)
  1926. && relocation_count > 0));
  1927. }
  1928. static bool
  1929. get_object_data_sections_count(AOTObjectData *obj_data, uint32 *p_count)
  1930. {
  1931. LLVMSectionIteratorRef sec_itr;
  1932. char *name;
  1933. uint32 count = 0;
  1934. if (!(sec_itr = LLVMObjectFileCopySectionIterator(obj_data->binary))) {
  1935. aot_set_last_error("llvm get section iterator failed.");
  1936. return false;
  1937. }
  1938. while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
  1939. if ((name = (char *)LLVMGetSectionName(sec_itr))
  1940. && (is_data_section(sec_itr, name))) {
  1941. count++;
  1942. }
  1943. LLVMMoveToNextSection(sec_itr);
  1944. }
  1945. LLVMDisposeSectionIterator(sec_itr);
  1946. *p_count = count;
  1947. return true;
  1948. }
  1949. static bool
  1950. aot_resolve_object_data_sections(AOTObjectData *obj_data)
  1951. {
  1952. LLVMSectionIteratorRef sec_itr;
  1953. char *name;
  1954. AOTObjectDataSection *data_section;
  1955. uint32 sections_count;
  1956. uint32 size;
  1957. if (!get_object_data_sections_count(obj_data, &sections_count)) {
  1958. return false;
  1959. }
  1960. if (sections_count > 0) {
  1961. size = (uint32)sizeof(AOTObjectDataSection) * sections_count;
  1962. if (!(data_section = obj_data->data_sections =
  1963. wasm_runtime_malloc(size))) {
  1964. aot_set_last_error("allocate memory for data sections failed.");
  1965. return false;
  1966. }
  1967. memset(obj_data->data_sections, 0, size);
  1968. obj_data->data_sections_count = sections_count;
  1969. if (!(sec_itr = LLVMObjectFileCopySectionIterator(obj_data->binary))) {
  1970. aot_set_last_error("llvm get section iterator failed.");
  1971. return false;
  1972. }
  1973. while (
  1974. !LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
  1975. if ((name = (char *)LLVMGetSectionName(sec_itr))
  1976. && (is_data_section(sec_itr, name))) {
  1977. data_section->name = name;
  1978. data_section->data = (uint8 *)LLVMGetSectionContents(sec_itr);
  1979. data_section->size = (uint32)LLVMGetSectionSize(sec_itr);
  1980. data_section++;
  1981. }
  1982. LLVMMoveToNextSection(sec_itr);
  1983. }
  1984. LLVMDisposeSectionIterator(sec_itr);
  1985. }
  1986. return true;
  1987. }
  1988. static bool
  1989. aot_resolve_functions(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
  1990. {
  1991. AOTObjectFunc *func;
  1992. LLVMSymbolIteratorRef sym_itr;
  1993. char *name, *prefix = AOT_FUNC_PREFIX;
  1994. uint32 func_index, total_size;
  1995. /* allocate memory for aot function */
  1996. obj_data->func_count = comp_ctx->comp_data->func_count;
  1997. if (obj_data->func_count) {
  1998. total_size = (uint32)sizeof(AOTObjectFunc) * obj_data->func_count;
  1999. if (!(obj_data->funcs = wasm_runtime_malloc(total_size))) {
  2000. aot_set_last_error("allocate memory for functions failed.");
  2001. return false;
  2002. }
  2003. memset(obj_data->funcs, 0, total_size);
  2004. }
  2005. if (!(sym_itr = LLVMObjectFileCopySymbolIterator(obj_data->binary))) {
  2006. aot_set_last_error("llvm get symbol iterator failed.");
  2007. return false;
  2008. }
  2009. while (!LLVMObjectFileIsSymbolIteratorAtEnd(obj_data->binary, sym_itr)) {
  2010. if ((name = (char *)LLVMGetSymbolName(sym_itr))
  2011. && str_starts_with(name, prefix)) {
  2012. func_index = (uint32)atoi(name + strlen(prefix));
  2013. if (func_index < obj_data->func_count) {
  2014. func = obj_data->funcs + func_index;
  2015. func->func_name = name;
  2016. func->text_offset = LLVMGetSymbolAddress(sym_itr);
  2017. }
  2018. }
  2019. LLVMMoveToNextSymbol(sym_itr);
  2020. }
  2021. LLVMDisposeSymbolIterator(sym_itr);
  2022. return true;
  2023. }
  2024. static bool
  2025. get_relocations_count(LLVMSectionIteratorRef sec_itr, uint32 *p_count)
  2026. {
  2027. uint32 relocation_count = 0;
  2028. LLVMRelocationIteratorRef rel_itr;
  2029. if (!(rel_itr = LLVMGetRelocations(sec_itr))) {
  2030. aot_set_last_error("llvm get relocations failed.");
  2031. LLVMDisposeSectionIterator(sec_itr);
  2032. return false;
  2033. }
  2034. while (!LLVMIsRelocationIteratorAtEnd(sec_itr, rel_itr)) {
  2035. relocation_count++;
  2036. LLVMMoveToNextRelocation(rel_itr);
  2037. }
  2038. LLVMDisposeRelocationIterator(rel_itr);
  2039. *p_count = relocation_count;
  2040. return true;
  2041. }
  2042. static bool
  2043. aot_resolve_object_relocation_group(AOTObjectData *obj_data,
  2044. AOTRelocationGroup *group,
  2045. LLVMSectionIteratorRef rel_sec)
  2046. {
  2047. LLVMRelocationIteratorRef rel_itr;
  2048. AOTRelocation *relocation = group->relocations;
  2049. uint32 size;
  2050. bool is_binary_32bit = is_32bit_binary(obj_data);
  2051. bool is_binary_little_endian = is_little_endian_binary(obj_data);
  2052. bool has_addend = str_starts_with(group->section_name, ".rela");
  2053. uint8 *rela_content = NULL;
  2054. /* calculate relocations count and allocate memory */
  2055. if (!get_relocations_count(rel_sec, &group->relocation_count))
  2056. return false;
  2057. if (group->relocation_count == 0) {
  2058. aot_set_last_error("invalid relocations count");
  2059. return false;
  2060. }
  2061. size = (uint32)sizeof(AOTRelocation) * group->relocation_count;
  2062. if (!(relocation = group->relocations = wasm_runtime_malloc(size))) {
  2063. aot_set_last_error("allocate memory for relocations failed.");
  2064. return false;
  2065. }
  2066. memset(group->relocations, 0, size);
  2067. if (has_addend) {
  2068. uint64 rela_content_size;
  2069. /* LLVM doesn't provide C API to get relocation addend. So we have to
  2070. * parse it manually. */
  2071. rela_content = (uint8 *)LLVMGetSectionContents(rel_sec);
  2072. rela_content_size = LLVMGetSectionSize(rel_sec);
  2073. if (is_binary_32bit)
  2074. size = (uint32)sizeof(struct elf32_rela) * group->relocation_count;
  2075. else
  2076. size = (uint32)sizeof(struct elf64_rela) * group->relocation_count;
  2077. if (rela_content_size != (uint64)size) {
  2078. aot_set_last_error("invalid relocation section content.");
  2079. return false;
  2080. }
  2081. }
  2082. /* pares each relocation */
  2083. if (!(rel_itr = LLVMGetRelocations(rel_sec))) {
  2084. aot_set_last_error("llvm get relocations failed.");
  2085. return false;
  2086. }
  2087. while (!LLVMIsRelocationIteratorAtEnd(rel_sec, rel_itr)) {
  2088. uint64 offset = LLVMGetRelocationOffset(rel_itr);
  2089. uint64 type = LLVMGetRelocationType(rel_itr);
  2090. LLVMSymbolIteratorRef rel_sym = LLVMGetRelocationSymbol(rel_itr);
  2091. if (!rel_sym) {
  2092. aot_set_last_error("llvm get relocation symbol failed.");
  2093. goto fail;
  2094. }
  2095. /* parse relocation addend from reloction content */
  2096. if (has_addend) {
  2097. if (is_binary_32bit) {
  2098. int32 addend =
  2099. (int32)(((struct elf32_rela *)rela_content)->r_addend);
  2100. if (is_binary_little_endian != is_little_endian())
  2101. exchange_uint32((uint8 *)&addend);
  2102. relocation->relocation_addend = (int64)addend;
  2103. rela_content += sizeof(struct elf32_rela);
  2104. }
  2105. else {
  2106. int64 addend =
  2107. (int64)(((struct elf64_rela *)rela_content)->r_addend);
  2108. if (is_binary_little_endian != is_little_endian())
  2109. exchange_uint64((uint8 *)&addend);
  2110. relocation->relocation_addend = addend;
  2111. rela_content += sizeof(struct elf64_rela);
  2112. }
  2113. }
  2114. /* set relocation fields */
  2115. relocation->relocation_offset = offset;
  2116. relocation->relocation_type = (uint32)type;
  2117. relocation->symbol_name = (char *)LLVMGetSymbolName(rel_sym);
  2118. /* for ".LCPIxxx", ".LJTIxxx", ".LBBxxx" and switch lookup table
  2119. * relocation, transform the symbol name to real section name and set
  2120. * addend to the offset of the symbol in the real section */
  2121. if (relocation->symbol_name
  2122. && (str_starts_with(relocation->symbol_name, ".LCPI")
  2123. || str_starts_with(relocation->symbol_name, ".LJTI")
  2124. || str_starts_with(relocation->symbol_name, ".LBB")
  2125. || str_starts_with(relocation->symbol_name,
  2126. ".Lswitch.table."))) {
  2127. /* change relocation->relocation_addend and
  2128. relocation->symbol_name */
  2129. LLVMSectionIteratorRef contain_section;
  2130. if (!(contain_section =
  2131. LLVMObjectFileCopySectionIterator(obj_data->binary))) {
  2132. aot_set_last_error("llvm get section iterator failed.");
  2133. goto fail;
  2134. }
  2135. LLVMMoveToContainingSection(contain_section, rel_sym);
  2136. if (LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary,
  2137. contain_section)) {
  2138. LLVMDisposeSectionIterator(contain_section);
  2139. aot_set_last_error("llvm get containing section failed.");
  2140. goto fail;
  2141. }
  2142. relocation->relocation_addend += LLVMGetSymbolAddress(rel_sym);
  2143. relocation->symbol_name =
  2144. (char *)LLVMGetSectionName(contain_section);
  2145. LLVMDisposeSectionIterator(contain_section);
  2146. }
  2147. LLVMDisposeSymbolIterator(rel_sym);
  2148. LLVMMoveToNextRelocation(rel_itr);
  2149. relocation++;
  2150. }
  2151. LLVMDisposeRelocationIterator(rel_itr);
  2152. return true;
  2153. fail:
  2154. LLVMDisposeRelocationIterator(rel_itr);
  2155. return false;
  2156. }
  2157. static bool
  2158. is_relocation_section_name(char *section_name)
  2159. {
  2160. return (!strcmp(section_name, ".rela.text")
  2161. || !strcmp(section_name, ".rel.text")
  2162. || !strcmp(section_name, ".rela.literal")
  2163. || !strcmp(section_name, ".rela.data")
  2164. || !strcmp(section_name, ".rel.data")
  2165. || !strcmp(section_name, ".rela.sdata")
  2166. || !strcmp(section_name, ".rel.sdata")
  2167. || !strcmp(section_name, ".rela.rodata")
  2168. || !strcmp(section_name, ".rel.rodata")
  2169. /* ".rela.rodata.cst4/8/16/.." */
  2170. || !strncmp(section_name, ".rela.rodata.cst",
  2171. strlen(".rela.rodata.cst"))
  2172. /* ".rel.rodata.cst4/8/16/.." */
  2173. || !strncmp(section_name, ".rel.rodata.cst",
  2174. strlen(".rel.rodata.cst")));
  2175. }
  2176. static bool
  2177. is_relocation_section(LLVMSectionIteratorRef sec_itr)
  2178. {
  2179. uint32 count = 0;
  2180. char *name = (char *)LLVMGetSectionName(sec_itr);
  2181. if (name) {
  2182. if (is_relocation_section_name(name))
  2183. return true;
  2184. else if ((!strcmp(name, ".text") || !strcmp(name, ".rdata"))
  2185. && get_relocations_count(sec_itr, &count) && count > 0)
  2186. return true;
  2187. }
  2188. return false;
  2189. }
  2190. static bool
  2191. get_relocation_groups_count(AOTObjectData *obj_data, uint32 *p_count)
  2192. {
  2193. uint32 count = 0;
  2194. LLVMSectionIteratorRef sec_itr;
  2195. if (!(sec_itr = LLVMObjectFileCopySectionIterator(obj_data->binary))) {
  2196. aot_set_last_error("llvm get section iterator failed.");
  2197. return false;
  2198. }
  2199. while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
  2200. if (is_relocation_section(sec_itr)) {
  2201. count++;
  2202. }
  2203. LLVMMoveToNextSection(sec_itr);
  2204. }
  2205. LLVMDisposeSectionIterator(sec_itr);
  2206. *p_count = count;
  2207. return true;
  2208. }
  2209. static bool
  2210. aot_resolve_object_relocation_groups(AOTObjectData *obj_data)
  2211. {
  2212. LLVMSectionIteratorRef sec_itr;
  2213. AOTRelocationGroup *relocation_group;
  2214. uint32 group_count;
  2215. char *name;
  2216. uint32 size;
  2217. /* calculate relocation groups count and allocate memory */
  2218. if (!get_relocation_groups_count(obj_data, &group_count))
  2219. return false;
  2220. if (0 == (obj_data->relocation_group_count = group_count))
  2221. return true;
  2222. size = (uint32)sizeof(AOTRelocationGroup) * group_count;
  2223. if (!(relocation_group = obj_data->relocation_groups =
  2224. wasm_runtime_malloc(size))) {
  2225. aot_set_last_error("allocate memory for relocation groups failed.");
  2226. return false;
  2227. }
  2228. memset(obj_data->relocation_groups, 0, size);
  2229. /* resolve each relocation group */
  2230. if (!(sec_itr = LLVMObjectFileCopySectionIterator(obj_data->binary))) {
  2231. aot_set_last_error("llvm get section iterator failed.");
  2232. return false;
  2233. }
  2234. while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) {
  2235. if (is_relocation_section(sec_itr)) {
  2236. name = (char *)LLVMGetSectionName(sec_itr);
  2237. relocation_group->section_name = name;
  2238. if (!aot_resolve_object_relocation_group(obj_data, relocation_group,
  2239. sec_itr)) {
  2240. LLVMDisposeSectionIterator(sec_itr);
  2241. return false;
  2242. }
  2243. relocation_group++;
  2244. }
  2245. LLVMMoveToNextSection(sec_itr);
  2246. }
  2247. LLVMDisposeSectionIterator(sec_itr);
  2248. return true;
  2249. }
  2250. static void
  2251. destroy_relocation_groups(AOTRelocationGroup *relocation_groups,
  2252. uint32 relocation_group_count)
  2253. {
  2254. uint32 i;
  2255. AOTRelocationGroup *relocation_group = relocation_groups;
  2256. for (i = 0; i < relocation_group_count; i++, relocation_group++)
  2257. if (relocation_group->relocations)
  2258. wasm_runtime_free(relocation_group->relocations);
  2259. wasm_runtime_free(relocation_groups);
  2260. }
  2261. static void
  2262. destroy_relocation_symbol_list(AOTSymbolList *symbol_list)
  2263. {
  2264. AOTSymbolNode *elem;
  2265. elem = symbol_list->head;
  2266. while (elem) {
  2267. AOTSymbolNode *next = elem->next;
  2268. wasm_runtime_free(elem);
  2269. elem = next;
  2270. }
  2271. }
  2272. static void
  2273. aot_obj_data_destroy(AOTObjectData *obj_data)
  2274. {
  2275. if (obj_data->binary)
  2276. LLVMDisposeBinary(obj_data->binary);
  2277. if (obj_data->mem_buf)
  2278. LLVMDisposeMemoryBuffer(obj_data->mem_buf);
  2279. if (obj_data->funcs)
  2280. wasm_runtime_free(obj_data->funcs);
  2281. if (obj_data->data_sections)
  2282. wasm_runtime_free(obj_data->data_sections);
  2283. if (obj_data->relocation_groups)
  2284. destroy_relocation_groups(obj_data->relocation_groups,
  2285. obj_data->relocation_group_count);
  2286. if (obj_data->symbol_list.len)
  2287. destroy_relocation_symbol_list(&obj_data->symbol_list);
  2288. wasm_runtime_free(obj_data);
  2289. }
  2290. static AOTObjectData *
  2291. aot_obj_data_create(AOTCompContext *comp_ctx)
  2292. {
  2293. char *err = NULL;
  2294. AOTObjectData *obj_data;
  2295. LLVMTargetRef target = LLVMGetTargetMachineTarget(comp_ctx->target_machine);
  2296. bh_print_time("Begin to emit object file to buffer");
  2297. if (!(obj_data = wasm_runtime_malloc(sizeof(AOTObjectData)))) {
  2298. aot_set_last_error("allocate memory failed.");
  2299. return false;
  2300. }
  2301. memset(obj_data, 0, sizeof(AOTObjectData));
  2302. bh_print_time("Begin to emit object file");
  2303. if (comp_ctx->external_llc_compiler || comp_ctx->external_asm_compiler) {
  2304. #if defined(_WIN32) || defined(_WIN32_)
  2305. aot_set_last_error("external toolchain not supported on Windows");
  2306. goto fail;
  2307. #else
  2308. /* Generate a temp file name */
  2309. int ret;
  2310. char obj_file_name[64];
  2311. if (!aot_generate_tempfile_name("wamrc-obj", "o", obj_file_name,
  2312. sizeof(obj_file_name))) {
  2313. goto fail;
  2314. }
  2315. if (!aot_emit_object_file(comp_ctx, obj_file_name)) {
  2316. goto fail;
  2317. }
  2318. /* create memory buffer from object file */
  2319. ret = LLVMCreateMemoryBufferWithContentsOfFile(
  2320. obj_file_name, &obj_data->mem_buf, &err);
  2321. /* remove temp object file */
  2322. unlink(obj_file_name);
  2323. if (ret != 0) {
  2324. if (err) {
  2325. LLVMDisposeMessage(err);
  2326. err = NULL;
  2327. }
  2328. aot_set_last_error("create mem buffer with file failed.");
  2329. goto fail;
  2330. }
  2331. #endif /* end of defined(_WIN32) || defined(_WIN32_) */
  2332. }
  2333. else if (!strncmp(LLVMGetTargetName(target), "arc", 3)) {
  2334. #if defined(_WIN32) || defined(_WIN32_)
  2335. aot_set_last_error("emit object file on Windows is unsupported.");
  2336. goto fail;
  2337. #else
  2338. /* Emit to assmelby file instead for arc target
  2339. as it cannot emit to object file */
  2340. char file_name[] = "wasm-XXXXXX", buf[128];
  2341. int fd, ret;
  2342. if ((fd = mkstemp(file_name)) <= 0) {
  2343. aot_set_last_error("make temp file failed.");
  2344. goto fail;
  2345. }
  2346. /* close and remove temp file */
  2347. close(fd);
  2348. unlink(file_name);
  2349. snprintf(buf, sizeof(buf), "%s%s", file_name, ".s");
  2350. if (LLVMTargetMachineEmitToFile(comp_ctx->target_machine,
  2351. comp_ctx->module, buf, LLVMAssemblyFile,
  2352. &err)
  2353. != 0) {
  2354. if (err) {
  2355. LLVMDisposeMessage(err);
  2356. err = NULL;
  2357. }
  2358. aot_set_last_error("emit elf to object file failed.");
  2359. goto fail;
  2360. }
  2361. /* call arc gcc to compile assembly file to object file */
  2362. /* TODO: get arc gcc from environment variable firstly
  2363. and check whether the toolchain exists actually */
  2364. snprintf(buf, sizeof(buf), "%s%s%s%s%s%s",
  2365. "/opt/zephyr-sdk/arc-zephyr-elf/bin/arc-zephyr-elf-gcc ",
  2366. "-mcpu=arcem -o ", file_name, ".o -c ", file_name, ".s");
  2367. /* TODO: use try..catch to handle possible exceptions */
  2368. ret = system(buf);
  2369. /* remove temp assembly file */
  2370. snprintf(buf, sizeof(buf), "%s%s", file_name, ".s");
  2371. unlink(buf);
  2372. if (ret != 0) {
  2373. aot_set_last_error("failed to compile asm file to obj file "
  2374. "with arc gcc toolchain.");
  2375. goto fail;
  2376. }
  2377. /* create memory buffer from object file */
  2378. snprintf(buf, sizeof(buf), "%s%s", file_name, ".o");
  2379. ret = LLVMCreateMemoryBufferWithContentsOfFile(buf, &obj_data->mem_buf,
  2380. &err);
  2381. /* remove temp object file */
  2382. snprintf(buf, sizeof(buf), "%s%s", file_name, ".o");
  2383. unlink(buf);
  2384. if (ret != 0) {
  2385. if (err) {
  2386. LLVMDisposeMessage(err);
  2387. err = NULL;
  2388. }
  2389. aot_set_last_error("create mem buffer with file failed.");
  2390. goto fail;
  2391. }
  2392. #endif /* end of defined(_WIN32) || defined(_WIN32_) */
  2393. }
  2394. else {
  2395. if (LLVMTargetMachineEmitToMemoryBuffer(
  2396. comp_ctx->target_machine, comp_ctx->module, LLVMObjectFile,
  2397. &err, &obj_data->mem_buf)
  2398. != 0) {
  2399. if (err) {
  2400. LLVMDisposeMessage(err);
  2401. err = NULL;
  2402. }
  2403. aot_set_last_error("llvm emit to memory buffer failed.");
  2404. goto fail;
  2405. }
  2406. }
  2407. if (!(obj_data->binary = LLVMCreateBinary(obj_data->mem_buf, NULL, &err))) {
  2408. if (err) {
  2409. LLVMDisposeMessage(err);
  2410. err = NULL;
  2411. }
  2412. aot_set_last_error("llvm create binary failed.");
  2413. goto fail;
  2414. }
  2415. bh_print_time("Begin to resolve object file info");
  2416. /* resolve target info/text/relocations/functions */
  2417. if (!aot_resolve_target_info(comp_ctx, obj_data)
  2418. || !aot_resolve_text(obj_data) || !aot_resolve_literal(obj_data)
  2419. || !aot_resolve_object_data_sections(obj_data)
  2420. || !aot_resolve_object_relocation_groups(obj_data)
  2421. || !aot_resolve_functions(comp_ctx, obj_data))
  2422. goto fail;
  2423. return obj_data;
  2424. fail:
  2425. aot_obj_data_destroy(obj_data);
  2426. return NULL;
  2427. }
  2428. uint8 *
  2429. aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data,
  2430. uint32 *p_aot_file_size)
  2431. {
  2432. AOTObjectData *obj_data = aot_obj_data_create(comp_ctx);
  2433. uint8 *aot_file_buf, *buf, *buf_end;
  2434. uint32 aot_file_size, offset = 0;
  2435. if (!obj_data)
  2436. return NULL;
  2437. aot_file_size = get_aot_file_size(comp_ctx, comp_data, obj_data);
  2438. if (!(buf = aot_file_buf = wasm_runtime_malloc(aot_file_size))) {
  2439. aot_set_last_error("allocate memory failed.");
  2440. goto fail1;
  2441. }
  2442. memset(aot_file_buf, 0, aot_file_size);
  2443. buf_end = buf + aot_file_size;
  2444. if (!aot_emit_file_header(buf, buf_end, &offset, comp_data, obj_data)
  2445. || !aot_emit_target_info_section(buf, buf_end, &offset, comp_data,
  2446. obj_data)
  2447. || !aot_emit_init_data_section(buf, buf_end, &offset, comp_ctx,
  2448. comp_data, obj_data)
  2449. || !aot_emit_text_section(buf, buf_end, &offset, comp_data, obj_data)
  2450. || !aot_emit_func_section(buf, buf_end, &offset, comp_data, obj_data)
  2451. || !aot_emit_export_section(buf, buf_end, &offset, comp_ctx, comp_data,
  2452. obj_data)
  2453. || !aot_emit_relocation_section(buf, buf_end, &offset, comp_ctx,
  2454. comp_data, obj_data)
  2455. || !aot_emit_native_symbol(buf, buf_end, &offset, comp_ctx)
  2456. || !aot_emit_name_section(buf, buf_end, &offset, comp_data, comp_ctx)
  2457. || !aot_emit_custom_sections(buf, buf_end, &offset, comp_data,
  2458. comp_ctx))
  2459. goto fail2;
  2460. #if 0
  2461. dump_buf(buf, offset, "sections");
  2462. #endif
  2463. if (offset != aot_file_size) {
  2464. aot_set_last_error("emit aot file failed.");
  2465. goto fail2;
  2466. }
  2467. *p_aot_file_size = aot_file_size;
  2468. aot_obj_data_destroy(obj_data);
  2469. return aot_file_buf;
  2470. fail2:
  2471. wasm_runtime_free(aot_file_buf);
  2472. fail1:
  2473. aot_obj_data_destroy(obj_data);
  2474. return NULL;
  2475. }
  2476. bool
  2477. aot_emit_aot_file(AOTCompContext *comp_ctx, AOTCompData *comp_data,
  2478. const char *file_name)
  2479. {
  2480. uint8 *aot_file_buf;
  2481. uint32 aot_file_size;
  2482. bool ret = false;
  2483. FILE *file;
  2484. bh_print_time("Begin to emit AOT file");
  2485. if (!(aot_file_buf =
  2486. aot_emit_aot_file_buf(comp_ctx, comp_data, &aot_file_size))) {
  2487. return false;
  2488. }
  2489. /* write buffer to file */
  2490. if (!(file = fopen(file_name, "wb"))) {
  2491. aot_set_last_error("open or create aot file failed.");
  2492. goto fail1;
  2493. }
  2494. if (!fwrite(aot_file_buf, aot_file_size, 1, file)) {
  2495. aot_set_last_error("write to aot file failed.");
  2496. goto fail2;
  2497. }
  2498. ret = true;
  2499. fail2:
  2500. fclose(file);
  2501. fail1:
  2502. wasm_runtime_free(aot_file_buf);
  2503. return ret;
  2504. }