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
This commit is contained in:
parent
1f44717732
commit
fb35d474a5
3 changed files with 79 additions and 27 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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__
|
||||
|
|
Loading…
Reference in a new issue