9

I am using __system_property_get() from sys/system_properties.h to get a system property. I am trying to use r10c ndk because I need arm64 toolchain.

__system_property_get() is defined in libc.so. Below is the readelf output of libc.so for armv5/armv7a.

readelf -Ws libc.so | grep property_get

       194: 00009100    20 FUNC    GLOBAL DEFAULT    4 __system_property_get
       198: 00009100    20 FUNC    GLOBAL DEFAULT    4 __system_property_get

But, looks like it has been removed for arm64 version! I am getting a linker error saying it is not defined. I analyzed all the shared libraries of arm64 but none of them have that symbol.

Is there an alternate API to get the system property in the native code?

Thank you!

kanak
  • 533
  • 1
  • 5
  • 8

3 Answers3

11

It's useful API for native apps, just as it is for Java apps, it originates from the native side (see http://rxwen.blogspot.com/2010/01/android-property-system.html), and other Android system code uses it, so it's unlikely to go away soon.

#include <android/log.h>
#include <dlfcn.h>

#if (__ANDROID_API__ >= 21)
// Android 'L' makes __system_property_get a non-global symbol.
// Here we provide a stub which loads the symbol from libc via dlsym.
typedef int (*PFN_SYSTEM_PROP_GET)(const char *, char *);
int __system_property_get(const char* name, char* value)
{
    static PFN_SYSTEM_PROP_GET __real_system_property_get = NULL;
    if (!__real_system_property_get) {
        // libc.so should already be open, get a handle to it.
        void *handle = dlopen("libc.so", RTLD_NOLOAD);
        if (!handle) {
            __android_log_print(ANDROID_LOG_ERROR, "foobar", "Cannot dlopen libc.so: %s.\n", dlerror());
        } else {
            __real_system_property_get = (PFN_SYSTEM_PROP_GET)dlsym(handle, "__system_property_get");
        }
        if (!__real_system_property_get) {
            __android_log_print(ANDROID_LOG_ERROR, "foobar", "Cannot resolve __system_property_get(): %s.\n", dlerror());
        }
    }
    if (!__real_system_property_get) return (0);
    return (*__real_system_property_get)(name, value);
} 
#endif // __ANDROID_API__ >= 21
bleater
  • 5,098
  • 50
  • 48
3

In older NDKs this was not an officially supported API. It was mistakenly exposed to the 32-bit ABIs early on, but wasn't exposed to the 64-bit ABIs until it was officially supported. Regardless, it is exposed by the system at all API levels, so newer NDKs are able to use this regardless of ABI or minSdkVersion.

Dan Albert
  • 10,079
  • 2
  • 36
  • 79
  • If it wasn't supposed to be a public API (but the implementation kept for ABI compatibility), it should be removed from the NDK headers as well (at least for the 64 bit version of the headers). I filed a question/bug report about this at http://b.android.com/143627 as well. – mstorsjo Feb 09 '15 at 18:42
  • Yeah, the header still being there is a bug. Thanks for the report. – Dan Albert Feb 09 '15 at 20:44
  • Yes. The API is still present in the header which prompted me to search for the symbols in all the libraries in the NDK. I am getting the device's serial number, model, etc using the system properties in my native library. Is there any other way to achieve this? – kanak Feb 10 '15 at 04:03
  • You can read the information from `/system/build.prop`. You can check the [source for the Java API](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/Build.java) for this information to figure out which keys map to which values. – Dan Albert Feb 10 '15 at 07:43
  • Thank you. I looked at that file and most of the properties are present in it. Although, I could not find ro.serialno in it. Probably it is coming from elsewhere. – kanak Feb 10 '15 at 09:59
  • 2
    You can also just call up into the Java API. That's probably the best solution, as build.prop isn't guaranteed to be stable (or even present). – Dan Albert Feb 10 '15 at 19:27
  • @DanAlbert Did this removal get reverted since 2015? Is it correct to say that `__system_property_get` is deprecated, but still usable for reliably getting `ro.build.version.sdk` and the like? https://groups.google.com/forum/#!msg/android-ndk/yaOW7iG7jOE/FyBnZ_LYBgAJ – Arto Bendiken Jan 14 '20 at 21:09
  • Yeah, this answer is out of date. It's an officially supported API with an unfortunately unsupported looking name these days. I'll make an edit. – Dan Albert Jan 15 '20 at 00:28
-1

Confirming @bleater's answer as a workaround for the unexposed __system_properties_* symbols: dlopen libc and dlsym as needed.

zerpt
  • 31
  • 3