+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))
+ if hpp_code is not None:
+ cpp_code(symbol_len_declaration + ' = {};'.format(len(data)))
+ cpp_code(symbol_declaration + ' = {')
+ cpp_code.indent()
+ step = 16
+ for i in six.moves.range(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):
+ with open(str(source[0]), 'rb') as f:
+ data = f.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)
+
+def GdbXml(xml_id, symbol):
+ Blob(joinpath(gdb_xml_dir, xml_id), symbol)
+