Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bpftrace
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
bpftrace
Commits
e20808ff
Commit
e20808ff
authored
Jul 08, 2017
by
Alastair Robertson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for different sized values
parent
21eb3db3
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
166 additions
and
123 deletions
+166
-123
src/ast.h
src/ast.h
+4
-0
src/attached_probe.cpp
src/attached_probe.cpp
+25
-0
src/attached_probe.h
src/attached_probe.h
+5
-0
src/bpftrace.cpp
src/bpftrace.cpp
+12
-12
src/codegen_llvm.cpp
src/codegen_llvm.cpp
+35
-22
src/irbuilderbpf.cpp
src/irbuilderbpf.cpp
+28
-6
src/irbuilderbpf.h
src/irbuilderbpf.h
+3
-1
src/map.cpp
src/map.cpp
+4
-4
src/map.h
src/map.h
+3
-3
src/mapkey.cpp
src/mapkey.cpp
+3
-3
src/mapkey.h
src/mapkey.h
+2
-2
src/semantic_analyser.cpp
src/semantic_analyser.cpp
+31
-32
src/semantic_analyser.h
src/semantic_analyser.h
+1
-3
src/types.cpp
src/types.cpp
+4
-28
src/types.h
src/types.h
+6
-7
No files found.
src/ast.h
View file @
e20808ff
...
...
@@ -3,6 +3,8 @@
#include <string>
#include <vector>
#include "types.h"
namespace
bpftrace
{
namespace
ast
{
...
...
@@ -12,6 +14,8 @@ class Node {
public:
virtual
~
Node
()
{
}
virtual
void
accept
(
Visitor
&
v
)
=
0
;
SizedType
type
;
};
class
Expression
:
public
Node
{
...
...
src/attached_probe.cpp
View file @
e20808ff
...
...
@@ -10,6 +10,31 @@
namespace
bpftrace
{
bpf_probe_attach_type
attachtype
(
ProbeType
t
)
{
switch
(
t
)
{
case
ProbeType
:
:
kprobe
:
return
BPF_PROBE_ENTRY
;
break
;
case
ProbeType
:
:
kretprobe
:
return
BPF_PROBE_RETURN
;
break
;
case
ProbeType
:
:
uprobe
:
return
BPF_PROBE_ENTRY
;
break
;
case
ProbeType
:
:
uretprobe
:
return
BPF_PROBE_RETURN
;
break
;
default:
abort
();
}
}
bpf_prog_type
progtype
(
ProbeType
t
)
{
switch
(
t
)
{
case
ProbeType
:
:
kprobe
:
return
BPF_PROG_TYPE_KPROBE
;
break
;
case
ProbeType
:
:
kretprobe
:
return
BPF_PROG_TYPE_KPROBE
;
break
;
case
ProbeType
:
:
uprobe
:
return
BPF_PROG_TYPE_KPROBE
;
break
;
case
ProbeType
:
:
uretprobe
:
return
BPF_PROG_TYPE_KPROBE
;
break
;
default:
abort
();
}
}
AttachedProbe
::
AttachedProbe
(
Probe
&
probe
,
std
::
tuple
<
uint8_t
*
,
uintptr_t
>
&
func
)
:
probe_
(
probe
),
func_
(
func
)
{
...
...
src/attached_probe.h
View file @
e20808ff
...
...
@@ -2,8 +2,13 @@
#include "types.h"
#include "libbpf.h"
namespace
bpftrace
{
bpf_probe_attach_type
attachtype
(
ProbeType
t
);
bpf_prog_type
progtype
(
ProbeType
t
);
class
AttachedProbe
{
public:
...
...
src/bpftrace.cpp
View file @
e20808ff
...
...
@@ -64,7 +64,7 @@ int BPFtrace::print_maps() const
{
Map
&
map
=
*
mapmap
.
second
.
get
();
int
err
;
if
(
map
.
type_
==
Type
::
quantize
)
if
(
map
.
type_
.
type
==
Type
::
quantize
)
err
=
print_map_quantize
(
map
);
else
err
=
print_map
(
map
);
...
...
@@ -95,19 +95,19 @@ int BPFtrace::print_map(Map &map) const
{
std
::
cout
<<
map
.
name_
<<
map
.
key_
.
argument_value_list
(
*
this
,
key
)
<<
": "
;
int64_t
value
;
int
err
=
bpf_lookup_elem
(
map
.
mapfd_
,
key
.
data
(),
&
value
);
auto
value
=
std
::
vector
<
uint8_t
>
(
map
.
type_
.
size
)
;
int
err
=
bpf_lookup_elem
(
map
.
mapfd_
,
key
.
data
(),
value
.
data
()
);
if
(
err
)
{
std
::
cerr
<<
"Error looking up elem: "
<<
err
<<
std
::
endl
;
return
-
1
;
}
if
(
map
.
type_
==
Type
::
stack
)
std
::
cout
<<
get_stack
(
value
,
false
,
8
);
else
if
(
map
.
type_
==
Type
::
ustack
)
std
::
cout
<<
get_stack
(
value
,
true
,
8
);
if
(
map
.
type_
.
type
==
Type
::
stack
)
std
::
cout
<<
get_stack
(
*
(
uint32_t
*
)
value
.
data
()
,
false
,
8
);
else
if
(
map
.
type_
.
type
==
Type
::
ustack
)
std
::
cout
<<
get_stack
(
*
(
uint32_t
*
)
value
.
data
()
,
true
,
8
);
else
std
::
cout
<<
value
<<
std
::
endl
;
std
::
cout
<<
*
(
int64_t
*
)
value
.
data
()
<<
std
::
endl
;
old_key
=
key
;
}
...
...
@@ -255,17 +255,17 @@ std::vector<uint8_t> BPFtrace::find_empty_key(Map &map, size_t size) const
{
if
(
size
==
0
)
size
=
8
;
auto
key
=
std
::
vector
<
uint8_t
>
(
size
);
uint8_t
value
;
auto
value
=
std
::
vector
<
uint8_t
>
(
map
.
type_
.
size
)
;
if
(
bpf_lookup_elem
(
map
.
mapfd_
,
key
.
data
(),
&
value
))
if
(
bpf_lookup_elem
(
map
.
mapfd_
,
key
.
data
(),
value
.
data
()
))
return
key
;
for
(
auto
&
elem
:
key
)
elem
=
0xff
;
if
(
bpf_lookup_elem
(
map
.
mapfd_
,
key
.
data
(),
&
value
))
if
(
bpf_lookup_elem
(
map
.
mapfd_
,
key
.
data
(),
value
.
data
()
))
return
key
;
for
(
auto
&
elem
:
key
)
elem
=
0x55
;
if
(
bpf_lookup_elem
(
map
.
mapfd_
,
key
.
data
(),
&
value
))
if
(
bpf_lookup_elem
(
map
.
mapfd_
,
key
.
data
(),
value
.
data
()
))
return
key
;
throw
std
::
runtime_error
(
"Could not find empty key"
);
...
...
src/codegen_llvm.cpp
View file @
e20808ff
...
...
@@ -56,7 +56,7 @@ void CodegenLLVM::visit(Builtin &builtin)
{
int
arg_num
=
atoi
(
builtin
.
ident
.
substr
(
3
).
c_str
());
AllocaInst
*
dst
=
b_
.
CreateAllocaBPF
(
builtin
.
ident
);
AllocaInst
*
dst
=
b_
.
CreateAllocaBPF
(
builtin
.
type
,
builtin
.
ident
);
int
offset
=
arch
::
arg_offset
(
arg_num
)
*
sizeof
(
uintptr_t
);
Value
*
src
=
b_
.
CreateGEP
(
ctx_
,
b_
.
getInt64
(
offset
));
b_
.
CreateProbeRead
(
dst
,
b_
.
getInt64
(
8
),
src
);
...
...
@@ -64,7 +64,7 @@ void CodegenLLVM::visit(Builtin &builtin)
}
else
if
(
builtin
.
ident
==
"retval"
)
{
AllocaInst
*
dst
=
b_
.
CreateAllocaBPF
(
builtin
.
ident
);
AllocaInst
*
dst
=
b_
.
CreateAllocaBPF
(
builtin
.
type
,
builtin
.
ident
);
int
offset
=
arch
::
ret_offset
()
*
sizeof
(
uintptr_t
);
Value
*
src
=
b_
.
CreateGEP
(
ctx_
,
b_
.
getInt64
(
offset
));
b_
.
CreateProbeRead
(
dst
,
b_
.
getInt64
(
8
),
src
);
...
...
@@ -126,7 +126,7 @@ void CodegenLLVM::visit(Unop &unop)
case
bpftrace
:
:
Parser
::
token
::
BNOT
:
expr_
=
b_
.
CreateNeg
(
expr_
);
break
;
case
bpftrace
:
:
Parser
::
token
::
MUL
:
{
AllocaInst
*
dst
=
b_
.
CreateAllocaBPF
(
"deref"
);
AllocaInst
*
dst
=
b_
.
CreateAllocaBPF
(
unop
.
expr
->
type
,
"deref"
);
b_
.
CreateProbeRead
(
dst
,
b_
.
getInt64
(
8
),
expr_
);
expr_
=
b_
.
CreateLoad
(
dst
);
break
;
...
...
@@ -144,12 +144,11 @@ void CodegenLLVM::visit(AssignMapStatement &assignment)
{
Map
&
map
=
*
assignment
.
map
;
AllocaInst
*
val
=
b_
.
CreateAllocaBPF
(
map
.
ident
+
"_val"
);
assignment
.
expr
->
accept
(
*
this
);
b_
.
CreateStore
(
expr_
,
val
);
AllocaInst
*
val
=
b_
.
CreateAllocaBPF
(
map
.
type
,
map
.
ident
+
"_val"
);
b_
.
CreateStore
(
expr_
,
val
);
AllocaInst
*
key
=
getMapKey
(
map
);
b_
.
CreateMapUpdateElem
(
map
,
key
,
val
);
}
...
...
@@ -162,7 +161,7 @@ void CodegenLLVM::visit(AssignMapCallStatement &assignment)
{
AllocaInst
*
key
=
getMapKey
(
map
);
Value
*
oldval
=
b_
.
CreateMapLookupElem
(
map
,
key
);
AllocaInst
*
newval
=
b_
.
CreateAllocaBPF
(
map
.
ident
+
"_val"
);
AllocaInst
*
newval
=
b_
.
CreateAllocaBPF
(
map
.
type
,
map
.
ident
+
"_val"
);
b_
.
CreateStore
(
b_
.
CreateAdd
(
oldval
,
b_
.
getInt64
(
1
)),
newval
);
b_
.
CreateMapUpdateElem
(
map
,
key
,
newval
);
}
...
...
@@ -174,7 +173,7 @@ void CodegenLLVM::visit(AssignMapCallStatement &assignment)
AllocaInst
*
key
=
getQuantizeMapKey
(
map
,
log2
);
Value
*
oldval
=
b_
.
CreateMapLookupElem
(
map
,
key
);
AllocaInst
*
newval
=
b_
.
CreateAllocaBPF
(
map
.
ident
+
"_val"
);
AllocaInst
*
newval
=
b_
.
CreateAllocaBPF
(
map
.
type
,
map
.
ident
+
"_val"
);
b_
.
CreateStore
(
b_
.
CreateAdd
(
oldval
,
b_
.
getInt64
(
1
)),
newval
);
b_
.
CreateMapUpdateElem
(
map
,
key
,
newval
);
}
...
...
@@ -246,17 +245,24 @@ AllocaInst *CodegenLLVM::getMapKey(Map &map)
{
AllocaInst
*
key
;
if
(
map
.
vargs
)
{
key
=
b_
.
CreateAllocaBPF
(
map
.
ident
+
"_key"
,
map
.
vargs
->
size
());
int
i
=
0
;
size_t
size
=
0
;
for
(
Expression
*
expr
:
*
map
.
vargs
)
{
size
+=
expr
->
type
.
size
;
}
key
=
b_
.
CreateAllocaMapKey
(
size
,
map
.
ident
+
"_key"
);
int
offset
=
0
;
for
(
Expression
*
expr
:
*
map
.
vargs
)
{
expr
->
accept
(
*
this
);
Value
*
offset
=
b_
.
CreateGEP
(
key
,
b_
.
getInt64
(
i
++
));
b_
.
CreateStore
(
expr_
,
offset
);
Value
*
offset_val
=
b_
.
CreateGEP
(
key
,
{
b_
.
getInt64
(
0
),
b_
.
getInt64
(
offset
)});
b_
.
CreateStore
(
expr_
,
offset_val
);
offset
+=
expr
->
type
.
size
;
}
}
else
{
key
=
b_
.
CreateAllocaBPF
(
map
.
ident
+
"_key"
);
key
=
b_
.
CreateAllocaBPF
(
map
.
type
,
map
.
ident
+
"_key"
);
b_
.
CreateStore
(
b_
.
getInt64
(
0
),
key
);
}
return
key
;
...
...
@@ -266,19 +272,26 @@ AllocaInst *CodegenLLVM::getQuantizeMapKey(Map &map, Value *log2)
{
AllocaInst
*
key
;
if
(
map
.
vargs
)
{
key
=
b_
.
CreateAllocaBPF
(
map
.
ident
+
"_key"
,
map
.
vargs
->
size
()
+
1
);
int
i
=
0
;
size_t
size
=
8
;
// Extra space for the bucket value
for
(
Expression
*
expr
:
*
map
.
vargs
)
{
size
+=
expr
->
type
.
size
;
}
key
=
b_
.
CreateAllocaMapKey
(
size
,
map
.
ident
+
"_key"
);
int
offset
=
0
;
for
(
Expression
*
expr
:
*
map
.
vargs
)
{
expr
->
accept
(
*
this
);
Value
*
offset
=
b_
.
CreateGEP
(
key
,
b_
.
getInt64
(
i
++
));
b_
.
CreateStore
(
expr_
,
offset
);
Value
*
offset_val
=
b_
.
CreateGEP
(
key
,
{
b_
.
getInt64
(
0
),
b_
.
getInt64
(
offset
)});
b_
.
CreateStore
(
expr_
,
offset_val
);
offset
+=
expr
->
type
.
size
;
}
Value
*
offset
=
b_
.
CreateGEP
(
key
,
b_
.
getInt64
(
i
)
);
b_
.
CreateStore
(
log2
,
offset
);
Value
*
offset
_val
=
b_
.
CreateGEP
(
key
,
{
b_
.
getInt64
(
0
),
b_
.
getInt64
(
offset
)}
);
b_
.
CreateStore
(
log2
,
offset
_val
);
}
else
{
key
=
b_
.
CreateAllocaBPF
(
map
.
ident
+
"_key"
);
key
=
b_
.
CreateAllocaBPF
(
SizedType
(
Type
::
integer
,
8
),
map
.
ident
+
"_key"
);
b_
.
CreateStore
(
log2
,
key
);
}
return
key
;
...
...
@@ -330,10 +343,10 @@ void CodegenLLVM::createLog2Function()
Value
*
arg
=
&
log2_func
->
getArgumentList
().
front
();
Value
*
n_alloc
=
b_
.
CreateAllocaBPF
();
Value
*
n_alloc
=
b_
.
CreateAllocaBPF
(
SizedType
(
Type
::
integer
,
8
)
);
b_
.
CreateStore
(
arg
,
n_alloc
);
Value
*
result
=
b_
.
CreateAllocaBPF
();
Value
*
result
=
b_
.
CreateAllocaBPF
(
SizedType
(
Type
::
integer
,
8
)
);
b_
.
CreateStore
(
b_
.
getInt64
(
0
),
result
);
for
(
int
i
=
4
;
i
>=
0
;
i
--
)
...
...
src/irbuilderbpf.cpp
View file @
e20808ff
...
...
@@ -25,16 +25,38 @@ IRBuilderBPF::IRBuilderBPF(LLVMContext &context,
&
module_
);
}
AllocaInst
*
IRBuilderBPF
::
CreateAllocaBPF
(
const
std
::
string
&
name
,
int
num_items
)
AllocaInst
*
IRBuilderBPF
::
CreateAllocaBPF
(
const
SizedType
&
stype
,
const
std
::
string
&
name
)
{
llvm
::
Type
*
ty
=
getInt64Ty
();
Value
*
array_size
=
getInt64
(
num_items
);
llvm
::
Type
*
ty
;
switch
(
stype
.
size
)
{
case
8
:
ty
=
getInt64Ty
();
break
;
case
4
:
ty
=
getInt32Ty
();
break
;
default:
abort
();
}
Function
*
parent
=
GetInsertBlock
()
->
getParent
();
BasicBlock
&
entry_block
=
parent
->
getEntryBlock
();
if
(
entry_block
.
empty
())
return
new
AllocaInst
(
ty
,
array_size
,
name
,
&
entry_block
);
return
new
AllocaInst
(
ty
,
name
,
&
entry_block
);
else
return
new
AllocaInst
(
ty
,
array_size
,
name
,
&
entry_block
.
front
());
return
new
AllocaInst
(
ty
,
name
,
&
entry_block
.
front
());
}
AllocaInst
*
IRBuilderBPF
::
CreateAllocaMapKey
(
int
bytes
,
const
std
::
string
&
name
)
{
llvm
::
Type
*
ty
=
ArrayType
::
get
(
getInt8Ty
(),
bytes
);
Value
*
array_size
=
getInt64
(
bytes
);
Function
*
parent
=
GetInsertBlock
()
->
getParent
();
BasicBlock
&
entry_block
=
parent
->
getEntryBlock
();
if
(
entry_block
.
empty
())
return
new
AllocaInst
(
ty
,
name
,
&
entry_block
);
else
return
new
AllocaInst
(
ty
,
name
,
&
entry_block
.
front
());
}
CallInst
*
IRBuilderBPF
::
CreateBpfPseudoCall
(
int
mapfd
)
...
...
@@ -72,7 +94,7 @@ LoadInst *IRBuilderBPF::CreateMapLookupElem(Map &map, AllocaInst *key)
BasicBlock
*
lookup_failure_block
=
BasicBlock
::
Create
(
module_
.
getContext
(),
"lookup_failure"
,
parent
);
BasicBlock
*
lookup_merge_block
=
BasicBlock
::
Create
(
module_
.
getContext
(),
"lookup_merge"
,
parent
);
Value
*
value
=
CreateAllocaBPF
(
"lookup_elem_val"
);
Value
*
value
=
CreateAllocaBPF
(
SizedType
(
Type
::
integer
,
8
),
"lookup_elem_val"
);
Value
*
condition
=
CreateICmpNE
(
CreateIntCast
(
call
,
getInt8PtrTy
(),
true
),
ConstantExpr
::
getCast
(
Instruction
::
IntToPtr
,
getInt64
(
0
),
getInt8PtrTy
()),
...
...
src/irbuilderbpf.h
View file @
e20808ff
...
...
@@ -2,6 +2,7 @@
#include "ast.h"
#include "bpftrace.h"
#include "types.h"
#include <llvm/IR/IRBuilder.h>
...
...
@@ -17,7 +18,8 @@ public:
Module
&
module
,
BPFtrace
&
bpftrace
);
AllocaInst
*
CreateAllocaBPF
(
const
std
::
string
&
name
=
""
,
int
num_items
=
1
);
AllocaInst
*
CreateAllocaBPF
(
const
SizedType
&
stype
,
const
std
::
string
&
name
=
""
);
AllocaInst
*
CreateAllocaMapKey
(
int
bytes
,
const
std
::
string
&
name
=
""
);
CallInst
*
CreateBpfPseudoCall
(
int
mapfd
);
CallInst
*
CreateBpfPseudoCall
(
Map
&
map
);
LoadInst
*
CreateMapLookupElem
(
Map
&
map
,
AllocaInst
*
key
);
...
...
src/map.cpp
View file @
e20808ff
...
...
@@ -6,16 +6,16 @@
namespace
bpftrace
{
Map
::
Map
(
std
::
string
&
name
,
Type
type
,
MapKey
key
)
Map
::
Map
(
const
std
::
string
&
name
,
const
SizedType
&
type
,
const
MapKey
&
key
)
:
name_
(
name
),
type_
(
type
),
key_
(
key
)
{
int
key_size
=
key
.
size
();
if
(
type
==
Type
::
quantize
)
if
(
type
.
type
==
Type
::
quantize
)
key_size
+=
8
;
if
(
key_size
==
0
)
key_size
=
8
;
int
value_size
=
8
;
int
value_size
=
type
.
size
;
int
max_entries
=
128
;
int
flags
=
0
;
mapfd_
=
bpf_create_map
(
BPF_MAP_TYPE_HASH
,
key_size
,
value_size
,
max_entries
,
flags
);
...
...
@@ -25,7 +25,7 @@ Map::Map(std::string &name, Type type, MapKey key)
}
}
Map
::
Map
(
std
::
string
name
)
:
name_
(
name
)
Map
::
Map
(
const
std
::
string
&
name
)
:
name_
(
name
)
{
// Only used for creating maps for storing stack IDs
int
key_size
=
4
;
...
...
src/map.h
View file @
e20808ff
...
...
@@ -11,15 +11,15 @@ namespace bpftrace {
class
Map
{
public:
Map
(
std
::
string
&
name
,
Type
type
,
MapKey
key
);
Map
(
std
::
string
name
);
Map
(
const
std
::
string
&
name
,
const
SizedType
&
type
,
const
MapKey
&
key
);
Map
(
const
std
::
string
&
name
);
~
Map
();
Map
(
const
Map
&
)
=
delete
;
Map
&
operator
=
(
const
Map
&
)
=
delete
;
int
mapfd_
;
std
::
string
name_
;
Type
type_
;
Sized
Type
type_
;
MapKey
key_
;
};
...
...
src/mapkey.cpp
View file @
e20808ff
...
...
@@ -42,17 +42,17 @@ std::string MapKey::argument_value_list(const BPFtrace &bpftrace,
int
offset
=
0
;
for
(
size_t
i
=
0
;
i
<
n
-
1
;
i
++
)
{
const
MapKeyArgument
&
arg
=
args_
.
at
(
i
);
const
SizedType
&
arg
=
args_
.
at
(
i
);
list
<<
argument_value
(
bpftrace
,
arg
,
&
data
.
at
(
offset
))
<<
", "
;
offset
+=
arg
.
size
;
}
const
MapKeyArgument
&
arg
=
args_
.
at
(
n
-
1
);
const
SizedType
&
arg
=
args_
.
at
(
n
-
1
);
list
<<
argument_value
(
bpftrace
,
arg
,
&
data
.
at
(
offset
))
<<
"]"
;
return
list
.
str
();
}
std
::
string
MapKey
::
argument_value
(
const
BPFtrace
&
bpftrace
,
const
MapKeyArgument
&
arg
,
const
SizedType
&
arg
,
const
void
*
data
)
{
switch
(
arg
.
type
)
...
...
src/mapkey.h
View file @
e20808ff
...
...
@@ -12,7 +12,7 @@ class BPFtrace;
class
MapKey
{
public:
std
::
vector
<
MapKeyArgument
>
args_
;
std
::
vector
<
SizedType
>
args_
;
bool
operator
!=
(
const
MapKey
&
k
)
const
;
...
...
@@ -23,7 +23,7 @@ public:
private:
static
std
::
string
argument_value
(
const
BPFtrace
&
bpftrace
,
const
MapKeyArgument
&
arg
,
const
SizedType
&
arg
,
const
void
*
data
);
};
...
...
src/semantic_analyser.cpp
View file @
e20808ff
...
...
@@ -8,9 +8,9 @@
namespace
bpftrace
{
namespace
ast
{
void
SemanticAnalyser
::
visit
(
Integer
&
)
void
SemanticAnalyser
::
visit
(
Integer
&
integer
)
{
type_
=
Type
::
integer
;
integer
.
type
=
SizedType
(
Type
::
integer
,
8
)
;
}
void
SemanticAnalyser
::
visit
(
Builtin
&
builtin
)
...
...
@@ -21,14 +21,14 @@ void SemanticAnalyser::visit(Builtin &builtin)
builtin
.
ident
==
"uid"
||
builtin
.
ident
==
"gid"
||
builtin
.
ident
==
"retval"
)
{
type_
=
Type
::
integer
;
builtin
.
type
=
SizedType
(
Type
::
integer
,
8
)
;
}
else
if
(
builtin
.
ident
==
"stack"
)
{
type_
=
Type
::
stack
;
builtin
.
type
=
SizedType
(
Type
::
stack
,
8
)
;
needs_stackid_map_
=
true
;
}
else
if
(
builtin
.
ident
==
"ustack"
)
{
type_
=
Type
::
ustack
;
builtin
.
type
=
SizedType
(
Type
::
ustack
,
8
)
;
needs_stackid_map_
=
true
;
}
else
if
(
!
builtin
.
ident
.
compare
(
0
,
3
,
"arg"
)
&&
builtin
.
ident
.
size
()
==
4
&&
...
...
@@ -36,10 +36,10 @@ void SemanticAnalyser::visit(Builtin &builtin)
int
arg_num
=
atoi
(
builtin
.
ident
.
substr
(
3
).
c_str
());
if
(
arg_num
>
arch
::
max_arg
())
err_
<<
arch
::
name
()
<<
" doesn't support "
<<
builtin
.
ident
<<
std
::
endl
;
type_
=
Type
::
integer
;
builtin
.
type
=
SizedType
(
Type
::
integer
,
8
)
;
}
else
{
type_
=
Type
::
none
;
builtin
.
type
=
SizedType
(
Type
::
none
,
0
)
;
err_
<<
"Unknown builtin: '"
<<
builtin
.
ident
<<
"'"
<<
std
::
endl
;
}
}
...
...
@@ -59,18 +59,18 @@ void SemanticAnalyser::visit(Call &call)
err_
<<
"quantize() should take 1 argument ("
;
err_
<<
nargs
<<
" provided)"
<<
std
::
endl
;
}
if
(
type_
!=
Type
::
integer
)
{
if
(
call
.
vargs
->
at
(
0
)
->
type
.
type
!=
Type
::
integer
)
{
err_
<<
"quantize() only supports integer arguments"
;
err_
<<
" ("
<<
type_
<<
" provided)"
<<
std
::
endl
;
err_
<<
" ("
<<
call
.
vargs
->
at
(
0
)
->
type
.
type
<<
" provided)"
<<
std
::
endl
;
}
type_
=
Type
::
quantize
;
call
.
type
=
SizedType
(
Type
::
quantize
,
8
)
;
}
else
if
(
call
.
func
==
"count"
)
{
if
(
nargs
!=
0
)
{
err_
<<
"count() should take 0 arguments ("
;
err_
<<
nargs
<<
" provided)"
<<
std
::
endl
;
}
type_
=
Type
::
count
;
call
.
type
=
SizedType
(
Type
::
count
,
8
)
;
}
else
if
(
call
.
func
==
"delete"
)
{
if
(
nargs
!=
0
)
{
...
...
@@ -80,7 +80,7 @@ void SemanticAnalyser::visit(Call &call)
// Don't assign a type
}
else
{
type_
=
Type
::
none
;
call
.
type
=
SizedType
(
Type
::
none
,
0
)
;
err_
<<
"Unknown function: '"
<<
call
.
func
<<
"'"
<<
std
::
endl
;
}
}
...
...
@@ -91,7 +91,7 @@ void SemanticAnalyser::visit(Map &map)
if
(
map
.
vargs
)
{
for
(
Expression
*
expr
:
*
map
.
vargs
)
{
expr
->
accept
(
*
this
);
key
.
args_
.
push_back
({
type_
,
8
});
key
.
args_
.
push_back
({
expr
->
type
.
type
,
expr
->
type
.
size
});
}
}
...
...
@@ -112,23 +112,22 @@ void SemanticAnalyser::visit(Map &map)
auto
search_val
=
map_val_
.
find
(
map
.
ident
);
if
(
search_val
!=
map_val_
.
end
())
{
type_
=
search_val
->
second
;
map
.
type
=
search_val
->
second
;
}
else
{
if
(
is_final_pass
())
{
err_
<<
"Undefined map: "
<<
map
.
ident
<<
std
::
endl
;
}
type_
=
Type
::
none
;
map
.
type
=
SizedType
(
Type
::
none
,
0
)
;
}
}
void
SemanticAnalyser
::
visit
(
Binop
&
binop
)
{
Type
lhs
,
rhs
;
binop
.
left
->
accept
(
*
this
);
lhs
=
type_
;
binop
.
right
->
accept
(
*
this
);
rhs
=
type_
;
Type
&
lhs
=
binop
.
left
->
type
.
type
;
Type
&
rhs
=
binop
.
right
->
type
.
type
;
if
(
is_final_pass
()
&&
lhs
!=
rhs
)
{
err_
<<
"Type mismatch for '"
<<
opstr
(
binop
)
<<
"': "
;
...
...
@@ -136,18 +135,18 @@ void SemanticAnalyser::visit(Binop &binop)
err_
<<
"with '"
<<
rhs
<<
"'"
<<
std
::
endl
;
}
type_
=
Type
::
integer
;
binop
.
type
=
SizedType
(
Type
::
integer
,
8
)
;
}
void
SemanticAnalyser
::
visit
(
Unop
&
unop
)
{
unop
.
expr
->
accept
(
*
this
);
if
(
type_
!=
Type
::
integer
)
{
err_
<<
"The "
<<
opstr
(
unop
)
<<
" operator can not be used on expressions of type "
<<
type_
<<
std
::
endl
;
if
(
unop
.
expr
->
type
.
type
!=
Type
::
integer
)
{
err_
<<
"The "
<<
opstr
(
unop
)
<<
" operator can not be used on expressions of type "
<<
unop
.
expr
->
type
<<
std
::
endl
;
}
type_
=
Type
::
integer
;
unop
.
type
=
SizedType
(
Type
::
integer
,
8
)
;
}
void
SemanticAnalyser
::
visit
(
ExprStatement
&
expr
)
...
...
@@ -163,24 +162,24 @@ void SemanticAnalyser::visit(AssignMapStatement &assignment)
std
::
string
map_ident
=
assignment
.
map
->
ident
;
auto
search
=
map_val_
.
find
(
map_ident
);
if
(
search
!=
map_val_
.
end
())
{
if
(
search
->
second
==
Type
::
none
)
{
if
(
search
->
second
.
type
==
Type
::
none
)
{
if
(
is_final_pass
())
{
err_
<<
"Undefined map: "
<<
map_ident
<<
std
::
endl
;
}
else
{
search
->
second
=
type_
;
search
->
second
=
assignment
.
expr
->
type
;
}
}
else
if
(
search
->
second
!=
type_
)
{
else
if
(
search
->
second
.
type
!=
assignment
.
expr
->
type
.
type
)
{
err_
<<
"Type mismatch for "
<<
map_ident
<<
": "
;
err_
<<
"trying to assign value of type '"
<<
type_
;
err_
<<
"trying to assign value of type '"
<<
assignment
.
expr
->
type
;
err_
<<
"'
\n\t
when map already contains a value of type '"
;
err_
<<
search
->
second
<<
"'
\n
"
<<
std
::
endl
;
}
}
else
{
// This map hasn't been seen before
map_val_
.
insert
({
map_ident
,
type_
});
map_val_
.
insert
({
map_ident
,
assignment
.
expr
->
type
});
}
}
...
...
@@ -192,15 +191,15 @@ void SemanticAnalyser::visit(AssignMapCallStatement &assignment)
std
::
string
map_ident
=
assignment
.
map
->
ident
;
auto
search
=
map_val_
.
find
(
map_ident
);
if
(
search
!=
map_val_
.
end
())
{
if
(
search
->
second
==
Type
::
none
)
{
if
(
search
->
second
.
type
==
Type
::
none
)
{
if
(
is_final_pass
())
{
err_
<<
"Undefined map: "
<<
map_ident
<<
std
::
endl
;
}
else
{
search
->
second
=
type_
;
search
->
second
=
assignment
.
call
->
type
;
}
}
else
if
(
search
->
second
!=
type_
)
{
else
if
(
search
->
second
.
type
!=
assignment
.
call
->
type
.
type
)
{
err_
<<
"Type mismatch for "
<<
map_ident
<<
": "
;
err_
<<
"trying to assign result of '"
<<
assignment
.
call
->
func
;
err_
<<
"()'
\n\t
when map already contains a value of type '"
;
...
...
@@ -209,7 +208,7 @@ void SemanticAnalyser::visit(AssignMapCallStatement &assignment)
}
else
{
// This map hasn't been seen before
map_val_
.
insert
({
map_ident
,
type_
});
map_val_
.
insert
({
map_ident
,
assignment
.
call
->
type
});
}
}
...
...
@@ -261,7 +260,7 @@ int SemanticAnalyser::create_maps()
for
(
auto
&
map_val
:
map_val_
)
{
std
::
string
map_name
=
map_val
.
first
;
Type
type
=
map_val
.
second
;
Sized
Type
type
=
map_val
.
second
;
auto
search_args
=
map_key_
.
find
(
map_name
);
if
(
search_args
==
map_key_
.
end
())
...
...
src/semantic_analyser.h
View file @
e20808ff
...
...
@@ -43,9 +43,7 @@ private:
bool
is_final_pass
()
const
;
using
Type
=
bpftrace
::
Type
;
Type
type_
;
std
::
map
<
std
::
string
,
Type
>
map_val_
;
std
::
map
<
std
::
string
,
SizedType
>
map_val_
;
std
::
map
<
std
::
string
,
MapKey
>
map_key_
;
bool
needs_stackid_map_
=
false
;
};
...
...
src/types.cpp
View file @
e20808ff
...
...
@@ -10,15 +10,15 @@ std::ostream &operator<<(std::ostream &os, Type type)
return
os
;
}
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
MapKeyArgument
arg
)
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
SizedType
&
type
)
{
os
<<
arg
.
type
;
os
<<
type
.
type
;
return
os
;
}
bool
MapKeyArgument
::
operator
==
(
const
MapKeyArgument
&
a
)
const
bool
SizedType
::
operator
==
(
const
SizedType
&
t
)
const
{
return
type
==
a
.
type
&&
size
==
a
.
size
;
return
type
==
t
.
type
&&
size
==
t
.
size
;
}
std
::
string
typestr
(
Type
t
)
...
...
@@ -35,28 +35,4 @@ std::string typestr(Type t)
}
}
bpf_probe_attach_type
attachtype
(
ProbeType
t
)
{
switch
(
t
)
{
case
ProbeType
:
:
kprobe
:
return
BPF_PROBE_ENTRY
;
break
;
case
ProbeType
:
:
kretprobe
:
return
BPF_PROBE_RETURN
;
break
;
case
ProbeType
:
:
uprobe
:
return
BPF_PROBE_ENTRY
;
break
;
case
ProbeType
:
:
uretprobe
:
return
BPF_PROBE_RETURN
;
break
;
default:
abort
();
}
}
bpf_prog_type
progtype
(
ProbeType
t
)
{
switch
(
t
)
{
case
ProbeType
:
:
kprobe
:
return
BPF_PROG_TYPE_KPROBE
;
break
;
case
ProbeType
:
:
kretprobe
:
return
BPF_PROG_TYPE_KPROBE
;
break
;
case
ProbeType
:
:
uprobe
:
return
BPF_PROG_TYPE_KPROBE
;
break
;
case
ProbeType
:
:
uretprobe
:
return
BPF_PROG_TYPE_KPROBE
;
break
;
default:
abort
();
}
}
}
// namespace bpftrace
src/types.h
View file @
e20808ff
...
...
@@ -6,8 +6,6 @@
#include <vector>
#include <unistd.h>
#include "libbpf.h"
namespace
bpftrace
{
const
int
MAX_STACK_SIZE
=
32
;
...
...
@@ -20,20 +18,23 @@ enum class Type
count
,
stack
,
ustack
,
string
,
};
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
Type
type
);
class
MapKeyArgument
class
SizedType
{
public:
SizedType
()
:
type
(
Type
::
none
),
size
(
0
)
{
}
SizedType
(
Type
type
,
size_t
size
)
:
type
(
type
),
size
(
size
)
{
}
Type
type
;
size_t
size
;
bool
operator
==
(
const
MapKeyArgument
&
a
)
const
;
bool
operator
==
(
const
SizedType
&
t
)
const
;
};
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
MapKeyArgument
arg
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
SizedType
&
type
);
enum
class
ProbeType
{
...
...
@@ -44,8 +45,6 @@ enum class ProbeType
};
std
::
string
typestr
(
Type
t
);
bpf_probe_attach_type
attachtype
(
ProbeType
t
);
bpf_prog_type
progtype
(
ProbeType
t
);
class
Probe
{
...
...
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