system.redirect_paths = _redirect_paths(options)
+ # Setting the interpreter path. This is used to load the
+ # guest dynamic linker itself from the elf file.
+ interp = getattr(options, 'interp_dir', None)
+ if interp:
+ from m5.core import setInterpDir
+ setInterpDir(interp)
+
+ print("Setting the interpreter path to:", interp,
+ "\nFor dynamically linked applications you might still "
+ "need to setup the --redirects so that libraries are "
+ "found\n")
+
def register_node(cpu_list, mem, node_number):
nodebasedir = joinpath(m5.options.outdir, 'fs', 'sys', 'devices',
'system', 'node')
"for information or functionality. Instead of " \
"finding files on the __HOST__ filesystem, the " \
"process will find the user's replacment files.")
+ parser.add_option("--interp-dir", action="store", type="string",
+ default=None,
+ help="The interp-dir option is used for "
+ "setting the interpreter's path. This will "
+ "allow to load the guest dynamic linker/loader "
+ "itself from the elf binary. The option points to "
+ "the parent folder of the guest /lib in the "
+ "host fs")
+
parser.add_option("--redirects", action="append", type="string",
default=[],
help="A collection of one or more redirect paths "
{
ElfObjectFormat elfObjectFormat;
+std::string interpDir;
} // anonymous namespace
+void
+setInterpDir(const std::string &dirname)
+{
+ fatal_if(!interpDir.empty(),
+ "Error: setInterpDir has already been called once\n");
+ interpDir = dirname;
+}
+
ElfObject::ElfObject(ImageFileDataPtr ifd) : ObjectFile(ifd)
{
// get a pointer to elf structure
handleLoadableSegment(phdr, i);
if (phdr.p_type == PT_INTERP) {
// Make sure the interpreter is an valid ELF file.
- char *interp_path = (char *)imageData->data() + phdr.p_offset;
+ auto interp_path = getInterpPath(phdr);
ObjectFile *obj = createObjectFile(interp_path);
interpreter = dynamic_cast<ElfObject *>(obj);
assert(interpreter != nullptr);
// We will actually read the sections when we need to load them
}
+std::string
+ElfObject::getInterpPath(const GElf_Phdr &phdr) const
+{
+ // This is the interpreter path as specified in the elf file
+ const std::string elf_path = (char *)imageData->data() + phdr.p_offset;
+ if (!interpDir.empty())
+ return interpDir + elf_path;
+ else
+ return elf_path;
+}
+
void
ElfObject::determineArch()
{
ObjectFile *getInterpreter() const override { return interpreter; }
+ std::string getInterpPath(const GElf_Phdr &phdr) const;
+
Addr bias() const override { return ldBias; }
bool relocatable() const override { return relocate; }
Addr mapSize() const override { return ldMax - ldMin; }
uint16_t programHeaderCount() {return _programHeaderCount;}
};
+/**
+ * This is the interface for setting up a base path for the
+ * elf interpreter. This is needed when loading a
+ * cross-compiled (guest ISA != host ISA) dynamically
+ * linked application.
+ * @param dirname base path for the interpreter
+ */
+void setInterpDir(const std::string &dirname);
+
#endif // __BASE_LOADER_ELF_OBJECT_HH__
+# Copyright (c) 2019 ARM Limited
+# All rights reserved.
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder. You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
# Copyright (c) 2008 The Hewlett-Packard Development Company
# All rights reserved.
#
from __future__ import absolute_import
from _m5.core import setOutputDir
+from _m5.loader import setInterpDir
#include "base/addr_range.hh"
#include "base/inet.hh"
+#include "base/loader/elf_object.hh"
#include "base/logging.hh"
#include "base/random.hh"
#include "base/socket.hh"
;
}
+static void
+init_loader(py::module &m_native)
+{
+ py::module m = m_native.def_submodule("loader");
+
+ m.def("setInterpDir", &setInterpDir);
+}
+
void
pybind_init_core(py::module &m_native)
{
init_serialize(m_native);
init_range(m_native);
init_net(m_native);
+ init_loader(m_native);
}