Merge "Remove EXCLUDE_FS_CONFIG_STRUCTURES"
diff --git a/libbpf_android/BpfUtils.cpp b/libbpf_android/BpfUtils.cpp
index c7c56d5..97b3363 100644
--- a/libbpf_android/BpfUtils.cpp
+++ b/libbpf_android/BpfUtils.cpp
@@ -39,7 +39,6 @@
 #include <log/log.h>
 #include <processgroup/processgroup.h>
 
-using android::base::GetUintProperty;
 using android::base::unique_fd;
 
 // The buffer size for the buffer that records program loading logs, needs to be large enough for
@@ -86,8 +85,8 @@
 int setrlimitForTest() {
     // Set the memory rlimit for the test process if the default MEMLOCK rlimit is not enough.
     struct rlimit limit = {
-            .rlim_cur = 8388608,  // 8 MiB
-            .rlim_max = 8388608,  // 8 MiB
+            .rlim_cur = 1073741824,  // 1 GiB
+            .rlim_max = 1073741824,  // 1 GiB
     };
     int res = setrlimit(RLIMIT_MEMLOCK, &limit);
     if (res) {
@@ -117,9 +116,9 @@
 std::string BpfLevelToString(BpfLevel bpfLevel) {
     switch (bpfLevel) {
         case BpfLevel::NONE:
-            return "None [pre-4.9]";
+            return "None [pre-4.9 or pre-P]";
         case BpfLevel::BASIC_4_9:
-            return "Basic [4.9]";
+            return "Basic [4.9 P+]";
         case BpfLevel::EXTENDED_4_14:
             return "Extended [4.14]";
         case BpfLevel::EXTENDED_4_19:
@@ -132,20 +131,25 @@
 }
 
 static BpfLevel getUncachedBpfSupportLevel() {
-    uint64_t api_level = GetUintProperty<uint64_t>("ro.product.first_api_level", 0);
-    if (api_level == 0) {
-        ALOGE("Cannot determine initial API level of the device");
-        api_level = GetUintProperty<uint64_t>("ro.build.version.sdk", 0);
-    }
-
-    // Check if the device is shipped originally with android P.
-    if (api_level < MINIMUM_API_REQUIRED) return BpfLevel::NONE;
-
     unsigned kver = kernelVersion();
 
     if (kver >= KVER(5, 4, 0)) return BpfLevel::EXTENDED_5_4;
     if (kver >= KVER(4, 19, 0)) return BpfLevel::EXTENDED_4_19;
     if (kver >= KVER(4, 14, 0)) return BpfLevel::EXTENDED_4_14;
+
+    // Override for devices launched with O but now on a 4.9-P+ kernel.
+    bool has_ebpf = base::GetBoolProperty("ro.product.kernel_has_ebpf", false);
+    if (has_ebpf) return BpfLevel::BASIC_4_9;
+
+    uint64_t api_level = base::GetUintProperty<uint64_t>("ro.product.first_api_level", 0);
+    if (api_level == 0) {
+        ALOGE("Cannot determine initial API level of the device");
+        api_level = base::GetUintProperty<uint64_t>("ro.build.version.sdk", 0);
+    }
+
+    // Check if the device is shipped originally with android P.
+    if (api_level < MINIMUM_API_REQUIRED) return BpfLevel::NONE;
+
     if (kver >= KVER(4, 9, 0)) return BpfLevel::BASIC_4_9;
 
     return BpfLevel::NONE;
diff --git a/libbpf_android/include/bpf/BpfMap.h b/libbpf_android/include/bpf/BpfMap.h
index 25096db..8c35931 100644
--- a/libbpf_android/include/bpf/BpfMap.h
+++ b/libbpf_android/include/bpf/BpfMap.h
@@ -57,7 +57,7 @@
   public:
     explicit BpfMap<Key, Value>(const char* pathname) : BpfMap<Key, Value>(pathname, 0) {}
 
-    BpfMap<Key, Value>(bpf_map_type map_type, uint32_t max_entries, uint32_t map_flags) {
+    BpfMap<Key, Value>(bpf_map_type map_type, uint32_t max_entries, uint32_t map_flags = 0) {
         int map_fd = createMap(map_type, sizeof(Key), sizeof(Value), max_entries, map_flags);
         if (map_fd >= 0) mMapFd.reset(map_fd);
     }
@@ -128,6 +128,11 @@
 
     const base::unique_fd& getMap() const { return mMapFd; };
 
+    // Copy assignment operator
+    void operator=(const BpfMap<Key, Value>& other) {
+        mMapFd.reset(fcntl(other.mMapFd.get(), F_DUPFD_CLOEXEC, 0));
+    }
+
     // Move constructor
     void operator=(BpfMap<Key, Value>&& other) noexcept {
         mMapFd = std::move(other.mMapFd);
diff --git a/progs/include/bpf_helpers.h b/progs/include/bpf_helpers.h
index 09c3373..8ff155f 100644
--- a/progs/include/bpf_helpers.h
+++ b/progs/include/bpf_helpers.h
@@ -9,6 +9,9 @@
 /* place things in different elf sections */
 #define SEC(NAME) __attribute__((section(NAME), used))
 
+/* Example use: LICENSE("GPL"); or LICENSE("Apache 2.0"); */
+#define LICENSE(NAME) char _license[] SEC("license") = (NAME)
+
 /*
  * Helper functions called from eBPF programs written in C. These are
  * implemented in the kernel sources.