diff --git a/libbpf_android/Loader.cpp b/libbpf_android/Loader.cpp
new file mode 100644
index 0000000..332c0b4
--- /dev/null
+++ b/libbpf_android/Loader.cpp
@@ -0,0 +1,588 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LibBpfLoader"
+
+#include <errno.h>
+#include <linux/bpf.h>
+#include <linux/elf.h>
+#include <log/log.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+
+#include "LoaderUtils.h"
+#include "include/libbpf_android.h"
+
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <string>
+
+#include <android-base/strings.h>
+
+#define BPF_FS_PATH "/sys/fs/bpf/"
+
+// Size of the BPF log buffer for verifier logging
+#define BPF_LOAD_LOG_SZ 0x1ffff
+
+using android::base::StartsWith;
+using std::ifstream;
+using std::ios;
+using std::vector;
+
+namespace android {
+namespace bpf {
+
+typedef struct {
+    const char* name;
+    enum bpf_prog_type type;
+} sectionType;
+
+/*
+ * Map section name prefixes to program types, the section name will be:
+ * SEC(<prefix>/<name-of-program>)
+ * For example:
+ * SEC("tracepoint/sched_switch_func") where sched_switch_funcs
+ * is the name of the program, and tracepoint is the type.
+ */
+sectionType sectionNameTypes[] = {
+    { "kprobe", BPF_PROG_TYPE_KPROBE },
+    { "tracepoint", BPF_PROG_TYPE_TRACEPOINT },
+    { "skfilter", BPF_PROG_TYPE_SOCKET_FILTER },
+    { "cgroupskb", BPF_PROG_TYPE_CGROUP_SKB },
+
+    /* End of table */
+    { "END", BPF_PROG_TYPE_UNSPEC },
+};
+
+typedef struct {
+    enum bpf_prog_type type;
+    string name;
+    vector<char> data;
+    vector<char> rel_data;
+
+    int prog_fd; /* fd after loading */
+} codeSection;
+
+/* Common with the eBPF C program */
+struct bpf_map_def {
+    enum bpf_map_type type;
+    unsigned int key_size;
+    unsigned int value_size;
+    unsigned int max_entries;
+    unsigned int map_flags;
+    unsigned int inner_map_idx;
+    unsigned int numa_node;
+};
+
+static int readElfHeader(ifstream& elfFile, Elf64_Ehdr* eh) {
+    elfFile.seekg(0);
+    if (elfFile.fail()) return -1;
+
+    if (!elfFile.read((char*)eh, sizeof(*eh))) return -1;
+
+    return 0;
+}
+
+/* Reads all section header tables into an Shdr array */
+static int readSectionHeadersAll(ifstream& elfFile, vector<Elf64_Shdr>& shTable) {
+    Elf64_Ehdr eh;
+    int ret = 0;
+
+    ret = readElfHeader(elfFile, &eh);
+    if (ret) return ret;
+
+    elfFile.seekg(eh.e_shoff);
+    if (elfFile.fail()) return -1;
+
+    /* Read shdr table entries */
+    shTable.resize(eh.e_shnum);
+
+    if (!elfFile.read((char*)shTable.data(), (eh.e_shnum * eh.e_shentsize))) return -ENOMEM;
+
+    return 0;
+}
+
+/* Read a section by its index - for ex to get sec hdr strtab blob */
+static int readSectionByIdx(ifstream& elfFile, int id, vector<char>& sec) {
+    vector<Elf64_Shdr> shTable;
+    int entries, ret = 0;
+
+    ret = readSectionHeadersAll(elfFile, shTable);
+    if (ret) return ret;
+    entries = shTable.size();
+
+    elfFile.seekg(shTable[id].sh_offset);
+    if (elfFile.fail()) return -1;
+
+    sec.resize(shTable[id].sh_size);
+    if (!elfFile.read(sec.data(), shTable[id].sh_size)) return -1;
+
+    return 0;
+}
+
+/* Read whole section header string table */
+static int readSectionHeaderStrtab(ifstream& elfFile, vector<char>& strtab) {
+    Elf64_Ehdr eh;
+    int ret = 0;
+
+    ret = readElfHeader(elfFile, &eh);
+    if (ret) return ret;
+
+    ret = readSectionByIdx(elfFile, eh.e_shstrndx, strtab);
+    if (ret) return ret;
+
+    return 0;
+}
+
+/* Get name from offset in strtab */
+static int getSymName(ifstream& elfFile, int nameOff, string& name) {
+    int ret;
+    vector<char> secStrTab;
+
+    ret = readSectionHeaderStrtab(elfFile, secStrTab);
+    if (ret) return ret;
+
+    if (nameOff >= (int)secStrTab.size()) return -1;
+
+    name = string((char*)secStrTab.data() + nameOff);
+    return 0;
+}
+
+/* Reads a full section by name - example to get the GPL license */
+static int readSectionByName(const char* name, ifstream& elfFile, vector<char>& data) {
+    vector<char> secStrTab;
+    vector<Elf64_Shdr> shTable;
+    int ret;
+
+    ret = readSectionHeadersAll(elfFile, shTable);
+    if (ret) return ret;
+
+    ret = readSectionHeaderStrtab(elfFile, secStrTab);
+    if (ret) return ret;
+
+    for (int i = 0; i < (int)shTable.size(); i++) {
+        char* secname = secStrTab.data() + shTable[i].sh_name;
+        if (!secname) continue;
+
+        if (!strcmp(secname, name)) {
+            vector<char> dataTmp;
+            dataTmp.resize(shTable[i].sh_size);
+
+            elfFile.seekg(shTable[i].sh_offset);
+            if (elfFile.fail()) return -1;
+
+            if (!elfFile.read((char*)dataTmp.data(), shTable[i].sh_size)) return -1;
+
+            data = dataTmp;
+            return 0;
+        }
+    }
+    return -2;
+}
+
+static int readSectionByType(ifstream& elfFile, int type, vector<char>& data) {
+    int ret;
+    vector<Elf64_Shdr> shTable;
+
+    ret = readSectionHeadersAll(elfFile, shTable);
+    if (ret) return ret;
+
+    for (int i = 0; i < (int)shTable.size(); i++) {
+        if ((int)shTable[i].sh_type != type) continue;
+
+        vector<char> dataTmp;
+        dataTmp.resize(shTable[i].sh_size);
+
+        elfFile.seekg(shTable[i].sh_offset);
+        if (elfFile.fail()) return -1;
+
+        if (!elfFile.read((char*)dataTmp.data(), shTable[i].sh_size)) return -1;
+
+        data = dataTmp;
+        return 0;
+    }
+    return -2;
+}
+
+static bool symCompare(Elf64_Sym a, Elf64_Sym b) {
+    return (a.st_value < b.st_value);
+}
+
+static int readSymTab(ifstream& elfFile, int sort, vector<Elf64_Sym>& data) {
+    int ret, numElems;
+    Elf64_Sym* buf;
+    vector<char> secData;
+
+    ret = readSectionByType(elfFile, SHT_SYMTAB, secData);
+    if (ret) return ret;
+
+    buf = (Elf64_Sym*)secData.data();
+    numElems = (secData.size() / sizeof(Elf64_Sym));
+    data.assign(buf, buf + numElems);
+
+    if (sort) std::sort(data.begin(), data.end(), symCompare);
+    return 0;
+}
+
+static enum bpf_prog_type getSectionType(string& name) {
+    for (int i = 0; sectionNameTypes[i].type != BPF_PROG_TYPE_UNSPEC; i++)
+        if (StartsWith(name, sectionNameTypes[i].name)) return sectionNameTypes[i].type;
+
+    return BPF_PROG_TYPE_UNSPEC;
+}
+
+/* If ever needed
+static string getSectionName(enum bpf_prog_type type)
+{
+    for (int i = 0; sectionNameTypes[i].type != BPF_PROG_TYPE_UNSPEC; i++)
+        if (sectionNameTypes[i].type == type)
+            return std::string(sectionNameTypes[i].name);
+
+    return NULL;
+}
+*/
+
+static bool isRelSection(codeSection& cs, string& name) {
+    for (int i = 0; sectionNameTypes[i].type != BPF_PROG_TYPE_UNSPEC; i++) {
+        sectionType st = sectionNameTypes[i];
+
+        if (st.type != cs.type) continue;
+
+        if (StartsWith(name, std::string(".rel") + st.name + "/"))
+            return true;
+        else
+            return false;
+    }
+    return false;
+}
+
+/* Read a section by its index - for ex to get sec hdr strtab blob */
+static int readCodeSections(ifstream& elfFile, vector<codeSection>& cs) {
+    vector<Elf64_Shdr> shTable;
+    int entries, ret = 0;
+
+    ret = readSectionHeadersAll(elfFile, shTable);
+    if (ret) return ret;
+    entries = shTable.size();
+
+    for (int i = 0; i < entries; i++) {
+        string name;
+        codeSection cs_temp;
+        cs_temp.type = BPF_PROG_TYPE_UNSPEC;
+
+        ret = getSymName(elfFile, shTable[i].sh_name, name);
+        if (ret) return ret;
+
+        enum bpf_prog_type ptype = getSectionType(name);
+        if (ptype != BPF_PROG_TYPE_UNSPEC) {
+            deslash(name);
+            cs_temp.type = ptype;
+            cs_temp.name = name;
+
+            ret = readSectionByIdx(elfFile, i, cs_temp.data);
+            if (ret) return ret;
+            ALOGD("Loaded code section %d (%s)\n", i, name.c_str());
+        }
+
+        /* Check for rel section */
+        if (cs_temp.data.size() > 0 && i < entries) {
+            ret = getSymName(elfFile, shTable[i + 1].sh_name, name);
+            if (ret) return ret;
+
+            if (isRelSection(cs_temp, name)) {
+                ret = readSectionByIdx(elfFile, i + 1, cs_temp.rel_data);
+                if (ret) return ret;
+                ALOGD("Loaded relo section %d (%s)\n", i, name.c_str());
+            }
+        }
+
+        if (cs_temp.data.size() > 0) {
+            cs.push_back(cs_temp);
+            ALOGD("Adding section %d to cs list\n", i);
+        }
+    }
+    return 0;
+}
+
+static int getSymNameByIdx(ifstream& elfFile, int index, string& name) {
+    vector<Elf64_Sym> symtab;
+    int ret = 0;
+
+    ret = readSymTab(elfFile, 0 /* !sort */, symtab);
+    if (ret) return ret;
+
+    if (index >= (int)symtab.size()) return -1;
+
+    return getSymName(elfFile, symtab[index].st_name, name);
+}
+
+static int getMapNames(ifstream& elfFile, vector<string>& names) {
+    int ret;
+    string mapName;
+    vector<Elf64_Sym> symtab;
+    vector<Elf64_Shdr> shTable;
+
+    ret = readSymTab(elfFile, 1 /* sort */, symtab);
+    if (ret) return ret;
+
+    /* Get index of maps section */
+    ret = readSectionHeadersAll(elfFile, shTable);
+    if (ret) return ret;
+
+    int maps_idx = -1;
+    for (int i = 0; i < (int)shTable.size(); i++) {
+        ret = getSymName(elfFile, shTable[i].sh_name, mapName);
+        if (ret) return ret;
+
+        if (!mapName.compare("maps")) {
+            maps_idx = i;
+            break;
+        }
+    }
+
+    /* No maps found */
+    if (maps_idx == -1) {
+        ALOGE("No maps could be found in elf object\n");
+        return -1;
+    }
+
+    for (int i = 0; i < (int)symtab.size(); i++) {
+        if (symtab[i].st_shndx == maps_idx) {
+            string s;
+            ret = getSymName(elfFile, symtab[i].st_name, s);
+            if (ret) return ret;
+            names.push_back(s);
+        }
+    }
+
+    return 0;
+}
+
+static int createMaps(const char* elfPath, ifstream& elfFile, vector<int>& mapFds) {
+    int ret, fd;
+    vector<char> mdData;
+    vector<struct bpf_map_def> md;
+    vector<string> mapNames;
+    string fname = pathToFilename(string(elfPath), true);
+
+    ret = readSectionByName("maps", elfFile, mdData);
+    if (ret) return ret;
+    md.resize(mdData.size() / sizeof(struct bpf_map_def));
+    memcpy(md.data(), mdData.data(), mdData.size());
+
+    ret = getMapNames(elfFile, mapNames);
+    if (ret) return ret;
+
+    mapFds.resize(mapNames.size());
+
+    for (int i = 0; i < (int)mapNames.size(); i++) {
+        // Format of pin location is /sys/fs/bpf/map_<filename>_<mapname>
+        string mapPinLoc;
+        bool reuse = false;
+
+        mapPinLoc = string(BPF_FS_PATH) + "map_" + fname + "_" + string(mapNames[i]);
+        if (access(mapPinLoc.c_str(), F_OK) == 0) {
+            fd = bpf_obj_get(mapPinLoc.c_str());
+            ALOGD("bpf_create_map reusing map %s, ret: %d\n", mapNames[i].c_str(), fd);
+            reuse = true;
+        } else {
+            fd = bpf_create_map(md[i].type, mapNames[i].c_str(), md[i].key_size, md[i].value_size,
+                                md[i].max_entries, md[i].map_flags);
+            ALOGD("bpf_create_map name %s, ret: %d\n", mapNames[i].c_str(), fd);
+        }
+
+        if (fd < 0) return fd;
+        if (fd == 0) return -EINVAL;
+
+        if (!reuse) {
+            ret = bpf_obj_pin(fd, mapPinLoc.c_str());
+            if (ret < 0) return ret;
+        }
+
+        mapFds[i] = fd;
+    }
+
+    return ret;
+}
+
+/* For debugging, dump all instructions */
+static void dumpIns(char* ins, int size) {
+    for (int row = 0; row < size / 8; row++) {
+        ALOGE("%d: ", row);
+        for (int j = 0; j < 8; j++) {
+            ALOGE("%3x ", ins[(row * 8) + j]);
+        }
+        ALOGE("\n");
+    }
+}
+
+/* For debugging, dump all code sections from cs list */
+static void dumpAllCs(vector<codeSection>& cs) {
+    for (int i = 0; i < (int)cs.size(); i++) {
+        ALOGE("Dumping cs %d, name %s\n", int(i), cs[i].name.c_str());
+        dumpIns((char*)cs[i].data.data(), cs[i].data.size());
+        ALOGE("-----------\n");
+    }
+}
+
+static void applyRelo(void* insnsPtr, Elf64_Addr offset, int fd) {
+    int insnIndex;
+    struct bpf_insn *insn, *insns;
+
+    insns = (struct bpf_insn*)(insnsPtr);
+
+    insnIndex = offset / sizeof(struct bpf_insn);
+    insn = &insns[insnIndex];
+
+    ALOGD(
+        "applying relo to instruction at byte offset: %d, \
+	       insn offset %d , insn %lx\n",
+        (int)offset, (int)insnIndex, *(unsigned long*)insn);
+
+    if (insn->code != (BPF_LD | BPF_IMM | BPF_DW)) {
+        ALOGE("Dumping all instructions till ins %d\n", insnIndex);
+        ALOGE("invalid relo for insn %d: code 0x%x\n", insnIndex, insn->code);
+        dumpIns((char*)insnsPtr, (insnIndex + 3) * 8);
+        return;
+    }
+
+    insn->imm = fd;
+    insn->src_reg = BPF_PSEUDO_MAP_FD;
+}
+
+static void applyMapRelo(ifstream& elfFile, vector<int> mapFds, vector<codeSection>& cs) {
+    vector<string> mapNames;
+
+    int ret = getMapNames(elfFile, mapNames);
+    if (ret) return;
+
+    for (int k = 0; k != (int)cs.size(); k++) {
+        Elf64_Rel* rel = (Elf64_Rel*)(cs[k].rel_data.data());
+        int n_rel = cs[k].rel_data.size() / sizeof(*rel);
+
+        for (int i = 0; i < n_rel; i++) {
+            int symIndex = ELF64_R_SYM(rel[i].r_info);
+            string symName;
+
+            ret = getSymNameByIdx(elfFile, symIndex, symName);
+            if (ret) return;
+
+            /* Find the map fd and apply relo */
+            for (int j = 0; j < (int)mapNames.size(); j++) {
+                if (!mapNames[j].compare(symName)) {
+                    applyRelo(cs[k].data.data(), rel[i].r_offset, mapFds[j]);
+                    break;
+                }
+            }
+        }
+    }
+}
+
+static int loadCodeSections(const char* elfPath, vector<codeSection>& cs, string license) {
+    int ret, fd, kvers;
+
+    if ((kvers = getMachineKvers()) < 0) return -1;
+
+    string fname = pathToFilename(string(elfPath), true);
+
+    for (int i = 0; i < (int)cs.size(); i++) {
+        string progPinLoc;
+        bool reuse = false;
+
+        // Format of pin location is
+        // /sys/fs/bpf/prog_<filename>_<mapname>
+        progPinLoc = string(BPF_FS_PATH) + "prog_" + fname + "_" + cs[i].name;
+        if (access(progPinLoc.c_str(), F_OK) == 0) {
+            fd = bpf_obj_get(progPinLoc.c_str());
+            ALOGD("New bpf prog load reusing prog %s, ret: %d\n", cs[i].name.c_str(), fd);
+            reuse = true;
+        } else {
+            vector<char> log_buf(BPF_LOAD_LOG_SZ, 0);
+
+            fd = bpf_prog_load(cs[i].type, cs[i].name.c_str(), (struct bpf_insn*)cs[i].data.data(),
+                               cs[i].data.size(), license.c_str(), kvers, 0,
+                               log_buf.data(), log_buf.size());
+            ALOGD("New bpf core prog_load for %s (%s) returned: %d\n", elfPath, cs[i].name.c_str(),
+                  fd);
+
+            if (fd <= 0)
+                ALOGE("bpf_prog_load: log_buf contents: %s\n", (char *)log_buf.data());
+        }
+
+        if (fd < 0) return fd;
+        if (fd == 0) return -EINVAL;
+
+        if (!reuse) {
+            ret = bpf_obj_pin(fd, progPinLoc.c_str());
+            if (ret < 0) return ret;
+        }
+
+        cs[i].prog_fd = fd;
+    }
+
+    return 0;
+}
+
+int loadProg(const char* elfPath) {
+    vector<char> license;
+    vector<codeSection> cs;
+    vector<int> mapFds;
+    int ret;
+
+    ifstream elfFile(elfPath, ios::in | ios::binary);
+    if (!elfFile.is_open()) return -1;
+
+    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());
+    }
+
+    ret = readCodeSections(elfFile, cs);
+    if (ret) {
+        ALOGE("Couldn't read all code sections in %s\n", elfPath);
+        return ret;
+    }
+
+    /* Just for future debugging */
+    if (0) dumpAllCs(cs);
+
+    ret = createMaps(elfPath, elfFile, mapFds);
+    if (ret) {
+        ALOGE("Failed to create maps: (ret=%d) in %s\n", ret, elfPath);
+        return ret;
+    }
+
+    for (int i = 0; i < (int)mapFds.size(); i++)
+        ALOGD("map_fd found at %d is %d in %s\n", i, mapFds[i], elfPath);
+
+    applyMapRelo(elfFile, mapFds, cs);
+
+    ret = loadCodeSections(elfPath, cs, string(license.data()));
+    if (ret) ALOGE("Failed to load programs, loadCodeSections ret=%d\n", ret);
+
+    return ret;
+}
+
+}  // namespace bpf
+}  // namespace android
