summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2006-08-11 20:27:22 -0400
committerGabe Black <gblack@eecs.umich.edu>2006-08-11 20:27:22 -0400
commitfb35d474a58dcc55da589c925d240b4bd1935646 (patch)
tree7b57f8cf514a6c59875b412782819832ca09c946 /src
parent1f44717732028a2491177816264a91f0690254c3 (diff)
downloadgem5-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.cc65
-rw-r--r--src/base/loader/elf_object.cc32
-rw-r--r--src/base/loader/elf_object.hh9
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__