| 51 | } |
| 52 | |
| 53 | BString ElfLoader::getInterpreter(FsOpenNode* openNode, bool* isElf) { |
| 54 | U8 buffer[sizeof(struct k_Elf32_Ehdr)] = { 0 }; |
| 55 | struct k_Elf32_Ehdr* hdr = (struct k_Elf32_Ehdr*)buffer; |
| 56 | U32 len = openNode->readNative(buffer, sizeof(buffer)); |
| 57 | char interp[MAX_FILEPATH_LEN] = { 0 }; |
| 58 | |
| 59 | *isElf=true; |
| 60 | if (len!=sizeof(buffer)) { |
| 61 | *isElf=true; |
| 62 | } |
| 63 | if (*isElf) { |
| 64 | *isElf = isValidElf(hdr); |
| 65 | } |
| 66 | if (!*isElf) { |
| 67 | if (buffer[0]=='#') { |
| 68 | U32 mode = 0; |
| 69 | U32 pos = 0; |
| 70 | char shell_interp[MAX_FILEPATH_LEN] = { 0 }; |
| 71 | |
| 72 | for (U32 i=1;i<len;i++) { |
| 73 | if (mode==0) { |
| 74 | if (buffer[i]=='!') |
| 75 | mode = 1; |
| 76 | } else if (mode==1 && (buffer[i]==' ' || buffer[i]=='\t')) { |
| 77 | continue; |
| 78 | } else if (buffer[i]=='\n' || buffer[i]=='\r') { |
| 79 | break; |
| 80 | } else { |
| 81 | mode = 2; |
| 82 | shell_interp[pos++] = buffer[i]; |
| 83 | } |
| 84 | } |
| 85 | shell_interp[pos++]=0; |
| 86 | return BString::copy(shell_interp); |
| 87 | } |
| 88 | } else { |
| 89 | U32 i; |
| 90 | |
| 91 | openNode->seek(hdr->e_phoff); |
| 92 | for (i=0;i<hdr->e_phoff;i++) { |
| 93 | struct k_Elf32_Phdr phdr; |
| 94 | openNode->seek(hdr->e_phoff+i*hdr->e_phentsize); |
| 95 | openNode->readNative((U8*)&phdr, sizeof(struct k_Elf32_Phdr)); |
| 96 | if (phdr.p_type==PT_INTERP) { |
| 97 | openNode->seek(phdr.p_offset); |
| 98 | openNode->readNative((U8*)interp, phdr.p_filesz); |
| 99 | interp[phdr.p_filesz] = 0; |
| 100 | return BString::copy(interp); |
| 101 | } |
| 102 | } |
| 103 | } |
| 104 | return B(""); |
| 105 | } |
| 106 | |
| 107 | FsOpenNode* ElfLoader::inspectNode(BString currentDirectory, const std::shared_ptr<FsNode>& node, BString& loader, BString& interpreter, std::vector<BString>& interpreterArgs) { |
| 108 | bool isElf = 0; |
nothing calls this directly
no test coverage detected