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

View file

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

View file

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