From 39354092a8f24f576ae221b5dee3c2494f105939 Mon Sep 17 00:00:00 2001 From: Brenden Blanco Date: Sat, 6 Feb 2016 20:59:10 -0800 Subject: [PATCH] Support array and pointer types in scanf generated function The rewriter-created sscanf and snprintf routines did not support map structs with arrays or pointer types in them. Add such support. Signed-off-by: Brenden Blanco --- src/cc/bpf_module.cc | 13 +++++++++++++ tests/cc/test_clang.py | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/cc/bpf_module.cc b/src/cc/bpf_module.cc index 7e1a409..fbdb71b 100644 --- a/src/cc/bpf_module.cc +++ b/src/cc/bpf_module.cc @@ -148,6 +148,19 @@ static void parse_type(IRBuilder<> &B, vector *args, string *fmt, *fmt += " "; } *fmt += "}"; + } else if (ArrayType *at = dyn_cast(type)) { + *fmt += "[ "; + for (size_t i = 0; i < at->getNumElements(); ++i) { + parse_type(B, args, fmt, at->getElementType(), B.CreateStructGEP(type, out, i), is_writer); + *fmt += " "; + } + *fmt += "]"; + } else if (PointerType *pt = dyn_cast(type)) { + *fmt += "0xl"; + if (is_writer) + *fmt += "x"; + else + *fmt += "i"; } else if (IntegerType *it = dyn_cast(type)) { if (is_writer) *fmt += "0x"; diff --git a/tests/cc/test_clang.py b/tests/cc/test_clang.py index 87f2bd4..ae19519 100755 --- a/tests/cc/test_clang.py +++ b/tests/cc/test_clang.py @@ -3,6 +3,7 @@ # Licensed under the Apache License, Version 2.0 (the "License") from bcc import BPF +import ctypes from unittest import main, TestCase class TestClang(TestCase): @@ -89,6 +90,22 @@ int foo(void *ctx) { self.assertEqual(l.s.a, 5) self.assertEqual(l.s.b, 6) + def test_sscanf_array(self): + text = """ +BPF_TABLE("hash", int, struct { u32 a[3]; u32 b; }, stats, 10); +""" + b = BPF(text=text, debug=0) + t = b.get_table("stats") + s1 = t.key_sprintf(t.Key(2)) + self.assertEqual(s1, b"0x2") + s2 = t.leaf_sprintf(t.Leaf((ctypes.c_uint * 3)(1,2,3), 4)) + self.assertEqual(s2, b"{ [ 0x1 0x2 0x3 ] 0x4 }") + l = t.leaf_scanf(s2) + self.assertEqual(l.a[0], 1) + self.assertEqual(l.a[1], 2) + self.assertEqual(l.a[2], 3) + self.assertEqual(l.b, 4) + def test_iosnoop(self): text = """ #include -- 2.7.4