blob: 313c7cd16462860fa9da03effe43d387ffc50480 [file] [log] [blame]
// Copyright 2018 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.
#ifndef SRC_DEVELOPER_DEBUG_ZXDB_SYMBOLS_VARIABLE_LOCATION_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_SYMBOLS_VARIABLE_LOCATION_H_
#include <inttypes.h>
#include <vector>
namespace zxdb {
class SymbolContext;
// Describes the location of a value. A value can be in different locations depending on what the
// value of the IP is at which is represented as a series of ranges. The location for the value
// within those ranges is described as an opaque array of bytes (this is the DWARF expression which
// will evaluate to the value).
//
// In DWARF, simple variables that are always valid look like this:
// DW_AT_location (DW_OP_reg5 RDI)
//
// Complicated ones with ranges look like this:
// DW_AT_location:
// [0x00000000000ad6be, 0x00000000000ad6c8): DW_OP_reg2 RCX
// [0x00000000000ad6c8, 0x00000000000ad780): DW_OP_reg14 R14
class VariableLocation {
public:
struct Entry {
// These addresses are relative to the module that generated the symbol. A symbol context is
// required to compare to physical addresses.
//
// These will be 0,0 for a range that's always valid.
uint64_t begin = 0; // First address.
uint64_t end = 0; // First address past end.
// Returns whether this entry matches the given physical IP.
bool InRange(const SymbolContext& symbol_context, uint64_t ip) const;
// The DWARF expression that evaluates to the result. Evaluate with the DwarfExprEval object.
std::vector<uint8_t> expression;
};
VariableLocation();
// Constructs a Location with a single location valid for all address ranges, with the program
// contained in the given buffer.
VariableLocation(const uint8_t* data, size_t size);
// Constructs with an extracted array of Entries.
VariableLocation(std::vector<Entry> locations);
~VariableLocation();
// Returns whether this location lacks any actual locations.
bool is_null() const { return locations_.empty(); }
const std::vector<Entry>& locations() const { return locations_; }
// Returns the Entry that corresponds to the given IP, or nullptr if none matched.
const Entry* EntryForIP(const SymbolContext& symbol_context, uint64_t ip) const;
private:
// The location list. The DWARF spec explicitly allows for ranges to overlap which means the value
// can be retrieved from either location.
std::vector<Entry> locations_;
};
} // namespace zxdb
#endif // SRC_DEVELOPER_DEBUG_ZXDB_SYMBOLS_VARIABLE_LOCATION_H_