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
b493aa6c
Commit
b493aa6c
authored
May 10, 2017
by
4ast
Committed by
GitHub
May 10, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1167 from iovisor/rw_finalize_defer
Use late-binding to finalize snprintf/sscanf
parents
4033200e
dadea22d
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
101 additions
and
138 deletions
+101
-138
src/cc/BPFTable.h
src/cc/BPFTable.h
+10
-24
src/cc/bpf_module.cc
src/cc/bpf_module.cc
+77
-96
src/cc/bpf_module.h
src/cc/bpf_module.h
+10
-4
src/cc/table_desc.h
src/cc/table_desc.h
+4
-14
No files found.
src/cc/BPFTable.h
View file @
b493aa6c
...
...
@@ -39,41 +39,27 @@ class BPFTableBase {
size_t
capacity
()
{
return
desc
.
max_entries
;
}
StatusTuple
string_to_key
(
const
std
::
string
&
key_str
,
KeyType
*
key
)
{
if
(
!
desc
.
key_sscanf
)
return
StatusTuple
(
-
1
,
"Key sscanf not available"
);
if
(
desc
.
key_sscanf
(
key_str
.
c_str
(),
key
)
!=
0
)
return
StatusTuple
(
-
1
,
"Error on key_sscanff: %s"
,
std
::
strerror
(
errno
));
return
StatusTuple
(
0
);
return
desc
.
key_sscanf
(
key_str
.
c_str
(),
key
);
}
StatusTuple
string_to_leaf
(
const
std
::
string
&
value_str
,
ValueType
*
value
)
{
if
(
!
desc
.
leaf_sscanf
)
return
StatusTuple
(
-
1
,
"Leaf sscanf not available"
);
if
(
desc
.
leaf_sscanf
(
value_str
.
c_str
(),
value
)
!=
0
)
return
StatusTuple
(
-
1
,
"Error on leaf_sscanff: %s"
,
std
::
strerror
(
errno
));
return
StatusTuple
(
0
);
return
desc
.
leaf_sscanf
(
value_str
.
c_str
(),
value
);
}
StatusTuple
key_to_string
(
const
KeyType
*
key
,
std
::
string
&
key_str
)
{
char
buf
[
8
*
desc
.
key_size
];
if
(
!
desc
.
key_snprintf
)
return
StatusTuple
(
-
1
,
"Key snprintf not available"
);
if
(
desc
.
key_snprintf
(
buf
,
sizeof
(
buf
),
key
)
<
0
)
return
StatusTuple
(
-
1
,
"Error on key_sprintf: %s"
,
std
::
strerror
(
errno
));
StatusTuple
rc
=
desc
.
key_snprintf
(
buf
,
sizeof
(
buf
),
key
);
if
(
!
rc
.
code
())
key_str
.
assign
(
buf
);
return
StatusTuple
(
0
)
;
return
rc
;
}
StatusTuple
leaf_to_string
(
const
ValueType
*
value
,
std
::
string
&
value_str
)
{
char
buf
[
8
*
desc
.
leaf_size
];
if
(
!
desc
.
leaf_snprintf
)
return
StatusTuple
(
-
1
,
"Leaf snprintf not available"
);
if
(
desc
.
leaf_snprintf
(
buf
,
sizeof
(
buf
),
value
)
<
0
)
return
StatusTuple
(
-
1
,
"Error on leaf_sprintf: %s"
,
std
::
strerror
(
errno
));
StatusTuple
rc
=
desc
.
leaf_snprintf
(
buf
,
sizeof
(
buf
),
value
);
if
(
!
rc
.
code
())
value_str
.
assign
(
buf
);
return
StatusTuple
(
0
)
;
return
rc
;
}
protected:
...
...
src/cc/bpf_module.cc
View file @
b493aa6c
...
...
@@ -116,18 +116,25 @@ BPFModule::BPFModule(unsigned flags, TableStorage *ts)
}
}
static
StatusTuple
unimplemented_sscanf
(
const
char
*
,
void
*
)
{
return
StatusTuple
(
-
1
,
"sscanf unimplemented"
);
}
static
StatusTuple
unimplemented_snprintf
(
char
*
,
size_t
,
const
void
*
)
{
return
StatusTuple
(
-
1
,
"snprintf unimplemented"
);
}
BPFModule
::~
BPFModule
()
{
for
(
auto
&
v
:
tables_
)
{
v
->
key_sscanf
=
unimplemented_sscanf
;
v
->
leaf_sscanf
=
unimplemented_sscanf
;
v
->
key_snprintf
=
unimplemented_snprintf
;
v
->
leaf_snprintf
=
unimplemented_snprintf
;
}
engine_
.
reset
();
rw_engine_
.
reset
();
ctx_
.
reset
();
for
(
auto
&
v
:
tables_
)
{
v
->
key_sscanf
=
nullptr
;
v
->
leaf_sscanf
=
nullptr
;
v
->
key_snprintf
=
nullptr
;
v
->
leaf_snprintf
=
nullptr
;
}
ts_
->
DeletePrefix
(
Path
({
id_
}));
}
...
...
@@ -189,7 +196,7 @@ static void parse_type(IRBuilder<> &B, vector<Value *> *args, string *fmt,
}
}
Function
*
BPFModule
::
make_reader
(
Module
*
mod
,
Type
*
type
)
{
string
BPFModule
::
make_reader
(
Module
*
mod
,
Type
*
type
)
{
auto
fn_it
=
readers_
.
find
(
type
);
if
(
fn_it
!=
readers_
.
end
())
return
fn_it
->
second
;
...
...
@@ -202,10 +209,11 @@ Function * BPFModule::make_reader(Module *mod, Type *type) {
IRBuilder
<>
B
(
*
ctx_
);
string
name
=
"reader"
+
std
::
to_string
(
readers_
.
size
());
vector
<
Type
*>
fn_args
({
B
.
getInt8PtrTy
(),
PointerType
::
getUnqual
(
type
)});
FunctionType
*
fn_type
=
FunctionType
::
get
(
B
.
getInt32Ty
(),
fn_args
,
/*isVarArg=*/
false
);
Function
*
fn
=
Function
::
Create
(
fn_type
,
GlobalValue
::
ExternalLinkage
,
"reader"
+
std
::
to_string
(
readers_
.
size
())
,
mod
);
Function
*
fn
=
Function
::
Create
(
fn_type
,
GlobalValue
::
ExternalLinkage
,
name
,
mod
);
auto
arg_it
=
fn
->
arg_begin
();
Argument
*
arg_in
=
&*
arg_it
;
++
arg_it
;
...
...
@@ -251,11 +259,11 @@ Function * BPFModule::make_reader(Module *mod, Type *type) {
B
.
SetInsertPoint
(
label_exit
);
B
.
CreateRet
(
B
.
getInt32
(
0
));
readers_
[
type
]
=
fn
;
return
fn
;
readers_
[
type
]
=
name
;
return
name
;
}
Function
*
BPFModule
::
make_writer
(
Module
*
mod
,
Type
*
type
)
{
string
BPFModule
::
make_writer
(
Module
*
mod
,
Type
*
type
)
{
auto
fn_it
=
writers_
.
find
(
type
);
if
(
fn_it
!=
writers_
.
end
())
return
fn_it
->
second
;
...
...
@@ -266,10 +274,11 @@ Function * BPFModule::make_writer(Module *mod, Type *type) {
IRBuilder
<>
B
(
*
ctx_
);
string
name
=
"writer"
+
std
::
to_string
(
writers_
.
size
());
vector
<
Type
*>
fn_args
({
B
.
getInt8PtrTy
(),
B
.
getInt64Ty
(),
PointerType
::
getUnqual
(
type
)});
FunctionType
*
fn_type
=
FunctionType
::
get
(
B
.
getInt32Ty
(),
fn_args
,
/*isVarArg=*/
false
);
Function
*
fn
=
Function
::
Create
(
fn_type
,
GlobalValue
::
ExternalLinkage
,
"writer"
+
std
::
to_string
(
writers_
.
size
())
,
mod
);
Function
*
fn
=
Function
::
Create
(
fn_type
,
GlobalValue
::
ExternalLinkage
,
name
,
mod
);
auto
arg_it
=
fn
->
arg_begin
();
Argument
*
arg_out
=
&*
arg_it
;
++
arg_it
;
...
...
@@ -308,8 +317,8 @@ Function * BPFModule::make_writer(Module *mod, Type *type) {
B
.
CreateRet
(
call
);
writers_
[
type
]
=
fn
;
return
fn
;
writers_
[
type
]
=
name
;
return
name
;
}
unique_ptr
<
ExecutionEngine
>
BPFModule
::
finalize_rw
(
unique_ptr
<
Module
>
m
)
{
...
...
@@ -355,15 +364,6 @@ int BPFModule::annotate() {
// separate module to hold the reader functions
auto
m
=
ebpf
::
make_unique
<
Module
>
(
"sscanf"
,
*
ctx_
);
struct
llvmfnpointers
{
llvm
::
Function
*
key_sscanf
;
llvm
::
Function
*
leaf_sscanf
;
llvm
::
Function
*
key_snprintf
;
llvm
::
Function
*
leaf_snprintf
;
};
std
::
map
<
TableDesc
*
,
llvmfnpointers
>
ptrs_map
;
size_t
id
=
0
;
Path
path
({
id_
});
for
(
auto
it
=
ts_
->
lower_bound
(
path
),
up
=
ts_
->
upper_bound
(
path
);
it
!=
up
;
++
it
)
{
...
...
@@ -378,48 +378,53 @@ int BPFModule::annotate() {
Type
*
key_type
=
st
->
elements
()[
0
];
Type
*
leaf_type
=
st
->
elements
()[
1
];
llvmfnpointers
fns
;
fns
.
key_sscanf
=
make_reader
(
&*
m
,
key_type
);
if
(
!
fns
.
key_sscanf
)
errs
()
<<
"Failed to compile sscanf for "
<<
*
key_type
<<
"
\n
"
;
fns
.
leaf_sscanf
=
make_reader
(
&*
m
,
leaf_type
);
if
(
!
fns
.
leaf_sscanf
)
errs
()
<<
"Failed to compile sscanf for "
<<
*
leaf_type
<<
"
\n
"
;
fns
.
key_snprintf
=
make_writer
(
&*
m
,
key_type
);
if
(
!
fns
.
key_snprintf
)
errs
()
<<
"Failed to compile snprintf for "
<<
*
key_type
<<
"
\n
"
;
fns
.
leaf_snprintf
=
make_writer
(
&*
m
,
leaf_type
);
if
(
!
fns
.
leaf_snprintf
)
errs
()
<<
"Failed to compile snprintf for "
<<
*
leaf_type
<<
"
\n
"
;
ptrs_map
[
&
it
->
second
]
=
fns
;
using
std
::
placeholders
::
_1
;
using
std
::
placeholders
::
_2
;
using
std
::
placeholders
::
_3
;
table
.
key_sscanf
=
std
::
bind
(
&
BPFModule
::
sscanf
,
this
,
make_reader
(
&*
m
,
key_type
),
_1
,
_2
);
table
.
leaf_sscanf
=
std
::
bind
(
&
BPFModule
::
sscanf
,
this
,
make_reader
(
&*
m
,
leaf_type
),
_1
,
_2
);
table
.
key_snprintf
=
std
::
bind
(
&
BPFModule
::
snprintf
,
this
,
make_writer
(
&*
m
,
key_type
),
_1
,
_2
,
_3
);
table
.
leaf_snprintf
=
std
::
bind
(
&
BPFModule
::
snprintf
,
this
,
make_writer
(
&*
m
,
leaf_type
),
_1
,
_2
,
_3
);
}
}
}
rw_engine_
=
finalize_rw
(
move
(
m
));
if
(
rw_engine_
)
rw_engine_
->
finalizeObject
();
for
(
auto
&
it
:
ptrs_map
)
{
auto
t
=
it
.
first
;
auto
ptr
=
it
.
second
;
t
->
key_sscanf
=
(
sscanf_fn
)
rw_engine_
->
getPointerToFunction
(
ptr
.
key_sscanf
);
t
->
leaf_sscanf
=
(
sscanf_fn
)
rw_engine_
->
getPointerToFunction
(
ptr
.
leaf_sscanf
);
t
->
key_snprintf
=
(
snprintf_fn
)
rw_engine_
->
getPointerToFunction
(
ptr
.
key_snprintf
);
t
->
leaf_snprintf
=
(
snprintf_fn
)
rw_engine_
->
getPointerToFunction
(
ptr
.
leaf_snprintf
);
}
if
(
!
rw_engine_
)
return
-
1
;
return
0
;
}
StatusTuple
BPFModule
::
sscanf
(
string
fn_name
,
const
char
*
str
,
void
*
val
)
{
auto
fn
=
(
int
(
*
)(
const
char
*
,
void
*
))
rw_engine_
->
getFunctionAddress
(
fn_name
);
if
(
!
fn
)
return
StatusTuple
(
-
1
,
"sscanf not available"
);
int
rc
=
fn
(
str
,
val
);
if
(
rc
<
0
)
return
StatusTuple
(
rc
,
"error in sscanf: %s"
,
std
::
strerror
(
errno
));
return
StatusTuple
(
rc
);
}
StatusTuple
BPFModule
::
snprintf
(
string
fn_name
,
char
*
str
,
size_t
sz
,
const
void
*
val
)
{
auto
fn
=
(
int
(
*
)(
char
*
,
size_t
,
const
void
*
))
rw_engine_
->
getFunctionAddress
(
fn_name
);
if
(
!
fn
)
return
StatusTuple
(
-
1
,
"snprintf not available"
);
int
rc
=
fn
(
str
,
sz
,
val
);
if
(
rc
<
0
)
return
StatusTuple
(
rc
,
"error in snprintf: %s"
,
std
::
strerror
(
errno
));
if
((
size_t
)
rc
==
sz
)
return
StatusTuple
(
-
1
,
"buffer of size %zd too small"
,
sz
);
return
StatusTuple
(
0
);
}
void
BPFModule
::
dump_ir
(
Module
&
mod
)
{
legacy
::
PassManager
PM
;
PM
.
add
(
createPrintModulePass
(
errs
()));
...
...
@@ -649,17 +654,9 @@ int BPFModule::table_key_printf(size_t id, char *buf, size_t buflen, const void
if
(
id
>=
tables_
.
size
())
return
-
1
;
const
TableDesc
&
desc
=
*
tables_
[
id
];
if
(
!
desc
.
key_snprintf
)
{
fprintf
(
stderr
,
"Key snprintf not available
\n
"
);
return
-
1
;
}
int
rc
=
desc
.
key_snprintf
(
buf
,
buflen
,
key
);
if
(
rc
<
0
)
{
perror
(
"snprintf"
);
return
-
1
;
}
if
((
size_t
)
rc
>=
buflen
)
{
fprintf
(
stderr
,
"snprintf ran out of buffer space
\n
"
);
StatusTuple
rc
=
desc
.
key_snprintf
(
buf
,
buflen
,
key
);
if
(
rc
.
code
()
<
0
)
{
fprintf
(
stderr
,
"%s
\n
"
,
rc
.
msg
().
c_str
());
return
-
1
;
}
return
0
;
...
...
@@ -669,17 +666,9 @@ int BPFModule::table_leaf_printf(size_t id, char *buf, size_t buflen, const void
if
(
id
>=
tables_
.
size
())
return
-
1
;
const
TableDesc
&
desc
=
*
tables_
[
id
];
if
(
!
desc
.
leaf_snprintf
)
{
fprintf
(
stderr
,
"Key snprintf not available
\n
"
);
return
-
1
;
}
int
rc
=
desc
.
leaf_snprintf
(
buf
,
buflen
,
leaf
);
if
(
rc
<
0
)
{
perror
(
"snprintf"
);
return
-
1
;
}
if
((
size_t
)
rc
>=
buflen
)
{
fprintf
(
stderr
,
"snprintf ran out of buffer space
\n
"
);
StatusTuple
rc
=
desc
.
leaf_snprintf
(
buf
,
buflen
,
leaf
);
if
(
rc
.
code
()
<
0
)
{
fprintf
(
stderr
,
"%s
\n
"
,
rc
.
msg
().
c_str
());
return
-
1
;
}
return
0
;
...
...
@@ -689,13 +678,9 @@ int BPFModule::table_key_scanf(size_t id, const char *key_str, void *key) {
if
(
id
>=
tables_
.
size
())
return
-
1
;
const
TableDesc
&
desc
=
*
tables_
[
id
];
if
(
!
desc
.
key_sscanf
)
{
fprintf
(
stderr
,
"Key sscanf not available
\n
"
);
return
-
1
;
}
int
rc
=
desc
.
key_sscanf
(
key_str
,
key
);
if
(
rc
!=
0
)
{
perror
(
"sscanf"
);
StatusTuple
rc
=
desc
.
key_sscanf
(
key_str
,
key
);
if
(
rc
.
code
()
<
0
)
{
fprintf
(
stderr
,
"%s
\n
"
,
rc
.
msg
().
c_str
());
return
-
1
;
}
return
0
;
...
...
@@ -705,13 +690,9 @@ int BPFModule::table_leaf_scanf(size_t id, const char *leaf_str, void *leaf) {
if
(
id
>=
tables_
.
size
())
return
-
1
;
const
TableDesc
&
desc
=
*
tables_
[
id
];
if
(
!
desc
.
leaf_sscanf
)
{
fprintf
(
stderr
,
"Key sscanf not available
\n
"
);
return
-
1
;
}
int
rc
=
desc
.
leaf_sscanf
(
leaf_str
,
leaf
);
if
(
rc
!=
0
)
{
perror
(
"sscanf"
);
StatusTuple
rc
=
desc
.
leaf_sscanf
(
leaf_str
,
leaf
);
if
(
rc
.
code
()
<
0
)
{
fprintf
(
stderr
,
"%s
\n
"
,
rc
.
msg
().
c_str
());
return
-
1
;
}
return
0
;
...
...
src/cc/bpf_module.h
View file @
b493aa6c
...
...
@@ -22,6 +22,8 @@
#include <string>
#include <vector>
#include "bcc_exception.h"
namespace
llvm
{
class
ExecutionEngine
;
class
Function
;
...
...
@@ -44,14 +46,18 @@ class BPFModule {
int
finalize
();
int
annotate
();
std
::
unique_ptr
<
llvm
::
ExecutionEngine
>
finalize_rw
(
std
::
unique_ptr
<
llvm
::
Module
>
mod
);
llvm
::
Function
*
make_reader
(
llvm
::
Module
*
mod
,
llvm
::
Type
*
type
);
llvm
::
Function
*
make_writer
(
llvm
::
Module
*
mod
,
llvm
::
Type
*
type
);
std
::
string
make_reader
(
llvm
::
Module
*
mod
,
llvm
::
Type
*
type
);
std
::
string
make_writer
(
llvm
::
Module
*
mod
,
llvm
::
Type
*
type
);
void
dump_ir
(
llvm
::
Module
&
mod
);
int
load_file_module
(
std
::
unique_ptr
<
llvm
::
Module
>
*
mod
,
const
std
::
string
&
file
,
bool
in_memory
);
int
load_includes
(
const
std
::
string
&
text
);
int
load_cfile
(
const
std
::
string
&
file
,
bool
in_memory
,
const
char
*
cflags
[],
int
ncflags
);
int
kbuild_flags
(
const
char
*
uname_release
,
std
::
vector
<
std
::
string
>
*
cflags
);
int
run_pass_manager
(
llvm
::
Module
&
mod
);
StatusTuple
sscanf
(
std
::
string
fn_name
,
const
char
*
str
,
void
*
val
);
StatusTuple
snprintf
(
std
::
string
fn_name
,
char
*
str
,
size_t
sz
,
const
void
*
val
);
public:
BPFModule
(
unsigned
flags
,
TableStorage
*
ts
=
nullptr
);
~
BPFModule
();
...
...
@@ -106,8 +112,8 @@ class BPFModule {
std
::
vector
<
TableDesc
*>
tables_
;
std
::
map
<
std
::
string
,
size_t
>
table_names_
;
std
::
vector
<
std
::
string
>
function_names_
;
std
::
map
<
llvm
::
Type
*
,
llvm
::
Function
*
>
readers_
;
std
::
map
<
llvm
::
Type
*
,
llvm
::
Function
*
>
writers_
;
std
::
map
<
llvm
::
Type
*
,
std
::
string
>
readers_
;
std
::
map
<
llvm
::
Type
*
,
std
::
string
>
writers_
;
std
::
string
id_
;
TableStorage
*
ts_
;
std
::
unique_ptr
<
TableStorage
>
local_ts_
;
...
...
src/cc/table_desc.h
View file @
b493aa6c
...
...
@@ -18,15 +18,13 @@
#include <unistd.h>
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
#include "bcc_exception.h"
#include "common.h"
namespace
llvm
{
class
Function
;
}
namespace
clang
{
class
ASTContext
;
class
QualType
;
...
...
@@ -34,8 +32,8 @@ class QualType;
namespace
ebpf
{
typedef
int
(
*
sscanf_fn
)(
const
char
*
,
void
*
)
;
typedef
int
(
*
snprintf_fn
)(
char
*
,
size_t
,
const
void
*
)
;
typedef
std
::
function
<
StatusTuple
(
const
char
*
,
void
*
)
>
sscanf_fn
;
typedef
std
::
function
<
StatusTuple
(
char
*
,
size_t
,
const
void
*
)
>
snprintf_fn
;
/// TableDesc uniquely stores all of the runtime state for an active bpf table.
/// The copy constructor/assign operator are disabled since the file handles
...
...
@@ -68,10 +66,6 @@ class TableDesc {
leaf_size
(
0
),
max_entries
(
0
),
flags
(
0
),
key_sscanf
(
nullptr
),
leaf_sscanf
(
nullptr
),
key_snprintf
(
nullptr
),
leaf_snprintf
(
nullptr
),
is_shared
(
false
),
is_extern
(
false
)
{}
TableDesc
(
const
std
::
string
&
name
,
FileDesc
&&
fd
,
int
type
,
size_t
key_size
,
...
...
@@ -83,10 +77,6 @@ class TableDesc {
leaf_size
(
leaf_size
),
max_entries
(
max_entries
),
flags
(
flags
),
key_sscanf
(
nullptr
),
leaf_sscanf
(
nullptr
),
key_snprintf
(
nullptr
),
leaf_snprintf
(
nullptr
),
is_shared
(
false
),
is_extern
(
false
)
{}
TableDesc
(
TableDesc
&&
that
)
=
default
;
...
...
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