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:
Dam Sunwoo 2012-01-31 07:46:04 -08:00
parent af6aaf2581
commit 0ed3c84c7b
9 changed files with 117 additions and 10 deletions

View file

@ -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);

View file

@ -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 },

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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, "" },

View file

@ -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);

View file

@ -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)

View file

@ -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