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:
Gabe Black 2006-08-11 20:27:22 -04:00
parent 1f44717732
commit fb35d474a5
3 changed files with 79 additions and 27 deletions

View file

@ -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

View file

@ -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;
}
}

View file

@ -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__