MCPcopy Create free account
hub / github.com/FEX-Emu/FEX / LoadElfFile

Method LoadElfFile

Source/Tools/FEXLoader/ELFCodeLoader.h:124–204  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

122 }
123
124 std::optional<uintptr_t> LoadElfFile(ELFParser& Elf, uintptr_t* BrkBase, FEX::HLE::SyscallHandler* const Handler, uint64_t LoadHint = 0) {
125
126 uintptr_t LoadBase = 0;
127 uintptr_t BrkLoadBase = 0;
128 const bool DynELF = Elf.ehdr.e_type == ET_DYN;
129 const bool NeedsLateBRKMap = BrkBase && !DynELF;
130
131 if (DynELF) {
132 // Allocate a base address plus BRK padding.
133 auto TotalSize = CalculateDYNELFSize(Elf.phdrs) + (BrkBase ? BRK_SIZE : 0);
134 LoadBase =
135 (uintptr_t)Handler->GuestMmap(nullptr, reinterpret_cast<void*>(LoadHint), TotalSize, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
136 if (FEX::HLE::HasSyscallError(LoadBase)) {
137 return {};
138 }
139
140 // fprintf(stderr, "elf %d: %lx-%lx\n", Elf.fd, LoadBase, LoadBase + TotalSize);
141 if (BrkBase) {
142 BrkLoadBase = LoadBase + (TotalSize - BRK_SIZE);
143 }
144 }
145
146 for (const auto& Header : Elf.phdrs) {
147 if (Header.p_type != PT_LOAD) {
148 continue;
149 }
150
151 int MapProt = MapFlags(Header);
152 int MapType = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
153
154 if (!MapFile(Elf, LoadBase, Header, MapProt, MapType, Handler)) {
155 return {};
156 }
157
158 if (Header.p_memsz > Header.p_filesz) {
159 // clear bss
160 auto BSSStart = LoadBase + Header.p_vaddr + Header.p_filesz;
161 auto BSSPageStart = PAGE_ALIGN(BSSStart);
162 auto BSSPageEnd = PAGE_ALIGN(LoadBase + Header.p_vaddr + Header.p_memsz);
163
164 // Only clear padding bytes if the section is writable
165 if (Header.p_flags & PF_W) {
166 memset((void*)BSSStart, 0, BSSPageStart - BSSStart);
167 }
168
169 if (BSSPageStart != BSSPageEnd) {
170 auto bss = Handler->GuestMmap(nullptr, (void*)BSSPageStart, BSSPageEnd - BSSPageStart, MapProt, MapType | MAP_ANONYMOUS, -1, 0);
171 if (FEX::HLE::HasSyscallError(bss)) {
172 LogMan::Msg::EFmt("Failed to allocate BSS @ {}, {}\n", fmt::ptr(bss), errno);
173 return {};
174 }
175 }
176 }
177
178 if (NeedsLateBRKMap) {
179 // Keep track of highest address for BRK in the case of non-dynamic ELF files.
180 auto memend = LoadBase + Header.p_vaddr + Header.p_memsz;
181

Callers

nothing calls this directly

Calls 4

HasSyscallErrorFunction · 0.85
EFmtFunction · 0.85
AlignUpFunction · 0.85
GuestMmapMethod · 0.45

Tested by

no test coverage detected