46 #include <sys/types.h>
56 #include "debug/Loader.hh"
67 if (elf_version(EV_CURRENT) == EV_NONE)
68 panic(
"wrong elf version number!");
75 elf_memory((
char *)
const_cast<uint8_t *
>(ifd->data()), ifd->len());
79 if (gelf_getehdr(elf, &ehdr) == 0)
93 std::string interpDir;
101 "Error: setInterpDir has already been called once\n");
108 elf = elf_memory((
char *)
const_cast<uint8_t *
>(
imageData->data()),
121 for (
int i = 0;
i <
ehdr.e_phnum; ++
i) {
123 if (gelf_getphdr(
elf,
i, &phdr) == 0) {
124 panic(
"gelf_getphdr failed for segment %d.",
i);
127 if (phdr.p_type == PT_LOAD)
129 if (phdr.p_type == PT_INTERP) {
141 "No loadable segments in '%s'. ELF file corrupted?\n",
150 if (elf_version(EV_CURRENT) == EV_NONE)
151 panic(
"wrong elf version number!");
155 Elf_Scn *section = elf_getscn(
elf, sec_idx);
160 gelf_getshdr(section, &shdr);
162 if (shdr.sh_type == SHT_SYMTAB) {
163 Elf_Data *
data = elf_getdata(section,
nullptr);
164 int count = shdr.sh_size / shdr.sh_entsize;
170 gelf_getsym(
data,
i, &sym);
172 char *sym_name = elf_strptr(
elf, shdr.sh_link, sym.st_name);
173 if (!sym_name || sym_name[0] ==
'$')
178 symbol.
name = sym_name;
180 switch (GELF_ST_BIND(sym.st_info)) {
201 section = elf_getscn(
elf, sec_idx);
209 const std::string elf_path = (
char *)
imageData->data() + phdr.p_offset;
210 if (!interpDir.empty())
211 return interpDir + elf_path;
219 auto &emach =
ehdr.e_machine;
220 auto &eclass =
ehdr.e_ident[EI_CLASS];
221 auto &edata =
ehdr.e_ident[EI_DATA];
224 if (emach == EM_SPARC64 || (emach == EM_SPARC && eclass == ELFCLASS64) ||
225 emach == EM_SPARCV9) {
227 }
else if (emach == EM_SPARC32PLUS ||
228 (emach == EM_SPARC && eclass == ELFCLASS32)) {
230 }
else if (emach == EM_MIPS && eclass == ELFCLASS32) {
232 if (edata != ELFDATA2LSB) {
233 fatal(
"The binary you're trying to load is compiled for big "
234 "endian MIPS. gem5\nonly supports little endian MIPS. "
235 "Please recompile your binary.\n");
237 }
else if (emach == EM_X86_64 && eclass == ELFCLASS64) {
239 }
else if (emach == EM_386 && eclass == ELFCLASS32) {
241 }
else if (emach == EM_ARM && eclass == ELFCLASS32) {
243 }
else if (emach == EM_AARCH64 && eclass == ELFCLASS64) {
245 }
else if (emach == EM_RISCV) {
247 }
else if (emach == EM_PPC && eclass == ELFCLASS32) {
249 if (edata != ELFDATA2MSB) {
250 fatal(
"The binary you're trying to load is compiled for "
251 "little endian Power.\ngem5 only supports big "
252 "endian Power. Please recompile your binary.\n");
254 }
else if (emach == EM_PPC64) {
255 fatal(
"The binary you're trying to load is compiled for 64-bit "
256 "Power. M5\n only supports 32-bit Power. Please "
257 "recompile your binary.\n");
259 warn(
"Unknown architecture: %d\n", emach);
267 switch (
ehdr.e_ident[EI_OSABI]) {
271 case ELFOSABI_SOLARIS:
280 case ELFOSABI_FREEBSD:
287 Elf_Scn *section = elf_getscn(
elf, 1);
288 for (
int sec_idx = 1; section; section = elf_getscn(
elf, ++sec_idx)) {
290 gelf_getshdr(section, &shdr);
292 char *e_str = elf_strptr(
elf,
ehdr.e_shstrndx, shdr.sh_name);
293 if (shdr.sh_type == SHT_NOTE && !strcmp(
".note.ABI-tag", e_str)) {
297 Elf_Data *raw_data = elf_rawdata(section,
nullptr);
298 assert(raw_data && raw_data->d_buf);
300 uint32_t raw_abi = ((uint32_t *)raw_data->d_buf)[4];
301 bool is_le =
ehdr.e_ident[EI_DATA] == ELFDATA2LSB;
302 uint32_t os_abi = is_le ?
htole(raw_abi) :
htobe(raw_abi);
309 fatal(
"gem5 does not support the HURD ABI.\n");
319 if (!strcmp(
".SUNW_version", e_str) || !strcmp(
".stab.index", e_str)) {
332 phdr.p_offset, phdr.p_filesz });
333 Addr uninitialized = phdr.p_memsz - phdr.p_filesz;
340 phdr.p_paddr + phdr.p_filesz, uninitialized });
343 const Addr file_start = phdr.p_offset;
344 const Addr file_end = file_start + phdr.p_filesz;
350 if (file_start <= ehdr.e_phoff && file_end >
ehdr.e_phoff)
365 if (elf_version(EV_CURRENT) == EV_NONE)
366 panic(
"wrong elf version number!");
370 elf_memory((
char *)
const_cast<uint8_t *
>(
imageData->data()),
376 if (gelf_getehdr(
elf, &
ehdr) ==0) {
377 panic(
"Not ELF, shouldn't be here");
382 Elf_Scn *section = elf_getscn(
elf, sec_idx);
387 gelf_getshdr(section, &shdr);
389 section = elf_getscn(
elf, ++sec_idx);