summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorBrandon Potter <brandon.potter@amd.com>2016-03-17 10:31:03 -0700
committerBrandon Potter <brandon.potter@amd.com>2016-03-17 10:31:03 -0700
commit9b4249410ec18cac9df2c7e9c0a4a6ce5459233d (patch)
treec3260ef4f23b9eca7d835ab1e0dfc8ce1173b17c /src/arch
parent4fc69db8f89049a881a5f4aa68545840818b124c (diff)
downloadgem5-9b4249410ec18cac9df2c7e9c0a4a6ce5459233d.tar.xz
base: support dynamic loading of Linux ELF objects in SE mode
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/alpha/process.cc9
-rw-r--r--src/arch/arm/process.cc13
-rw-r--r--src/arch/mips/process.cc9
-rw-r--r--src/arch/power/process.cc14
-rw-r--r--src/arch/sparc/process.cc13
-rw-r--r--src/arch/x86/process.cc24
6 files changed, 54 insertions, 28 deletions
diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc
index 54ef338f3..9e298f0c6 100644
--- a/src/arch/alpha/process.cc
+++ b/src/arch/alpha/process.cc
@@ -67,6 +67,9 @@ AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params,
void
AlphaLiveProcess::argsInit(int intSize, int pageSize)
{
+ // Patch the ld_bias for dynamic executables.
+ updateBias();
+
objFile->loadSections(initVirtMem);
typedef AuxVector<uint64_t> auxv_t;
@@ -88,6 +91,10 @@ AlphaLiveProcess::argsInit(int intSize, int pageSize)
auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
DPRINTF(Loader, "auxv at PHDR %08p\n", elfObject->programHeaderTable());
auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
+ // This is the base address of the ELF interpreter; it should be
+ // zero for static executables or contain the base address for
+ // dynamic executables.
+ auxv.push_back(auxv_t(M5_AT_BASE, getBias()));
auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
auxv.push_back(auxv_t(M5_AT_UID, uid()));
auxv.push_back(auxv_t(M5_AT_EUID, euid()));
@@ -163,7 +170,7 @@ AlphaLiveProcess::argsInit(int intSize, int pageSize)
setSyscallArg(tc, 1, argv_array_base);
tc->setIntReg(StackPointerReg, stack_min);
- tc->pcState(objFile->entryPoint());
+ tc->pcState(getStartPC());
}
void
diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc
index 0c6f48fb5..a787b1f66 100644
--- a/src/arch/arm/process.cc
+++ b/src/arch/arm/process.cc
@@ -156,6 +156,9 @@ ArmLiveProcess::argsInit(int pageSize, IntRegIndex spIndex)
//We want 16 byte alignment
uint64_t align = 16;
+ // Patch the ld_bias for dynamic executables.
+ updateBias();
+
// load object file into target memory
objFile->loadSections(initVirtMem);
@@ -225,10 +228,10 @@ ArmLiveProcess::argsInit(int pageSize, IntRegIndex spIndex)
auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
// This is the number of program headers from the original elf file.
auxv.push_back(auxv_t(M5_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(auxv_t(M5_AT_BASE, 0));
+ // This is the base address of the ELF interpreter; it should be
+ // zero for static executables or contain the base address for
+ // dynamic executables.
+ auxv.push_back(auxv_t(M5_AT_BASE, getBias()));
//XXX Figure out what this should be.
auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
//The entry point to the program
@@ -392,7 +395,7 @@ ArmLiveProcess::argsInit(int pageSize, IntRegIndex spIndex)
pc.nextThumb(pc.thumb());
pc.aarch64(arch == ObjectFile::Arm64);
pc.nextAArch64(pc.aarch64());
- pc.set(objFile->entryPoint() & ~mask(1));
+ pc.set(getStartPC() & ~mask(1));
tc->pcState(pc);
//Align the "stack_min" to a page boundary.
diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc
index 8754191fa..6947eeafd 100644
--- a/src/arch/mips/process.cc
+++ b/src/arch/mips/process.cc
@@ -78,6 +78,9 @@ MipsLiveProcess::argsInit(int pageSize)
{
int intSize = sizeof(IntType);
+ // Patch the ld_bias for dynamic executables.
+ updateBias();
+
// load object file into target memory
objFile->loadSections(initVirtMem);
@@ -100,6 +103,10 @@ MipsLiveProcess::argsInit(int pageSize)
auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
// This is the number of program headers from the original elf file.
auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
+ // This is the base address of the ELF interpreter; it should be
+ // zero for static executables or contain the base address for
+ // dynamic executables.
+ auxv.push_back(auxv_t(M5_AT_BASE, getBias()));
//The entry point to the program
auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
//Different user and group IDs
@@ -177,7 +184,7 @@ MipsLiveProcess::argsInit(int pageSize)
setSyscallArg(tc, 1, argv_array_base);
tc->setIntReg(StackPointerReg, stack_min);
- tc->pcState(objFile->entryPoint());
+ tc->pcState(getStartPC());
}
diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc
index a770d8137..10e4a85a0 100644
--- a/src/arch/power/process.cc
+++ b/src/arch/power/process.cc
@@ -85,6 +85,9 @@ PowerLiveProcess::argsInit(int intSize, int pageSize)
//We want 16 byte alignment
uint64_t align = 16;
+ // Patch the ld_bias for dynamic executables.
+ updateBias();
+
// load object file into target memory
objFile->loadSections(initVirtMem);
@@ -108,11 +111,10 @@ PowerLiveProcess::argsInit(int intSize, int pageSize)
auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
// This is the number of program headers from the original elf file.
auxv.push_back(auxv_t(M5_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(auxv_t(M5_AT_BASE, 0));
-
+ // This is the base address of the ELF interpreter; it should be
+ // zero for static executables or contain the base address for
+ // dynamic executables.
+ auxv.push_back(auxv_t(M5_AT_BASE, getBias()));
//XXX Figure out what this should be.
auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
//The entry point to the program
@@ -255,7 +257,7 @@ PowerLiveProcess::argsInit(int intSize, int pageSize)
//Set the stack pointer register
tc->setIntReg(StackPointerReg, stack_min);
- tc->pcState(objFile->entryPoint());
+ tc->pcState(getStartPC());
//Align the "stack_min" to a page boundary.
stack_min = roundDown(stack_min, pageSize);
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 8c8be65ab..09d52ae6b 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -203,6 +203,9 @@ SparcLiveProcess::argsInit(int pageSize)
// maintain double word alignment of the stack pointer.
uint64_t align = 16;
+ // Patch the ld_bias for dynamic executables.
+ updateBias();
+
// load object file into target memory
objFile->loadSections(initVirtMem);
@@ -245,10 +248,10 @@ SparcLiveProcess::argsInit(int pageSize)
auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
// This is the number of program headers from the original elf file.
auxv.push_back(auxv_t(M5_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(auxv_t(M5_AT_BASE, 0));
+ // This is the base address of the ELF interpreter; it should be
+ // zero for static executables or contain the base address for
+ // dynamic executables.
+ auxv.push_back(auxv_t(M5_AT_BASE, getBias()));
// This is hardwired to 0 in the elf loading code in the kernel
auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
// The entry point to the program
@@ -402,7 +405,7 @@ SparcLiveProcess::argsInit(int pageSize)
// don't have anything like that, it should be set to 0.
tc->setIntReg(1, 0);
- tc->pcState(objFile->entryPoint());
+ tc->pcState(getStartPC());
// Align the "stack_min" to a page boundary.
stack_min = roundDown(stack_min, pageSize);
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index d2ce4dbd1..66a520bc3 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -756,6 +756,9 @@ X86LiveProcess::argsInit(int pageSize,
//We want 16 byte alignment
uint64_t align = 16;
+ // Patch the ld_bias for dynamic executables.
+ updateBias();
+
// load object file into target memory
objFile->loadSections(initVirtMem);
@@ -798,8 +801,10 @@ X86LiveProcess::argsInit(int pageSize,
X86_IA64Processor = 1 << 30
};
- // Setup the auxilliary vectors. These will already have endian conversion.
- // Auxilliary vectors are loaded only for elf formatted executables.
+ // Setup the auxiliary vectors. These will already have endian
+ // conversion. Auxiliary vectors are loaded only for elf formatted
+ // executables; the auxv is responsible for passing information from
+ // the OS to the interpreter.
ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
if (elfObject) {
uint64_t features =
@@ -842,18 +847,17 @@ X86LiveProcess::argsInit(int pageSize,
//Frequency at which times() increments
//Defined to be 100 in the kernel source.
auxv.push_back(auxv_t(M5_AT_CLKTCK, 100));
- // For statically linked executables, this is the virtual address of the
- // program header tables if they appear in the executable image
+ // This is the virtual address of the program header tables if they
+ // appear in the executable image.
auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
// This is the size of a program header entry from the elf file.
auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
// This is the number of program headers from the original elf file.
auxv.push_back(auxv_t(M5_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(auxv_t(M5_AT_BASE, 0));
-
+ // This is the base address of the ELF interpreter; it should be
+ // zero for static executables or contain the base address for
+ // dynamic executables.
+ auxv.push_back(auxv_t(M5_AT_BASE, getBias()));
//XXX Figure out what this should be.
auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
//The entry point to the program
@@ -1014,7 +1018,7 @@ X86LiveProcess::argsInit(int pageSize,
// There doesn't need to be any segment base added in since we're dealing
// with the flat segmentation model.
- tc->pcState(objFile->entryPoint());
+ tc->pcState(getStartPC());
//Align the "stack_min" to a page boundary.
stack_min = roundDown(stack_min, pageSize);