Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic USDT support for s390x #2266

Merged
merged 1 commit into from Mar 12, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -81,6 +81,7 @@ class Argument {
friend class ArgumentParser;
friend class ArgumentParser_aarch64;
friend class ArgumentParser_powerpc64;
friend class ArgumentParser_s390x;
friend class ArgumentParser_x64;
};

@@ -130,6 +131,12 @@ class ArgumentParser_powerpc64 : public ArgumentParser {
ArgumentParser_powerpc64(const char *arg) : ArgumentParser(arg) {}
};

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

class ArgumentParser_x64 : public ArgumentParser {
private:
enum Register {
@@ -40,6 +40,8 @@ Location::Location(uint64_t addr, const std::string &bin_path, const char *arg_f
ArgumentParser_aarch64 parser(arg_fmt);
#elif __powerpc64__
ArgumentParser_powerpc64 parser(arg_fmt);
#elif __s390x__
ArgumentParser_s390x parser(arg_fmt);
#else
ArgumentParser_x64 parser(arg_fmt);
#endif
@@ -285,6 +285,59 @@ bool ArgumentParser_powerpc64::parse(Argument *dest) {
return true;
}

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

bool matched;
std::cmatch matches;
#define S390X_IMM "(-?[0-9]+)"
std::regex arg_n_regex("^" S390X_IMM "@");
// <imm>
std::regex arg_op_regex_imm("^" S390X_IMM "(?: +|$)");
// %r<N>
#define S390X_REG "%r([0-9]|1[0-5])"
std::regex arg_op_regex_reg("^" S390X_REG "(?: +|$)");
// <disp>(%r<N>,%r<N>)
std::regex arg_op_regex_mem("^" S390X_IMM "?\\(" S390X_REG
"(?:," S390X_REG ")?\\)(?: +|$)");
#undef S390X_IMM
#undef S390X_REG

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

if (std::regex_search(arg_ + cur_pos_, matches, arg_op_regex_imm)) {
dest->constant_ = stoi(matches.str(1));
} else if (std::regex_search(arg_ + cur_pos_, matches, arg_op_regex_reg)) {
dest->base_register_name_ = "gprs[" + matches.str(1) + "]";
} else if (std::regex_search(arg_ + cur_pos_, matches, arg_op_regex_mem)) {
if (matches.length(1) > 0) {
dest->deref_offset_ = stoi(matches.str(1));
}
dest->base_register_name_ = "gprs[" + matches.str(2) + "]";
if (matches.length(3) > 0) {
dest->index_register_name_ = "gprs[" + matches.str(3) + "]";
}
} 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] == '_') {
@@ -58,6 +58,8 @@ TEST_CASE("test usdt argument parsing", "[usdt]") {
USDT::ArgumentParser_aarch64 parser("4@[x32,200]");
#elif __powerpc64__
USDT::ArgumentParser_powerpc64 parser("4@-12(42)");
#elif __s390x__
USDT::ArgumentParser_s390x parser("4@-12(%r42)");
#elif defined(__x86_64__)
USDT::ArgumentParser_x64 parser("4@i%ra+1r");
#endif
@@ -121,6 +123,50 @@ TEST_CASE("test usdt argument parsing", "[usdt]") {
verify_register(parser, 2, 1097);
verify_register(parser, 4, "gpr[30]", 108);
verify_register(parser, -2, "gpr[31]", -4);
#elif __s390x__
USDT::ArgumentParser_s390x parser(
"-4@%r0 8@%r0 8@0 4@0(%r0) -2@0(%r0) "
"1@%r0 -2@%r3 -8@9 -1@0(%r4) -4@16(%r6) "
"2@%r7 4@%r11 4@-67 8@-16(%r15) 1@-52(%r11) "
"-8@%r4 -8@%r14 2@-11 -2@14(%r13) -8@-32(%r12) "
"4@%r5 2@%r11 -8@-693 -1@-23(%r10) 4@28(%r9) "
"-2@%r3 -4@%r8 2@1097 4@108(%r7) -2@-4(%r6)");

verify_register(parser, -4, "gprs[0]");
verify_register(parser, 8, "gprs[0]");
verify_register(parser, 8, 0);
verify_register(parser, 4, "gprs[0]", 0);
verify_register(parser, -2, "gprs[0]", 0);

verify_register(parser, 1, "gprs[0]");
verify_register(parser, -2, "gprs[3]");
verify_register(parser, -8, 9);
verify_register(parser, -1, "gprs[4]", 0);
verify_register(parser, -4, "gprs[6]", 16);

verify_register(parser, 2, "gprs[7]");
verify_register(parser, 4, "gprs[11]");
verify_register(parser, 4, -67);
verify_register(parser, 8, "gprs[15]", -16);
verify_register(parser, 1, "gprs[11]", -52);

verify_register(parser, -8, "gprs[4]");
verify_register(parser, -8, "gprs[14]");
verify_register(parser, 2, -11);
verify_register(parser, -2, "gprs[13]", 14);
verify_register(parser, -8, "gprs[12]", -32);

verify_register(parser, 4, "gprs[5]");
verify_register(parser, 2, "gprs[11]");
verify_register(parser, -8, -693);
verify_register(parser, -1, "gprs[10]", -23);
verify_register(parser, 4, "gprs[9]", 28);

verify_register(parser, -2, "gprs[3]");
verify_register(parser, -4, "gprs[8]");
verify_register(parser, 2, 1097);
verify_register(parser, 4, "gprs[7]", 108);
verify_register(parser, -2, "gprs[6]", -4);
#elif defined(__x86_64__)
USDT::ArgumentParser_x64 parser(
"-4@$0 8@$1234 %rdi %rax %rsi "
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.