diff options
author | Ciro Santilli <ciro.santilli@arm.com> | 2018-11-19 15:25:43 +0000 |
---|---|---|
committer | Ciro Santilli <ciro.santilli@arm.com> | 2019-01-22 11:35:12 +0000 |
commit | f2bda876f73af4ecc38406f3562a3d16fd28a5a9 (patch) | |
tree | 51cf43a27af5b5143269447d1f895476fbecdf06 | |
parent | af5a23a39f544568e79a93250548bef83f9c2fff (diff) | |
download | gem5-f2bda876f73af4ecc38406f3562a3d16fd28a5a9.tar.xz |
scons: allow embedding arbitrary blobs into the gem5 executable
The initial motivation for this is to embed the GDB XML target
description files into the executable.
Change-Id: I721e8dd37119d8e6eb376d7e9050b1094282bacc
Reviewed-on: https://gem5-review.googlesource.com/c/15136
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
-rwxr-xr-x | src/SConscript | 92 |
1 files changed, 84 insertions, 8 deletions
diff --git a/src/SConscript b/src/SConscript index dc284b104..5f8a2d2d3 100755 --- a/src/SConscript +++ b/src/SConscript @@ -1,5 +1,16 @@ # -*- mode:python -*- +# Copyright (c) 2018 ARM Limited +# +# 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) 2004-2005 The Regents of The University of Michigan # All rights reserved. # @@ -212,6 +223,76 @@ class SourceFile(object): def __eq__(self, other): return self.filename == other.filename def __ne__(self, other): return self.filename != other.filename +def blobToCpp(data, symbol, cpp_code, hpp_code=None, namespace=None): + ''' + Convert bytes data into C++ .cpp and .hh uint8_t byte array + code containing that binary data. + + :param data: binary data to be converted to C++ + :param symbol: name of the symbol + :param cpp_code: append the generated cpp_code to this object + :param hpp_code: append the generated hpp_code to this object + If None, ignore it. Otherwise, also include it + in the .cpp file. + :param namespace: namespace to put the symbol into. If None, + don't put the symbols into any namespace. + ''' + symbol_len_declaration = 'const std::size_t {}_len'.format(symbol) + symbol_declaration = 'const std::uint8_t {}[]'.format(symbol) + if hpp_code is not None: + cpp_code('''\ +#include "blobs/{}.hh" +'''.format(symbol)) + hpp_code('''\ +#include <cstddef> +#include <cstdint> +''') + if namespace is not None: + hpp_code('namespace {} {{'.format(namespace)) + hpp_code('extern ' + symbol_len_declaration + ';') + hpp_code('extern ' + symbol_declaration + ';') + if namespace is not None: + hpp_code('}') + if namespace is not None: + cpp_code('namespace {} {{'.format(namespace)) + cpp_code(symbol_len_declaration + ' = {};'.format(len(data))) + cpp_code(symbol_declaration + ' = {') + cpp_code.indent() + step = 16 + for i in xrange(0, len(data), step): + x = array.array('B', data[i:i+step]) + cpp_code(''.join('%d,' % d for d in x)) + cpp_code.dedent() + cpp_code('};') + if namespace is not None: + cpp_code('}') + +def Blob(blob_path, symbol): + ''' + Embed an arbitrary blob into the gem5 executable, + and make it accessible to C++ as a byte array. + ''' + blob_path = os.path.abspath(blob_path) + blob_out_dir = os.path.join(env['BUILDDIR'], 'blobs') + path_noext = joinpath(blob_out_dir, symbol) + cpp_path = path_noext + '.cc' + hpp_path = path_noext + '.hh' + def embedBlob(target, source, env): + data = file(str(source[0]), 'r').read() + cpp_code = code_formatter() + hpp_code = code_formatter() + blobToCpp(data, symbol, cpp_code, hpp_code, namespace='Blobs') + cpp_path = str(target[0]) + hpp_path = str(target[1]) + cpp_dir = os.path.split(cpp_path)[0] + if not os.path.exists(cpp_dir): + os.makedirs(cpp_dir) + cpp_code.write(cpp_path) + hpp_code.write(hpp_path) + env.Command([cpp_path, hpp_path], blob_path, + MakeAction(embedBlob, Transform("EMBED BLOB"))) + Source(cpp_path) + class Source(SourceFile): ungrouped_tag = 'No link group' source_groups = set() @@ -440,6 +521,7 @@ class Gem5(Executable): # Children should have access +Export('Blob') Export('Source') Export('PySource') Export('SimObject') @@ -1069,16 +1151,10 @@ def embedPyFile(target, source, env): namespace { -const uint8_t data_${sym}[] = { ''') - code.indent() - step = 16 - for i in xrange(0, len(data), step): - x = array.array('B', data[i:i+step]) - code(''.join('%d,' % d for d in x)) - code.dedent() + blobToCpp(data, 'data_' + sym, code) + code('''\ - code('''}; EmbeddedPython embedded_${sym}( ${{c_str(pysource.arcname)}}, |