Use generic VM types in snapshot/elf

A step towards making these files usable by non-Linux systems.

Bug: crashpad:196
Change-Id: I2497fd7e3bcb5390ae1e6ae22902ab6f56b59dff
Reviewed-on: https://chromium-review.googlesource.com/685405
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
Commit-Queue: Dave Bort <dbort@google.com>
This commit is contained in:
Dave Bort 2017-09-12 16:49:35 -07:00 committed by Commit Bot
parent cea0671011
commit 6c9bd10a24
7 changed files with 72 additions and 73 deletions

View File

@ -24,8 +24,8 @@ namespace {
template <typename DynType>
bool Read(const ProcessMemoryRange& memory,
LinuxVMAddress address,
LinuxVMSize size,
VMAddress address,
VMSize size,
std::map<uint64_t, uint64_t>* values) {
std::map<uint64_t, uint64_t> local_values;
@ -66,8 +66,8 @@ ElfDynamicArrayReader::ElfDynamicArrayReader() : values_() {}
ElfDynamicArrayReader::~ElfDynamicArrayReader() {}
bool ElfDynamicArrayReader::Initialize(const ProcessMemoryRange& memory,
LinuxVMAddress address,
LinuxVMSize size) {
VMAddress address,
VMSize size) {
return memory.Is64Bit() ? Read<Elf64_Dyn>(memory, address, size, &values_)
: Read<Elf32_Dyn>(memory, address, size, &values_);
}

View File

@ -21,8 +21,8 @@
#include "base/logging.h"
#include "base/macros.h"
#include "util/linux/address_types.h"
#include "util/linux/process_memory_range.h"
#include "util/misc/address_types.h"
#include "util/misc/reinterpret_bytes.h"
namespace crashpad {
@ -43,8 +43,8 @@ class ElfDynamicArrayReader {
//! the ELF dynamic table is loaded.
//! \param[in] size The maximum number of bytes to read.
bool Initialize(const ProcessMemoryRange& memory,
LinuxVMAddress address,
LinuxVMSize size);
VMAddress address,
VMSize size);
//! \brief Retrieve a value from the array.
//!

View File

@ -21,6 +21,7 @@
#include "base/logging.h"
#include "build/build_config.h"
#include "util/numeric/checked_vm_address_range.h"
namespace crashpad {
@ -30,11 +31,10 @@ class ElfImageReader::ProgramHeaderTable {
virtual bool VerifyLoadSegments() const = 0;
virtual size_t Size() const = 0;
virtual bool GetDynamicSegment(LinuxVMAddress* address,
LinuxVMSize* size) const = 0;
virtual bool GetPreferredElfHeaderAddress(LinuxVMAddress* address) const = 0;
virtual bool GetPreferredLoadedMemoryRange(LinuxVMAddress* address,
LinuxVMSize* size) const = 0;
virtual bool GetDynamicSegment(VMAddress* address, VMSize* size) const = 0;
virtual bool GetPreferredElfHeaderAddress(VMAddress* address) const = 0;
virtual bool GetPreferredLoadedMemoryRange(VMAddress* address,
VMSize* size) const = 0;
protected:
ProgramHeaderTable() {}
@ -48,8 +48,8 @@ class ElfImageReader::ProgramHeaderTableSpecific
~ProgramHeaderTableSpecific<PhdrType>() {}
bool Initialize(const ProcessMemoryRange& memory,
LinuxVMAddress address,
LinuxVMSize num_segments) {
VMAddress address,
VMSize num_segments) {
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
table_.resize(num_segments);
if (!memory.Read(address, sizeof(PhdrType) * num_segments, table_.data())) {
@ -66,11 +66,11 @@ class ElfImageReader::ProgramHeaderTableSpecific
bool VerifyLoadSegments() const override {
constexpr bool is_64_bit = std::is_same<PhdrType, Elf64_Phdr>::value;
LinuxVMAddress last_vaddr;
VMAddress last_vaddr;
bool load_found = false;
for (const auto& header : table_) {
if (header.p_type == PT_LOAD) {
CheckedLinuxAddressRange load_range(
CheckedVMAddressRange load_range(
is_64_bit, header.p_vaddr, header.p_memsz);
if (!load_range.IsValid()) {
@ -91,7 +91,7 @@ class ElfImageReader::ProgramHeaderTableSpecific
size_t Size() const override { return sizeof(PhdrType) * table_.size(); }
bool GetPreferredElfHeaderAddress(LinuxVMAddress* address) const override {
bool GetPreferredElfHeaderAddress(VMAddress* address) const override {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
for (const auto& header : table_) {
if (header.p_type == PT_LOAD && header.p_offset == 0) {
@ -103,12 +103,12 @@ class ElfImageReader::ProgramHeaderTableSpecific
return false;
}
bool GetPreferredLoadedMemoryRange(LinuxVMAddress* base,
LinuxVMSize* size) const override {
bool GetPreferredLoadedMemoryRange(VMAddress* base,
VMSize* size) const override {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
LinuxVMAddress preferred_base = 0;
LinuxVMAddress preferred_end = 0;
VMAddress preferred_base = 0;
VMAddress preferred_end = 0;
bool load_found = false;
for (const auto& header : table_) {
if (header.p_type == PT_LOAD) {
@ -128,8 +128,7 @@ class ElfImageReader::ProgramHeaderTableSpecific
return false;
}
bool GetDynamicSegment(LinuxVMAddress* address,
LinuxVMSize* size) const override {
bool GetDynamicSegment(VMAddress* address, VMSize* size) const override {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
const PhdrType* phdr;
if (!GetProgramHeader(PT_DYNAMIC, &phdr)) {
@ -173,7 +172,7 @@ ElfImageReader::ElfImageReader()
ElfImageReader::~ElfImageReader() {}
bool ElfImageReader::Initialize(const ProcessMemoryRange& memory,
LinuxVMAddress address) {
VMAddress address) {
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
ehdr_address_ = address;
if (!memory_.Initialize(memory)) {
@ -244,15 +243,15 @@ bool ElfImageReader::Initialize(const ProcessMemoryRange& memory,
return false;
}
LinuxVMAddress preferred_ehdr_address;
VMAddress preferred_ehdr_address;
if (!program_headers_.get()->GetPreferredElfHeaderAddress(
&preferred_ehdr_address)) {
return false;
}
load_bias_ = ehdr_address_ - preferred_ehdr_address;
LinuxVMAddress base_address;
LinuxVMSize loaded_size;
VMAddress base_address;
VMSize loaded_size;
if (!program_headers_.get()->GetPreferredLoadedMemoryRange(&base_address,
&loaded_size)) {
return false;
@ -263,8 +262,8 @@ bool ElfImageReader::Initialize(const ProcessMemoryRange& memory,
return false;
}
LinuxVMSize ehdr_size;
LinuxVMAddress phdr_address;
VMSize ehdr_size;
VMAddress phdr_address;
if (memory_.Is64Bit()) {
ehdr_size = sizeof(header_64_);
phdr_address = ehdr_address_ + header_64_.e_phoff;
@ -273,13 +272,13 @@ bool ElfImageReader::Initialize(const ProcessMemoryRange& memory,
phdr_address = ehdr_address_ + header_32_.e_phoff;
}
CheckedLinuxAddressRange range(memory_.Is64Bit(), base_address, loaded_size);
if (!range.ContainsRange(CheckedLinuxAddressRange(
memory_.Is64Bit(), ehdr_address_, ehdr_size))) {
CheckedVMAddressRange range(memory_.Is64Bit(), base_address, loaded_size);
if (!range.ContainsRange(
CheckedVMAddressRange(memory_.Is64Bit(), ehdr_address_, ehdr_size))) {
LOG(ERROR) << "ehdr out of range";
return false;
}
if (!range.ContainsRange(CheckedLinuxAddressRange(
if (!range.ContainsRange(CheckedVMAddressRange(
memory.Is64Bit(), phdr_address, program_headers_->Size()))) {
LOG(ERROR) << "phdrs out of range";
return false;
@ -295,8 +294,8 @@ uint16_t ElfImageReader::FileType() const {
}
bool ElfImageReader::GetDynamicSymbol(const std::string& name,
LinuxVMAddress* address,
LinuxVMSize* size) {
VMAddress* address,
VMSize* size) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
if (!InitializeDynamicSymbolTable()) {
return false;
@ -343,15 +342,15 @@ bool ElfImageReader::GetDynamicSymbol(const std::string& name,
return true;
}
bool ElfImageReader::ReadDynamicStringTableAtOffset(LinuxVMSize offset,
bool ElfImageReader::ReadDynamicStringTableAtOffset(VMSize offset,
std::string* string) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
if (!InitializeDynamicArray()) {
return false;
}
LinuxVMAddress string_table_address;
LinuxVMSize string_table_size;
VMAddress string_table_address;
VMSize string_table_size;
if (!GetAddressFromDynamicArray(DT_STRTAB, &string_table_address) ||
!dynamic_array_->GetValue(DT_STRSZ, &string_table_size)) {
LOG(ERROR) << "missing string table info";
@ -370,7 +369,7 @@ bool ElfImageReader::ReadDynamicStringTableAtOffset(LinuxVMSize offset,
return true;
}
bool ElfImageReader::GetDebugAddress(LinuxVMAddress* debug) {
bool ElfImageReader::GetDebugAddress(VMAddress* debug) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
if (!InitializeDynamicArray()) {
return false;
@ -410,8 +409,8 @@ bool ElfImageReader::InitializeDynamicArray() {
}
dynamic_array_initialized_.set_invalid();
LinuxVMAddress dyn_segment_address;
LinuxVMSize dyn_segment_size;
VMAddress dyn_segment_address;
VMSize dyn_segment_size;
if (!program_headers_.get()->GetDynamicSegment(&dyn_segment_address,
&dyn_segment_size)) {
LOG(ERROR) << "no dynamic segment";
@ -441,7 +440,7 @@ bool ElfImageReader::InitializeDynamicSymbolTable() {
return false;
}
LinuxVMAddress symbol_table_address;
VMAddress symbol_table_address;
if (!GetAddressFromDynamicArray(DT_SYMTAB, &symbol_table_address)) {
LOG(ERROR) << "no symbol table";
return false;
@ -454,7 +453,7 @@ bool ElfImageReader::InitializeDynamicSymbolTable() {
}
bool ElfImageReader::GetAddressFromDynamicArray(uint64_t tag,
LinuxVMAddress* address) {
VMAddress* address) {
if (!dynamic_array_->GetValue(tag, address)) {
return false;
}

View File

@ -22,10 +22,10 @@
#include <string>
#include "base/macros.h"
#include "util/linux/address_types.h"
#include "snapshot/elf/elf_dynamic_array_reader.h"
#include "snapshot/elf/elf_symbol_table_reader.h"
#include "util/linux/process_memory_range.h"
#include "util/misc/address_types.h"
#include "util/misc/initialization_state.h"
#include "util/misc/initialization_state_dcheck.h"
@ -47,20 +47,20 @@ class ElfImageReader {
//! \param[in] memory A memory reader for the remote process.
//! \param[in] address The address in the remote process' address space where
//! the ELF image is loaded.
bool Initialize(const ProcessMemoryRange& memory, LinuxVMAddress address);
bool Initialize(const ProcessMemoryRange& memory, VMAddress address);
//! \brief Returns the base address of the image's memory range.
//!
//! This may differ from the address passed to Initialize() if the ELF header
//! is not loaded at the start of the first `PT_LOAD` segment.
LinuxVMAddress Address() const { return memory_.Base(); }
VMAddress Address() const { return memory_.Base(); }
//! \brief Returns the size of the range containing all loaded segments for
//! this image.
//!
//! The size may include memory that is unmapped or mapped to other objects if
//! this image's `PT_LOAD` segments are not contiguous.
LinuxVMSize Size() const { return memory_.Size(); }
VMSize Size() const { return memory_.Size(); }
//! \brief Returns the file type for the image.
//!
@ -70,7 +70,7 @@ class ElfImageReader {
//! \brief Returns the load bias for the image.
//!
//! The load bias is the actual load address minus the preferred load address.
LinuxVMOffset GetLoadBias() const { return load_bias_; }
VMOffset GetLoadBias() const { return load_bias_; }
//! \brief Reads information from the dynamic symbol table about the symbol
//! identified by \a name.
@ -81,8 +81,8 @@ class ElfImageReader {
//! \param[out] size The size of the symbol, if found.
//! \return `true` if the symbol was found.
bool GetDynamicSymbol(const std::string& name,
LinuxVMAddress* address,
LinuxVMSize* size);
VMAddress* address,
VMSize* size);
//! \brief Reads a `NUL`-terminated C string from this image's dynamic string
//! table.
@ -90,7 +90,7 @@ class ElfImageReader {
//! \param[in] offset the byte offset in the string table to start reading.
//! \param[out] string the string read.
//! \return `true` on success. Otherwise `false` with a message logged.
bool ReadDynamicStringTableAtOffset(LinuxVMSize offset, std::string* string);
bool ReadDynamicStringTableAtOffset(VMSize offset, std::string* string);
//! \brief Determine the debug address.
//!
@ -99,7 +99,7 @@ class ElfImageReader {
//!
//! \param[out] debug the debug address, if found.
//! \return `true` if the debug address was found.
bool GetDebugAddress(LinuxVMAddress* debug);
bool GetDebugAddress(VMAddress* debug);
private:
class ProgramHeaderTable;
@ -109,14 +109,14 @@ class ElfImageReader {
bool InitializeProgramHeaders();
bool InitializeDynamicArray();
bool InitializeDynamicSymbolTable();
bool GetAddressFromDynamicArray(uint64_t tag, LinuxVMAddress* address);
bool GetAddressFromDynamicArray(uint64_t tag, VMAddress* address);
union {
Elf32_Ehdr header_32_;
Elf64_Ehdr header_64_;
};
LinuxVMAddress ehdr_address_;
LinuxVMOffset load_bias_;
VMAddress ehdr_address_;
VMOffset load_bias_;
ProcessMemoryRange memory_;
std::unique_ptr<ProgramHeaderTable> program_headers_;
std::unique_ptr<ElfDynamicArrayReader> dynamic_array_;

View File

@ -22,9 +22,9 @@
#include "gtest/gtest.h"
#include "test/multiprocess.h"
#include "util/file/file_io.h"
#include "util/linux/address_types.h"
#include "util/linux/auxiliary_vector.h"
#include "util/linux/memory_map.h"
#include "util/misc/address_types.h"
#include "util/misc/from_pointer_cast.h"
extern "C" {
@ -36,11 +36,11 @@ namespace crashpad {
namespace test {
namespace {
void LocateExecutable(pid_t pid, bool is_64_bit, LinuxVMAddress* elf_address) {
void LocateExecutable(pid_t pid, bool is_64_bit, VMAddress* elf_address) {
AuxiliaryVector aux;
ASSERT_TRUE(aux.Initialize(pid, is_64_bit));
LinuxVMAddress phdrs;
VMAddress phdrs;
ASSERT_TRUE(aux.GetValue(AT_PHDR, &phdrs));
MemoryMap memory_map;
@ -54,10 +54,10 @@ void LocateExecutable(pid_t pid, bool is_64_bit, LinuxVMAddress* elf_address) {
}
void ExpectElfImageWithSymbol(pid_t pid,
LinuxVMAddress address,
VMAddress address,
bool is_64_bit,
std::string symbol_name,
LinuxVMAddress expected_symbol_address) {
VMAddress expected_symbol_address) {
ProcessMemory memory;
ASSERT_TRUE(memory.Initialize(pid));
ProcessMemoryRange range;
@ -66,8 +66,8 @@ void ExpectElfImageWithSymbol(pid_t pid,
ElfImageReader reader;
ASSERT_TRUE(reader.Initialize(range, address));
LinuxVMAddress symbol_address;
LinuxVMSize symbol_size;
VMAddress symbol_address;
VMSize symbol_size;
ASSERT_TRUE(
reader.GetDynamicSymbol(symbol_name, &symbol_address, &symbol_size));
EXPECT_EQ(symbol_address, expected_symbol_address);
@ -83,7 +83,7 @@ void ReadThisExecutableInTarget(pid_t pid) {
constexpr bool am_64_bit = false;
#endif // ARCH_CPU_64_BITS
LinuxVMAddress elf_address;
VMAddress elf_address;
LocateExecutable(pid, am_64_bit, &elf_address);
ExpectElfImageWithSymbol(
@ -91,7 +91,7 @@ void ReadThisExecutableInTarget(pid_t pid) {
elf_address,
am_64_bit,
"ElfImageReaderTestExportedSymbol",
FromPointerCast<LinuxVMAddress>(ElfImageReaderTestExportedSymbol));
FromPointerCast<VMAddress>(ElfImageReaderTestExportedSymbol));
}
// Assumes that libc is loaded at the same address in this process as in the
@ -106,13 +106,13 @@ void ReadLibcInTarget(pid_t pid) {
Dl_info info;
ASSERT_TRUE(dladdr(reinterpret_cast<void*>(getpid), &info)) << "dladdr:"
<< dlerror();
LinuxVMAddress elf_address = FromPointerCast<LinuxVMAddress>(info.dli_fbase);
VMAddress elf_address = FromPointerCast<VMAddress>(info.dli_fbase);
ExpectElfImageWithSymbol(pid,
elf_address,
am_64_bit,
"getpid",
FromPointerCast<LinuxVMAddress>(getpid));
FromPointerCast<VMAddress>(getpid));
}
class ReadExecutableChildTest : public Multiprocess {

View File

@ -51,7 +51,7 @@ uint8_t GetVisibility(const Elf64_Sym& sym) {
ElfSymbolTableReader::ElfSymbolTableReader(const ProcessMemoryRange* memory,
ElfImageReader* elf_reader,
LinuxVMAddress address)
VMAddress address)
: memory_(memory), elf_reader_(elf_reader), base_address_(address) {}
ElfSymbolTableReader::~ElfSymbolTableReader() {}
@ -65,7 +65,7 @@ bool ElfSymbolTableReader::GetSymbol(const std::string& name,
template <typename SymEnt>
bool ElfSymbolTableReader::ScanSymbolTable(const std::string& name,
SymbolInformation* info_out) {
LinuxVMAddress address = base_address_;
VMAddress address = base_address_;
SymEnt entry;
std::string string;
while (memory_->Read(address, sizeof(entry), &entry) &&

View File

@ -20,8 +20,8 @@
#include <string>
#include "base/macros.h"
#include "util/linux/address_types.h"
#include "util/linux/process_memory_range.h"
#include "util/misc/address_types.h"
namespace crashpad {
@ -34,10 +34,10 @@ class ElfSymbolTableReader {
struct SymbolInformation {
//! \brief The address of the symbol as it exists in the symbol table, not
//! adjusted for any load bias.
LinuxVMAddress address;
VMAddress address;
//! \brief The size of the symbol.
LinuxVMSize size;
VMSize size;
//! \brief The section index that the symbol definition is in relation to.
uint16_t shndx;
@ -61,7 +61,7 @@ class ElfSymbolTableReader {
// lookup.
ElfSymbolTableReader(const ProcessMemoryRange* memory,
ElfImageReader* elf_reader,
LinuxVMAddress address);
VMAddress address);
~ElfSymbolTableReader();
//! \brief Lookup information about a symbol.
@ -77,7 +77,7 @@ class ElfSymbolTableReader {
const ProcessMemoryRange* const memory_; // weak
ElfImageReader* const elf_reader_; // weak
const LinuxVMAddress base_address_;
const VMAddress base_address_;
DISALLOW_COPY_AND_ASSIGN(ElfSymbolTableReader);
};