allow tagging a bpf .o as critical

This does not yet do anything with this information besides logging it.

Test: builds
  $ adb logcat -s -d LibBpfLoader:D | egrep Loading
  06-14 22:52:48.657   430   430 D LibBpfLoader: Loading critical for netd ELF object /system/etc/bpf/offload.o with license Apache 2.0
  06-14 22:52:48.682   430   430 D LibBpfLoader: Loading optional ELF object /system/etc/bpf/time_in_state.o with license GPL
  06-14 22:52:48.729   430   430 D LibBpfLoader: Loading critical for netd ELF object /system/etc/bpf/clatd.o with license Apache 2.0
  06-14 22:52:48.767   430   430 D LibBpfLoader: Loading critical for netd ELF object /system/etc/bpf/netd.o with license Apache 2.0
  06-14 22:53:26.052  2605  2605 D LibBpfLoader: Loading optional ELF object /data/local/tmp/32/kern.o with license Apache 2.0
  06-14 22:54:26.070  2605  2605 D LibBpfLoader: Loading optional ELF object /data/local/tmp/32/kern.o with license Apache 2.0
Bug: 150040815
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Ie07549528800d6d7c5ff7f12b859702113d7194e
diff --git a/libbpf_android/Loader.cpp b/libbpf_android/Loader.cpp
index 4244eb7..9f57ce6 100644
--- a/libbpf_android/Loader.cpp
+++ b/libbpf_android/Loader.cpp
@@ -608,19 +608,26 @@
 
 int loadProg(const char* elfPath) {
     vector<char> license;
+    vector<char> critical;
     vector<codeSection> cs;
     vector<unique_fd> mapFds;
+    bool is_critical;
     int ret;
 
     ifstream elfFile(elfPath, ios::in | ios::binary);
     if (!elfFile.is_open()) return -1;
 
+    ret = readSectionByName("critical", elfFile, critical);
+    is_critical = !ret;
+
     ret = readSectionByName("license", elfFile, license);
     if (ret) {
         ALOGE("Couldn't find license in %s\n", elfPath);
         return ret;
     } else {
-        ALOGD("Loading ELF object %s with license %s\n", elfPath, (char*)license.data());
+        ALOGD("Loading %s%s ELF object %s with license %s\n",
+              is_critical ? "critical for " : "optional", is_critical ? (char*)critical.data() : "",
+              elfPath, (char*)license.data());
     }
 
     ret = readCodeSections(elfFile, cs);
diff --git a/progs/include/bpf_helpers.h b/progs/include/bpf_helpers.h
index 8ff155f..f76b382 100644
--- a/progs/include/bpf_helpers.h
+++ b/progs/include/bpf_helpers.h
@@ -12,6 +12,12 @@
 /* Example use: LICENSE("GPL"); or LICENSE("Apache 2.0"); */
 #define LICENSE(NAME) char _license[] SEC("license") = (NAME)
 
+/* flag the resulting bpf .o file as critical to system functionality,
+ * loading all kernel version appropriate programs in it must succeed
+ * for bpfloader success
+ */
+#define CRITICAL(REASON) char _critical[] SEC("critical") = (REASON)
+
 /*
  * Helper functions called from eBPF programs written in C. These are
  * implemented in the kernel sources.