Skip to content

Commit

Permalink
Added support for parsing usdt arguments to RISC-V
Browse files Browse the repository at this point in the history
  • Loading branch information
andreyviktorov2 authored and chenhengqi committed Nov 17, 2023
1 parent cbda69d commit 003b003
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 1 deletion.
7 changes: 7 additions & 0 deletions src/cc/usdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class Argument {
friend class ArgumentParser_loongarch64;
friend class ArgumentParser_powerpc64;
friend class ArgumentParser_s390x;
friend class ArgumentParser_riscv64;
friend class ArgumentParser_x64;
};

Expand Down Expand Up @@ -158,6 +159,12 @@ class ArgumentParser_s390x : public ArgumentParser {
ArgumentParser_s390x(const char *arg) : ArgumentParser(arg) {}
};

class ArgumentParser_riscv64 : public ArgumentParser {
public:
bool parse(Argument *dest);
ArgumentParser_riscv64(const char *arg) : ArgumentParser(arg) {}
};

class ArgumentParser_x64 : public ArgumentParser {
private:
enum Register {
Expand Down
2 changes: 2 additions & 0 deletions src/cc/usdt/usdt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ Location::Location(uint64_t addr, const std::string &bin_path, const char *arg_f
ArgumentParser_powerpc64 parser(arg_fmt);
#elif __s390x__
ArgumentParser_s390x parser(arg_fmt);
#elif __riscv
ArgumentParser_riscv64 parser(arg_fmt);
#else
ArgumentParser_x64 parser(arg_fmt);
#endif
Expand Down
50 changes: 50 additions & 0 deletions src/cc/usdt/usdt_args.cc
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,56 @@ bool ArgumentParser_s390x::parse(Argument *dest) {
return true;
}



bool ArgumentParser_riscv64::parse(Argument *dest) {
if (done())
return false;

bool matched;
std::smatch matches;
std::string arg_str(&arg_[cur_pos_]);
std::regex arg_n_regex("^(\\-?[1248])\\@");
// Operands with constants of form NUM
std::regex arg_op_regex_const("^(\\-?[0-9]+)( +|$)");
std::string reg_str =
"((a[0-9])|((s[0-9p])|s1[0-1])|(t[0-6p])|(pc)|(ra)|(fp)|(gp))";
// Operands with register only of form REG
std::regex arg_op_regex_reg("^" + reg_str + "( +|$)");
// Operands with a base register and an offset of form NUM(REG) or -NUM(REG)
std::regex arg_op_regex_breg_off("^(\\-?[0-9]+)\\(" + reg_str + "\\)( +|$)");

matched = std::regex_search(arg_str, matches, arg_n_regex);
if (matched) {
dest->arg_size_ = stoi(matches.str(1));
cur_pos_ += matches.length(0);
arg_str = &arg_[cur_pos_];
std::string reg_name;

if (std::regex_search(arg_str, matches, arg_op_regex_const)) {
dest->constant_ = (long long)stoull(matches.str(1));
} else if (std::regex_search(arg_str, matches, arg_op_regex_reg)) {
dest->base_register_name_ = matches.str(1);
} else if (std::regex_search(arg_str, matches, arg_op_regex_breg_off)) {
dest->deref_offset_ = stoi(matches.str(1));
dest->base_register_name_ = matches.str(2);
} else {
matched = false;
}
}

if (!matched) {
print_error(cur_pos_);
skip_until_whitespace_from(cur_pos_);
skip_whitespace_from(cur_pos_);
return false;
}

cur_pos_ += matches.length(0);
skip_whitespace_from(cur_pos_);
return true;
}

ssize_t ArgumentParser_x64::parse_identifier(ssize_t pos,
optional<std::string> *result) {
if (isalpha(arg_[pos]) || arg_[pos] == '_') {
Expand Down
13 changes: 12 additions & 1 deletion tests/cc/test_usdt_args.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static void verify_register(USDT::ArgumentParser &parser, int arg_size,
/* supported arches only */
#if defined(__aarch64__) || defined(__loongarch64) || \
defined(__powerpc64__) || defined(__s390x__) || \
defined(__x86_64__)
defined(__x86_64__) || defined(__riscv)

TEST_CASE("test usdt argument parsing", "[usdt]") {
SECTION("parse failure") {
Expand All @@ -67,6 +67,8 @@ TEST_CASE("test usdt argument parsing", "[usdt]") {
USDT::ArgumentParser_powerpc64 parser("4@-12(42)");
#elif __s390x__
USDT::ArgumentParser_s390x parser("4@-12(%r42)");
#elif __riscv
USDT::ArgumentParser_riscv64 parser("4@20(s35)");
#elif defined(__x86_64__)
USDT::ArgumentParser_x64 parser("4@i%ra+1r");
#endif
Expand Down Expand Up @@ -186,6 +188,15 @@ TEST_CASE("test usdt argument parsing", "[usdt]") {
verify_register(parser, 2, 1097);
verify_register(parser, 4, "gprs[7]", 108);
verify_register(parser, -2, "gprs[6]", -4);
#elif __riscv
USDT::ArgumentParser_riscv64 parser(
"-4@s5 -4@a0 4@20(s1) -4@-1 8@-72(s0) 8@0");
verify_register(parser, -4, "s5");
verify_register(parser, -4, "a0");
verify_register(parser, 4, "s1", 20);
verify_register(parser, -4, -1);
verify_register(parser, 8, "s0", -72);
verify_register(parser, 8, 0);
#elif defined(__x86_64__)
USDT::ArgumentParser_x64 parser(
"-4@$0 8@$1234 %rdi %rax %rsi "
Expand Down

0 comments on commit 003b003

Please sign in to comment.