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/isa_traits.hh"
|
||||||
#include "arch/sparc/process.hh"
|
#include "arch/sparc/process.hh"
|
||||||
#include "base/loader/object_file.hh"
|
#include "base/loader/object_file.hh"
|
||||||
|
#include "base/loader/elf_object.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
|
@ -129,7 +130,8 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
|
||||||
SPARC_AT_UID = 11,
|
SPARC_AT_UID = 11,
|
||||||
SPARC_AT_EUID = 12,
|
SPARC_AT_EUID = 12,
|
||||||
SPARC_AT_GID = 13,
|
SPARC_AT_GID = 13,
|
||||||
SPARC_AT_EGID = 14
|
SPARC_AT_EGID = 14,
|
||||||
|
SPARC_AT_SECURE = 23
|
||||||
};
|
};
|
||||||
|
|
||||||
enum hardwareCaps
|
enum hardwareCaps
|
||||||
|
@ -153,31 +155,42 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
|
||||||
M5_HWCAP_SPARC_V9 |
|
M5_HWCAP_SPARC_V9 |
|
||||||
M5_HWCAP_SPARC_ULTRA3;
|
M5_HWCAP_SPARC_ULTRA3;
|
||||||
|
|
||||||
//Setup the auxilliary vectors. These will already have
|
|
||||||
//endian conversion.
|
//Setup the auxilliary vectors. These will already have endian conversion.
|
||||||
auxv.push_back(buildAuxVect(SPARC_AT_EGID, 100));
|
//Auxilliary vectors are loaded only for elf formatted executables.
|
||||||
auxv.push_back(buildAuxVect(SPARC_AT_GID, 100));
|
ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
|
||||||
auxv.push_back(buildAuxVect(SPARC_AT_EUID, 100));
|
if(elfObject)
|
||||||
auxv.push_back(buildAuxVect(SPARC_AT_UID, 100));
|
{
|
||||||
//This would work, but the entry point is a protected member
|
//Bits which describe the system hardware capabilities
|
||||||
//auxv.push_back(buildAuxVect(SPARC_AT_ENTRY, objFile->entry));
|
auxv.push_back(buildAuxVect(SPARC_AT_HWCAP, hwcap));
|
||||||
auxv.push_back(buildAuxVect(SPARC_AT_FLAGS, 0));
|
//The system page size
|
||||||
//This is the address of the elf "interpreter", which I don't
|
auxv.push_back(buildAuxVect(SPARC_AT_PAGESZ, SparcISA::VMPageSize));
|
||||||
//think we currently set up. It should be set to 0 (I think)
|
//Defined to be 100 in the kernel source.
|
||||||
//auxv.push_back(buildAuxVect(SPARC_AT_BASE, 0));
|
//Frequency at which times() increments
|
||||||
//This is the number of headers which were in the original elf
|
auxv.push_back(buildAuxVect(SPARC_AT_CLKTCK, 100));
|
||||||
//file. This information isn't avaibale by this point.
|
// For statically linked executables, this is the virtual address of the
|
||||||
//auxv.push_back(buildAuxVect(SPARC_AT_PHNUM, 3));
|
// program header tables if they appear in the executable image
|
||||||
//This is the size of a program header entry. This isn't easy
|
auxv.push_back(buildAuxVect(SPARC_AT_PHDR, elfObject->programHeaderTable()));
|
||||||
//to compute here.
|
// This is the size of a program header entry from the elf file.
|
||||||
//auxv.push_back(buildAuxVect(SPARC_AT_PHENT, blah));
|
auxv.push_back(buildAuxVect(SPARC_AT_PHENT, elfObject->programHeaderSize()));
|
||||||
//This is should be set to load_addr (whatever that is) +
|
// This is the number of program headers from the original elf file.
|
||||||
//e_phoff. I think it's a pointer to the program headers.
|
auxv.push_back(buildAuxVect(SPARC_AT_PHNUM, elfObject->programHeaderCount()));
|
||||||
//auxv.push_back(buildAuxVect(SPARC_AT_PHDR, blah));
|
//This is the address of the elf "interpreter", It should be set
|
||||||
//This should be easy to get right, but I won't set it for now
|
//to 0 for regular executables. It should be something else
|
||||||
//auxv.push_back(buildAuxVect(SPARC_AT_CLKTCK, blah));
|
//(not sure what) for dynamic libraries.
|
||||||
auxv.push_back(buildAuxVect(SPARC_AT_PAGESZ, SparcISA::VMPageSize));
|
auxv.push_back(buildAuxVect(SPARC_AT_BASE, 0));
|
||||||
auxv.push_back(buildAuxVect(SPARC_AT_HWCAP, hwcap));
|
//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
|
//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
|
} // 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);
|
elf_end(elf);
|
||||||
return new ElfObject(fname, fd, len, data, arch, opSys);
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,12 @@ class ElfObject : public ObjectFile
|
||||||
{
|
{
|
||||||
protected:
|
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().
|
/// Helper functions for loadGlobalSymbols() and loadLocalSymbols().
|
||||||
bool loadSomeSymbols(SymbolTable *symtab, int binding);
|
bool loadSomeSymbols(SymbolTable *symtab, int binding);
|
||||||
|
|
||||||
|
@ -52,6 +58,9 @@ class ElfObject : public ObjectFile
|
||||||
|
|
||||||
static ObjectFile *tryFile(const std::string &fname, int fd,
|
static ObjectFile *tryFile(const std::string &fname, int fd,
|
||||||
size_t len, uint8_t *data);
|
size_t len, uint8_t *data);
|
||||||
|
Addr programHeaderTable() {return _programHeaderTable;}
|
||||||
|
uint16_t programHeaderSize() {return _programHeaderSize;}
|
||||||
|
uint16_t programHeaderCount() {return _programHeaderCount;}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ELF_OBJECT_HH__
|
#endif // __ELF_OBJECT_HH__
|
||||||
|
|
Loading…
Reference in a new issue