SlideShare a Scribd company logo
1 of 102
Download to read offline
Discover System Facilities
  inside Your Android Phone



Jim Huang ( 黃敬群 )
Developer, 0xlab
                             jserv@0xlab.org

                    Feb 26, 2012 / Study-Area
Rights to copy
                                                           © Copyright 2011-2012 0xlab
                                                                        http://0xlab.org/
                                                                            contact@0xlab.org
Attribution – ShareAlike 3.0
You are free                                                  Corrections, suggestions, contributions and
                                                                               translations are welcome!
   to copy, distribute, display, and perform the work
   to make derivative works                                                  Latest update: Feb 26, 2012
   to make commercial use of the work
Under the following conditions
      Attribution. You must give the original author credit.
      Share Alike. If you alter, transform, or build upon this work, you may distribute the
      resulting work only under a license identical to this one.
   For any reuse or distribution, you must make clear to others the license terms of this
   work.
   Any of these conditions can be waived if you get permission from the copyright holder.
Your fair use and other rights are in no way affected by the above.
License text: http://creativecommons.org/licenses/by-sa/3.0/legalcode
Goals of This Presentation

• Pick up one Android phone and discover its internals
• Learn how to select the "weapons" to fight with
  Android system facilities
• Skipping Java parts, we focus on the native area:
  dynamic linking, processes, debugger, memory
  layout, IPC, and interactions with frameworks.
• It is not comprehensive to familarize Android. The
  goal is to utilize Android platforms, which are the
  popular and powerful development devices to us.
Agenda   Part I
         (0) Environment Setup
         (1) Hello World!
         Part II
         (2) Case: Angry Birds
         (3) Case: Binder driver
         (4) Case: Power Management
Environment Setup
Reference Hardware and Host
                            Configurations
• Android Phone: Nexus S
  – http://www.google.com/phone/detail/nexus-s
  – Install CyanogenMod (CM9; 4.0)
     http://www.cyanogenmod.com/

• Host: Lenovo x200
  – Ubuntu Linux 11.10+
• Toolchain: Sourcery CodeBench Lite
   – GNU/Linux Release 2011.09-70
  – http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/

• AOSP/CM9 source code: 4.0.3
• Android NDK r5c/r7b
Build CM9 from source

• Follow the instructions in Wiki
   – http://wiki.cyanogenmod.com/wiki/Building_from_source

• Follow the instructrions in AOSP
   – http://source.android.com/source/downloading.html
   – http://source.android.com/source/building.html
   – http://source.android.com/source/building-devices.html

• Obtaining proprietary binaries
  – Starting with ICS, AOSP can't be used from pure source code
    only, and requires additional hardware-related proprietary
    libraries to run, specifically for hardware graphics acceleration.
   – Binaries for Nexus Phones and Flagship Devices
      http://code.google.com/android/nexus/drivers.html
• Confirm the exact match
  – between AOSP version and proprietary packages
Steps to Build CM            (1)



• cyanogen-ics$ source build/envsetup.sh
  including device/moto/stingray/vendorsetup.sh
  including device/moto/wingray/vendorsetup.sh
  including device/samsung/maguro/vendorsetup.sh
  including device/samsung/toro/vendorsetup.sh
  including device/ti/panda/vendorsetup.sh
  including vendor/cm/vendorsetup.sh
  including sdk/bash_completion/adb.bash
• cyanogen-ics$ lunch
  You're building on Linux
  Lunch menu... pick a combo:
       1. full-eng                Target: cm_crespo
  …                             Configuration: userdebug
       8. full_panda-eng
       9. cm_crespo-userdebug
Steps to Build CM      (2)



• Which would you like? [full-eng] 9
  ============================================
  PLATFORM_VERSION_CODENAME=REL
  PLATFORM_VERSION=4.0.3
  TARGET_PRODUCT=cm_crespo
  TARGET_BUILD_VARIANT=userdebug
  TARGET_BUILD_TYPE=release
  TARGET_BUILD_APPS=
  TARGET_ARCH=arm
  TARGET_ARCH_VARIANT=armv7-a-neon
  HOST_ARCH=x86
  HOST_OS=linux
  HOST_BUILD_TYPE=release
  BUILD_ID=MR1
  ============================================
hello.c

           #include <stdio.h>
           int main()
           {
               printf("Hello World!n");
               return 0;
           }




Assume file hello.c is placed in directory 'test'
under AOSP top-level source tree.
Android.mk

          LOCAL_PATH:= $(call my-dir)

          include $(CLEAR_VARS)
          LOCAL_MODULE_TAGS := optional
          LOCAL_MODULE := hello
          LOCAL_SRC_FILES := hello.c
          include $(BUILD_EXECUTABLE)




Assume file Android.mk is placed in directory
'test' under AOSP top-level source tree.
Hello World!
                       (use Android toolchain and build rules)

• cd tests             Trigger Android build system to generate 'hello'
• mm -B
  No private recovery resources for TARGET_DEVICE crespo
  make: Entering directory `/home/jserv/cyanogen-ics'
  target thumb C: hello <= tests/hello.c
  target Executable: hello
  (out/target/product/crespo/obj/EXECUTABLES/hello_intermediates/LINKED/hello)
  target Symbolic: hello
  (out/target/product/crespo/symbols/system/bin/hello)
  target Strip: hello
  (out/target/product/crespo/obj/EXECUTABLES/hello_intermediates/hello)
  Install: out/target/product/crespo/system/bin/hello
• adb push 
      ../out/target/product/crespo/system/bin/hello 
      /data/local/

        For Android 'user' build, only directory
        /data/local is writable and executable.
Hello World!
                (deploy to Android device and execute)

• adb push 
      ../out/target/product/crespo/system/bin/hello 
      /data/local/
• adb shell /data/local/hello
 Hello World!
• arm-eabi-readelf -a 
      ../out/target/product/crespo/system/bin/hello
 ELF Header:
   Magic:    7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
   Class:                              ELF32
  ...
   Type:                               EXEC (Executable file)
   Machine:                            ARM
 ...
ADB: Android Debug Bridge
   ARCHITECTURE
       • ADB includes three compnenent: Server, Client and Daemon.


                   Host                                 Device/Emulator
      ADB           ADB             ADB                        Applications
      Client        Client          Client
                                                         APP              APP
                    ADT          Command
      DDMS
                   Eclipse         line




                 ADB Server                                    ADB Daemon




Details:
http://developer.android.com/guide/developing/tools/adb.html
Hello World!
        (use strace to trace the system calls during execution)

      • adb shell strace /data/local/hello
         execve("/data/local/hello", ["/data/local/hello"], [/*
         13 vars */]) = 0
         ...
         stat64("/system/lib/libc.so", {st_mode=S_IFREG|0644,
         st_size=282248, ...}) = 0
         open("/system/lib/libc.so", O_RDONLY|O_LARGEFILE) = 3
         ioctl(1, TCGETS or SNDCTL_TMR_TIMEBASE, {B38400 opost
         isig icanon echo ...}) = 0
         write(1, "Hello World!n", 13Hello World!
         )          = 13
         ...




The above log shows dynamic library
/system/lib/libc.so is open and manipulated.
Hello World!
                                           (Remote Debugging)
Map host port 12345 to device port 12345
• adb forward tcp:12345 tcp:12345
• adb shell gdbserver :12345 /data/local/hello
  Process /data/local/hello created; pid =
  18696          Run gdbserver on device to listen port 12345
  Listening on port 12345

  (execute the following in another terminal)
• arm-eabi-gdb 
       out/target/product/crespo/symbols/system/bin/hello
  (gdb) target remote :12345
  Remote debugging using :12345
arm-eabi-gdb 
    out/target/product/crespo/symbols/system/bin/hello
(gdb) target remote :12345

                     adb shell gdbserver :12345 /data/local/hello
                     Process /data/local/hello created; pid = 18696
                     Listening on port 12345

                 NOTE: You don't have to
                 specify TCP/IP address
                 because ADB forwarding
                 already prepares.




                      Port 12345

                                           gdb stub (gdbserver)
Linux host running
GDB                                           Android phone
'hello' is loaded (process created, PID=18696)
But not executed.                                                             Hello World!
        • adb shell cat /proc/18696/maps
         00008000-00009000   r-xp   00000000   b3:02   8959       /data/local/hello
         00009000-0000a000   rwxp   00001000   b3:02   8959       /data/local/hello
         b0001000-b0009000   r-xp   00001000   b3:01   128        /system/bin/linker
         b0009000-b000a000   rwxp   00009000   b3:01   128        /system/bin/linker
         b000a000-b0015000   rwxp   00000000   00:00   0
         beb07000-beb28000   rw-p   00000000   00:00   0          [stack]
         ffff0000-ffff1000   r-xp   00000000   00:00   0          [vectors]
        • (gdb) b main
          (gdb) c        Continue exec                        Process map changes after execuation.
          Continuing.                                         This means magic in dynamic linking!
        • adb shell cat /proc/18696/maps
         00008000-00009000   r-xp   00000000   b3:02   8959       /data/local/hello
         00009000-0000a000   rwxp   00001000   b3:02   8959       /data/local/hello
         40061000-40062000   r-xp   00000000   00:00   0
         40079000-40081000   r-xs   00000000   00:0b   392        /dev/__properties__ (deleted)
         40087000-400c9000   r-xp   00000000   b3:01   548        /system/lib/libc.so
         400c9000-400cc000   rwxp   00042000   b3:01   548        /system/lib/libc.so
         400cc000-400d7000   rwxp   00000000   00:00   0
         400d7000-400ec000   r-xp   00000000   b3:01   597        /system/lib/libm.so
         400ec000-400ed000   rwxp   00015000   b3:01   597        /system/lib/libm.so
         40101000-40102000   r-xp   00000000   b3:01   644        /system/lib/libstdc++.so
         40102000-40103000   rwxp   00001000   b3:01   644        /system/lib/libstdc++.so
         b0001000-b0009000   r-xp   00001000   b3:01   128        /system/bin/linker
         b0009000-b000a000   rwxp   00009000   b3:01   128        /system/bin/linker
         b000a000-b0015000   rwxp   00000000   00:00   0
         beb07000-beb28000   rw-p   00000000   00:00   0          [stack]
         ffff0000-ffff1000   r-xp   00000000   00:00   0          [vectors]
Everything starts from
    Hello World!
Execution flow of Hello World!                                (GNU/Linux)
                                                                  Dynamic Link
                                                                  Static Link

 Shell                                                           hello

            ./hello                       ld-linux.so

                                             Dynamic Linker

                                                        eglibc
                                       libc_start_main              main
            execve

                                            exit
           SYS_execve                    SYS_exit

kernel
     Examine Executable Start loader    Drop Process

         Allocate Process
Figure out ELF information                                  (glibc/x86)
• gcc -o hello hello.c
• readelf -a hello
 ...
   Type:                                     EXEC (Executable file)
   Machine:                                  Intel 80386
 ...
 Relocation section '.rel.plt' at offset 0x298 contains 3 entries:
  Offset       Info      Type               Sym.Value   Sym. Name
 0804a000    00000107 R_386_JUMP_SLOT        00000000    puts
 ...
 0804a008    00000307 R_386_JUMP_SLOT        00000000    __libc_start_main


 Symbol table '.dynsym' contains 5 entries:
      Num:    Value    Size Type     Bind     Vis       Ndx Name
 ...
        3: 00000000       0 FUNC     GLOBAL DEFAULT     UND __libc_start_main@GLIBC_2.0
 ….
 Program Headers:
   Type               Offset    VirtAddr     PhysAddr    FileSiz MemSiz   Flg Align
 ...
   INTERP             0x000154 0x08048154 0x08048154 0x00013 0x00013 R        0x1
         [Requesting program interpreter: /lib/ld-linux.so.2]
Figure out ELF information                   (Android/ARM)
• arm-eabi-readelf -a 
      ../out/target/product/crespo/system/bin/hello
 ...
   Machine:                           ARM
 ...
 Relocation section '.rel.plt' at offset 0x3c0 contains 2 entries:
  Offset      Info   Type            Sym.Value Sym. Name
 000090d4 00000216 R_ARM_JUMP_SLOT    00000000   __libc_init
 ...
 Symbol table '.dynsym' contains 18 entries:
     Num:    Value Size Type    Bind   Vis      Ndx Name
 ...
       2: 00000000    0 FUNC    GLOBAL DEFAULT UND __libc_init
 …
 Program Headers:
   Type            Offset   VirtAddr   PhysAddr   FileSiz
 ...
   INTERP          0x000114 0x00008114 0x00008114 0x00013
        [Requesting program interpreter: /system/bin/linker]
Execution flow of Hello World!                                (Android/ARM)
                                                                     Dynamic Link
                                                                     Static Link

  Shell                                                             hello

      /data/local/hello                  /system/bin/linker

                                                Dynamic Linker

                                                           bionic
                                             __libc_init               main
             execve

                                                exit
            SYS_execve                       SYS_exit

  kernel
       Examine Executable Start loader      Drop Process

          Allocate Process
ELF Image
     m.c                     a.c

 Translators                Translators
  (cc1, as)                   (cc1,as)                    Shared Library
                                                          Dynamically relocatable
                                                          object files
     m.o                     a.o

                                      Linker (ld)           $ ldd hello
                                                                libc.so.6 => /lib/i386-linux-
                                                            gnu/libc.so (0x00aab000)
       Partially linked              program libc.so            /lib/ld-linux.so.2 (0x00fdb000)
       executable
       (on disk)
                  ar g
                vect or         Loader / Dynamic Linker
                main(  )             (ld-linux.so)         libc.so functions called by m.c
               printf(  )                                  and a.c are loaded, linked, and
                   ..
                   ..
                                                           (potentially) shared among
                                                           processes.
Fully linked executable             Program’
(in memory)
.interp →elf_interpreter




                                       $ /lib/ld-linux.so.2
                                       Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-
                                       PROGRAM...]
                                       You have invoked `ld.so', the helper program for shared library
                                       executables. This program usually lives in the file `/lib/ld.so',
$ objdump -s -j .interp hello          and special directives in executable files using ELF shared
                                       libraries tell the system's program loader to load the helper
                                       program from this file. This helper program loads the shared
hello:    file format elf32-i386       libraries needed by the program executable, prepares the
                                       program to run, and runs it.

Contents of section .interp:
 8048114 2f6c6962 2f6c642d 6c696e75 782e736f    /lib/ld-linux.so
 8048124 2e3200                                 .2.
ELF Interpreter
• objdump -s -j .interp hello-x86
 hello:       file format elf32-i386

 Contents of section .interp:
  8048154 2f6c6962 2f6c642d 6c696e75 782e736f           /lib/ld-linux.so
  8048164 2e3200                                        .2.

• arm-eabi-objdump -s -j .interp 
 ../out/target/product/crespo/system/bin/hello

 ../out/target/product/crespo/system/bin/hello:   file format elf32-littlearm


 Contents of section .interp:
  8114 2f737973 74656d2f 62696e2f 6c696e6b          /system/bin/link
  8124 657200                                       er.
$ /lib/ld-linux.so.2
                                  $ /lib/ld-linux.so.2
                                  Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]
                                  Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]
$ file /lib/ld-linux.so.2
/lib/ld-linux.so.2: symbolic link to `i386-linux-gnu/ld-2.13.so'
$ file /lib/i386-linux-gnu/ld-2.13.so
/lib/i386-linux-gnu/ld-2.13.so: ELF 32-bit LSB shared object, Intel
80386, version 1 (SYSV), dynamically linked,
BuildID[sha1]=0x41de5107934017489907fa244bf835ce98feddc1, stripped
$ objdump -f /lib/ld-linux.so.2
/lib/ld-linux.so.2:      file format elf32-i386
architecture: i386, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED                  glibc
start address 0x000010e0                    sysdeps/generic/dl-sysdep.c
                                            elf/rtld.c
$ LD_DEBUG=help /lib/ld-2.13.so
Valid options for the LD_DEBUG environment variable
are:                                                       Hint
 libs           display library search paths
                                                           Try LD_DEBUG=XXX ./hello
 reloc      display relocation processing
 files          display progress for input file
 symbols    display symbol table processing
 bindings     display information about symbol binding
 versions     display version dependencies
 all            all previous options combined
 statistics     display relocation statistics
 unused     determined unused DSOs             Hint
 help                                          LD_TRACE_PRELINKING=1
                display this help message and exit                                       ./hello
Hello World!
(use plain Linux toolchain and try to execute in Android)
• export PATH=/usr/local/csl/arm-2011.09/bin:$PATH
• arm-none-linux-gnueabi-gcc -o hello hello.c
• adb push hello /data/local && 
  adb shell /data/local/hello               Why?!
  /system/bin/sh: /data/local/hello: No such file
  or directory
• arm-eabi-readelf -a hello | grep interpreter
  [Requesting program interpreter: /lib/ld-linux.so.3]
• find /usr/local/csl/arm-2011.09/                      Directory /lib is
  -name ld-linux.so.3                                    empty in Android.
  /usr/local/csl/arm-2011.09/arm-none-linux-gnueabi/libc/lib/ld-linux.so.3
  /usr/local/csl/arm-2011.09/arm-none-linux-gnueabi/libc/armv4t/lib/ld-
  linux.so.3
  /usr/local/csl/arm-2011.09/arm-none-linux-gnueabi/libc/thumb2/lib/ld-
  linux.so.3
• adb push    /usr/local/csl/arm-2011.09/arm-none-linux-
  gnueabi/libc/lib/ld-linux.so.3 /data/local/
Hello World!
Specify ELF interpreter                  (use GNU/Linux toolchain)
to /data/local/ld-linux.so.3

       • arm-none-linux-gnueabi-gcc -o hello hello.c 
         -Wl,-dynamic-linker,/data/local/ld-linux.so.3
       • adb push hello /data/local && 
         adb shell /data/local/hello
                                                                  Why?!
           Inconsistency detected by ld.so: dl-deps.c: 622:
           _dl_map_object_deps: Assertion `nlist > 1' failed!
       • adb shell strace /data/local/hello
           open("/vendor/lib/tls/v7l/neon/vfp/libgcc_s.so.1", O_RDONLY)
           = -1 ENOENT (No such file or directory)
           ...
           open("/usr/lib/libgcc_s.so.1", O_RDONLY) = -1 ENOENT (No such
           file or directory)
       • arm-none-linux-gnueabi-gcc -o hello hello.c 
         -Wl,-dynamic-linker,/data/local/ld-linux.so.3 
         -static-libgcc
                         Eliminate libgcc_s.so.1
                         dependency by static linking
Hello World!
                                        (use GNU/Linux toolchain)
•   arm-none-linux-gnueabi-gcc -o hello hello.c 
    -Wl,-dynamic-linker,/data/local/ld-linux.so.3 
    -static-libgcc
•   adb push hello /data/local && adb shell /data/local/hello
    Inconsistency detected by ld.so: dl-deps.c: 622: _dl_map_object_deps:
    Assertion `nlist > 1' failed!
•   adb shell strace /data/local/hello
    open("/usr/lib/libc.so.6", O_RDONLY)    = -1 ENOENT (No such file or
    directory)
•   find /usr/local/csl/arm-2011.09 -name libc.so.6
    /usr/local/csl/arm-2011.09/arm-none-linux-gnueabi/libc/lib/libc.so.6
    /usr/local/csl/arm-2011.09/arm-none-linux-             Let's provide libc
    gnueabi/libc/armv4t/lib/libc.so.6
    /usr/local/csl/arm-2011.09/arm-none-linux-
                                                           on Androi device.
    gnueabi/libc/thumb2/lib/libc.so.6
•   adb push /usr/local/csl/arm-2011.09/arm-none-linux-
    gnueabi/libc/lib/libc.so.6 /data/local/
•   arm-none-linux-gnueabi-gcc -o hello hello.c 
                                                         rpath: runtime
    -Wl,-dynamic-linker,/data/local/ld-linux.so.3 
    -static-libgcc -Wl,--rpath -Wl,/data/local
                                                         library search path
•   adb push hello /data/local && adb shell /data/local/hello
    Hello World!
Options when compiling and linking

• There is no libgcc runtime in Android target device. Build
  system looks for libgcc.a provided by toolchain and link it
  statically.
• Two flags have to be passed to linker
  – dynamic-linker
  – rpath
• Source file: build/core/combo/TARGET_linux-arm.mk
  define transform-o-to-executable-inner
  $(hide) $(PRIVATE_CXX) -nostdlib -Bdynamic -Wl,-T,$
  (BUILD_SYSTEM)/armelf.x 
          -Wl,-dynamic-linker,/system/bin/linker 
          -Wl,--gc-sections 
          -Wl,-z,nocopyreloc 
          -o $@ 
          $(TARGET_GLOBAL_LD_DIRS) 
          -Wl,-rpath-link=$(TARGET_OUT_INTERMEDIATE_LIBRARIES)
hello-crash.c

           #include <stdio.h>
           void hello() { printf("Hello World!n"); }
           void (*ptr)();
           int main()
           {
               ptr = &hello;
               (*ptr)();
               ptr = NULL;               NOTE: The reason why
               (*ptr)();                 we would take a memory
                                         violation program is that it
               return 0;                 can help us to trace the
           }                             internals when crashing.


Assume file hello-crash.c is placed in
directory 'test' under AOSP top-level source tree.
Hello Crash!

• mm -B
• adb push 
   ../out/target/product/crespo/system/bin/hello-crash 
   /data/local
• adb logcat -c
• adb shell /data/local/hello-crash
  Hello World!
  Segmentation fault
• adb logcat
Magic in Android debuggerd
• adb logcat
 ---------   beginning of /dev/log/main
 F/libc      (14127): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1)
 ...
 I/DEBUG     ( 8044): pid: 14127, tid: 14127 >>> /data/local/hello-crash <<<
 I/DEBUG     ( 8044): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
 ...
 I/DEBUG     (   8044):            #00   pc 00000000
 I/DEBUG     (   8044):            #01   pc 00008440     /data/local/hello-crash
 I/DEBUG     (   8044):            #02   pc 00016330     /system/lib/libc.so (__libc_init)
 I/DEBUG     (   8044):
 I/DEBUG     (   8044):   code around pc:
 I/DEBUG     (   8044):   00000000 ffffffff   ffffffff   ffffffff ffffffff ................
                                                          __libc_init was mentioned
 I/DEBUG     (   8044):   00000010 ffffffff   ffffffff   ffffffff ffffffff ................
                                                          in previous diagram
 I/DEBUG     (   8044):   00000020 ffffffff   ffffffff   ffffffff ffffffff ................
 I/DEBUG     (   8044):   00000030 ffffffff   ffffffff   ffffffff ffffffff ................
 I/DEBUG     (   8044):   00000040 ffffffff   ffffffff   ffffffff ffffffff ................

                 Call stack when
                 executing hello-crash
#00
#01
      pc 00000000
      pc 00008440    /data/local/hello-crash
                                                         Debuggerd
#02   pc 00016330    /system/lib/libc.so (__libc_init)



       • arm-eabi-addr2line -e 
          ../out/target/product/crespo/symbols/system/bin/hello-rash 
          00008440
          /home/jserv/cyanogen-ics/tests/hello-crash.c:6

      Line   01     #include <stdio.h>
      Line   02     void hello() { printf("Hello World!n"); }
      Line   03     void (*ptr)();
      Line   04     int main()
      Line   05     {
      Line   06         ptr = &hello;
      Line   07         (*ptr)();
      Line   08         ptr = NULL;
      Line   09         (*ptr)();
      Line   10         return 0;
      Line   11     }
#00
#01
       pc 00000000
       pc 00008440   /data/local/hello-crash
                                                         Debuggerd
#02    pc 00016330   /system/lib/libc.so (__libc_init)



        • addr2line -e 
             ../out/target/product/crespo/symbols/system/lib/libc.so   
             00016330
             /home/jserv/cyanogen-
             ics/bionic/libc/bionic/libc_init_dynamic.c:99




Line    94     __noreturn void __libc_init(uintptr_t *elfdata,
Line    95                       void (*onexit)(void),
Line    96                       int (*slingshot)(int, char**, char**),
Line    97                       structors_array_t const * const structors)
Line    98     {
Line    99         int     argc = (int)*elfdata;
How Debuggerd Works

• Android dynamic linker provides its own _start
  routine that registers a signal handler on SIGSEGV
  and the like.
• Whenever a dynamically linked executable crashes,
  the signal handler gets invoked and transmits the
  thread id of the crashing process to the debuggerd
  via a local socket.
   – bionic/linker/debugger.c
• The debuggerd uses ptrace to get the register
  contents of the crashing process and to display the
  call chain.
   – system/core/debuggerd/debuggerd.c
ELF symbol names are looked up
and browsable in debuggerd.




Use Android port of libunwind from Linaro to
Improve stack trace view
Two implementations for __libc_init

 • Two implementations
   – File bionic/libc/bionic/libc_init_dynamic.c
     /* This function is called from the executable's _start entry point
      * (see arch-$ARCH/bionic/crtbegin_dynamic.S), which is itself
      * called by the dynamic linker after it has loaded all shared
      * libraries the executable depends on.

   – File bionic/libc/bionic/libc_init_static.c
     __noreturn void __libc_init(uintptr_t *elfdata,
                               void (*onexit)(void),
                               int (*slingshot)(int, char**, char**),
                               structors_array_t const * const structors)


 • Very similar to each other
 • Require the corresponding
   crtbegin_{dynamic,static}.S
__noreturn void __libc_init(uintptr_t *elfdata,
                       void (*onexit)(void),
                       int (*slingshot)(int, char**, char**),
                       structors_array_t const * const structors)
{
    int     argc = (int)*elfdata;                                             Dynamic Link
    char** argv = (char**)(elfdata + 1);
    char** envp = argv + argc + 1;                                            Static Link

    if (structors->fini_array)
        __cxa_atexit(__libc_fini,structors->fini_array,NULL);
                                                                             hello

    exit(slingshot(argc, argv, envp));
}

                                                        Dynamic Linker

                                                                    bionic
                                                    __libc_init                 main
                  execve

                                                        exit
                SYS_execve                          SYS_exit

       kernel
             Examine Executable Start loader       Drop Process

              Allocate Process
Memory Allocation
 while executing
  Hello World!
Magic number
                                                                                                      ELF
                                         
   Page size
   Virtual address
                                            type (.o / .so / exec)
    memory segment                          Machine
    (sections)                              byte order
   Segment size                            …
                                                                                                            0
                                                                                   ELF header
            Initialized (static) data                                         Program header table
                                                    code
                                                                             (required for executables)
   Un-initialized (static) data
   Block started by symbol                                                      .text section
   Has section header but                                                       .data section
    occupies no space
                                                                                  .bss section

           Symbol table                                                            .symtab
           Procedure and static variable names                                    .rel.txt
           Section name
                                                                                  .rel.data
           Relocation info for .text section
                                                                                     .debug
           Addresses of instructions that need to be
            modified in the executable instructions for                        Section header table
            modifying.                                                       (required for relocatables)

           Relocation info for .data section                  Info for symbolic debugging
           Address pointer data will need to be
            modified in the merged executable
$ readelf -s hello

Symbol table '.dynsym' contains 5 entries:
  Num: Value Size Type Bind Vis           Ndx Name
   0:   00000000   0 NOTYPE   LOCAL DEFAULT    UND
   1:   00000000 399 FUNC     GLOBAL DEFAULT   UND puts@GLIBC_2.0 (2)
   2:   00000000 415 FUNC     GLOBAL DEFAULT   UND __libc_start_main@GLIBC_2.0 (2)
   3:   08048438   4 OBJECT   GLOBAL DEFAULT    14 _IO_stdin_used
   4:   00000000   0 NOTYPE   WEAK DEFAULT     UND __gmon_start__

Symbol table '.symtab' contains 81 entries:



                                                   -s|--syms|--symbols
$ cp -f hello hello.strip                       –     Displays the entries in symbol table
$ strip –s hello.strip                                section of the file, if it has one   .
  $ readelf -s hello.strip

  Symbol table '.dynsym' contains 5 entries:
    Num: Value Size Type Bind Vis           Ndx Name
     0: 00000000   0 NOTYPE LOCAL DEFAULT       UND
     1: 00000000 399 FUNC GLOBAL DEFAULT        UND puts@GLIBC_2.0 (2)
     2: 00000000 415 FUNC GLOBAL DEFAULT        UND __libc_start_main@GLIBC_2.0 (2)
     3: 08048438   4 OBJECT GLOBAL DEFAULT       14 _IO_stdin_used
     4: 00000000   0 NOTYPE WEAK DEFAULT        UND __gmon_start__
ELF
Executable object file                   Process image

                                0
      ELF header
                                                                 Virtual address
  Program header table
(required for executables)                                       0x080483e0
                                         init and shared lib
      .text section                           segments

      .data section
                                                                 0x08048494
      .bss section                        .text segment
                                              (r/o)
        .symtab

         .rel.text                                               0x0804a010
                                          .data segment
        .rel.data                          (initialized r/w)

         .debug
                                                                 0x0804a3b0
  Section header table                    .bss segment
(required for relocatables)               (un-initialized r/w)


                              Loading ELF Binaries…
GOT (global offset table):in data segment
PLT (procedure linkage table): in code segment
Each process has its own address space                          FF


          Address Space
0xffffffff                                                                     C0
               kernel virtual memory       memory                              BF    Stack
              (code, data, heap, stack)    invisible to
0xc0000000                                 user code               Runtime stack
                    user stack                                     8 Mb limit
                (created at runtime)
                                            %esp (stack pointer)

                                                                               80
             memory mapped region for                                          7F
                 shared libraries                                                    Heap
0x40000000


                                              brk                                    Shared
                  run-time heap                                                     Libraries
                (managed by malloc)                                            40
                read/write segment
                                                                               3F
                    (.data, .bss)                                                    Heap
                                           loaded from the
                read-only segment          executable file
                 (.init, .text, .rodata)                                              Data
0x08048000
                       unused                                                  08     Text
      0
                                                                               00
                                           Linux memory layout
Linux Memory Allocation
     Initial        Linked           Heap (1)         Heap (2)
BF     Stack   BF     Stack     BF     Stack     BF     Stack




80             80               80               80
7F             7F               7F               7F
                                                        Heap
                                       Heap

40             40   Libraries   40   Libraries   40   Libraries
3F             3F               3F               3F
                                                        Heap
       Data           Data             Data             Data
08     Text    08     Text      08     Text      08     Text
00             00               00               00
Stack “Bottom”                          Linked
i386 stack                                                            BF     Stack


                                                   Address increase


                                                                      80
                                                    Stack increase    7F
                   Stack pointer
                       %esp

                                     Stack “Top”
   Stack                                popl DEST
                                                                      40   Libraries
   Push                                                               3F
  pushl SRC                              Stack
                                          Pop                                Data
                                                                      08     Text
                                                                      00
                                          Stack
                                         Pointer
 Stack                                    %esp
                                                    +4
Pointer
              -4
 %esp
Recall process maps
• adb shell cat /proc/18696/maps
  00008000-00009000 r-xp 00000000   b3:02   8959    /data/local/hello
  00009000-0000a000 rwxp 00001000   b3:02   8959    /data/local/hello
  40061000-40062000 r-xp 00000000   00:00   0
  40079000-40081000 r-xs 00000000   00:0b   392     /dev/__properties__ (deleted)
  40087000-400c9000 r-xp 00000000   b3:01   548     /system/lib/libc.so
  400c9000-400cc000 rwxp 00042000   b3:01   548     /system/lib/libc.so
  400cc000-400d7000 rwxp 00000000   00:00   0
  400d7000-400ec000 r-xp 00000000   b3:01   597     /system/lib/libm.so
  400ec000-400ed000 rwxp 00015000   b3:01   597     /system/lib/libm.so
  40101000-40102000 r-xp 00000000   b3:01   644     /system/lib/libstdc++.so
  40102000-40103000 rwxp 00001000   b3:01   644     /system/lib/libstdc++.so
  b0001000-b0009000 r-xp 00001000   b3:01   128     /system/bin/linker
  b0009000-b000a000 rwxp 00009000   b3:01   128     /system/bin/linker
  b000a000-b0015000 rwxp 00000000   00:00   0
  beb07000-beb28000 rw-p 00000000   00:00   0       [stack]
  ffff0000-ffff1000 r-xp 00000000   00:00   0       [vectors]


Meaning of each field:
 start-end perm offset major:minor inode image

Start-end: The beginning and ending virtual addresses for this memory area.
Perm: a bit mask with the memroy area’s read, write, and execute permissions
Offset: Where the memory area begins in the file
Major/Minor: Major and minor numbers of the device holding the file (or partition)
Map vs. ELF sections
 • arm-eabi-objdump -h 
       ../out/target/product/crespo/system/bin/hello
   Sections:
   Idx Name          Size      VMA       LMA       File off Algn
     0 .interp       00000013 00008114 00008114 00000114 2**0
                     CONTENTS, ALLOC, LOAD, READONLY, DATA
   ...
     4 .rel.plt      00000018 000083dc 000083dc 000003dc 2**2
                     CONTENTS, ALLOC, LOAD, READONLY, DATA
     5 .plt          00000038 000083f4 000083f4 000003f4 2**2
                     CONTENTS, ALLOC, LOAD, READONLY, CODE
     6 .text         00000054 00008430 00008430 00000430 2**4
                     CONTENTS, ALLOC, LOAD, READONLY, CODE
     7 .rodata       0000000d 00008484 00008484 00000484 2**0
                     CONTENTS, ALLOC, LOAD, READONLY, DATA
 • adb shell cat /proc/18696/maps
 00008000-00009000 r-xp 00000000 b3:02 8959       /data/local/hello
 00009000-0000a000 rwxp 00001000 b3:02 8959       /data/local/hello



.data section of 'hello' program → Readable and Writable

                      .text section of 'hello' program → Read-only
Recall process maps
     • adb shell cat /proc/18696/maps
                                                   .bss section of libc
       00008000-00009000 r-xp 00000000   b3:02   8959      /data/local/hello
       00009000-0000a000 rwxp 00001000   b3:02   8959      /data/local/hello
       40061000-40062000 r-xp 00000000   00:00   0
       40079000-40081000 r-xs 00000000   00:0b   392       /dev/__properties__ (deleted)
       40087000-400c9000 r-xp 00000000   b3:01   548       /system/lib/libc.so
       400c9000-400cc000 rwxp 00042000   b3:01   548       /system/lib/libc.so
       400cc000-400d7000 rwxp 00000000   00:00   0
       400d7000-400ec000 r-xp 00000000   b3:01   597       /system/lib/libm.so
       400ec000-400ed000 rwxp 00015000   b3:01   597       /system/lib/libm.so
       40101000-40102000 r-xp 00000000   b3:01   644       /system/lib/libstdc++.so
       40102000-40103000 rwxp 00001000   b3:01   644       /system/lib/libstdc++.so
       b0001000-b0009000 r-xp 00001000   b3:01   128       /system/bin/linker
       b0009000-b000a000 rwxp 00009000   b3:01   128       /system/bin/linker
       b000a000-b0015000 rwxp 00000000   00:00   0
       beb07000-beb28000 rw-p 00000000   00:00   0         [stack]
       ffff0000-ffff1000 r-xp 00000000   00:00   0         [vectors]

                                                        .text section of dynamic linker
.data section of dynamic linker

                             .bss section of dynamic linker
•   adb shell cat /proc/18696/maps
                                                         00008000-00009000 r-xp 00000000 /data/local/hello
                                                         00009000-0000a000 rwxp 00001000 /data/local/hello
                                                         40061000-40062000 r-xp 00000000 00:00 0
                                                         40079000-40081000 r-xs 00000000 /dev/__properties
                                                         40087000-400c9000 r-xp 00000000 /system/lib/libc.so
                process-specific data                    400c9000-400cc000 rwxp 00042000 /system/lib/libc.so
                      structures
                                                         400cc000-400d7000 rwxp 00000000 00:00 0
                     (page tables,
                 task and mm structs)                    400d7000-400ec000 r-xp 00000000 /system/lib/libm.so
                                                         400ec000-400ed000 rwxp 00015000 /system/lib/libm.so
                                            demand-zero
same for           physical memory                       40101000-40102000 r-xp 00000000 /system/lib/libstdc++.so
  each                                                   40102000-40103000 rwxp 00001000 /system/lib/libstdc++.so
process                                     kernel       b0001000-b0009000 r-xp 00001000 /system/bin/linker
                kernel code/data/stack      VM
  0xc0                                                   b0009000-b000a000 rwxp 00009000 /system/bin/linker
 %esp                    stack                           b000a000-b0015000 rwxp 00000000 00:00 0
                                             process beb07000-beb28000 rw-p 00000000 [stack]
                                             VM
                                                         ffff0000-ffff1000 r-xp 00000000 [vectors]

               Memory mapped region               .data
                 for shared libraries             .text
                                                                         NOTE: reverse order between
                                                libc.so                  process view and maps
   brk
               runtime heap (via malloc)
                                                demand-zero
                uninitialized data (.bss)
                initialized data (.data)          .data
                  program text (.text)            .text
                       forbidden               program
           0
Case Study




       GDB meets Angry Birds
Setup (1)

• Download Android NDK
  – http://developer.android.com/sdk/ndk/
  – Version: r7b / r5c
• Download apktool
  – a tool for reverse engineering 3rd party, closed,
    binary Android apps. It can decode resources to
    nearly original form and rebuild them after making
    some modifications
  – http://code.google.com/p/android-apktool/
• Download Angry Birds Rio from Androi Market
  – Date: Feb 3, 2012
APK content

$ unzip Angry+Birds.apk
Archive: Angry+Birds.apk
...
  inflating: AndroidManifest.xml
 extracting: resources.arsc
 extracting: res/drawable-hdpi/icon.png
 extracting: res/drawable-ldpi/icon.png
 extracting: res/drawable-mdpi/icon.png
  inflating: classes.dex Dalvik DEX
  inflating: lib/armeabi/libangrybirds.so JNI
  inflating: lib/armeabi-v7a/libangrybirds.so
  inflating: META-INF/MANIFEST.MF
  inflating: META-INF/CERT.SF
                                   manifest +
  inflating: META-INF/CERT.RSA      signature
AndroidManifest

    $ unzip Angry+Birds.apk
    Archive: Angry+Birds.apk
    ...
    ...
      inflating: AndroidManifest.xml
     extracting: resources.arsc
     extracting: res/drawable-hdpi/icon.png
$ file AndroidManifest.xml
     extracting: res/drawable-ldpi/icon.png
AndroidManifest.xml: DBase 3 data file (2328 records)
     extracting: res/drawable-mdpi/icon.png
$ apktool d ../AngryBirds/Angry+Birds.apk
      inflating: classes.dex
I: Baksmaling...
I: Loading resource lib/armeabi/libangrybirds.so
      inflating: table...
...
      inflating: lib/armeabi-v7a/libangrybirds.so
I: Decoding file-resources...
      inflating: META-INF/MANIFEST.MF
I: Decoding values*/* XMLs...
I: Done.
      inflating: META-INF/CERT.SF
I: Copying assets and libs...
$ fileinflating: META-INF/CERT.RSA
       Angry+Birds/AndroidManifest.xml
Angry+Birds/AndroidManifest.xml: XML   document text
Setup (2)
• Pull Angry Birds' APK and extract
  adb pull /data/app/com.rovio.angrybirdsrio-1.apk
  java -jar apktool.jar d com.rovio.angrybirdsrio-1.apk

• Prepare environment to satisfy NDK
  cp -af com.rovio.angrybirdsrio-1/lib/ libs
  mkdir -p obj/local/armeabi obj/local/armeabi-v7a
  cp -f libs/armeabi/libangrybirds.so ./obj/local/armeabi/ 
                                      ./obj/local/armeabi-v7a/
  echo "set solib-search-path `pwd`/obj/local/armeabi" > 
        libs/armeabi/gdb.setup
  cp -f libs/armeabi/gdb.setup libs/armeabi-v7a/gdb.setup

• Use gdbserver from NDK
  adb push android-ndk-r7b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/gdbserver 
               /data/data/com.rovio.angrybirdsrio/lib
Use GDB from Android NDK(1)

• $ android-ndk-r7b/ndk-gdb --verbose –force 
                             --launch=com.rovio.ka3d.App
  Android NDK installation path: /tmp/angry-birds/android-ndk-r7b
  Using default adb command: /usr/bin/adb
  ADB version found: Android Debug Bridge version 1.0.26
  Using ADB flags:
  Using auto-detected project path: .
  Found package name: com.rovio.angrybirdsrio
  ...
  Launching activity: com.rovio.angrybirdsrio/com.rovio.ka3d.App
  ## COMMAND: /usr/bin/adb shell am start -n
  com.rovio.angrybirdsrio/com.rovio.ka3d.App
  Starting: Intent { cmp=com.rovio.angrybirdsrio/com.rovio.ka3d.App }
  ...
  GDB will be unable to debug shared library initializers
  and track explicitly loaded dynamic code.
  warning: shared library handler failed to enable breakpoint
  0x40043384 in epoll_wait ()
      from /tmp/angry-birds/obj/local/armeabi/libc.so
  (gdb)
Use GDB from Android NDK(2)

• (gdb) info shared
 From         To           Syms Read   Shared Object Library
                           No          /system/bin/linker
 0x40041fc0   0x4006f99c   Yes         armeabi/libc.so
                           No          libstdc++.so
                           No          libm.so
                           No          liblog.so
                           No          libcutils.so
                           No          libz.so
 ...
 0x507b0ae8   0x508ec948   Yes         armeabi/libangrybirds.so
Use GDB from Android NDK(3)

(gdb) set $m = (int*)malloc(480*699*4)
(gdb)
(gdb) set $f = fopen("/sdcard/outputfile", "wb+")
(gdb) call fwrite($m, 1, 480*699*4, $f)
$1 = 1342080
(gdb) call fclose($f)
$2 = 0                   You can dump memory/variables/buffer
(gdb) x/s __progname     into storage for observation purpose.
0xbef30d26: "com.rovio.angrybirdsrio"

(gdb) print __page_size
$3 = 4096
Case Study




      Binder IPC: The heart of Android




For detailed interaction and implementations,
please check my presentation in 南台科技大學資
工系 (March 19, 2012)
Processes running on Android
$ ps
    ...
root        37    1    248      156     c00aef2c   0000875c   S   /sbin/ueventd
system      42    1    768      260     c022950c   afd0b6fc   S   /system/bin/servicemanager
root        43    1    3824     564     ffffffff   afd0bdac   S   /system/bin/vold
root        44    1    3796     560     ffffffff   afd0bdac   S   /system/bin/netd
root        45    1    628      264     c02588c0   afd0c0cc   S   /system/bin/debuggerd
radio       46    1    4336     672     ffffffff   afd0bdac   S   /system/bin/rild
root        47    1    62224    27576   c00aef2c   afd0b844   S   zygote
media       48    1    16828    3736    ffffffff   afd0b6fc   S   /system/bin/mediaserver
bluetooth   49    1    1216     572     c00aef2c   afd0c59c   S   /system/bin/dbus-daemon
root        50    1    776      316     c02a8424   afd0b45c   S   /system/bin/installd
keystore    51    1    1704     432     c02588c0   afd0c0cc   S   /system/bin/keystore
shell       52    1    696      336     c0050934   afd0c3ac   S   /system/bin/sh
root        53    1    3356     160     ffffffff   00008294   S   /sbin/adbd
system      67    47   172464   32596   ffffffff   afd0b6fc   S   system_server
system      115   47   80028    20728   ffffffff   afd0c51c   S   com.android.systemui
app_24      124   47   80732    20720   ffffffff   afd0c51c   S   com.android.inputmethod.latin
radio       135   47   87848    20324   ffffffff   afd0c51c   S   com.android.phone
app_18      144   47   89136    24160   ffffffff   afd0c51c   S   com.android.launcher
app_7       165   47   86136    22736   ffffffff   afd0c51c   S   android.process.acore
app_0       197   47   73996    17472   ffffffff   afd0c51c   S   com.android.deskclock
app_14      208   47   75000    18464   ffffffff   afd0c51c   S   android.process.media
app_3       219   47   72228    17652   ffffffff   afd0c51c   S   com.android.bluetooth
app_25      234   47   85336    17836   ffffffff   afd0c51c   S   com.android.mms
app_26      254   47   74656    19080   ffffffff   afd0c51c   S   com.android.email
app_27      266   47   74912    18100   ffffffff   afd0c51c   S   com.android.providers.calendar
app_1       285   47   71616    16280   ffffffff   afd0c51c   S   com.android.protips
app_19      293   47   72184    16572   ffffffff   afd0c51c   S   com.android.music
app_21      301   47   74728    17208   ffffffff   afd0c51c   S   com.android.quicksearchbox
app_28      311   47   75408    18040   ffffffff   afd0c51c   S   com.cooliris.media
shell       323   52   856      316     00000000   afd0b45c   R   ps
$
                   More than 30 processes (200+ threads).
IPC = Inter-Process Communication




                Activity
     Activity              Window     Alarm
     Manager               Manager   Manager




Kernel
IPC Abstraction

                  More abstract
Intent                            • Intent
                                     – The highest level abstraction
    AIDL                          • Inter process method invocation
                                     – AIDL: Android Interface
         Binder                       Definition Language
                                  • binder: kernel driver
                                  • ashmem: shared memory
Method invocation




      caller




      callee


In the same process
Inter-process method invocation


                        caller
                                   interface



caller

            interface
                            How?
callee

                                   interface


                        callee
Inter-process method invocation


                           caller
                                            interface


                           Proxy
caller

            interface    Binder in kernel


                        Binder Thread
callee
                             Stub
                                            interface


                           callee
android.os.Parcel



            Delivering arguments of method




”flatten”                                    ”unflatten”


                     transmit
UML Representation



        <<interface>>

                   implements


Proxy                   Stub
UML Representation

                                 caller



        <<interface>>              calls


                   implements


Proxy                   Stub

                               extends

                        callee
AIDL

Auto generated from .aidl file                      caller



                           <<interface>>




                   Proxy                   Stub



                                           callee
Use Case:
             Who calls onPause() in Activity?
                  2
                      Send message
                       by Handler         Activity

                                                     3
                                                         OnPause() is
                      queue               Looper     called in main thread

  Activity
  Manager                                   Main
                        Binder             Thread
                       Thread #1




Kernel        1

                  Call ”schedulePauseActivity”
                         across process
Binder

• Multi-thread aware
  – Have internal status per thead
  – Compare to UNIX socket: sockets have internal
    status per file descriptor (FD)
Binder




 A pool of threads is associated to each service application to process
  incoming IPC (Inter-Process Communication).
 Binder performs mapping of object between two processes.
 Binder uses an object reference as an address in a process’s memory
  space.
 Synchronous call, reference couting
Binder
Binder is different from UNIX socket

                  socket             binder
internal status   associated to FD   associated to PID
                                     (FD can be shared among
                                     threads in the same
                                     process)


read & write      stream I/O         done at once by
operation                            ioctl

network           Yes                No
transparency                         expected local only
Transaction of Binder

                      binder_write_read
         write_size                        write buffer
    write_consumed
       write_buffer
        read_size
    read_consumed                          read buffer
       read_buffer




if (ioctl(fd, BINDER_WRITE_READ, &bwt ) >= 0)
     err = NO_ERROR;
else
     err = -errno;
Transaction of Binder
                                           Process A and B have different memory space.
                                           They can not see each other.
             Kernel                             Process B
                                             Process A
                       Binder



                                 Copy memory by copy_from _user
                                 Then, wake up process B

             Kernel
                                                  Process B
                       Binder



                                             Process A
                                 Copy memory by copy_to_user



Internally, Android uses Binder for graphics data transaction across processes.
                               It is fairly efficient.
Binder sample program

• Build binder benchmark program
  cd system/extras/tests/binder/benchmarks
  mm
  adb push 
   ../../../../out/target/product/crespo/data/nativebenchmark/binderAddInts   
    /data/local/
• Execute
  adb shell
  su
  /data/local/binderAddInts -d 5 -n 5 &
  ps
  ...
  root      17133 16754 4568          860     ffffffff 400e6284 S
  /data/local/binderAddInts
  root      17135 17133 2520          616     00000000 400e5cb0 R
  /data/local/binderAddInts
Binder sample program

• Execute
  /data/local/binderAddInts -d 5 -n 5 &
  ps
  ...
  root      17133 16754 4568   860   ffffffff 400e6284 S
  /data/local/binderAddInts
  root      17135 17133 2520   616   00000000 400e5cb0 R
  /data/local/binderAddInts
  cat /sys/kernel/debug/binder/transaction_log
  transaction_log:3439847: call from 17133:17133 to 72:0 node
  1 handle 0 size 124:4
  transaction_log:3439850: reply from 72:72 to 17133:17133 node
  0 handle 0 size 4:0
  transaction_log:3439855: call from 17135:17135 to 17133:0
  node 3439848 handle 1 size 8:0
  ...
Binder sysfs entries

• adb shell ls /sys/kernel/debug/binder
  failed_transaction_log
  proc
  state
  stats
  transaction_log
  transactions
Communication protocol




If one process sends data to another process, it is called transaction.
The data is called transaction data.
Binder use case: Android Graphics
Real Case




Binder IPC is used for communicating between Graphics client and server.
Taken from http://www.cnblogs.com/xl19862005/archive/2011/11/17/2215363.html
Surface

  Source: frameworks/base/core/java/android/view/Surface.java
• /* Handle on to a raw buffer that is being
  managed by the screen compositor */
  public class Surface implements Parcelable {
     public Surface() {
        mCanvas = new CompatibleCanvas();
      }
      private class CompatibleCanvas
               extends Canvas { /* ... */ }
  }
 Surface instances can be written to and restored from a Parcel.
 Surface instances can be written to and restored from a Parcel.
Delivering arguments of method



”flatten”                                    ”unflatten”


                     transmit
   Properties
                                   Android SurfaceFlinger
        Can combine 2D/3D surfaces and surfaces from multiple applications
        Surfaces passed as buffers via Binder IPC calls
        Can use OpenGL ES and 2D hardware accelerator for its compositions
             Double-buffering using page-flip
Case Study




    Android Power Management:
 how to interact between system and framework
Base: Linux Kernel



Android does rely on Linux Kernel for core system
services
●   Memory/Process Management
●   Device Driver Model
●   sysfs, kobject/uevent, netlink
Android Kernel extensions
●   Binder                      Key Idea: Android attempts to provide
                                Key Idea: Android attempts to provide
                                    an abstraction layer between
                                     an abstraction layer between
●   android_power              hardware and the related software stack.
                               hardware and the related software stack.

     –   /sys/android_power/, /sys/power/
Android's PM Concepts
     Android PM is built on top of standard Linux Power Management.
     It can support more aggressive PM, but looks fairly simple now.
     Components make requests to keep the power on through
     “Wake Locks”.
      ●   PM does support several types of “Wake Locks”.




If there are no active wake locks, CPU will
be turned off.

If there is are partial wake locks, screen
and keyboard will be turned off.
PM State Machine
Touchscreen or keyboard user activity
Touchscreen or keyboard user activity
  event or full wake locks acquired.
  event or full wake locks acquired.




        All partial wake locks
        All partial wake locks
               released
                released

                     Partial wake locks acquired
                     Partial wake locks acquired
Design and Implementation




IBinder as interface
 IBinder as interface
  to PowerManager
   to PowerManager
Sample WakeLocks usage: AudioFlinger
•   File frameworks/base/services/audioflinger/AudioFlinger.cpp
    void AudioFlinger::ThreadBase::acquireWakeLock_l() {
        if (mPowerManager == 0) {
             sp<IBinder> binder =
                 defaultServiceManager()->checkService(String16("power"));
             if (binder == 0) {
                 LOGW("Thread %s can't connect to the PM service", mName);
             } else {
                 mPowerManager = interface_cast<IPowerManager>(binder);
                 binder->linkToDeath(mDeathRecipient);
             }
        }
        if (mPowerManager != 0) {
             sp<IBinder> binder = new BBinder();
             status_t status =
                 mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK,
                                                     binder, String16(mName));
             if (status == NO_ERROR) { mWakeLockToken = binder; }
             LOGV("acquireWakeLock_l() %s status %d", mName, status);
        }
    }
android_os_Power
                               frameworks/base/core/jni/android_os_Power.cpp
                               frameworks/base/core/jni/android_os_Power.cpp
...
...
static JNINativeMethod method_table[] = {
static JNINativeMethod method_table[] = {
    { "acquireWakeLock", "(ILjava/lang/String;)V", (void*)acquireWakeLock },
    { "acquireWakeLock", "(ILjava/lang/String;)V", (void*)acquireWakeLock },
    { "releaseWakeLock", "(Ljava/lang/String;)V", (void*)releaseWakeLock },
    { "releaseWakeLock", "(Ljava/lang/String;)V", (void*)releaseWakeLock },
    { "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout },
    { "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout },
    { "setLightBrightness", "(II)I", (void*)setLightBrightness },
    { "setLightBrightness", "(II)I", (void*)setLightBrightness },
    { "setScreenState", "(Z)I", (void*)setScreenState },
    { "setScreenState", "(Z)I", (void*)setScreenState },
    { "shutdown", "()V", (void*)android_os_Power_shutdown },
    { "shutdown", "()V", (void*)android_os_Power_shutdown },
    { "reboot", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot },
    { "reboot", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot },
};
};
int register_android_os_Power(JNIEnv *env)
 int register_android_os_Power(JNIEnv *env)
{{
     return AndroidRuntime::registerNativeMethods(
     return AndroidRuntime::registerNativeMethods(
         env, "android/os/Power",
         env, "android/os/Power",
         method_table, NELEM(method_table));
         method_table, NELEM(method_table));
}}



                               static void
                               static void
                               acquireWakeLock(JNIEnv *env, jobject clazz,
                               acquireWakeLock(JNIEnv *env, jobject clazz,
                                               jint lock, jstring idObj)
                                                jint lock, jstring idObj)
                               {
                               {
                                   if (idObj == NULL) {
                                   if (idObj == NULL) {
                                       throw_NullPointerException(env, "id is null");
                                       throw_NullPointerException(env, "id is null");
                                       return ;
                                       return ;
                                   }
                                   }
                                   const char *id = env->GetStringUTFChars(idObj, NULL);
                                   const char *id = env->GetStringUTFChars(idObj, NULL);
                                   acquire_wake_lock(lock, id);
                                   acquire_wake_lock(lock, id);
                                   env->ReleaseStringUTFChars(idObj, id);
                                   env->ReleaseStringUTFChars(idObj, id);
                               }
                               }
Power
                                                          hardware/libhardware_legacy/power/power.c
                                                          hardware/libhardware_legacy/power/power.c
                                                          ...
                                                          ...
                                                          int
                                                          int
                                                          acquire_wake_lock(int lock, const char* id)
                                                          acquire_wake_lock(int lock, const char* id)
                                                          {
                                                          {
                                                              initialize_fds();
                                                              initialize_fds();
const char * const OLD_PATHS[] = {
const char * const OLD_PATHS[] = {                            if (g_error) return g_error;
                                                              if (g_error) return g_error;
    "/sys/android_power/acquire_partial_wake_lock",
    "/sys/android_power/acquire_partial_wake_lock",
    "/sys/android_power/release_wake_lock",
    "/sys/android_power/release_wake_lock",                   int fd;
                                                              int fd;
    "/sys/android_power/request_state"
    "/sys/android_power/request_state"                        if (lock == PARTIAL_WAKE_LOCK) {
                                                              if (lock == PARTIAL_WAKE_LOCK) {
};
};                                                                fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];
                                                                  fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];
                                                              }
                                                              }
const char * const NEW_PATHS[] = {
const char * const NEW_PATHS[] = {                            else {
                                                              else {
    "/sys/power/wake_lock",
    "/sys/power/wake_lock",                                       return EINVAL;
                                                                  return EINVAL;
    "/sys/power/wake_unlock",
    "/sys/power/wake_unlock",                                 }
                                                              }
    "/sys/power/state"
    "/sys/power/state"                                        return write(fd, id, strlen(id));
                                                              return write(fd, id, strlen(id));
};
};                                                        }
                                                          }
        (Kernel interface changes in Android Cupcake)
        (Kernel interface changes in Android Cupcake)




                                                        static inline void
                                                        static inline void
                                                        initialize_fds(void)
                                                        initialize_fds(void)
                                                        {
                                                        {
                                                            if (g_initialized == 0) {
                                                            if (g_initialized == 0) {
                                                                if(open_file_descriptors(NEW_PATHS) < 0) {
                                                                if(open_file_descriptors(NEW_PATHS) < 0) {
                                                                    open_file_descriptors(OLD_PATHS);
                                                                    open_file_descriptors(OLD_PATHS);
                                                                    on_state = "wake";
                                                                    on_state = "wake";
                                                                    off_state = "standby";
                                                                    off_state = "standby";
                                                                }
                                                                }
                                                                g_initialized = 1;
                                                                g_initialized = 1;
                                                            }
                                                            }
                                                        }
                                                        }
Android PM Kernel APIs
   Source code
                                                 static long has_wake_lock_locked(int type)
                                                 static long has_wake_lock_locked(int type)
                                                 {
                                                 {
                                                      struct wake_lock *lock, *n;
                                                      struct wake_lock *lock, *n;
                                                      long max_timeout = 0;
                                                      long max_timeout = 0;
    ●   kernel/power/userwake.c                       BUG_ON(type >= WAKE_LOCK_TYPE_COUNT);
                                                      BUG_ON(type >= WAKE_LOCK_TYPE_COUNT);
                                                      list_for_each_entry_safe(lock, n,
                                                      list_for_each_entry_safe(lock, n,
                                                                &active_wake_locks[type], link) {
                                                                 &active_wake_locks[type], link) {
    ●   /kernel/power/wakelock.c                           if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) {
                                                           if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) {
                                                                long timeout = lock->expires - jiffies;
                                                                long timeout = lock->expires - jiffies;
                                                                if (timeout <= 0)
                                                                if (timeout <= 0)
                                                                     expire_wake_lock(lock);
                                                                      expire_wake_lock(lock);
                                                                else if (timeout > max_timeout)
                                                                else if (timeout > max_timeout)
static int power_suspend_late(
static int power_suspend_late(                                       max_timeout = timeout;
     struct platform_device *pdev,                                    max_timeout = timeout;
      struct platform_device *pdev,                        } else
                                                           } else
     pm_message_t state)
      pm_message_t state)                                       return -1;
{                                                               return -1;
{                                                     }
                                                      }
     int ret =
     int ret =                                        return max_timeout;
           has_wake_lock(WAKE_LOCK_SUSPEND) ?         return max_timeout;
           has_wake_lock(WAKE_LOCK_SUSPEND) ?    }
                                                 }
           -EAGAIN : 0;
           -EAGAIN : 0;
     return ret;
     return ret;                                 long has_wake_lock(int type)
}                                                long has_wake_lock(int type)
}                                                {
                                                 {
                                                      long ret;
                                                      long ret;
static struct platform_driver power_driver = {
static struct platform_driver power_driver = {        unsigned long irqflags;
     .driver.name = "power",                          unsigned long irqflags;
     .driver.name = "power",                          spin_lock_irqsave(&list_lock, irqflags);
                                                      spin_lock_irqsave(&list_lock, irqflags);
     .suspend_late = power_suspend_late,
     .suspend_late = power_suspend_late,              ret = has_wake_lock_locked(type);
};                                                    ret = has_wake_lock_locked(type);
};                                                    spin_unlock_irqrestore(&list_lock, irqflags);
                                                      spin_unlock_irqrestore(&list_lock, irqflags);
static struct platform_device power_device = {
static struct platform_device power_device = {        return ret;
     .name = "power",                                 return ret;
     .name = "power",                            }
                                                 }
};
};
Android PM Kernel APIs
kernel/power/wakelock.c



                          static int __init wakelocks_init(void)
                          static int __init wakelocks_init(void)
                          {
                          {
                               int ret;
                               int ret;
                               int i;
                               int i;
                              for (i = 0; i < ARRAY_SIZE(active_wake_locks); i++)
                              for (i = 0; i < ARRAY_SIZE(active_wake_locks); i++)
                                   INIT_LIST_HEAD(&active_wake_locks[i]);
                                   INIT_LIST_HEAD(&active_wake_locks[i]);


                              wake_lock_init(&main_wake_lock, WAKE_LOCK_SUSPEND, "main");
                              wake_lock_init(&main_wake_lock, WAKE_LOCK_SUSPEND, "main");
                              wake_lock(&main_wake_lock);
                              wake_lock(&main_wake_lock);
                              wake_lock_init(&unknown_wakeup, WAKE_LOCK_SUSPEND, "unknown_wakeups");
                              wake_lock_init(&unknown_wakeup, WAKE_LOCK_SUSPEND, "unknown_wakeups");
                              ret = platform_device_register(&power_device);
                              ret = platform_device_register(&power_device);
                              if (ret) {
                              if (ret) {
                                   pr_err("wakelocks_init: platform_device_register failedn");
                                   pr_err("wakelocks_init: platform_device_register failedn");
                                   goto err_platform_device_register;
                                   goto err_platform_device_register;
                              }
                              }
                              ret = platform_driver_register(&power_driver);
                              ret = platform_driver_register(&power_driver);
                              if (ret) {
                              if (ret) {
                                   pr_err("wakelocks_init: platform_driver_register failedn");
                                   pr_err("wakelocks_init: platform_driver_register failedn");
                                   goto err_platform_driver_register;
                                   goto err_platform_driver_register;
                              }
                              }
                              suspend_work_queue = create_singlethread_workqueue("suspend");
                              suspend_work_queue = create_singlethread_workqueue("suspend");
                              if (suspend_work_queue == NULL) {
                              if (suspend_work_queue == NULL) {
                                   ret = -ENOMEM;
                                   ret = -ENOMEM;
                                   goto err_suspend_work_queue;
                                   goto err_suspend_work_queue;
                              }
                              }
Review

• Native area
  – dynamic linking
  – Processes
  – Memory layout
  – Binder IPC
  – interactions with frameworks
http://0xlab.org

More Related Content

What's hot

Develop Your Own Operating Systems using Cheap ARM Boards
Develop Your Own Operating Systems using Cheap ARM BoardsDevelop Your Own Operating Systems using Cheap ARM Boards
Develop Your Own Operating Systems using Cheap ARM BoardsNational Cheng Kung University
 
Shorten Device Boot Time for Automotive IVI and Navigation Systems
Shorten Device Boot Time for Automotive IVI and Navigation SystemsShorten Device Boot Time for Automotive IVI and Navigation Systems
Shorten Device Boot Time for Automotive IVI and Navigation SystemsNational Cheng Kung University
 
F9: A Secure and Efficient Microkernel Built for Deeply Embedded Systems
F9: A Secure and Efficient Microkernel Built for Deeply Embedded SystemsF9: A Secure and Efficient Microkernel Built for Deeply Embedded Systems
F9: A Secure and Efficient Microkernel Built for Deeply Embedded SystemsNational Cheng Kung University
 
Introduction to Android by Demian Neidetcher
Introduction to Android by Demian NeidetcherIntroduction to Android by Demian Neidetcher
Introduction to Android by Demian NeidetcherMatthew McCullough
 
Dalvik Vm &amp; Jit
Dalvik Vm &amp; JitDalvik Vm &amp; Jit
Dalvik Vm &amp; JitAnkit Somani
 
Learning, Analyzing and Protecting Android with TOMOYO Linux (JLS2009)
Learning, Analyzing and Protecting Android with TOMOYO Linux (JLS2009)Learning, Analyzing and Protecting Android with TOMOYO Linux (JLS2009)
Learning, Analyzing and Protecting Android with TOMOYO Linux (JLS2009)Toshiharu Harada, Ph.D
 
0xdroid -- community-developed Android distribution by 0xlab
0xdroid -- community-developed Android distribution by 0xlab0xdroid -- community-developed Android distribution by 0xlab
0xdroid -- community-developed Android distribution by 0xlabNational Cheng Kung University
 

What's hot (20)

Accelerated Android Development with Linaro
Accelerated Android Development with LinaroAccelerated Android Development with Linaro
Accelerated Android Development with Linaro
 
淺談探索 Linux 系統設計之道
淺談探索 Linux 系統設計之道 淺談探索 Linux 系統設計之道
淺談探索 Linux 系統設計之道
 
Develop Your Own Operating Systems using Cheap ARM Boards
Develop Your Own Operating Systems using Cheap ARM BoardsDevelop Your Own Operating Systems using Cheap ARM Boards
Develop Your Own Operating Systems using Cheap ARM Boards
 
Low Level View of Android System Architecture
Low Level View of Android System ArchitectureLow Level View of Android System Architecture
Low Level View of Android System Architecture
 
Shorten Device Boot Time for Automotive IVI and Navigation Systems
Shorten Device Boot Time for Automotive IVI and Navigation SystemsShorten Device Boot Time for Automotive IVI and Navigation Systems
Shorten Device Boot Time for Automotive IVI and Navigation Systems
 
Build Programming Language Runtime with LLVM
Build Programming Language Runtime with LLVMBuild Programming Language Runtime with LLVM
Build Programming Language Runtime with LLVM
 
F9: A Secure and Efficient Microkernel Built for Deeply Embedded Systems
F9: A Secure and Efficient Microkernel Built for Deeply Embedded SystemsF9: A Secure and Efficient Microkernel Built for Deeply Embedded Systems
F9: A Secure and Efficient Microkernel Built for Deeply Embedded Systems
 
Embedded Hypervisor for ARM
Embedded Hypervisor for ARMEmbedded Hypervisor for ARM
Embedded Hypervisor for ARM
 
Applied Computer Science Concepts in Android
Applied Computer Science Concepts in AndroidApplied Computer Science Concepts in Android
Applied Computer Science Concepts in Android
 
Embedded Virtualization for Mobile Devices
Embedded Virtualization for Mobile DevicesEmbedded Virtualization for Mobile Devices
Embedded Virtualization for Mobile Devices
 
Implement Runtime Environments for HSA using LLVM
Implement Runtime Environments for HSA using LLVMImplement Runtime Environments for HSA using LLVM
Implement Runtime Environments for HSA using LLVM
 
Introduction to Android by Demian Neidetcher
Introduction to Android by Demian NeidetcherIntroduction to Android by Demian Neidetcher
Introduction to Android by Demian Neidetcher
 
Dalvik Vm &amp; Jit
Dalvik Vm &amp; JitDalvik Vm &amp; Jit
Dalvik Vm &amp; Jit
 
Learning, Analyzing and Protecting Android with TOMOYO Linux (JLS2009)
Learning, Analyzing and Protecting Android with TOMOYO Linux (JLS2009)Learning, Analyzing and Protecting Android with TOMOYO Linux (JLS2009)
Learning, Analyzing and Protecting Android with TOMOYO Linux (JLS2009)
 
Android IPC Mechanism
Android IPC MechanismAndroid IPC Mechanism
Android IPC Mechanism
 
0xdroid -- community-developed Android distribution by 0xlab
0xdroid -- community-developed Android distribution by 0xlab0xdroid -- community-developed Android distribution by 0xlab
0xdroid -- community-developed Android distribution by 0xlab
 
Faults inside System Software
Faults inside System SoftwareFaults inside System Software
Faults inside System Software
 
TOMOYO Linux on Android
TOMOYO Linux on AndroidTOMOYO Linux on Android
TOMOYO Linux on Android
 
Jnode
JnodeJnode
Jnode
 
Unix v6 Internals
Unix v6 InternalsUnix v6 Internals
Unix v6 Internals
 

Similar to Discover System Facilities inside Your Android Phone

C# Production Debugging Made Easy
 C# Production Debugging Made Easy C# Production Debugging Made Easy
C# Production Debugging Made EasyAlon Fliess
 
Working with the AOSP - Linaro Connect Asia 2013
Working with the AOSP - Linaro Connect Asia 2013Working with the AOSP - Linaro Connect Asia 2013
Working with the AOSP - Linaro Connect Asia 2013Opersys inc.
 
Droidcon uk2012 androvm
Droidcon uk2012 androvmDroidcon uk2012 androvm
Droidcon uk2012 androvmdfages
 
Android tools for testers
Android tools for testersAndroid tools for testers
Android tools for testersMaksim Kovalev
 
ABS 2012 - Android Device Porting Walkthrough
ABS 2012 - Android Device Porting WalkthroughABS 2012 - Android Device Porting Walkthrough
ABS 2012 - Android Device Porting WalkthroughBenjamin Zores
 
Android Embedded - Smart Hubs als Schaltzentrale des IoT
Android Embedded - Smart Hubs als Schaltzentrale des IoTAndroid Embedded - Smart Hubs als Schaltzentrale des IoT
Android Embedded - Smart Hubs als Schaltzentrale des IoTinovex GmbH
 
Kandroid for nhn_deview_20131013_v5_final
Kandroid for nhn_deview_20131013_v5_finalKandroid for nhn_deview_20131013_v5_final
Kandroid for nhn_deview_20131013_v5_finalNAVER D2
 
An Introduction To Android
An Introduction To AndroidAn Introduction To Android
An Introduction To Androidnatdefreitas
 
Android OS Porting: Introduction
Android OS Porting: IntroductionAndroid OS Porting: Introduction
Android OS Porting: IntroductionJollen Chen
 
Rhodes mobile Framework
Rhodes mobile FrameworkRhodes mobile Framework
Rhodes mobile FrameworkYoshi Sakai
 
Droidcon 2013 France - Android Platform Anatomy
Droidcon 2013 France - Android Platform AnatomyDroidcon 2013 France - Android Platform Anatomy
Droidcon 2013 France - Android Platform AnatomyBenjamin Zores
 
Android Developer Meetup
Android Developer MeetupAndroid Developer Meetup
Android Developer MeetupMedialets
 
OWF12/PAUG Conf Days Alternative to google's android emulator, daniel fages, ...
OWF12/PAUG Conf Days Alternative to google's android emulator, daniel fages, ...OWF12/PAUG Conf Days Alternative to google's android emulator, daniel fages, ...
OWF12/PAUG Conf Days Alternative to google's android emulator, daniel fages, ...Paris Open Source Summit
 
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis OverviewLeo Lorieri
 
0xdroid osdc-2010-100426084937-phpapp02
0xdroid osdc-2010-100426084937-phpapp020xdroid osdc-2010-100426084937-phpapp02
0xdroid osdc-2010-100426084937-phpapp02chon2010
 
Open shift
Open shiftOpen shift
Open shiftmarcolof
 
LAP2 iOS and Android Development environment setup
LAP2 iOS and Android Development environment setupLAP2 iOS and Android Development environment setup
LAP2 iOS and Android Development environment setupUniversity of Catania
 
Zeelogic android-training-2013
Zeelogic android-training-2013Zeelogic android-training-2013
Zeelogic android-training-2013Zeelogic Solu
 

Similar to Discover System Facilities inside Your Android Phone (20)

C# Production Debugging Made Easy
 C# Production Debugging Made Easy C# Production Debugging Made Easy
C# Production Debugging Made Easy
 
Working with the AOSP - Linaro Connect Asia 2013
Working with the AOSP - Linaro Connect Asia 2013Working with the AOSP - Linaro Connect Asia 2013
Working with the AOSP - Linaro Connect Asia 2013
 
Droidcon uk2012 androvm
Droidcon uk2012 androvmDroidcon uk2012 androvm
Droidcon uk2012 androvm
 
Android tools for testers
Android tools for testersAndroid tools for testers
Android tools for testers
 
Core Android
Core AndroidCore Android
Core Android
 
ABS 2012 - Android Device Porting Walkthrough
ABS 2012 - Android Device Porting WalkthroughABS 2012 - Android Device Porting Walkthrough
ABS 2012 - Android Device Porting Walkthrough
 
Android Embedded - Smart Hubs als Schaltzentrale des IoT
Android Embedded - Smart Hubs als Schaltzentrale des IoTAndroid Embedded - Smart Hubs als Schaltzentrale des IoT
Android Embedded - Smart Hubs als Schaltzentrale des IoT
 
Kandroid for nhn_deview_20131013_v5_final
Kandroid for nhn_deview_20131013_v5_finalKandroid for nhn_deview_20131013_v5_final
Kandroid for nhn_deview_20131013_v5_final
 
An Introduction To Android
An Introduction To AndroidAn Introduction To Android
An Introduction To Android
 
Android OS Porting: Introduction
Android OS Porting: IntroductionAndroid OS Porting: Introduction
Android OS Porting: Introduction
 
Rhodes mobile Framework
Rhodes mobile FrameworkRhodes mobile Framework
Rhodes mobile Framework
 
Droidcon 2013 France - Android Platform Anatomy
Droidcon 2013 France - Android Platform AnatomyDroidcon 2013 France - Android Platform Anatomy
Droidcon 2013 France - Android Platform Anatomy
 
Android Platform Debugging & Development
Android Platform Debugging & Development Android Platform Debugging & Development
Android Platform Debugging & Development
 
Android Developer Meetup
Android Developer MeetupAndroid Developer Meetup
Android Developer Meetup
 
OWF12/PAUG Conf Days Alternative to google's android emulator, daniel fages, ...
OWF12/PAUG Conf Days Alternative to google's android emulator, daniel fages, ...OWF12/PAUG Conf Days Alternative to google's android emulator, daniel fages, ...
OWF12/PAUG Conf Days Alternative to google's android emulator, daniel fages, ...
 
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview
 
0xdroid osdc-2010-100426084937-phpapp02
0xdroid osdc-2010-100426084937-phpapp020xdroid osdc-2010-100426084937-phpapp02
0xdroid osdc-2010-100426084937-phpapp02
 
Open shift
Open shiftOpen shift
Open shift
 
LAP2 iOS and Android Development environment setup
LAP2 iOS and Android Development environment setupLAP2 iOS and Android Development environment setup
LAP2 iOS and Android Development environment setup
 
Zeelogic android-training-2013
Zeelogic android-training-2013Zeelogic android-training-2013
Zeelogic android-training-2013
 

More from National Cheng Kung University

PyPy's approach to construct domain-specific language runtime
PyPy's approach to construct domain-specific language runtimePyPy's approach to construct domain-specific language runtime
PyPy's approach to construct domain-specific language runtimeNational Cheng Kung University
 
進階嵌入式作業系統設計與實做 (2015 年秋季 ) 課程說明
進階嵌入式作業系統設計與實做 (2015 年秋季 ) 課程說明進階嵌入式作業系統設計與實做 (2015 年秋季 ) 課程說明
進階嵌入式作業系統設計與實做 (2015 年秋季 ) 課程說明National Cheng Kung University
 
給自己更好未來的 3 個練習:嵌入式作業系統設計、實做,與移植 (2015 年春季 ) 課程說明
給自己更好未來的 3 個練習:嵌入式作業系統設計、實做,與移植 (2015 年春季 ) 課程說明給自己更好未來的 3 個練習:嵌入式作業系統設計、實做,與移植 (2015 年春季 ) 課程說明
給自己更好未來的 3 個練習:嵌入式作業系統設計、實做,與移植 (2015 年春季 ) 課程說明National Cheng Kung University
 
進階嵌入式系統開發與實做 (2014 年秋季 ) 課程說明
進階嵌入式系統開發與實做 (2014 年秋季 ) 課程說明進階嵌入式系統開發與實做 (2014 年秋季 ) 課程說明
進階嵌入式系統開發與實做 (2014 年秋季 ) 課程說明National Cheng Kung University
 
Lecture notice about Embedded Operating System Design and Implementation
Lecture notice about Embedded Operating System Design and ImplementationLecture notice about Embedded Operating System Design and Implementation
Lecture notice about Embedded Operating System Design and ImplementationNational Cheng Kung University
 
中輟生談教育: 完全用開放原始碼軟體進行 嵌入式系統教學
中輟生談教育: 完全用開放原始碼軟體進行 嵌入式系統教學中輟生談教育: 完全用開放原始碼軟體進行 嵌入式系統教學
中輟生談教育: 完全用開放原始碼軟體進行 嵌入式系統教學National Cheng Kung University
 
進階嵌入式系統開發與實作 (2013 秋季班 ) 課程說明
進階嵌入式系統開發與實作 (2013 秋季班 ) 課程說明進階嵌入式系統開發與實作 (2013 秋季班 ) 課程說明
進階嵌入式系統開發與實作 (2013 秋季班 ) 課程說明National Cheng Kung University
 

More from National Cheng Kung University (20)

PyPy's approach to construct domain-specific language runtime
PyPy's approach to construct domain-specific language runtimePyPy's approach to construct domain-specific language runtime
PyPy's approach to construct domain-specific language runtime
 
Making Linux do Hard Real-time
Making Linux do Hard Real-timeMaking Linux do Hard Real-time
Making Linux do Hard Real-time
 
2016 年春季嵌入式作業系統課程說明
2016 年春季嵌入式作業系統課程說明2016 年春季嵌入式作業系統課程說明
2016 年春季嵌入式作業系統課程說明
 
Interpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratchInterpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratch
 
進階嵌入式作業系統設計與實做 (2015 年秋季 ) 課程說明
進階嵌入式作業系統設計與實做 (2015 年秋季 ) 課程說明進階嵌入式作業系統設計與實做 (2015 年秋季 ) 課程說明
進階嵌入式作業系統設計與實做 (2015 年秋季 ) 課程說明
 
Construct an Efficient and Secure Microkernel for IoT
Construct an Efficient and Secure Microkernel for IoTConstruct an Efficient and Secure Microkernel for IoT
Construct an Efficient and Secure Microkernel for IoT
 
The Internals of "Hello World" Program
The Internals of "Hello World" ProgramThe Internals of "Hello World" Program
The Internals of "Hello World" Program
 
How A Compiler Works: GNU Toolchain
How A Compiler Works: GNU ToolchainHow A Compiler Works: GNU Toolchain
How A Compiler Works: GNU Toolchain
 
Virtual Machine Constructions for Dummies
Virtual Machine Constructions for DummiesVirtual Machine Constructions for Dummies
Virtual Machine Constructions for Dummies
 
給自己更好未來的 3 個練習:嵌入式作業系統設計、實做,與移植 (2015 年春季 ) 課程說明
給自己更好未來的 3 個練習:嵌入式作業系統設計、實做,與移植 (2015 年春季 ) 課程說明給自己更好未來的 3 個練習:嵌入式作業系統設計、實做,與移植 (2015 年春季 ) 課程說明
給自己更好未來的 3 個練習:嵌入式作業系統設計、實做,與移植 (2015 年春季 ) 課程說明
 
從線上售票看作業系統設計議題
從線上售票看作業系統設計議題從線上售票看作業系統設計議題
從線上售票看作業系統設計議題
 
進階嵌入式系統開發與實做 (2014 年秋季 ) 課程說明
進階嵌入式系統開發與實做 (2014 年秋季 ) 課程說明進階嵌入式系統開發與實做 (2014 年秋季 ) 課程說明
進階嵌入式系統開發與實做 (2014 年秋季 ) 課程說明
 
Xvisor: embedded and lightweight hypervisor
Xvisor: embedded and lightweight hypervisorXvisor: embedded and lightweight hypervisor
Xvisor: embedded and lightweight hypervisor
 
Making Linux do Hard Real-time
Making Linux do Hard Real-timeMaking Linux do Hard Real-time
Making Linux do Hard Real-time
 
Priority Inversion on Mars
Priority Inversion on MarsPriority Inversion on Mars
Priority Inversion on Mars
 
Lecture notice about Embedded Operating System Design and Implementation
Lecture notice about Embedded Operating System Design and ImplementationLecture notice about Embedded Operating System Design and Implementation
Lecture notice about Embedded Operating System Design and Implementation
 
中輟生談教育: 完全用開放原始碼軟體進行 嵌入式系統教學
中輟生談教育: 完全用開放原始碼軟體進行 嵌入式系統教學中輟生談教育: 完全用開放原始碼軟體進行 嵌入式系統教學
中輟生談教育: 完全用開放原始碼軟體進行 嵌入式系統教學
 
Open Source from Legend, Business, to Ecosystem
Open Source from Legend, Business, to EcosystemOpen Source from Legend, Business, to Ecosystem
Open Source from Legend, Business, to Ecosystem
 
Summer Project: Microkernel (2013)
Summer Project: Microkernel (2013)Summer Project: Microkernel (2013)
Summer Project: Microkernel (2013)
 
進階嵌入式系統開發與實作 (2013 秋季班 ) 課程說明
進階嵌入式系統開發與實作 (2013 秋季班 ) 課程說明進階嵌入式系統開發與實作 (2013 秋季班 ) 課程說明
進階嵌入式系統開發與實作 (2013 秋季班 ) 課程說明
 

Recently uploaded

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 

Recently uploaded (20)

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 

Discover System Facilities inside Your Android Phone

  • 1. Discover System Facilities inside Your Android Phone Jim Huang ( 黃敬群 ) Developer, 0xlab jserv@0xlab.org Feb 26, 2012 / Study-Area
  • 2. Rights to copy © Copyright 2011-2012 0xlab http://0xlab.org/ contact@0xlab.org Attribution – ShareAlike 3.0 You are free Corrections, suggestions, contributions and translations are welcome! to copy, distribute, display, and perform the work to make derivative works Latest update: Feb 26, 2012 to make commercial use of the work Under the following conditions Attribution. You must give the original author credit. Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one. For any reuse or distribution, you must make clear to others the license terms of this work. Any of these conditions can be waived if you get permission from the copyright holder. Your fair use and other rights are in no way affected by the above. License text: http://creativecommons.org/licenses/by-sa/3.0/legalcode
  • 3. Goals of This Presentation • Pick up one Android phone and discover its internals • Learn how to select the "weapons" to fight with Android system facilities • Skipping Java parts, we focus on the native area: dynamic linking, processes, debugger, memory layout, IPC, and interactions with frameworks. • It is not comprehensive to familarize Android. The goal is to utilize Android platforms, which are the popular and powerful development devices to us.
  • 4. Agenda Part I (0) Environment Setup (1) Hello World! Part II (2) Case: Angry Birds (3) Case: Binder driver (4) Case: Power Management
  • 6. Reference Hardware and Host Configurations • Android Phone: Nexus S – http://www.google.com/phone/detail/nexus-s – Install CyanogenMod (CM9; 4.0) http://www.cyanogenmod.com/ • Host: Lenovo x200 – Ubuntu Linux 11.10+ • Toolchain: Sourcery CodeBench Lite – GNU/Linux Release 2011.09-70 – http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/ • AOSP/CM9 source code: 4.0.3 • Android NDK r5c/r7b
  • 7. Build CM9 from source • Follow the instructions in Wiki – http://wiki.cyanogenmod.com/wiki/Building_from_source • Follow the instructrions in AOSP – http://source.android.com/source/downloading.html – http://source.android.com/source/building.html – http://source.android.com/source/building-devices.html • Obtaining proprietary binaries – Starting with ICS, AOSP can't be used from pure source code only, and requires additional hardware-related proprietary libraries to run, specifically for hardware graphics acceleration. – Binaries for Nexus Phones and Flagship Devices http://code.google.com/android/nexus/drivers.html • Confirm the exact match – between AOSP version and proprietary packages
  • 8. Steps to Build CM (1) • cyanogen-ics$ source build/envsetup.sh including device/moto/stingray/vendorsetup.sh including device/moto/wingray/vendorsetup.sh including device/samsung/maguro/vendorsetup.sh including device/samsung/toro/vendorsetup.sh including device/ti/panda/vendorsetup.sh including vendor/cm/vendorsetup.sh including sdk/bash_completion/adb.bash • cyanogen-ics$ lunch You're building on Linux Lunch menu... pick a combo: 1. full-eng Target: cm_crespo … Configuration: userdebug 8. full_panda-eng 9. cm_crespo-userdebug
  • 9. Steps to Build CM (2) • Which would you like? [full-eng] 9 ============================================ PLATFORM_VERSION_CODENAME=REL PLATFORM_VERSION=4.0.3 TARGET_PRODUCT=cm_crespo TARGET_BUILD_VARIANT=userdebug TARGET_BUILD_TYPE=release TARGET_BUILD_APPS= TARGET_ARCH=arm TARGET_ARCH_VARIANT=armv7-a-neon HOST_ARCH=x86 HOST_OS=linux HOST_BUILD_TYPE=release BUILD_ID=MR1 ============================================
  • 10. hello.c #include <stdio.h> int main() { printf("Hello World!n"); return 0; } Assume file hello.c is placed in directory 'test' under AOSP top-level source tree.
  • 11. Android.mk LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_MODULE := hello LOCAL_SRC_FILES := hello.c include $(BUILD_EXECUTABLE) Assume file Android.mk is placed in directory 'test' under AOSP top-level source tree.
  • 12. Hello World! (use Android toolchain and build rules) • cd tests Trigger Android build system to generate 'hello' • mm -B No private recovery resources for TARGET_DEVICE crespo make: Entering directory `/home/jserv/cyanogen-ics' target thumb C: hello <= tests/hello.c target Executable: hello (out/target/product/crespo/obj/EXECUTABLES/hello_intermediates/LINKED/hello) target Symbolic: hello (out/target/product/crespo/symbols/system/bin/hello) target Strip: hello (out/target/product/crespo/obj/EXECUTABLES/hello_intermediates/hello) Install: out/target/product/crespo/system/bin/hello • adb push ../out/target/product/crespo/system/bin/hello /data/local/ For Android 'user' build, only directory /data/local is writable and executable.
  • 13. Hello World! (deploy to Android device and execute) • adb push ../out/target/product/crespo/system/bin/hello /data/local/ • adb shell /data/local/hello Hello World! • arm-eabi-readelf -a ../out/target/product/crespo/system/bin/hello ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 ... Type: EXEC (Executable file) Machine: ARM ...
  • 14. ADB: Android Debug Bridge ARCHITECTURE • ADB includes three compnenent: Server, Client and Daemon. Host Device/Emulator ADB ADB ADB Applications Client Client Client APP APP ADT Command DDMS Eclipse line ADB Server ADB Daemon Details: http://developer.android.com/guide/developing/tools/adb.html
  • 15. Hello World! (use strace to trace the system calls during execution) • adb shell strace /data/local/hello execve("/data/local/hello", ["/data/local/hello"], [/* 13 vars */]) = 0 ... stat64("/system/lib/libc.so", {st_mode=S_IFREG|0644, st_size=282248, ...}) = 0 open("/system/lib/libc.so", O_RDONLY|O_LARGEFILE) = 3 ioctl(1, TCGETS or SNDCTL_TMR_TIMEBASE, {B38400 opost isig icanon echo ...}) = 0 write(1, "Hello World!n", 13Hello World! ) = 13 ... The above log shows dynamic library /system/lib/libc.so is open and manipulated.
  • 16. Hello World! (Remote Debugging) Map host port 12345 to device port 12345 • adb forward tcp:12345 tcp:12345 • adb shell gdbserver :12345 /data/local/hello Process /data/local/hello created; pid = 18696 Run gdbserver on device to listen port 12345 Listening on port 12345 (execute the following in another terminal) • arm-eabi-gdb out/target/product/crespo/symbols/system/bin/hello (gdb) target remote :12345 Remote debugging using :12345
  • 17. arm-eabi-gdb out/target/product/crespo/symbols/system/bin/hello (gdb) target remote :12345 adb shell gdbserver :12345 /data/local/hello Process /data/local/hello created; pid = 18696 Listening on port 12345 NOTE: You don't have to specify TCP/IP address because ADB forwarding already prepares. Port 12345 gdb stub (gdbserver) Linux host running GDB Android phone
  • 18. 'hello' is loaded (process created, PID=18696) But not executed. Hello World! • adb shell cat /proc/18696/maps 00008000-00009000 r-xp 00000000 b3:02 8959 /data/local/hello 00009000-0000a000 rwxp 00001000 b3:02 8959 /data/local/hello b0001000-b0009000 r-xp 00001000 b3:01 128 /system/bin/linker b0009000-b000a000 rwxp 00009000 b3:01 128 /system/bin/linker b000a000-b0015000 rwxp 00000000 00:00 0 beb07000-beb28000 rw-p 00000000 00:00 0 [stack] ffff0000-ffff1000 r-xp 00000000 00:00 0 [vectors] • (gdb) b main (gdb) c Continue exec Process map changes after execuation. Continuing. This means magic in dynamic linking! • adb shell cat /proc/18696/maps 00008000-00009000 r-xp 00000000 b3:02 8959 /data/local/hello 00009000-0000a000 rwxp 00001000 b3:02 8959 /data/local/hello 40061000-40062000 r-xp 00000000 00:00 0 40079000-40081000 r-xs 00000000 00:0b 392 /dev/__properties__ (deleted) 40087000-400c9000 r-xp 00000000 b3:01 548 /system/lib/libc.so 400c9000-400cc000 rwxp 00042000 b3:01 548 /system/lib/libc.so 400cc000-400d7000 rwxp 00000000 00:00 0 400d7000-400ec000 r-xp 00000000 b3:01 597 /system/lib/libm.so 400ec000-400ed000 rwxp 00015000 b3:01 597 /system/lib/libm.so 40101000-40102000 r-xp 00000000 b3:01 644 /system/lib/libstdc++.so 40102000-40103000 rwxp 00001000 b3:01 644 /system/lib/libstdc++.so b0001000-b0009000 r-xp 00001000 b3:01 128 /system/bin/linker b0009000-b000a000 rwxp 00009000 b3:01 128 /system/bin/linker b000a000-b0015000 rwxp 00000000 00:00 0 beb07000-beb28000 rw-p 00000000 00:00 0 [stack] ffff0000-ffff1000 r-xp 00000000 00:00 0 [vectors]
  • 19. Everything starts from Hello World!
  • 20. Execution flow of Hello World! (GNU/Linux) Dynamic Link Static Link Shell hello ./hello ld-linux.so Dynamic Linker eglibc libc_start_main main execve exit SYS_execve SYS_exit kernel Examine Executable Start loader Drop Process Allocate Process
  • 21. Figure out ELF information (glibc/x86) • gcc -o hello hello.c • readelf -a hello ... Type: EXEC (Executable file) Machine: Intel 80386 ... Relocation section '.rel.plt' at offset 0x298 contains 3 entries: Offset Info Type Sym.Value Sym. Name 0804a000 00000107 R_386_JUMP_SLOT 00000000 puts ... 0804a008 00000307 R_386_JUMP_SLOT 00000000 __libc_start_main Symbol table '.dynsym' contains 5 entries: Num: Value Size Type Bind Vis Ndx Name ... 3: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0 …. Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align ... INTERP 0x000154 0x08048154 0x08048154 0x00013 0x00013 R 0x1 [Requesting program interpreter: /lib/ld-linux.so.2]
  • 22. Figure out ELF information (Android/ARM) • arm-eabi-readelf -a ../out/target/product/crespo/system/bin/hello ... Machine: ARM ... Relocation section '.rel.plt' at offset 0x3c0 contains 2 entries: Offset Info Type Sym.Value Sym. Name 000090d4 00000216 R_ARM_JUMP_SLOT 00000000 __libc_init ... Symbol table '.dynsym' contains 18 entries: Num: Value Size Type Bind Vis Ndx Name ... 2: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_init … Program Headers: Type Offset VirtAddr PhysAddr FileSiz ... INTERP 0x000114 0x00008114 0x00008114 0x00013 [Requesting program interpreter: /system/bin/linker]
  • 23. Execution flow of Hello World! (Android/ARM) Dynamic Link Static Link Shell hello /data/local/hello /system/bin/linker Dynamic Linker bionic __libc_init main execve exit SYS_execve SYS_exit kernel Examine Executable Start loader Drop Process Allocate Process
  • 24. ELF Image m.c a.c Translators Translators (cc1, as) (cc1,as) Shared Library Dynamically relocatable object files m.o a.o Linker (ld) $ ldd hello libc.so.6 => /lib/i386-linux- gnu/libc.so (0x00aab000) Partially linked program libc.so /lib/ld-linux.so.2 (0x00fdb000) executable (on disk) ar g vect or Loader / Dynamic Linker main( ) (ld-linux.so) libc.so functions called by m.c printf( ) and a.c are loaded, linked, and .. .. (potentially) shared among processes. Fully linked executable Program’ (in memory)
  • 25. .interp →elf_interpreter $ /lib/ld-linux.so.2 Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR- PROGRAM...] You have invoked `ld.so', the helper program for shared library executables. This program usually lives in the file `/lib/ld.so', $ objdump -s -j .interp hello and special directives in executable files using ELF shared libraries tell the system's program loader to load the helper program from this file. This helper program loads the shared hello: file format elf32-i386 libraries needed by the program executable, prepares the program to run, and runs it. Contents of section .interp: 8048114 2f6c6962 2f6c642d 6c696e75 782e736f /lib/ld-linux.so 8048124 2e3200 .2.
  • 26. ELF Interpreter • objdump -s -j .interp hello-x86 hello: file format elf32-i386 Contents of section .interp: 8048154 2f6c6962 2f6c642d 6c696e75 782e736f /lib/ld-linux.so 8048164 2e3200 .2. • arm-eabi-objdump -s -j .interp ../out/target/product/crespo/system/bin/hello ../out/target/product/crespo/system/bin/hello: file format elf32-littlearm Contents of section .interp: 8114 2f737973 74656d2f 62696e2f 6c696e6b /system/bin/link 8124 657200 er.
  • 27. $ /lib/ld-linux.so.2 $ /lib/ld-linux.so.2 Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...] Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...] $ file /lib/ld-linux.so.2 /lib/ld-linux.so.2: symbolic link to `i386-linux-gnu/ld-2.13.so' $ file /lib/i386-linux-gnu/ld-2.13.so /lib/i386-linux-gnu/ld-2.13.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=0x41de5107934017489907fa244bf835ce98feddc1, stripped $ objdump -f /lib/ld-linux.so.2 /lib/ld-linux.so.2: file format elf32-i386 architecture: i386, flags 0x00000150: HAS_SYMS, DYNAMIC, D_PAGED glibc start address 0x000010e0 sysdeps/generic/dl-sysdep.c elf/rtld.c $ LD_DEBUG=help /lib/ld-2.13.so Valid options for the LD_DEBUG environment variable are: Hint libs display library search paths Try LD_DEBUG=XXX ./hello reloc display relocation processing files display progress for input file symbols display symbol table processing bindings display information about symbol binding versions display version dependencies all all previous options combined statistics display relocation statistics unused determined unused DSOs Hint help LD_TRACE_PRELINKING=1 display this help message and exit ./hello
  • 28. Hello World! (use plain Linux toolchain and try to execute in Android) • export PATH=/usr/local/csl/arm-2011.09/bin:$PATH • arm-none-linux-gnueabi-gcc -o hello hello.c • adb push hello /data/local && adb shell /data/local/hello Why?! /system/bin/sh: /data/local/hello: No such file or directory • arm-eabi-readelf -a hello | grep interpreter [Requesting program interpreter: /lib/ld-linux.so.3] • find /usr/local/csl/arm-2011.09/ Directory /lib is -name ld-linux.so.3 empty in Android. /usr/local/csl/arm-2011.09/arm-none-linux-gnueabi/libc/lib/ld-linux.so.3 /usr/local/csl/arm-2011.09/arm-none-linux-gnueabi/libc/armv4t/lib/ld- linux.so.3 /usr/local/csl/arm-2011.09/arm-none-linux-gnueabi/libc/thumb2/lib/ld- linux.so.3 • adb push /usr/local/csl/arm-2011.09/arm-none-linux- gnueabi/libc/lib/ld-linux.so.3 /data/local/
  • 29. Hello World! Specify ELF interpreter (use GNU/Linux toolchain) to /data/local/ld-linux.so.3 • arm-none-linux-gnueabi-gcc -o hello hello.c -Wl,-dynamic-linker,/data/local/ld-linux.so.3 • adb push hello /data/local && adb shell /data/local/hello Why?! Inconsistency detected by ld.so: dl-deps.c: 622: _dl_map_object_deps: Assertion `nlist > 1' failed! • adb shell strace /data/local/hello open("/vendor/lib/tls/v7l/neon/vfp/libgcc_s.so.1", O_RDONLY) = -1 ENOENT (No such file or directory) ... open("/usr/lib/libgcc_s.so.1", O_RDONLY) = -1 ENOENT (No such file or directory) • arm-none-linux-gnueabi-gcc -o hello hello.c -Wl,-dynamic-linker,/data/local/ld-linux.so.3 -static-libgcc Eliminate libgcc_s.so.1 dependency by static linking
  • 30. Hello World! (use GNU/Linux toolchain) • arm-none-linux-gnueabi-gcc -o hello hello.c -Wl,-dynamic-linker,/data/local/ld-linux.so.3 -static-libgcc • adb push hello /data/local && adb shell /data/local/hello Inconsistency detected by ld.so: dl-deps.c: 622: _dl_map_object_deps: Assertion `nlist > 1' failed! • adb shell strace /data/local/hello open("/usr/lib/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) • find /usr/local/csl/arm-2011.09 -name libc.so.6 /usr/local/csl/arm-2011.09/arm-none-linux-gnueabi/libc/lib/libc.so.6 /usr/local/csl/arm-2011.09/arm-none-linux- Let's provide libc gnueabi/libc/armv4t/lib/libc.so.6 /usr/local/csl/arm-2011.09/arm-none-linux- on Androi device. gnueabi/libc/thumb2/lib/libc.so.6 • adb push /usr/local/csl/arm-2011.09/arm-none-linux- gnueabi/libc/lib/libc.so.6 /data/local/ • arm-none-linux-gnueabi-gcc -o hello hello.c rpath: runtime -Wl,-dynamic-linker,/data/local/ld-linux.so.3 -static-libgcc -Wl,--rpath -Wl,/data/local library search path • adb push hello /data/local && adb shell /data/local/hello Hello World!
  • 31. Options when compiling and linking • There is no libgcc runtime in Android target device. Build system looks for libgcc.a provided by toolchain and link it statically. • Two flags have to be passed to linker – dynamic-linker – rpath • Source file: build/core/combo/TARGET_linux-arm.mk define transform-o-to-executable-inner $(hide) $(PRIVATE_CXX) -nostdlib -Bdynamic -Wl,-T,$ (BUILD_SYSTEM)/armelf.x -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc -o $@ $(TARGET_GLOBAL_LD_DIRS) -Wl,-rpath-link=$(TARGET_OUT_INTERMEDIATE_LIBRARIES)
  • 32. hello-crash.c #include <stdio.h> void hello() { printf("Hello World!n"); } void (*ptr)(); int main() { ptr = &hello; (*ptr)(); ptr = NULL; NOTE: The reason why (*ptr)(); we would take a memory violation program is that it return 0; can help us to trace the } internals when crashing. Assume file hello-crash.c is placed in directory 'test' under AOSP top-level source tree.
  • 33. Hello Crash! • mm -B • adb push ../out/target/product/crespo/system/bin/hello-crash /data/local • adb logcat -c • adb shell /data/local/hello-crash Hello World! Segmentation fault • adb logcat
  • 34. Magic in Android debuggerd • adb logcat --------- beginning of /dev/log/main F/libc (14127): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1) ... I/DEBUG ( 8044): pid: 14127, tid: 14127 >>> /data/local/hello-crash <<< I/DEBUG ( 8044): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000 ... I/DEBUG ( 8044): #00 pc 00000000 I/DEBUG ( 8044): #01 pc 00008440 /data/local/hello-crash I/DEBUG ( 8044): #02 pc 00016330 /system/lib/libc.so (__libc_init) I/DEBUG ( 8044): I/DEBUG ( 8044): code around pc: I/DEBUG ( 8044): 00000000 ffffffff ffffffff ffffffff ffffffff ................ __libc_init was mentioned I/DEBUG ( 8044): 00000010 ffffffff ffffffff ffffffff ffffffff ................ in previous diagram I/DEBUG ( 8044): 00000020 ffffffff ffffffff ffffffff ffffffff ................ I/DEBUG ( 8044): 00000030 ffffffff ffffffff ffffffff ffffffff ................ I/DEBUG ( 8044): 00000040 ffffffff ffffffff ffffffff ffffffff ................ Call stack when executing hello-crash
  • 35. #00 #01 pc 00000000 pc 00008440 /data/local/hello-crash Debuggerd #02 pc 00016330 /system/lib/libc.so (__libc_init) • arm-eabi-addr2line -e ../out/target/product/crespo/symbols/system/bin/hello-rash 00008440 /home/jserv/cyanogen-ics/tests/hello-crash.c:6 Line 01 #include <stdio.h> Line 02 void hello() { printf("Hello World!n"); } Line 03 void (*ptr)(); Line 04 int main() Line 05 { Line 06 ptr = &hello; Line 07 (*ptr)(); Line 08 ptr = NULL; Line 09 (*ptr)(); Line 10 return 0; Line 11 }
  • 36. #00 #01 pc 00000000 pc 00008440 /data/local/hello-crash Debuggerd #02 pc 00016330 /system/lib/libc.so (__libc_init) • addr2line -e ../out/target/product/crespo/symbols/system/lib/libc.so 00016330 /home/jserv/cyanogen- ics/bionic/libc/bionic/libc_init_dynamic.c:99 Line 94 __noreturn void __libc_init(uintptr_t *elfdata, Line 95 void (*onexit)(void), Line 96 int (*slingshot)(int, char**, char**), Line 97 structors_array_t const * const structors) Line 98 { Line 99 int argc = (int)*elfdata;
  • 37. How Debuggerd Works • Android dynamic linker provides its own _start routine that registers a signal handler on SIGSEGV and the like. • Whenever a dynamically linked executable crashes, the signal handler gets invoked and transmits the thread id of the crashing process to the debuggerd via a local socket. – bionic/linker/debugger.c • The debuggerd uses ptrace to get the register contents of the crashing process and to display the call chain. – system/core/debuggerd/debuggerd.c
  • 38.
  • 39. ELF symbol names are looked up and browsable in debuggerd. Use Android port of libunwind from Linaro to Improve stack trace view
  • 40. Two implementations for __libc_init • Two implementations – File bionic/libc/bionic/libc_init_dynamic.c /* This function is called from the executable's _start entry point * (see arch-$ARCH/bionic/crtbegin_dynamic.S), which is itself * called by the dynamic linker after it has loaded all shared * libraries the executable depends on. – File bionic/libc/bionic/libc_init_static.c __noreturn void __libc_init(uintptr_t *elfdata, void (*onexit)(void), int (*slingshot)(int, char**, char**), structors_array_t const * const structors) • Very similar to each other • Require the corresponding crtbegin_{dynamic,static}.S
  • 41. __noreturn void __libc_init(uintptr_t *elfdata, void (*onexit)(void), int (*slingshot)(int, char**, char**), structors_array_t const * const structors) { int argc = (int)*elfdata; Dynamic Link char** argv = (char**)(elfdata + 1); char** envp = argv + argc + 1; Static Link if (structors->fini_array) __cxa_atexit(__libc_fini,structors->fini_array,NULL); hello exit(slingshot(argc, argv, envp)); } Dynamic Linker bionic __libc_init main execve exit SYS_execve SYS_exit kernel Examine Executable Start loader Drop Process Allocate Process
  • 42. Memory Allocation while executing Hello World!
  • 43. Magic number ELF   Page size  Virtual address  type (.o / .so / exec) memory segment  Machine (sections)  byte order  Segment size  … 0 ELF header  Initialized (static) data Program header table  code (required for executables)  Un-initialized (static) data  Block started by symbol .text section  Has section header but .data section occupies no space .bss section  Symbol table .symtab  Procedure and static variable names .rel.txt  Section name .rel.data  Relocation info for .text section .debug  Addresses of instructions that need to be modified in the executable instructions for Section header table modifying. (required for relocatables)  Relocation info for .data section  Info for symbolic debugging  Address pointer data will need to be modified in the merged executable
  • 44. $ readelf -s hello Symbol table '.dynsym' contains 5 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 399 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.0 (2) 2: 00000000 415 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0 (2) 3: 08048438 4 OBJECT GLOBAL DEFAULT 14 _IO_stdin_used 4: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ Symbol table '.symtab' contains 81 entries:  -s|--syms|--symbols $ cp -f hello hello.strip – Displays the entries in symbol table $ strip –s hello.strip section of the file, if it has one . $ readelf -s hello.strip Symbol table '.dynsym' contains 5 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 399 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.0 (2) 2: 00000000 415 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0 (2) 3: 08048438 4 OBJECT GLOBAL DEFAULT 14 _IO_stdin_used 4: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
  • 45. ELF Executable object file Process image 0 ELF header Virtual address Program header table (required for executables) 0x080483e0 init and shared lib .text section segments .data section 0x08048494 .bss section .text segment (r/o) .symtab .rel.text 0x0804a010 .data segment .rel.data (initialized r/w) .debug 0x0804a3b0 Section header table .bss segment (required for relocatables) (un-initialized r/w) Loading ELF Binaries…
  • 46. GOT (global offset table):in data segment PLT (procedure linkage table): in code segment
  • 47. Each process has its own address space FF Address Space 0xffffffff C0 kernel virtual memory memory BF Stack (code, data, heap, stack) invisible to 0xc0000000 user code Runtime stack user stack 8 Mb limit (created at runtime) %esp (stack pointer) 80 memory mapped region for 7F shared libraries Heap 0x40000000 brk Shared run-time heap Libraries (managed by malloc) 40 read/write segment 3F (.data, .bss) Heap loaded from the read-only segment executable file (.init, .text, .rodata) Data 0x08048000 unused 08 Text 0 00 Linux memory layout
  • 48. Linux Memory Allocation Initial Linked Heap (1) Heap (2) BF Stack BF Stack BF Stack BF Stack 80 80 80 80 7F 7F 7F 7F Heap Heap 40 40 Libraries 40 Libraries 40 Libraries 3F 3F 3F 3F Heap Data Data Data Data 08 Text 08 Text 08 Text 08 Text 00 00 00 00
  • 49. Stack “Bottom” Linked i386 stack BF Stack Address increase 80 Stack increase 7F Stack pointer %esp Stack “Top” Stack popl DEST 40 Libraries Push 3F pushl SRC Stack Pop Data 08 Text 00 Stack Pointer Stack %esp +4 Pointer -4 %esp
  • 50. Recall process maps • adb shell cat /proc/18696/maps 00008000-00009000 r-xp 00000000 b3:02 8959 /data/local/hello 00009000-0000a000 rwxp 00001000 b3:02 8959 /data/local/hello 40061000-40062000 r-xp 00000000 00:00 0 40079000-40081000 r-xs 00000000 00:0b 392 /dev/__properties__ (deleted) 40087000-400c9000 r-xp 00000000 b3:01 548 /system/lib/libc.so 400c9000-400cc000 rwxp 00042000 b3:01 548 /system/lib/libc.so 400cc000-400d7000 rwxp 00000000 00:00 0 400d7000-400ec000 r-xp 00000000 b3:01 597 /system/lib/libm.so 400ec000-400ed000 rwxp 00015000 b3:01 597 /system/lib/libm.so 40101000-40102000 r-xp 00000000 b3:01 644 /system/lib/libstdc++.so 40102000-40103000 rwxp 00001000 b3:01 644 /system/lib/libstdc++.so b0001000-b0009000 r-xp 00001000 b3:01 128 /system/bin/linker b0009000-b000a000 rwxp 00009000 b3:01 128 /system/bin/linker b000a000-b0015000 rwxp 00000000 00:00 0 beb07000-beb28000 rw-p 00000000 00:00 0 [stack] ffff0000-ffff1000 r-xp 00000000 00:00 0 [vectors] Meaning of each field: start-end perm offset major:minor inode image Start-end: The beginning and ending virtual addresses for this memory area. Perm: a bit mask with the memroy area’s read, write, and execute permissions Offset: Where the memory area begins in the file Major/Minor: Major and minor numbers of the device holding the file (or partition)
  • 51. Map vs. ELF sections • arm-eabi-objdump -h ../out/target/product/crespo/system/bin/hello Sections: Idx Name Size VMA LMA File off Algn 0 .interp 00000013 00008114 00008114 00000114 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA ... 4 .rel.plt 00000018 000083dc 000083dc 000003dc 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .plt 00000038 000083f4 000083f4 000003f4 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 6 .text 00000054 00008430 00008430 00000430 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 7 .rodata 0000000d 00008484 00008484 00000484 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA • adb shell cat /proc/18696/maps 00008000-00009000 r-xp 00000000 b3:02 8959 /data/local/hello 00009000-0000a000 rwxp 00001000 b3:02 8959 /data/local/hello .data section of 'hello' program → Readable and Writable .text section of 'hello' program → Read-only
  • 52. Recall process maps • adb shell cat /proc/18696/maps .bss section of libc 00008000-00009000 r-xp 00000000 b3:02 8959 /data/local/hello 00009000-0000a000 rwxp 00001000 b3:02 8959 /data/local/hello 40061000-40062000 r-xp 00000000 00:00 0 40079000-40081000 r-xs 00000000 00:0b 392 /dev/__properties__ (deleted) 40087000-400c9000 r-xp 00000000 b3:01 548 /system/lib/libc.so 400c9000-400cc000 rwxp 00042000 b3:01 548 /system/lib/libc.so 400cc000-400d7000 rwxp 00000000 00:00 0 400d7000-400ec000 r-xp 00000000 b3:01 597 /system/lib/libm.so 400ec000-400ed000 rwxp 00015000 b3:01 597 /system/lib/libm.so 40101000-40102000 r-xp 00000000 b3:01 644 /system/lib/libstdc++.so 40102000-40103000 rwxp 00001000 b3:01 644 /system/lib/libstdc++.so b0001000-b0009000 r-xp 00001000 b3:01 128 /system/bin/linker b0009000-b000a000 rwxp 00009000 b3:01 128 /system/bin/linker b000a000-b0015000 rwxp 00000000 00:00 0 beb07000-beb28000 rw-p 00000000 00:00 0 [stack] ffff0000-ffff1000 r-xp 00000000 00:00 0 [vectors] .text section of dynamic linker .data section of dynamic linker .bss section of dynamic linker
  • 53. adb shell cat /proc/18696/maps 00008000-00009000 r-xp 00000000 /data/local/hello 00009000-0000a000 rwxp 00001000 /data/local/hello 40061000-40062000 r-xp 00000000 00:00 0 40079000-40081000 r-xs 00000000 /dev/__properties 40087000-400c9000 r-xp 00000000 /system/lib/libc.so process-specific data 400c9000-400cc000 rwxp 00042000 /system/lib/libc.so structures 400cc000-400d7000 rwxp 00000000 00:00 0 (page tables, task and mm structs) 400d7000-400ec000 r-xp 00000000 /system/lib/libm.so 400ec000-400ed000 rwxp 00015000 /system/lib/libm.so demand-zero same for physical memory 40101000-40102000 r-xp 00000000 /system/lib/libstdc++.so each 40102000-40103000 rwxp 00001000 /system/lib/libstdc++.so process kernel b0001000-b0009000 r-xp 00001000 /system/bin/linker kernel code/data/stack VM 0xc0 b0009000-b000a000 rwxp 00009000 /system/bin/linker %esp stack b000a000-b0015000 rwxp 00000000 00:00 0 process beb07000-beb28000 rw-p 00000000 [stack] VM ffff0000-ffff1000 r-xp 00000000 [vectors] Memory mapped region .data for shared libraries .text NOTE: reverse order between libc.so process view and maps brk runtime heap (via malloc) demand-zero uninitialized data (.bss) initialized data (.data) .data program text (.text) .text forbidden program 0
  • 54. Case Study GDB meets Angry Birds
  • 55. Setup (1) • Download Android NDK – http://developer.android.com/sdk/ndk/ – Version: r7b / r5c • Download apktool – a tool for reverse engineering 3rd party, closed, binary Android apps. It can decode resources to nearly original form and rebuild them after making some modifications – http://code.google.com/p/android-apktool/ • Download Angry Birds Rio from Androi Market – Date: Feb 3, 2012
  • 56. APK content $ unzip Angry+Birds.apk Archive: Angry+Birds.apk ... inflating: AndroidManifest.xml extracting: resources.arsc extracting: res/drawable-hdpi/icon.png extracting: res/drawable-ldpi/icon.png extracting: res/drawable-mdpi/icon.png inflating: classes.dex Dalvik DEX inflating: lib/armeabi/libangrybirds.so JNI inflating: lib/armeabi-v7a/libangrybirds.so inflating: META-INF/MANIFEST.MF inflating: META-INF/CERT.SF manifest + inflating: META-INF/CERT.RSA signature
  • 57. AndroidManifest $ unzip Angry+Birds.apk Archive: Angry+Birds.apk ... ... inflating: AndroidManifest.xml extracting: resources.arsc extracting: res/drawable-hdpi/icon.png $ file AndroidManifest.xml extracting: res/drawable-ldpi/icon.png AndroidManifest.xml: DBase 3 data file (2328 records) extracting: res/drawable-mdpi/icon.png $ apktool d ../AngryBirds/Angry+Birds.apk inflating: classes.dex I: Baksmaling... I: Loading resource lib/armeabi/libangrybirds.so inflating: table... ... inflating: lib/armeabi-v7a/libangrybirds.so I: Decoding file-resources... inflating: META-INF/MANIFEST.MF I: Decoding values*/* XMLs... I: Done. inflating: META-INF/CERT.SF I: Copying assets and libs... $ fileinflating: META-INF/CERT.RSA Angry+Birds/AndroidManifest.xml Angry+Birds/AndroidManifest.xml: XML document text
  • 58. Setup (2) • Pull Angry Birds' APK and extract adb pull /data/app/com.rovio.angrybirdsrio-1.apk java -jar apktool.jar d com.rovio.angrybirdsrio-1.apk • Prepare environment to satisfy NDK cp -af com.rovio.angrybirdsrio-1/lib/ libs mkdir -p obj/local/armeabi obj/local/armeabi-v7a cp -f libs/armeabi/libangrybirds.so ./obj/local/armeabi/ ./obj/local/armeabi-v7a/ echo "set solib-search-path `pwd`/obj/local/armeabi" > libs/armeabi/gdb.setup cp -f libs/armeabi/gdb.setup libs/armeabi-v7a/gdb.setup • Use gdbserver from NDK adb push android-ndk-r7b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/gdbserver /data/data/com.rovio.angrybirdsrio/lib
  • 59. Use GDB from Android NDK(1) • $ android-ndk-r7b/ndk-gdb --verbose –force --launch=com.rovio.ka3d.App Android NDK installation path: /tmp/angry-birds/android-ndk-r7b Using default adb command: /usr/bin/adb ADB version found: Android Debug Bridge version 1.0.26 Using ADB flags: Using auto-detected project path: . Found package name: com.rovio.angrybirdsrio ... Launching activity: com.rovio.angrybirdsrio/com.rovio.ka3d.App ## COMMAND: /usr/bin/adb shell am start -n com.rovio.angrybirdsrio/com.rovio.ka3d.App Starting: Intent { cmp=com.rovio.angrybirdsrio/com.rovio.ka3d.App } ... GDB will be unable to debug shared library initializers and track explicitly loaded dynamic code. warning: shared library handler failed to enable breakpoint 0x40043384 in epoll_wait () from /tmp/angry-birds/obj/local/armeabi/libc.so (gdb)
  • 60. Use GDB from Android NDK(2) • (gdb) info shared From To Syms Read Shared Object Library No /system/bin/linker 0x40041fc0 0x4006f99c Yes armeabi/libc.so No libstdc++.so No libm.so No liblog.so No libcutils.so No libz.so ... 0x507b0ae8 0x508ec948 Yes armeabi/libangrybirds.so
  • 61. Use GDB from Android NDK(3) (gdb) set $m = (int*)malloc(480*699*4) (gdb) (gdb) set $f = fopen("/sdcard/outputfile", "wb+") (gdb) call fwrite($m, 1, 480*699*4, $f) $1 = 1342080 (gdb) call fclose($f) $2 = 0 You can dump memory/variables/buffer (gdb) x/s __progname into storage for observation purpose. 0xbef30d26: "com.rovio.angrybirdsrio" (gdb) print __page_size $3 = 4096
  • 62. Case Study Binder IPC: The heart of Android For detailed interaction and implementations, please check my presentation in 南台科技大學資 工系 (March 19, 2012)
  • 63. Processes running on Android $ ps ... root 37 1 248 156 c00aef2c 0000875c S /sbin/ueventd system 42 1 768 260 c022950c afd0b6fc S /system/bin/servicemanager root 43 1 3824 564 ffffffff afd0bdac S /system/bin/vold root 44 1 3796 560 ffffffff afd0bdac S /system/bin/netd root 45 1 628 264 c02588c0 afd0c0cc S /system/bin/debuggerd radio 46 1 4336 672 ffffffff afd0bdac S /system/bin/rild root 47 1 62224 27576 c00aef2c afd0b844 S zygote media 48 1 16828 3736 ffffffff afd0b6fc S /system/bin/mediaserver bluetooth 49 1 1216 572 c00aef2c afd0c59c S /system/bin/dbus-daemon root 50 1 776 316 c02a8424 afd0b45c S /system/bin/installd keystore 51 1 1704 432 c02588c0 afd0c0cc S /system/bin/keystore shell 52 1 696 336 c0050934 afd0c3ac S /system/bin/sh root 53 1 3356 160 ffffffff 00008294 S /sbin/adbd system 67 47 172464 32596 ffffffff afd0b6fc S system_server system 115 47 80028 20728 ffffffff afd0c51c S com.android.systemui app_24 124 47 80732 20720 ffffffff afd0c51c S com.android.inputmethod.latin radio 135 47 87848 20324 ffffffff afd0c51c S com.android.phone app_18 144 47 89136 24160 ffffffff afd0c51c S com.android.launcher app_7 165 47 86136 22736 ffffffff afd0c51c S android.process.acore app_0 197 47 73996 17472 ffffffff afd0c51c S com.android.deskclock app_14 208 47 75000 18464 ffffffff afd0c51c S android.process.media app_3 219 47 72228 17652 ffffffff afd0c51c S com.android.bluetooth app_25 234 47 85336 17836 ffffffff afd0c51c S com.android.mms app_26 254 47 74656 19080 ffffffff afd0c51c S com.android.email app_27 266 47 74912 18100 ffffffff afd0c51c S com.android.providers.calendar app_1 285 47 71616 16280 ffffffff afd0c51c S com.android.protips app_19 293 47 72184 16572 ffffffff afd0c51c S com.android.music app_21 301 47 74728 17208 ffffffff afd0c51c S com.android.quicksearchbox app_28 311 47 75408 18040 ffffffff afd0c51c S com.cooliris.media shell 323 52 856 316 00000000 afd0b45c R ps $ More than 30 processes (200+ threads).
  • 64. IPC = Inter-Process Communication Activity Activity Window Alarm Manager Manager Manager Kernel
  • 65. IPC Abstraction More abstract Intent • Intent – The highest level abstraction AIDL • Inter process method invocation – AIDL: Android Interface Binder Definition Language • binder: kernel driver • ashmem: shared memory
  • 66. Method invocation caller callee In the same process
  • 67. Inter-process method invocation caller interface caller interface How? callee interface callee
  • 68. Inter-process method invocation caller interface Proxy caller interface Binder in kernel Binder Thread callee Stub interface callee
  • 69. android.os.Parcel Delivering arguments of method ”flatten” ”unflatten” transmit
  • 70. UML Representation <<interface>> implements Proxy Stub
  • 71. UML Representation caller <<interface>> calls implements Proxy Stub extends callee
  • 72. AIDL Auto generated from .aidl file caller <<interface>> Proxy Stub callee
  • 73. Use Case: Who calls onPause() in Activity? 2 Send message by Handler Activity 3 OnPause() is queue Looper called in main thread Activity Manager Main Binder Thread Thread #1 Kernel 1 Call ”schedulePauseActivity” across process
  • 74. Binder • Multi-thread aware – Have internal status per thead – Compare to UNIX socket: sockets have internal status per file descriptor (FD)
  • 75. Binder  A pool of threads is associated to each service application to process incoming IPC (Inter-Process Communication).  Binder performs mapping of object between two processes.  Binder uses an object reference as an address in a process’s memory space.  Synchronous call, reference couting
  • 77. Binder is different from UNIX socket socket binder internal status associated to FD associated to PID (FD can be shared among threads in the same process) read & write stream I/O done at once by operation ioctl network Yes No transparency expected local only
  • 78. Transaction of Binder binder_write_read write_size write buffer write_consumed write_buffer read_size read_consumed read buffer read_buffer if (ioctl(fd, BINDER_WRITE_READ, &bwt ) >= 0) err = NO_ERROR; else err = -errno;
  • 79. Transaction of Binder Process A and B have different memory space. They can not see each other. Kernel Process B Process A Binder Copy memory by copy_from _user Then, wake up process B Kernel Process B Binder Process A Copy memory by copy_to_user Internally, Android uses Binder for graphics data transaction across processes. It is fairly efficient.
  • 80. Binder sample program • Build binder benchmark program cd system/extras/tests/binder/benchmarks mm adb push ../../../../out/target/product/crespo/data/nativebenchmark/binderAddInts /data/local/ • Execute adb shell su /data/local/binderAddInts -d 5 -n 5 & ps ... root 17133 16754 4568 860 ffffffff 400e6284 S /data/local/binderAddInts root 17135 17133 2520 616 00000000 400e5cb0 R /data/local/binderAddInts
  • 81. Binder sample program • Execute /data/local/binderAddInts -d 5 -n 5 & ps ... root 17133 16754 4568 860 ffffffff 400e6284 S /data/local/binderAddInts root 17135 17133 2520 616 00000000 400e5cb0 R /data/local/binderAddInts cat /sys/kernel/debug/binder/transaction_log transaction_log:3439847: call from 17133:17133 to 72:0 node 1 handle 0 size 124:4 transaction_log:3439850: reply from 72:72 to 17133:17133 node 0 handle 0 size 4:0 transaction_log:3439855: call from 17135:17135 to 17133:0 node 3439848 handle 1 size 8:0 ...
  • 82. Binder sysfs entries • adb shell ls /sys/kernel/debug/binder failed_transaction_log proc state stats transaction_log transactions
  • 83. Communication protocol If one process sends data to another process, it is called transaction. The data is called transaction data.
  • 84. Binder use case: Android Graphics
  • 85. Real Case Binder IPC is used for communicating between Graphics client and server. Taken from http://www.cnblogs.com/xl19862005/archive/2011/11/17/2215363.html
  • 86. Surface Source: frameworks/base/core/java/android/view/Surface.java • /* Handle on to a raw buffer that is being managed by the screen compositor */ public class Surface implements Parcelable { public Surface() { mCanvas = new CompatibleCanvas(); } private class CompatibleCanvas extends Canvas { /* ... */ } } Surface instances can be written to and restored from a Parcel. Surface instances can be written to and restored from a Parcel.
  • 87. Delivering arguments of method ”flatten” ”unflatten” transmit
  • 88. Properties Android SurfaceFlinger  Can combine 2D/3D surfaces and surfaces from multiple applications  Surfaces passed as buffers via Binder IPC calls  Can use OpenGL ES and 2D hardware accelerator for its compositions  Double-buffering using page-flip
  • 89.
  • 90. Case Study Android Power Management: how to interact between system and framework
  • 91. Base: Linux Kernel Android does rely on Linux Kernel for core system services ● Memory/Process Management ● Device Driver Model ● sysfs, kobject/uevent, netlink Android Kernel extensions ● Binder Key Idea: Android attempts to provide Key Idea: Android attempts to provide an abstraction layer between an abstraction layer between ● android_power hardware and the related software stack. hardware and the related software stack. – /sys/android_power/, /sys/power/
  • 92. Android's PM Concepts Android PM is built on top of standard Linux Power Management. It can support more aggressive PM, but looks fairly simple now. Components make requests to keep the power on through “Wake Locks”. ● PM does support several types of “Wake Locks”. If there are no active wake locks, CPU will be turned off. If there is are partial wake locks, screen and keyboard will be turned off.
  • 93.
  • 94. PM State Machine Touchscreen or keyboard user activity Touchscreen or keyboard user activity event or full wake locks acquired. event or full wake locks acquired. All partial wake locks All partial wake locks released released Partial wake locks acquired Partial wake locks acquired
  • 95. Design and Implementation IBinder as interface IBinder as interface to PowerManager to PowerManager
  • 96. Sample WakeLocks usage: AudioFlinger • File frameworks/base/services/audioflinger/AudioFlinger.cpp void AudioFlinger::ThreadBase::acquireWakeLock_l() { if (mPowerManager == 0) { sp<IBinder> binder = defaultServiceManager()->checkService(String16("power")); if (binder == 0) { LOGW("Thread %s can't connect to the PM service", mName); } else { mPowerManager = interface_cast<IPowerManager>(binder); binder->linkToDeath(mDeathRecipient); } } if (mPowerManager != 0) { sp<IBinder> binder = new BBinder(); status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK, binder, String16(mName)); if (status == NO_ERROR) { mWakeLockToken = binder; } LOGV("acquireWakeLock_l() %s status %d", mName, status); } }
  • 97. android_os_Power frameworks/base/core/jni/android_os_Power.cpp frameworks/base/core/jni/android_os_Power.cpp ... ... static JNINativeMethod method_table[] = { static JNINativeMethod method_table[] = { { "acquireWakeLock", "(ILjava/lang/String;)V", (void*)acquireWakeLock }, { "acquireWakeLock", "(ILjava/lang/String;)V", (void*)acquireWakeLock }, { "releaseWakeLock", "(Ljava/lang/String;)V", (void*)releaseWakeLock }, { "releaseWakeLock", "(Ljava/lang/String;)V", (void*)releaseWakeLock }, { "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout }, { "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout }, { "setLightBrightness", "(II)I", (void*)setLightBrightness }, { "setLightBrightness", "(II)I", (void*)setLightBrightness }, { "setScreenState", "(Z)I", (void*)setScreenState }, { "setScreenState", "(Z)I", (void*)setScreenState }, { "shutdown", "()V", (void*)android_os_Power_shutdown }, { "shutdown", "()V", (void*)android_os_Power_shutdown }, { "reboot", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot }, { "reboot", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot }, }; }; int register_android_os_Power(JNIEnv *env) int register_android_os_Power(JNIEnv *env) {{ return AndroidRuntime::registerNativeMethods( return AndroidRuntime::registerNativeMethods( env, "android/os/Power", env, "android/os/Power", method_table, NELEM(method_table)); method_table, NELEM(method_table)); }} static void static void acquireWakeLock(JNIEnv *env, jobject clazz, acquireWakeLock(JNIEnv *env, jobject clazz, jint lock, jstring idObj) jint lock, jstring idObj) { { if (idObj == NULL) { if (idObj == NULL) { throw_NullPointerException(env, "id is null"); throw_NullPointerException(env, "id is null"); return ; return ; } } const char *id = env->GetStringUTFChars(idObj, NULL); const char *id = env->GetStringUTFChars(idObj, NULL); acquire_wake_lock(lock, id); acquire_wake_lock(lock, id); env->ReleaseStringUTFChars(idObj, id); env->ReleaseStringUTFChars(idObj, id); } }
  • 98. Power hardware/libhardware_legacy/power/power.c hardware/libhardware_legacy/power/power.c ... ... int int acquire_wake_lock(int lock, const char* id) acquire_wake_lock(int lock, const char* id) { { initialize_fds(); initialize_fds(); const char * const OLD_PATHS[] = { const char * const OLD_PATHS[] = { if (g_error) return g_error; if (g_error) return g_error; "/sys/android_power/acquire_partial_wake_lock", "/sys/android_power/acquire_partial_wake_lock", "/sys/android_power/release_wake_lock", "/sys/android_power/release_wake_lock", int fd; int fd; "/sys/android_power/request_state" "/sys/android_power/request_state" if (lock == PARTIAL_WAKE_LOCK) { if (lock == PARTIAL_WAKE_LOCK) { }; }; fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK]; fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK]; } } const char * const NEW_PATHS[] = { const char * const NEW_PATHS[] = { else { else { "/sys/power/wake_lock", "/sys/power/wake_lock", return EINVAL; return EINVAL; "/sys/power/wake_unlock", "/sys/power/wake_unlock", } } "/sys/power/state" "/sys/power/state" return write(fd, id, strlen(id)); return write(fd, id, strlen(id)); }; }; } } (Kernel interface changes in Android Cupcake) (Kernel interface changes in Android Cupcake) static inline void static inline void initialize_fds(void) initialize_fds(void) { { if (g_initialized == 0) { if (g_initialized == 0) { if(open_file_descriptors(NEW_PATHS) < 0) { if(open_file_descriptors(NEW_PATHS) < 0) { open_file_descriptors(OLD_PATHS); open_file_descriptors(OLD_PATHS); on_state = "wake"; on_state = "wake"; off_state = "standby"; off_state = "standby"; } } g_initialized = 1; g_initialized = 1; } } } }
  • 99. Android PM Kernel APIs Source code static long has_wake_lock_locked(int type) static long has_wake_lock_locked(int type) { { struct wake_lock *lock, *n; struct wake_lock *lock, *n; long max_timeout = 0; long max_timeout = 0; ● kernel/power/userwake.c BUG_ON(type >= WAKE_LOCK_TYPE_COUNT); BUG_ON(type >= WAKE_LOCK_TYPE_COUNT); list_for_each_entry_safe(lock, n, list_for_each_entry_safe(lock, n, &active_wake_locks[type], link) { &active_wake_locks[type], link) { ● /kernel/power/wakelock.c if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) { if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) { long timeout = lock->expires - jiffies; long timeout = lock->expires - jiffies; if (timeout <= 0) if (timeout <= 0) expire_wake_lock(lock); expire_wake_lock(lock); else if (timeout > max_timeout) else if (timeout > max_timeout) static int power_suspend_late( static int power_suspend_late( max_timeout = timeout; struct platform_device *pdev, max_timeout = timeout; struct platform_device *pdev, } else } else pm_message_t state) pm_message_t state) return -1; { return -1; { } } int ret = int ret = return max_timeout; has_wake_lock(WAKE_LOCK_SUSPEND) ? return max_timeout; has_wake_lock(WAKE_LOCK_SUSPEND) ? } } -EAGAIN : 0; -EAGAIN : 0; return ret; return ret; long has_wake_lock(int type) } long has_wake_lock(int type) } { { long ret; long ret; static struct platform_driver power_driver = { static struct platform_driver power_driver = { unsigned long irqflags; .driver.name = "power", unsigned long irqflags; .driver.name = "power", spin_lock_irqsave(&list_lock, irqflags); spin_lock_irqsave(&list_lock, irqflags); .suspend_late = power_suspend_late, .suspend_late = power_suspend_late, ret = has_wake_lock_locked(type); }; ret = has_wake_lock_locked(type); }; spin_unlock_irqrestore(&list_lock, irqflags); spin_unlock_irqrestore(&list_lock, irqflags); static struct platform_device power_device = { static struct platform_device power_device = { return ret; .name = "power", return ret; .name = "power", } } }; };
  • 100. Android PM Kernel APIs kernel/power/wakelock.c static int __init wakelocks_init(void) static int __init wakelocks_init(void) { { int ret; int ret; int i; int i; for (i = 0; i < ARRAY_SIZE(active_wake_locks); i++) for (i = 0; i < ARRAY_SIZE(active_wake_locks); i++) INIT_LIST_HEAD(&active_wake_locks[i]); INIT_LIST_HEAD(&active_wake_locks[i]); wake_lock_init(&main_wake_lock, WAKE_LOCK_SUSPEND, "main"); wake_lock_init(&main_wake_lock, WAKE_LOCK_SUSPEND, "main"); wake_lock(&main_wake_lock); wake_lock(&main_wake_lock); wake_lock_init(&unknown_wakeup, WAKE_LOCK_SUSPEND, "unknown_wakeups"); wake_lock_init(&unknown_wakeup, WAKE_LOCK_SUSPEND, "unknown_wakeups"); ret = platform_device_register(&power_device); ret = platform_device_register(&power_device); if (ret) { if (ret) { pr_err("wakelocks_init: platform_device_register failedn"); pr_err("wakelocks_init: platform_device_register failedn"); goto err_platform_device_register; goto err_platform_device_register; } } ret = platform_driver_register(&power_driver); ret = platform_driver_register(&power_driver); if (ret) { if (ret) { pr_err("wakelocks_init: platform_driver_register failedn"); pr_err("wakelocks_init: platform_driver_register failedn"); goto err_platform_driver_register; goto err_platform_driver_register; } } suspend_work_queue = create_singlethread_workqueue("suspend"); suspend_work_queue = create_singlethread_workqueue("suspend"); if (suspend_work_queue == NULL) { if (suspend_work_queue == NULL) { ret = -ENOMEM; ret = -ENOMEM; goto err_suspend_work_queue; goto err_suspend_work_queue; } }
  • 101. Review • Native area – dynamic linking – Processes – Memory layout – Binder IPC – interactions with frameworks