diff options
Diffstat (limited to 'base')
-rw-r--r-- | base/chunk_generator.hh | 137 | ||||
-rw-r--r-- | base/intmath.hh | 4 | ||||
-rw-r--r-- | base/loader/aout_object.cc | 26 | ||||
-rw-r--r-- | base/loader/aout_object.hh | 2 | ||||
-rw-r--r-- | base/loader/ecoff_object.cc | 26 | ||||
-rw-r--r-- | base/loader/ecoff_object.hh | 2 | ||||
-rw-r--r-- | base/loader/elf_object.cc | 48 | ||||
-rw-r--r-- | base/loader/elf_object.hh | 5 | ||||
-rw-r--r-- | base/loader/object_file.cc | 34 | ||||
-rw-r--r-- | base/loader/object_file.hh | 16 | ||||
-rw-r--r-- | base/remote_gdb.cc | 4 | ||||
-rw-r--r-- | base/traceflags.py | 1 |
12 files changed, 209 insertions, 96 deletions
diff --git a/base/chunk_generator.hh b/base/chunk_generator.hh new file mode 100644 index 000000000..1dca50db4 --- /dev/null +++ b/base/chunk_generator.hh @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2001-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __BASE__CHUNK_GENERATOR_HH__ +#define __BASE__CHUNK_GENERATOR_HH__ + +/** + * @file + * Declaration and inline definition of ChunkGenerator object. + */ + +#include <algorithm> +#include "base/intmath.hh" +#include "arch/isa_traits.hh" // for Addr + +/** + * This class takes an arbitrary memory region (address/length pair) + * and generates a series of appropriately (e.g. block- or page-) + * aligned chunks covering the same region. + * + * Example usage: + +\code + for (ChunkGenerator gen(addr, size, chunkSize); !gen.done(); gen.next()) { + doSomethingChunky(gen.addr(), gen.size()); + } +\endcode + */ +class ChunkGenerator +{ + private: + /** The starting address of the current chunk. */ + Addr curAddr; + /** The starting address of the next chunk (after the current one). */ + Addr nextAddr; + /** The size of the current chunk (in bytes). */ + int curSize; + /** The number of bytes remaining in the region after the current chunk. */ + int sizeLeft; + /** The maximum chunk size, e.g., the cache block size or page size. */ + const int chunkSize; + + public: + /** + * Constructor. + * @param startAddr The starting address of the region. + * @param totalSize The total size of the region. + * @param _chunkSize The size/alignment of chunks into which + * the region should be decomposed. + */ + ChunkGenerator(Addr startAddr, int totalSize, int _chunkSize) + : chunkSize(_chunkSize) + { + // chunkSize must be a power of two + assert(chunkSize == 0 || isPowerOf2(chunkSize)); + + // set up initial chunk. + curAddr = startAddr; + + if (chunkSize == 0) //Special Case, if we see 0, assume no chuncking + { + nextAddr = startAddr + totalSize; + } + else + { + // nextAddr should be *next* chunk start + nextAddr = roundUp(startAddr, chunkSize); + if (curAddr == nextAddr) { + // ... even if startAddr is already chunk-aligned + nextAddr += chunkSize; + } + } + + // how many bytes are left between curAddr and the end of this chunk? + int left_in_chunk = nextAddr - curAddr; + curSize = std::min(totalSize, left_in_chunk); + sizeLeft = totalSize - curSize; + } + + /** Return starting address of current chunk. */ + Addr addr() { return curAddr; } + /** Return size in bytes of current chunk. */ + int size() { return curSize; } + + /** + * Are we done? That is, did the last call to next() advance + * past the end of the region? + * @return True if yes, false if more to go. + */ + bool done() { return (curSize == 0); } + + /** + * Advance generator to next chunk. + * @return True if successful, false if unsuccessful + * (because we were at the last chunk). + */ + bool next() + { + if (sizeLeft == 0) { + curSize = 0; + return false; + } + + curAddr = nextAddr; + curSize = std::min(sizeLeft, chunkSize); + sizeLeft -= curSize; + nextAddr += curSize; + return true; + } +}; + +#endif // __BASE__CHUNK_GENERATOR_HH__ diff --git a/base/intmath.hh b/base/intmath.hh index df0687c62..51baddb91 100644 --- a/base/intmath.hh +++ b/base/intmath.hh @@ -186,9 +186,9 @@ roundUp(T val, int align) template <class T> inline T -roundDown(T val, T align) +roundDown(T val, int align) { - T mask = align - 1; + T mask = (T)align - 1; return val & ~mask; } diff --git a/base/loader/aout_object.cc b/base/loader/aout_object.cc index c81f7123f..564898ca3 100644 --- a/base/loader/aout_object.cc +++ b/base/loader/aout_object.cc @@ -30,7 +30,6 @@ #include "base/loader/aout_object.hh" -#include "mem/functional/functional.hh" #include "base/loader/symtab.hh" #include "base/trace.hh" // for DPRINTF @@ -64,12 +63,15 @@ AoutObject::AoutObject(const string &_filename, int _fd, text.baseAddr = N_TXTADDR(*execHdr); text.size = execHdr->tsize; + text.fileImage = fileData + N_TXTOFF(*execHdr); data.baseAddr = N_DATADDR(*execHdr); data.size = execHdr->dsize; + data.fileImage = fileData + N_DATOFF(*execHdr); bss.baseAddr = N_BSSADDR(*execHdr); bss.size = execHdr->bsize; + bss.fileImage = NULL; DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n", text.baseAddr, text.size, data.baseAddr, data.size, @@ -78,28 +80,6 @@ AoutObject::AoutObject(const string &_filename, int _fd, bool -AoutObject::loadSections(FunctionalMemory *mem, bool loadPhys) -{ - Addr textAddr = text.baseAddr; - Addr dataAddr = data.baseAddr; - - if (loadPhys) { - textAddr &= (ULL(1) << 40) - 1; - dataAddr &= (ULL(1) << 40) - 1; - } - - // Since we don't really have an MMU and all memory is - // zero-filled, there's no need to set up the BSS segment. - if (text.size != 0) - mem->prot_write(textAddr, fileData + N_TXTOFF(*execHdr), text.size); - if (data.size != 0) - mem->prot_write(dataAddr, fileData + N_DATOFF(*execHdr), data.size); - - return true; -} - - -bool AoutObject::loadGlobalSymbols(SymbolTable *symtab) { // a.out symbols not supported yet diff --git a/base/loader/aout_object.hh b/base/loader/aout_object.hh index 1868192b2..aeb710427 100644 --- a/base/loader/aout_object.hh +++ b/base/loader/aout_object.hh @@ -46,8 +46,6 @@ class AoutObject : public ObjectFile public: virtual ~AoutObject() {} - virtual bool loadSections(FunctionalMemory *mem, - bool loadPhys = false); virtual bool loadGlobalSymbols(SymbolTable *symtab); virtual bool loadLocalSymbols(SymbolTable *symtab); diff --git a/base/loader/ecoff_object.cc b/base/loader/ecoff_object.cc index 353a5f333..80917ee9c 100644 --- a/base/loader/ecoff_object.cc +++ b/base/loader/ecoff_object.cc @@ -29,8 +29,7 @@ #include <string> #include "base/loader/ecoff_object.hh" - -#include "mem/functional/functional.hh" +#include "base/misc.hh" #include "base/loader/symtab.hh" #include "base/trace.hh" // for DPRINTF @@ -68,12 +67,15 @@ EcoffObject::EcoffObject(const string &_filename, int _fd, text.baseAddr = aoutHdr->text_start; text.size = aoutHdr->tsize; + text.fileImage = fileData + ECOFF_TXTOFF(execHdr); data.baseAddr = aoutHdr->data_start; data.size = aoutHdr->dsize; + data.fileImage = fileData + ECOFF_DATOFF(execHdr); bss.baseAddr = aoutHdr->bss_start; bss.size = aoutHdr->bsize; + bss.fileImage = NULL; DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n", text.baseAddr, text.size, data.baseAddr, data.size, @@ -82,26 +84,6 @@ EcoffObject::EcoffObject(const string &_filename, int _fd, bool -EcoffObject::loadSections(FunctionalMemory *mem, bool loadPhys) -{ - Addr textAddr = text.baseAddr; - Addr dataAddr = data.baseAddr; - - if (loadPhys) { - textAddr &= (ULL(1) << 40) - 1; - dataAddr &= (ULL(1) << 40) - 1; - } - - // Since we don't really have an MMU and all memory is - // zero-filled, there's no need to set up the BSS segment. - mem->prot_write(textAddr, fileData + ECOFF_TXTOFF(execHdr), text.size); - mem->prot_write(dataAddr, fileData + ECOFF_DATOFF(execHdr), data.size); - - return true; -} - - -bool EcoffObject::loadGlobalSymbols(SymbolTable *symtab) { if (!symtab) diff --git a/base/loader/ecoff_object.hh b/base/loader/ecoff_object.hh index 78aa7f3f7..603c70bec 100644 --- a/base/loader/ecoff_object.hh +++ b/base/loader/ecoff_object.hh @@ -50,8 +50,6 @@ class EcoffObject : public ObjectFile public: virtual ~EcoffObject() {} - virtual bool loadSections(FunctionalMemory *mem, - bool loadPhys = false); virtual bool loadGlobalSymbols(SymbolTable *symtab); virtual bool loadLocalSymbols(SymbolTable *symtab); diff --git a/base/loader/elf_object.cc b/base/loader/elf_object.cc index 791c6f6de..58029bc3e 100644 --- a/base/loader/elf_object.cc +++ b/base/loader/elf_object.cc @@ -42,12 +42,14 @@ #include "libelf/gelf.h" #include "base/loader/elf_object.hh" +#include "base/misc.hh" -#include "mem/functional/functional.hh" #include "base/loader/symtab.hh" #include "base/trace.hh" // for DPRINTF +#include "sim/byteswap.hh" + using namespace std; @@ -73,8 +75,7 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) DPRINTFR(Loader, "Not ELF\n"); elf_end(elf); return NULL; - } - else { + } else { //Detect the architecture //Versioning issues in libelf need to be resolved to get the correct //SPARC constants. @@ -90,7 +91,7 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) arch = ObjectFile::SPARC; } else if (ehdr.e_machine == EM_MIPS && ehdr.e_ident[EI_CLASS] == ELFCLASS32) { - arch = ObjectFile::MIPS; + arch = ObjectFile::Mips; } else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) { arch = ObjectFile::Alpha; } else { @@ -154,6 +155,7 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) section = elf_getscn(elf, ++secIdx); } // while sections } + elf_end(elf); return new ElfObject(fname, fd, len, data, arch, opSys); } @@ -185,6 +187,7 @@ ElfObject::ElfObject(const string &_filename, int _fd, entry = ehdr.e_entry; + // initialize segment sizes to 0 in case they're not present text.size = data.size = bss.size = 0; @@ -203,20 +206,18 @@ ElfObject::ElfObject(const string &_filename, int _fd, if (text.size == 0) { // haven't seen text segment yet text.baseAddr = phdr.p_vaddr; text.size = phdr.p_filesz; - // remember where the data is for loadSections() - fileTextBits = fileData + phdr.p_offset; + text.fileImage = fileData + phdr.p_offset; // if there's any padding at the end that's not in the // file, call it the bss. This happens in the "text" // segment if there's only one loadable segment (as for // kernel images). bss.size = phdr.p_memsz - phdr.p_filesz; bss.baseAddr = phdr.p_vaddr + phdr.p_filesz; - } - else if (data.size == 0) { // have text, this must be data + bss.fileImage = NULL; + } else if (data.size == 0) { // have text, this must be data data.baseAddr = phdr.p_vaddr; data.size = phdr.p_filesz; - // remember where the data is for loadSections() - fileDataBits = fileData + phdr.p_offset; + data.fileImage = fileData + phdr.p_offset; // if there's any padding at the end that's not in the // file, call it the bss. Warn if this happens for both // the text & data segments (should only have one bss). @@ -225,6 +226,11 @@ ElfObject::ElfObject(const string &_filename, int _fd, } bss.size = phdr.p_memsz - phdr.p_filesz; bss.baseAddr = phdr.p_vaddr + phdr.p_filesz; + bss.fileImage = NULL; + } else { + warn("More than two loadable segments in ELF object."); + warn("Ignoring segment @ 0x%x length 0x%x.", + phdr.p_vaddr, phdr.p_filesz); } } @@ -242,28 +248,6 @@ ElfObject::ElfObject(const string &_filename, int _fd, bool -ElfObject::loadSections(FunctionalMemory *mem, bool loadPhys) -{ - Addr textAddr = text.baseAddr; - Addr dataAddr = data.baseAddr; - - if (loadPhys) { - textAddr &= (ULL(1) << 40) - 1; - dataAddr &= (ULL(1) << 40) - 1; - } - - // Since we don't really have an MMU and all memory is - // zero-filled, there's no need to set up the BSS segment. - if (text.size != 0) - mem->prot_write(textAddr, fileTextBits, text.size); - if (data.size != 0) - mem->prot_write(dataAddr, fileDataBits, data.size); - - return true; -} - - -bool ElfObject::loadSomeSymbols(SymbolTable *symtab, int binding) { Elf *elf; diff --git a/base/loader/elf_object.hh b/base/loader/elf_object.hh index 66d8b3e63..72c265edd 100644 --- a/base/loader/elf_object.hh +++ b/base/loader/elf_object.hh @@ -35,9 +35,6 @@ class ElfObject : public ObjectFile { protected: - uint8_t *fileTextBits; //!< Pointer to file's text segment image - uint8_t *fileDataBits; //!< Pointer to file's data segment image - /// Helper functions for loadGlobalSymbols() and loadLocalSymbols(). bool loadSomeSymbols(SymbolTable *symtab, int binding); @@ -48,8 +45,6 @@ class ElfObject : public ObjectFile public: virtual ~ElfObject() {} - virtual bool loadSections(FunctionalMemory *mem, - bool loadPhys = false); virtual bool loadGlobalSymbols(SymbolTable *symtab); virtual bool loadLocalSymbols(SymbolTable *symtab); diff --git a/base/loader/object_file.cc b/base/loader/object_file.cc index 1410d05b8..7f46ae2fb 100644 --- a/base/loader/object_file.cc +++ b/base/loader/object_file.cc @@ -43,6 +43,8 @@ #include "base/loader/aout_object.hh" #include "base/loader/elf_object.hh" +#include "mem/translating_port.hh" + using namespace std; ObjectFile::ObjectFile(const string &_filename, int _fd, @@ -60,6 +62,38 @@ ObjectFile::~ObjectFile() } +bool +ObjectFile::loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys) +{ + if (sec->size != 0) { + Addr addr = sec->baseAddr; + if (loadPhys) { + // this is Alpha-specific... going to have to fix this + // for other architectures + addr &= (ULL(1) << 40) - 1; + } + + if (sec->fileImage) { + memPort->writeBlob(addr, sec->fileImage, sec->size, true); + } + else { + // no image: must be bss + memPort->memsetBlob(addr, 0, sec->size, true); + } + } + return true; +} + + +bool +ObjectFile::loadSections(TranslatingPort *memPort, bool loadPhys) +{ + return (loadSection(&text, memPort, loadPhys) + && loadSection(&data, memPort, loadPhys) + && loadSection(&bss, memPort, loadPhys)); +} + + void ObjectFile::close() { diff --git a/base/loader/object_file.hh b/base/loader/object_file.hh index 1b44ae14f..309089728 100644 --- a/base/loader/object_file.hh +++ b/base/loader/object_file.hh @@ -33,7 +33,7 @@ #include "sim/host.hh" // for Addr -class FunctionalMemory; +class TranslatingPort; class SymbolTable; class ObjectFile @@ -44,7 +44,7 @@ class ObjectFile UnknownArch, Alpha, SPARC, - MIPS + Mips }; enum OpSys { @@ -72,8 +72,7 @@ class ObjectFile void close(); - virtual bool loadSections(FunctionalMemory *mem, - bool loadPhys = false) = 0; + virtual bool loadSections(TranslatingPort *memPort, bool loadPhys = false); virtual bool loadGlobalSymbols(SymbolTable *symtab) = 0; virtual bool loadLocalSymbols(SymbolTable *symtab) = 0; @@ -83,8 +82,9 @@ class ObjectFile protected: struct Section { - Addr baseAddr; - size_t size; + Addr baseAddr; + uint8_t *fileImage; + size_t size; }; Addr entry; @@ -94,8 +94,12 @@ class ObjectFile Section data; Section bss; + bool loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys); + void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; } + public: Addr entryPoint() const { return entry; } + Addr globalPointer() const { return globalPtr; } Addr textBase() const { return text.baseAddr; } diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc index 84093459c..8a6cbdc33 100644 --- a/base/remote_gdb.cc +++ b/base/remote_gdb.cc @@ -440,7 +440,7 @@ RemoteGDB::getregs() #ifdef KGDB_FP_REGS for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { - gdbregs[i + KGDB_REG_F0] = context->readFloatRegInt(i); + gdbregs[i + KGDB_REG_F0] = context->readFloatRegBits(i); } #endif } @@ -467,7 +467,7 @@ RemoteGDB::setregs() #ifdef KGDB_FP_REGS for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { - context->setFloatRegInt(i, gdbregs[i + KGDB_REG_F0]); + context->setFloatRegBits(i, gdbregs[i + KGDB_REG_F0]); } #endif context->setPC(gdbregs[KGDB_REG_PC]); diff --git a/base/traceflags.py b/base/traceflags.py index e814a00fb..c3b878027 100644 --- a/base/traceflags.py +++ b/base/traceflags.py @@ -142,6 +142,7 @@ baseFlags = [ 'OoOCPU', 'HWPrefetch', 'Stack', + 'SimpleCPU', ] # |