#define TRACEPOINT_PROBE(category, event) \
int tracepoint__##category##__##event(struct tracepoint__##category##__##event *args)
+#define TP_DATA_LOC_READ_CONST(dst, field, length) \
+ do { \
+ short __offset = args->data_loc_##field & 0xFFFF; \
+ bpf_probe_read((void *)dst, length, (char *)args + __offset); \
+ } while (0);
+
+#define TP_DATA_LOC_READ(dst, field) \
+ do { \
+ short __offset = args->data_loc_##field & 0xFFFF; \
+ short __length = args->data_loc_##field >> 16; \
+ bpf_probe_read((void *)dst, __length, (char *)args + __offset); \
+ } while (0);
+
#endif
)********"
: C(C), diag_(C.getDiagnostics()), rewriter_(rewriter), out_(llvm::errs()) {
}
-static inline bool _is_valid_field(string const& line,
- string& field_type,
- string& field_name) {
+enum class field_kind_t {
+ common,
+ data_loc,
+ regular,
+ invalid
+};
+
+static inline field_kind_t _get_field_kind(string const& line,
+ string& field_type,
+ string& field_name) {
auto field_pos = line.find("field:");
if (field_pos == string::npos)
- return false;
+ return field_kind_t::invalid;
auto semi_pos = line.find(';', field_pos);
if (semi_pos == string::npos)
- return false;
+ return field_kind_t::invalid;
auto size_pos = line.find("size:", semi_pos);
if (size_pos == string::npos)
- return false;
+ return field_kind_t::invalid;
auto field = line.substr(field_pos + 6/*"field:"*/,
semi_pos - field_pos - 6);
auto pos = field.find_last_of("\t ");
if (pos == string::npos)
- return false;
+ return field_kind_t::invalid;
field_type = field.substr(0, pos);
field_name = field.substr(pos + 1);
if (field_type.find("__data_loc") != string::npos)
- return false;
+ return field_kind_t::data_loc;
if (field_name.find("common_") == 0)
- return false;
+ return field_kind_t::common;
- return true;
+ return field_kind_t::regular;
}
string TracepointTypeVisitor::GenerateTracepointStruct(
tp_struct += "\tu64 __do_not_use__;\n";
for (string line; getline(input, line); ) {
string field_type, field_name;
- if (!_is_valid_field(line, field_type, field_name))
- continue;
- tp_struct += "\t" + field_type + " " + field_name + ";\n";
+ switch (_get_field_kind(line, field_type, field_name)) {
+ case field_kind_t::invalid:
+ case field_kind_t::common:
+ continue;
+ case field_kind_t::data_loc:
+ tp_struct += "\tint data_loc_" + field_name + ";\n";
+ break;
+ case field_kind_t::regular:
+ tp_struct += "\t" + field_type + " " + field_name + ";\n";
+ break;
+ }
}
tp_struct += "};\n";