-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathELFLoader.cpp
More file actions
82 lines (60 loc) · 2.4 KB
/
ELFLoader.cpp
File metadata and controls
82 lines (60 loc) · 2.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include "ELFLoader.h"
#include <iostream>
#include <string>
#include <fstream>
uint32_t ELFLoader::loadELF(const std::string& filename, Bus& bus)
{
std::ifstream file(filename, std::ios::binary);
if (!file) {
throw std::runtime_error ("Failed to open ELF file.\n");
}
// Read ELF Header and compare magic
Ehdr eheader;
file.read((char*)&eheader, sizeof(eheader));
//Checks
if (eheader.e_ident[0] != CHECKS::num || eheader.e_ident[1] != CHECKS::E
|| eheader.e_ident[2] != CHECKS::L || eheader.e_ident[3] != CHECKS::F)
{
std::cerr << "TYPE error\n";
throw std::runtime_error("Not an ELF file.\n");
}
if (eheader.e_type != CHECKS::EXEC) {
std::cerr << "TYPE error\n";
throw std::runtime_error("ELF file is not an executable.\n");
}
if (eheader.e_machine != CHECKS::RISCV) {
std::cerr << "TYPE error\n";
throw std::runtime_error("ELF file is not for RISC-V.\n");
}
if (eheader.e_ident[4] != CHECKS::TYPE) {
std::cerr << "TYPE error\n";
throw std::runtime_error("ELF file is not 32-bit.\n");
}
// read Program header files
//use the offset to find the start of Program headers
file.seekg(eheader.e_phoff, std::ios::beg);
// for number of program headers loop through them
for (int i = 0; i < eheader.e_phnum; ++i) {
Phdr pheader;
file.read((char*)&pheader, sizeof(pheader));
//LOAD
if (pheader.p_type != CHECKS::LOAD) continue;
char* segment = new char[pheader.p_filesz];
//Segment offset used to find where the segment begins
file.seekg(pheader.p_offset, std::ios::beg);
file.read(segment, pheader.p_filesz);
// put LOAD segment into memory
for (size_t j = 0; j < pheader.p_filesz; ++j) {
bus.storeInMem(pheader.p_vaddr + j, BYTE_SIZE, static_cast<uint8_t>(segment[j]));
}
// Zero out the rest of the memory if memsz > filesz
if (pheader.p_memsz > pheader.p_filesz) {
size_t remaining = pheader.p_memsz - pheader.p_filesz;
for (size_t j = 0; j < remaining; ++j) {
bus.storeInMem(pheader.p_vaddr + pheader.p_filesz + j, BYTE_SIZE, 0);
}
}
delete[] segment;
}
return eheader.e_entry;
}