Что& #39;s.init _раздел массива в двоичном формате ELF?

В каждой статье говорится, что раздел массива.init _является массивом функций, но по моему опыту это не так.

Вот мой.init _массив libc.so, скомпилированный для Android:

$ 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.......

он содержит 4 слова (с прямым порядком байтов):

000162e1
ffffffff
00029475
00000000

000162e1и 00029475похоже на какой-то указатель на функцию:

000162e0 <__libc_preinit>:
 * 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 <__libc_preinit+0x18>)
    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 <__libc_init_common>

    /* Setup malloc routines accordingly to the environment.
     * Requires system properties
     */
    extern void malloc_debug_init(void);
    malloc_debug_init();
   162f0:   f7ff fd0e   bl  15d10 <malloc_debug_init>
}
   162f4:   bd10        pop {r4, pc}
   162f6:   46c0        nop         (mov r8, r8)
   162f8:   ffff0ff0   .word   0xffff0ff0

и 00029475:

00029474 <__guard_setup>:

/* 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 <__guard_setup+0x44>)
   29478:   2100        movs    r1, #0
   2947a:   4478        add r0, pc
   2947c:   f7ef f89a   bl  185b4 <open>
    if (fd != -1) {
        ssize_t len = read(fd, &__stack_chk_guard,
   29480:   4d0e        ldr r5, [pc, #56]   (294bc <__guard_setup+0x48>)
   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 <__guard_setup+0x2c>
        ssize_t len = read(fd, &__stack_chk_guard,
   2948a:   4b0d        ldr r3, [pc, #52]   (294c0 <__guard_setup+0x4c>)
   2948c:   2204        movs    r2, #4
   2948e:   58e9        ldr r1, [r5, r3]
   29490:   f7e3 e8fe   blx c690 <read>
   29494:   1c04        adds    r4, r0, #0
                           sizeof(__stack_chk_guard));
        close(fd);
   29496:   1c30        adds    r0, r6, #0
   29498:   f7e3 e96a   blx c770 <close>
        if (len == sizeof(__stack_chk_guard))
   2949c:   2c04        cmp r4, #4
   2949e:   d009        beq.n   294b4 <__guard_setup+0x40>
            return;
    }

    /* If that failed, switch to 'terminator canary' */
    ((unsigned char *)&__stack_chk_guard)[0] = 0;
   294a0:   4c07        ldr r4, [pc, #28]   (294c0 <__guard_setup+0x4c>)
    ((unsigned char *)&__stack_chk_guard)[1] = 0;
    ((unsigned char *)&__stack_chk_guard)[2] = '\n';
    ((unsigned char *)&__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 *)&__stack_chk_guard)[0] = 0;
   294a4:   2600        movs    r6, #0
   294a6:   5928        ldr r0, [r5, r4]
    ((unsigned char *)&__stack_chk_guard)[1] = 0;
    ((unsigned char *)&__stack_chk_guard)[2] = '\n';
    ((unsigned char *)&__stack_chk_guard)[3] = 255;
   294a8:   424a        negs    r2, r1
    }

    /* If that failed, switch to 'terminator canary' */
    ((unsigned char *)&__stack_chk_guard)[0] = 0;
    ((unsigned char *)&__stack_chk_guard)[1] = 0;
    ((unsigned char *)&__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 *)&__stack_chk_guard)[0] = 0;
   294ac:   7006        strb    r6, [r0, #0]
    ((unsigned char *)&__stack_chk_guard)[1] = 0;
   294ae:   7046        strb    r6, [r0, #1]
    ((unsigned char *)&__stack_chk_guard)[2] = '\n';
   294b0:   7085        strb    r5, [r0, #2]
    ((unsigned char *)&__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

Есть 3 вопроса:

  1. Почему смещение равно 1 байту? в архитектуре arm все инструкции выровнены по 2-байтовой границе, но это не так.
  2. Что ffffffffв этом массиве?
  3. Что 00000000в этом массиве?
5
задан Philippe 17 May 2013 в 14:12
поделиться