summaryrefslogtreecommitdiff
path: root/src/base/loader
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2019-10-01 21:15:06 -0700
committerGabe Black <gabeblack@google.com>2019-10-12 04:10:59 +0000
commit6ee86bf497ea87a585fe8e4651760e71244fa2fb (patch)
treeb2038b4d87285261ce57d29e82ad9e67baf99676 /src/base/loader
parent211869ea950f3cc3116655f06b1d46d3fa39fb3a (diff)
downloadgem5-6ee86bf497ea87a585fe8e4651760e71244fa2fb.tar.xz
arch,base: Separate the idea of a memory image and object file.
A memory image can be described by an object file, but an object file is more than a memory image. Also, it makes sense to manipulate a memory image to, for instance, change how it's loaded into memory. That takes on larger implications (relocations, the entry point, symbols, etc.) when talking about the whole object file, and also modifies aspects which may not need to change. For instance if an image needs to be loaded into memory at addresses different from what's in the object file, but other things like symbols need to stay unmodified. Change-Id: Ia360405ffb2c1c48e0cc201ac0a0764357996a54 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21466 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Brandon Potter <Brandon.Potter@amd.com> Maintainer: Gabe Black <gabeblack@google.com>
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);