diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/alpha/linux/process.cc | 2 | ||||
-rw-r--r-- | src/base/loader/elf_object.cc | 18 | ||||
-rw-r--r-- | src/base/loader/elf_object.hh | 8 | ||||
-rw-r--r-- | src/base/loader/object_file.cc | 6 | ||||
-rw-r--r-- | src/base/loader/object_file.hh | 3 | ||||
-rw-r--r-- | src/dev/i8254xGBe.cc | 47 | ||||
-rw-r--r-- | src/dev/i8254xGBe.hh | 5 | ||||
-rw-r--r-- | src/sim/process.cc | 8 | ||||
-rw-r--r-- | src/sim/syscall_emul.hh | 26 |
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 |