summaryrefslogtreecommitdiff
path: root/src/base/loader
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/loader')
-rw-r--r--src/base/loader/aout_object.cc22
-rw-r--r--src/base/loader/aout_object.hh15
-rw-r--r--src/base/loader/dtb_object.cc13
-rw-r--r--src/base/loader/dtb_object.hh74
-rw-r--r--src/base/loader/ecoff_object.cc24
-rw-r--r--src/base/loader/ecoff_object.hh14
-rw-r--r--src/base/loader/elf_object.cc20
-rw-r--r--src/base/loader/elf_object.hh38
-rw-r--r--src/base/loader/memory_image.cc64
-rw-r--r--src/base/loader/memory_image.hh146
-rw-r--r--src/base/loader/object_file.cc25
-rw-r--r--src/base/loader/object_file.hh87
-rw-r--r--src/base/loader/raw_object.cc10
-rw-r--r--src/base/loader/raw_object.hh17
14 files changed, 347 insertions, 222 deletions
diff --git a/src/base/loader/aout_object.cc b/src/base/loader/aout_object.cc
index 97651586f..eb633c1ce 100644
--- a/src/base/loader/aout_object.cc
+++ b/src/base/loader/aout_object.cc
@@ -58,17 +58,23 @@ AoutObject::AoutObject(const string &_filename,
: ObjectFile(_filename, _len, _data, _arch, _opSys)
{
execHdr = (aout_exechdr *)fileData;
-
entry = execHdr->entry;
+}
- addSegment("text", N_TXTADDR(*execHdr), fileData + N_TXTOFF(*execHdr),
- execHdr->tsize);
- addSegment("data", N_DATADDR(*execHdr), fileData + N_DATOFF(*execHdr),
- execHdr->dsize);
- addSegment("bss", N_BSSADDR(*execHdr), nullptr, execHdr->bsize);
+MemoryImage
+AoutObject::buildImage() const
+{
+ MemoryImage image({
+ { "text", N_TXTADDR(*execHdr),
+ fileData + N_TXTOFF(*execHdr), execHdr->tsize },
+ { "data", N_DATADDR(*execHdr),
+ fileData + N_DATOFF(*execHdr), execHdr->dsize },
+ { "bss", N_BSSADDR(*execHdr), nullptr, execHdr->bsize}
+ });
- for (auto &seg: segments)
- DPRINTFR(Loader, "%s\n", *seg);
+ for (auto &seg: image.segments())
+ DPRINTFR(Loader, "%s\n", seg);
+ return image;
}
diff --git a/src/base/loader/aout_object.hh b/src/base/loader/aout_object.hh
index 65ed7ca0f..4f8c86fcd 100644
--- a/src/base/loader/aout_object.hh
+++ b/src/base/loader/aout_object.hh
@@ -48,13 +48,14 @@ class AoutObject : public ObjectFile
public:
virtual ~AoutObject() {}
- virtual bool loadAllSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addr_mask = maxAddr);
- virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0,
- Addr addr_mask = maxAddr);
- virtual bool loadLocalSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addr_mask = maxAddr);
+ MemoryImage buildImage() const override;
+
+ bool loadAllSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask = MaxAddr) override;
+ bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadLocalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
static ObjectFile *tryFile(const std::string &fname,
size_t len, uint8_t *data);
diff --git a/src/base/loader/dtb_object.cc b/src/base/loader/dtb_object.cc
index 275139a8c..f5b206a74 100644
--- a/src/base/loader/dtb_object.cc
+++ b/src/base/loader/dtb_object.cc
@@ -53,10 +53,8 @@ DtbObject::tryFile(const std::string &fname, size_t len, uint8_t *data)
DtbObject::DtbObject(const std::string &_filename, size_t _len, uint8_t *_data,
Arch _arch, OpSys _opSys)
- : ObjectFile(_filename, _len, _data, _arch, _opSys),
- data(new Segment{ "data", 0, fileData, len })
+ : ObjectFile(_filename, _len, _data, _arch, _opSys)
{
- segments.emplace_back(data);
fileDataMmapped = true;
}
@@ -131,9 +129,6 @@ DtbObject::addBootCmdLine(const char* _args, size_t len)
return false;
}
- data->size = newLen;
- data->data = fdt_buf_w_space;
-
// clean up old buffer and set to new fdt blob
munmap(fileData, this->len);
fileData = fdt_buf_w_space;
@@ -164,6 +159,12 @@ DtbObject::findReleaseAddr()
return rel_addr;
}
+MemoryImage
+DtbObject::buildImage() const
+{
+ return {{"data", 0, fileData, len}};
+}
+
bool
DtbObject::loadAllSymbols(SymbolTable *symtab, Addr base, Addr offset,
Addr addr_mask)
diff --git a/src/base/loader/dtb_object.hh b/src/base/loader/dtb_object.hh
index 7cb842e43..1284025ff 100644
--- a/src/base/loader/dtb_object.hh
+++ b/src/base/loader/dtb_object.hh
@@ -40,50 +40,50 @@
*/
class DtbObject : public ObjectFile
{
- protected:
- DtbObject(const std::string &_filename, size_t _len, uint8_t *_data,
- Arch _arch, OpSys _opSys);
+ protected:
+ DtbObject(const std::string &_filename, size_t _len, uint8_t *_data,
+ Arch _arch, OpSys _opSys);
- /** Bool marking if this dtb file has replaced the original
- * read in DTB file with a new modified buffer
- */
- bool fileDataMmapped;
+ /** Bool marking if this dtb file has replaced the original
+ * read in DTB file with a new modified buffer
+ */
+ bool fileDataMmapped;
- Segment *data;
+ public:
+ virtual ~DtbObject();
- public:
- virtual ~DtbObject();
+ /** Adds the passed in Command Line options for the kernel
+ * to the proper location in the device tree.
+ * @param _args command line to append
+ * @param len length of the command line string
+ * @return returns true on success, false otherwise
+ */
+ bool addBootCmdLine(const char* _args, size_t len);
- /** Adds the passed in Command Line options for the kernel
- * to the proper location in the device tree.
- * @param _args command line to append
- * @param len length of the command line string
- * @return returns true on success, false otherwise
- */
- bool addBootCmdLine(const char* _args, size_t len);
+ /** Parse the DTB file enough to find the provided release
+ * address and return it.
+ * @return release address for SMP boot
+ */
+ Addr findReleaseAddr();
- /** Parse the DTB file enough to find the provided release
- * address and return it.
- * @return release address for SMP boot
- */
- Addr findReleaseAddr();
+ MemoryImage buildImage() const override;
- bool loadAllSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addrMask = maxAddr);
- bool loadGlobalSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addrMask = maxAddr);
- bool loadLocalSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addrMask = maxAddr);
+ bool loadAllSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addrMask=MaxAddr) override;
+ bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addrMask=MaxAddr) override;
+ bool loadLocalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addrMask=MaxAddr) override;
- /** Static function that tries to load file as a
- * flattened device tree blob.
- * @param fname path to file
- * @param len length of file
- * @param data mmap'ed data buffer containing file contents
- * @return ObjectFile representing closest match of file type
- */
- static ObjectFile *tryFile(const std::string &fname,
- size_t len, uint8_t *data);
+ /** Static function that tries to load file as a
+ * flattened device tree blob.
+ * @param fname path to file
+ * @param len length of file
+ * @param data mmap'ed data buffer containing file contents
+ * @return ObjectFile representing closest match of file type
+ */
+ static ObjectFile *tryFile(const std::string &fname,
+ size_t len, uint8_t *data);
};
#endif //__DTB_OBJECT_HH__
diff --git a/src/base/loader/ecoff_object.cc b/src/base/loader/ecoff_object.cc
index 56f9b35fc..cecc68dc1 100644
--- a/src/base/loader/ecoff_object.cc
+++ b/src/base/loader/ecoff_object.cc
@@ -72,15 +72,23 @@ EcoffObject::EcoffObject(const string &_filename, size_t _len, uint8_t *_data,
aoutHdr = &(execHdr->a);
entry = aoutHdr->entry;
+}
- addSegment("text", aoutHdr->text_start, fileData + ECOFF_TXTOFF(execHdr),
- aoutHdr->tsize);
- addSegment("data", aoutHdr->data_start, fileData + ECOFF_DATOFF(execHdr),
- aoutHdr->dsize);
- addSegment("bss", aoutHdr->bss_start, nullptr, aoutHdr->bsize);
-
- for (auto &seg: segments)
- DPRINTFR(Loader, "%s\n", *seg);
+MemoryImage
+EcoffObject::buildImage() const
+{
+ MemoryImage image({
+ { "text", aoutHdr->text_start,
+ fileData + ECOFF_TXTOFF(execHdr), aoutHdr->tsize },
+ { "data", aoutHdr->data_start,
+ fileData + ECOFF_DATOFF(execHdr), aoutHdr->dsize },
+ { "bss", aoutHdr->bss_start, nullptr, aoutHdr->bsize }
+ });
+
+ for (auto &seg: image.segments())
+ DPRINTFR(Loader, "%s\n", seg);
+
+ return image;
}
bool
diff --git a/src/base/loader/ecoff_object.hh b/src/base/loader/ecoff_object.hh
index b1ae91107..94811158e 100644
--- a/src/base/loader/ecoff_object.hh
+++ b/src/base/loader/ecoff_object.hh
@@ -51,12 +51,14 @@ class EcoffObject : public ObjectFile
public:
virtual ~EcoffObject() {}
- virtual bool loadAllSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addr_mask = maxAddr);
- virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addr_mask = maxAddr);
- virtual bool loadLocalSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addr_mask = maxAddr);
+ MemoryImage buildImage() const override;
+
+ bool loadAllSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadLocalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
static ObjectFile *tryFile(const std::string &fname,
size_t len, uint8_t *data);
diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc
index 4cf20975d..7a83c0bd2 100644
--- a/src/base/loader/elf_object.cc
+++ b/src/base/loader/elf_object.cc
@@ -339,26 +339,25 @@ ElfObject::ElfObject(const std::string &_filename, size_t _len,
section = elf_getscn(elf, ++sec_idx);
}
- addSegment(name, phdr.p_paddr, fileData + phdr.p_offset,
- phdr.p_filesz);
+ image.addSegment(name, phdr.p_paddr, fileData + phdr.p_offset,
+ phdr.p_filesz);
Addr uninitialized = phdr.p_memsz - phdr.p_filesz;
if (uninitialized) {
// There may be parts of a segment which aren't included in the
// file. In those cases, we need to create a new segment with no
// data to take up the extra space. This should be zeroed when
// loaded into memory.
- addSegment(name + "(uninitialized)", phdr.p_paddr + phdr.p_filesz,
- nullptr, uninitialized);
+ image.addSegment(name + "(uninitialized)",
+ phdr.p_paddr + phdr.p_filesz, nullptr, uninitialized);
}
}
// should have found at least one loadable segment
- warn_if(segments.empty(),
- "No loadable segments in '%s'. ELF file corrupted?\n",
- filename);
+ warn_if(image.segments().empty(),
+ "No loadable segments in '%s'. ELF file corrupted?\n", filename);
- for (auto &seg: segments)
- DPRINTFR(Loader, "%s\n", *seg);
+ for (auto &seg: image.segments())
+ DPRINTFR(Loader, "%s\n", seg);
elf_end(elf);
@@ -518,6 +517,5 @@ ElfObject::updateBias(Addr bias_addr)
entry += bias_addr;
// Patch segments with the bias_addr.
- for (auto &segment : segments)
- segment->base += bias_addr;
+ image.offset(bias_addr);
}
diff --git a/src/base/loader/elf_object.hh b/src/base/loader/elf_object.hh
index dbefadd19..0b8c79b47 100644
--- a/src/base/loader/elf_object.hh
+++ b/src/base/loader/elf_object.hh
@@ -86,34 +86,30 @@ class ElfObject : public ObjectFile
void getSections();
bool sectionExists(std::string sec);
+ MemoryImage image;
+
public:
virtual ~ElfObject() {}
- virtual bool loadAllSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addr_mask = maxAddr)
- override;
-
- virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addr_mask = maxAddr)
- override;
-
- virtual bool loadLocalSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addr_mask = maxAddr)
- override;
+ MemoryImage buildImage() const override { return image; }
- virtual bool loadWeakSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addr_mask = maxAddr)
- override;
+ bool loadAllSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadLocalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadWeakSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
- virtual ObjectFile *getInterpreter() const override
- { return interpreter; }
- virtual Addr bias() const override { return ldBias; }
- virtual bool relocatable() const override { return relocate; }
- virtual Addr mapSize() const override { return ldMax - ldMin; }
- virtual void updateBias(Addr bias_addr) override;
+ ObjectFile *getInterpreter() const override { return interpreter; }
+ Addr bias() const override { return ldBias; }
+ bool relocatable() const override { return relocate; }
+ Addr mapSize() const override { return ldMax - ldMin; }
+ void updateBias(Addr bias_addr) override;
- virtual bool hasTLS() override { return sectionExists(".tbss"); }
+ bool hasTLS() override { return sectionExists(".tbss"); }
static ObjectFile *tryFile(const std::string &fname,
size_t len, uint8_t *data,
diff --git a/src/base/loader/memory_image.cc b/src/base/loader/memory_image.cc
new file mode 100644
index 000000000..6fa70c99d
--- /dev/null
+++ b/src/base/loader/memory_image.cc
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2002-2004 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.
+ *
+ * Authors: Nathan Binkert
+ * Steve Reinhardt
+ */
+
+#include "base/loader/memory_image.hh"
+#include "mem/port_proxy.hh"
+
+bool
+MemoryImage::writeSegment(const Segment &seg, const PortProxy &proxy) const
+{
+ if (seg.size != 0) {
+ if (seg.data) {
+ proxy.writeBlob(seg.base, seg.data, seg.size);
+ } else {
+ // no image: must be bss
+ proxy.memsetBlob(seg.base, 0, seg.size);
+ }
+ }
+ return true;
+}
+
+bool
+MemoryImage::write(const PortProxy &proxy) const
+{
+ for (auto &seg: _segments)
+ if (!writeSegment(seg, proxy))
+ return false;
+ return true;
+}
+
+MemoryImage &
+MemoryImage::move(std::function<Addr(Addr)> mapper)
+{
+ for (auto &seg: _segments)
+ seg.base = mapper(seg.base);
+ return *this;
+}
diff --git a/src/base/loader/memory_image.hh b/src/base/loader/memory_image.hh
new file mode 100644
index 000000000..866e9560c
--- /dev/null
+++ b/src/base/loader/memory_image.hh
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2002-2004 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.
+ *
+ * Authors: Nathan Binkert
+ * Steve Reinhardt
+ */
+
+#ifndef __BASE_LOADER_MEMORY_IMAGE_HH__
+#define __BASE_LOADER_MEMORY_IMAGE_HH__
+
+#include <functional>
+#include <initializer_list>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/logging.hh"
+#include "base/types.hh"
+
+class PortProxy;
+class Process;
+class ProcessParams;
+class SymbolTable;
+
+class MemoryImage
+{
+ public:
+ struct Segment
+ {
+ std::string name;
+ Addr base;
+ uint8_t *data;
+ size_t size;
+ };
+
+ MemoryImage() {}
+
+ MemoryImage(std::initializer_list<Segment> new_segs)
+ {
+ for (auto &seg: new_segs)
+ addSegment(seg);
+ }
+
+ private:
+ std::vector<Segment> _segments;
+ bool writeSegment(const Segment &seg, const PortProxy &proxy) const;
+
+ public:
+ const std::vector<Segment> &
+ segments() const
+ {
+ return _segments;
+ }
+
+ void
+ addSegment(const Segment &seg)
+ {
+ _segments.emplace_back(seg);
+ }
+
+ void
+ addSegment(std::string name, Addr base, uint8_t *data, size_t size)
+ {
+ _segments.push_back(Segment({name, base, data, size}));
+ }
+
+ bool write(const PortProxy &proxy) const;
+ MemoryImage &move(std::function<Addr(Addr)> mapper);
+ MemoryImage &
+ offset(Addr by)
+ {
+ return move([by](Addr a){ return by + a; });
+ }
+ MemoryImage &
+ mask(Addr m) {
+ return move([m](Addr a) { return a & m; });
+ }
+
+ Addr
+ maxAddr() const
+ {
+ Addr max = 0;
+ for (auto &seg: _segments) {
+ Addr end = seg.base + seg.size;
+ if (end > max)
+ max = end;
+ }
+ return max;
+ }
+
+ Addr
+ minAddr() const
+ {
+ Addr min = MaxAddr;
+ for (auto &seg: _segments)
+ if (seg.base < min)
+ min = seg.base;
+ return min;
+ }
+
+ bool
+ contains(Addr addr) const
+ {
+ for (auto &seg: _segments) {
+ Addr start = seg.base;
+ Addr end = seg.base + seg.size;
+ if (addr >= start && addr < end)
+ return true;
+ }
+ return false;
+ }
+};
+
+static inline std::ostream &
+operator << (std::ostream &os, const MemoryImage::Segment &seg)
+{
+ ccprintf(os, "%s: %#x %d", seg.name, seg.base, seg.size);
+ return os;
+}
+
+
+#endif // __BASE_LOADER_MEMORY_IMAGE_HH__
diff --git a/src/base/loader/object_file.cc b/src/base/loader/object_file.cc
index d63b2221b..afecd21e3 100644
--- a/src/base/loader/object_file.cc
+++ b/src/base/loader/object_file.cc
@@ -70,31 +70,6 @@ ObjectFile::~ObjectFile()
}
-bool
-ObjectFile::loadSegment(Segment *seg, const PortProxy &mem_proxy)
-{
- if (seg->size != 0) {
- Addr addr = (seg->base & loadMask) + loadOffset;
- if (seg->data) {
- mem_proxy.writeBlob(addr, seg->data, seg->size);
- } else {
- // no image: must be bss
- mem_proxy.memsetBlob(addr, 0, seg->size);
- }
- }
- return true;
-}
-
-
-bool
-ObjectFile::loadSegments(const PortProxy &proxy)
-{
- for (auto &seg: segments)
- if (!loadSegment(seg.get(), proxy))
- return false;
- return true;
-}
-
namespace
{
diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh
index e5053ad82..669afeb11 100644
--- a/src/base/loader/object_file.hh
+++ b/src/base/loader/object_file.hh
@@ -37,6 +37,7 @@
#include <string>
#include <vector>
+#include "base/loader/memory_image.hh"
#include "base/logging.hh"
#include "base/types.hh"
@@ -74,14 +75,10 @@ class ObjectFile
FreeBSD
};
- static const Addr maxAddr = std::numeric_limits<Addr>::max();
-
protected:
const std::string filename;
uint8_t *fileData;
size_t len;
- Addr loadOffset=0;
- Addr loadMask=maxAddr;
Arch arch;
OpSys opSys;
@@ -92,16 +89,16 @@ class ObjectFile
public:
virtual ~ObjectFile();
- virtual bool loadSegments(const PortProxy &mem_proxy);
+ virtual MemoryImage buildImage() const = 0;
virtual bool loadAllSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset=0, Addr mask=maxAddr) = 0;
+ Addr offset=0, Addr mask=MaxAddr) = 0;
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset=0, Addr mask=maxAddr) = 0;
+ Addr offset=0, Addr mask=MaxAddr) = 0;
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr base=0,
- Addr offset=0, Addr mask=maxAddr) = 0;
+ Addr offset=0, Addr mask=MaxAddr) = 0;
virtual bool loadWeakSymbols(SymbolTable *symtab, Addr base=0,
- Addr offset=0, Addr mask=maxAddr)
+ Addr offset=0, Addr mask=MaxAddr)
{ return false; }
virtual ObjectFile *getInterpreter() const { return nullptr; }
@@ -117,77 +114,12 @@ class ObjectFile
Arch getArch() const { return arch; }
OpSys getOpSys() const { return opSys; }
- struct Segment
- {
- std::string name;
- Addr base;
- uint8_t *data;
- size_t size;
- };
-
protected:
Addr entry;
- std::vector<std::unique_ptr<Segment>> segments;
-
- void
- addSegment(std::string name, Addr base, uint8_t *data, size_t size)
- {
- Segment *seg = new Segment;
- seg->name = name;
- seg->base = base;
- seg->data = data;
- seg->size = size;
- segments.emplace_back(seg);
- }
-
- bool loadSegment(Segment *seg, const PortProxy &mem_proxy);
-
public:
Addr entryPoint() const { return entry; }
- Addr
- maxSegmentAddr() const
- {
- Addr max = 0;
- for (auto &seg: segments) {
- Addr end = seg->base + seg->size;
- if (end > max)
- max = end;
- }
- return max;
- }
-
- Addr
- minSegmentAddr() const
- {
- Addr min = maxAddr;
- for (auto &seg: segments)
- if (seg->base < min)
- min = seg->base;
- return min;
- }
-
- bool
- contains(Addr addr) const
- {
- for (auto &seg: segments) {
- Addr start = seg->base;
- Addr end = seg->base + seg->size;
- if (addr >= start && addr < end)
- return true;
- }
- return false;
- }
-
- /* This function allows you to override the base address where
- * a binary is going to be loaded or set it if the binary is just a
- * blob that doesn't include an object header.
- * @param a address to load the binary/text section at
- */
- void setLoadOffset(Addr val) { loadOffset = val; }
- void setLoadMask(Addr val) { loadMask = val; }
-
/**
* Each instance of a Loader subclass will have a chance to try to load
* an object file when tryLoaders is called. If they can't because they
@@ -221,13 +153,6 @@ class ObjectFile
static Process *tryLoaders(ProcessParams *params, ObjectFile *obj_file);
};
-static inline std::ostream &
-operator << (std::ostream &os, const ObjectFile::Segment &seg)
-{
- ccprintf(os, "%s: %#x %d", seg.name, seg.base, seg.size);
- return os;
-}
-
ObjectFile *createObjectFile(const std::string &fname, bool raw = false);
diff --git a/src/base/loader/raw_object.cc b/src/base/loader/raw_object.cc
index b0ece3ba2..35ed485c4 100644
--- a/src/base/loader/raw_object.cc
+++ b/src/base/loader/raw_object.cc
@@ -43,10 +43,14 @@ RawObject::tryFile(const std::string &fname, size_t len, uint8_t *data)
RawObject::RawObject(const std::string &_filename, size_t _len,
uint8_t *_data, Arch _arch, OpSys _opSys)
- : ObjectFile(_filename, _len, _data, _arch, _opSys),
- data(new Segment{ "data", 0, fileData, len })
+ : ObjectFile(_filename, _len, _data, _arch, _opSys)
{
- segments.emplace_back(data);
+}
+
+MemoryImage
+RawObject::buildImage() const
+{
+ return {{ "data", 0, fileData, len }};
}
bool
diff --git a/src/base/loader/raw_object.hh b/src/base/loader/raw_object.hh
index 9eb929107..6dc54c7aa 100644
--- a/src/base/loader/raw_object.hh
+++ b/src/base/loader/raw_object.hh
@@ -39,18 +39,17 @@ class RawObject: public ObjectFile
RawObject(const std::string &_filename, size_t _len,
uint8_t *_data, Arch _arch, OpSys _opSys);
- Segment *data;
-
public:
virtual ~RawObject() {}
- virtual bool loadAllSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addr_mask = maxAddr);
- virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0,
- Addr addr_mask = maxAddr);
- virtual bool loadLocalSymbols(SymbolTable *symtab, Addr base = 0,
- Addr offset = 0, Addr addr_mask = maxAddr);
+ MemoryImage buildImage() const override;
+
+ bool loadAllSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
+ bool loadLocalSymbols(SymbolTable *symtab, Addr base=0,
+ Addr offset=0, Addr addr_mask=MaxAddr) override;
static ObjectFile *tryFile(const std::string &fname, size_t len,
uint8_t *data);