Merge "More <limits.h> fixes."
diff --git a/libc/private/CachedProperty.h b/libc/private/CachedProperty.h
index 417a855..84ead01 100644
--- a/libc/private/CachedProperty.h
+++ b/libc/private/CachedProperty.h
@@ -42,7 +42,9 @@
     : property_name_(property_name),
       prop_info_(nullptr),
       cached_area_serial_(0),
-      cached_property_serial_(0) {
+      cached_property_serial_(0),
+      is_read_only_(strncmp(property_name, "ro.", 3) == 0),
+      read_only_property_(nullptr) {
     cached_value_[0] = '\0';
   }
 
@@ -76,7 +78,9 @@
         __system_property_read_callback(prop_info_, &CachedProperty::Callback, this);
       }
     }
-
+    if (is_read_only_ && read_only_property_ != nullptr) {
+      return read_only_property_;
+    }
     return cached_value_;
   }
 
@@ -86,10 +90,18 @@
   uint32_t cached_area_serial_;
   uint32_t cached_property_serial_;
   char cached_value_[PROP_VALUE_MAX];
+  bool is_read_only_;
+  const char* read_only_property_;
 
   static void Callback(void* data, const char*, const char* value, uint32_t serial) {
     CachedProperty* instance = reinterpret_cast<CachedProperty*>(data);
     instance->cached_property_serial_ = serial;
-    strcpy(instance->cached_value_, value);
+    // Read only properties can be larger than PROP_VALUE_MAX, but also never change value or
+    // location, thus we return the pointer from the shared memory directly.
+    if (instance->is_read_only_) {
+      instance->read_only_property_ = value;
+    } else {
+      strlcpy(instance->cached_value_, value, PROP_VALUE_MAX);
+    }
   }
 };
diff --git a/libdl/Android.bp b/libdl/Android.bp
index b0bbe99..44daaec 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -4,7 +4,7 @@
 cc_library_static {
     name: "libdl_static",
 
-    srcs: ["libdl.c", "libdl_cfi.cpp"],
+    srcs: ["libdl.cpp", "libdl_cfi.cpp"],
 
     cflags: [
         "-Wall",
diff --git a/libdl/libdl.c b/libdl/libdl.cpp
similarity index 98%
rename from libdl/libdl.c
rename to libdl/libdl.cpp
index b747c22..97cdeb4 100644
--- a/libdl/libdl.c
+++ b/libdl/libdl.cpp
@@ -23,11 +23,13 @@
 // These functions are exported by the loader
 // TODO(dimitry): replace these with reference to libc.so
 
+extern "C" {
+
 __attribute__((__weak__, visibility("default")))
 void* __loader_dlopen(const char* filename, int flags, const void* caller_addr);
 
 __attribute__((__weak__, visibility("default")))
-void* __loader_dlerror();
+char* __loader_dlerror();
 
 __attribute__((__weak__, visibility("default")))
 void* __loader_dlsym(void* handle, const char* symbol, const void* caller_addr);
@@ -212,3 +214,5 @@
 struct android_namespace_t* android_get_exported_namespace(const char* name) {
   return __loader_android_get_exported_namespace(name);
 }
+
+} // extern "C"