Dalvik analysis of the second: JNI, so

Source: Internet
Author: User

  Android mostly uses Java to develop, there is a concept in Java called JNI. Of course, when it comes to JNI, native code must be indispensable. The so library is in Android. To analyze the use of JNI in Android Dalvik, the following is my study and annotation of the registration process analysis article for the Dalvik virtual machine Jni method. Before that, let's say a few concepts:

JAVAVM: Virtual machine instance can also be described by a member variable vmlist of a dvmglobals struct described by the global variable GDVM;

JNIENV: A Java environment that describes the current thread, which can be used to invoke the JNI method registered in the zygote (see zygote boot process) to Dalvik

Jobject: To describe the Java object that is currently executing the JNI method

From Lao Luo's blog (the following is the map to expand)

  

  We are in the Java function in the load so library:

System.loadlibrary ("Nanosleep");    

 So library writing:

StaticJint Shy_luo_jni_classwithjni_nanosleep (jnienv*env, Jobject clazz, jlong seconds, Jlong nanoseconds) {    structTimespec req; Req.tv_sec=seconds; Req.tv_nsec=nanoseconds; returnNanosleep (&req, NULL);}Static ConstJninativemethod method_table[] = {    {"Nanosleep","(JJ) I", (void*) Shy_luo_jni_classwithjni_nanosleep},};extern "C"Jint jni_onload (javavm* vm,void*reserved) {jnienv* env =NULL; Jint result= -1; if(Vm->getenv (void* *) &env, jni_version_1_4)! =JNI_OK) {        returnresult; } jniregisternativemethods (env,"Shy/luo/jni/classwithjni", Method_table, Nelem (method_table)); returnjni_version_1_4;}

When the Java layer is in the LoadLibrary so library, the system actually does a few things (step 4):

1 call Dlopen in process to load so library;

2 Call Dlsym to obtain the address of the function named "Jni_onload" in the so library and save it in the function pointer func: func= dlsym (handle, "Jni_onload");

3 Execute the Jni_onload function in the so library: Version = (*func) (Gdvm.vmlist, NULL);

this time our gaze shifts to the C + + layer: Jni_onload (the JNI method is registered here). Look at the code, actually call the jniregisternativemethods function. But let's see if we know how some of the actual functions actually break, or rely on Dvmregisterjnimethod to perform:

 static  bool  Dvmregisterjnimethod ( classobject* Clazz, const  char  * MethodName,  const  char  * Signature, void  * Fnptr) {
//interpret the following parameters:
// Clazz: Class name "Shy/luo/jni/classwithjni";
///MethodName: The Jni method name to be registered Nanosleep;
//Signature: The signature of the method is essentially the parameter and return value of the method, Functions that distinguish different parameters
//Fnptr:jni method function address is shy_luo_jni_classwithjni_nanosleep function; Dalvik is the function, it's important.
    Method* method;    ......     = Dvmfinddirectmethodbydescriptor (clazz, MethodName, signature);    ......    Dvmusejnibridge (method, fnptr);    ......}

What I'm going to add here is the attention. The dvmfinddirectmethodbydescriptor function. The function that the JNI method corresponds to in the Java layer is empty, and the JNI registration is to bind the Jni method to the corresponding Java layer function body. So how do we find them to match up? Dvmfinddirectmethodbydescriptor uses MethodName and signature parameters to achieve the above purpose. In Dvmfinddirectmethodbydescriptor, the function List of class is methods, and the args, ReturnType and signature of Methods[index] are equal, If equal, the Jni method finds the function in the Java layer (JNI: I am also a ^_^ on the upper level). Ok, find method, quickly bound Ah also don't let her escape ah.

void void* func)  {      = Shouldtrace (method)          ? dvmtracecalljnimethod           Dvmselectjnibridge(method);      Dvmsetnativefunc (Method, Bridge, func);  }  
There is a bridge in the east, we do not look at the following will be mentioned (see the details of Lao Luo's article). See Dvmsetnativefunc directly
 void  dvmsetnativefunc (method* Method,       Dalvikbridgefunc func,  const  u2* Insns) { ...//parameter Func = Bridge 
//Parameter Insns = func ( Dvmsetnativefunc (method, Bridge, Func)); That is, Func = (void*) shy_luo_jni_classwithjni_nanosleep
 if  (Insns!= /*   update both, ensuring that "Insns" is observed first  */  Method->insns = Insns; Android_atomic_release_store ((int32_t) func, (void*) &method->  
     
      NATIVEFUNC); 
     }  else   { /*   */ Span style= "color: #000000;"      > method ->nativefunc = Func; }        ......  }
 in the Dvmsetnativefunc function, since bridge is assigned to Method->nativefunc,shy_luo_jni_classwithjni_ Nanosleep assigned to Method->insns, when will be executed to Shy_luo_jni_classwithjni_nanosleep AH (in Dalvik, If the method is native the Method->nativefunc will be executed )! With this question, we look back at Dvmselectjnibridge:
/** Returns the appropriate JNI bridge for ' method ', also taking to account * The-xcheck:jni setting. */  StaticDalvikbridgefunc Dvmselectjnibridge (Constmethod*method) {      enum{kjnigeneral=0, Kjnisync=1, Kjnivirtualnoref=2, Kjnistaticnoref=3,} kind; Static ConstDalvikbridgefunc stdfunc[] ={dvmcalljnimethod_general, dvmcalljnimethod_synchronized, Dvmcalljnimethod_virtualnoref,      DVMCALLJNIMETHOD_STATICNOREF}; Static ConstDalvikbridgefunc checkfunc[] ={dvmcheckcalljnimethod_general, dvmcheckcalljnimethod_synchronized, Dvmcheckcalljnimethod        _virtualnoref, dvmcheckcalljnimethod_staticnoref}; BOOLHasrefarg =false; if(Dvmissynchronizedmethod (method)) {/*Use version with synchronization; calls to General handler*/Kind=Kjnisync; .....if(hasrefarg) {/*Use General handler to slurp up reference args*/Kind=kjnigeneral; } Else {              /*virtual methods has a ref in Args[0] (not in signature)*/              if(Dvmisstaticmethod (method)) Kind=Kjnistaticnoref; ElseKind=Kjnivirtualnoref; }      }        returnDvmischeckjnienabled ()?Checkfunc[kind]: Stdfunc[kind]; }  
  look directly at the last return dvmischeckjnienabled ()? Checkfunc[kind]: stdFunc[ Kind]; Suppose to return  stdfunc  [kind]. Look at the above  stdfunc definition, that bridge is actually a function. We then assume that the most common dvmcalljnimethod_general, then in the  dvmcalljnimethod_general. OK, so let's take a look at  dvmcalljnimethod_general is executing our  shy_luo_jni_classwithjni_nanosleep. 
void dvmcalljnimethod_general (const u4* args, jvalue* pResult,    const method* method, thread* self )    ...    Dvmplatforminvoke (env, Staticmethodclass,        method->jniarginfo, Method->inssize, Modargs, method-> Shorty,        (void*) method->Insns, pResult);    ......}

Then look at Dvmplatforminvoke:

void dvmplatforminvoke (voidintint  argc,    constconst  charvoid* func, jvalue* preturn) {    ...    Ffi_call (&CIF, FFI_FN (func), Preturn, values);}

Wow, see no end or call Method->insns (in Java functions, the Method->insns in Dalvik is the DEX code of the function body) Shy_luo_jni_classwithjni_nanosleep.

OK, the steps in are all gone. Discovering the essence of JNI registration is to bind the native function body to the corresponding Java layer function body, so that Dalvik discovers that the function is native when native code can be executed.

Thinking:

1 method is native, Dalvik will call Method->nativefunc to execute; When is this native flag set? When Dex is loaded into Dalvik?

2 So library loads the process when Dlopen loads and then executes calls to its jni_onload function. What is the specific implementation process? is the reinforcement of so library a fuss here?

Resources:

1 Lao Luo's Android tour

Dalvik Analysis II: JNI, so

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.