diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2006-08-11 20:27:22 -0400 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2006-08-11 20:27:22 -0400 |
commit | fb35d474a58dcc55da589c925d240b4bd1935646 (patch) | |
tree | 7b57f8cf514a6c59875b412782819832ca09c946 /src | |
parent | 1f44717732028a2491177816264a91f0690254c3 (diff) | |
download | gem5-fb35d474a58dcc55da589c925d240b4bd1935646.tar.xz |
Added code to support setting up all of the auxillieary vectors configured by the sparc linux elf loader.
src/arch/sparc/process.cc:
All of the auxilliary vectors are now set like they are in the linux elf loader. This code should probably be moved to arch/sparc/linux/process.cc somehow.
--HG--
extra : convert_revision : 4a90cacf70b1032cad3f18b0f833a6df8237e0de
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/sparc/process.cc | 65 | ||||
-rw-r--r-- | src/base/loader/elf_object.cc | 32 | ||||
-rw-r--r-- | src/base/loader/elf_object.hh | 9 |
3 files changed, 79 insertions, 27 deletions
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 75f01e038..70c7e719f 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -32,6 +32,7 @@ #include "arch/sparc/isa_traits.hh" #include "arch/sparc/process.hh" #include "base/loader/object_file.hh" +#include "base/loader/elf_object.hh" #include "base/misc.hh" #include "cpu/thread_context.hh" #include "mem/page_table.hh" @@ -129,7 +130,8 @@ SparcLiveProcess::argsInit(int intSize, int pageSize) SPARC_AT_UID = 11, SPARC_AT_EUID = 12, SPARC_AT_GID = 13, - SPARC_AT_EGID = 14 + SPARC_AT_EGID = 14, + SPARC_AT_SECURE = 23 }; enum hardwareCaps @@ -153,31 +155,42 @@ SparcLiveProcess::argsInit(int intSize, int pageSize) M5_HWCAP_SPARC_V9 | M5_HWCAP_SPARC_ULTRA3; - //Setup the auxilliary vectors. These will already have - //endian conversion. - auxv.push_back(buildAuxVect(SPARC_AT_EGID, 100)); - auxv.push_back(buildAuxVect(SPARC_AT_GID, 100)); - auxv.push_back(buildAuxVect(SPARC_AT_EUID, 100)); - auxv.push_back(buildAuxVect(SPARC_AT_UID, 100)); - //This would work, but the entry point is a protected member - //auxv.push_back(buildAuxVect(SPARC_AT_ENTRY, objFile->entry)); - auxv.push_back(buildAuxVect(SPARC_AT_FLAGS, 0)); - //This is the address of the elf "interpreter", which I don't - //think we currently set up. It should be set to 0 (I think) - //auxv.push_back(buildAuxVect(SPARC_AT_BASE, 0)); - //This is the number of headers which were in the original elf - //file. This information isn't avaibale by this point. - //auxv.push_back(buildAuxVect(SPARC_AT_PHNUM, 3)); - //This is the size of a program header entry. This isn't easy - //to compute here. - //auxv.push_back(buildAuxVect(SPARC_AT_PHENT, blah)); - //This is should be set to load_addr (whatever that is) + - //e_phoff. I think it's a pointer to the program headers. - //auxv.push_back(buildAuxVect(SPARC_AT_PHDR, blah)); - //This should be easy to get right, but I won't set it for now - //auxv.push_back(buildAuxVect(SPARC_AT_CLKTCK, blah)); - auxv.push_back(buildAuxVect(SPARC_AT_PAGESZ, SparcISA::VMPageSize)); - auxv.push_back(buildAuxVect(SPARC_AT_HWCAP, hwcap)); + + //Setup the auxilliary vectors. These will already have endian conversion. + //Auxilliary vectors are loaded only for elf formatted executables. + ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile); + if(elfObject) + { + //Bits which describe the system hardware capabilities + auxv.push_back(buildAuxVect(SPARC_AT_HWCAP, hwcap)); + //The system page size + auxv.push_back(buildAuxVect(SPARC_AT_PAGESZ, SparcISA::VMPageSize)); + //Defined to be 100 in the kernel source. + //Frequency at which times() increments + auxv.push_back(buildAuxVect(SPARC_AT_CLKTCK, 100)); + // For statically linked executables, this is the virtual address of the + // program header tables if they appear in the executable image + auxv.push_back(buildAuxVect(SPARC_AT_PHDR, elfObject->programHeaderTable())); + // This is the size of a program header entry from the elf file. + auxv.push_back(buildAuxVect(SPARC_AT_PHENT, elfObject->programHeaderSize())); + // This is the number of program headers from the original elf file. + auxv.push_back(buildAuxVect(SPARC_AT_PHNUM, elfObject->programHeaderCount())); + //This is the address of the elf "interpreter", It should be set + //to 0 for regular executables. It should be something else + //(not sure what) for dynamic libraries. + auxv.push_back(buildAuxVect(SPARC_AT_BASE, 0)); + //This is hardwired to 0 in the elf loading code in the kernel + auxv.push_back(buildAuxVect(SPARC_AT_FLAGS, 0)); + //The entry point to the program + auxv.push_back(buildAuxVect(SPARC_AT_ENTRY, objFile->entryPoint())); + //Different user and group IDs + auxv.push_back(buildAuxVect(SPARC_AT_UID, 100)); + auxv.push_back(buildAuxVect(SPARC_AT_EUID, 100)); + auxv.push_back(buildAuxVect(SPARC_AT_GID, 100)); + auxv.push_back(buildAuxVect(SPARC_AT_EGID, 100)); + //Whether to enable "secure mode" in the executable + auxv.push_back(buildAuxVect(SPARC_AT_SECURE, 0)); + } //Figure out how big the initial stack needs to be diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc index 00d218b76..2ca0d4f4a 100644 --- a/src/base/loader/elf_object.cc +++ b/src/base/loader/elf_object.cc @@ -153,8 +153,38 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) } // while sections } + ElfObject * result = new ElfObject(fname, fd, len, data, arch, opSys); + + //The number of headers in the file + result->_programHeaderCount = ehdr.e_phnum; + //Record the size of each entry + result->_programHeaderSize = ehdr.e_phentsize; + if(result->_programHeaderCount) //If there is a program header table + { + //Figure out the virtual address of the header table in the + //final memory image. We use the program headers themselves + //to translate from a file offset to the address in the image. + GElf_Phdr phdr; + uint64_t e_phoff = ehdr.e_phoff; + result->_programHeaderTable = 0; + for(int hdrnum = 0; hdrnum < result->_programHeaderCount; hdrnum++) + { + gelf_getphdr(elf, hdrnum, &phdr); + //Check if we've found the segment with the headers in it + if(phdr.p_offset <= e_phoff && + phdr.p_offset + phdr.p_filesz > e_phoff) + { + result->_programHeaderTable = phdr.p_vaddr + e_phoff; + break; + } + } + } + else + result->_programHeaderTable = 0; + + elf_end(elf); - return new ElfObject(fname, fd, len, data, arch, opSys); + return result; } } diff --git a/src/base/loader/elf_object.hh b/src/base/loader/elf_object.hh index 46dbfe37b..9755426b4 100644 --- a/src/base/loader/elf_object.hh +++ b/src/base/loader/elf_object.hh @@ -37,6 +37,12 @@ class ElfObject : public ObjectFile { protected: + //These values are provided to a linux process by the kernel, so we + //need to keep them around. + Addr _programHeaderTable; + uint16_t _programHeaderSize; + uint16_t _programHeaderCount; + /// Helper functions for loadGlobalSymbols() and loadLocalSymbols(). bool loadSomeSymbols(SymbolTable *symtab, int binding); @@ -52,6 +58,9 @@ class ElfObject : public ObjectFile static ObjectFile *tryFile(const std::string &fname, int fd, size_t len, uint8_t *data); + Addr programHeaderTable() {return _programHeaderTable;} + uint16_t programHeaderSize() {return _programHeaderSize;} + uint16_t programHeaderCount() {return _programHeaderCount;} }; #endif // __ELF_OBJECT_HH__ |