Added code to support setting up all of the auxillieary vectors configured by the...
authorGabe Black <gblack@eecs.umich.edu>
Sat, 12 Aug 2006 00:27:22 +0000 (20:27 -0400)
committerGabe Black <gblack@eecs.umich.edu>
Sat, 12 Aug 2006 00:27:22 +0000 (20:27 -0400)
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

src/arch/sparc/process.cc
src/base/loader/elf_object.cc
src/base/loader/elf_object.hh

index 75f01e0382d00c3c70aed8b73b17b51ca200a72f..70c7e719f42aad92706722446efce86f9cddadcc 100644 (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
 
index 00d218b768c57ce0920173017922cba69355f7ce..2ca0d4f4afeb84f218a3c797bfeadcd0349d5662 100644 (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;
     }
 }
 
index 46dbfe37b54fdcb68a2950dba9a44523af20f923..9755426b470a9aa4293e6ac0873477440155fc6d 100644 (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__