util: implements "writefile" gem5 op to export file from guest to host filesystem
Usage: m5 writefile <filename> File will be created in the gem5 output folder with the identical filename. Implementation is largely based on the existing "readfile" functionality. Currently does not support exporting of folders.
This commit is contained in:
parent
af6aaf2581
commit
0ed3c84c7b
9 changed files with 117 additions and 10 deletions
|
@ -64,6 +64,7 @@ def format M5ops() {{
|
|||
case 0x42: return new Dumpresetstats(machInst);
|
||||
case 0x43: return new M5checkpoint(machInst);
|
||||
#if FULL_SYSTEM
|
||||
case 0x4F: return new M5writefile(machInst);
|
||||
case 0x50: return new M5readfile(machInst);
|
||||
#endif
|
||||
case 0x51: return new M5break(machInst);
|
||||
|
|
|
@ -265,6 +265,24 @@ let {{
|
|||
decoder_output += BasicConstructor.subst(m5readfileIop)
|
||||
exec_output += PredOpExecute.subst(m5readfileIop)
|
||||
|
||||
m5writefileCode = '''
|
||||
#if FULL_SYSTEM
|
||||
int n = 4;
|
||||
uint64_t offset = getArgument(xc->tcBase(), n, sizeof(uint64_t), false);
|
||||
n = 6;
|
||||
Addr filenameAddr = getArgument(xc->tcBase(), n, sizeof(Addr), false);
|
||||
R0 = PseudoInst::writefile(xc->tcBase(), R0, join32to64(R3,R2), offset,
|
||||
filenameAddr);
|
||||
#endif
|
||||
'''
|
||||
m5writefileIop = InstObjParams("m5writefile", "M5writefile", "PredOp",
|
||||
{ "code": m5writefileCode,
|
||||
"predicate_test": predicateTest },
|
||||
["IsNonSpeculative"])
|
||||
header_output += BasicDeclare.subst(m5writefileIop)
|
||||
decoder_output += BasicConstructor.subst(m5writefileIop)
|
||||
exec_output += PredOpExecute.subst(m5writefileIop)
|
||||
|
||||
m5breakIop = InstObjParams("m5break", "M5break", "PredOp",
|
||||
{ "code": "PseudoInst::debugbreak(xc->tcBase());",
|
||||
"predicate_test": predicateTest },
|
||||
|
|
|
@ -73,6 +73,13 @@ class OutputDirectory
|
|||
*/
|
||||
std::ostream *checkForStdio(const std::string &name) const;
|
||||
|
||||
public:
|
||||
/** Constructor. */
|
||||
OutputDirectory();
|
||||
|
||||
/** Destructor. */
|
||||
~OutputDirectory();
|
||||
|
||||
/** Opens a file (optionally compressed).
|
||||
*
|
||||
* Will open a file as a compressed stream if filename ends in .gz.
|
||||
|
@ -84,13 +91,6 @@ class OutputDirectory
|
|||
std::ostream *openFile(const std::string &filename,
|
||||
std::ios_base::openmode mode = std::ios::trunc);
|
||||
|
||||
public:
|
||||
/** Constructor. */
|
||||
OutputDirectory();
|
||||
|
||||
/** Destructor. */
|
||||
~OutputDirectory();
|
||||
|
||||
/**
|
||||
* Sets name of this directory.
|
||||
* @param dir name of this directory
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2010 ARM Limited
|
||||
* Copyright (c) 2010-2011 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
|
@ -50,6 +50,7 @@
|
|||
|
||||
#include "arch/vtophys.hh"
|
||||
#include "base/debug.hh"
|
||||
#include "base/output.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "config/the_isa.hh"
|
||||
#include "cpu/base.hh"
|
||||
|
@ -358,6 +359,48 @@ readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
|
|||
return result;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
writefile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset,
|
||||
Addr filename_addr)
|
||||
{
|
||||
ostream *os;
|
||||
|
||||
// copy out target filename
|
||||
char fn[100];
|
||||
std::string filename;
|
||||
CopyStringOut(tc, fn, filename_addr, 100);
|
||||
filename = std::string(fn);
|
||||
|
||||
if (offset == 0) {
|
||||
// create a new file (truncate)
|
||||
os = simout.create(filename, true);
|
||||
} else {
|
||||
// do not truncate file if offset is non-zero
|
||||
// (ios::in flag is required as well to keep the existing data
|
||||
// intact, otherwise existing data will be zeroed out.)
|
||||
os = simout.openFile(simout.directory() + filename,
|
||||
ios::in | ios::out | ios::binary);
|
||||
}
|
||||
if (!os)
|
||||
panic("could not open file %s\n", filename);
|
||||
|
||||
// seek to offset
|
||||
os->seekp(offset);
|
||||
|
||||
// copy out data and write to file
|
||||
char *buf = new char[len];
|
||||
CopyOut(tc, buf, vaddr, len);
|
||||
os->write(buf, len);
|
||||
if (os->fail() || os->bad())
|
||||
panic("Error while doing writefile!\n");
|
||||
|
||||
simout.close(os);
|
||||
|
||||
delete [] buf;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
|
|
|
@ -55,6 +55,8 @@ void quiesceCycles(ThreadContext *tc, uint64_t cycles);
|
|||
uint64_t quiesceTime(ThreadContext *tc);
|
||||
uint64_t readfile(ThreadContext *tc, Addr vaddr, uint64_t len,
|
||||
uint64_t offset);
|
||||
uint64_t writefile(ThreadContext *tc, Addr vaddr, uint64_t len,
|
||||
uint64_t offset, Addr filenameAddr);
|
||||
void loadsymbol(ThreadContext *xc);
|
||||
void addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr);
|
||||
uint64_t initParam(ThreadContext *xc);
|
||||
|
|
43
util/m5/m5.c
43
util/m5/m5.c
|
@ -88,6 +88,33 @@ read_file(int dest_fid)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
write_file(const char *filename)
|
||||
{
|
||||
fprintf(stderr, "opening %s\n", filename);
|
||||
int src_fid = open(filename, O_RDONLY);
|
||||
|
||||
if (src_fid < 0) {
|
||||
fprintf(stderr, "error opening %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
char buf[256*1024];
|
||||
int offset = 0;
|
||||
int len;
|
||||
int bytes = 0;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
while ((len = read(src_fid, buf, sizeof(buf))) > 0) {
|
||||
bytes += m5_writefile(buf, len, offset, filename);
|
||||
offset += len;
|
||||
}
|
||||
fprintf(stderr, "written %d bytes\n", bytes);
|
||||
|
||||
close(src_fid);
|
||||
}
|
||||
|
||||
void
|
||||
do_exit(int argc, char *argv[])
|
||||
{
|
||||
|
@ -130,6 +157,17 @@ do_read_file(int argc, char *argv[])
|
|||
read_file(STDOUT_FILENO);
|
||||
}
|
||||
|
||||
void
|
||||
do_write_file(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 1)
|
||||
usage();
|
||||
|
||||
const char *filename = argv[0];
|
||||
|
||||
write_file(filename);
|
||||
}
|
||||
|
||||
void
|
||||
do_exec_file(int argc, char *argv[])
|
||||
{
|
||||
|
@ -227,8 +265,9 @@ struct MainFunc mainfuncs[] = {
|
|||
{ "resetstats", do_reset_stats, "[delay [period]]" },
|
||||
{ "dumpstats", do_dump_stats, "[delay [period]]" },
|
||||
{ "dumpresetstats", do_dump_reset_stats, "[delay [period]]" },
|
||||
{ "readfile", do_read_file, "[filename]" },
|
||||
{ "execfile", do_exec_file, "<filename>" },
|
||||
{ "readfile", do_read_file, "" },
|
||||
{ "writefile", do_write_file, "<filename>" },
|
||||
{ "execfile", do_exec_file, "" },
|
||||
{ "checkpoint", do_checkpoint, "[delay [period]]" },
|
||||
{ "loadsymbol", do_load_symbol, "<address> <symbol>" },
|
||||
{ "initparam", do_initparam, "" },
|
||||
|
|
|
@ -49,6 +49,7 @@ void m5_reset_stats(uint64_t ns_delay, uint64_t ns_period);
|
|||
void m5_dump_stats(uint64_t ns_delay, uint64_t ns_period);
|
||||
void m5_dumpreset_stats(uint64_t ns_delay, uint64_t ns_period);
|
||||
uint64_t m5_readfile(void *buffer, uint64_t len, uint64_t offset);
|
||||
uint64_t m5_writefile(void *buffer, uint64_t len, uint64_t offset, const char *filename);
|
||||
void m5_debugbreak(void);
|
||||
void m5_switchcpu(void);
|
||||
void m5_addsymbol(uint64_t addr, char *symbol);
|
||||
|
|
|
@ -80,6 +80,7 @@ func:
|
|||
#define DUMPRST_STATS INST(m5_op, 0, 0, dumprststats_func)
|
||||
#define CHECKPOINT INST(m5_op, 0, 0, ckpt_func)
|
||||
#define READFILE INST(m5_op, 0, 0, readfile_func)
|
||||
#define WRITEFILE INST(m5_op, 0, 0, writefile_func)
|
||||
#define DEBUGBREAK INST(m5_op, 0, 0, debugbreak_func)
|
||||
#define SWITCHCPU INST(m5_op, 0, 0, switchcpu_func)
|
||||
#define ADDSYMBOL INST(m5_op, 0, 0, addsymbol_func)
|
||||
|
@ -121,6 +122,7 @@ SIMPLE_OP(m5_dump_stats, DUMP_STATS)
|
|||
SIMPLE_OP(m5_dumpreset_stats, DUMPRST_STATS)
|
||||
SIMPLE_OP(m5_checkpoint, CHECKPOINT)
|
||||
SIMPLE_OP(m5_readfile, READFILE)
|
||||
SIMPLE_OP(m5_writefile, WRITEFILE)
|
||||
SIMPLE_OP(m5_debugbreak, DEBUGBREAK)
|
||||
SIMPLE_OP(m5_switchcpu, SWITCHCPU)
|
||||
SIMPLE_OP(m5_addsymbol, ADDSYMBOL)
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#define dumpstats_func 0x41
|
||||
#define dumprststats_func 0x42
|
||||
#define ckpt_func 0x43
|
||||
#define writefile_func 0x4F
|
||||
#define readfile_func 0x50
|
||||
#define debugbreak_func 0x51
|
||||
#define switchcpu_func 0x52
|
||||
|
|
Loading…
Reference in a new issue