title: What's .init_array section in ELF binary?
body: <p>Every article says .init_array section is a function array, but in my experience it isn't.</p>
  
  <p>Here is my .init_array of libc.so compiled for Android:</p>
  
  <pre><code>$ prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-objdump -s -j .init_array out/target/product/e910/obj/SHARED_LIBRARIES/libc_intermediates/LINKED/libc.so 
  
  out/target/product/e910/obj/SHARED_LIBRARIES/libc_intermediates/LINKED/libc.so:     file format elf32-littlearm
  
  Contents of section .init_array:
   42000 e1620100 ffffffff 75940200 00000000  .b......u.......
  </code></pre>
  
  <p>it contains 4 word (little endian):</p>
  
  <pre><code>000162e1
  ffffffff
  00029475
  00000000
  </code></pre>
  
  <p><code>000162e1</code> and <code>00029475</code> seems like some function pointer:</p>
  
  <pre><code>000162e0 &lt;__libc_preinit&gt;:
   * as soon as the shared library is loaded.
   */
  void __attribute__((constructor)) __libc_preinit(void);
  
  void __libc_preinit(void)
  {
     162e0:   b510        push    {r4, lr}
       * Note that:
       * - we clear the slot so no other initializer sees its value.
       * - __libc_init_common() will change the TLS area so the old one
       *   won't be accessible anyway.
       */
      void**      tls_area = (void**)__get_tls();
     162e2:   4805        ldr r0, [pc, #20]   (162f8 &lt;__libc_preinit+0x18&gt;)
      unsigned*   elfdata   = tls_area[TLS_SLOT_BIONIC_PREINIT];
  
      tls_area[TLS_SLOT_BIONIC_PREINIT] = NULL;
     162e4:   2200        movs    r2, #0
       * Note that:
       * - we clear the slot so no other initializer sees its value.
       * - __libc_init_common() will change the TLS area so the old one
       *   won't be accessible anyway.
       */
      void**      tls_area = (void**)__get_tls();
     162e6:   6803        ldr r3, [r0, #0]
      unsigned*   elfdata   = tls_area[TLS_SLOT_BIONIC_PREINIT];
     162e8:   68d8        ldr r0, [r3, #12]
  
      tls_area[TLS_SLOT_BIONIC_PREINIT] = NULL;
     162ea:   60da        str r2, [r3, #12]
  
      __libc_init_common(elfdata);
     162ec:   f010 fed6   bl  2709c &lt;__libc_init_common&gt;
  
      /* Setup malloc routines accordingly to the environment.
       * Requires system properties
       */
      extern void malloc_debug_init(void);
      malloc_debug_init();
     162f0:   f7ff fd0e   bl  15d10 &lt;malloc_debug_init&gt;
  }
     162f4:   bd10        pop {r4, pc}
     162f6:   46c0        nop         (mov r8, r8)
     162f8:   ffff0ff0    .word   0xffff0ff0
  </code></pre>
  
  <p>and <code>00029475</code> is:</p>
  
  <pre><code>00029474 &lt;__guard_setup&gt;:
  
  /* Initialize the canary with a random value from /dev/urandom.
   * If that fails, use the "terminator canary". */
  static void __attribute__ ((constructor))
  __guard_setup(void)
  {
     29474:   b570        push    {r4, r5, r6, lr}
      int fd;
  
      fd = open("/dev/urandom", O_RDONLY);
     29476:   4810        ldr r0, [pc, #64]   (294b8 &lt;__guard_setup+0x44&gt;)
     29478:   2100        movs    r1, #0
     2947a:   4478        add r0, pc
     2947c:   f7ef f89a   bl  185b4 &lt;open&gt;
      if (fd != -1) {
          ssize_t len = read(fd, &amp;__stack_chk_guard,
     29480:   4d0e        ldr r5, [pc, #56]   (294bc &lt;__guard_setup+0x48&gt;)
     29482:   447d        add r5, pc
  static void __attribute__ ((constructor))
  __guard_setup(void)
  {
      int fd;
  
      fd = open("/dev/urandom", O_RDONLY);
     29484:   1c06        adds    r6, r0, #0
      if (fd != -1) {
     29486:   1c43        adds    r3, r0, #1
     29488:   d00a        beq.n   294a0 &lt;__guard_setup+0x2c&gt;
          ssize_t len = read(fd, &amp;__stack_chk_guard,
     2948a:   4b0d        ldr r3, [pc, #52]   (294c0 &lt;__guard_setup+0x4c&gt;)
     2948c:   2204        movs    r2, #4
     2948e:   58e9        ldr r1, [r5, r3]
     29490:   f7e3 e8fe   blx c690 &lt;read&gt;
     29494:   1c04        adds    r4, r0, #0
                             sizeof(__stack_chk_guard));
          close(fd);
     29496:   1c30        adds    r0, r6, #0
     29498:   f7e3 e96a   blx c770 &lt;close&gt;
          if (len == sizeof(__stack_chk_guard))
     2949c:   2c04        cmp r4, #4
     2949e:   d009        beq.n   294b4 &lt;__guard_setup+0x40&gt;
              return;
      }
  
      /* If that failed, switch to 'terminator canary' */
      ((unsigned char *)&amp;__stack_chk_guard)[0] = 0;
     294a0:   4c07        ldr r4, [pc, #28]   (294c0 &lt;__guard_setup+0x4c&gt;)
      ((unsigned char *)&amp;__stack_chk_guard)[1] = 0;
      ((unsigned char *)&amp;__stack_chk_guard)[2] = '\n';
      ((unsigned char *)&amp;__stack_chk_guard)[3] = 255;
     294a2:   2101        movs    r1, #1
          if (len == sizeof(__stack_chk_guard))
              return;
      }
  
      /* If that failed, switch to 'terminator canary' */
      ((unsigned char *)&amp;__stack_chk_guard)[0] = 0;
     294a4:   2600        movs    r6, #0
     294a6:   5928        ldr r0, [r5, r4]
      ((unsigned char *)&amp;__stack_chk_guard)[1] = 0;
      ((unsigned char *)&amp;__stack_chk_guard)[2] = '\n';
      ((unsigned char *)&amp;__stack_chk_guard)[3] = 255;
     294a8:   424a        negs    r2, r1
      }
  
      /* If that failed, switch to 'terminator canary' */
      ((unsigned char *)&amp;__stack_chk_guard)[0] = 0;
      ((unsigned char *)&amp;__stack_chk_guard)[1] = 0;
      ((unsigned char *)&amp;__stack_chk_guard)[2] = '\n';
     294aa:   250a        movs    r5, #10
          if (len == sizeof(__stack_chk_guard))
              return;
      }
  
      /* If that failed, switch to 'terminator canary' */
      ((unsigned char *)&amp;__stack_chk_guard)[0] = 0;
     294ac:   7006        strb    r6, [r0, #0]
      ((unsigned char *)&amp;__stack_chk_guard)[1] = 0;
     294ae:   7046        strb    r6, [r0, #1]
      ((unsigned char *)&amp;__stack_chk_guard)[2] = '\n';
     294b0:   7085        strb    r5, [r0, #2]
      ((unsigned char *)&amp;__stack_chk_guard)[3] = 255;
     294b2:   70c2        strb    r2, [r0, #3]
  }
     294b4:   bd70        pop {r4, r5, r6, pc}
     294b6:   46c0        nop         (mov r8, r8)
     294b8:   0001451d    .word   0x0001451d
     294bc:   0001a09e    .word   0x0001a09e
     294c0:   ffffff1c    .word   0xffffff1c
  </code></pre>
  
  <h2>There are 3 questions:</h2>
  
  <ol>
  <li>Why there is 1 byte offset ? in arm architecture all instruction aligned to 2 byte boundary, but they are not.</li>
  <li>What's <code>ffffffff</code> in that array ?</li>
  <li>What's <code>00000000</code> in that array ?</li>
  </ol>