• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  * conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  * of conditions and the following disclaimer in the documentation and/or other materials
13  * provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  * to endorse or promote products derived from this software without specific prior written
17  * permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/mman.h>
33 #include "los_lms_pri.h"
34 #include "debug.h"
35 
36 #define LMS_FREE_NODE_SIZE 16
37 
38 struct MmapNode {
39     uintptr_t addr;
40     size_t mapSize;
41     struct MmapNode *next;
42 };
43 
44 struct MmapNode g_freeNode[LMS_FREE_NODE_SIZE];
45 
46 struct MmapNode *g_mmapNode = NULL;
47 
48 uint32_t g_shadowStartAddr = SHADOW_BASE;
49 
50 pthread_mutex_t g_lmsMutex = PTHREAD_MUTEX_INITIALIZER;
51 
LmsMem2Shadow(uintptr_t memAddr,uintptr_t * shadowAddr,uint32_t * shadowOffset)52 ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsMem2Shadow(uintptr_t memAddr, uintptr_t *shadowAddr, uint32_t *shadowOffset)
53 {
54     uint32_t memOffset = memAddr - USPACE_MAP_BASE;
55     *shadowAddr = g_shadowStartAddr + memOffset / LMS_SHADOW_U8_REFER_BYTES;
56     *shadowOffset = ((memOffset % LMS_SHADOW_U8_REFER_BYTES) / LMS_SHADOW_U8_CELL_NUM) * LMS_SHADOW_BITS_PER_CELL;
57 }
58 
LmsIsShadowAddrMapped(uintptr_t sdStartAddr,uintptr_t sdEndAddr)59 ATTRIBUTE_NO_SANITIZE_ADDRESS uint32_t LmsIsShadowAddrMapped(uintptr_t sdStartAddr, uintptr_t sdEndAddr)
60 {
61     struct MmapNode *node = g_mmapNode;
62     while (node != NULL) {
63         if ((sdStartAddr >= node->addr) && (sdEndAddr < node->addr + node->mapSize)) {
64             return LMS_OK;
65         }
66         node = node->next;
67     }
68     return LMS_NOK;
69 }
70 
LmsAddMapNode(uintptr_t sdStartAddr,uintptr_t sdEndAddr)71 ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsAddMapNode(uintptr_t sdStartAddr, uintptr_t sdEndAddr)
72 {
73     static uint32_t freeNodeIdx = 0;
74     struct MmapNode *node = g_mmapNode;
75     size_t mapSize;
76     uintptr_t shadowPageStartAddr = LMS_MEM_ALIGN_DOWN(sdStartAddr, 0x1000);
77     uintptr_t shadowPageEndAddr = LMS_MEM_ALIGN_UP(sdEndAddr, 0x1000);
78 
79     struct MmapNode *expandNode = NULL;
80 
81     while (node != NULL) {
82         if ((shadowPageStartAddr >= node->addr) && (shadowPageStartAddr <= node->addr + node->mapSize)) {
83             expandNode = node;
84             break;
85         }
86         node = node->next;
87     }
88 
89     if (expandNode != NULL) {
90         shadowPageStartAddr = expandNode->addr + expandNode->mapSize;
91         expandNode->mapSize = shadowPageEndAddr - expandNode->addr;
92     }
93 
94     mapSize = shadowPageEndAddr - shadowPageStartAddr;
95     void *mapPtr =
96         mmap((void *)shadowPageStartAddr, mapSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
97     if (mapPtr == (void *)-1) {
98         LMS_OUTPUT_INFO("mmap error! file:%s line:%d\n", __FILE__, __LINE__);
99         return;
100     }
101     __real_memset(mapPtr, 0, mapSize);
102 
103     if (expandNode != NULL) {
104         return;
105     }
106 
107     if (freeNodeIdx >= LMS_FREE_NODE_SIZE) {
108         LMS_OUTPUT_INFO("Add new mmap node error! file:%s line:%d\n", __FILE__, __LINE__);
109         return;
110     }
111 
112     struct MmapNode *newNode = &g_freeNode[freeNodeIdx];
113     freeNodeIdx++;
114     newNode->addr = shadowPageStartAddr;
115     newNode->mapSize = mapSize;
116     newNode->next = g_mmapNode;
117     g_mmapNode = newNode;
118 }
119 
LmsSetShadowValue(uintptr_t startAddr,uintptr_t endAddr,char value)120 ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsSetShadowValue(uintptr_t startAddr, uintptr_t endAddr, char value)
121 {
122     uintptr_t shadowStart;
123     uintptr_t shadowEnd;
124     uint32_t startOffset;
125     uint32_t endOffset;
126 
127     unsigned char shadowValueMask;
128     unsigned char shadowValue;
129 
130     /* endAddr - 1, then we mark [startAddr, endAddr) to value */
131     LmsMem2Shadow(startAddr, &shadowStart, &startOffset);
132     LmsMem2Shadow(endAddr - 1, &shadowEnd, &endOffset);
133 
134     if (shadowStart == shadowEnd) { /* in the same u8 */
135         /* because endAddr - 1, the endOffset falls into the previous cell,
136         so endOffset + 2 is required for calculation */
137         shadowValueMask = LMS_SHADOW_MASK_U8;
138         shadowValueMask =
139             (shadowValueMask << startOffset) & (~(shadowValueMask << (endOffset + LMS_SHADOW_BITS_PER_CELL)));
140         shadowValue = value & shadowValueMask;
141         *(char *)shadowStart &= ~shadowValueMask;
142         *(char *)shadowStart |= shadowValue;
143     } else {
144         /* Adjust startAddr to left util it reach the beginning of a u8 */
145         if (startOffset > 0) {
146             shadowValueMask = LMS_SHADOW_MASK_U8;
147             shadowValueMask = shadowValueMask << startOffset;
148             shadowValue = value & shadowValueMask;
149             *(char *)shadowStart &= ~shadowValueMask;
150             *(char *)shadowStart |= shadowValue;
151             shadowStart += 1;
152         }
153 
154         /* Adjust endAddr to right util it reach the end of a u8 */
155         if (endOffset < (LMS_SHADOW_U8_CELL_NUM - 1) * LMS_SHADOW_BITS_PER_CELL) {
156             shadowValueMask = LMS_SHADOW_MASK_U8;
157             shadowValueMask &= ~(shadowValueMask << (endOffset + LMS_SHADOW_BITS_PER_CELL));
158             shadowValue = value & shadowValueMask;
159             *(char *)shadowEnd &= ~shadowValueMask;
160             *(char *)shadowEnd |= shadowValue;
161             shadowEnd -= 1;
162         }
163 
164         if (shadowEnd + 1 > shadowStart) {
165             (void)__real_memset((void *)shadowStart, value & LMS_SHADOW_MASK_U8, shadowEnd + 1 - shadowStart);
166         }
167     }
168 }
169 
LmsGetShadowValue(uintptr_t addr,uint32_t * shadowValue)170 ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsGetShadowValue(uintptr_t addr, uint32_t *shadowValue)
171 {
172     uintptr_t shadowAddr;
173     uint32_t shadowOffset;
174     LmsMem2Shadow(addr, &shadowAddr, &shadowOffset);
175     /* If the shadow addr is not mapped then regarded as legal access */
176     if (LmsIsShadowAddrMapped(shadowAddr, shadowAddr) != LMS_OK) {
177         *shadowValue = LMS_SHADOW_ACCESSIBLE_U8;
178         return;
179     }
180 
181     *shadowValue = ((*(char *)shadowAddr) >> shadowOffset) & LMS_SHADOW_MASK;
182 }
183 
LmsMallocMark(uintptr_t preRzStart,uintptr_t accessMemStart,uintptr_t nextRzStart,uintptr_t RzEndAddr)184 ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsMallocMark(uintptr_t preRzStart, uintptr_t accessMemStart, uintptr_t nextRzStart,
185     uintptr_t RzEndAddr)
186 {
187     LmsSetShadowValue(preRzStart, accessMemStart, LMS_SHADOW_REDZONE_U8);
188     LmsSetShadowValue(accessMemStart, nextRzStart, LMS_SHADOW_ACCESSIBLE_U8);
189     LmsSetShadowValue(nextRzStart, RzEndAddr, LMS_SHADOW_REDZONE_U8);
190 }
191 
LmsTagMem(void * ptr,size_t origSize)192 ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsTagMem(void *ptr, size_t origSize)
193 {
194     g_shadowStartAddr = SHADOW_BASE;
195     size_t mSize = malloc_usable_size(ptr);
196     uint32_t memOffset = (uintptr_t)ptr + mSize + OVERHEAD - USPACE_MAP_BASE;
197     uintptr_t shadowEndAddr = g_shadowStartAddr + memOffset / LMS_SHADOW_U8_REFER_BYTES;
198     LMS_OUTPUT_INFO("SHADOW_BASE:%x g_shadowStartAddr:%x memOffset: %x\n", SHADOW_BASE, g_shadowStartAddr, memOffset);
199     memOffset = (uintptr_t)ptr - OVERHEAD - USPACE_MAP_BASE;
200     uintptr_t shadowStartAddr = g_shadowStartAddr + memOffset / LMS_SHADOW_U8_REFER_BYTES;
201 
202     LmsLock(&g_lmsMutex);
203     if (LmsIsShadowAddrMapped(shadowStartAddr, shadowEndAddr) != LMS_OK) {
204         LmsAddMapNode(shadowStartAddr, shadowEndAddr);
205     }
206 
207     LmsMallocMark((uintptr_t)ptr - OVERHEAD, (uintptr_t)ptr, (uintptr_t)ptr + LMS_MEM_ALIGN_UP(origSize, LMS_RZ_SIZE),
208         (uintptr_t)((uintptr_t)ptr + mSize + OVERHEAD));
209     LmsUnlock(&g_lmsMutex);
210 
211     return ptr;
212 }
213 
LmsCheckAddr(uintptr_t addr)214 ATTRIBUTE_NO_SANITIZE_ADDRESS uint32_t LmsCheckAddr(uintptr_t addr)
215 {
216     LmsLock(&g_lmsMutex);
217     uint32_t shadowValue = -1;
218     LmsGetShadowValue(addr, &shadowValue);
219     LmsUnlock(&g_lmsMutex);
220     return shadowValue;
221 }
222 
LmsCheckAddrRegion(uintptr_t addr,size_t size)223 ATTRIBUTE_NO_SANITIZE_ADDRESS uint32_t LmsCheckAddrRegion(uintptr_t addr, size_t size)
224 {
225     if (LmsCheckAddr(addr) || LmsCheckAddr(addr + size - 1)) {
226         return LMS_NOK;
227     } else {
228         return LMS_OK;
229     }
230 }
231 
LmsPrintMemInfo(uintptr_t addr)232 ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsPrintMemInfo(uintptr_t addr)
233 {
234 #define LMS_DUMP_OFFSET 4
235 #define LMS_DUMP_RANGE_DOUBLE 2
236 
237     LMS_OUTPUT_INFO("\nDump info around address [0x%8x]:\n", addr);
238     uint32_t printY = LMS_DUMP_OFFSET * LMS_DUMP_RANGE_DOUBLE + 1;
239     uint32_t printX = LMS_MEM_BYTES_PER_SHADOW_CELL * LMS_DUMP_RANGE_DOUBLE;
240     uintptr_t dumpAddr = addr - addr % printX - LMS_DUMP_OFFSET * printX;
241     uint32_t shadowValue = 0;
242     uintptr_t shadowAddr = 0;
243     uint32_t shadowOffset = 0;
244     int isCheckAddr;
245 
246     for (int y = 0; y < printY; y++, dumpAddr += printX) {
247         LmsMem2Shadow(dumpAddr, &shadowAddr, &shadowOffset);
248         /* find util dumpAddr in pool region */
249         if (LmsIsShadowAddrMapped(shadowAddr, shadowAddr) != LMS_OK) {
250             continue;
251         }
252         uintptr_t maxShadowAddr;
253         uint32_t maxShadowOffset;
254         LmsMem2Shadow(dumpAddr + printX, &maxShadowAddr, &maxShadowOffset);
255         /* finish if dumpAddr exceeds pool's upper region */
256         if (LmsIsShadowAddrMapped(maxShadowAddr, maxShadowAddr) != LMS_OK) {
257             goto END;
258         }
259 
260         LMS_OUTPUT_INFO("\n\t[0x%x]: ", dumpAddr);
261         for (int x = 0; x < printX; x++) {
262             if (dumpAddr + x == addr) {
263                 LMS_OUTPUT_INFO("[%02x]", *(uint8_t *)(dumpAddr + x));
264             } else {
265                 LMS_OUTPUT_INFO(" %02x ", *(uint8_t *)(dumpAddr + x));
266             }
267         }
268 
269         LMS_OUTPUT_INFO("|\t[0x%x | %2u]: ", shadowAddr, shadowOffset);
270 
271         for (int x = 0; x < printX; x += LMS_MEM_BYTES_PER_SHADOW_CELL) {
272             LmsGetShadowValue(dumpAddr + x, &shadowValue);
273             isCheckAddr = dumpAddr + x - (uintptr_t)addr + LMS_MEM_BYTES_PER_SHADOW_CELL;
274             if (isCheckAddr > 0 && isCheckAddr <= LMS_MEM_BYTES_PER_SHADOW_CELL) {
275                 LMS_OUTPUT_INFO("[%1x]", shadowValue);
276             } else {
277                 LMS_OUTPUT_INFO(" %1x ", shadowValue);
278             }
279         }
280     }
281 END:
282     LMS_OUTPUT_INFO("\n");
283 }
284 
LmsGetShadowInfo(uintptr_t memAddr,LmsAddrInfo * info)285 ATTRIBUTE_NO_SANITIZE_ADDRESS static inline void LmsGetShadowInfo(uintptr_t memAddr, LmsAddrInfo *info)
286 {
287     uintptr_t shadowAddr;
288     uint32_t shadowOffset;
289     uint32_t shadowValue;
290 
291     LmsMem2Shadow(memAddr, &shadowAddr, &shadowOffset);
292 
293     shadowValue = ((*(char *)shadowAddr) >> shadowOffset) & LMS_SHADOW_MASK;
294     info->memAddr = memAddr;
295     info->shadowAddr = shadowAddr;
296     info->shadowOffset = shadowOffset;
297     info->shadowValue = shadowValue;
298 }
299 
LmsGetErrorInfo(uintptr_t addr,size_t size,LmsAddrInfo * info)300 ATTRIBUTE_NO_SANITIZE_ADDRESS static void LmsGetErrorInfo(uintptr_t addr, size_t size, LmsAddrInfo *info)
301 {
302     LmsGetShadowInfo(addr, info);
303     if (info->shadowValue != LMS_SHADOW_ACCESSIBLE_U8) {
304         return;
305     } else {
306         LmsGetShadowInfo(addr + size - 1, info);
307     }
308 }
309 
LmsPrintErrInfo(LmsAddrInfo * info,uint32_t errMod)310 ATTRIBUTE_NO_SANITIZE_ADDRESS static void LmsPrintErrInfo(LmsAddrInfo *info, uint32_t errMod)
311 {
312     switch (info->shadowValue) {
313         case LMS_SHADOW_AFTERFREE:
314             LMS_OUTPUT_ERROR("Use after free error detected!\n");
315             break;
316         case LMS_SHADOW_REDZONE:
317             LMS_OUTPUT_ERROR("Heap buffer overflow error detected!\n");
318             break;
319         case LMS_SHADOW_ACCESSIBLE:
320             LMS_OUTPUT_ERROR("No error!\n");
321             break;
322         default:
323             LMS_OUTPUT_ERROR("UnKnown Error detected!\n");
324             break;
325     }
326 
327     switch (errMod) {
328         case FREE_ERRORMODE:
329             LMS_OUTPUT_ERROR("Illegal Double free address at: [0x%x]\n", info->memAddr);
330             break;
331         case LOAD_ERRMODE:
332             LMS_OUTPUT_ERROR("Illegal READ address at: [0x%x]\n", info->memAddr);
333             break;
334         case STORE_ERRMODE:
335             LMS_OUTPUT_ERROR("Illegal WRITE address at: [0x%x]\n", info->memAddr);
336             break;
337         default:
338             LMS_OUTPUT_ERROR("UnKnown Error mode at: [0x%x]\n", info->memAddr);
339             break;
340     }
341 
342     LMS_OUTPUT_INFO("Shadow memory address: [0x%x : %u]  Shadow memory value: [%u] \n", info->shadowAddr,
343         info->shadowOffset, info->shadowValue);
344 
345     LMS_OUTPUT_INFO("\n");
346     LMS_OUTPUT_INFO("%-25s%d\n", "Accessible heap addr", LMS_SHADOW_ACCESSIBLE);
347     LMS_OUTPUT_INFO("%-25s%d\n", "Heap red zone", LMS_SHADOW_REDZONE);
348     LMS_OUTPUT_INFO("%-25s%d\n", "Heap freed buffer", LMS_SHADOW_AFTERFREE);
349     LMS_OUTPUT_INFO("\n");
350 }
351 
LmsReportError(uintptr_t p,size_t size,uint32_t errMod)352 ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsReportError(uintptr_t p, size_t size, uint32_t errMod)
353 {
354     LmsAddrInfo info;
355     (void)__real_memset(&info, 0, sizeof(LmsAddrInfo));
356 
357     int locked = LmsTrylock(&g_lmsMutex);
358     LMS_OUTPUT_ERROR("\n*****  Lite Memory Sanitizer Error Detected  *****\n");
359     LmsGetErrorInfo(p, size, &info);
360     LmsPrintErrInfo(&info, errMod);
361     LmsPrintMemInfo(info.memAddr);
362     LMS_OUTPUT_ERROR("*****  Lite Memory Sanitizer Error Detected End *****\n");
363     if (!locked) {
364         LmsUnlock(&g_lmsMutex);
365     }
366 
367     if (LMS_CRASH_MODE > 0) {
368         LmsCrash();
369     } else {
370         print_trace();
371     }
372 }
373 
LmsCheckValid(const char * dest,const char * src)374 void LmsCheckValid(const char *dest, const char *src)
375 {
376     if (LmsCheckAddr((uintptr_t)dest) != LMS_SHADOW_ACCESSIBLE_U8) {
377         LmsReportError((uintptr_t)dest, MEM_REGION_SIZE_1, STORE_ERRMODE);
378         return;
379     }
380 
381     if (LmsCheckAddr((uintptr_t)src) != LMS_SHADOW_ACCESSIBLE_U8) {
382         LmsReportError((uintptr_t)src, MEM_REGION_SIZE_1, LOAD_ERRMODE);
383         return;
384     }
385 
386     for (uint32_t i = 0; *(src + i) != '\0'; i++) {
387         if (LmsCheckAddr((uintptr_t)dest + i + 1) != LMS_SHADOW_ACCESSIBLE_U8) {
388             LmsReportError((uintptr_t)dest + i + 1, MEM_REGION_SIZE_1, STORE_ERRMODE);
389             return;
390         }
391 
392         if (LmsCheckAddr((uintptr_t)src + i + 1) != LMS_SHADOW_ACCESSIBLE_U8) {
393             LmsReportError((uintptr_t)src + i + 1, MEM_REGION_SIZE_1, LOAD_ERRMODE);
394             return;
395         }
396     }
397 }
398 
__asan_store1_noabort(uintptr_t p)399 void __asan_store1_noabort(uintptr_t p)
400 {
401     if (LmsCheckAddr(p) != LMS_SHADOW_ACCESSIBLE_U8) {
402         LmsReportError(p, MEM_REGION_SIZE_1, STORE_ERRMODE);
403     }
404 }
405 
__asan_store2_noabort(uintptr_t p)406 void __asan_store2_noabort(uintptr_t p)
407 {
408     if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_2) != LMS_OK) {
409         LmsReportError(p, MEM_REGION_SIZE_2, STORE_ERRMODE);
410     }
411 }
412 
__asan_store4_noabort(uintptr_t p)413 void __asan_store4_noabort(uintptr_t p)
414 {
415     if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_4) != LMS_OK) {
416         LmsReportError(p, MEM_REGION_SIZE_4, STORE_ERRMODE);
417     }
418 }
419 
__asan_store8_noabort(uintptr_t p)420 void __asan_store8_noabort(uintptr_t p)
421 {
422     if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_8) != LMS_OK) {
423         LmsReportError(p, MEM_REGION_SIZE_8, STORE_ERRMODE);
424     }
425 }
426 
__asan_store16_noabort(uintptr_t p)427 void __asan_store16_noabort(uintptr_t p)
428 {
429     if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_16) != LMS_OK) { /* 16 byte memory for check */
430         LmsReportError(p, MEM_REGION_SIZE_16, STORE_ERRMODE);
431     }
432 }
433 
__asan_storeN_noabort(uintptr_t p,size_t size)434 void __asan_storeN_noabort(uintptr_t p, size_t size)
435 {
436     if (LmsCheckAddrRegion(p, size) != LMS_OK) {
437         LmsReportError(p, size, STORE_ERRMODE);
438     }
439 }
440 
__asan_load1_noabort(uintptr_t p)441 void __asan_load1_noabort(uintptr_t p)
442 {
443     if (LmsCheckAddr(p) != LMS_SHADOW_ACCESSIBLE_U8) {
444         LmsReportError(p, MEM_REGION_SIZE_1, LOAD_ERRMODE);
445     }
446 }
447 
__asan_load2_noabort(uintptr_t p)448 void __asan_load2_noabort(uintptr_t p)
449 {
450     if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_2) != LMS_OK) {
451         LmsReportError(p, MEM_REGION_SIZE_2, LOAD_ERRMODE);
452     }
453 }
454 
__asan_load4_noabort(uintptr_t p)455 void __asan_load4_noabort(uintptr_t p)
456 {
457     if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_4) != LMS_OK) {
458         LmsReportError(p, MEM_REGION_SIZE_4, LOAD_ERRMODE);
459     }
460 }
461 
__asan_load8_noabort(uintptr_t p)462 void __asan_load8_noabort(uintptr_t p)
463 {
464     if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_8) != LMS_OK) {
465         LmsReportError(p, MEM_REGION_SIZE_8, LOAD_ERRMODE);
466     }
467 }
468 
__asan_load16_noabort(uintptr_t p)469 void __asan_load16_noabort(uintptr_t p)
470 {
471     if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_16) != LMS_OK) {
472         LmsReportError(p, MEM_REGION_SIZE_16, LOAD_ERRMODE);
473     }
474 }
475 
__asan_loadN_noabort(uintptr_t p,size_t size)476 void __asan_loadN_noabort(uintptr_t p, size_t size)
477 {
478     if (LmsCheckAddrRegion(p, size) != LMS_OK) {
479         LmsReportError(p, size, LOAD_ERRMODE);
480     }
481 }
482 
__asan_handle_no_return(void)483 void __asan_handle_no_return(void)
484 {
485     return;
486 }