* Copyright (c) 2016-2023 Google, Inc. All rights reserved.
* **********************************************************/
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Google, Inc. nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
* application processes and presents them via an iterator interface
* to the cache simulator.
*/
#ifndef _FILE_READER_H_
#define _FILE_READER_H_ 1
#include <inttypes.h>
#include <stdint.h>
#include <string.h>
#include <fstream>
#include <queue>
#include <string>
#include <vector>
#include "directory_iterator.h"
#include "memref.h"
#include "reader.h"
#include "trace_entry.h"
#include "utils.h"
namespace dynamorio {
namespace drmemtrace {
#ifndef ZHEX64_FORMAT_STRING
* external code.
*/
# ifdef WINDOWS
# define ZHEX64_FORMAT_STRING "%016I64x"
# else
# define ZHEX64_FORMAT_STRING "%" PRIx64
# endif
#endif
* We templatize on the file type itself for specializing for compression and
* other different types. An alternative would be to require a std::istream
* interface and add gzip_istream_t (paralleling gzip_ostream_t used for
* raw2trace).
*/
template <typename T> class file_reader_t : public reader_t {
public:
file_reader_t();
file_reader_t(const std::string &path, int verbosity = 0)
: reader_t(verbosity, "[file_reader]")
, input_path_(path)
{
online_ = false;
}
virtual ~file_reader_t();
bool
init() override
{
at_eof_ = false;
if (!open_input_file())
return false;
++*this;
return true;
}
std::string
get_stream_name() const override
{
size_t ind = input_path_.find_last_of(DIRSEP);
if (ind == std::string::npos)
return input_path_;
return input_path_.substr(ind + 1);
}
protected:
trace_entry_t *
read_next_entry() override;
virtual bool
open_single_file(const std::string &path);
virtual bool
open_input_file()
{
if (!open_single_file(input_path_)) {
ERRMSG("Failed to open %s\n", input_path_.c_str());
return false;
}
trace_entry_t *entry;
trace_entry_t header = {}, pid = {}, tid = {};
entry = read_next_entry();
if (entry == nullptr || entry->type != TRACE_TYPE_HEADER) {
ERRMSG("Invalid header\n");
return false;
}
header = *entry;
if (entry->addr > TRACE_ENTRY_VERSION) {
ERRMSG("Cannot handle version #%zu (expect version <= #%u)\n", entry->addr,
TRACE_ENTRY_VERSION);
return false;
}
std::queue<trace_entry_t> marker_queue;
while ((entry = read_next_entry()) != nullptr) {
if (entry->type == TRACE_TYPE_PID) {
pid = *entry;
break;
} else if (entry->type == TRACE_TYPE_THREAD)
tid = *entry;
else if (entry->type == TRACE_TYPE_MARKER)
marker_queue.push(*entry);
else {
ERRMSG("Unexpected trace sequence\n");
return false;
}
}
VPRINT(this, 2, "Read header: ver=%zu, pid=%zu, tid=%zu\n", header.addr, pid.addr,
tid.addr);
queue_.push(tid);
queue_.push(pid);
while (!marker_queue.empty()) {
queue_.push(marker_queue.front());
marker_queue.pop();
}
return true;
}
reader_t &
skip_instructions(uint64_t instruction_count) override
{
return reader_t::skip_instructions(instruction_count);
}
T input_file_;
private:
std::string input_path_;
};
}
}
#endif