更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
los_load_elf.c 文件参考

浏览源代码.

函数

STATIC INT32 OsELFOpen (const CHAR *fileName, INT32 oflags)
 打开ELF文件 更多...
 
STATIC INT32 OsELFClose (INT32 procFd)
 
STATIC INT32 OsGetFileLength (UINT32 *fileLen, const CHAR *fileName)
 
STATIC INT32 OsReadELFInfo (INT32 procfd, UINT8 *buffer, size_t readSize, off_t offset)
 
STATIC INT32 OsVerifyELFEhdr (const LD_ELF_EHDR *ehdr, UINT32 fileLen)
 
STATIC INT32 OsVerifyELFPhdr (const LD_ELF_PHDR *phdr)
 
STATIC VOID OsLoadInit (ELFLoadInfo *loadInfo)
 
STATIC INT32 OsReadEhdr (const CHAR *fileName, ELFInfo *elfInfo, BOOL isExecFile)
 
STATIC INT32 OsReadPhdrs (ELFInfo *elfInfo, BOOL isExecFile)
 
STATIC INT32 OsReadInterpInfo (ELFLoadInfo *loadInfo)
 
STATIC UINT32 OsGetProt (UINT32 pFlags)
 
STATIC UINT32 OsGetAllocSize (const LD_ELF_PHDR *elfPhdr, INT32 phdrNum)
 
STATIC UINTPTR OsDoMmapFile (INT32 fd, UINTPTR addr, const LD_ELF_PHDR *elfPhdr, UINT32 prot, UINT32 flags, UINT32 mapSize)
 
INT32 OsGetKernelVaddr (LosVmSpace *space, VADDR_T vaddr, VADDR_T *kvaddr)
 
STATIC INT32 OsSetBss (const LD_ELF_PHDR *elfPhdr, INT32 fd, UINTPTR bssStart, UINT32 bssEnd, UINT32 elfProt)
 
STATIC INT32 OsMmapELFFile (INT32 procfd, const LD_ELF_PHDR *elfPhdr, const LD_ELF_EHDR *elfEhdr, UINTPTR *elfLoadAddr, UINT32 mapSize, UINTPTR *loadBase)
 
STATIC INT32 OsLoadInterpBinary (ELFLoadInfo *loadInfo, UINTPTR *interpMapBase)
 
STATIC CHAROsGetParamPtr (CHAR *const *ptr, INT32 index)
 
STATIC INT32 OsPutUserArg (INT32 val, const UINTPTR *sp)
 
STATIC INT32 OsPutUserArgv (UINTPTR *strPtr, UINTPTR **sp, INT32 count)
 
STATIC INT32 OsCopyParams (ELFLoadInfo *loadInfo, INT32 argc, CHAR *const *argv)
 
STATIC INT32 OsGetParamNum (CHAR *const *argv)
 
UINT32 OsGetRndOffset (INT32 randomDevFD)
 
STATIC VOID OsGetStackProt (ELFLoadInfo *loadInfo)
 
STATIC UINT32 OsStackAlloc (LosVmSpace *space, VADDR_T vaddr, UINT32 vsize, UINT32 psize, UINT32 regionFlags)
 分配栈区 更多...
 
STATIC INT32 OsSetArgParams (ELFLoadInfo *loadInfo, CHAR *const *argv, CHAR *const *envp)
 
STATIC INT32 OsPutParamToStack (ELFLoadInfo *loadInfo, const UINTPTR *auxVecInfo, INT32 vecIndex)
 
STATIC INT32 OsGetRndNum (const ELFLoadInfo *loadInfo, UINT32 *rndVec, UINT32 vecSize)
 
STATIC INT32 OsMakeArgsStack (ELFLoadInfo *loadInfo, UINTPTR interpMapBase)
 
STATIC INT32 OsLoadELFSegment (ELFLoadInfo *loadInfo)
 
STATIC VOID OsFlushAspace (ELFLoadInfo *loadInfo)
 
STATIC VOID OsDeInitLoadInfo (ELFLoadInfo *loadInfo)
 
STATIC VOID OsDeInitFiles (ELFLoadInfo *loadInfo)
 
INT32 OsLoadELFFile (ELFLoadInfo *loadInfo)
 

变量

STATIC BOOL g_srandInit
 

函数说明

◆ OsCopyParams()

STATIC INT32 OsCopyParams ( ELFLoadInfo loadInfo,
INT32  argc,
CHAR *const *  argv 
)

在文件 los_load_elf.c637 行定义.

638{
639 CHAR *strPtr = NULL;
640 UINT32 offset, strLen;
641 errno_t err;
642 INT32 ret, i;
643 vaddr_t kvaddr = 0;
644
645 if ((argc > 0) && (argv == NULL)) {
646 return -EINVAL;
647 }
648
649 ret = OsGetKernelVaddr(loadInfo->newSpace, loadInfo->stackParamBase, &kvaddr);
650 if (ret != LOS_OK) {
651 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
652 return -EFAULT;
653 }
654
655 for (i = argc - 1; i >= 0; --i) {
656 strPtr = OsGetParamPtr(argv, i);
657 if (LOS_IsKernelAddress((VADDR_T)(UINTPTR)strPtr)) {
658 strLen = strlen(strPtr) + 1;
659 } else {
660 strLen = LOS_StrnlenUser(strPtr, PATH_MAX);
661 }
662 if (strLen < 1) {
663 continue;
664 }
665
666 offset = loadInfo->topOfMem - loadInfo->stackParamBase;
667 if (offset < strLen) {
668 PRINT_ERR("%s[%d], The size of param is out of limit: %#x bytes!\n", __FUNCTION__, __LINE__,
669 USER_PARAM_BYTE_MAX);
670 return -E2BIG;
671 }
672 loadInfo->topOfMem -= strLen;
673 offset -= strLen;
674
675 /* copy strings to user stack */
676 if (LOS_IsKernelAddress((VADDR_T)(UINTPTR)strPtr)) {
677 err = memcpy_s((VOID *)(UINTPTR)(kvaddr + offset), strLen, strPtr, strLen);
678 } else {
679 err = LOS_ArchCopyFromUser((VOID *)(UINTPTR)(kvaddr + offset), strPtr, strLen);
680 }
681
682 if (err != EOK) {
683 PRINT_ERR("%s[%d], copy strings failed! err: %d\n", __FUNCTION__, __LINE__, err);
684 return -EFAULT;
685 }
686 }
687
688 return LOS_OK;
689}
INT32 OsGetKernelVaddr(LosVmSpace *space, VADDR_T vaddr, VADDR_T *kvaddr)
Definition: los_load_elf.c:423
STATIC CHAR * OsGetParamPtr(CHAR *const *ptr, INT32 index)
Definition: los_load_elf.c:564
signed int INT32
Definition: los_typedef.h:60
unsigned long vaddr_t
Definition: los_typedef.h:206
unsigned long VADDR_T
Definition: los_typedef.h:208
unsigned long UINTPTR
Definition: los_typedef.h:68
unsigned int UINT32
Definition: los_typedef.h:57
char CHAR
Definition: los_typedef.h:63
STATIC INLINE BOOL LOS_IsKernelAddress(VADDR_T vaddr)
虚拟地址是否在内核空间
Definition: los_vm_map.h:213
INT32 LOS_StrnlenUser(const CHAR *src, INT32 count)
Definition: strnlen_user.c:37
UINTPTR topOfMem
虚拟空间顶部位置,loadInfo->topOfMem = loadInfo->stackTopMax - sizeof(UINTPTR);
Definition: los_load_elf.h:119
UINTPTR stackParamBase
栈参数空间,放置启动ELF时的外部参数,大小为 USER_PARAM_BYTE_MAX 4K
Definition: los_load_elf.h:113
LosVmSpace * newSpace
新虚拟空间
Definition: los_load_elf.h:121
size_t LOS_ArchCopyFromUser(void *dst, const void *src, size_t len)
Definition: user_copy.c:58
函数调用图:
这是这个函数的调用关系图:

◆ OsDeInitFiles()

STATIC VOID OsDeInitFiles ( ELFLoadInfo loadInfo)

在文件 los_load_elf.c1028 行定义.

1029{
1030 if (loadInfo->execInfo.procfd != INVALID_FD) {
1031 (VOID)OsELFClose(loadInfo->execInfo.procfd);
1032 }
1033
1034 if (loadInfo->interpInfo.procfd != INVALID_FD) {
1035 (VOID)OsELFClose(loadInfo->interpInfo.procfd);
1036 }
1037#ifdef LOSCFG_FS_VFS
1038 delete_files_snapshot((struct files_struct *)loadInfo->oldFiles);
1039#endif
1040}
void delete_files_snapshot(struct files_struct *files)
删除文件管理器快照
STATIC INT32 OsELFClose(INT32 procFd)
Definition: los_load_elf.c:76
INT32 procfd
文件描述符
Definition: los_load_elf.h:95
ELFInfo execInfo
可执行文件信息
Definition: los_load_elf.h:102
UINTPTR oldFiles
旧空间的文件映像
Definition: los_load_elf.h:120
ELFInfo interpInfo
解析器文件信息 lib/libc.so
Definition: los_load_elf.h:103
函数调用图:
这是这个函数的调用关系图:

◆ OsDeInitLoadInfo()

STATIC VOID OsDeInitLoadInfo ( ELFLoadInfo loadInfo)

在文件 los_load_elf.c1015 行定义.

1016{
1017 (VOID)close(loadInfo->randomDevFD);
1018
1019 if (loadInfo->execInfo.elfPhdr != NULL) {
1020 (VOID)LOS_MemFree(m_aucSysMem0, loadInfo->execInfo.elfPhdr);
1021 }
1022
1023 if (loadInfo->interpInfo.elfPhdr != NULL) {
1024 (VOID)LOS_MemFree(m_aucSysMem0, loadInfo->interpInfo.elfPhdr);
1025 }
1026}
UINT32 LOS_MemFree(VOID *pool, VOID *ptr)
释放从指定动态内存中申请的内存
Definition: los_memory.c:1369
UINT8 * m_aucSysMem0
异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。
Definition: los_memory.c:107
LD_ELF_PHDR * elfPhdr
ELF程序头信息,也称段头信息
Definition: los_load_elf.h:93
INT32 randomDevFD
Definition: los_load_elf.h:123
函数调用图:
这是这个函数的调用关系图:

◆ OsDoMmapFile()

STATIC UINTPTR OsDoMmapFile ( INT32  fd,
UINTPTR  addr,
const LD_ELF_PHDR *  elfPhdr,
UINT32  prot,
UINT32  flags,
UINT32  mapSize 
)

在文件 los_load_elf.c399 行定义.

401{
402 UINTPTR mapAddr;
403 UINT32 size;
404 UINT32 offset = elfPhdr->offset - ROUNDOFFSET(elfPhdr->vAddr, PAGE_SIZE);
405 addr = ROUNDDOWN(addr, PAGE_SIZE);
406
407 if (mapSize != 0) {
408 mapAddr = (UINTPTR)LOS_MMap(addr, mapSize, prot, flags, fd, offset >> PAGE_SHIFT);
409 } else {
410 size = elfPhdr->memSize + ROUNDOFFSET(elfPhdr->vAddr, PAGE_SIZE);
411 if (size == 0) {
412 return addr;
413 }
414 mapAddr = (UINTPTR)LOS_MMap(addr, size, prot, flags, fd, offset >> PAGE_SHIFT);
415 }
416 if (!LOS_IsUserAddress((VADDR_T)mapAddr)) {
417 PRINT_ERR("%s %d, Failed to map a valid addr\n", __FUNCTION__, __LINE__);
418 return 0;
419 }
420 return mapAddr;
421}
STATIC INLINE BOOL LOS_IsUserAddress(VADDR_T vaddr)
虚拟地址是否在用户空间
Definition: los_vm_map.h:275
VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags, int fd, unsigned long pgoff)
函数调用图:
这是这个函数的调用关系图:

◆ OsELFClose()

STATIC INT32 OsELFClose ( INT32  procFd)

在文件 los_load_elf.c76 行定义.

77{
78 INT32 ret;
79 /* Process procfd convert to system global procfd */
80 INT32 sysfd = DisassociateProcessFd(procFd);
81 if (sysfd < 0) {
82 return -EBADF;
83 }
84
85 ret = close(sysfd);
86 if (ret < 0) {
87 AssociateSystemFd(procFd, sysfd);
88 return -get_errno();
89 }
90 FreeProcessFd(procFd);
91 return ret;
92}
void AssociateSystemFd(int procFd, int sysFd)
参数进程FD和参数系统FD进行绑定(关联)
Definition: vfs_procfd.c:105
void FreeProcessFd(int procFd)
释放进程文件描述符
Definition: vfs_procfd.c:191
int DisassociateProcessFd(int procFd)
解绑系统文件描述符,返回系统文件描述符
Definition: vfs_procfd.c:206
函数调用图:
这是这个函数的调用关系图:

◆ OsELFOpen()

STATIC INT32 OsELFOpen ( const CHAR fileName,
INT32  oflags 
)

打开ELF文件

在文件 los_load_elf.c52 行定义.

53{
54 INT32 ret = -LOS_NOK;
55 INT32 procFd;
56
57 procFd = AllocProcessFd();//分配一个文件描述符
58 if (procFd < 0) {
59 return -EMFILE;
60 }
61
62 if (oflags & O_CLOEXEC) {
63 SetCloexecFlag(procFd);
64 }
65
66 ret = open(fileName, oflags);//打开文件
67 if (ret < 0) {
68 FreeProcessFd(procFd);
69 return -get_errno();
70 }
71
72 AssociateSystemFd(procFd, ret);//分配一个系统描述符
73 return procFd;
74}
void SetCloexecFlag(int procFd)
Definition: vfs_cloexec.c:62
int AllocProcessFd(void)
分配文件描述符
Definition: vfs_procfd.c:228
函数调用图:
这是这个函数的调用关系图:

◆ OsFlushAspace()

STATIC VOID OsFlushAspace ( ELFLoadInfo loadInfo)

在文件 los_load_elf.c1010 行定义.

1011{
1012 loadInfo->oldSpace = OsExecProcessVmSpaceReplace(loadInfo->newSpace, loadInfo->stackBase, loadInfo->randomDevFD);
1013}
LITE_OS_SEC_TEXT LosVmSpace * OsExecProcessVmSpaceReplace(LosVmSpace *newSpace, UINTPTR stackBase, INT32 randomDevFD)
Definition: los_process.c:1541
LosVmSpace * oldSpace
旧虚拟空间
Definition: los_load_elf.h:122
UINTPTR stackBase
栈顶位置,栈基地址
Definition: los_load_elf.h:112
函数调用图:
这是这个函数的调用关系图:

◆ OsGetAllocSize()

STATIC UINT32 OsGetAllocSize ( const LD_ELF_PHDR *  elfPhdr,
INT32  phdrNum 
)

在文件 los_load_elf.c364 行定义.

365{
366 const LD_ELF_PHDR *elfPhdrTemp = elfPhdr;
367 UINTPTR addrMin = SIZE_MAX;
368 UINTPTR addrMax = 0;
369 UINT32 offStart = 0;
370 UINT64 size;
371 INT32 i;
372
373 for (i = 0; i < phdrNum; ++i, ++elfPhdrTemp) {
374 if (elfPhdrTemp->type != LD_PT_LOAD) {
375 continue;
376 }
377
378 if (OsVerifyELFPhdr(elfPhdrTemp) != LOS_OK) {
379 return 0;
380 }
381
382 if (elfPhdrTemp->vAddr < addrMin) {
383 addrMin = elfPhdrTemp->vAddr;
384 offStart = elfPhdrTemp->offset;
385 }
386 if ((elfPhdrTemp->vAddr + elfPhdrTemp->memSize) > addrMax) {
387 addrMax = elfPhdrTemp->vAddr + elfPhdrTemp->memSize;
388 }
389 }
390
391 if (OsIsBadUserAddress((VADDR_T)addrMax) || OsIsBadUserAddress((VADDR_T)addrMin) || (addrMax < addrMin)) {
392 return 0;
393 }
394 size = ROUNDUP(addrMax, PAGE_SIZE) - ROUNDDOWN(addrMin, PAGE_SIZE) + ROUNDDOWN(offStart, PAGE_SIZE);
395
396 return (size > UINT_MAX) ? 0 : (UINT32)size;
397}
STATIC INT32 OsVerifyELFPhdr(const LD_ELF_PHDR *phdr)
Definition: los_load_elf.c:180
STATIC INLINE BOOL OsIsBadUserAddress(VADDR_T vaddr)
不超过用户空间顶部位置
Definition: los_load_elf.h:126
long unsigned int UINT64
Definition: los_typedef.h:66
函数调用图:
这是这个函数的调用关系图:

◆ OsGetFileLength()

STATIC INT32 OsGetFileLength ( UINT32 fileLen,
const CHAR fileName 
)

在文件 los_load_elf.c94 行定义.

95{
96 struct stat buf;
97 INT32 ret;
98
99 ret = stat(fileName, &buf);
100 if (ret < 0) {
101#ifndef LOSCFG_SHELL
102 if (strcmp(fileName, "/bin/shell") != 0) {
103#endif
104 PRINT_ERR("%s[%d], Failed to stat file: %s, errno: %d\n", __FUNCTION__, __LINE__, fileName, errno);
105#ifndef LOSCFG_SHELL
106 }
107#endif
108 return LOS_NOK;
109 }
110
111 if (S_ISREG(buf.st_mode) == 0) {
112 PRINT_ERR("%s[%d], The file: %s is invalid!\n", __FUNCTION__, __LINE__, fileName);
113 return LOS_NOK;
114 }
115 if (buf.st_size > FILE_LENGTH_MAX) {
116 PRINT_ERR("%s[%d], The file: %s length is out of limit!\n", __FUNCTION__, __LINE__, fileName);
117 return LOS_NOK;
118 }
119
120 *fileLen = (UINT32)buf.st_size;
121 return LOS_OK;
122}
这是这个函数的调用关系图:

◆ OsGetKernelVaddr()

INT32 OsGetKernelVaddr ( LosVmSpace space,
VADDR_T  vaddr,
VADDR_T kvaddr 
)

在文件 los_load_elf.c423 行定义.

424{
425 INT32 ret;
426 PADDR_T paddr = 0;
427
428 if ((space == NULL) || (vaddr == 0) || (kvaddr == NULL)) {
429 PRINT_ERR("%s[%d], space: %#x, vaddr: %#x\n", __FUNCTION__, __LINE__, space, vaddr);
430 return LOS_NOK;
431 }
432
433 if (LOS_IsKernelAddress(vaddr)) {
434 *kvaddr = vaddr;
435 return LOS_OK;
436 }
437
438 ret = LOS_ArchMmuQuery(&space->archMmu, vaddr, &paddr, NULL);
439 if (ret != LOS_OK) {
440 PRINT_ERR("%s[%d], Failed to query the vaddr: %#x, status: %d\n", __FUNCTION__, __LINE__, vaddr, ret);
441 return LOS_NOK;
442 }
443 *kvaddr = (VADDR_T)(UINTPTR)LOS_PaddrToKVaddr(paddr);
444 if (*kvaddr == 0) {
445 PRINT_ERR("%s[%d], kvaddr is null\n", __FUNCTION__, __LINE__);
446 return LOS_NOK;
447 }
448
449 return LOS_OK;
450}
STATUS_T LOS_ArchMmuQuery(const LosArchMmu *archMmu, VADDR_T vaddr, PADDR_T *paddr, UINT32 *flags)
LOS_ArchMmuQuery 获取进程空间虚拟地址对应的物理地址以及映射属性。 本函数是内核高频函数,通过MMU查询虚拟地址是否映射过,带走映射的物理地址和权限
Definition: los_arch_mmu.c:569
unsigned long PADDR_T
Definition: los_typedef.h:207
VADDR_T * LOS_PaddrToKVaddr(PADDR_T paddr)
通过物理地址获取内核虚拟地址
Definition: los_vm_phys.c:688
LosArchMmu archMmu
Definition: los_vm_map.h:157
函数调用图:
这是这个函数的调用关系图:

◆ OsGetParamNum()

STATIC INT32 OsGetParamNum ( CHAR *const *  argv)

在文件 los_load_elf.c691 行定义.

692{
693 CHAR *argPtr = NULL;
694 INT32 count = 0;
695 INT32 ret;
696
697 if (argv == NULL) {
698 return count;
699 }
700
701 argPtr = OsGetParamPtr(argv, count);
702 while (argPtr != NULL) {
703 ret = LOS_StrnlenUser(argPtr, PATH_MAX);
704 if ((ret == 0) || (ret > PATH_MAX)) {
705 PRINT_ERR("%s[%d], the len of string of argv is invalid, index: %d, len: %d\n", __FUNCTION__,
706 __LINE__, count, ret);
707 break;
708 }
709 ++count;
710 if (count >= STRINGS_COUNT_MAX) {
711 break;
712 }
713 argPtr = OsGetParamPtr(argv, count);
714 }
715
716 return count;
717}
函数调用图:
这是这个函数的调用关系图:

◆ OsGetParamPtr()

STATIC CHAR * OsGetParamPtr ( CHAR *const *  ptr,
INT32  index 
)

在文件 los_load_elf.c564 行定义.

565{
566 UINTPTR userStrPtr = 0;
567 INT32 ret;
568
569 if (ptr == NULL) {
570 return NULL;
571 }
572
573 if (LOS_IsKernelAddress((UINTPTR)ptr)) {
574 return ptr[index];
575 }
576 ret = LOS_GetUser(&userStrPtr, (UINTPTR *)(ptr + index));
577 if (ret != LOS_OK) {
578 PRINT_ERR("%s[%d], %#x\n", __FUNCTION__, __LINE__, ptr);
579 return NULL;
580 }
581
582 return (CHAR *)userStrPtr;
583}
函数调用图:
这是这个函数的调用关系图:

◆ OsGetProt()

STATIC UINT32 OsGetProt ( UINT32  pFlags)

在文件 los_load_elf.c354 行定义.

355{
356 UINT32 prot;
357
358 prot = (((pFlags & PF_R) ? PROT_READ : 0) |
359 ((pFlags & PF_W) ? PROT_WRITE : 0) |
360 ((pFlags & PF_X) ? PROT_EXEC : 0));
361 return prot;
362}
这是这个函数的调用关系图:

◆ OsGetRndNum()

STATIC INT32 OsGetRndNum ( const ELFLoadInfo loadInfo,
UINT32 rndVec,
UINT32  vecSize 
)

在文件 los_load_elf.c881 行定义.

882{
883 UINT32 randomValue = 0;
884 UINT32 i, ret;
885
886 for (i = 0; i < vecSize; ++i) {
887 ret = read(loadInfo->randomDevFD, &randomValue, sizeof(UINT32));
888 if (ret != sizeof(UINT32)) {
889 rndVec[i] = (UINT32)random();
890 continue;
891 }
892 rndVec[i] = randomValue;
893 }
894
895 return LOS_OK;
896}
这是这个函数的调用关系图:

◆ OsGetRndOffset()

UINT32 OsGetRndOffset ( INT32  randomDevFD)

在文件 los_load_elf.c719 行定义.

720{
721 UINT32 randomValue = 0;
722
723#ifdef LOSCFG_ASLR
724 if (read(randomDevFD, &randomValue, sizeof(UINT32)) == sizeof(UINT32)) {
725 randomValue &= RANDOM_MASK;
726 } else {
727 randomValue = (UINT32)random() & RANDOM_MASK;
728 }
729#else
730 (VOID)randomDevFD;
731#endif
732
733 return ROUNDDOWN(randomValue, PAGE_SIZE);
734}
这是这个函数的调用关系图:

◆ OsGetStackProt()

STATIC VOID OsGetStackProt ( ELFLoadInfo loadInfo)

在文件 los_load_elf.c736 行定义.

737{
738 LD_ELF_PHDR *elfPhdrTemp = loadInfo->execInfo.elfPhdr;
739 INT32 i;
740
741 for (i = 0; i < loadInfo->execInfo.elfEhdr.elfPhNum; ++i, ++elfPhdrTemp) {
742 if (elfPhdrTemp->type == LD_PT_GNU_STACK) {
743 loadInfo->stackProt = OsGetProt(elfPhdrTemp->flags);
744 }
745 }
746}
STATIC UINT32 OsGetProt(UINT32 pFlags)
Definition: los_load_elf.c:354
LD_ELF_EHDR elfEhdr
ELF头信息
Definition: los_load_elf.h:92
INT32 stackProt
LD_PT_GNU_STACK栈的权限 ,例如(RW)
Definition: los_load_elf.h:115
函数调用图:
这是这个函数的调用关系图:

◆ OsLoadELFFile()

INT32 OsLoadELFFile ( ELFLoadInfo loadInfo)

在文件 los_load_elf.c1042 行定义.

1043{
1044 INT32 ret;
1045
1046 OsLoadInit(loadInfo);
1047
1048 ret = OsReadEhdr(loadInfo->fileName, &loadInfo->execInfo, TRUE);
1049 if (ret != LOS_OK) {
1050 goto OUT;
1051 }
1052
1053 ret = OsReadPhdrs(&loadInfo->execInfo, TRUE);
1054 if (ret != LOS_OK) {
1055 goto OUT;
1056 }
1057
1058 ret = OsReadInterpInfo(loadInfo);
1059 if (ret != LOS_OK) {
1060 goto OUT;
1061 }
1062
1063 ret = OsSetArgParams(loadInfo, loadInfo->argv, loadInfo->envp);
1064 if (ret != LOS_OK) {
1065 goto OUT;
1066 }
1067
1068 OsFlushAspace(loadInfo);
1069
1070 ret = OsLoadELFSegment(loadInfo);
1071 if (ret != LOS_OK) {
1073 goto OUT;
1074 }
1075
1076 OsDeInitLoadInfo(loadInfo);
1077
1078 return LOS_OK;
1079
1080OUT:
1081 OsDeInitFiles(loadInfo);
1082 (VOID)LOS_VmSpaceFree(loadInfo->newSpace);
1083 (VOID)OsDeInitLoadInfo(loadInfo);
1084 return ret;
1085}
STATIC VOID OsFlushAspace(ELFLoadInfo *loadInfo)
STATIC INT32 OsReadPhdrs(ELFInfo *elfInfo, BOOL isExecFile)
Definition: los_load_elf.c:253
STATIC VOID OsLoadInit(ELFLoadInfo *loadInfo)
Definition: los_load_elf.c:198
STATIC VOID OsDeInitFiles(ELFLoadInfo *loadInfo)
STATIC INT32 OsReadInterpInfo(ELFLoadInfo *loadInfo)
Definition: los_load_elf.c:292
STATIC INT32 OsSetArgParams(ELFLoadInfo *loadInfo, CHAR *const *argv, CHAR *const *envp)
Definition: los_load_elf.c:791
STATIC INT32 OsReadEhdr(const CHAR *fileName, ELFInfo *elfInfo, BOOL isExecFile)
Definition: los_load_elf.c:210
STATIC INT32 OsLoadELFSegment(ELFLoadInfo *loadInfo)
Definition: los_load_elf.c:956
STATIC VOID OsDeInitLoadInfo(ELFLoadInfo *loadInfo)
LITE_OS_SEC_TEXT VOID OsExecProcessVmSpaceRestore(LosVmSpace *oldSpace)
Definition: los_process.c:1531
STATUS_T LOS_VmSpaceFree(LosVmSpace *space)
CHAR *const * envp
环境变量数组
Definition: los_load_elf.h:109
CHAR *const * argv
参数数组
Definition: los_load_elf.h:108
const CHAR * fileName
文件名称
Definition: los_load_elf.h:104
函数调用图:
这是这个函数的调用关系图:

◆ OsLoadELFSegment()

STATIC INT32 OsLoadELFSegment ( ELFLoadInfo loadInfo)

在文件 los_load_elf.c956 行定义.

957{
958 LD_ELF_PHDR *elfPhdrTemp = loadInfo->execInfo.elfPhdr;
959 UINTPTR loadBase = 0;
960 UINTPTR interpMapBase = 0;
961 UINT32 mapSize = 0;
962 INT32 ret;
963 loadInfo->loadAddr = 0;
964
965 if (loadInfo->execInfo.elfEhdr.elfType == LD_ET_DYN) {
966 loadBase = EXEC_MMAP_BASE + OsGetRndOffset(loadInfo->randomDevFD);
967 mapSize = OsGetAllocSize(elfPhdrTemp, loadInfo->execInfo.elfEhdr.elfPhNum);
968 if (mapSize == 0) {
969 PRINT_ERR("%s[%d], Failed to get allocation size of file: %s!\n", __FUNCTION__, __LINE__,
970 loadInfo->fileName);
971 return -EINVAL;
972 }
973 }
974
975 ret = OsMmapELFFile(loadInfo->execInfo.procfd, loadInfo->execInfo.elfPhdr, &loadInfo->execInfo.elfEhdr,
976 &loadInfo->loadAddr, mapSize, &loadBase);
977 OsELFClose(loadInfo->execInfo.procfd);
978 loadInfo->execInfo.procfd = INVALID_FD;
979 if (ret != LOS_OK) {
980 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
981 return ret;
982 }
983
984 if (loadInfo->interpInfo.procfd != INVALID_FD) {
985 ret = OsLoadInterpBinary(loadInfo, &interpMapBase);
986 OsELFClose(loadInfo->interpInfo.procfd);
987 loadInfo->interpInfo.procfd = INVALID_FD;
988 if (ret != LOS_OK) {
989 return ret;
990 }
991
992 loadInfo->elfEntry = loadInfo->interpInfo.elfEhdr.elfEntry + interpMapBase;
993 loadInfo->execInfo.elfEhdr.elfEntry = loadInfo->execInfo.elfEhdr.elfEntry + loadBase;
994 } else {
995 loadInfo->elfEntry = loadInfo->execInfo.elfEhdr.elfEntry;
996 }
997
998 ret = OsMakeArgsStack(loadInfo, interpMapBase);
999 if (ret != LOS_OK) {
1000 return ret;
1001 }
1002 if (!LOS_IsUserAddress((VADDR_T)loadInfo->stackTop)) {
1003 PRINT_ERR("%s[%d], StackTop is out of limit!\n", __FUNCTION__, __LINE__);
1004 return -EINVAL;
1005 }
1006
1007 return LOS_OK;
1008}
STATIC INT32 OsMakeArgsStack(ELFLoadInfo *loadInfo, UINTPTR interpMapBase)
Definition: los_load_elf.c:898
STATIC INT32 OsLoadInterpBinary(ELFLoadInfo *loadInfo, UINTPTR *interpMapBase)
Definition: los_load_elf.c:543
STATIC UINT32 OsGetAllocSize(const LD_ELF_PHDR *elfPhdr, INT32 phdrNum)
Definition: los_load_elf.c:364
STATIC INT32 OsMmapELFFile(INT32 procfd, const LD_ELF_PHDR *elfPhdr, const LD_ELF_EHDR *elfEhdr, UINTPTR *elfLoadAddr, UINT32 mapSize, UINTPTR *loadBase)
Definition: los_load_elf.c:482
UINT32 OsGetRndOffset(INT32 randomDevFD)
Definition: los_load_elf.c:719
UINTPTR elfEntry
装载点地址 即: _start 函数地址
Definition: los_load_elf.h:118
UINTPTR stackTop
栈底位置,递减满栈下,stackTop是高地址位
Definition: los_load_elf.h:110
UINTPTR loadAddr
加载地址
Definition: los_load_elf.h:117
函数调用图:
这是这个函数的调用关系图:

◆ OsLoadInit()

STATIC VOID OsLoadInit ( ELFLoadInfo loadInfo)

在文件 los_load_elf.c198 行定义.

199{
200#ifdef LOSCFG_FS_VFS
201 const struct files_struct *oldFiles = OsCurrProcessGet()->files;
202 loadInfo->oldFiles = (UINTPTR)create_files_snapshot(oldFiles);
203#else
204 loadInfo->oldFiles = NULL;
205#endif
206 loadInfo->execInfo.procfd = INVALID_FD;
207 loadInfo->interpInfo.procfd = INVALID_FD;
208}
struct files_struct * create_files_snapshot(const struct files_struct *oldf)
创建文件管理器快照,所谓快照就是一份拷贝
STATIC INLINE LosProcessCB * OsCurrProcessGet(VOID)
struct files_struct * files
函数调用图:
这是这个函数的调用关系图:

◆ OsLoadInterpBinary()

STATIC INT32 OsLoadInterpBinary ( ELFLoadInfo loadInfo,
UINTPTR interpMapBase 
)

在文件 los_load_elf.c543 行定义.

544{
545 UINTPTR loadBase = 0;
546 UINT32 mapSize;
547 INT32 ret;
548
549 mapSize = OsGetAllocSize(loadInfo->interpInfo.elfPhdr, loadInfo->interpInfo.elfEhdr.elfPhNum);
550 if (mapSize == 0) {
551 PRINT_ERR("%s[%d], Failed to get interp allocation size!\n", __FUNCTION__, __LINE__);
552 return -EINVAL;
553 }
554
555 ret = OsMmapELFFile(loadInfo->interpInfo.procfd, loadInfo->interpInfo.elfPhdr, &loadInfo->interpInfo.elfEhdr,
556 interpMapBase, mapSize, &loadBase);
557 if (ret != LOS_OK) {
558 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
559 }
560
561 return ret;
562}
函数调用图:
这是这个函数的调用关系图:

◆ OsMakeArgsStack()

STATIC INT32 OsMakeArgsStack ( ELFLoadInfo loadInfo,
UINTPTR  interpMapBase 
)

在文件 los_load_elf.c898 行定义.

899{
900 UINTPTR auxVector[AUX_VECTOR_SIZE] = { 0 };
901 UINTPTR *auxVecInfo = (UINTPTR *)auxVector;
902 INT32 vecIndex = 0;
903 UINT32 rndVec[RANDOM_VECTOR_SIZE];
904 UINTPTR rndVecStart;
905 INT32 ret;
906#ifdef LOSCFG_KERNEL_VDSO
907 vaddr_t vdsoLoadAddr;
908#endif
909
910 ret = OsGetRndNum(loadInfo, rndVec, sizeof(rndVec));
911 if (ret != LOS_OK) {
912 return ret;
913 }
914 loadInfo->topOfMem -= sizeof(rndVec);
915 rndVecStart = loadInfo->topOfMem;
916
917 ret = LOS_ArchCopyToUser((VOID *)loadInfo->topOfMem, rndVec, sizeof(rndVec));
918 if (ret != 0) {
919 return -EFAULT;
920 }
921
922 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_PHDR, loadInfo->loadAddr + loadInfo->execInfo.elfEhdr.elfPhoff);
923 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_PHENT, sizeof(LD_ELF_PHDR));
924 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_PHNUM, loadInfo->execInfo.elfEhdr.elfPhNum);
925 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_PAGESZ, PAGE_SIZE);
926 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_BASE, interpMapBase);
927 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_FLAGS, 0);
928 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_ENTRY, loadInfo->execInfo.elfEhdr.elfEntry);
929 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_UID, 0);
930 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_EUID, 0);
931 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_GID, 0);
932 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_EGID, 0);
933 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_HWCAP, 0);
934 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_CLKTCK, 0);
935 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_SECURE, 0);
936 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_RANDOM, rndVecStart);
937 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_EXECFN, (UINTPTR)loadInfo->execName);
938
939#ifdef LOSCFG_KERNEL_VDSO
940 vdsoLoadAddr = OsVdsoLoad(OsCurrProcessGet());//为当前进程加载 VDSO ELF
941 if (vdsoLoadAddr != 0) {
942 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_SYSINFO_EHDR, vdsoLoadAddr);
943 }
944#endif
945 AUX_VEC_ENTRY(auxVector, vecIndex, AUX_NULL, 0);
946
947 ret = OsPutParamToStack(loadInfo, auxVecInfo, vecIndex);
948 if (ret != LOS_OK) {
949 PRINT_ERR("%s[%d], Failed to put param to user stack\n", __FUNCTION__, __LINE__);
950 return ret;
951 }
952
953 return LOS_OK;
954}
STATIC INT32 OsGetRndNum(const ELFLoadInfo *loadInfo, UINT32 *rndVec, UINT32 vecSize)
Definition: los_load_elf.c:881
STATIC INT32 OsPutParamToStack(ELFLoadInfo *loadInfo, const UINTPTR *auxVecInfo, INT32 vecIndex)
Definition: los_load_elf.c:844
vaddr_t OsVdsoLoad(const LosProcessCB *)
OsVdsoLoad 为指定进程加载vdso 本质是将系统镜像中的vsdo部分映射到进程空间
Definition: los_vdso.c:147
CHAR * execName
程序名称
Definition: los_load_elf.h:105
size_t LOS_ArchCopyToUser(void *dst, const void *src, size_t len)
从内核空间拷贝到用户空间
Definition: user_copy.c:79
函数调用图:
这是这个函数的调用关系图:

◆ OsMmapELFFile()

STATIC INT32 OsMmapELFFile ( INT32  procfd,
const LD_ELF_PHDR *  elfPhdr,
const LD_ELF_EHDR *  elfEhdr,
UINTPTR elfLoadAddr,
UINT32  mapSize,
UINTPTR loadBase 
)

在文件 los_load_elf.c482 行定义.

484{
485 const LD_ELF_PHDR *elfPhdrTemp = elfPhdr;
486 UINTPTR vAddr, mapAddr, bssStart;
487 UINT32 bssEnd, elfProt, elfFlags;
488 INT32 ret, i;
489 INT32 fd = GetAssociatedSystemFd(procfd);
490
491 for (i = 0; i < elfEhdr->elfPhNum; ++i, ++elfPhdrTemp) {
492 if (elfPhdrTemp->type != LD_PT_LOAD) {
493 continue;
494 }
495 if (elfEhdr->elfType == LD_ET_EXEC) {
496 if (OsVerifyELFPhdr(elfPhdrTemp) != LOS_OK) {
497 return -ENOEXEC;
498 }
499 }
500
501 elfProt = OsGetProt(elfPhdrTemp->flags);
502 if ((elfProt & PROT_READ) == 0) {
503 return -ENOEXEC;
504 }
505 elfFlags = MAP_PRIVATE | MAP_FIXED;
506 vAddr = elfPhdrTemp->vAddr;
507 if ((vAddr == 0) && (*loadBase == 0)) {
508 elfFlags &= ~MAP_FIXED;
509 }
510
511 mapAddr = OsDoMmapFile(fd, (vAddr + *loadBase), elfPhdrTemp, elfProt, elfFlags, mapSize);
512 if (!LOS_IsUserAddress((VADDR_T)mapAddr)) {
513 return -ENOMEM;
514 }
515#ifdef LOSCFG_DRIVERS_TZDRIVER
516 if ((elfPhdrTemp->flags & PF_R) && (elfPhdrTemp->flags & PF_X) && !(elfPhdrTemp->flags & PF_W)) {
517 SetVmmRegionCodeStart(vAddr + *loadBase, elfPhdrTemp->memSize);
518 }
519#endif
520 mapSize = 0;
521
522 if (*elfLoadAddr == 0) {
523 *elfLoadAddr = mapAddr + ROUNDOFFSET(vAddr, PAGE_SIZE);
524 }
525
526 if ((*loadBase == 0) && (elfEhdr->elfType == LD_ET_DYN)) {
527 *loadBase = mapAddr;
528 }
529
530 if ((elfPhdrTemp->memSize > elfPhdrTemp->fileSize) && (elfPhdrTemp->flags & PF_W)) {
531 bssStart = mapAddr + ROUNDOFFSET(vAddr, PAGE_SIZE) + elfPhdrTemp->fileSize;
532 bssEnd = mapAddr + ROUNDOFFSET(vAddr, PAGE_SIZE) + elfPhdrTemp->memSize;
533 ret = OsSetBss(elfPhdrTemp, fd, bssStart, bssEnd, elfProt);
534 if (ret != LOS_OK) {
535 return ret;
536 }
537 }
538 }
539
540 return LOS_OK;
541}
STATIC INT32 OsSetBss(const LD_ELF_PHDR *elfPhdr, INT32 fd, UINTPTR bssStart, UINT32 bssEnd, UINT32 elfProt)
Definition: los_load_elf.c:452
STATIC UINTPTR OsDoMmapFile(INT32 fd, UINTPTR addr, const LD_ELF_PHDR *elfPhdr, UINT32 prot, UINT32 flags, UINT32 mapSize)
Definition: los_load_elf.c:399
int GetAssociatedSystemFd(int procFd)
获取绑定的系统描述符
Definition: vfs_procfd.c:133
函数调用图:
这是这个函数的调用关系图:

◆ OsPutParamToStack()

STATIC INT32 OsPutParamToStack ( ELFLoadInfo loadInfo,
const UINTPTR auxVecInfo,
INT32  vecIndex 
)

在文件 los_load_elf.c844 行定义.

845{
846 UINTPTR *topMem = (UINTPTR *)ROUNDDOWN(loadInfo->topOfMem, sizeof(UINTPTR));
847 UINTPTR *argsPtr = NULL;
848 INT32 items = (loadInfo->argc + 1) + (loadInfo->envc + 1) + 1;
849 size_t size;
850
851 loadInfo->topOfMem = ROUNDDOWN((UINTPTR)(topMem - vecIndex - items), STACK_ALIGN_SIZE);
852 argsPtr = (UINTPTR *)loadInfo->topOfMem;
853 loadInfo->stackTop = (UINTPTR)argsPtr;
854
855 if ((loadInfo->stackTopMax - loadInfo->stackTop) > USER_PARAM_BYTE_MAX) {
856 return -E2BIG;
857 }
858
859 if (OsPutUserArg(loadInfo->argc, argsPtr)) {
860 PRINT_ERR("%s[%d], Failed to put argc to user stack!\n", __FUNCTION__, __LINE__);
861 return -EFAULT;
862 }
863
864 argsPtr++;
865
866 if ((OsPutUserArgv(&loadInfo->argStart, &argsPtr, loadInfo->argc) != LOS_OK) ||
867 (OsPutUserArgv(&loadInfo->argStart, &argsPtr, loadInfo->envc) != LOS_OK)) {
868 PRINT_ERR("%s[%d], Failed to put argv or envp to user stack!\n", __FUNCTION__, __LINE__);
869 return -EFAULT;
870 }
871
872 size = LOS_ArchCopyToUser(argsPtr, auxVecInfo, vecIndex * sizeof(UINTPTR));
873 if (size != 0) {
874 PRINT_ERR("%s[%d], Failed to copy strings! Bytes not copied: %d\n", __FUNCTION__, __LINE__, size);
875 return -EFAULT;
876 }
877
878 return LOS_OK;
879}
STATIC INT32 OsPutUserArg(INT32 val, const UINTPTR *sp)
Definition: los_load_elf.c:585
STATIC INT32 OsPutUserArgv(UINTPTR *strPtr, UINTPTR **sp, INT32 count)
Definition: los_load_elf.c:602
UINTPTR argStart
开始参数位置
Definition: los_load_elf.h:116
INT32 argc
参数个数
Definition: los_load_elf.h:106
INT32 envc
环境变量个数
Definition: los_load_elf.h:107
UINTPTR stackTopMax
栈最大上限
Definition: los_load_elf.h:111
函数调用图:
这是这个函数的调用关系图:

◆ OsPutUserArg()

STATIC INT32 OsPutUserArg ( INT32  val,
const UINTPTR sp 
)

在文件 los_load_elf.c585 行定义.

586{
587 INT32 ret;
588
589 if (sp == NULL) {
590 return LOS_NOK;
591 }
592
593 ret = LOS_PutUser((INT32 *)&val, (INT32 *)sp);
594 if (ret != LOS_OK) {
595 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
596 return -EFAULT;
597 }
598
599 return LOS_OK;
600}
macro EXC_SP_SET reg1 mrc 获取CPU信息 and mov mul reg0 计算当前CPU栈的偏移位置 ldr reg1 相减得到栈顶 mov sp
Definition: asm.h:57
这是这个函数的调用关系图:

◆ OsPutUserArgv()

STATIC INT32 OsPutUserArgv ( UINTPTR strPtr,
UINTPTR **  sp,
INT32  count 
)

在文件 los_load_elf.c602 行定义.

603{
604 INT32 len;
605 INT32 i;
606 CHAR *ptr = NULL;
607
608 if ((strPtr == NULL) || (sp == NULL)) {
609 return LOS_NOK;
610 }
611
612 for (i = 0; i < count; ++i) {
613 /* put the addr of arg strings to user stack */
614 if (OsPutUserArg(*strPtr, *sp) != LOS_OK) {
615 return LOS_NOK;
616 }
617 ptr = OsGetParamPtr((CHAR **)strPtr, 0);
618 if (ptr == NULL) {
619 return LOS_NOK;
620 }
621 len = LOS_StrnlenUser(ptr, PATH_MAX);
622 if (len == 0) {
623 return LOS_NOK;
624 }
625 *strPtr += len;
626 ++(*sp);
627 }
628 /* put zero to end of argv */
629 if (OsPutUserArg(0, *sp) != LOS_OK) {
630 return LOS_NOK;
631 }
632 ++(*sp);
633
634 return LOS_OK;
635}
函数调用图:
这是这个函数的调用关系图:

◆ OsReadEhdr()

STATIC INT32 OsReadEhdr ( const CHAR fileName,
ELFInfo elfInfo,
BOOL  isExecFile 
)

在文件 los_load_elf.c210 行定义.

211{
212 INT32 ret;
213
214 ret = OsGetFileLength(&elfInfo->fileLen, fileName);
215 if (ret != LOS_OK) {
216 return -ENOENT;
217 }
218
219 ret = OsELFOpen(fileName, O_RDONLY | O_EXECVE | O_CLOEXEC);
220 if (ret < 0) {
221 PRINT_ERR("%s[%d], Failed to open ELF file: %s!\n", __FUNCTION__, __LINE__, fileName);
222 return ret;
223 }
224 elfInfo->procfd = ret;
225
226#ifdef LOSCFG_DRIVERS_TZDRIVER
227 if (isExecFile) {
228 struct file *filep = NULL;
229 ret = fs_getfilep(GetAssociatedSystemFd(elfInfo->procfd), &filep);
230 if (ret) {
231 PRINT_ERR("%s[%d], Failed to get struct file %s!\n", __FUNCTION__, __LINE__, fileName);
232 /* File will be closed by OsLoadELFFile */
233 return ret;
234 }
235 OsCurrProcessGet()->execVnode = filep->f_vnode;
236 }
237#endif
238 ret = OsReadELFInfo(elfInfo->procfd, (UINT8 *)&elfInfo->elfEhdr, sizeof(LD_ELF_EHDR), 0);
239 if (ret != LOS_OK) {
240 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
241 return -EIO;
242 }
243
244 ret = OsVerifyELFEhdr(&elfInfo->elfEhdr, elfInfo->fileLen);
245 if (ret != LOS_OK) {
246 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
247 return isExecFile ? -ENOEXEC : -ELIBBAD;
248 }
249
250 return LOS_OK;
251}
STATIC INT32 OsELFOpen(const CHAR *fileName, INT32 oflags)
打开ELF文件
Definition: los_load_elf.c:52
STATIC INT32 OsReadELFInfo(INT32 procfd, UINT8 *buffer, size_t readSize, off_t offset)
Definition: los_load_elf.c:124
STATIC INT32 OsVerifyELFEhdr(const LD_ELF_EHDR *ehdr, UINT32 fileLen)
Definition: los_load_elf.c:150
STATIC INT32 OsGetFileLength(UINT32 *fileLen, const CHAR *fileName)
Definition: los_load_elf.c:94
unsigned char UINT8
Definition: los_typedef.h:55
UINT32 fileLen
文件长度
Definition: los_load_elf.h:94
struct Vnode * execVnode
函数调用图:
这是这个函数的调用关系图:

◆ OsReadELFInfo()

STATIC INT32 OsReadELFInfo ( INT32  procfd,
UINT8 buffer,
size_t  readSize,
off_t  offset 
)

在文件 los_load_elf.c124 行定义.

125{
126 ssize_t byteNum;
127 off_t returnPos;
128 INT32 fd = GetAssociatedSystemFd(procfd);
129 if (fd < 0) {
130 PRINT_ERR("%s[%d], Invalid procfd!\n", __FUNCTION__, __LINE__);
131 return LOS_NOK;
132 }
133
134 if (readSize > 0) {
135 returnPos = lseek(fd, offset, SEEK_SET);
136 if (returnPos != offset) {
137 PRINT_ERR("%s[%d], Failed to seek the position!, offset: %#x\n", __FUNCTION__, __LINE__, offset);
138 return LOS_NOK;
139 }
140
141 byteNum = read(fd, buffer, readSize);
142 if (byteNum <= 0) {
143 PRINT_ERR("%s[%d], Failed to read from offset: %#x!\n", __FUNCTION__, __LINE__, offset);
144 return LOS_NOK;
145 }
146 }
147 return LOS_OK;
148}
INT64 ssize_t
Definition: los_typedef.h:79
函数调用图:
这是这个函数的调用关系图:

◆ OsReadInterpInfo()

STATIC INT32 OsReadInterpInfo ( ELFLoadInfo loadInfo)

在文件 los_load_elf.c292 行定义.

293{
294 LD_ELF_PHDR *elfPhdr = loadInfo->execInfo.elfPhdr;
295 CHAR *elfInterpName = NULL;
296 INT32 ret, i;
297
298 for (i = 0; i < loadInfo->execInfo.elfEhdr.elfPhNum; ++i, ++elfPhdr) {
299 if (elfPhdr->type != LD_PT_INTERP) {
300 continue;
301 }
302
303 if (OsVerifyELFPhdr(elfPhdr) != LOS_OK) {
304 return -ENOEXEC;
305 }
306
307 if ((elfPhdr->fileSize > FILE_PATH_MAX) || (elfPhdr->fileSize < FILE_PATH_MIN) ||
308 (elfPhdr->offset + elfPhdr->fileSize > loadInfo->execInfo.fileLen)) {
309 PRINT_ERR("%s[%d], The size of file is out of limit!\n", __FUNCTION__, __LINE__);
310 return -ENOEXEC;
311 }
312
313 elfInterpName = LOS_MemAlloc(m_aucSysMem0, elfPhdr->fileSize);
314 if (elfInterpName == NULL) {
315 PRINT_ERR("%s[%d], Failed to allocate for elfInterpName!\n", __FUNCTION__, __LINE__);
316 return -ENOMEM;
317 }
318
319 ret = OsReadELFInfo(loadInfo->execInfo.procfd, (UINT8 *)elfInterpName, elfPhdr->fileSize, elfPhdr->offset);
320 if (ret != LOS_OK) {
321 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
322 ret = -EIO;
323 goto OUT;
324 }
325
326 if (elfInterpName[elfPhdr->fileSize - 1] != '\0') {
327 PRINT_ERR("%s[%d], The name of interpreter is invalid!\n", __FUNCTION__, __LINE__);
328 ret = -ENOEXEC;
329 goto OUT;
330 }
331
332 ret = OsReadEhdr(INTERP_FULL_PATH, &loadInfo->interpInfo, FALSE);
333 if (ret != LOS_OK) {
334 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
335 goto OUT;
336 }
337
338 ret = OsReadPhdrs(&loadInfo->interpInfo, FALSE);
339 if (ret != LOS_OK) {
340 goto OUT;
341 }
342
343 (VOID)LOS_MemFree(m_aucSysMem0, elfInterpName);
344 break;
345 }
346
347 return LOS_OK;
348
349OUT:
350 (VOID)LOS_MemFree(m_aucSysMem0, elfInterpName);
351 return ret;
352}
VOID * LOS_MemAlloc(VOID *pool, UINT32 size)
从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存
Definition: los_memory.c:1123
函数调用图:
这是这个函数的调用关系图:

◆ OsReadPhdrs()

STATIC INT32 OsReadPhdrs ( ELFInfo elfInfo,
BOOL  isExecFile 
)

在文件 los_load_elf.c253 行定义.

254{
255 LD_ELF_EHDR *elfEhdr = &elfInfo->elfEhdr;
256 UINT32 size;
257 INT32 ret;
258
259 if (elfEhdr->elfPhNum < 1) {
260 goto OUT;
261 }
262
263 if (elfEhdr->elfPhEntSize != sizeof(LD_ELF_PHDR)) {
264 goto OUT;
265 }
266
267 size = sizeof(LD_ELF_PHDR) * elfEhdr->elfPhNum;
268 if ((elfEhdr->elfPhoff + size) > elfInfo->fileLen) {
269 goto OUT;
270 }
271
272 elfInfo->elfPhdr = LOS_MemAlloc(m_aucSysMem0, size);
273 if (elfInfo->elfPhdr == NULL) {
274 PRINT_ERR("%s[%d], Failed to allocate for elfPhdr!\n", __FUNCTION__, __LINE__);
275 return -ENOMEM;
276 }
277
278 ret = OsReadELFInfo(elfInfo->procfd, (UINT8 *)elfInfo->elfPhdr, size, elfEhdr->elfPhoff);
279 if (ret != LOS_OK) {
280 (VOID)LOS_MemFree(m_aucSysMem0, elfInfo->elfPhdr);
281 elfInfo->elfPhdr = NULL;
282 PRINT_ERR("%s[%d]\n", __FUNCTION__, __LINE__);
283 return -EIO;
284 }
285
286 return LOS_OK;
287OUT:
288 PRINT_ERR("%s[%d], elf file is bad!\n", __FUNCTION__, __LINE__);
289 return isExecFile ? -ENOEXEC : -ELIBBAD;
290}
if(tv==NULL)
Definition: time.c:430
函数调用图:
这是这个函数的调用关系图:

◆ OsSetArgParams()

STATIC INT32 OsSetArgParams ( ELFLoadInfo loadInfo,
CHAR *const *  argv,
CHAR *const *  envp 
)

在文件 los_load_elf.c791 行定义.

792{
793 UINT32 vmFlags;
794 INT32 ret;
795
796 loadInfo->randomDevFD = open("/dev/urandom", O_RDONLY);
797 if (loadInfo->randomDevFD < 0) {
798 if (!g_srandInit) {
799 srand((UINT32)time(NULL));
800 g_srandInit = TRUE;
801 }
802 }
803
804 (VOID)OsGetStackProt(loadInfo);
805 if (((UINT32)loadInfo->stackProt & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE)) {
806 return -ENOEXEC;
807 }
808 loadInfo->stackTopMax = USER_STACK_TOP_MAX - OsGetRndOffset(loadInfo->randomDevFD);//计算栈底位置
809 loadInfo->stackBase = loadInfo->stackTopMax - USER_STACK_SIZE;//计算栈基位置
810 loadInfo->stackSize = USER_STACK_SIZE; //用户态栈大小
811 loadInfo->stackParamBase = loadInfo->stackTopMax - USER_PARAM_BYTE_MAX; //栈参数空间
812 vmFlags = OsCvtProtFlagsToRegionFlags(loadInfo->stackProt, MAP_FIXED);
813 vmFlags |= VM_MAP_REGION_FLAG_STACK; //标记映射区为栈区
814 ret = OsStackAlloc((VOID *)loadInfo->newSpace, loadInfo->stackBase, USER_STACK_SIZE,
815 USER_PARAM_BYTE_MAX, vmFlags);//分配映射区
816 if (ret != LOS_OK) {
817 PRINT_ERR("%s[%d], Failed to alloc memory for user stack!\n", __FUNCTION__, __LINE__);
818 return -ENOMEM;
819 }
820 loadInfo->topOfMem = loadInfo->stackTopMax - sizeof(UINTPTR);
821
822 loadInfo->argc = OsGetParamNum(argv);
823 loadInfo->envc = OsGetParamNum(envp);
824 ret = OsCopyParams(loadInfo, 1, (CHAR *const *)&loadInfo->fileName);
825 if (ret != LOS_OK) {
826 PRINT_ERR("%s[%d], Failed to copy filename to user stack!\n", __FUNCTION__, __LINE__);
827 return ret;
828 }
829 loadInfo->execName = (CHAR *)loadInfo->topOfMem;
830
831 ret = OsCopyParams(loadInfo, loadInfo->envc, envp);
832 if (ret != LOS_OK) {
833 return ret;
834 }
835 ret = OsCopyParams(loadInfo, loadInfo->argc, argv);
836 if (ret != LOS_OK) {
837 return ret;
838 }
839 loadInfo->argStart = loadInfo->topOfMem;
840
841 return LOS_OK;
842}
STATIC INT32 OsCopyParams(ELFLoadInfo *loadInfo, INT32 argc, CHAR *const *argv)
Definition: los_load_elf.c:637
STATIC INT32 OsGetParamNum(CHAR *const *argv)
Definition: los_load_elf.c:691
STATIC BOOL g_srandInit
Definition: los_load_elf.c:50
STATIC UINT32 OsStackAlloc(LosVmSpace *space, VADDR_T vaddr, UINT32 vsize, UINT32 psize, UINT32 regionFlags)
分配栈区
Definition: los_load_elf.c:748
STATIC VOID OsGetStackProt(ELFLoadInfo *loadInfo)
Definition: los_load_elf.c:736
STATIC INLINE UINT32 OsCvtProtFlagsToRegionFlags(unsigned long prot, unsigned long flags)
从外部权限标签转化为线性区权限标签
Definition: los_vm_map.h:197
void srand(unsigned s)
初始化随机数生成器
Definition: stdlib.c:43
UINT32 stackSize
栈大小
Definition: los_load_elf.h:114
time_t time(time_t *t)
Definition: time.c:1224
函数调用图:
这是这个函数的调用关系图:

◆ OsSetBss()

STATIC INT32 OsSetBss ( const LD_ELF_PHDR *  elfPhdr,
INT32  fd,
UINTPTR  bssStart,
UINT32  bssEnd,
UINT32  elfProt 
)

在文件 los_load_elf.c452 行定义.

453{
454 UINTPTR bssStartPageAlign, bssEndPageAlign;
455 UINTPTR mapBase;
456 UINT32 bssMapSize;
457 INT32 stackFlags;
458 INT32 ret;
459
460 bssStartPageAlign = ROUNDUP(bssStart, PAGE_SIZE);
461 bssEndPageAlign = ROUNDUP(bssEnd, PAGE_SIZE);
462
463 ret = LOS_UserMemClear((VOID *)bssStart, PAGE_SIZE - ROUNDOFFSET(bssStart, PAGE_SIZE));
464 if (ret != 0) {
465 PRINT_ERR("%s[%d], Failed to clear bss\n", __FUNCTION__, __LINE__);
466 return -EFAULT;
467 }
468
469 bssMapSize = bssEndPageAlign - bssStartPageAlign;
470 if (bssMapSize > 0) {
471 stackFlags = MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS;
472 mapBase = (UINTPTR)LOS_MMap(bssStartPageAlign, bssMapSize, elfProt, stackFlags, -1, 0);
473 if (!LOS_IsUserAddress((VADDR_T)mapBase)) {
474 PRINT_ERR("%s[%d], Failed to map bss\n", __FUNCTION__, __LINE__);
475 return -ENOMEM;
476 }
477 }
478
479 return LOS_OK;
480}
INT32 LOS_UserMemClear(unsigned char *buf, UINT32 len)
清除用户空间数据
Definition: user_copy.c:114
函数调用图:
这是这个函数的调用关系图:

◆ OsStackAlloc()

STATIC UINT32 OsStackAlloc ( LosVmSpace space,
VADDR_T  vaddr,
UINT32  vsize,
UINT32  psize,
UINT32  regionFlags 
)

分配栈区

在文件 los_load_elf.c748 行定义.

749{
750 LosVmPage *vmPage = NULL;
751 VADDR_T *kvaddr = NULL;
752 LosVmMapRegion *region = NULL;
753 VADDR_T vaddrTemp;
754 PADDR_T paddrTemp;
755 UINT32 len;
756
757 (VOID)LOS_MuxAcquire(&space->regionMux);
758 kvaddr = LOS_PhysPagesAllocContiguous(psize >> PAGE_SHIFT);
759 if (kvaddr == NULL) {
760 goto OUT;
761 }
762
763 region = LOS_RegionAlloc(space, vaddr, vsize, regionFlags | VM_MAP_REGION_FLAG_FIXED, 0);
764 if (region == NULL) {
765 goto PFREE;
766 }
767
768 len = psize;
769 vaddrTemp = region->range.base + vsize - psize;
770 paddrTemp = LOS_PaddrQuery(kvaddr);
771 while (len > 0) {
772 vmPage = LOS_VmPageGet(paddrTemp);
773 LOS_AtomicInc(&vmPage->refCounts);
774
775 (VOID)LOS_ArchMmuMap(&space->archMmu, vaddrTemp, paddrTemp, 1, region->regionFlags);
776
777 paddrTemp += PAGE_SIZE;
778 vaddrTemp += PAGE_SIZE;
779 len -= PAGE_SIZE;
780 }
781 (VOID)LOS_MuxRelease(&space->regionMux);
782 return LOS_OK;
783
784PFREE:
785 (VOID)LOS_PhysPagesFreeContiguous(kvaddr, psize >> PAGE_SHIFT);
786OUT:
787 (VOID)LOS_MuxRelease(&space->regionMux);
788 return LOS_NOK;
789}
STATIC INLINE VOID LOS_AtomicInc(Atomic *v)
Atomic addSelf.
Definition: los_atomic.h:253
STATUS_T LOS_ArchMmuMap(LosArchMmu *archMmu, VADDR_T vaddr, PADDR_T paddr, size_t count, UINT32 flags)
LOS_ArchMmuMap 映射进程空间虚拟地址区间与物理地址区间 所谓的map就是生成L1,L2页表项的过程
Definition: los_arch_mmu.c:891
STATIC INLINE STATUS_T LOS_MuxAcquire(LosMux *m)
Definition: los_vm_lock.h:48
STATIC INLINE STATUS_T LOS_MuxRelease(LosMux *m)
Definition: los_vm_lock.h:53
PADDR_T LOS_PaddrQuery(VOID *vaddr)
通过虚拟地址查询映射的物理地址
Definition: los_vm_map.c:550
LosVmMapRegion * LOS_RegionAlloc(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, UINT32 regionFlags, VM_OFFSET_T pgoff)
Definition: los_vm_map.c:581
LosVmPage * LOS_VmPageGet(PADDR_T paddr)
通过物理地址获取页框
Definition: los_vm_page.c:120
VOID * LOS_PhysPagesAllocContiguous(size_t nPages)
分配连续的物理页
Definition: los_vm_phys.c:478
VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages)
释放指定页数地址连续的物理内存
Definition: los_vm_phys.c:494
VADDR_T base
Definition: los_vm_map.h:84
UINT32 regionFlags
Definition: los_vm_map.h:125
LosVmMapRange range
Definition: los_vm_map.h:123
物理页框描述符 虚拟内存体现的是程序对内存资源的需求,而物理内存是对该请求的供应。 伙伴算法的思想是:把内存中连续的空闲页框空间看成是空闲页框块,并按照它们的大小(连续页框的数目)分组
Definition: los_vm_page.h:53
Atomic refCounts
Definition: los_vm_page.h:57
LosMux regionMux
Definition: los_vm_map.h:149
函数调用图:
这是这个函数的调用关系图:

◆ OsVerifyELFEhdr()

STATIC INT32 OsVerifyELFEhdr ( const LD_ELF_EHDR *  ehdr,
UINT32  fileLen 
)

在文件 los_load_elf.c150 行定义.

151{
152 if (memcmp(ehdr->elfIdent, LD_ELFMAG, LD_SELFMAG) != 0) {
153 PRINT_ERR("%s[%d], The file is not elf!\n", __FUNCTION__, __LINE__);
154 return LOS_NOK;
155 }
156 if ((ehdr->elfType != LD_ET_EXEC) && (ehdr->elfType != LD_ET_DYN)) {
157 PRINT_ERR("%s[%d], The type of file is not ET_EXEC or ET_DYN!\n", __FUNCTION__, __LINE__);
158 return LOS_NOK;
159 }
160 if (ehdr->elfMachine != LD_EM_ARM) {
161 PRINT_ERR("%s[%d], The type of machine is not EM_ARM!\n", __FUNCTION__, __LINE__);
162 return LOS_NOK;
163 }
164 if (ehdr->elfPhNum > ELF_PHDR_NUM_MAX) {
165 PRINT_ERR("%s[%d], The num of program header is out of limit\n", __FUNCTION__, __LINE__);
166 return LOS_NOK;
167 }
168 if (ehdr->elfPhoff > fileLen) {
169 PRINT_ERR("%s[%d], The offset of program header is invalid, elf file is bad\n", __FUNCTION__, __LINE__);
170 return LOS_NOK;
171 }
172 if (OsIsBadUserAddress((VADDR_T)ehdr->elfEntry)) {
173 PRINT_ERR("%s[%d], The entry of program is invalid\n", __FUNCTION__, __LINE__);
174 return LOS_NOK;
175 }
176
177 return LOS_OK;
178}
int memcmp(const void *str1, const void *str2, size_t n)
Definition: memcmp.c:37
函数调用图:
这是这个函数的调用关系图:

◆ OsVerifyELFPhdr()

STATIC INT32 OsVerifyELFPhdr ( const LD_ELF_PHDR *  phdr)

在文件 los_load_elf.c180 行定义.

181{
182 if ((phdr->fileSize > FILE_LENGTH_MAX) || (phdr->offset > FILE_LENGTH_MAX)) {
183 PRINT_ERR("%s[%d], The size of phdr is out of limit\n", __FUNCTION__, __LINE__);
184 return LOS_NOK;
185 }
186 if (phdr->memSize > MEM_SIZE_MAX) {
187 PRINT_ERR("%s[%d], The mem size of phdr is out of limit\n", __FUNCTION__, __LINE__);
188 return LOS_NOK;
189 }
190 if (OsIsBadUserAddress((VADDR_T)phdr->vAddr)) {
191 PRINT_ERR("%s[%d], The vaddr of phdr is invalid\n", __FUNCTION__, __LINE__);
192 return LOS_NOK;
193 }
194
195 return LOS_OK;
196}
函数调用图:
这是这个函数的调用关系图:

变量说明

◆ g_srandInit

STATIC BOOL g_srandInit

在文件 los_load_elf.c50 行定义.