aot_loader.c 118 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "aot_runtime.h"
  6. #include "bh_common.h"
  7. #include "bh_log.h"
  8. #include "aot_reloc.h"
  9. #include "../common/wasm_runtime_common.h"
  10. #include "../common/wasm_native.h"
  11. #include "../compilation/aot.h"
  12. #if WASM_ENABLE_DEBUG_AOT != 0
  13. #include "debug/elf_parser.h"
  14. #include "debug/jit_debug.h"
  15. #endif
  16. #define YMM_PLT_PREFIX "__ymm@"
  17. #define XMM_PLT_PREFIX "__xmm@"
  18. #define REAL_PLT_PREFIX "__real@"
  19. static void
  20. set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
  21. {
  22. if (error_buf != NULL) {
  23. snprintf(error_buf, error_buf_size, "AOT module load failed: %s",
  24. string);
  25. }
  26. }
  27. static void
  28. set_error_buf_v(char *error_buf, uint32 error_buf_size, const char *format, ...)
  29. {
  30. va_list args;
  31. char buf[128];
  32. if (error_buf != NULL) {
  33. va_start(args, format);
  34. vsnprintf(buf, sizeof(buf), format, args);
  35. va_end(args);
  36. snprintf(error_buf, error_buf_size, "AOT module load failed: %s", buf);
  37. }
  38. }
  39. #define exchange_uint8(p_data) (void)0
  40. static void
  41. exchange_uint16(uint8 *p_data)
  42. {
  43. uint8 value = *p_data;
  44. *p_data = *(p_data + 1);
  45. *(p_data + 1) = value;
  46. }
  47. static void
  48. exchange_uint32(uint8 *p_data)
  49. {
  50. uint8 value = *p_data;
  51. *p_data = *(p_data + 3);
  52. *(p_data + 3) = value;
  53. value = *(p_data + 1);
  54. *(p_data + 1) = *(p_data + 2);
  55. *(p_data + 2) = value;
  56. }
  57. static void
  58. exchange_uint64(uint8 *pData)
  59. {
  60. uint32 value;
  61. value = *(uint32 *)pData;
  62. *(uint32 *)pData = *(uint32 *)(pData + 4);
  63. *(uint32 *)(pData + 4) = value;
  64. exchange_uint32(pData);
  65. exchange_uint32(pData + 4);
  66. }
  67. static union {
  68. int a;
  69. char b;
  70. } __ue = { .a = 1 };
  71. #define is_little_endian() (__ue.b == 1)
  72. static bool
  73. check_buf(const uint8 *buf, const uint8 *buf_end, uint32 length,
  74. char *error_buf, uint32 error_buf_size)
  75. {
  76. if ((uintptr_t)buf + length < (uintptr_t)buf
  77. || (uintptr_t)buf + length > (uintptr_t)buf_end) {
  78. set_error_buf(error_buf, error_buf_size, "unexpect end");
  79. return false;
  80. }
  81. return true;
  82. }
  83. #define CHECK_BUF(buf, buf_end, length) \
  84. do { \
  85. if (!check_buf(buf, buf_end, length, error_buf, error_buf_size)) { \
  86. goto fail; \
  87. } \
  88. } while (0)
  89. static uint8 *
  90. align_ptr(const uint8 *p, uint32 b)
  91. {
  92. uintptr_t v = (uintptr_t)p;
  93. uintptr_t m = b - 1;
  94. return (uint8 *)((v + m) & ~m);
  95. }
  96. static inline uint64
  97. GET_U64_FROM_ADDR(uint32 *addr)
  98. {
  99. union {
  100. uint64 val;
  101. uint32 parts[2];
  102. } u;
  103. u.parts[0] = addr[0];
  104. u.parts[1] = addr[1];
  105. return u.val;
  106. }
  107. #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
  108. static inline uint8
  109. GET_U8_FROM_ADDR(const uint8 *p)
  110. {
  111. uint8 res = 0;
  112. bh_assert(p);
  113. const uint8 *p_aligned = align_ptr(p, 4);
  114. p_aligned = (p_aligned > p) ? p_aligned - 4 : p_aligned;
  115. uint32 buf32 = *(const uint32 *)p_aligned;
  116. const uint8 *pbuf = (const uint8 *)&buf32;
  117. res = *(uint8 *)(pbuf + (p - p_aligned));
  118. return res;
  119. }
  120. static inline uint16
  121. GET_U16_FROM_ADDR(const uint8 *p)
  122. {
  123. uint16 res = 0;
  124. bh_assert(p);
  125. const uint8 *p_aligned = align_ptr(p, 4);
  126. p_aligned = (p_aligned > p) ? p_aligned - 4 : p_aligned;
  127. uint32 buf32 = *(const uint32 *)p_aligned;
  128. const uint8 *pbuf = (const uint8 *)&buf32;
  129. res = *(uint16 *)(pbuf + (p - p_aligned));
  130. return res;
  131. }
  132. #define TEMPLATE_READ(p, p_end, res, type) \
  133. do { \
  134. if (sizeof(type) != sizeof(uint64)) \
  135. p = (uint8 *)align_ptr(p, sizeof(type)); \
  136. else \
  137. /* align 4 bytes if type is uint64 */ \
  138. p = (uint8 *)align_ptr(p, sizeof(uint32)); \
  139. CHECK_BUF(p, p_end, sizeof(type)); \
  140. if (sizeof(type) == sizeof(uint8)) \
  141. res = GET_U8_FROM_ADDR(p); \
  142. else if (sizeof(type) == sizeof(uint16)) \
  143. res = GET_U16_FROM_ADDR(p); \
  144. else if (sizeof(type) == sizeof(uint32)) \
  145. res = *(type *)p; \
  146. else \
  147. res = (type)GET_U64_FROM_ADDR((uint32 *)p); \
  148. if (!is_little_endian()) \
  149. exchange_##type((uint8 *)&res); \
  150. p += sizeof(type); \
  151. } while (0)
  152. #define read_byte_array(p, p_end, addr, len) \
  153. do { \
  154. CHECK_BUF(p, p_end, len); \
  155. bh_memcpy_wa(addr, len, p, len); \
  156. p += len; \
  157. } while (0)
  158. #define read_string(p, p_end, str) \
  159. do { \
  160. if (!(str = load_string((uint8 **)&p, p_end, module, \
  161. is_load_from_file_buf, true, error_buf, \
  162. error_buf_size))) \
  163. goto fail; \
  164. } while (0)
  165. #else /* else of (WASM_ENABLE_WORD_ALIGN_READ != 0) */
  166. #define TEMPLATE_READ(p, p_end, res, type) \
  167. do { \
  168. if (sizeof(type) != sizeof(uint64)) \
  169. p = (uint8 *)align_ptr(p, sizeof(type)); \
  170. else \
  171. /* align 4 bytes if type is uint64 */ \
  172. p = (uint8 *)align_ptr(p, sizeof(uint32)); \
  173. CHECK_BUF(p, p_end, sizeof(type)); \
  174. if (sizeof(type) != sizeof(uint64)) \
  175. res = *(type *)p; \
  176. else \
  177. res = (type)GET_U64_FROM_ADDR((uint32 *)p); \
  178. if (!is_little_endian()) \
  179. exchange_##type((uint8 *)&res); \
  180. p += sizeof(type); \
  181. } while (0)
  182. #define read_byte_array(p, p_end, addr, len) \
  183. do { \
  184. CHECK_BUF(p, p_end, len); \
  185. bh_memcpy_s(addr, len, p, len); \
  186. p += len; \
  187. } while (0)
  188. #define read_string(p, p_end, str) \
  189. do { \
  190. if (!(str = load_string((uint8 **)&p, p_end, module, \
  191. is_load_from_file_buf, error_buf, \
  192. error_buf_size))) \
  193. goto fail; \
  194. } while (0)
  195. #endif /* end of (WASM_ENABLE_WORD_ALIGN_READ != 0) */
  196. #define read_uint8(p, p_end, res) TEMPLATE_READ(p, p_end, res, uint8)
  197. #define read_uint16(p, p_end, res) TEMPLATE_READ(p, p_end, res, uint16)
  198. #define read_uint32(p, p_end, res) TEMPLATE_READ(p, p_end, res, uint32)
  199. #define read_uint64(p, p_end, res) TEMPLATE_READ(p, p_end, res, uint64)
  200. /* Legal values for bin_type */
  201. #define BIN_TYPE_ELF32L 0 /* 32-bit little endian */
  202. #define BIN_TYPE_ELF32B 1 /* 32-bit big endian */
  203. #define BIN_TYPE_ELF64L 2 /* 64-bit little endian */
  204. #define BIN_TYPE_ELF64B 3 /* 64-bit big endian */
  205. #define BIN_TYPE_COFF32 4 /* 32-bit little endian */
  206. #define BIN_TYPE_COFF64 6 /* 64-bit little endian */
  207. /* Legal values for e_type (object file type). */
  208. #define E_TYPE_NONE 0 /* No file type */
  209. #define E_TYPE_REL 1 /* Relocatable file */
  210. #define E_TYPE_EXEC 2 /* Executable file */
  211. #define E_TYPE_DYN 3 /* Shared object file */
  212. #define E_TYPE_XIP 4 /* eXecute In Place file */
  213. /* Legal values for e_machine (architecture). */
  214. #define E_MACHINE_386 3 /* Intel 80386 */
  215. #define E_MACHINE_MIPS 8 /* MIPS R3000 big-endian */
  216. #define E_MACHINE_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
  217. #define E_MACHINE_ARM 40 /* ARM/Thumb */
  218. #define E_MACHINE_AARCH64 183 /* AArch64 */
  219. #define E_MACHINE_ARC 45 /* Argonaut RISC Core */
  220. #define E_MACHINE_IA_64 50 /* Intel Merced */
  221. #define E_MACHINE_MIPS_X 51 /* Stanford MIPS-X */
  222. #define E_MACHINE_X86_64 62 /* AMD x86-64 architecture */
  223. #define E_MACHINE_ARC_COMPACT 93 /* ARC International ARCompact */
  224. #define E_MACHINE_ARC_COMPACT2 195 /* Synopsys ARCompact V2 */
  225. #define E_MACHINE_XTENSA 94 /* Tensilica Xtensa Architecture */
  226. #define E_MACHINE_RISCV 243 /* RISC-V 32/64 */
  227. #define E_MACHINE_WIN_I386 0x14c /* Windows i386 architecture */
  228. #define E_MACHINE_WIN_X86_64 0x8664 /* Windows x86-64 architecture */
  229. /* Legal values for e_version */
  230. #define E_VERSION_CURRENT 1 /* Current version */
  231. static void *
  232. loader_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
  233. {
  234. void *mem;
  235. if (size >= UINT32_MAX || !(mem = wasm_runtime_malloc((uint32)size))) {
  236. set_error_buf(error_buf, error_buf_size, "allocate memory failed");
  237. return NULL;
  238. }
  239. memset(mem, 0, (uint32)size);
  240. return mem;
  241. }
  242. static char *
  243. const_str_set_insert(const uint8 *str, int32 len, AOTModule *module,
  244. #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
  245. bool is_vram_word_align,
  246. #endif
  247. char *error_buf, uint32 error_buf_size)
  248. {
  249. HashMap *set = module->const_str_set;
  250. char *c_str, *value;
  251. /* Create const string set if it isn't created */
  252. if (!set
  253. && !(set = module->const_str_set = bh_hash_map_create(
  254. 32, false, (HashFunc)wasm_string_hash,
  255. (KeyEqualFunc)wasm_string_equal, NULL, wasm_runtime_free))) {
  256. set_error_buf(error_buf, error_buf_size,
  257. "create const string set failed");
  258. return NULL;
  259. }
  260. /* Lookup const string set, use the string if found */
  261. if (!(c_str = loader_malloc((uint32)len + 1, error_buf, error_buf_size))) {
  262. return NULL;
  263. }
  264. #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
  265. if (is_vram_word_align) {
  266. bh_memcpy_wa(c_str, (uint32)(len + 1), str, (uint32)len);
  267. }
  268. else
  269. #endif
  270. {
  271. bh_memcpy_s(c_str, (uint32)(len + 1), str, (uint32)len);
  272. }
  273. c_str[len] = '\0';
  274. if ((value = bh_hash_map_find(set, c_str))) {
  275. wasm_runtime_free(c_str);
  276. return value;
  277. }
  278. if (!bh_hash_map_insert(set, c_str, c_str)) {
  279. set_error_buf(error_buf, error_buf_size,
  280. "insert string to hash map failed");
  281. wasm_runtime_free(c_str);
  282. return NULL;
  283. }
  284. return c_str;
  285. }
  286. static char *
  287. load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  288. bool is_load_from_file_buf,
  289. #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
  290. bool is_vram_word_align,
  291. #endif
  292. char *error_buf, uint32 error_buf_size)
  293. {
  294. uint8 *p = *p_buf;
  295. const uint8 *p_end = buf_end;
  296. char *str;
  297. uint16 str_len;
  298. read_uint16(p, p_end, str_len);
  299. CHECK_BUF(p, p_end, str_len);
  300. if (str_len == 0) {
  301. str = "";
  302. }
  303. #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
  304. else if (is_vram_word_align) {
  305. if (!(str = const_str_set_insert((uint8 *)p, str_len, module,
  306. is_vram_word_align, error_buf,
  307. error_buf_size))) {
  308. goto fail;
  309. }
  310. }
  311. #endif
  312. else if (p[str_len - 1] == '\0') {
  313. /* The string is terminated with '\0', use it directly */
  314. str = (char *)p;
  315. }
  316. else if (is_load_from_file_buf) {
  317. /* As the file buffer can be referred to after loading,
  318. we use the 2 bytes of size to adjust the string:
  319. move string 2 byte backward and then append '\0' */
  320. str = (char *)(p - 2);
  321. bh_memmove_s(str, (uint32)(str_len + 1), p, (uint32)str_len);
  322. str[str_len] = '\0';
  323. }
  324. else {
  325. /* Load from sections, the file buffer cannot be reffered to
  326. after loading, we must create another string and insert it
  327. into const string set */
  328. if (!(str = const_str_set_insert((uint8 *)p, str_len, module,
  329. #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
  330. is_vram_word_align,
  331. #endif
  332. error_buf, error_buf_size))) {
  333. goto fail;
  334. }
  335. }
  336. p += str_len;
  337. *p_buf = p;
  338. return str;
  339. fail:
  340. return NULL;
  341. }
  342. static bool
  343. get_aot_file_target(AOTTargetInfo *target_info, char *target_buf,
  344. uint32 target_buf_size, char *error_buf,
  345. uint32 error_buf_size)
  346. {
  347. char *machine_type = NULL;
  348. switch (target_info->e_machine) {
  349. case E_MACHINE_X86_64:
  350. case E_MACHINE_WIN_X86_64:
  351. machine_type = "x86_64";
  352. break;
  353. case E_MACHINE_386:
  354. case E_MACHINE_WIN_I386:
  355. machine_type = "i386";
  356. break;
  357. case E_MACHINE_ARM:
  358. case E_MACHINE_AARCH64:
  359. machine_type = target_info->arch;
  360. break;
  361. case E_MACHINE_MIPS:
  362. machine_type = "mips";
  363. break;
  364. case E_MACHINE_XTENSA:
  365. machine_type = "xtensa";
  366. break;
  367. case E_MACHINE_RISCV:
  368. machine_type = "riscv";
  369. break;
  370. case E_MACHINE_ARC_COMPACT:
  371. case E_MACHINE_ARC_COMPACT2:
  372. machine_type = "arc";
  373. break;
  374. default:
  375. set_error_buf_v(error_buf, error_buf_size,
  376. "unknown machine type %d", target_info->e_machine);
  377. return false;
  378. }
  379. if (strncmp(target_info->arch, machine_type, strlen(machine_type))) {
  380. set_error_buf_v(
  381. error_buf, error_buf_size,
  382. "machine type (%s) isn't consistent with target type (%s)",
  383. machine_type, target_info->arch);
  384. return false;
  385. }
  386. snprintf(target_buf, target_buf_size, "%s", target_info->arch);
  387. return true;
  388. }
  389. static bool
  390. check_machine_info(AOTTargetInfo *target_info, char *error_buf,
  391. uint32 error_buf_size)
  392. {
  393. char target_expected[32], target_got[32];
  394. get_current_target(target_expected, sizeof(target_expected));
  395. if (!get_aot_file_target(target_info, target_got, sizeof(target_got),
  396. error_buf, error_buf_size))
  397. return false;
  398. if (strncmp(target_expected, target_got, strlen(target_expected))) {
  399. set_error_buf_v(error_buf, error_buf_size,
  400. "invalid target type, expected %s but got %s",
  401. target_expected, target_got);
  402. return false;
  403. }
  404. return true;
  405. }
  406. static bool
  407. load_target_info_section(const uint8 *buf, const uint8 *buf_end,
  408. AOTModule *module, char *error_buf,
  409. uint32 error_buf_size)
  410. {
  411. AOTTargetInfo target_info;
  412. const uint8 *p = buf, *p_end = buf_end;
  413. bool is_target_little_endian, is_target_64_bit;
  414. read_uint16(p, p_end, target_info.bin_type);
  415. read_uint16(p, p_end, target_info.abi_type);
  416. read_uint16(p, p_end, target_info.e_type);
  417. read_uint16(p, p_end, target_info.e_machine);
  418. read_uint32(p, p_end, target_info.e_version);
  419. read_uint32(p, p_end, target_info.e_flags);
  420. read_uint32(p, p_end, target_info.reserved);
  421. read_byte_array(p, p_end, target_info.arch, sizeof(target_info.arch));
  422. if (p != buf_end) {
  423. set_error_buf(error_buf, error_buf_size, "invalid section size");
  424. return false;
  425. }
  426. /* Check target endian type */
  427. is_target_little_endian = target_info.bin_type & 1 ? false : true;
  428. if (is_little_endian() != is_target_little_endian) {
  429. set_error_buf_v(error_buf, error_buf_size,
  430. "invalid target endian type, expected %s but got %s",
  431. is_little_endian() ? "little endian" : "big endian",
  432. is_target_little_endian ? "little endian"
  433. : "big endian");
  434. return false;
  435. }
  436. /* Check target bit width */
  437. is_target_64_bit = target_info.bin_type & 2 ? true : false;
  438. if ((sizeof(void *) == 8 ? true : false) != is_target_64_bit) {
  439. set_error_buf_v(error_buf, error_buf_size,
  440. "invalid target bit width, expected %s but got %s",
  441. sizeof(void *) == 8 ? "64-bit" : "32-bit",
  442. is_target_64_bit ? "64-bit" : "32-bit");
  443. return false;
  444. }
  445. /* Check target elf file type */
  446. if (target_info.e_type != E_TYPE_REL && target_info.e_type != E_TYPE_XIP) {
  447. set_error_buf(error_buf, error_buf_size,
  448. "invalid object file type, "
  449. "expected relocatable or XIP file type but got others");
  450. return false;
  451. }
  452. /* Check machine info */
  453. if (!check_machine_info(&target_info, error_buf, error_buf_size)) {
  454. return false;
  455. }
  456. if (target_info.e_version != E_VERSION_CURRENT) {
  457. set_error_buf(error_buf, error_buf_size, "invalid elf file version");
  458. return false;
  459. }
  460. return true;
  461. fail:
  462. return false;
  463. }
  464. static void *
  465. get_native_symbol_by_name(const char *name)
  466. {
  467. void *func = NULL;
  468. uint32 symnum = 0;
  469. SymbolMap *sym = NULL;
  470. sym = get_target_symbol_map(&symnum);
  471. while (symnum--) {
  472. if (strcmp(sym->symbol_name, name) == 0) {
  473. func = sym->symbol_addr;
  474. break;
  475. }
  476. sym++;
  477. }
  478. return func;
  479. }
  480. static bool
  481. str2uint32(const char *buf, uint32 *p_res);
  482. static bool
  483. str2uint64(const char *buf, uint64 *p_res);
  484. #if WASM_ENABLE_MULTI_MODULE != 0
  485. static void *
  486. aot_loader_resolve_function(const char *module_name, const char *function_name,
  487. const AOTFuncType *expected_function_type,
  488. char *error_buf, uint32 error_buf_size)
  489. {
  490. WASMModuleCommon *module_reg;
  491. void *function = NULL;
  492. AOTExport *export = NULL;
  493. AOTModule *module = NULL;
  494. AOTFuncType *target_function_type = NULL;
  495. module_reg = wasm_runtime_find_module_registered(module_name);
  496. if (!module_reg || module_reg->module_type != Wasm_Module_AoT) {
  497. LOG_DEBUG("can not find a module named %s for function %s", module_name,
  498. function_name);
  499. set_error_buf(error_buf, error_buf_size, "unknown import");
  500. return NULL;
  501. }
  502. module = (AOTModule *)module_reg;
  503. export = loader_find_export(module_reg, module_name, function_name,
  504. EXPORT_KIND_FUNC, error_buf, error_buf_size);
  505. if (!export) {
  506. return NULL;
  507. }
  508. /* resolve function type and function */
  509. if (export->index < module->import_func_count) {
  510. target_function_type = module->import_funcs[export->index].func_type;
  511. function = module->import_funcs[export->index].func_ptr_linked;
  512. }
  513. else {
  514. target_function_type =
  515. module->func_types[module->func_type_indexes
  516. [export->index - module->import_func_count]];
  517. function =
  518. (module->func_ptrs[export->index - module->import_func_count]);
  519. }
  520. /* check function type */
  521. if (!wasm_type_equal(expected_function_type, target_function_type)) {
  522. LOG_DEBUG("%s.%s failed the type check", module_name, function_name);
  523. set_error_buf(error_buf, error_buf_size, "incompatible import type");
  524. return NULL;
  525. }
  526. return function;
  527. }
  528. #endif /* end of WASM_ENABLE_MULTI_MODULE */
  529. static bool
  530. load_native_symbol_section(const uint8 *buf, const uint8 *buf_end,
  531. AOTModule *module, bool is_load_from_file_buf,
  532. char *error_buf, uint32 error_buf_size)
  533. {
  534. const uint8 *p = buf, *p_end = buf_end;
  535. uint32 cnt;
  536. int32 i;
  537. const char *symbol;
  538. read_uint32(p, p_end, cnt);
  539. if (cnt > 0) {
  540. module->native_symbol_list = wasm_runtime_malloc(cnt * sizeof(void *));
  541. if (module->native_symbol_list == NULL) {
  542. set_error_buf(error_buf, error_buf_size,
  543. "malloc native symbol list failed");
  544. goto fail;
  545. }
  546. for (i = cnt - 1; i >= 0; i--) {
  547. read_string(p, p_end, symbol);
  548. if (!strncmp(symbol, "f32#", 4) || !strncmp(symbol, "i32#", 4)) {
  549. uint32 u32;
  550. /* Resolve the raw int bits of f32 const */
  551. if (!str2uint32(symbol + 4, &u32)) {
  552. set_error_buf_v(error_buf, error_buf_size,
  553. "resolve symbol %s failed", symbol);
  554. goto fail;
  555. }
  556. *(uint32 *)(&module->native_symbol_list[i]) = u32;
  557. }
  558. else if (!strncmp(symbol, "f64#", 4)
  559. || !strncmp(symbol, "i64#", 4)) {
  560. uint64 u64;
  561. /* Resolve the raw int bits of f64 const */
  562. if (!str2uint64(symbol + 4, &u64)) {
  563. set_error_buf_v(error_buf, error_buf_size,
  564. "resolve symbol %s failed", symbol);
  565. goto fail;
  566. }
  567. *(uint64 *)(&module->native_symbol_list[i]) = u64;
  568. }
  569. else if (!strncmp(symbol, "__ignore", 8)) {
  570. /* Padding bytes to make f64 on 8-byte aligned address,
  571. or it is the second 32-bit slot in 32-bit system */
  572. continue;
  573. }
  574. else {
  575. module->native_symbol_list[i] =
  576. get_native_symbol_by_name(symbol);
  577. if (module->native_symbol_list[i] == NULL) {
  578. set_error_buf_v(error_buf, error_buf_size,
  579. "missing native symbol: %s", symbol);
  580. goto fail;
  581. }
  582. }
  583. }
  584. }
  585. return true;
  586. fail:
  587. return false;
  588. }
  589. static bool
  590. load_name_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
  591. bool is_load_from_file_buf, char *error_buf,
  592. uint32 error_buf_size)
  593. {
  594. #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
  595. const uint8 *p = buf, *p_end = buf_end;
  596. uint32 *aux_func_indexes;
  597. const char **aux_func_names;
  598. uint32 name_type, subsection_size;
  599. uint32 previous_name_type = 0;
  600. uint32 num_func_name;
  601. uint32 func_index;
  602. uint32 previous_func_index = ~0U;
  603. uint32 name_index;
  604. int i = 0;
  605. uint32 name_len;
  606. uint64 size;
  607. if (p >= p_end) {
  608. set_error_buf(error_buf, error_buf_size, "unexpected end");
  609. return false;
  610. }
  611. read_uint32(p, p_end, name_len);
  612. if (name_len != 4 || p + name_len > p_end) {
  613. set_error_buf(error_buf, error_buf_size, "unexpected end");
  614. return false;
  615. }
  616. if (memcmp(p, "name", 4) != 0) {
  617. set_error_buf(error_buf, error_buf_size, "invalid custom name section");
  618. return false;
  619. }
  620. p += name_len;
  621. while (p < p_end) {
  622. read_uint32(p, p_end, name_type);
  623. if (i != 0) {
  624. if (name_type == previous_name_type) {
  625. set_error_buf(error_buf, error_buf_size,
  626. "duplicate sub-section");
  627. return false;
  628. }
  629. if (name_type < previous_name_type) {
  630. set_error_buf(error_buf, error_buf_size,
  631. "out-of-order sub-section");
  632. return false;
  633. }
  634. }
  635. previous_name_type = name_type;
  636. read_uint32(p, p_end, subsection_size);
  637. CHECK_BUF(p, p_end, subsection_size);
  638. switch (name_type) {
  639. case SUB_SECTION_TYPE_FUNC:
  640. if (subsection_size) {
  641. read_uint32(p, p_end, num_func_name);
  642. if (num_func_name
  643. > module->import_func_count + module->func_count) {
  644. set_error_buf(error_buf, error_buf_size,
  645. "function name count out of bounds");
  646. return false;
  647. }
  648. module->aux_func_name_count = num_func_name;
  649. /* Allocate memory */
  650. size = sizeof(uint32) * (uint64)module->aux_func_name_count;
  651. if (!(aux_func_indexes = module->aux_func_indexes =
  652. loader_malloc(size, error_buf, error_buf_size))) {
  653. return false;
  654. }
  655. size =
  656. sizeof(char **) * (uint64)module->aux_func_name_count;
  657. if (!(aux_func_names = module->aux_func_names =
  658. loader_malloc(size, error_buf, error_buf_size))) {
  659. return false;
  660. }
  661. for (name_index = 0; name_index < num_func_name;
  662. name_index++) {
  663. read_uint32(p, p_end, func_index);
  664. if (name_index != 0
  665. && func_index == previous_func_index) {
  666. set_error_buf(error_buf, error_buf_size,
  667. "duplicate function name");
  668. return false;
  669. }
  670. if (name_index != 0
  671. && func_index < previous_func_index) {
  672. set_error_buf(error_buf, error_buf_size,
  673. "out-of-order function index ");
  674. return false;
  675. }
  676. if (func_index
  677. >= module->import_func_count + module->func_count) {
  678. set_error_buf(error_buf, error_buf_size,
  679. "function index out of bounds");
  680. return false;
  681. }
  682. previous_func_index = func_index;
  683. *(aux_func_indexes + name_index) = func_index;
  684. read_string(p, p_end, *(aux_func_names + name_index));
  685. #if 0
  686. LOG_DEBUG("func_index %u -> aux_func_name = %s\n",
  687. func_index, *(aux_func_names + name_index));
  688. #endif
  689. }
  690. }
  691. break;
  692. case SUB_SECTION_TYPE_MODULE: /* TODO: Parse for module subsection
  693. */
  694. case SUB_SECTION_TYPE_LOCAL: /* TODO: Parse for local subsection */
  695. default:
  696. p = p + subsection_size;
  697. break;
  698. }
  699. i++;
  700. }
  701. return true;
  702. fail:
  703. return false;
  704. #else
  705. return true;
  706. #endif /* WASM_ENABLE_CUSTOM_NAME_SECTION != 0 */
  707. }
  708. static bool
  709. load_custom_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
  710. bool is_load_from_file_buf, char *error_buf,
  711. uint32 error_buf_size)
  712. {
  713. const uint8 *p = buf, *p_end = buf_end;
  714. uint32 sub_section_type;
  715. read_uint32(p, p_end, sub_section_type);
  716. buf = p;
  717. switch (sub_section_type) {
  718. case AOT_CUSTOM_SECTION_NATIVE_SYMBOL:
  719. if (!load_native_symbol_section(buf, buf_end, module,
  720. is_load_from_file_buf, error_buf,
  721. error_buf_size))
  722. goto fail;
  723. break;
  724. case AOT_CUSTOM_SECTION_NAME:
  725. if (!load_name_section(buf, buf_end, module, is_load_from_file_buf,
  726. error_buf, error_buf_size))
  727. LOG_VERBOSE("Load name section failed.");
  728. else
  729. LOG_VERBOSE("Load name section success.");
  730. break;
  731. #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
  732. case AOT_CUSTOM_SECTION_RAW:
  733. {
  734. const char *section_name;
  735. WASMCustomSection *section;
  736. if (p >= p_end) {
  737. set_error_buf(error_buf, error_buf_size, "unexpected end");
  738. goto fail;
  739. }
  740. read_string(p, p_end, section_name);
  741. section = loader_malloc(sizeof(WASMCustomSection), error_buf,
  742. error_buf_size);
  743. if (!section) {
  744. goto fail;
  745. }
  746. section->name_addr = (char *)section_name;
  747. section->name_len = (uint32)strlen(section_name);
  748. section->content_addr = (uint8 *)p;
  749. section->content_len = (uint32)(p_end - p);
  750. section->next = module->custom_section_list;
  751. module->custom_section_list = section;
  752. LOG_VERBOSE("Load custom section [%s] success.", section_name);
  753. break;
  754. }
  755. #endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */
  756. default:
  757. break;
  758. }
  759. return true;
  760. fail:
  761. return false;
  762. }
  763. static void
  764. destroy_import_memories(AOTImportMemory *import_memories)
  765. {
  766. wasm_runtime_free(import_memories);
  767. }
  768. static void
  769. destroy_mem_init_data_list(AOTMemInitData **data_list, uint32 count)
  770. {
  771. uint32 i;
  772. for (i = 0; i < count; i++)
  773. if (data_list[i])
  774. wasm_runtime_free(data_list[i]);
  775. wasm_runtime_free(data_list);
  776. }
  777. static bool
  778. load_mem_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
  779. AOTModule *module, char *error_buf,
  780. uint32 error_buf_size)
  781. {
  782. const uint8 *buf = *p_buf;
  783. AOTMemInitData **data_list;
  784. uint64 size;
  785. uint32 i;
  786. /* Allocate memory */
  787. size = sizeof(AOTMemInitData *) * (uint64)module->mem_init_data_count;
  788. if (!(module->mem_init_data_list = data_list =
  789. loader_malloc(size, error_buf, error_buf_size))) {
  790. return false;
  791. }
  792. /* Create each memory data segment */
  793. for (i = 0; i < module->mem_init_data_count; i++) {
  794. uint32 init_expr_type, byte_count;
  795. uint64 init_expr_value;
  796. uint32 is_passive;
  797. uint32 memory_index;
  798. read_uint32(buf, buf_end, is_passive);
  799. read_uint32(buf, buf_end, memory_index);
  800. read_uint32(buf, buf_end, init_expr_type);
  801. read_uint64(buf, buf_end, init_expr_value);
  802. read_uint32(buf, buf_end, byte_count);
  803. size = offsetof(AOTMemInitData, bytes) + (uint64)byte_count;
  804. if (!(data_list[i] = loader_malloc(size, error_buf, error_buf_size))) {
  805. return false;
  806. }
  807. #if WASM_ENABLE_BULK_MEMORY != 0
  808. /* is_passive and memory_index is only used in bulk memory mode */
  809. data_list[i]->is_passive = (bool)is_passive;
  810. data_list[i]->memory_index = memory_index;
  811. #endif
  812. data_list[i]->offset.init_expr_type = (uint8)init_expr_type;
  813. data_list[i]->offset.u.i64 = (int64)init_expr_value;
  814. data_list[i]->byte_count = byte_count;
  815. read_byte_array(buf, buf_end, data_list[i]->bytes,
  816. data_list[i]->byte_count);
  817. }
  818. *p_buf = buf;
  819. return true;
  820. fail:
  821. return false;
  822. }
  823. static bool
  824. load_memory_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  825. char *error_buf, uint32 error_buf_size)
  826. {
  827. uint32 i;
  828. uint64 total_size;
  829. const uint8 *buf = *p_buf;
  830. read_uint32(buf, buf_end, module->import_memory_count);
  831. /* We don't support import_memory_count > 0 currently */
  832. bh_assert(module->import_memory_count == 0);
  833. read_uint32(buf, buf_end, module->memory_count);
  834. total_size = sizeof(AOTMemory) * (uint64)module->memory_count;
  835. if (!(module->memories =
  836. loader_malloc(total_size, error_buf, error_buf_size))) {
  837. return false;
  838. }
  839. for (i = 0; i < module->memory_count; i++) {
  840. read_uint32(buf, buf_end, module->memories[i].memory_flags);
  841. read_uint32(buf, buf_end, module->memories[i].num_bytes_per_page);
  842. read_uint32(buf, buf_end, module->memories[i].mem_init_page_count);
  843. read_uint32(buf, buf_end, module->memories[i].mem_max_page_count);
  844. }
  845. read_uint32(buf, buf_end, module->mem_init_data_count);
  846. /* load memory init data list */
  847. if (module->mem_init_data_count > 0
  848. && !load_mem_init_data_list(&buf, buf_end, module, error_buf,
  849. error_buf_size))
  850. return false;
  851. *p_buf = buf;
  852. return true;
  853. fail:
  854. return false;
  855. }
  856. static void
  857. destroy_import_tables(AOTImportTable *import_tables)
  858. {
  859. wasm_runtime_free(import_tables);
  860. }
  861. static void
  862. destroy_tables(AOTTable *tables)
  863. {
  864. wasm_runtime_free(tables);
  865. }
  866. static void
  867. destroy_table_init_data_list(AOTTableInitData **data_list, uint32 count)
  868. {
  869. uint32 i;
  870. for (i = 0; i < count; i++)
  871. if (data_list[i])
  872. wasm_runtime_free(data_list[i]);
  873. wasm_runtime_free(data_list);
  874. }
  875. static bool
  876. load_import_table_list(const uint8 **p_buf, const uint8 *buf_end,
  877. AOTModule *module, char *error_buf,
  878. uint32 error_buf_size)
  879. {
  880. const uint8 *buf = *p_buf;
  881. AOTImportTable *import_table;
  882. uint64 size;
  883. uint32 i, possible_grow;
  884. /* Allocate memory */
  885. size = sizeof(AOTImportTable) * (uint64)module->import_table_count;
  886. if (!(module->import_tables = import_table =
  887. loader_malloc(size, error_buf, error_buf_size))) {
  888. return false;
  889. }
  890. /* keep sync with aot_emit_table_info() aot_emit_aot_file */
  891. for (i = 0; i < module->import_table_count; i++, import_table++) {
  892. read_uint32(buf, buf_end, import_table->elem_type);
  893. read_uint32(buf, buf_end, import_table->table_init_size);
  894. read_uint32(buf, buf_end, import_table->table_max_size);
  895. read_uint32(buf, buf_end, possible_grow);
  896. import_table->possible_grow = (possible_grow & 0x1);
  897. }
  898. *p_buf = buf;
  899. return true;
  900. fail:
  901. return false;
  902. }
  903. static bool
  904. load_table_list(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  905. char *error_buf, uint32 error_buf_size)
  906. {
  907. const uint8 *buf = *p_buf;
  908. AOTTable *table;
  909. uint64 size;
  910. uint32 i, possible_grow;
  911. /* Allocate memory */
  912. size = sizeof(AOTTable) * (uint64)module->table_count;
  913. if (!(module->tables = table =
  914. loader_malloc(size, error_buf, error_buf_size))) {
  915. return false;
  916. }
  917. /* Create each table data segment */
  918. for (i = 0; i < module->table_count; i++, table++) {
  919. read_uint32(buf, buf_end, table->elem_type);
  920. read_uint32(buf, buf_end, table->table_flags);
  921. read_uint32(buf, buf_end, table->table_init_size);
  922. read_uint32(buf, buf_end, table->table_max_size);
  923. read_uint32(buf, buf_end, possible_grow);
  924. table->possible_grow = (possible_grow & 0x1);
  925. }
  926. *p_buf = buf;
  927. return true;
  928. fail:
  929. return false;
  930. }
  931. static bool
  932. load_table_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
  933. AOTModule *module, char *error_buf,
  934. uint32 error_buf_size)
  935. {
  936. const uint8 *buf = *p_buf;
  937. AOTTableInitData **data_list;
  938. uint64 size;
  939. uint32 i;
  940. /* Allocate memory */
  941. size = sizeof(AOTTableInitData *) * (uint64)module->table_init_data_count;
  942. if (!(module->table_init_data_list = data_list =
  943. loader_malloc(size, error_buf, error_buf_size))) {
  944. return false;
  945. }
  946. /* Create each table data segment */
  947. for (i = 0; i < module->table_init_data_count; i++) {
  948. uint32 mode, elem_type;
  949. uint32 table_index, init_expr_type, func_index_count;
  950. uint64 init_expr_value, size1;
  951. read_uint32(buf, buf_end, mode);
  952. read_uint32(buf, buf_end, elem_type);
  953. read_uint32(buf, buf_end, table_index);
  954. read_uint32(buf, buf_end, init_expr_type);
  955. read_uint64(buf, buf_end, init_expr_value);
  956. read_uint32(buf, buf_end, func_index_count);
  957. size1 = sizeof(uint32) * (uint64)func_index_count;
  958. size = offsetof(AOTTableInitData, func_indexes) + size1;
  959. if (!(data_list[i] = loader_malloc(size, error_buf, error_buf_size))) {
  960. return false;
  961. }
  962. data_list[i]->mode = mode;
  963. data_list[i]->elem_type = elem_type;
  964. data_list[i]->table_index = table_index;
  965. data_list[i]->offset.init_expr_type = (uint8)init_expr_type;
  966. data_list[i]->offset.u.i64 = (int64)init_expr_value;
  967. data_list[i]->func_index_count = func_index_count;
  968. read_byte_array(buf, buf_end, data_list[i]->func_indexes,
  969. (uint32)size1);
  970. }
  971. *p_buf = buf;
  972. return true;
  973. fail:
  974. return false;
  975. }
  976. static bool
  977. load_table_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  978. char *error_buf, uint32 error_buf_size)
  979. {
  980. const uint8 *buf = *p_buf;
  981. read_uint32(buf, buf_end, module->import_table_count);
  982. if (module->import_table_count > 0
  983. && !load_import_table_list(&buf, buf_end, module, error_buf,
  984. error_buf_size))
  985. return false;
  986. read_uint32(buf, buf_end, module->table_count);
  987. if (module->table_count > 0
  988. && !load_table_list(&buf, buf_end, module, error_buf, error_buf_size))
  989. return false;
  990. read_uint32(buf, buf_end, module->table_init_data_count);
  991. /* load table init data list */
  992. if (module->table_init_data_count > 0
  993. && !load_table_init_data_list(&buf, buf_end, module, error_buf,
  994. error_buf_size))
  995. return false;
  996. *p_buf = buf;
  997. return true;
  998. fail:
  999. return false;
  1000. }
  1001. static void
  1002. destroy_func_types(AOTFuncType **func_types, uint32 count)
  1003. {
  1004. uint32 i;
  1005. for (i = 0; i < count; i++)
  1006. if (func_types[i])
  1007. wasm_runtime_free(func_types[i]);
  1008. wasm_runtime_free(func_types);
  1009. }
  1010. static bool
  1011. load_func_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  1012. char *error_buf, uint32 error_buf_size)
  1013. {
  1014. const uint8 *buf = *p_buf;
  1015. AOTFuncType **func_types;
  1016. uint64 size;
  1017. uint32 i;
  1018. /* Allocate memory */
  1019. size = sizeof(AOTFuncType *) * (uint64)module->func_type_count;
  1020. if (!(module->func_types = func_types =
  1021. loader_malloc(size, error_buf, error_buf_size))) {
  1022. return false;
  1023. }
  1024. /* Create each function type */
  1025. for (i = 0; i < module->func_type_count; i++) {
  1026. uint32 param_count, result_count;
  1027. uint32 param_cell_num, ret_cell_num;
  1028. uint64 size1;
  1029. read_uint32(buf, buf_end, param_count);
  1030. read_uint32(buf, buf_end, result_count);
  1031. if (param_count > UINT16_MAX || result_count > UINT16_MAX) {
  1032. set_error_buf(error_buf, error_buf_size,
  1033. "param count or result count too large");
  1034. return false;
  1035. }
  1036. size1 = (uint64)param_count + (uint64)result_count;
  1037. size = offsetof(AOTFuncType, types) + size1;
  1038. if (!(func_types[i] = loader_malloc(size, error_buf, error_buf_size))) {
  1039. return false;
  1040. }
  1041. func_types[i]->param_count = (uint16)param_count;
  1042. func_types[i]->result_count = (uint16)result_count;
  1043. read_byte_array(buf, buf_end, func_types[i]->types, (uint32)size1);
  1044. param_cell_num = wasm_get_cell_num(func_types[i]->types, param_count);
  1045. ret_cell_num =
  1046. wasm_get_cell_num(func_types[i]->types + param_count, result_count);
  1047. if (param_cell_num > UINT16_MAX || ret_cell_num > UINT16_MAX) {
  1048. set_error_buf(error_buf, error_buf_size,
  1049. "param count or result count too large");
  1050. return false;
  1051. }
  1052. func_types[i]->param_cell_num = (uint16)param_cell_num;
  1053. func_types[i]->ret_cell_num = (uint16)ret_cell_num;
  1054. #if WASM_ENABLE_QUICK_AOT_ENTRY != 0
  1055. func_types[i]->quick_aot_entry =
  1056. wasm_native_lookup_quick_aot_entry(func_types[i]);
  1057. #endif
  1058. }
  1059. *p_buf = buf;
  1060. return true;
  1061. fail:
  1062. return false;
  1063. }
  1064. static bool
  1065. load_func_type_info(const uint8 **p_buf, const uint8 *buf_end,
  1066. AOTModule *module, char *error_buf, uint32 error_buf_size)
  1067. {
  1068. const uint8 *buf = *p_buf;
  1069. read_uint32(buf, buf_end, module->func_type_count);
  1070. /* load function type */
  1071. if (module->func_type_count > 0
  1072. && !load_func_types(&buf, buf_end, module, error_buf, error_buf_size))
  1073. return false;
  1074. *p_buf = buf;
  1075. return true;
  1076. fail:
  1077. return false;
  1078. }
  1079. static void
  1080. destroy_import_globals(AOTImportGlobal *import_globals)
  1081. {
  1082. wasm_runtime_free(import_globals);
  1083. }
  1084. static bool
  1085. load_import_globals(const uint8 **p_buf, const uint8 *buf_end,
  1086. AOTModule *module, bool is_load_from_file_buf,
  1087. char *error_buf, uint32 error_buf_size)
  1088. {
  1089. const uint8 *buf = *p_buf;
  1090. AOTImportGlobal *import_globals;
  1091. uint64 size;
  1092. uint32 i, data_offset = 0;
  1093. #if WASM_ENABLE_LIBC_BUILTIN != 0
  1094. WASMGlobalImport tmp_global;
  1095. #endif
  1096. /* Allocate memory */
  1097. size = sizeof(AOTImportGlobal) * (uint64)module->import_global_count;
  1098. if (!(module->import_globals = import_globals =
  1099. loader_malloc(size, error_buf, error_buf_size))) {
  1100. return false;
  1101. }
  1102. /* Create each import global */
  1103. for (i = 0; i < module->import_global_count; i++) {
  1104. buf = (uint8 *)align_ptr(buf, 2);
  1105. read_uint8(buf, buf_end, import_globals[i].type);
  1106. read_uint8(buf, buf_end, import_globals[i].is_mutable);
  1107. read_string(buf, buf_end, import_globals[i].module_name);
  1108. read_string(buf, buf_end, import_globals[i].global_name);
  1109. #if WASM_ENABLE_LIBC_BUILTIN != 0
  1110. if (wasm_native_lookup_libc_builtin_global(
  1111. import_globals[i].module_name, import_globals[i].global_name,
  1112. &tmp_global)) {
  1113. if (tmp_global.type != import_globals[i].type
  1114. || tmp_global.is_mutable != import_globals[i].is_mutable) {
  1115. set_error_buf(error_buf, error_buf_size,
  1116. "incompatible import type");
  1117. return false;
  1118. }
  1119. import_globals[i].global_data_linked =
  1120. tmp_global.global_data_linked;
  1121. import_globals[i].is_linked = true;
  1122. }
  1123. #else
  1124. import_globals[i].is_linked = false;
  1125. #endif
  1126. import_globals[i].size = wasm_value_type_size(import_globals[i].type);
  1127. import_globals[i].data_offset = data_offset;
  1128. data_offset += import_globals[i].size;
  1129. module->global_data_size += import_globals[i].size;
  1130. }
  1131. *p_buf = buf;
  1132. return true;
  1133. fail:
  1134. return false;
  1135. }
  1136. static bool
  1137. load_import_global_info(const uint8 **p_buf, const uint8 *buf_end,
  1138. AOTModule *module, bool is_load_from_file_buf,
  1139. char *error_buf, uint32 error_buf_size)
  1140. {
  1141. const uint8 *buf = *p_buf;
  1142. read_uint32(buf, buf_end, module->import_global_count);
  1143. /* load import globals */
  1144. if (module->import_global_count > 0
  1145. && !load_import_globals(&buf, buf_end, module, is_load_from_file_buf,
  1146. error_buf, error_buf_size))
  1147. return false;
  1148. *p_buf = buf;
  1149. return true;
  1150. fail:
  1151. return false;
  1152. }
  1153. static void
  1154. destroy_globals(AOTGlobal *globals)
  1155. {
  1156. wasm_runtime_free(globals);
  1157. }
  1158. static bool
  1159. load_globals(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  1160. char *error_buf, uint32 error_buf_size)
  1161. {
  1162. const uint8 *buf = *p_buf;
  1163. AOTGlobal *globals;
  1164. uint64 size;
  1165. uint32 i, data_offset = 0;
  1166. AOTImportGlobal *last_import_global;
  1167. /* Allocate memory */
  1168. size = sizeof(AOTGlobal) * (uint64)module->global_count;
  1169. if (!(module->globals = globals =
  1170. loader_malloc(size, error_buf, error_buf_size))) {
  1171. return false;
  1172. }
  1173. if (module->import_global_count > 0) {
  1174. last_import_global =
  1175. &module->import_globals[module->import_global_count - 1];
  1176. data_offset =
  1177. last_import_global->data_offset + last_import_global->size;
  1178. }
  1179. /* Create each global */
  1180. for (i = 0; i < module->global_count; i++) {
  1181. uint16 init_expr_type;
  1182. read_uint8(buf, buf_end, globals[i].type);
  1183. read_uint8(buf, buf_end, globals[i].is_mutable);
  1184. read_uint16(buf, buf_end, init_expr_type);
  1185. if (init_expr_type != INIT_EXPR_TYPE_V128_CONST) {
  1186. read_uint64(buf, buf_end, globals[i].init_expr.u.i64);
  1187. }
  1188. else {
  1189. uint64 *i64x2 = (uint64 *)globals[i].init_expr.u.v128.i64x2;
  1190. CHECK_BUF(buf, buf_end, sizeof(uint64) * 2);
  1191. wasm_runtime_read_v128(buf, &i64x2[0], &i64x2[1]);
  1192. buf += sizeof(uint64) * 2;
  1193. }
  1194. globals[i].init_expr.init_expr_type = (uint8)init_expr_type;
  1195. globals[i].size = wasm_value_type_size(globals[i].type);
  1196. globals[i].data_offset = data_offset;
  1197. data_offset += globals[i].size;
  1198. module->global_data_size += globals[i].size;
  1199. }
  1200. *p_buf = buf;
  1201. return true;
  1202. fail:
  1203. return false;
  1204. }
  1205. static bool
  1206. load_global_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  1207. char *error_buf, uint32 error_buf_size)
  1208. {
  1209. const uint8 *buf = *p_buf;
  1210. read_uint32(buf, buf_end, module->global_count);
  1211. /* load globals */
  1212. if (module->global_count > 0
  1213. && !load_globals(&buf, buf_end, module, error_buf, error_buf_size))
  1214. return false;
  1215. *p_buf = buf;
  1216. return true;
  1217. fail:
  1218. return false;
  1219. }
  1220. static void
  1221. destroy_import_funcs(AOTImportFunc *import_funcs)
  1222. {
  1223. wasm_runtime_free(import_funcs);
  1224. }
  1225. static bool
  1226. load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  1227. bool is_load_from_file_buf, char *error_buf,
  1228. uint32 error_buf_size)
  1229. {
  1230. char *module_name, *field_name;
  1231. const uint8 *buf = *p_buf;
  1232. AOTImportFunc *import_funcs;
  1233. uint64 size;
  1234. uint32 i;
  1235. #if WASM_ENABLE_MULTI_MODULE != 0
  1236. AOTModule *sub_module = NULL;
  1237. AOTFunc *linked_func = NULL;
  1238. WASMType *declare_func_type = NULL;
  1239. #endif
  1240. /* Allocate memory */
  1241. size = sizeof(AOTImportFunc) * (uint64)module->import_func_count;
  1242. if (!(module->import_funcs = import_funcs =
  1243. loader_malloc(size, error_buf, error_buf_size))) {
  1244. return false;
  1245. }
  1246. /* Create each import func */
  1247. for (i = 0; i < module->import_func_count; i++) {
  1248. read_uint16(buf, buf_end, import_funcs[i].func_type_index);
  1249. if (import_funcs[i].func_type_index >= module->func_type_count) {
  1250. set_error_buf(error_buf, error_buf_size, "unknown type");
  1251. return false;
  1252. }
  1253. #if WASM_ENABLE_MULTI_MODULE != 0
  1254. declare_func_type = module->func_types[import_funcs[i].func_type_index];
  1255. read_string(buf, buf_end, module_name);
  1256. read_string(buf, buf_end, field_name);
  1257. import_funcs[i].module_name = module_name;
  1258. import_funcs[i].func_name = field_name;
  1259. linked_func = wasm_native_resolve_symbol(
  1260. module_name, field_name, declare_func_type,
  1261. &import_funcs[i].signature, &import_funcs[i].attachment,
  1262. &import_funcs[i].call_conv_raw);
  1263. if (!linked_func) {
  1264. if (!wasm_runtime_is_built_in_module(module_name)) {
  1265. sub_module = (AOTModule *)wasm_runtime_load_depended_module(
  1266. (WASMModuleCommon *)module, module_name, error_buf,
  1267. error_buf_size);
  1268. if (!sub_module) {
  1269. return false;
  1270. }
  1271. }
  1272. linked_func = aot_loader_resolve_function(
  1273. module_name, field_name, declare_func_type, error_buf,
  1274. error_buf_size);
  1275. }
  1276. import_funcs[i].func_ptr_linked = linked_func;
  1277. import_funcs[i].func_type = declare_func_type;
  1278. #else
  1279. import_funcs[i].func_type =
  1280. module->func_types[import_funcs[i].func_type_index];
  1281. read_string(buf, buf_end, import_funcs[i].module_name);
  1282. read_string(buf, buf_end, import_funcs[i].func_name);
  1283. module_name = import_funcs[i].module_name;
  1284. field_name = import_funcs[i].func_name;
  1285. import_funcs[i].func_ptr_linked = wasm_native_resolve_symbol(
  1286. module_name, field_name, import_funcs[i].func_type,
  1287. &import_funcs[i].signature, &import_funcs[i].attachment,
  1288. &import_funcs[i].call_conv_raw);
  1289. #endif
  1290. #if WASM_ENABLE_LIBC_WASI != 0
  1291. if (!strcmp(import_funcs[i].module_name, "wasi_unstable")
  1292. || !strcmp(import_funcs[i].module_name, "wasi_snapshot_preview1"))
  1293. module->import_wasi_api = true;
  1294. #endif
  1295. }
  1296. *p_buf = buf;
  1297. return true;
  1298. fail:
  1299. return false;
  1300. }
  1301. static bool
  1302. load_import_func_info(const uint8 **p_buf, const uint8 *buf_end,
  1303. AOTModule *module, bool is_load_from_file_buf,
  1304. char *error_buf, uint32 error_buf_size)
  1305. {
  1306. const uint8 *buf = *p_buf;
  1307. read_uint32(buf, buf_end, module->import_func_count);
  1308. /* load import funcs */
  1309. if (module->import_func_count > 0
  1310. && !load_import_funcs(&buf, buf_end, module, is_load_from_file_buf,
  1311. error_buf, error_buf_size))
  1312. return false;
  1313. *p_buf = buf;
  1314. return true;
  1315. fail:
  1316. return false;
  1317. }
  1318. static void
  1319. destroy_object_data_sections(AOTObjectDataSection *data_sections,
  1320. uint32 data_section_count)
  1321. {
  1322. uint32 i;
  1323. AOTObjectDataSection *data_section = data_sections;
  1324. for (i = 0; i < data_section_count; i++, data_section++)
  1325. if (data_section->data) {
  1326. #if WASM_ENABLE_STATIC_PGO != 0
  1327. if (!strncmp(data_section->name, "__llvm_prf_data", 15)) {
  1328. LLVMProfileData *data = (LLVMProfileData *)data_section->data;
  1329. if (data->values) {
  1330. uint32 num_value_sites =
  1331. data->num_value_sites[0] + data->num_value_sites[1];
  1332. uint32 j;
  1333. for (j = 0; j < num_value_sites; j++) {
  1334. ValueProfNode *node = data->values[j], *node_next;
  1335. while (node) {
  1336. node_next = node->next;
  1337. wasm_runtime_free(node);
  1338. node = node_next;
  1339. }
  1340. }
  1341. wasm_runtime_free(data->values);
  1342. }
  1343. }
  1344. #endif
  1345. os_munmap(data_section->data, data_section->size);
  1346. }
  1347. wasm_runtime_free(data_sections);
  1348. }
  1349. static bool
  1350. load_object_data_sections(const uint8 **p_buf, const uint8 *buf_end,
  1351. AOTModule *module, bool is_load_from_file_buf,
  1352. char *error_buf, uint32 error_buf_size)
  1353. {
  1354. const uint8 *buf = *p_buf;
  1355. AOTObjectDataSection *data_sections;
  1356. uint64 size;
  1357. uint32 i;
  1358. /* Allocate memory */
  1359. size = sizeof(AOTObjectDataSection) * (uint64)module->data_section_count;
  1360. if (!(module->data_sections = data_sections =
  1361. loader_malloc(size, error_buf, error_buf_size))) {
  1362. return false;
  1363. }
  1364. /* Create each data section */
  1365. for (i = 0; i < module->data_section_count; i++) {
  1366. int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE;
  1367. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
  1368. || defined(BUILD_TARGET_RISCV64_LP64D) \
  1369. || defined(BUILD_TARGET_RISCV64_LP64)
  1370. /* aot code and data in x86_64 must be in range 0 to 2G due to
  1371. relocation for R_X86_64_32/32S/PC32 */
  1372. int map_flags = MMAP_MAP_32BIT;
  1373. #else
  1374. int map_flags = MMAP_MAP_NONE;
  1375. #endif
  1376. read_string(buf, buf_end, data_sections[i].name);
  1377. read_uint32(buf, buf_end, data_sections[i].size);
  1378. /* Allocate memory for data */
  1379. if (data_sections[i].size > 0
  1380. && !(data_sections[i].data =
  1381. os_mmap(NULL, data_sections[i].size, map_prot, map_flags,
  1382. os_get_invalid_handle()))) {
  1383. set_error_buf(error_buf, error_buf_size, "allocate memory failed");
  1384. return false;
  1385. }
  1386. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
  1387. #if !defined(BH_PLATFORM_LINUX_SGX) && !defined(BH_PLATFORM_WINDOWS) \
  1388. && !defined(BH_PLATFORM_DARWIN)
  1389. /* address must be in the first 2 Gigabytes of
  1390. the process address space */
  1391. bh_assert((uintptr_t)data_sections[i].data < INT32_MAX);
  1392. #endif
  1393. #endif
  1394. read_byte_array(buf, buf_end, data_sections[i].data,
  1395. data_sections[i].size);
  1396. }
  1397. *p_buf = buf;
  1398. return true;
  1399. fail:
  1400. return false;
  1401. }
  1402. static bool
  1403. load_object_data_sections_info(const uint8 **p_buf, const uint8 *buf_end,
  1404. AOTModule *module, bool is_load_from_file_buf,
  1405. char *error_buf, uint32 error_buf_size)
  1406. {
  1407. const uint8 *buf = *p_buf;
  1408. read_uint32(buf, buf_end, module->data_section_count);
  1409. /* load object data sections */
  1410. if (module->data_section_count > 0
  1411. && !load_object_data_sections(&buf, buf_end, module,
  1412. is_load_from_file_buf, error_buf,
  1413. error_buf_size))
  1414. return false;
  1415. *p_buf = buf;
  1416. return true;
  1417. fail:
  1418. return false;
  1419. }
  1420. static bool
  1421. load_init_data_section(const uint8 *buf, const uint8 *buf_end,
  1422. AOTModule *module, bool is_load_from_file_buf,
  1423. char *error_buf, uint32 error_buf_size)
  1424. {
  1425. const uint8 *p = buf, *p_end = buf_end;
  1426. if (!load_memory_info(&p, p_end, module, error_buf, error_buf_size)
  1427. || !load_table_info(&p, p_end, module, error_buf, error_buf_size)
  1428. || !load_func_type_info(&p, p_end, module, error_buf, error_buf_size)
  1429. || !load_import_global_info(&p, p_end, module, is_load_from_file_buf,
  1430. error_buf, error_buf_size)
  1431. || !load_global_info(&p, p_end, module, error_buf, error_buf_size)
  1432. || !load_import_func_info(&p, p_end, module, is_load_from_file_buf,
  1433. error_buf, error_buf_size))
  1434. return false;
  1435. /* load function count and start function index */
  1436. read_uint32(p, p_end, module->func_count);
  1437. read_uint32(p, p_end, module->start_func_index);
  1438. /* check start function index */
  1439. if (module->start_func_index != (uint32)-1
  1440. && (module->start_func_index
  1441. >= module->import_func_count + module->func_count)) {
  1442. set_error_buf(error_buf, error_buf_size,
  1443. "invalid start function index");
  1444. return false;
  1445. }
  1446. read_uint32(p, p_end, module->aux_data_end_global_index);
  1447. read_uint32(p, p_end, module->aux_data_end);
  1448. read_uint32(p, p_end, module->aux_heap_base_global_index);
  1449. read_uint32(p, p_end, module->aux_heap_base);
  1450. read_uint32(p, p_end, module->aux_stack_top_global_index);
  1451. read_uint32(p, p_end, module->aux_stack_bottom);
  1452. read_uint32(p, p_end, module->aux_stack_size);
  1453. if (!load_object_data_sections_info(&p, p_end, module,
  1454. is_load_from_file_buf, error_buf,
  1455. error_buf_size))
  1456. return false;
  1457. if (p != p_end) {
  1458. set_error_buf(error_buf, error_buf_size,
  1459. "invalid init data section size");
  1460. return false;
  1461. }
  1462. return true;
  1463. fail:
  1464. return false;
  1465. }
  1466. static bool
  1467. load_text_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
  1468. char *error_buf, uint32 error_buf_size)
  1469. {
  1470. uint8 *plt_base;
  1471. if (module->func_count > 0 && buf_end == buf) {
  1472. set_error_buf(error_buf, error_buf_size, "invalid code size");
  1473. return false;
  1474. }
  1475. /* The layout is: literal size + literal + code (with plt table) */
  1476. read_uint32(buf, buf_end, module->literal_size);
  1477. /* literal data is at beginning of the text section */
  1478. module->literal = (uint8 *)buf;
  1479. module->code = (void *)(buf + module->literal_size);
  1480. module->code_size = (uint32)(buf_end - (uint8 *)module->code);
  1481. #if WASM_ENABLE_DEBUG_AOT != 0
  1482. module->elf_size = module->code_size;
  1483. if (is_ELF(module->code)) {
  1484. /* Now code points to an ELF object, we pull it down to .text section */
  1485. uint64 offset;
  1486. uint64 size;
  1487. char *code_buf = module->code;
  1488. module->elf_hdr = code_buf;
  1489. if (!get_text_section(code_buf, &offset, &size)) {
  1490. set_error_buf(error_buf, error_buf_size,
  1491. "get text section of ELF failed");
  1492. return false;
  1493. }
  1494. module->code = code_buf + offset;
  1495. module->code_size -= (uint32)offset;
  1496. }
  1497. #endif
  1498. if ((module->code_size > 0) && !module->is_indirect_mode) {
  1499. plt_base = (uint8 *)buf_end - get_plt_table_size();
  1500. init_plt_table(plt_base);
  1501. }
  1502. return true;
  1503. fail:
  1504. return false;
  1505. }
  1506. static bool
  1507. load_function_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
  1508. char *error_buf, uint32 error_buf_size)
  1509. {
  1510. const uint8 *p = buf, *p_end = buf_end;
  1511. uint32 i;
  1512. uint64 size, text_offset;
  1513. size = sizeof(void *) * (uint64)module->func_count;
  1514. if (size > 0
  1515. && !(module->func_ptrs =
  1516. loader_malloc(size, error_buf, error_buf_size))) {
  1517. return false;
  1518. }
  1519. for (i = 0; i < module->func_count; i++) {
  1520. if (sizeof(void *) == 8) {
  1521. read_uint64(p, p_end, text_offset);
  1522. }
  1523. else {
  1524. uint32 text_offset32;
  1525. read_uint32(p, p_end, text_offset32);
  1526. text_offset = text_offset32;
  1527. }
  1528. if (text_offset >= module->code_size) {
  1529. set_error_buf(error_buf, error_buf_size,
  1530. "invalid function code offset");
  1531. return false;
  1532. }
  1533. module->func_ptrs[i] = (uint8 *)module->code + text_offset;
  1534. #if defined(BUILD_TARGET_THUMB) || defined(BUILD_TARGET_THUMB_VFP)
  1535. /* bits[0] of thumb function address must be 1 */
  1536. module->func_ptrs[i] = (void *)((uintptr_t)module->func_ptrs[i] | 1);
  1537. #endif
  1538. }
  1539. /* Set start function when function pointers are resolved */
  1540. if (module->start_func_index != (uint32)-1) {
  1541. if (module->start_func_index >= module->import_func_count)
  1542. module->start_function =
  1543. module->func_ptrs[module->start_func_index
  1544. - module->import_func_count];
  1545. else
  1546. /* TODO: fix start function can be import function issue */
  1547. module->start_function = NULL;
  1548. }
  1549. else {
  1550. module->start_function = NULL;
  1551. }
  1552. size = sizeof(uint32) * (uint64)module->func_count;
  1553. if (size > 0
  1554. && !(module->func_type_indexes =
  1555. loader_malloc(size, error_buf, error_buf_size))) {
  1556. return false;
  1557. }
  1558. for (i = 0; i < module->func_count; i++) {
  1559. read_uint32(p, p_end, module->func_type_indexes[i]);
  1560. if (module->func_type_indexes[i] >= module->func_type_count) {
  1561. set_error_buf(error_buf, error_buf_size, "unknown type");
  1562. return false;
  1563. }
  1564. }
  1565. if (p != buf_end) {
  1566. set_error_buf(error_buf, error_buf_size,
  1567. "invalid function section size");
  1568. return false;
  1569. }
  1570. return true;
  1571. fail:
  1572. return false;
  1573. }
  1574. static void
  1575. destroy_exports(AOTExport *exports)
  1576. {
  1577. wasm_runtime_free(exports);
  1578. }
  1579. static bool
  1580. load_exports(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  1581. bool is_load_from_file_buf, char *error_buf, uint32 error_buf_size)
  1582. {
  1583. const uint8 *buf = *p_buf;
  1584. AOTExport *exports;
  1585. uint64 size;
  1586. uint32 i;
  1587. /* Allocate memory */
  1588. size = sizeof(AOTExport) * (uint64)module->export_count;
  1589. if (!(module->exports = exports =
  1590. loader_malloc(size, error_buf, error_buf_size))) {
  1591. return false;
  1592. }
  1593. /* Create each export */
  1594. for (i = 0; i < module->export_count; i++) {
  1595. read_uint32(buf, buf_end, exports[i].index);
  1596. read_uint8(buf, buf_end, exports[i].kind);
  1597. read_string(buf, buf_end, exports[i].name);
  1598. #if 0 /* TODO: check kind and index */
  1599. if (export_funcs[i].index >=
  1600. module->func_count + module->import_func_count) {
  1601. set_error_buf(error_buf, error_buf_size,
  1602. "function index is out of range");
  1603. return false;
  1604. }
  1605. #endif
  1606. }
  1607. *p_buf = buf;
  1608. return true;
  1609. fail:
  1610. return false;
  1611. }
  1612. static bool
  1613. load_export_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
  1614. bool is_load_from_file_buf, char *error_buf,
  1615. uint32 error_buf_size)
  1616. {
  1617. const uint8 *p = buf, *p_end = buf_end;
  1618. /* load export functions */
  1619. read_uint32(p, p_end, module->export_count);
  1620. if (module->export_count > 0
  1621. && !load_exports(&p, p_end, module, is_load_from_file_buf, error_buf,
  1622. error_buf_size))
  1623. return false;
  1624. if (p != p_end) {
  1625. set_error_buf(error_buf, error_buf_size, "invalid export section size");
  1626. return false;
  1627. }
  1628. return true;
  1629. fail:
  1630. return false;
  1631. }
  1632. static void *
  1633. get_data_section_addr(AOTModule *module, const char *section_name,
  1634. uint32 *p_data_size)
  1635. {
  1636. uint32 i;
  1637. AOTObjectDataSection *data_section = module->data_sections;
  1638. for (i = 0; i < module->data_section_count; i++, data_section++) {
  1639. if (!strcmp(data_section->name, section_name)) {
  1640. if (p_data_size)
  1641. *p_data_size = data_section->size;
  1642. return data_section->data;
  1643. }
  1644. }
  1645. return NULL;
  1646. }
  1647. const void *
  1648. aot_get_data_section_addr(AOTModule *module, const char *section_name,
  1649. uint32 *p_data_size)
  1650. {
  1651. return get_data_section_addr(module, section_name, p_data_size);
  1652. }
  1653. static void *
  1654. resolve_target_sym(const char *symbol, int32 *p_index)
  1655. {
  1656. uint32 i, num = 0;
  1657. SymbolMap *target_sym_map;
  1658. if (!(target_sym_map = get_target_symbol_map(&num)))
  1659. return NULL;
  1660. for (i = 0; i < num; i++) {
  1661. if (!strcmp(target_sym_map[i].symbol_name, symbol)
  1662. #if defined(_WIN32) || defined(_WIN32_)
  1663. /* In Win32, the symbol name of function added by
  1664. LLVMAddFunction() is prefixed by '_', ignore it */
  1665. || (strlen(symbol) > 1 && symbol[0] == '_'
  1666. && !strcmp(target_sym_map[i].symbol_name, symbol + 1))
  1667. #endif
  1668. ) {
  1669. *p_index = (int32)i;
  1670. return target_sym_map[i].symbol_addr;
  1671. }
  1672. }
  1673. return NULL;
  1674. }
  1675. static bool
  1676. is_literal_relocation(const char *reloc_sec_name)
  1677. {
  1678. return !strcmp(reloc_sec_name, ".rela.literal");
  1679. }
  1680. static bool
  1681. str2uint32(const char *buf, uint32 *p_res)
  1682. {
  1683. uint32 res = 0, val;
  1684. const char *buf_end = buf + 8;
  1685. char ch;
  1686. while (buf < buf_end) {
  1687. ch = *buf++;
  1688. if (ch >= '0' && ch <= '9')
  1689. val = ch - '0';
  1690. else if (ch >= 'a' && ch <= 'f')
  1691. val = ch - 'a' + 0xA;
  1692. else if (ch >= 'A' && ch <= 'F')
  1693. val = ch - 'A' + 0xA;
  1694. else
  1695. return false;
  1696. res = (res << 4) | val;
  1697. }
  1698. *p_res = res;
  1699. return true;
  1700. }
  1701. static bool
  1702. str2uint64(const char *buf, uint64 *p_res)
  1703. {
  1704. uint64 res = 0, val;
  1705. const char *buf_end = buf + 16;
  1706. char ch;
  1707. while (buf < buf_end) {
  1708. ch = *buf++;
  1709. if (ch >= '0' && ch <= '9')
  1710. val = ch - '0';
  1711. else if (ch >= 'a' && ch <= 'f')
  1712. val = ch - 'a' + 0xA;
  1713. else if (ch >= 'A' && ch <= 'F')
  1714. val = ch - 'A' + 0xA;
  1715. else
  1716. return false;
  1717. res = (res << 4) | val;
  1718. }
  1719. *p_res = res;
  1720. return true;
  1721. }
  1722. #define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative offset to GOT */
  1723. static bool
  1724. do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
  1725. char *error_buf, uint32 error_buf_size)
  1726. {
  1727. bool is_literal = is_literal_relocation(group->section_name);
  1728. uint8 *aot_text = is_literal ? module->literal : module->code;
  1729. uint32 aot_text_size =
  1730. is_literal ? module->literal_size : module->code_size;
  1731. uint32 i, func_index, symbol_len;
  1732. #if defined(BH_PLATFORM_WINDOWS)
  1733. uint32 ymm_plt_index = 0, xmm_plt_index = 0;
  1734. uint32 real_plt_index = 0, float_plt_index = 0, j;
  1735. #endif
  1736. char symbol_buf[128] = { 0 }, *symbol, *p;
  1737. void *symbol_addr;
  1738. AOTRelocation *relocation = group->relocations;
  1739. if (group->relocation_count > 0 && !aot_text) {
  1740. set_error_buf(error_buf, error_buf_size,
  1741. "invalid text relocation count");
  1742. return false;
  1743. }
  1744. for (i = 0; i < group->relocation_count; i++, relocation++) {
  1745. int32 symbol_index = -1;
  1746. symbol_len = (uint32)strlen(relocation->symbol_name);
  1747. if (symbol_len + 1 <= sizeof(symbol_buf))
  1748. symbol = symbol_buf;
  1749. else {
  1750. if (!(symbol = loader_malloc(symbol_len + 1, error_buf,
  1751. error_buf_size))) {
  1752. return false;
  1753. }
  1754. }
  1755. bh_memcpy_s(symbol, symbol_len, relocation->symbol_name, symbol_len);
  1756. symbol[symbol_len] = '\0';
  1757. #if WASM_ENABLE_STATIC_PGO != 0
  1758. if (!strcmp(symbol, "__llvm_profile_runtime")
  1759. || !strcmp(symbol, "__llvm_profile_register_function")
  1760. || !strcmp(symbol, "__llvm_profile_register_names_function")) {
  1761. continue;
  1762. }
  1763. #endif
  1764. if (!strncmp(symbol, AOT_FUNC_PREFIX, strlen(AOT_FUNC_PREFIX))) {
  1765. p = symbol + strlen(AOT_FUNC_PREFIX);
  1766. if (*p == '\0'
  1767. || (func_index = (uint32)atoi(p)) > module->func_count) {
  1768. set_error_buf_v(error_buf, error_buf_size,
  1769. "invalid import symbol %s", symbol);
  1770. goto check_symbol_fail;
  1771. }
  1772. #if (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) \
  1773. && !defined(BH_PLATFORM_WINDOWS)
  1774. if (relocation->relocation_type == R_X86_64_GOTPCREL) {
  1775. GOTItem *got_item = module->got_item_list;
  1776. uint32 got_item_idx = 0;
  1777. while (got_item) {
  1778. if (got_item->func_idx == func_index)
  1779. break;
  1780. got_item_idx++;
  1781. got_item = got_item->next;
  1782. }
  1783. /* Calculate `GOT + G` */
  1784. symbol_addr = module->got_func_ptrs + got_item_idx;
  1785. }
  1786. else
  1787. symbol_addr = module->func_ptrs[func_index];
  1788. #else
  1789. symbol_addr = module->func_ptrs[func_index];
  1790. #endif
  1791. }
  1792. #if defined(BH_PLATFORM_WINDOWS) && defined(BUILD_TARGET_X86_32)
  1793. /* AOT function name starts with '_' in windows x86-32 */
  1794. else if (!strncmp(symbol, "_" AOT_FUNC_PREFIX,
  1795. strlen("_" AOT_FUNC_PREFIX))) {
  1796. p = symbol + strlen("_" AOT_FUNC_PREFIX);
  1797. if (*p == '\0'
  1798. || (func_index = (uint32)atoi(p)) > module->func_count) {
  1799. set_error_buf_v(error_buf, error_buf_size, "invalid symbol %s",
  1800. symbol);
  1801. goto check_symbol_fail;
  1802. }
  1803. symbol_addr = module->func_ptrs[func_index];
  1804. }
  1805. #endif
  1806. else if (!strcmp(symbol, ".text")) {
  1807. symbol_addr = module->code;
  1808. }
  1809. else if (!strcmp(symbol, ".data") || !strcmp(symbol, ".sdata")
  1810. || !strcmp(symbol, ".rdata")
  1811. || !strcmp(symbol, ".rodata")
  1812. /* ".rodata.cst4/8/16/.." */
  1813. || !strncmp(symbol, ".rodata.cst", strlen(".rodata.cst"))
  1814. /* ".rodata.strn.m" */
  1815. || !strncmp(symbol, ".rodata.str", strlen(".rodata.str"))
  1816. || !strcmp(symbol, AOT_STACK_SIZES_SECTION_NAME)
  1817. #if WASM_ENABLE_STATIC_PGO != 0
  1818. || !strncmp(symbol, "__llvm_prf_cnts", 15)
  1819. || !strncmp(symbol, "__llvm_prf_data", 15)
  1820. || !strncmp(symbol, "__llvm_prf_names", 16)
  1821. #endif
  1822. ) {
  1823. symbol_addr = get_data_section_addr(module, symbol, NULL);
  1824. if (!symbol_addr) {
  1825. set_error_buf_v(error_buf, error_buf_size,
  1826. "invalid data section (%s)", symbol);
  1827. goto check_symbol_fail;
  1828. }
  1829. }
  1830. else if (!strcmp(symbol, ".literal")) {
  1831. symbol_addr = module->literal;
  1832. }
  1833. #if defined(BH_PLATFORM_WINDOWS)
  1834. /* Relocation for symbols which start with "__ymm@", "__xmm@" or
  1835. "__real@" and end with the ymm value, xmm value or real value.
  1836. In Windows PE file, the data is stored in some individual ".rdata"
  1837. sections. We simply create extra plt data, parse the values from
  1838. the symbols and stored them into the extra plt data. */
  1839. else if (!strcmp(group->section_name, ".text")
  1840. && !strncmp(symbol, YMM_PLT_PREFIX, strlen(YMM_PLT_PREFIX))
  1841. && strlen(symbol) == strlen(YMM_PLT_PREFIX) + 64) {
  1842. char ymm_buf[17] = { 0 };
  1843. symbol_addr = module->extra_plt_data + ymm_plt_index * 32;
  1844. for (j = 0; j < 4; j++) {
  1845. bh_memcpy_s(ymm_buf, sizeof(ymm_buf),
  1846. symbol + strlen(YMM_PLT_PREFIX) + 48 - 16 * j, 16);
  1847. if (!str2uint64(ymm_buf,
  1848. (uint64 *)((uint8 *)symbol_addr + 8 * j))) {
  1849. set_error_buf_v(error_buf, error_buf_size,
  1850. "resolve symbol %s failed", symbol);
  1851. goto check_symbol_fail;
  1852. }
  1853. }
  1854. ymm_plt_index++;
  1855. }
  1856. else if (!strcmp(group->section_name, ".text")
  1857. && !strncmp(symbol, XMM_PLT_PREFIX, strlen(XMM_PLT_PREFIX))
  1858. && strlen(symbol) == strlen(XMM_PLT_PREFIX) + 32) {
  1859. char xmm_buf[17] = { 0 };
  1860. symbol_addr = module->extra_plt_data + module->ymm_plt_count * 32
  1861. + xmm_plt_index * 16;
  1862. for (j = 0; j < 2; j++) {
  1863. bh_memcpy_s(xmm_buf, sizeof(xmm_buf),
  1864. symbol + strlen(XMM_PLT_PREFIX) + 16 - 16 * j, 16);
  1865. if (!str2uint64(xmm_buf,
  1866. (uint64 *)((uint8 *)symbol_addr + 8 * j))) {
  1867. set_error_buf_v(error_buf, error_buf_size,
  1868. "resolve symbol %s failed", symbol);
  1869. goto check_symbol_fail;
  1870. }
  1871. }
  1872. xmm_plt_index++;
  1873. }
  1874. else if (!strcmp(group->section_name, ".text")
  1875. && !strncmp(symbol, REAL_PLT_PREFIX, strlen(REAL_PLT_PREFIX))
  1876. && strlen(symbol) == strlen(REAL_PLT_PREFIX) + 16) {
  1877. char real_buf[17] = { 0 };
  1878. symbol_addr = module->extra_plt_data + module->ymm_plt_count * 32
  1879. + module->xmm_plt_count * 16 + real_plt_index * 8;
  1880. bh_memcpy_s(real_buf, sizeof(real_buf),
  1881. symbol + strlen(REAL_PLT_PREFIX), 16);
  1882. if (!str2uint64(real_buf, (uint64 *)symbol_addr)) {
  1883. set_error_buf_v(error_buf, error_buf_size,
  1884. "resolve symbol %s failed", symbol);
  1885. goto check_symbol_fail;
  1886. }
  1887. real_plt_index++;
  1888. }
  1889. else if (!strcmp(group->section_name, ".text")
  1890. && !strncmp(symbol, REAL_PLT_PREFIX, strlen(REAL_PLT_PREFIX))
  1891. && strlen(symbol) == strlen(REAL_PLT_PREFIX) + 8) {
  1892. char float_buf[9] = { 0 };
  1893. symbol_addr = module->extra_plt_data + module->ymm_plt_count * 32
  1894. + module->xmm_plt_count * 16
  1895. + module->real_plt_count * 8 + float_plt_index * 4;
  1896. bh_memcpy_s(float_buf, sizeof(float_buf),
  1897. symbol + strlen(REAL_PLT_PREFIX), 8);
  1898. if (!str2uint32(float_buf, (uint32 *)symbol_addr)) {
  1899. set_error_buf_v(error_buf, error_buf_size,
  1900. "resolve symbol %s failed", symbol);
  1901. goto check_symbol_fail;
  1902. }
  1903. float_plt_index++;
  1904. }
  1905. #endif /* end of defined(BH_PLATFORM_WINDOWS) */
  1906. else if (!(symbol_addr = resolve_target_sym(symbol, &symbol_index))) {
  1907. set_error_buf_v(error_buf, error_buf_size,
  1908. "resolve symbol %s failed", symbol);
  1909. goto check_symbol_fail;
  1910. }
  1911. if (symbol != symbol_buf)
  1912. wasm_runtime_free(symbol);
  1913. if (!apply_relocation(
  1914. module, aot_text, aot_text_size, relocation->relocation_offset,
  1915. relocation->relocation_addend, relocation->relocation_type,
  1916. symbol_addr, symbol_index, error_buf, error_buf_size))
  1917. return false;
  1918. }
  1919. return true;
  1920. check_symbol_fail:
  1921. if (symbol != symbol_buf)
  1922. wasm_runtime_free(symbol);
  1923. return false;
  1924. }
  1925. static bool
  1926. do_data_relocation(AOTModule *module, AOTRelocationGroup *group,
  1927. char *error_buf, uint32 error_buf_size)
  1928. {
  1929. uint8 *data_addr;
  1930. uint32 data_size = 0, i;
  1931. AOTRelocation *relocation = group->relocations;
  1932. void *symbol_addr;
  1933. char *symbol, *data_section_name;
  1934. if (!strncmp(group->section_name, ".rela.", 6)) {
  1935. data_section_name = group->section_name + strlen(".rela");
  1936. }
  1937. else if (!strncmp(group->section_name, ".rel.", 5)) {
  1938. data_section_name = group->section_name + strlen(".rel");
  1939. }
  1940. else if (!strcmp(group->section_name, ".rdata")) {
  1941. data_section_name = group->section_name;
  1942. }
  1943. #if WASM_ENABLE_STATIC_PGO != 0
  1944. else if (!strncmp(group->section_name, ".rel__llvm_prf_data", 19)) {
  1945. data_section_name = group->section_name + strlen(".rel");
  1946. }
  1947. else if (!strncmp(group->section_name, ".rela__llvm_prf_data", 20)) {
  1948. data_section_name = group->section_name + strlen(".rela");
  1949. }
  1950. #endif
  1951. else {
  1952. set_error_buf(error_buf, error_buf_size,
  1953. "invalid data relocation section name");
  1954. return false;
  1955. }
  1956. data_addr = get_data_section_addr(module, data_section_name, &data_size);
  1957. if (group->relocation_count > 0 && !data_addr) {
  1958. set_error_buf(error_buf, error_buf_size,
  1959. "invalid data relocation count");
  1960. return false;
  1961. }
  1962. for (i = 0; i < group->relocation_count; i++, relocation++) {
  1963. symbol = relocation->symbol_name;
  1964. if (!strcmp(symbol, ".text")) {
  1965. symbol_addr = module->code;
  1966. }
  1967. #if WASM_ENABLE_STATIC_PGO != 0
  1968. else if (!strncmp(symbol, AOT_FUNC_PREFIX, strlen(AOT_FUNC_PREFIX))) {
  1969. char *p = symbol + strlen(AOT_FUNC_PREFIX);
  1970. uint32 func_index;
  1971. if (*p == '\0'
  1972. || (func_index = (uint32)atoi(p)) > module->func_count) {
  1973. set_error_buf_v(error_buf, error_buf_size,
  1974. "invalid relocation symbol %s", symbol);
  1975. return false;
  1976. }
  1977. symbol_addr = module->func_ptrs[func_index];
  1978. }
  1979. else if (!strcmp(symbol, "__llvm_prf_cnts")) {
  1980. uint32 j;
  1981. for (j = 0; j < module->data_section_count; j++) {
  1982. if (!strncmp(module->data_sections[j].name, symbol, 15)) {
  1983. bh_assert(relocation->relocation_addend + sizeof(uint64)
  1984. <= module->data_sections[j].size);
  1985. symbol_addr = module->data_sections[j].data;
  1986. break;
  1987. }
  1988. }
  1989. if (j == module->data_section_count) {
  1990. set_error_buf_v(error_buf, error_buf_size,
  1991. "invalid relocation symbol %s", symbol);
  1992. return false;
  1993. }
  1994. }
  1995. else if (!strncmp(symbol, "__llvm_prf_cnts", 15)) {
  1996. uint32 j;
  1997. for (j = 0; j < module->data_section_count; j++) {
  1998. if (!strcmp(module->data_sections[j].name, symbol)) {
  1999. symbol_addr = module->data_sections[j].data;
  2000. break;
  2001. }
  2002. }
  2003. if (j == module->data_section_count) {
  2004. set_error_buf_v(error_buf, error_buf_size,
  2005. "invalid relocation symbol %s", symbol);
  2006. return false;
  2007. }
  2008. }
  2009. #endif /* end of WASM_ENABLE_STATIC_PGO != 0 */
  2010. else {
  2011. set_error_buf_v(error_buf, error_buf_size,
  2012. "invalid relocation symbol %s", symbol);
  2013. return false;
  2014. }
  2015. if (!apply_relocation(
  2016. module, data_addr, data_size, relocation->relocation_offset,
  2017. relocation->relocation_addend, relocation->relocation_type,
  2018. symbol_addr, -1, error_buf, error_buf_size))
  2019. return false;
  2020. }
  2021. return true;
  2022. }
  2023. static bool
  2024. validate_symbol_table(uint8 *buf, uint8 *buf_end, uint32 *offsets, uint32 count,
  2025. char *error_buf, uint32 error_buf_size)
  2026. {
  2027. uint32 i, str_len_addr = 0;
  2028. uint16 str_len;
  2029. for (i = 0; i < count; i++) {
  2030. if (offsets[i] != str_len_addr)
  2031. return false;
  2032. read_uint16(buf, buf_end, str_len);
  2033. str_len_addr += (uint32)sizeof(uint16) + str_len;
  2034. str_len_addr = align_uint(str_len_addr, 2);
  2035. buf += str_len;
  2036. buf = (uint8 *)align_ptr(buf, 2);
  2037. }
  2038. if (buf == buf_end)
  2039. return true;
  2040. fail:
  2041. return false;
  2042. }
  2043. static bool
  2044. load_relocation_section(const uint8 *buf, const uint8 *buf_end,
  2045. AOTModule *module, bool is_load_from_file_buf,
  2046. char *error_buf, uint32 error_buf_size)
  2047. {
  2048. AOTRelocationGroup *groups = NULL, *group;
  2049. uint32 symbol_count = 0;
  2050. uint32 group_count = 0, i, j, got_item_count = 0;
  2051. uint64 size;
  2052. uint32 *symbol_offsets, total_string_len;
  2053. uint8 *symbol_buf, *symbol_buf_end;
  2054. int map_prot, map_flags;
  2055. bool ret = false;
  2056. char **symbols = NULL;
  2057. read_uint32(buf, buf_end, symbol_count);
  2058. symbol_offsets = (uint32 *)buf;
  2059. for (i = 0; i < symbol_count; i++) {
  2060. CHECK_BUF(buf, buf_end, sizeof(uint32));
  2061. buf += sizeof(uint32);
  2062. }
  2063. read_uint32(buf, buf_end, total_string_len);
  2064. symbol_buf = (uint8 *)buf;
  2065. symbol_buf_end = symbol_buf + total_string_len;
  2066. if (!validate_symbol_table(symbol_buf, symbol_buf_end, symbol_offsets,
  2067. symbol_count, error_buf, error_buf_size)) {
  2068. set_error_buf(error_buf, error_buf_size,
  2069. "validate symbol table failed");
  2070. goto fail;
  2071. }
  2072. if (symbol_count > 0) {
  2073. symbols = loader_malloc((uint64)sizeof(*symbols) * symbol_count,
  2074. error_buf, error_buf_size);
  2075. if (symbols == NULL) {
  2076. goto fail;
  2077. }
  2078. }
  2079. #if defined(BH_PLATFORM_WINDOWS)
  2080. buf = symbol_buf_end;
  2081. read_uint32(buf, buf_end, group_count);
  2082. for (i = 0; i < group_count; i++) {
  2083. uint32 name_index, relocation_count;
  2084. uint16 group_name_len;
  2085. uint8 *group_name;
  2086. /* section name address is 4 bytes aligned. */
  2087. buf = (uint8 *)align_ptr(buf, sizeof(uint32));
  2088. read_uint32(buf, buf_end, name_index);
  2089. if (name_index >= symbol_count) {
  2090. set_error_buf(error_buf, error_buf_size,
  2091. "symbol index out of range");
  2092. goto fail;
  2093. }
  2094. group_name = symbol_buf + symbol_offsets[name_index];
  2095. group_name_len = *(uint16 *)group_name;
  2096. group_name += sizeof(uint16);
  2097. read_uint32(buf, buf_end, relocation_count);
  2098. for (j = 0; j < relocation_count; j++) {
  2099. AOTRelocation relocation = { 0 };
  2100. char group_name_buf[128] = { 0 };
  2101. char symbol_name_buf[128] = { 0 };
  2102. uint32 symbol_index, offset32;
  2103. int32 addend32;
  2104. uint16 symbol_name_len;
  2105. uint8 *symbol_name;
  2106. if (sizeof(void *) == 8) {
  2107. read_uint64(buf, buf_end, relocation.relocation_offset);
  2108. read_uint64(buf, buf_end, relocation.relocation_addend);
  2109. }
  2110. else {
  2111. read_uint32(buf, buf_end, offset32);
  2112. relocation.relocation_offset = (uint64)offset32;
  2113. read_uint32(buf, buf_end, addend32);
  2114. relocation.relocation_addend = (int64)addend32;
  2115. }
  2116. read_uint32(buf, buf_end, relocation.relocation_type);
  2117. read_uint32(buf, buf_end, symbol_index);
  2118. if (symbol_index >= symbol_count) {
  2119. set_error_buf(error_buf, error_buf_size,
  2120. "symbol index out of range");
  2121. goto fail;
  2122. }
  2123. symbol_name = symbol_buf + symbol_offsets[symbol_index];
  2124. symbol_name_len = *(uint16 *)symbol_name;
  2125. symbol_name += sizeof(uint16);
  2126. bh_memcpy_s(group_name_buf, (uint32)sizeof(group_name_buf),
  2127. group_name, group_name_len);
  2128. bh_memcpy_s(symbol_name_buf, (uint32)sizeof(symbol_name_buf),
  2129. symbol_name, symbol_name_len);
  2130. if ((group_name_len == strlen(".text")
  2131. || (module->is_indirect_mode
  2132. && group_name_len == strlen(".text") + 1))
  2133. && !strncmp(group_name, ".text", strlen(".text"))) {
  2134. if ((symbol_name_len == strlen(YMM_PLT_PREFIX) + 64
  2135. || (module->is_indirect_mode
  2136. && symbol_name_len == strlen(YMM_PLT_PREFIX) + 64 + 1))
  2137. && !strncmp(symbol_name, YMM_PLT_PREFIX,
  2138. strlen(YMM_PLT_PREFIX))) {
  2139. module->ymm_plt_count++;
  2140. }
  2141. else if ((symbol_name_len == strlen(XMM_PLT_PREFIX) + 32
  2142. || (module->is_indirect_mode
  2143. && symbol_name_len
  2144. == strlen(XMM_PLT_PREFIX) + 32 + 1))
  2145. && !strncmp(symbol_name, XMM_PLT_PREFIX,
  2146. strlen(XMM_PLT_PREFIX))) {
  2147. module->xmm_plt_count++;
  2148. }
  2149. else if ((symbol_name_len == strlen(REAL_PLT_PREFIX) + 16
  2150. || (module->is_indirect_mode
  2151. && symbol_name_len
  2152. == strlen(REAL_PLT_PREFIX) + 16 + 1))
  2153. && !strncmp(symbol_name, REAL_PLT_PREFIX,
  2154. strlen(REAL_PLT_PREFIX))) {
  2155. module->real_plt_count++;
  2156. }
  2157. else if ((symbol_name_len >= strlen(REAL_PLT_PREFIX) + 8
  2158. || (module->is_indirect_mode
  2159. && symbol_name_len
  2160. == strlen(REAL_PLT_PREFIX) + 8 + 1))
  2161. && !strncmp(symbol_name, REAL_PLT_PREFIX,
  2162. strlen(REAL_PLT_PREFIX))) {
  2163. module->float_plt_count++;
  2164. }
  2165. }
  2166. }
  2167. }
  2168. /* Allocate memory for extra plt data */
  2169. size = sizeof(uint64) * 4 * module->ymm_plt_count
  2170. + sizeof(uint64) * 2 * module->xmm_plt_count
  2171. + sizeof(uint64) * module->real_plt_count
  2172. + sizeof(uint32) * module->float_plt_count;
  2173. if (size > 0) {
  2174. map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
  2175. /* aot code and data in x86_64 must be in range 0 to 2G due to
  2176. relocation for R_X86_64_32/32S/PC32 */
  2177. map_flags = MMAP_MAP_32BIT;
  2178. if (size > UINT32_MAX
  2179. || !(module->extra_plt_data =
  2180. os_mmap(NULL, (uint32)size, map_prot, map_flags,
  2181. os_get_invalid_handle()))) {
  2182. set_error_buf(error_buf, error_buf_size, "mmap memory failed");
  2183. goto fail;
  2184. }
  2185. module->extra_plt_data_size = (uint32)size;
  2186. }
  2187. #endif /* end of defined(BH_PLATFORM_WINDOWS) */
  2188. #if (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) \
  2189. && !defined(BH_PLATFORM_WINDOWS)
  2190. buf = symbol_buf_end;
  2191. read_uint32(buf, buf_end, group_count);
  2192. /* Resolve the relocations of type R_X86_64_GOTPCREL */
  2193. for (i = 0; i < group_count; i++) {
  2194. uint32 name_index, relocation_count;
  2195. uint16 group_name_len;
  2196. uint8 *group_name;
  2197. /* section name address is 4 bytes aligned. */
  2198. buf = (uint8 *)align_ptr(buf, sizeof(uint32));
  2199. read_uint32(buf, buf_end, name_index);
  2200. if (name_index >= symbol_count) {
  2201. set_error_buf(error_buf, error_buf_size,
  2202. "symbol index out of range");
  2203. goto fail;
  2204. }
  2205. group_name = symbol_buf + symbol_offsets[name_index];
  2206. group_name_len = *(uint16 *)group_name;
  2207. group_name += sizeof(uint16);
  2208. read_uint32(buf, buf_end, relocation_count);
  2209. for (j = 0; j < relocation_count; j++) {
  2210. AOTRelocation relocation = { 0 };
  2211. char group_name_buf[128] = { 0 };
  2212. char symbol_name_buf[128] = { 0 };
  2213. uint32 symbol_index;
  2214. uint16 symbol_name_len;
  2215. uint8 *symbol_name;
  2216. /* relocation offset and addend */
  2217. buf += sizeof(void *) * 2;
  2218. read_uint32(buf, buf_end, relocation.relocation_type);
  2219. read_uint32(buf, buf_end, symbol_index);
  2220. if (symbol_index >= symbol_count) {
  2221. set_error_buf(error_buf, error_buf_size,
  2222. "symbol index out of range");
  2223. goto fail;
  2224. }
  2225. symbol_name = symbol_buf + symbol_offsets[symbol_index];
  2226. symbol_name_len = *(uint16 *)symbol_name;
  2227. symbol_name += sizeof(uint16);
  2228. bh_memcpy_s(group_name_buf, (uint32)sizeof(group_name_buf),
  2229. group_name, group_name_len);
  2230. bh_memcpy_s(symbol_name_buf, (uint32)sizeof(symbol_name_buf),
  2231. symbol_name, symbol_name_len);
  2232. if (relocation.relocation_type == R_X86_64_GOTPCREL
  2233. && !strncmp(symbol_name_buf, AOT_FUNC_PREFIX,
  2234. strlen(AOT_FUNC_PREFIX))) {
  2235. uint32 func_idx =
  2236. atoi(symbol_name_buf + strlen(AOT_FUNC_PREFIX));
  2237. GOTItem *got_item = module->got_item_list;
  2238. if (func_idx >= module->func_count) {
  2239. set_error_buf(error_buf, error_buf_size,
  2240. "func index out of range");
  2241. goto fail;
  2242. }
  2243. while (got_item) {
  2244. if (got_item->func_idx == func_idx)
  2245. break;
  2246. got_item = got_item->next;
  2247. }
  2248. if (!got_item) {
  2249. /* Create the got item and append to the list */
  2250. got_item = wasm_runtime_malloc(sizeof(GOTItem));
  2251. if (!got_item) {
  2252. set_error_buf(error_buf, error_buf_size,
  2253. "allocate memory failed");
  2254. goto fail;
  2255. }
  2256. got_item->func_idx = func_idx;
  2257. got_item->next = NULL;
  2258. if (!module->got_item_list) {
  2259. module->got_item_list = module->got_item_list_end =
  2260. got_item;
  2261. }
  2262. else {
  2263. module->got_item_list_end->next = got_item;
  2264. module->got_item_list_end = got_item;
  2265. }
  2266. got_item_count++;
  2267. }
  2268. }
  2269. }
  2270. }
  2271. if (got_item_count) {
  2272. GOTItem *got_item = module->got_item_list;
  2273. uint32 got_item_idx = 0;
  2274. map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE;
  2275. /* aot code and data in x86_64 must be in range 0 to 2G due to
  2276. relocation for R_X86_64_32/32S/PC32 */
  2277. map_flags = MMAP_MAP_32BIT;
  2278. /* Create the GOT for func_ptrs, note that it is different from
  2279. the .got section of a dynamic object file */
  2280. size = (uint64)sizeof(void *) * got_item_count;
  2281. if (size > UINT32_MAX
  2282. || !(module->got_func_ptrs =
  2283. os_mmap(NULL, (uint32)size, map_prot, map_flags,
  2284. os_get_invalid_handle()))) {
  2285. set_error_buf(error_buf, error_buf_size, "mmap memory failed");
  2286. goto fail;
  2287. }
  2288. while (got_item) {
  2289. module->got_func_ptrs[got_item_idx++] =
  2290. module->func_ptrs[got_item->func_idx];
  2291. got_item = got_item->next;
  2292. }
  2293. module->got_item_count = got_item_count;
  2294. }
  2295. #else
  2296. (void)got_item_count;
  2297. #endif /* (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) && \
  2298. !defined(BH_PLATFORM_WINDOWS) */
  2299. buf = symbol_buf_end;
  2300. read_uint32(buf, buf_end, group_count);
  2301. /* Allocate memory for relocation groups */
  2302. size = sizeof(AOTRelocationGroup) * (uint64)group_count;
  2303. if (size > 0
  2304. && !(groups = loader_malloc(size, error_buf, error_buf_size))) {
  2305. goto fail;
  2306. }
  2307. /* Load each relocation group */
  2308. for (i = 0, group = groups; i < group_count; i++, group++) {
  2309. AOTRelocation *relocation;
  2310. uint32 name_index;
  2311. /* section name address is 4 bytes aligned. */
  2312. buf = (uint8 *)align_ptr(buf, sizeof(uint32));
  2313. read_uint32(buf, buf_end, name_index);
  2314. if (name_index >= symbol_count) {
  2315. set_error_buf(error_buf, error_buf_size,
  2316. "symbol index out of range");
  2317. goto fail;
  2318. }
  2319. if (symbols[name_index] == NULL) {
  2320. uint8 *name_addr = symbol_buf + symbol_offsets[name_index];
  2321. read_string(name_addr, buf_end, symbols[name_index]);
  2322. }
  2323. group->section_name = symbols[name_index];
  2324. read_uint32(buf, buf_end, group->relocation_count);
  2325. /* Allocate memory for relocations */
  2326. size = sizeof(AOTRelocation) * (uint64)group->relocation_count;
  2327. if (!(group->relocations = relocation =
  2328. loader_malloc(size, error_buf, error_buf_size))) {
  2329. ret = false;
  2330. goto fail;
  2331. }
  2332. /* Load each relocation */
  2333. for (j = 0; j < group->relocation_count; j++, relocation++) {
  2334. uint32 symbol_index;
  2335. if (sizeof(void *) == 8) {
  2336. read_uint64(buf, buf_end, relocation->relocation_offset);
  2337. read_uint64(buf, buf_end, relocation->relocation_addend);
  2338. }
  2339. else {
  2340. uint32 offset32, addend32;
  2341. read_uint32(buf, buf_end, offset32);
  2342. relocation->relocation_offset = (uint64)offset32;
  2343. read_uint32(buf, buf_end, addend32);
  2344. relocation->relocation_addend = (uint64)addend32;
  2345. }
  2346. read_uint32(buf, buf_end, relocation->relocation_type);
  2347. read_uint32(buf, buf_end, symbol_index);
  2348. if (symbol_index >= symbol_count) {
  2349. set_error_buf(error_buf, error_buf_size,
  2350. "symbol index out of range");
  2351. goto fail;
  2352. }
  2353. if (symbols[symbol_index] == NULL) {
  2354. uint8 *symbol_addr = symbol_buf + symbol_offsets[symbol_index];
  2355. read_string(symbol_addr, buf_end, symbols[symbol_index]);
  2356. }
  2357. relocation->symbol_name = symbols[symbol_index];
  2358. }
  2359. if (!strcmp(group->section_name, ".rel.text")
  2360. || !strcmp(group->section_name, ".rela.text")
  2361. || !strcmp(group->section_name, ".rela.literal")
  2362. #ifdef BH_PLATFORM_WINDOWS
  2363. || !strcmp(group->section_name, ".text")
  2364. #endif
  2365. ) {
  2366. #if !defined(BH_PLATFORM_LINUX) && !defined(BH_PLATFORM_LINUX_SGX) \
  2367. && !defined(BH_PLATFORM_DARWIN) && !defined(BH_PLATFORM_WINDOWS)
  2368. if (module->is_indirect_mode) {
  2369. set_error_buf(error_buf, error_buf_size,
  2370. "cannot apply relocation to text section "
  2371. "for aot file generated with "
  2372. "\"--enable-indirect-mode\" flag");
  2373. goto fail;
  2374. }
  2375. #endif
  2376. if (!do_text_relocation(module, group, error_buf, error_buf_size))
  2377. goto fail;
  2378. }
  2379. else {
  2380. if (!do_data_relocation(module, group, error_buf, error_buf_size))
  2381. goto fail;
  2382. }
  2383. }
  2384. /* Set read only for AOT code and some data sections */
  2385. map_prot = MMAP_PROT_READ | MMAP_PROT_EXEC;
  2386. if (module->code) {
  2387. /* The layout is: literal size + literal + code (with plt table) */
  2388. uint8 *mmap_addr = module->literal - sizeof(uint32);
  2389. uint32 total_size =
  2390. sizeof(uint32) + module->literal_size + module->code_size;
  2391. os_mprotect(mmap_addr, total_size, map_prot);
  2392. }
  2393. map_prot = MMAP_PROT_READ;
  2394. #if defined(BH_PLATFORM_WINDOWS)
  2395. if (module->extra_plt_data) {
  2396. os_mprotect(module->extra_plt_data, module->extra_plt_data_size,
  2397. map_prot);
  2398. }
  2399. #endif
  2400. for (i = 0; i < module->data_section_count; i++) {
  2401. AOTObjectDataSection *data_section = module->data_sections + i;
  2402. if (!strcmp(data_section->name, ".rdata")
  2403. || !strcmp(data_section->name, ".rodata")
  2404. /* ".rodata.cst4/8/16/.." */
  2405. || !strncmp(data_section->name, ".rodata.cst",
  2406. strlen(".rodata.cst"))
  2407. /* ".rodata.strn.m" */
  2408. || !strncmp(data_section->name, ".rodata.str",
  2409. strlen(".rodata.str"))) {
  2410. os_mprotect(data_section->data, data_section->size, map_prot);
  2411. }
  2412. }
  2413. ret = true;
  2414. fail:
  2415. if (symbols) {
  2416. wasm_runtime_free(symbols);
  2417. }
  2418. if (groups) {
  2419. for (i = 0, group = groups; i < group_count; i++, group++)
  2420. if (group->relocations)
  2421. wasm_runtime_free(group->relocations);
  2422. wasm_runtime_free(groups);
  2423. }
  2424. (void)map_flags;
  2425. return ret;
  2426. }
  2427. #if WASM_ENABLE_LINUX_PERF != 0
  2428. struct func_info {
  2429. uint32 idx;
  2430. void *ptr;
  2431. };
  2432. static uint32
  2433. get_func_size(const AOTModule *module, struct func_info *sorted_func_ptrs,
  2434. uint32 idx)
  2435. {
  2436. uint32 func_sz;
  2437. if (idx == module->func_count - 1)
  2438. func_sz = (uintptr_t)module->code + module->code_size
  2439. - (uintptr_t)(sorted_func_ptrs[idx].ptr);
  2440. else
  2441. func_sz = (uintptr_t)(sorted_func_ptrs[idx + 1].ptr)
  2442. - (uintptr_t)(sorted_func_ptrs[idx].ptr);
  2443. return func_sz;
  2444. }
  2445. static int
  2446. compare_func_ptrs(const void *f1, const void *f2)
  2447. {
  2448. return (intptr_t)((struct func_info *)f1)->ptr
  2449. - (intptr_t)((struct func_info *)f2)->ptr;
  2450. }
  2451. static struct func_info *
  2452. sort_func_ptrs(const AOTModule *module, char *error_buf, uint32 error_buf_size)
  2453. {
  2454. uint64 content_len;
  2455. struct func_info *sorted_func_ptrs;
  2456. unsigned i;
  2457. content_len = (uint64)sizeof(struct func_info) * module->func_count;
  2458. sorted_func_ptrs = loader_malloc(content_len, error_buf, error_buf_size);
  2459. if (!sorted_func_ptrs)
  2460. return NULL;
  2461. for (i = 0; i < module->func_count; i++) {
  2462. sorted_func_ptrs[i].idx = i;
  2463. sorted_func_ptrs[i].ptr = module->func_ptrs[i];
  2464. }
  2465. qsort(sorted_func_ptrs, module->func_count, sizeof(struct func_info),
  2466. compare_func_ptrs);
  2467. return sorted_func_ptrs;
  2468. }
  2469. static bool
  2470. create_perf_map(const AOTModule *module, char *error_buf, uint32 error_buf_size)
  2471. {
  2472. struct func_info *sorted_func_ptrs = NULL;
  2473. char perf_map_info[128] = { 0 };
  2474. FILE *perf_map = NULL;
  2475. uint32 i;
  2476. pid_t pid = getpid();
  2477. bool ret = false;
  2478. sorted_func_ptrs = sort_func_ptrs(module, error_buf, error_buf_size);
  2479. if (!sorted_func_ptrs)
  2480. goto quit;
  2481. snprintf(perf_map_info, 128, "/tmp/perf-%d.map", pid);
  2482. perf_map = fopen(perf_map_info, "w");
  2483. if (!perf_map) {
  2484. LOG_WARNING("warning: can't create /tmp/perf-%d.map, because %s", pid,
  2485. strerror(errno));
  2486. goto quit;
  2487. }
  2488. for (i = 0; i < module->func_count; i++) {
  2489. memset(perf_map_info, 0, 128);
  2490. snprintf(perf_map_info, 128, "%lx %x aot_func#%u\n",
  2491. (uintptr_t)sorted_func_ptrs[i].ptr,
  2492. get_func_size(module, sorted_func_ptrs, i),
  2493. sorted_func_ptrs[i].idx);
  2494. fwrite(perf_map_info, 1, strlen(perf_map_info), perf_map);
  2495. }
  2496. LOG_VERBOSE("generate /tmp/perf-%d.map", pid);
  2497. ret = true;
  2498. quit:
  2499. if (sorted_func_ptrs)
  2500. free(sorted_func_ptrs);
  2501. if (perf_map)
  2502. fclose(perf_map);
  2503. return ret;
  2504. }
  2505. #endif /* WASM_ENABLE_LINUX_PERF != 0*/
  2506. static bool
  2507. load_from_sections(AOTModule *module, AOTSection *sections,
  2508. bool is_load_from_file_buf, char *error_buf,
  2509. uint32 error_buf_size)
  2510. {
  2511. AOTSection *section = sections;
  2512. const uint8 *buf, *buf_end;
  2513. uint32 last_section_type = (uint32)-1, section_type;
  2514. uint32 i, func_index, func_type_index;
  2515. AOTFuncType *func_type;
  2516. AOTExport *exports;
  2517. while (section) {
  2518. buf = section->section_body;
  2519. buf_end = buf + section->section_body_size;
  2520. /* Check sections */
  2521. section_type = (uint32)section->section_type;
  2522. if ((last_section_type == (uint32)-1
  2523. && section_type != AOT_SECTION_TYPE_TARGET_INFO)
  2524. || (last_section_type != (uint32)-1
  2525. && (section_type != last_section_type + 1
  2526. && section_type != AOT_SECTION_TYPE_CUSTOM))) {
  2527. set_error_buf(error_buf, error_buf_size, "invalid section order");
  2528. return false;
  2529. }
  2530. last_section_type = section_type;
  2531. switch (section_type) {
  2532. case AOT_SECTION_TYPE_TARGET_INFO:
  2533. if (!load_target_info_section(buf, buf_end, module, error_buf,
  2534. error_buf_size))
  2535. return false;
  2536. break;
  2537. case AOT_SECTION_TYPE_INIT_DATA:
  2538. if (!load_init_data_section(buf, buf_end, module,
  2539. is_load_from_file_buf, error_buf,
  2540. error_buf_size))
  2541. return false;
  2542. break;
  2543. case AOT_SECTION_TYPE_TEXT:
  2544. if (!load_text_section(buf, buf_end, module, error_buf,
  2545. error_buf_size))
  2546. return false;
  2547. break;
  2548. case AOT_SECTION_TYPE_FUNCTION:
  2549. if (!load_function_section(buf, buf_end, module, error_buf,
  2550. error_buf_size))
  2551. return false;
  2552. break;
  2553. case AOT_SECTION_TYPE_EXPORT:
  2554. if (!load_export_section(buf, buf_end, module,
  2555. is_load_from_file_buf, error_buf,
  2556. error_buf_size))
  2557. return false;
  2558. break;
  2559. case AOT_SECTION_TYPE_RELOCATION:
  2560. if (!load_relocation_section(buf, buf_end, module,
  2561. is_load_from_file_buf, error_buf,
  2562. error_buf_size))
  2563. return false;
  2564. break;
  2565. case AOT_SECTION_TYPE_CUSTOM:
  2566. if (!load_custom_section(buf, buf_end, module,
  2567. is_load_from_file_buf, error_buf,
  2568. error_buf_size))
  2569. return false;
  2570. break;
  2571. default:
  2572. set_error_buf(error_buf, error_buf_size,
  2573. "invalid aot section type");
  2574. return false;
  2575. }
  2576. section = section->next;
  2577. }
  2578. if (last_section_type != AOT_SECTION_TYPE_RELOCATION
  2579. && last_section_type != AOT_SECTION_TYPE_CUSTOM) {
  2580. set_error_buf(error_buf, error_buf_size, "section missing");
  2581. return false;
  2582. }
  2583. /* Resolve malloc and free function */
  2584. module->malloc_func_index = (uint32)-1;
  2585. module->free_func_index = (uint32)-1;
  2586. module->retain_func_index = (uint32)-1;
  2587. exports = module->exports;
  2588. for (i = 0; i < module->export_count; i++) {
  2589. if (exports[i].kind == EXPORT_KIND_FUNC
  2590. && exports[i].index >= module->import_func_count) {
  2591. if (!strcmp(exports[i].name, "malloc")) {
  2592. func_index = exports[i].index - module->import_func_count;
  2593. func_type_index = module->func_type_indexes[func_index];
  2594. func_type = module->func_types[func_type_index];
  2595. if (func_type->param_count == 1 && func_type->result_count == 1
  2596. && func_type->types[0] == VALUE_TYPE_I32
  2597. && func_type->types[1] == VALUE_TYPE_I32) {
  2598. bh_assert(module->malloc_func_index == (uint32)-1);
  2599. module->malloc_func_index = func_index;
  2600. LOG_VERBOSE("Found malloc function, name: %s, index: %u",
  2601. exports[i].name, exports[i].index);
  2602. }
  2603. }
  2604. else if (!strcmp(exports[i].name, "__new")) {
  2605. func_index = exports[i].index - module->import_func_count;
  2606. func_type_index = module->func_type_indexes[func_index];
  2607. func_type = module->func_types[func_type_index];
  2608. if (func_type->param_count == 2 && func_type->result_count == 1
  2609. && func_type->types[0] == VALUE_TYPE_I32
  2610. && func_type->types[1] == VALUE_TYPE_I32
  2611. && func_type->types[2] == VALUE_TYPE_I32) {
  2612. uint32 j;
  2613. WASMExport *export_tmp;
  2614. bh_assert(module->malloc_func_index == (uint32)-1);
  2615. module->malloc_func_index = func_index;
  2616. LOG_VERBOSE("Found malloc function, name: %s, index: %u",
  2617. exports[i].name, exports[i].index);
  2618. /* resolve retain function.
  2619. If not find, reset malloc function index */
  2620. export_tmp = module->exports;
  2621. for (j = 0; j < module->export_count; j++, export_tmp++) {
  2622. if ((export_tmp->kind == EXPORT_KIND_FUNC)
  2623. && (!strcmp(export_tmp->name, "__retain")
  2624. || !strcmp(export_tmp->name, "__pin"))) {
  2625. func_index =
  2626. export_tmp->index - module->import_func_count;
  2627. func_type_index =
  2628. module->func_type_indexes[func_index];
  2629. func_type = module->func_types[func_type_index];
  2630. if (func_type->param_count == 1
  2631. && func_type->result_count == 1
  2632. && func_type->types[0] == VALUE_TYPE_I32
  2633. && func_type->types[1] == VALUE_TYPE_I32) {
  2634. bh_assert(module->retain_func_index
  2635. == (uint32)-1);
  2636. module->retain_func_index = export_tmp->index;
  2637. LOG_VERBOSE("Found retain function, name: %s, "
  2638. "index: %u",
  2639. export_tmp->name,
  2640. export_tmp->index);
  2641. break;
  2642. }
  2643. }
  2644. }
  2645. if (j == module->export_count) {
  2646. module->malloc_func_index = (uint32)-1;
  2647. LOG_VERBOSE("Can't find retain function,"
  2648. "reset malloc function index to -1");
  2649. }
  2650. }
  2651. }
  2652. else if ((!strcmp(exports[i].name, "free"))
  2653. || (!strcmp(exports[i].name, "__release"))
  2654. || (!strcmp(exports[i].name, "__unpin"))) {
  2655. func_index = exports[i].index - module->import_func_count;
  2656. func_type_index = module->func_type_indexes[func_index];
  2657. func_type = module->func_types[func_type_index];
  2658. if (func_type->param_count == 1 && func_type->result_count == 0
  2659. && func_type->types[0] == VALUE_TYPE_I32) {
  2660. bh_assert(module->free_func_index == (uint32)-1);
  2661. module->free_func_index = func_index;
  2662. LOG_VERBOSE("Found free function, name: %s, index: %u",
  2663. exports[i].name, exports[i].index);
  2664. }
  2665. }
  2666. }
  2667. }
  2668. /* Flush data cache before executing AOT code,
  2669. * otherwise unpredictable behavior can occur. */
  2670. os_dcache_flush();
  2671. #if WASM_ENABLE_MEMORY_TRACING != 0
  2672. wasm_runtime_dump_module_mem_consumption((WASMModuleCommon *)module);
  2673. #endif
  2674. #if WASM_ENABLE_DEBUG_AOT != 0
  2675. if (!jit_code_entry_create(module->elf_hdr, module->elf_size)) {
  2676. set_error_buf(error_buf, error_buf_size,
  2677. "create jit code entry failed");
  2678. return false;
  2679. }
  2680. #endif
  2681. return true;
  2682. }
  2683. static AOTModule *
  2684. create_module(char *error_buf, uint32 error_buf_size)
  2685. {
  2686. AOTModule *module =
  2687. loader_malloc(sizeof(AOTModule), error_buf, error_buf_size);
  2688. bh_list_status ret;
  2689. if (!module) {
  2690. return NULL;
  2691. }
  2692. module->module_type = Wasm_Module_AoT;
  2693. #if WASM_ENABLE_MULTI_MODULE != 0
  2694. module->import_module_list = &module->import_module_list_head;
  2695. ret = bh_list_init(module->import_module_list);
  2696. bh_assert(ret == BH_LIST_SUCCESS);
  2697. #endif
  2698. (void)ret;
  2699. return module;
  2700. }
  2701. AOTModule *
  2702. aot_load_from_sections(AOTSection *section_list, char *error_buf,
  2703. uint32 error_buf_size)
  2704. {
  2705. AOTModule *module = create_module(error_buf, error_buf_size);
  2706. if (!module)
  2707. return NULL;
  2708. if (!load_from_sections(module, section_list, false, error_buf,
  2709. error_buf_size)) {
  2710. aot_unload(module);
  2711. return NULL;
  2712. }
  2713. LOG_VERBOSE("Load module from sections success.\n");
  2714. return module;
  2715. }
  2716. static void
  2717. destroy_sections(AOTSection *section_list, bool destroy_aot_text)
  2718. {
  2719. AOTSection *section = section_list, *next;
  2720. while (section) {
  2721. next = section->next;
  2722. if (destroy_aot_text && section->section_type == AOT_SECTION_TYPE_TEXT
  2723. && section->section_body)
  2724. os_munmap((uint8 *)section->section_body,
  2725. section->section_body_size);
  2726. wasm_runtime_free(section);
  2727. section = next;
  2728. }
  2729. }
  2730. static bool
  2731. resolve_execute_mode(const uint8 *buf, uint32 size, bool *p_mode,
  2732. char *error_buf, uint32 error_buf_size)
  2733. {
  2734. const uint8 *p = buf, *p_end = buf + size;
  2735. uint32 section_type;
  2736. uint32 section_size = 0;
  2737. uint16 e_type = 0;
  2738. p += 8;
  2739. while (p < p_end) {
  2740. read_uint32(p, p_end, section_type);
  2741. if (section_type <= AOT_SECTION_TYPE_SIGANATURE
  2742. || section_type == AOT_SECTION_TYPE_TARGET_INFO) {
  2743. read_uint32(p, p_end, section_size);
  2744. CHECK_BUF(p, p_end, section_size);
  2745. if (section_type == AOT_SECTION_TYPE_TARGET_INFO) {
  2746. p += 4;
  2747. read_uint16(p, p_end, e_type);
  2748. if (e_type == E_TYPE_XIP) {
  2749. *p_mode = true;
  2750. }
  2751. else {
  2752. *p_mode = false;
  2753. }
  2754. break;
  2755. }
  2756. }
  2757. else if (section_type > AOT_SECTION_TYPE_SIGANATURE) {
  2758. set_error_buf(error_buf, error_buf_size,
  2759. "resolve execute mode failed");
  2760. break;
  2761. }
  2762. p += section_size;
  2763. }
  2764. return true;
  2765. fail:
  2766. return false;
  2767. }
  2768. static bool
  2769. create_sections(AOTModule *module, const uint8 *buf, uint32 size,
  2770. AOTSection **p_section_list, char *error_buf,
  2771. uint32 error_buf_size)
  2772. {
  2773. AOTSection *section_list = NULL, *section_list_end = NULL, *section;
  2774. const uint8 *p = buf, *p_end = buf + size;
  2775. bool destroy_aot_text = false;
  2776. bool is_indirect_mode = false;
  2777. uint32 section_type;
  2778. uint32 section_size;
  2779. uint64 total_size;
  2780. uint8 *aot_text;
  2781. #if (WASM_MEM_DUAL_BUS_MIRROR != 0)
  2782. uint8 *mirrored_text;
  2783. #endif
  2784. if (!resolve_execute_mode(buf, size, &is_indirect_mode, error_buf,
  2785. error_buf_size)) {
  2786. goto fail;
  2787. }
  2788. module->is_indirect_mode = is_indirect_mode;
  2789. p += 8;
  2790. while (p < p_end) {
  2791. read_uint32(p, p_end, section_type);
  2792. if (section_type < AOT_SECTION_TYPE_SIGANATURE
  2793. || section_type == AOT_SECTION_TYPE_CUSTOM) {
  2794. read_uint32(p, p_end, section_size);
  2795. CHECK_BUF(p, p_end, section_size);
  2796. if (!(section = loader_malloc(sizeof(AOTSection), error_buf,
  2797. error_buf_size))) {
  2798. goto fail;
  2799. }
  2800. memset(section, 0, sizeof(AOTSection));
  2801. section->section_type = (int32)section_type;
  2802. section->section_body = (uint8 *)p;
  2803. section->section_body_size = section_size;
  2804. if (section_type == AOT_SECTION_TYPE_TEXT) {
  2805. if ((section_size > 0) && !module->is_indirect_mode) {
  2806. int map_prot =
  2807. MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
  2808. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
  2809. || defined(BUILD_TARGET_RISCV64_LP64D) \
  2810. || defined(BUILD_TARGET_RISCV64_LP64)
  2811. /* aot code and data in x86_64 must be in range 0 to 2G due
  2812. to relocation for R_X86_64_32/32S/PC32 */
  2813. int map_flags = MMAP_MAP_32BIT;
  2814. #else
  2815. int map_flags = MMAP_MAP_NONE;
  2816. #endif
  2817. total_size =
  2818. (uint64)section_size + aot_get_plt_table_size();
  2819. total_size = (total_size + 3) & ~((uint64)3);
  2820. if (total_size >= UINT32_MAX
  2821. || !(aot_text =
  2822. os_mmap(NULL, (uint32)total_size, map_prot,
  2823. map_flags, os_get_invalid_handle()))) {
  2824. wasm_runtime_free(section);
  2825. set_error_buf(error_buf, error_buf_size,
  2826. "mmap memory failed");
  2827. goto fail;
  2828. }
  2829. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
  2830. #if !defined(BH_PLATFORM_LINUX_SGX) && !defined(BH_PLATFORM_WINDOWS) \
  2831. && !defined(BH_PLATFORM_DARWIN)
  2832. /* address must be in the first 2 Gigabytes of
  2833. the process address space */
  2834. bh_assert((uintptr_t)aot_text < INT32_MAX);
  2835. #endif
  2836. #endif
  2837. #if (WASM_MEM_DUAL_BUS_MIRROR != 0)
  2838. mirrored_text = os_get_dbus_mirror(aot_text);
  2839. bh_assert(mirrored_text != NULL);
  2840. bh_memcpy_s(mirrored_text, (uint32)total_size,
  2841. section->section_body, (uint32)section_size);
  2842. os_dcache_flush();
  2843. #else
  2844. bh_memcpy_s(aot_text, (uint32)total_size,
  2845. section->section_body, (uint32)section_size);
  2846. #endif
  2847. section->section_body = aot_text;
  2848. destroy_aot_text = true;
  2849. if ((uint32)total_size > section->section_body_size) {
  2850. memset(aot_text + (uint32)section_size, 0,
  2851. (uint32)total_size - section_size);
  2852. section->section_body_size = (uint32)total_size;
  2853. }
  2854. }
  2855. }
  2856. if (!section_list)
  2857. section_list = section_list_end = section;
  2858. else {
  2859. section_list_end->next = section;
  2860. section_list_end = section;
  2861. }
  2862. p += section_size;
  2863. }
  2864. else {
  2865. set_error_buf(error_buf, error_buf_size, "invalid section id");
  2866. goto fail;
  2867. }
  2868. }
  2869. if (!section_list) {
  2870. set_error_buf(error_buf, error_buf_size, "create section list failed");
  2871. return false;
  2872. }
  2873. *p_section_list = section_list;
  2874. return true;
  2875. fail:
  2876. if (section_list)
  2877. destroy_sections(section_list, destroy_aot_text);
  2878. return false;
  2879. }
  2880. static bool
  2881. load(const uint8 *buf, uint32 size, AOTModule *module, char *error_buf,
  2882. uint32 error_buf_size)
  2883. {
  2884. const uint8 *buf_end = buf + size;
  2885. const uint8 *p = buf, *p_end = buf_end;
  2886. uint32 magic_number, version;
  2887. AOTSection *section_list = NULL;
  2888. bool ret;
  2889. read_uint32(p, p_end, magic_number);
  2890. if (magic_number != AOT_MAGIC_NUMBER) {
  2891. set_error_buf(error_buf, error_buf_size, "magic header not detected");
  2892. return false;
  2893. }
  2894. read_uint32(p, p_end, version);
  2895. if (version != AOT_CURRENT_VERSION) {
  2896. set_error_buf(error_buf, error_buf_size, "unknown binary version");
  2897. return false;
  2898. }
  2899. if (!create_sections(module, buf, size, &section_list, error_buf,
  2900. error_buf_size))
  2901. return false;
  2902. ret = load_from_sections(module, section_list, true, error_buf,
  2903. error_buf_size);
  2904. if (!ret) {
  2905. /* If load_from_sections() fails, then aot text is destroyed
  2906. in destroy_sections() */
  2907. destroy_sections(section_list, module->is_indirect_mode ? false : true);
  2908. /* aot_unload() won't destroy aot text again */
  2909. module->code = NULL;
  2910. }
  2911. else {
  2912. /* If load_from_sections() succeeds, then aot text is set to
  2913. module->code and will be destroyed in aot_unload() */
  2914. destroy_sections(section_list, false);
  2915. }
  2916. #if 0
  2917. {
  2918. uint32 i;
  2919. for (i = 0; i < module->func_count; i++) {
  2920. os_printf("AOT func %u, addr: %p\n", i, module->func_ptrs[i]);
  2921. }
  2922. }
  2923. #endif
  2924. #if WASM_ENABLE_LINUX_PERF != 0
  2925. if (wasm_runtime_get_linux_perf())
  2926. if (!create_perf_map(module, error_buf, error_buf_size))
  2927. goto fail;
  2928. #endif
  2929. return ret;
  2930. fail:
  2931. return false;
  2932. }
  2933. AOTModule *
  2934. aot_load_from_aot_file(const uint8 *buf, uint32 size, char *error_buf,
  2935. uint32 error_buf_size)
  2936. {
  2937. AOTModule *module = create_module(error_buf, error_buf_size);
  2938. if (!module)
  2939. return NULL;
  2940. os_thread_jit_write_protect_np(false); /* Make memory writable */
  2941. if (!load(buf, size, module, error_buf, error_buf_size)) {
  2942. aot_unload(module);
  2943. return NULL;
  2944. }
  2945. os_thread_jit_write_protect_np(true); /* Make memory executable */
  2946. os_icache_flush(module->code, module->code_size);
  2947. LOG_VERBOSE("Load module success.\n");
  2948. return module;
  2949. }
  2950. void
  2951. aot_unload(AOTModule *module)
  2952. {
  2953. if (module->import_memories)
  2954. destroy_import_memories(module->import_memories);
  2955. if (module->memories)
  2956. wasm_runtime_free(module->memories);
  2957. if (module->mem_init_data_list)
  2958. destroy_mem_init_data_list(module->mem_init_data_list,
  2959. module->mem_init_data_count);
  2960. if (module->native_symbol_list)
  2961. wasm_runtime_free(module->native_symbol_list);
  2962. if (module->import_tables)
  2963. destroy_import_tables(module->import_tables);
  2964. if (module->tables)
  2965. destroy_tables(module->tables);
  2966. if (module->table_init_data_list)
  2967. destroy_table_init_data_list(module->table_init_data_list,
  2968. module->table_init_data_count);
  2969. if (module->func_types)
  2970. destroy_func_types(module->func_types, module->func_type_count);
  2971. if (module->import_globals)
  2972. destroy_import_globals(module->import_globals);
  2973. if (module->globals)
  2974. destroy_globals(module->globals);
  2975. if (module->import_funcs)
  2976. destroy_import_funcs(module->import_funcs);
  2977. if (module->exports)
  2978. destroy_exports(module->exports);
  2979. if (module->func_type_indexes)
  2980. wasm_runtime_free(module->func_type_indexes);
  2981. if (module->func_ptrs)
  2982. wasm_runtime_free(module->func_ptrs);
  2983. if (module->const_str_set)
  2984. bh_hash_map_destroy(module->const_str_set);
  2985. #if WASM_ENABLE_MULTI_MODULE != 0
  2986. /* just release the sub module list */
  2987. if (module->import_module_list) {
  2988. WASMRegisteredModule *node =
  2989. bh_list_first_elem(module->import_module_list);
  2990. while (node) {
  2991. WASMRegisteredModule *next = bh_list_elem_next(node);
  2992. bh_list_remove(module->import_module_list, node);
  2993. wasm_runtime_free(node);
  2994. node = next;
  2995. }
  2996. }
  2997. #endif
  2998. if (module->code && !module->is_indirect_mode) {
  2999. /* The layout is: literal size + literal + code (with plt table) */
  3000. uint8 *mmap_addr = module->literal - sizeof(uint32);
  3001. uint32 total_size =
  3002. sizeof(uint32) + module->literal_size + module->code_size;
  3003. os_munmap(mmap_addr, total_size);
  3004. }
  3005. #if defined(BH_PLATFORM_WINDOWS)
  3006. if (module->extra_plt_data) {
  3007. os_munmap(module->extra_plt_data, module->extra_plt_data_size);
  3008. }
  3009. #endif
  3010. #if (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) \
  3011. && !defined(BH_PLATFORM_WINDOWS)
  3012. {
  3013. GOTItem *got_item = module->got_item_list, *got_item_next;
  3014. if (module->got_func_ptrs) {
  3015. os_munmap(module->got_func_ptrs,
  3016. sizeof(void *) * module->got_item_count);
  3017. }
  3018. while (got_item) {
  3019. got_item_next = got_item->next;
  3020. wasm_runtime_free(got_item);
  3021. got_item = got_item_next;
  3022. }
  3023. }
  3024. #endif
  3025. if (module->data_sections)
  3026. destroy_object_data_sections(module->data_sections,
  3027. module->data_section_count);
  3028. #if WASM_ENABLE_DEBUG_AOT != 0
  3029. jit_code_entry_destroy(module->elf_hdr);
  3030. #endif
  3031. #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
  3032. if (module->aux_func_indexes) {
  3033. wasm_runtime_free(module->aux_func_indexes);
  3034. }
  3035. if (module->aux_func_names) {
  3036. wasm_runtime_free((void *)module->aux_func_names);
  3037. }
  3038. #endif
  3039. #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
  3040. wasm_runtime_destroy_custom_sections(module->custom_section_list);
  3041. #endif
  3042. wasm_runtime_free(module);
  3043. }
  3044. uint32
  3045. aot_get_plt_table_size()
  3046. {
  3047. return get_plt_table_size();
  3048. }
  3049. #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
  3050. const uint8 *
  3051. aot_get_custom_section(const AOTModule *module, const char *name, uint32 *len)
  3052. {
  3053. WASMCustomSection *section = module->custom_section_list;
  3054. while (section) {
  3055. if (strcmp(section->name_addr, name) == 0) {
  3056. if (len) {
  3057. *len = section->content_len;
  3058. }
  3059. return section->content_addr;
  3060. }
  3061. section = section->next;
  3062. }
  3063. return NULL;
  3064. }
  3065. #endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION */
  3066. #if WASM_ENABLE_STATIC_PGO != 0
  3067. void
  3068. aot_exchange_uint16(uint8 *p_data)
  3069. {
  3070. return exchange_uint16(p_data);
  3071. }
  3072. void
  3073. aot_exchange_uint32(uint8 *p_data)
  3074. {
  3075. return exchange_uint32(p_data);
  3076. }
  3077. void
  3078. aot_exchange_uint64(uint8 *p_data)
  3079. {
  3080. return exchange_uint64(p_data);
  3081. }
  3082. #endif