1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
#ifndef LOC2STAP_H
#define LOC2STAP_H 1
#include "staptree.h"
#include <elfutils/libdw.h>
enum location_type
{
loc_address, loc_register, loc_noncontiguous, loc_unavailable,
loc_value, loc_constant, loc_implicit_pointer,
loc_decl, loc_fragment, loc_final
};
struct location
{
location_type type;
unsigned byte_size;
// loc_address, loc_value, loc_fragment, loc_final
expression *program;
// loc_register
unsigned int regno;
// loc_noncontiguous
location *pieces;
location *piece_next;
// loc_constant
const void *constant_block;
// loc_implicit_pointer
location *target;
// loc_register, loc_implicit_pointer
Dwarf_Word offset;
location(location_type t = loc_unavailable)
: type(t), byte_size(0), program(0), regno(0), pieces(0),
piece_next(0), constant_block(0), target(0), offset(0)
{ }
};
struct dwflpp;
class location_context
{
public:
const target_symbol *e_orig; // unmodified original
target_symbol *e; // deep-copied + rewritten, for use within synthetic _dwarf_tvar* function body
// These three form the argument list to the function, in sequence.
// They will be referenced by the expression(s) computing the location.
vardecl *pointer;
std::vector<vardecl *> indicies;
vardecl *value;
Dwarf_Attribute *attr;
Dwarf_Addr dwbias;
Dwarf_Addr pc;
Dwarf_Attribute *fb_attr;
const Dwarf_Op *cfa_ops;
dwflpp *dw;
// Temporaries required while computing EVALS and LOCATIONS.
symbol *frame_base;
std::vector<vardecl *> locals;
std::vector<statement *> evals;
std::vector<vardecl *> globals;
std::map<Dwarf_Addr, block *> entry_probes;
Dwarf_Die *function;
Dwarf_Die *parameter_ref;
std::vector<location_context> call_site_values;
int param_ref_depth;
// A set of locations which have been requested to be evaluated.
// The last one can be considered "current", and thus the result
// is locations.back()->program.
// ??? This is the old loc->next list. Should we just have a
// single pointer here instead?
std::vector<location *> locations; // ??? old loc->next list
// The dwarf is within a user (vs kernel) context.
bool userspace_p;
location *new_location(location_type);
location *new_location(const location &old);
symbol *new_symref(vardecl *var);
symbol *new_local(const char *namebase);
expression *new_target_reg(unsigned regno);
expression *new_plus_const(expression *, int64_t);
expression *save_expression(expression *);
symbol *frame_location();
void adapt_pointer_to_bpf(int size, int offset, bool is_signed);
expression *handle_GNU_entry_value(Dwarf_Op expr);
expression *handle_GNU_parameter_ref(Dwarf_Op expr);
location *translate(const Dwarf_Op *expr, size_t len, size_t start,
location *input, bool may_use_fb, bool computing_value);
location *location_from_address (const Dwarf_Op *expr, size_t len,
location *input);
location *translate_offset (const Dwarf_Op *expr, size_t len, size_t i,
location *input, Dwarf_Word offset);
location *location_relative (const Dwarf_Op *expr, size_t len,
location *input);
location *translate_array_1(Dwarf_Die *anydie, Dwarf_Word stride,
location *loc, expression *index);
public:
location_context(target_symbol *, expression * = NULL);
expression *translate_address(Dwarf_Addr a);
location *translate_constant(Dwarf_Attribute *a);
location *translate_location(const Dwarf_Op *locexpr,
size_t locexprlen, location *input);
location *translate_argument (expression *value);
location *translate_argument (vardecl *var);
location *translate_array(Dwarf_Die *typedie, location *, expression *);
location *translate_array_pointer(Dwarf_Die *typedie, location *input,
expression *index);
location *translate_array_pointer (Dwarf_Die *, location *input,
vardecl *index);
location *discontiguify(location *loc, Dwarf_Word total_bytes,
Dwarf_Word max_piece_bytes);
};
#endif
|