blob: fda37417f0f547de77a5f273b060444841e62649 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "byte_block_file.h"
#include <cinttypes>
#include <unistd.h>
#include "lib/fxl/logging.h"
#include "lib/fxl/strings/string_printf.h"
#include "util.h"
namespace debugserver {
namespace util {
FileByteBlock::FileByteBlock(int fd)
: fd_(fd) {
FXL_DCHECK(fd >= 0);
}
FileByteBlock::~FileByteBlock() {
close(fd_);
}
bool FileByteBlock::Read(uintptr_t address, void* out_buffer,
size_t length) const {
FXL_DCHECK(out_buffer);
off_t where = lseek(fd_, address, SEEK_SET);
if (where != static_cast<off_t>(address)) {
FXL_LOG(ERROR) << fxl::StringPrintf("lseek to 0x%" PRIxPTR, address)
<< ", " << util::ErrnoString(errno);
return false;
}
ssize_t bytes_read = read(fd_, out_buffer, length);
if (bytes_read < 0) {
FXL_LOG(ERROR) <<
fxl::StringPrintf("Failed to read memory at addr: 0x%" PRIxPTR, address)
<< ", " << util::ErrnoString(errno);
return false;
}
if (length != static_cast<size_t>(bytes_read)) {
FXL_LOG(ERROR) << fxl::StringPrintf("Short read, got %zu bytes, expected %zu",
bytes_read, length);
return false;
}
// TODO(dje): Dump the bytes read at sufficiently high logging level (>2).
return true;
}
bool FileByteBlock::Write(uintptr_t address, const void* buffer,
size_t length) const {
FXL_DCHECK(buffer);
if (length == 0) {
FXL_VLOG(2) << "No data to write";
return true;
}
off_t where = lseek(fd_, address, SEEK_SET);
if (where != static_cast<off_t>(address)) {
FXL_LOG(ERROR) << fxl::StringPrintf("lseek to 0x%" PRIxPTR, address)
<< ", " << util::ErrnoString(errno);
return false;
}
ssize_t bytes_written = write(fd_, buffer, length);
if (bytes_written < 0) {
FXL_LOG(ERROR) <<
fxl::StringPrintf("Failed to read memory at addr: 0x%" PRIxPTR, address)
<< ", " << util::ErrnoString(errno);
return false;
}
if (length != static_cast<size_t>(bytes_written)) {
FXL_LOG(ERROR) << fxl::StringPrintf("Short write, wrote %zu bytes, expected %zu",
bytes_written, length);
return false;
}
// TODO(dje): Dump the bytes written at sufficiently high logging level (>2).
return true;
}
} // namespace util
} // namespace debugserver