Disable non-static function calls

Compiled BPF programs must consist of a single contiguous code block,
meaning trying to call other function entry points (besides the
kernel-defined helpers) is not possible. The bcc frontend didn't
explicitly prohibit this, even though the program would fail to
compile/load. Add an explicit check and error message.

Fixes: #653
Signed-off-by: Brenden Blanco <bblanco@gmail.com>
diff --git a/src/cc/frontends/clang/b_frontend_action.cc b/src/cc/frontends/clang/b_frontend_action.cc
index 779b995..293f374 100644
--- a/src/cc/frontends/clang/b_frontend_action.cc
+++ b/src/cc/frontends/clang/b_frontend_action.cc
@@ -462,6 +462,15 @@
           rewriter_.ReplaceText(expansionRange(Call->getSourceRange()), text);
         }
       }
+    } else if (FunctionDecl *F = dyn_cast<FunctionDecl>(Decl)) {
+      if (F->isExternallyVisible() && !F->getBuiltinID()) {
+        auto start_loc = rewriter_.getSourceMgr().getFileLoc(Decl->getLocStart());
+        if (rewriter_.getSourceMgr().getFileID(start_loc)
+            == rewriter_.getSourceMgr().getMainFileID()) {
+          error(Call->getLocStart(), "cannot call non-static helper function");
+          return false;
+        }
+      }
     }
   }
   return true;
diff --git a/tests/python/test_clang.py b/tests/python/test_clang.py
index d275e5f..3b75cc1 100755
--- a/tests/python/test_clang.py
+++ b/tests/python/test_clang.py
@@ -522,7 +522,17 @@
         with self.assertRaises(KeyError):
             b1["dummy"][c_key]
 
-
+    def test_invalid_noninline_call(self):
+        text = """
+int bar(void) {
+    return 0;
+}
+int foo(struct pt_regs *ctx) {
+    return bar();
+}
+"""
+        with self.assertRaises(Exception):
+            b = BPF(text=text)
 
 
 if __name__ == "__main__":
diff --git a/tools/pidpersec.py b/tools/pidpersec.py
index e68ca43..ddaaaa0 100755
--- a/tools/pidpersec.py
+++ b/tools/pidpersec.py
@@ -28,7 +28,7 @@
 
 BPF_ARRAY(stats, u64, S_MAXSTAT + 1);
 
-void stats_increment(int key) {
+static void stats_increment(int key) {
     u64 *leaf = stats.lookup(&key);
     if (leaf) (*leaf)++;
 }
diff --git a/tools/vfsstat.py b/tools/vfsstat.py
index fa0a147..208e61a 100755
--- a/tools/vfsstat.py
+++ b/tools/vfsstat.py
@@ -51,7 +51,7 @@
 
 BPF_ARRAY(stats, u64, S_MAXSTAT + 1);
 
-void stats_increment(int key) {
+static void stats_increment(int key) {
     u64 *leaf = stats.lookup(&key);
     if (leaf) (*leaf)++;
 }