summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/alpha/linux/process.cc2
-rw-r--r--src/base/loader/elf_object.cc18
-rw-r--r--src/base/loader/elf_object.hh8
-rw-r--r--src/base/loader/object_file.cc6
-rw-r--r--src/base/loader/object_file.hh3
-rw-r--r--src/dev/i8254xGBe.cc47
-rw-r--r--src/dev/i8254xGBe.hh5
-rw-r--r--src/sim/process.cc8
-rw-r--r--src/sim/syscall_emul.hh26
9 files changed, 84 insertions, 39 deletions
diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc
index f7d946e2e..b638aa927 100644
--- a/src/arch/alpha/linux/process.cc
+++ b/src/arch/alpha/linux/process.cc
@@ -549,7 +549,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
/* 422 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
/* 423 */ SyscallDesc("semtimedop", unimplementedFunc),
/* 424 */ SyscallDesc("tgkill", unimplementedFunc),
- /* 425 */ SyscallDesc("stat64", unimplementedFunc),
+ /* 425 */ SyscallDesc("stat64", stat64Func<AlphaLinux>),
/* 426 */ SyscallDesc("lstat64", lstat64Func<AlphaLinux>),
/* 427 */ SyscallDesc("fstat64", fstat64Func<AlphaLinux>),
/* 428 */ SyscallDesc("vserver", unimplementedFunc),
diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc
index f76ea593b..ecce175b2 100644
--- a/src/base/loader/elf_object.cc
+++ b/src/base/loader/elf_object.cc
@@ -343,8 +343,8 @@ ElfObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask)
return loadSomeSymbols(symtab, STB_LOCAL);
}
-bool
-ElfObject::isDynamic()
+void
+ElfObject::getSections()
{
Elf *elf;
int sec_idx = 1; // there is a 0 but it is nothing, go figure
@@ -353,6 +353,8 @@ ElfObject::isDynamic()
GElf_Ehdr ehdr;
+ assert(!sectionNames.size());
+
// check that header matches library version
if (elf_version(EV_CURRENT) == EV_NONE)
panic("wrong elf version number!");
@@ -372,11 +374,17 @@ ElfObject::isDynamic()
// While there are no more sections
while (section != NULL) {
gelf_getshdr(section, &shdr);
- if (!strcmp(".interp", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name)))
- return true;
+ sectionNames.insert(elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name));
section = elf_getscn(elf, ++sec_idx);
} // while sections
- return false;
+}
+
+bool
+ElfObject::sectionExists(string sec)
+{
+ if (!sectionNames.size())
+ getSections();
+ return sectionNames.find(sec) != sectionNames.end();
}
diff --git a/src/base/loader/elf_object.hh b/src/base/loader/elf_object.hh
index d909140f3..3e7c85874 100644
--- a/src/base/loader/elf_object.hh
+++ b/src/base/loader/elf_object.hh
@@ -32,6 +32,7 @@
#define __ELF_OBJECT_HH__
#include "base/loader/object_file.hh"
+#include <set>
class ElfObject : public ObjectFile
{
@@ -42,6 +43,7 @@ class ElfObject : public ObjectFile
Addr _programHeaderTable;
uint16_t _programHeaderSize;
uint16_t _programHeaderCount;
+ std::set<std::string> sectionNames;
/// Helper functions for loadGlobalSymbols() and loadLocalSymbols().
bool loadSomeSymbols(SymbolTable *symtab, int binding);
@@ -50,6 +52,9 @@ class ElfObject : public ObjectFile
size_t _len, uint8_t *_data,
Arch _arch, OpSys _opSys);
+ void getSections();
+ bool sectionExists(std::string sec);
+
public:
virtual ~ElfObject() {}
@@ -58,7 +63,8 @@ class ElfObject : public ObjectFile
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max());
- virtual bool isDynamic();
+ virtual bool isDynamic() { return sectionExists(".interp"); }
+ virtual bool hasTLS() { return sectionExists(".tbss"); }
static ObjectFile *tryFile(const std::string &fname, int fd,
size_t len, uint8_t *data);
diff --git a/src/base/loader/object_file.cc b/src/base/loader/object_file.cc
index 7424b9305..2273b6c4e 100644
--- a/src/base/loader/object_file.cc
+++ b/src/base/loader/object_file.cc
@@ -150,9 +150,3 @@ createObjectFile(const string &fname, bool raw)
munmap((char*)fileData, len);
return NULL;
}
-
-bool
-ObjectFile::isDynamic()
-{
- return false;
-}
diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh
index 4b44a6e22..4f0c17cc8 100644
--- a/src/base/loader/object_file.hh
+++ b/src/base/loader/object_file.hh
@@ -85,7 +85,8 @@ class ObjectFile
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max()) = 0;
- virtual bool isDynamic();
+ virtual bool isDynamic() { return false; }
+ virtual bool hasTLS() { return false; }
Arch getArch() const { return arch; }
OpSys getOpSys() const { return opSys; }
diff --git a/src/dev/i8254xGBe.cc b/src/dev/i8254xGBe.cc
index 81a111f71..84882b056 100644
--- a/src/dev/i8254xGBe.cc
+++ b/src/dev/i8254xGBe.cc
@@ -699,8 +699,9 @@ IGbE::RxDescCache::writePacket(EthPacketPtr packet)
packet->length, igbe->regs.rctl.descSize());
assert(packet->length < igbe->regs.rctl.descSize());
- if (!unusedCache.size())
- return false;
+ assert(unusedCache.size());
+ //if (!unusedCache.size())
+ // return false;
pktPtr = packet;
pktDone = false;
@@ -823,8 +824,10 @@ IGbE::RxDescCache::pktComplete()
void
IGbE::RxDescCache::enableSm()
{
- igbe->rxTick = true;
- igbe->restartClock();
+ if (!igbe->drainEvent) {
+ igbe->rxTick = true;
+ igbe->restartClock();
+ }
}
bool
@@ -952,6 +955,7 @@ IGbE::TxDescCache::pktComplete()
DPRINTF(EthernetDesc, "Partial Packet Descriptor Done\n");
enableSm();
+ igbe->checkDrain();
return;
}
@@ -1079,8 +1083,10 @@ IGbE::TxDescCache::packetAvailable()
void
IGbE::TxDescCache::enableSm()
{
- igbe->txTick = true;
- igbe->restartClock();
+ if (!igbe->drainEvent) {
+ igbe->txTick = true;
+ igbe->restartClock();
+ }
}
bool
@@ -1172,7 +1178,7 @@ IGbE::txStateMachine()
DPRINTF(EthernetSM, "TXS: packet placed in TX FIFO\n");
success = txFifo.push(txPacket);
- txFifoTick = true;
+ txFifoTick = true && !drainEvent;
assert(success);
txPacket = NULL;
txDescCache.writeback((cacheBlockSize()-1)>>4);
@@ -1194,18 +1200,18 @@ IGbE::txStateMachine()
if (txDescCache.descLeft() == 0) {
postInterrupt(IT_TXQE);
txDescCache.writeback(0);
+ txDescCache.fetchDescriptors();
DPRINTF(EthernetSM, "TXS: No descriptors left in ring, forcing "
"writeback stopping ticking and posting TXQE\n");
- txDescCache.fetchDescriptors();
txTick = false;
return;
}
if (!(txDescCache.descUnused())) {
+ txDescCache.fetchDescriptors();
DPRINTF(EthernetSM, "TXS: No descriptors available in cache, fetching and stopping ticking\n");
txTick = false;
- txDescCache.fetchDescriptors();
return;
}
@@ -1221,7 +1227,6 @@ IGbE::txStateMachine()
DPRINTF(EthernetSM, "TXS: No packets to get, writing back used descriptors\n");
txDescCache.writeback(0);
} else {
- txDescCache.writeback((cacheBlockSize()-1)>>4);
DPRINTF(EthernetSM, "TXS: FIFO full, stopping ticking until space "
"available in FIFO\n");
txTick = false;
@@ -1245,7 +1250,7 @@ IGbE::ethRxPkt(EthPacketPtr pkt)
}
// restart the state machines if they are stopped
- rxTick = true;
+ rxTick = true && !drainEvent;
if ((rxTick || txTick) && !tickEvent.scheduled()) {
DPRINTF(EthernetSM, "RXS: received packet into fifo, starting ticking\n");
restartClock();
@@ -1306,10 +1311,10 @@ IGbE::rxStateMachine()
}
if (rxDescCache.descUnused() == 0) {
+ rxDescCache.fetchDescriptors();
DPRINTF(EthernetSM, "RXS: No descriptors available in cache, "
"fetching descriptors and stopping ticking\n");
rxTick = false;
- rxDescCache.fetchDescriptors();
}
return;
}
@@ -1321,10 +1326,10 @@ IGbE::rxStateMachine()
}
if (!rxDescCache.descUnused()) {
+ rxDescCache.fetchDescriptors();
DPRINTF(EthernetSM, "RXS: No descriptors available in cache, stopping ticking\n");
rxTick = false;
DPRINTF(EthernetSM, "RXS: No descriptors available, fetching\n");
- rxDescCache.fetchDescriptors();
return;
}
@@ -1338,15 +1343,15 @@ IGbE::rxStateMachine()
pkt = rxFifo.front();
DPRINTF(EthernetSM, "RXS: Writing packet into memory\n");
- if (!rxDescCache.writePacket(pkt)) {
+ if (rxDescCache.writePacket(pkt)) {
+ DPRINTF(EthernetSM, "RXS: Removing packet from FIFO\n");
+ rxFifo.pop();
+ DPRINTF(EthernetSM, "RXS: stopping ticking until packet DMA completes\n");
+ rxTick = false;
+ rxDmaPacket = true;
return;
}
- DPRINTF(EthernetSM, "RXS: Removing packet from FIFO\n");
- rxFifo.pop();
- DPRINTF(EthernetSM, "RXS: stopping ticking until packet DMA completes\n");
- rxTick = false;
- rxDmaPacket = true;
}
void
@@ -1404,8 +1409,8 @@ IGbE::ethTxDone()
// restart the tx state machines if they are stopped
// fifo to send another packet
// tx sm to put more data into the fifo
- txFifoTick = true;
- if (txDescCache.descLeft() != 0)
+ txFifoTick = true && !drainEvent;
+ if (txDescCache.descLeft() != 0 && !drainEvent)
txTick = true;
restartClock();
diff --git a/src/dev/i8254xGBe.hh b/src/dev/i8254xGBe.hh
index 50101325a..cbe7cf8c0 100644
--- a/src/dev/i8254xGBe.hh
+++ b/src/dev/i8254xGBe.hh
@@ -388,14 +388,13 @@ class IGbE : public EtherDevice
oldHead, curHead);
// If we still have more to wb, call wb now
- bool oldMoreToWb = moreToWb;
+ intAfterWb();
if (moreToWb) {
DPRINTF(EthernetDesc, "Writeback has more todo\n");
writeback(wbAlignment);
}
- intAfterWb();
- if (!oldMoreToWb) {
+ if (!wbOut) {
igbe->checkDrain();
}
fetchAfterWb();
diff --git a/src/sim/process.cc b/src/sim/process.cc
index 4fa5c7aad..f943cb565 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -453,9 +453,15 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd,
if (objFile->isDynamic())
fatal("Object file is a dynamic executable however only static "
- "executables are supported!\n Please recompile your "
+ "executables are supported!\n Please recompile your "
"executable as a static binary and try again.\n");
+ if (objFile->hasTLS())
+ fatal("Object file has a TLS section and loading of TLS sections "
+ "are not currently supported!\n Please recompile your "
+ "executable with a non-TLS toolchain or add TLS support to "
+ "M5 and try again\n");
+
#if THE_ISA == ALPHA_ISA
if (objFile->getArch() != ObjectFile::Alpha)
fatal("Object file architecture does not match compiled ISA (Alpha).");
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index a3d95b8ec..e2d13067c 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -604,6 +604,32 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
}
+/// Target stat64() handler.
+template <class OS>
+SyscallReturn
+stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
+ ThreadContext *tc)
+{
+ std::string path;
+
+ if (!tc->getMemPort()->tryReadString(path, tc->getSyscallArg(0)))
+ return -EFAULT;
+
+ // Adjust path for current working directory
+ path = process->fullPath(path);
+
+ struct stat64 hostBuf;
+ int result = stat64(path.c_str(), &hostBuf);
+
+ if (result < 0)
+ return -errno;
+
+ copyOutStat64Buf<OS>(tc->getMemPort(), tc->getSyscallArg(1), &hostBuf);
+
+ return 0;
+}
+
+
/// Target fstat64() handler.
template <class OS>
SyscallReturn