In the given android stack,
excluding applications written using NDK kit at LIBRARIES layer,
I learnt that, Any app written at APPLICATIONS layer must run in their own processes, inside their own Dalvik VM instance, as shown below:
As per the process stack above, I see that Dalvik runtime is talking to HAL/kernel layer via bionic Libc library.
My question:
Can't Dalvik VM access HAL/Kernel layer without using bionic Libc library interface?
i see some confusion in you when it comes to C Language.
after all bionic is just standard C library for android.
first of all, your answer is NO.
although bionic libC is not below Dalvik in their diagram, the fact is that Dalvik uses libC helper functions to perform some tasks that are considered as operating system services.
like:
string handling, mathematical computations, input/output processing, memory allocation and several other operating system services.
Related
i used the code Webview.loadurl("www.google.com")
and I know that
using the dynamic analysis tool, in the libc.so module, the connection() function is used.
*connection format is connection(sockfd, addr, addrlen)
parameter:addr include "www.google.com" URL
I would like to know how this module and WebKit work.
enter image description here
Libc is the standard system library, including standard C library, POSIX, and other Linux and possibly android extensions).
So nearly all libraries need libc to work: they use it to call the system. Very seldom libraries call directly the kernel (because libc provide most of the call, but few special use calls).
Libc is very complex. You may read C books and POSIX. For implementation, you can Google: you will find a lot. Some complete, some made for tiny systems. Often they are open source, so you can check the implementation. Possibly try the small libraries (for embedded systems): the code is much more readable. Avoid glibc (now near the reference): it should be compiled for too many systems, so the code is made compatible with old and broken compilers, at cost of readability (but use glibc documentation).
Android apps can execute C/C++ code using the Android NDK. All Android apps also run on the Android VM (i.e. Dalvik/ART).
My question is, does native code in Android apps use the same stack/heap as the Android VM?
i.e. In native code, we can create local variables and also variables via malloc/new, and these will be stored on the stack or heap respectively. But also my understanding is that the Android VM will create objects of it's own for bookkeeping. So does the native code and Android VM share the same stack/heap in memory?
The managed JVM heap and the native heap are separate, but they are not completely isolated. Under the hood, JVM uses the same system calls, and via JNI, you can access java primitive arrays' memory.
As for stack, JVM and C share it per thread. But not all native threads are attached to JVM.
I came across this site and also there are some discussions about the topic here and here but I still could not find the answer.
It has been stated that Dalvik had separate stacks for native and Java code, while ART has a unified stack for the native and Java code. I tried to verify this by extracting memory addresses in an Android app (using unsafe lib). However, it seems that they belong to different memory regions ( it looks that the native heap resides between the native stack and the Java stack). So what is meant by a unified stack? is that at low level, or may be this is at an abstract level?
I cannot find any references to a detailed explanation about how JNI works on Android in detail, so:
Since every Android application runs in its own process, with its own instance of the Dalvik/ART virtual machine, I think that the native code will be executed in the same process, am I right?
I read that when the VM invokes a function, it passes a JNIEnv pointer, a jobject pointer, and any Java arguments declared by the Java method.
But how is this made at assembly level (under the hood)?
I read that you can instantiate objects, call methods, and so on, like Reflection, using the functions provided by the JNIEnv. Therefore, my question is: have I a "direct" memory access to the VM or I have always to use the JNIEnv's functions?
The Android JVM is under Apache license, so the best detailed and precise description can be found in the form of source code. Note that there are two different JVMs: dalvik and art. Under the hood they are very different, to the extent that a user of JNI may consider special adaptations.
the native code will be executed in the same process
Exactly. Note that an Android app can run in more than one process, and also it can spawn child processes (normal Unix behavior). But JNI is not IPC.
how is this made at assembly level?
More or less, this is described in a related
question: What does a JVM have to do when calling a native method?
have I a "direct" memory access to the VM?
Yes, you have. There is no security barrier between your C code and the JVM. You can reverse engineer the data structures, and do whatever you like. The exact implementations of the JVM not only depend on the Android version, but may be modified without notice by the vendor, as long as the public API of the JVM (including JNI) is compatible. The chances that you will do something useful with direct memory access to JVM are minimal, but the risk that it will crash is very high.
Note that this is not a security issue: your C code is running in a separate process (with your Java code), and is subject to the same permissions restrictions as the Java code. It has no access to the private memory of other apps or procsses. Whatever you change in your instance of JVM will not effect VM that runs other apps.
According to wiki (http://en.wikipedia.org/wiki/Android_Runtime) Dalvik gets entirely replaced by ART in Lollipop i.e. from that release onwards any app will be compiled to native code upon installation. This begs the question, is there a point in writing computing intense routines in NDK if the app will be compiled to native code anyway?
The Dalvik VM also compiled code to native code. The difference is that Dalvik did it "just in time", and only for the parts of code that were executed frequently.
The compiler in Art has a number of performance improvements over the one in Dalvik, but if you felt the need to go native for performance before, you will most likely continue to feel that need.
ART does not make pure "native code" in the sense of C language etc. It is still bytecode generated from Java sources.
So yes, there is still a lot of advantages to write some routines with the NDK, of course :)