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
7 years ago
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
{
...
...
This diff is collapsed.
Click to expand it.
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
)
{
...
...
This diff is collapsed.
Click to expand it.
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:
...
...
This diff is collapsed.
Click to expand it.
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"
);
...
...
This diff is collapsed.
Click to expand it.
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
--
)
...
...
This diff is collapsed.
Click to expand it.
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
()),
...
...
This diff is collapsed.
Click to expand it.
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
);
...
...
This diff is collapsed.
Click to expand it.
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
;
...
...
This diff is collapsed.
Click to expand it.
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_
;
};
...
...
This diff is collapsed.
Click to expand it.
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
)
...
...
This diff is collapsed.
Click to expand it.
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
);
};
...
...
This diff is collapsed.
Click to expand it.
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
())
...
...
This diff is collapsed.
Click to expand it.
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
;
};
...
...
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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
{
...
...
This diff is collapsed.
Click to expand it.
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