aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-02-04 22:04:37 +0100
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-02-04 22:04:37 +0100
commit54e20dad0f8efe01152d00fe41bf6aa2c44f5bba (patch)
tree67eed46fe364da8e947c03b870c6fa452edfce51
parent8c7a41702faf6760c74382ae269f0bf4603a0abe (diff)
downloadqtmips-54e20dad0f8efe01152d00fe41bf6aa2c44f5bba.tar.gz
qtmips-54e20dad0f8efe01152d00fe41bf6aa2c44f5bba.tar.bz2
qtmips-54e20dad0f8efe01152d00fe41bf6aa2c44f5bba.zip
Setup initial PC according executable entry form ELF file if it is non zero.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
-rw-r--r--qtmips_machine/programloader.cpp9
-rw-r--r--qtmips_machine/programloader.h2
-rw-r--r--qtmips_machine/qtmipsmachine.cpp3
3 files changed, 12 insertions, 2 deletions
diff --git a/qtmips_machine/programloader.cpp b/qtmips_machine/programloader.cpp
index 5a907c8..7722774 100644
--- a/qtmips_machine/programloader.cpp
+++ b/qtmips_machine/programloader.cpp
@@ -44,6 +44,7 @@
using namespace machine;
ProgramLoader::ProgramLoader(const char *file) {
+ const GElf_Ehdr *elf_ehdr;
// Initialize elf library
if (elf_version(EV_CURRENT) == EV_NONE)
throw QTMIPS_EXCEPTION(Input, "Elf library initialization failed", elf_errmsg(-1));
@@ -57,8 +58,10 @@ ProgramLoader::ProgramLoader(const char *file) {
if (elf_kind(this->elf) != ELF_K_ELF)
throw QTMIPS_EXCEPTION(Input, "Invalid input file elf format, plain elf file expected", "");
- if (!gelf_getehdr(this->elf, &this->hdr))
+ elf_ehdr = gelf_getehdr(this->elf, &this->hdr);
+ if (!elf_ehdr)
throw QTMIPS_EXCEPTION(Input, "Getting elf file header failed", elf_errmsg(-1));
+ executable_entry = elf_ehdr->e_entry;
// Check elf file format, executable expected, nothing else.
if (this->hdr.e_type != ET_EXEC)
throw QTMIPS_EXCEPTION(Input, "Invalid input file type", "");
@@ -119,3 +122,7 @@ std::uint32_t ProgramLoader::end() {
}
return last + 0x10; // We add offset so we are sure that also pipeline is empty
}
+
+std::uint32_t ProgramLoader::get_executable_entry() {
+ return executable_entry;
+}
diff --git a/qtmips_machine/programloader.h b/qtmips_machine/programloader.h
index 686f64c..607bdb0 100644
--- a/qtmips_machine/programloader.h
+++ b/qtmips_machine/programloader.h
@@ -54,6 +54,7 @@ public:
void to_memory(Memory *mem); // Writes all loaded sections to memory
std::uint32_t end(); // Return address after which there is no more code for sure
+ std::uint32_t get_executable_entry();
private:
int fd;
Elf *elf;
@@ -61,6 +62,7 @@ private:
size_t n_secs; // number of sections in elf program header
Elf32_Phdr *phdrs; // program section headers
QVector<size_t> map; // external index to phdrs index
+ std::uint32_t executable_entry;
};
}
diff --git a/qtmips_machine/qtmipsmachine.cpp b/qtmips_machine/qtmipsmachine.cpp
index ea14701..51e5580 100644
--- a/qtmips_machine/qtmipsmachine.cpp
+++ b/qtmips_machine/qtmipsmachine.cpp
@@ -45,8 +45,9 @@ QtMipsMachine::QtMipsMachine(const MachineConfig &cc) : QObject(), mcnf(&cc) {
mem_program_only = new Memory();
program.to_memory(mem_program_only);
program_end = program.end();
-
regs = new Registers();
+ if (program.get_executable_entry())
+ regs->pc_abs_jmp(program.get_executable_entry());
mem = new Memory(*mem_program_only);
cch_program = new Cache(mem, &cc.cache_program(), cc.memory_access_time_read(), cc.memory_access_time_write());
cch_data = new Cache(mem, &cc.cache_data(), cc.memory_access_time_read(), cc.memory_access_time_write());