bpfloader: don't depend on symtab ordering to find function name

readCodeSections implicitly assumes that a function's name will be the
first symbol in its section to appear in the symbol table, but this is
not guaranteed. In particular, when compiling with -g the section name
can appear before it, resulting in a failure to find the bpf_prog_def
information for that section's program.

Add a check for the STT_FUNC symbol type to narrow our search to the
function name symbol we actually want.

Also, add a test to check that a program with a minimum kernel version
of infinity will not be loaded, to verify that bpfloader successfully
finds bpf_prog_def information.

Test: boot & confirm progs all have correct owners & permissions
Test: build time_in_state.c with -g and confirm owner & permissions
set correctly
Test: libbpf_load_test now passes iff this fix is applied
Signed-off-by: Connor O'Brien <connoro@google.com>
Change-Id: I31db0c50d3adeed86ee5810b1a0fb972f56fdb47
diff --git a/libbpf_android/Loader.cpp b/libbpf_android/Loader.cpp
index cad5950..eb48cd0 100644
--- a/libbpf_android/Loader.cpp
+++ b/libbpf_android/Loader.cpp
@@ -356,7 +356,8 @@
     return 0;
 }
 
-static int getSectionSymNames(ifstream& elfFile, const string& sectionName, vector<string>& names) {
+static int getSectionSymNames(ifstream& elfFile, const string& sectionName, vector<string>& names,
+                              optional<unsigned> symbolType = std::nullopt) {
     int ret;
     string name;
     vector<Elf64_Sym> symtab;
@@ -387,6 +388,8 @@
     }
 
     for (int i = 0; i < (int)symtab.size(); i++) {
+        if (symbolType.has_value() && ELF_ST_TYPE(symtab[i].st_info) != symbolType) continue;
+
         if (symtab[i].st_shndx == sec_idx) {
             string s;
             ret = getSymName(elfFile, symtab[i].st_name, s);
@@ -437,7 +440,7 @@
             ALOGD("Loaded code section %d (%s)\n", i, name.c_str());
 
             vector<string> csSymNames;
-            ret = getSectionSymNames(elfFile, oldName, csSymNames);
+            ret = getSectionSymNames(elfFile, oldName, csSymNames, STT_FUNC);
             if (ret || !csSymNames.size()) return ret;
             for (size_t i = 0; i < progDefNames.size(); ++i) {
                 if (!progDefNames[i].compare(csSymNames[0] + "_def")) {