Commit 65c52ba5 authored by 4ast's avatar 4ast

Merge pull request #303 from iovisor/bblanco_dev

Improve json type support for misc struct/union types
parents fbe34c99 fe88e5a2
...@@ -67,10 +67,7 @@ bool BMapDeclVisitor::VisitRecordDecl(RecordDecl *D) { ...@@ -67,10 +67,7 @@ bool BMapDeclVisitor::VisitRecordDecl(RecordDecl *D) {
result_ += "\", ["; result_ += "\", [";
for (auto F : D->getDefinition()->fields()) { for (auto F : D->getDefinition()->fields()) {
result_ += "["; result_ += "[";
if (F->getType()->isPointerType()) TraverseDecl(F);
result_ += "\"" + F->getName().str() + "\", \"unsigned long long\"";
else
TraverseDecl(F);
if (const ConstantArrayType *T = dyn_cast<ConstantArrayType>(F->getType())) if (const ConstantArrayType *T = dyn_cast<ConstantArrayType>(F->getType()))
result_ += ", [" + T->getSize().toString(10, false) + "]"; result_ += ", [" + T->getSize().toString(10, false) + "]";
if (F->isBitField()) if (F->isBitField())
...@@ -79,9 +76,19 @@ bool BMapDeclVisitor::VisitRecordDecl(RecordDecl *D) { ...@@ -79,9 +76,19 @@ bool BMapDeclVisitor::VisitRecordDecl(RecordDecl *D) {
} }
if (!D->getDefinition()->field_empty()) if (!D->getDefinition()->field_empty())
result_.erase(result_.end() - 2); result_.erase(result_.end() - 2);
result_ += "]]"; result_ += "]";
if (D->isUnion())
result_ += ", \"union\"";
else if (D->isStruct())
result_ += ", \"struct\"";
result_ += "]";
return true; return true;
} }
// pointer to anything should be treated as terminal, don't recurse further
bool BMapDeclVisitor::VisitPointerType(const PointerType *T) {
result_ += "\"unsigned long long\"";
return false;
}
bool BMapDeclVisitor::VisitTagType(const TagType *T) { bool BMapDeclVisitor::VisitTagType(const TagType *T) {
return TraverseDecl(T->getDecl()->getDefinition()); return TraverseDecl(T->getDecl()->getDefinition());
} }
...@@ -510,22 +517,32 @@ bool BTypeVisitor::VisitVarDecl(VarDecl *Decl) { ...@@ -510,22 +517,32 @@ bool BTypeVisitor::VisitVarDecl(VarDecl *Decl) {
sscanf(un.release, "%d.%d.", &major, &minor); sscanf(un.release, "%d.%d.", &major, &minor);
} }
TableDesc table; TableDesc table = {};
table.name = Decl->getName(); table.name = Decl->getName();
unsigned i = 0; unsigned i = 0;
for (auto F : RD->fields()) { for (auto F : RD->fields()) {
size_t sz = C.getTypeSize(F->getType()) >> 3; size_t sz = C.getTypeSize(F->getType()) >> 3;
if (F->getName() == "key") { if (F->getName() == "key") {
if (sz == 0) {
unsigned diag_id = C.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error,
"invalid zero-sized leaf");
C.getDiagnostics().Report(F->getLocStart(), diag_id);
return false;
}
table.key_size = sz; table.key_size = sz;
BMapDeclVisitor visitor(C, table.key_desc); BMapDeclVisitor visitor(C, table.key_desc);
if (!visitor.TraverseType(F->getType())) visitor.TraverseType(F->getType());
return false;
} else if (F->getName() == "leaf") { } else if (F->getName() == "leaf") {
if (sz == 0) {
unsigned diag_id = C.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error,
"invalid zero-sized leaf");
C.getDiagnostics().Report(F->getLocStart(), diag_id);
return false;
}
table.leaf_size = sz; table.leaf_size = sz;
BMapDeclVisitor visitor(C, table.leaf_desc); BMapDeclVisitor visitor(C, table.leaf_desc);
if (!visitor.TraverseType(F->getType())) visitor.TraverseType(F->getType());
return false;
} else if (F->getName() == "data") { } else if (F->getName() == "data") {
table.max_entries = sz / table.leaf_size; table.max_entries = sz / table.leaf_size;
} }
......
...@@ -49,6 +49,7 @@ class BMapDeclVisitor : public clang::RecursiveASTVisitor<BMapDeclVisitor> { ...@@ -49,6 +49,7 @@ class BMapDeclVisitor : public clang::RecursiveASTVisitor<BMapDeclVisitor> {
bool VisitBuiltinType(const clang::BuiltinType *T); bool VisitBuiltinType(const clang::BuiltinType *T);
bool VisitTypedefType(const clang::TypedefType *T); bool VisitTypedefType(const clang::TypedefType *T);
bool VisitTagType(const clang::TagType *T); bool VisitTagType(const clang::TagType *T);
bool VisitPointerType(const clang::PointerType *T);
private: private:
clang::ASTContext &C; clang::ASTContext &C;
std::string &result_; std::string &result_;
......
...@@ -518,7 +518,13 @@ class BPF(object): ...@@ -518,7 +518,13 @@ class BPF(object):
fields.append((t[0], BPF._decode_table_type(t[1]), t[2])) fields.append((t[0], BPF._decode_table_type(t[1]), t[2]))
else: else:
raise Exception("Failed to decode type %s" % str(t)) raise Exception("Failed to decode type %s" % str(t))
cls = type(str(desc[0]), (ct.Structure,), dict(_fields_=fields)) base = ct.Structure
if len(desc) > 2:
if desc[2] == u"union":
base = ct.Union
elif desc[2] == u"struct":
base = ct.Structure
cls = type(str(desc[0]), (base,), dict(_fields_=fields))
return cls return cls
def get_table(self, name, keytype=None, leaftype=None): def get_table(self, name, keytype=None, leaftype=None):
......
...@@ -247,7 +247,7 @@ int kprobe____kmalloc(struct pt_regs *ctx, size_t size) { ...@@ -247,7 +247,7 @@ int kprobe____kmalloc(struct pt_regs *ctx, size_t size) {
if (leaf) if (leaf)
leaf->size += size; leaf->size += size;
return 0; return 0;
}""", debug=4) }""")
def test_unop_probe_read(self): def test_unop_probe_read(self):
text = """ text = """
...@@ -263,5 +263,29 @@ int trace_entry(struct pt_regs *ctx, struct request *req) { ...@@ -263,5 +263,29 @@ int trace_entry(struct pt_regs *ctx, struct request *req) {
b = BPF(text=text) b = BPF(text=text)
fn = b.load_func("trace_entry", BPF.KPROBE) fn = b.load_func("trace_entry", BPF.KPROBE)
def test_complex_leaf_types(self):
text = """
struct list;
struct list {
struct list *selfp;
struct list *another_selfp;
struct list *selfp_array[2];
};
struct empty {
};
union emptyu {
struct empty *em1;
struct empty em2;
struct empty em3;
struct empty em4;
};
BPF_TABLE("array", int, struct list, t1, 1);
BPF_TABLE("array", int, struct list *, t2, 1);
BPF_TABLE("array", int, union emptyu, t3, 1);
"""
b = BPF(text=text)
import ctypes
self.assertEqual(ctypes.sizeof(b["t3"].Leaf), 8)
if __name__ == "__main__": if __name__ == "__main__":
main() main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment