Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bcc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
bcc
Commits
422db709
Commit
422db709
authored
Oct 03, 2017
by
yonghong-song
Committed by
GitHub
Oct 03, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1365 from sandip4n/add-usdt-ppc64
Add basic USDT support for powerpc64
parents
91837cac
f86f0538
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
187 additions
and
49 deletions
+187
-49
src/cc/usdt.h
src/cc/usdt.h
+20
-14
src/cc/usdt/usdt.cc
src/cc/usdt/usdt.cc
+7
-1
src/cc/usdt/usdt_args.cc
src/cc/usdt/usdt_args.cc
+92
-29
tests/cc/test_usdt_args.cc
tests/cc/test_usdt_args.cc
+52
-2
tests/python/include/folly/tracing/StaticTracepoint-ELF.h
tests/python/include/folly/tracing/StaticTracepoint-ELF.h
+12
-1
tests/python/include/folly/tracing/StaticTracepoint.h
tests/python/include/folly/tracing/StaticTracepoint.h
+4
-2
No files found.
src/cc/usdt.h
View file @
422db709
...
...
@@ -74,37 +74,34 @@ public:
const
optional
<
int
>
deref_offset
()
const
{
return
deref_offset_
;
}
friend
class
ArgumentParser
;
friend
class
ArgumentParser_powerpc64
;
friend
class
ArgumentParser_x64
;
};
class
ArgumentParser
{
protected:
const
char
*
arg_
;
ssize_t
cur_pos_
;
void
skip_whitespace_from
(
size_t
pos
);
void
skip_until_whitespace_from
(
size_t
pos
);
protected:
virtual
bool
normalize_register
(
std
::
string
*
reg
,
int
*
reg_size
)
=
0
;
ssize_t
parse_register
(
ssize_t
pos
,
std
::
string
&
name
,
int
&
size
);
ssize_t
parse_number
(
ssize_t
pos
,
optional
<
int
>
*
number
);
ssize_t
parse_identifier
(
ssize_t
pos
,
optional
<
std
::
string
>
*
ident
);
ssize_t
parse_base_register
(
ssize_t
pos
,
Argument
*
dest
);
ssize_t
parse_index_register
(
ssize_t
pos
,
Argument
*
dest
);
ssize_t
parse_scale
(
ssize_t
pos
,
Argument
*
dest
);
ssize_t
parse_expr
(
ssize_t
pos
,
Argument
*
dest
);
ssize_t
parse_1
(
ssize_t
pos
,
Argument
*
dest
);
void
print_error
(
ssize_t
pos
);
public:
bool
parse
(
Argument
*
dest
)
;
virtual
bool
parse
(
Argument
*
dest
)
=
0
;
bool
done
()
{
return
cur_pos_
<
0
||
arg_
[
cur_pos_
]
==
'\0'
;
}
ArgumentParser
(
const
char
*
arg
)
:
arg_
(
arg
),
cur_pos_
(
0
)
{}
};
class
ArgumentParser_powerpc64
:
public
ArgumentParser
{
public:
bool
parse
(
Argument
*
dest
);
ArgumentParser_powerpc64
(
const
char
*
arg
)
:
ArgumentParser
(
arg
)
{}
};
class
ArgumentParser_x64
:
public
ArgumentParser
{
private:
enum
Register
{
REG_A
,
REG_B
,
...
...
@@ -133,8 +130,17 @@ class ArgumentParser_x64 : public ArgumentParser {
static
const
std
::
unordered_map
<
std
::
string
,
RegInfo
>
registers_
;
bool
normalize_register
(
std
::
string
*
reg
,
int
*
reg_size
);
void
reg_to_name
(
std
::
string
*
norm
,
Register
reg
);
ssize_t
parse_register
(
ssize_t
pos
,
std
::
string
&
name
,
int
&
size
);
ssize_t
parse_number
(
ssize_t
pos
,
optional
<
int
>
*
number
);
ssize_t
parse_identifier
(
ssize_t
pos
,
optional
<
std
::
string
>
*
ident
);
ssize_t
parse_base_register
(
ssize_t
pos
,
Argument
*
dest
);
ssize_t
parse_index_register
(
ssize_t
pos
,
Argument
*
dest
);
ssize_t
parse_scale
(
ssize_t
pos
,
Argument
*
dest
);
ssize_t
parse_expr
(
ssize_t
pos
,
Argument
*
dest
);
ssize_t
parse_1
(
ssize_t
pos
,
Argument
*
dest
);
public:
bool
parse
(
Argument
*
dest
);
ArgumentParser_x64
(
const
char
*
arg
)
:
ArgumentParser
(
arg
)
{}
};
...
...
src/cc/usdt/usdt.cc
View file @
422db709
...
...
@@ -32,7 +32,13 @@
namespace
USDT
{
Location
::
Location
(
uint64_t
addr
,
const
char
*
arg_fmt
)
:
address_
(
addr
)
{
#ifdef __powerpc64__
ArgumentParser_powerpc64
parser
(
arg_fmt
);
#elif defined(__x86_64__)
ArgumentParser_x64
parser
(
arg_fmt
);
#else
#error "bcc does not support this platform yet"
#endif
while
(
!
parser
.
done
())
{
Argument
arg
;
if
(
!
parser
.
parse
(
&
arg
))
...
...
@@ -174,7 +180,7 @@ bool Probe::usdt_getarg(std::ostream &stream) {
return
false
;
stream
<<
"
\n
return 0;
\n
}
\n
"
;
}
else
{
stream
<<
" switch(
ctx->ip
) {
\n
"
;
stream
<<
" switch(
PT_REGS_IP(ctx)
) {
\n
"
;
for
(
Location
&
location
:
locations_
)
{
uint64_t
global_address
;
...
...
src/cc/usdt/usdt_args.cc
View file @
422db709
...
...
@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <unordered_map>
#include <regex>
#include "syms.h"
#include "usdt.h"
...
...
@@ -112,7 +113,87 @@ bool Argument::assign_to_local(std::ostream &stream,
return
false
;
}
ssize_t
ArgumentParser
::
parse_number
(
ssize_t
pos
,
optional
<
int
>
*
result
)
{
void
ArgumentParser
::
print_error
(
ssize_t
pos
)
{
fprintf
(
stderr
,
"Parse error:
\n
%s
\n
"
,
arg_
);
for
(
ssize_t
i
=
0
;
i
<
pos
+
4
;
++
i
)
fputc
(
'-'
,
stderr
);
fputc
(
'^'
,
stderr
);
fputc
(
'\n'
,
stderr
);
}
void
ArgumentParser
::
skip_whitespace_from
(
size_t
pos
)
{
while
(
isspace
(
arg_
[
pos
]))
pos
++
;
cur_pos_
=
pos
;
}
void
ArgumentParser
::
skip_until_whitespace_from
(
size_t
pos
)
{
while
(
arg_
[
pos
]
!=
'\0'
&&
!
isspace
(
arg_
[
pos
]))
pos
++
;
cur_pos_
=
pos
;
}
bool
ArgumentParser_powerpc64
::
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 iNUM or i-NUM
std
::
regex
arg_op_regex_const
(
"^i(
\\
-?[0-9]+)( +|$)"
);
// Operands with register only of form REG or %rREG
std
::
regex
arg_op_regex_reg
(
"^(?:%r)?([1-2]?[0-9]|3[0-1])( +|$)"
);
// Operands with a base register and an offset of form
// NUM(REG) or -NUM(REG) or NUM(%rREG) or -NUM(%rREG)
std
::
regex
arg_op_regex_breg_off
(
"^(
\\
-?[0-9]+)
\\
((?:%r)?([1-2]?[0-9]|3[0-1])
\\
)( +|$)"
);
// Operands with a base register and an index register
// of form REG,REG or %rREG,%rREG
std
::
regex
arg_op_regex_breg_ireg
(
"^(?:%r)?([1-2]?[0-9]|3[0-1])
\\
,(?:%r)?([1-2]?[0-9]|3[0-1])( +|$)"
);
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_
];
if
(
std
::
regex_search
(
arg_str
,
matches
,
arg_op_regex_const
))
{
dest
->
constant_
=
stoi
(
matches
.
str
(
1
));
}
else
if
(
std
::
regex_search
(
arg_str
,
matches
,
arg_op_regex_reg
))
{
dest
->
base_register_name_
=
"gpr["
+
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_
=
"gpr["
+
matches
.
str
(
2
)
+
"]"
;
}
else
if
(
std
::
regex_search
(
arg_str
,
matches
,
arg_op_regex_breg_ireg
))
{
dest
->
deref_offset_
=
0
;
// In powerpc64, such operands contain a base
// register and an index register which are
// part of an indexed load/store operation.
// Even if no offset value is present, this
// is required by Argument::assign_to_local()
// in order to generate code for reading the
// argument. So, this is set to zero.
dest
->
base_register_name_
=
"gpr["
+
matches
.
str
(
1
)
+
"]"
;
dest
->
index_register_name_
=
"gpr["
+
matches
.
str
(
2
)
+
"]"
;
dest
->
scale_
=
abs
(
*
dest
->
arg_size_
);
}
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_number
(
ssize_t
pos
,
optional
<
int
>
*
result
)
{
char
*
endp
;
int
number
=
strtol
(
arg_
+
pos
,
&
endp
,
0
);
if
(
endp
>
arg_
+
pos
)
...
...
@@ -120,8 +201,8 @@ ssize_t ArgumentParser::parse_number(ssize_t pos, optional<int> *result) {
return
endp
-
arg_
;
}
ssize_t
ArgumentParser
::
parse_identifier
(
ssize_t
pos
,
optional
<
std
::
string
>
*
result
)
{
ssize_t
ArgumentParser
_x64
::
parse_identifier
(
ssize_t
pos
,
optional
<
std
::
string
>
*
result
)
{
if
(
isalpha
(
arg_
[
pos
])
||
arg_
[
pos
]
==
'_'
)
{
ssize_t
start
=
pos
++
;
while
(
isalnum
(
arg_
[
pos
])
||
arg_
[
pos
]
==
'_'
)
pos
++
;
...
...
@@ -131,8 +212,8 @@ ssize_t ArgumentParser::parse_identifier(ssize_t pos,
return
pos
;
}
ssize_t
ArgumentParser
::
parse_register
(
ssize_t
pos
,
std
::
string
&
name
,
int
&
size
)
{
ssize_t
ArgumentParser
_x64
::
parse_register
(
ssize_t
pos
,
std
::
string
&
name
,
int
&
size
)
{
ssize_t
start
=
++
pos
;
if
(
arg_
[
start
-
1
]
!=
'%'
)
return
-
start
;
...
...
@@ -147,7 +228,7 @@ ssize_t ArgumentParser::parse_register(ssize_t pos, std::string &name,
return
pos
;
}
ssize_t
ArgumentParser
::
parse_base_register
(
ssize_t
pos
,
Argument
*
dest
)
{
ssize_t
ArgumentParser
_x64
::
parse_base_register
(
ssize_t
pos
,
Argument
*
dest
)
{
int
size
;
std
::
string
name
;
ssize_t
res
=
parse_register
(
pos
,
name
,
size
);
...
...
@@ -161,7 +242,7 @@ ssize_t ArgumentParser::parse_base_register(ssize_t pos, Argument *dest) {
return
res
;
}
ssize_t
ArgumentParser
::
parse_index_register
(
ssize_t
pos
,
Argument
*
dest
)
{
ssize_t
ArgumentParser
_x64
::
parse_index_register
(
ssize_t
pos
,
Argument
*
dest
)
{
int
size
;
std
::
string
name
;
ssize_t
res
=
parse_register
(
pos
,
name
,
size
);
...
...
@@ -173,11 +254,11 @@ ssize_t ArgumentParser::parse_index_register(ssize_t pos, Argument *dest) {
return
res
;
}
ssize_t
ArgumentParser
::
parse_scale
(
ssize_t
pos
,
Argument
*
dest
)
{
ssize_t
ArgumentParser
_x64
::
parse_scale
(
ssize_t
pos
,
Argument
*
dest
)
{
return
parse_number
(
pos
,
&
dest
->
scale_
);
}
ssize_t
ArgumentParser
::
parse_expr
(
ssize_t
pos
,
Argument
*
dest
)
{
ssize_t
ArgumentParser
_x64
::
parse_expr
(
ssize_t
pos
,
Argument
*
dest
)
{
if
(
arg_
[
pos
]
==
'$'
)
return
parse_number
(
pos
+
1
,
&
dest
->
constant_
);
...
...
@@ -221,7 +302,7 @@ ssize_t ArgumentParser::parse_expr(ssize_t pos, Argument *dest) {
return
(
arg_
[
pos
]
==
')'
)
?
pos
+
1
:
-
pos
;
}
ssize_t
ArgumentParser
::
parse_1
(
ssize_t
pos
,
Argument
*
dest
)
{
ssize_t
ArgumentParser
_x64
::
parse_1
(
ssize_t
pos
,
Argument
*
dest
)
{
if
(
isdigit
(
arg_
[
pos
])
||
arg_
[
pos
]
==
'-'
)
{
optional
<
int
>
asize
;
ssize_t
m
=
parse_number
(
pos
,
&
asize
);
...
...
@@ -233,25 +314,7 @@ ssize_t ArgumentParser::parse_1(ssize_t pos, Argument *dest) {
return
parse_expr
(
pos
,
dest
);
}
void
ArgumentParser
::
print_error
(
ssize_t
pos
)
{
fprintf
(
stderr
,
"Parse error:
\n
%s
\n
"
,
arg_
);
for
(
ssize_t
i
=
0
;
i
<
pos
+
4
;
++
i
)
fputc
(
'-'
,
stderr
);
fputc
(
'^'
,
stderr
);
fputc
(
'\n'
,
stderr
);
}
void
ArgumentParser
::
skip_whitespace_from
(
size_t
pos
)
{
while
(
isspace
(
arg_
[
pos
]))
pos
++
;
cur_pos_
=
pos
;
}
void
ArgumentParser
::
skip_until_whitespace_from
(
size_t
pos
)
{
while
(
arg_
[
pos
]
!=
'\0'
&&
!
isspace
(
arg_
[
pos
]))
pos
++
;
cur_pos_
=
pos
;
}
bool
ArgumentParser
::
parse
(
Argument
*
dest
)
{
bool
ArgumentParser_x64
::
parse
(
Argument
*
dest
)
{
if
(
done
())
return
false
;
...
...
tests/cc/test_usdt_args.cc
View file @
422db709
...
...
@@ -22,7 +22,7 @@
using
std
::
experimental
::
optional
;
using
std
::
experimental
::
nullopt
;
static
void
verify_register
(
USDT
::
ArgumentParser
_x64
&
parser
,
int
arg_size
,
static
void
verify_register
(
USDT
::
ArgumentParser
&
parser
,
int
arg_size
,
int
constant
)
{
USDT
::
Argument
arg
;
REQUIRE
(
parser
.
parse
(
&
arg
));
...
...
@@ -32,7 +32,7 @@ static void verify_register(USDT::ArgumentParser_x64 &parser, int arg_size,
REQUIRE
(
arg
.
constant
()
==
constant
);
}
static
void
verify_register
(
USDT
::
ArgumentParser
_x64
&
parser
,
int
arg_size
,
static
void
verify_register
(
USDT
::
ArgumentParser
&
parser
,
int
arg_size
,
const
std
::
string
&
regname
,
optional
<
int
>
deref_offset
=
nullopt
,
optional
<
std
::
string
>
deref_ident
=
nullopt
,
...
...
@@ -54,7 +54,11 @@ static void verify_register(USDT::ArgumentParser_x64 &parser, int arg_size,
TEST_CASE
(
"test usdt argument parsing"
,
"[usdt]"
)
{
SECTION
(
"parse failure"
)
{
#ifdef __powerpc64__
USDT
::
ArgumentParser_powerpc64
parser
(
"4@-12(42)"
);
#elif defined(__x86_64__)
USDT
::
ArgumentParser_x64
parser
(
"4@i%ra+1r"
);
#endif
USDT
::
Argument
arg
;
REQUIRE
(
!
parser
.
parse
(
&
arg
));
int
i
;
...
...
@@ -65,6 +69,51 @@ TEST_CASE("test usdt argument parsing", "[usdt]") {
REQUIRE
(
i
<
10
);
}
SECTION
(
"argument examples from the Python implementation"
)
{
#ifdef __powerpc64__
USDT
::
ArgumentParser_powerpc64
parser
(
"-4@0 8@%r0 8@i0 4@0(%r0) -2@0(0) "
"1@0 -2@%r3 -8@i9 -1@0(%r4) -4@16(6) "
"2@7 4@%r11 4@i-67 8@-16(%r17) 1@-52(11) "
"-8@13 -8@%r25 2@i-11 -2@14(%r26) -8@-32(24) "
"4@29 2@%r17 -8@i-693 -1@-23(%r31) 4@28(30) "
"-2@31 -4@%r30 2@i1097 4@108(%r30) -2@-4(31)"
);
verify_register
(
parser
,
-
4
,
"gpr[0]"
);
verify_register
(
parser
,
8
,
"gpr[0]"
);
verify_register
(
parser
,
8
,
0
);
verify_register
(
parser
,
4
,
"gpr[0]"
,
0
);
verify_register
(
parser
,
-
2
,
"gpr[0]"
,
0
);
verify_register
(
parser
,
1
,
"gpr[0]"
);
verify_register
(
parser
,
-
2
,
"gpr[3]"
);
verify_register
(
parser
,
-
8
,
9
);
verify_register
(
parser
,
-
1
,
"gpr[4]"
,
0
);
verify_register
(
parser
,
-
4
,
"gpr[6]"
,
16
);
verify_register
(
parser
,
2
,
"gpr[7]"
);
verify_register
(
parser
,
4
,
"gpr[11]"
);
verify_register
(
parser
,
4
,
-
67
);
verify_register
(
parser
,
8
,
"gpr[17]"
,
-
16
);
verify_register
(
parser
,
1
,
"gpr[11]"
,
-
52
);
verify_register
(
parser
,
-
8
,
"gpr[13]"
);
verify_register
(
parser
,
-
8
,
"gpr[25]"
);
verify_register
(
parser
,
2
,
-
11
);
verify_register
(
parser
,
-
2
,
"gpr[26]"
,
14
);
verify_register
(
parser
,
-
8
,
"gpr[24]"
,
-
32
);
verify_register
(
parser
,
4
,
"gpr[29]"
);
verify_register
(
parser
,
2
,
"gpr[17]"
);
verify_register
(
parser
,
-
8
,
-
693
);
verify_register
(
parser
,
-
1
,
"gpr[31]"
,
-
23
);
verify_register
(
parser
,
4
,
"gpr[30]"
,
28
);
verify_register
(
parser
,
-
2
,
"gpr[31]"
);
verify_register
(
parser
,
-
4
,
"gpr[30]"
);
verify_register
(
parser
,
2
,
1097
);
verify_register
(
parser
,
4
,
"gpr[30]"
,
108
);
verify_register
(
parser
,
-
2
,
"gpr[31]"
,
-
4
);
#elif defined(__x86_64__)
USDT
::
ArgumentParser_x64
parser
(
"-4@$0 8@$1234 %rdi %rax %rsi "
"-8@%rbx 4@%r12 8@-8(%rbp) 4@(%rax) "
...
...
@@ -94,6 +143,7 @@ TEST_CASE("test usdt argument parsing", "[usdt]") {
verify_register
(
parser
,
8
,
"ax"
,
0
,
nullopt
,
std
::
string
(
"dx"
),
8
);
verify_register
(
parser
,
4
,
"bx"
,
0
,
nullopt
,
std
::
string
(
"cx"
));
#endif
REQUIRE
(
parser
.
done
());
}
...
...
tests/python/include/folly/tracing/StaticTracepoint-ELF
x86
.h
→
tests/python/include/folly/tracing/StaticTracepoint-ELF.h
View file @
422db709
...
...
@@ -18,8 +18,12 @@
// Default constraint for the probe arguments as operands.
#ifndef FOLLY_SDT_ARG_CONSTRAINT
#if defined(__powerpc64__) || defined(__powerpc__)
#define FOLLY_SDT_ARG_CONSTRAINT "nQr"
#elif defined(__x86_64__) || defined(__i386__)
#define FOLLY_SDT_ARG_CONSTRAINT "nor"
#endif
#endif
// Instruction to emit for the probe.
#define FOLLY_SDT_NOP nop
...
...
@@ -73,7 +77,14 @@
FOLLY_SDT_OPERANDS_7(_1, _2, _3, _4, _5, _6, _7), FOLLY_SDT_ARG(8, _8)
// Templates to reference the arguments from operands in note section.
#define FOLLY_SDT_ARGFMT(no) %n[FOLLY_SDT_S##no]@%[FOLLY_SDT_A##no]
#if defined(__powerpc64__ ) || defined(__powerpc__)
#define FOLLY_SDT_ARGTMPL(id) %I[id]%[id]
#elif defined(__i386__)
#define FOLLY_SDT_ARGTMPL(id) %w[id]
#else
#define FOLLY_SDT_ARGTMPL(id) %[id]
#endif
#define FOLLY_SDT_ARGFMT(no) %n[FOLLY_SDT_S##no]@FOLLY_SDT_ARGTMPL(FOLLY_SDT_A##no)
#define FOLLY_SDT_ARG_TEMPLATE_0
/*No arguments*/
#define FOLLY_SDT_ARG_TEMPLATE_1 FOLLY_SDT_ARGFMT(1)
#define FOLLY_SDT_ARG_TEMPLATE_2 FOLLY_SDT_ARG_TEMPLATE_1 FOLLY_SDT_ARGFMT(2)
...
...
tests/python/include/folly/tracing/StaticTracepoint.h
View file @
422db709
...
...
@@ -16,8 +16,10 @@
#pragma once
#if defined(__ELF__) && (defined(__x86_64__) || defined(__i386__))
#include <folly/tracing/StaticTracepoint-ELFx86.h>
#if defined(__ELF__) && \
(defined(__powerpc64__) || defined(__powerpc__) || \
defined(__x86_64__) || defined(__i386__))
#include <folly/tracing/StaticTracepoint-ELF.h>
#define FOLLY_SDT(provider, name, ...) \
FOLLY_SDT_PROBE_N( \
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment