Android Linker Script - Missing PT_DYNAMIC

1

I am attempting to run the following sample Android program that prints out the size of a function.

#include <stdio.h>

extern unsigned char func_start;
extern unsigned char func_end;

int func(void) __attribute__((section(".func")));
int func(void)
{
    return 0;
}

int main(int argc, char **argv)
{
    size_t func_size = &func_end - &func_start;

    printf("%zu\n", func_size);

    return 0;
}

I am using the following linker script to define the func_start and func_end variables.

SECTIONS
{
    .func : {
        func_start = .;
        *(.func);
        func_end = .;
    }
}

This code compiles with the following commands.

/opt/toolchains/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-gcc -Wall -Werror --sysroot /opt/android-ndk-r10d/platforms/android-19/arch-arm -o func func.c -T func.ld

When I attempt to run this program on a 4.4.4 Android device, I receive the following error from the linker.

CANNOT LINK EXECUTABLE: missing PT_DYNAMIC in "./func"

The following shows the program headers from readelf for the output ELF.

Elf file type is DYN (Shared object file)
Entry point 0x14
There are 7 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x00000000 0x00000000 0x000e0 0x000e0 R   0x4
  INTERP         0x001258 0x00000258 0x00000258 0x00013 0x00013 R   0x1
      [Requesting program interpreter: /system/bin/linker]
  LOAD           0x001000 0x00000000 0x00000000 0x0026b 0x0026b R E 0x1000
  LOAD           0x00126b 0x0000026b 0x0000026b 0x00149 0x00149 RW  0x1000
  LOAD           0x001438 0x00000438 0x00000438 0x0001c 0x0001c R E 0x1000
  DYNAMIC        0x00128c 0x0000028c 0x0000028c 0x000f0 0x000f0 RW  0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .text .plt .rel.plt .rel.dyn .note.android.ident .rodata .dynsym .dynstr .hash .interp 
   03     .data .fini_array .init_array .preinit_array .ctors .dynamic .got .bss 
   04     .func 
   05     .dynamic 
   06        

The following shows the section headers from readelf for the output ELF.

There are 26 section headers, starting at offset 0x1920:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 001000 000118 00  AX  0   0  4
  [ 2] .plt              PROGBITS        00000118 001118 000038 00  AX  0   0  4
  [ 3] .rel.plt          REL             00000150 001150 000018 08   A  7   0  4
  [ 4] .rel.dyn          REL             00000168 001168 000038 08   A  7   0  4
  [ 5] .note.android.ide PROGBITS        000001a0 0011a0 000018 00   A  0   0  4
  [ 6] .rodata           PROGBITS        000001b8 0011b8 000008 00   A  0   0  4
  [ 7] .dynsym           DYNSYM          000001c0 0011c0 000040 10   A  8   1  4
  [ 8] .dynstr           STRTAB          00000200 001200 000032 00   A  0   0  1
  [ 9] .hash             HASH            00000234 001234 000024 04   A  7   0  4
  [10] .interp           PROGBITS        00000258 001258 000013 00   A  0   0  1
  [11] .data             PROGBITS        0000026b 00126b 000000 00  WA  0   0  1
  [12] .fini_array       FINI_ARRAY      0000026c 00126c 000008 00  WA  0   0  4
  [13] .init_array       INIT_ARRAY      00000274 001274 000008 00  WA  0   0  4
  [14] .preinit_array    PREINIT_ARRAY   0000027c 00127c 000008 00  WA  0   0  4
  [15] .ctors            PROGBITS        00000284 001284 000008 00  WA  0   0  4
  [16] .dynamic          DYNAMIC         0000028c 00128c 0000f0 08  WA  8   0  4
  [17] .got              PROGBITS        0000037c 00137c 000034 00  WA  0   0  4
  [18] .bss              NOBITS          000003b0 0013b0 000004 00  WA  0   0  4
  [19] .func             PROGBITS        00000438 001438 00001c 00  AX  0   0  4
  [20] .comment          PROGBITS        00000000 001454 000035 01  MS  0   0  1
  [21] .note.gnu.gold-ve NOTE            00000000 00148c 00001c 00      0   0  4
  [22] .ARM.attributes   ARM_ATTRIBUTES  00000000 0014a8 00002d 00      0   0  1
  [23] .symtab           SYMTAB          00000000 0014d8 000240 10     24  25  4
  [24] .strtab           STRTAB          00000000 001718 000116 00      0   0  1
  [25] .shstrtab         STRTAB          00000000 00182e 0000ef 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

As dynamic program header clearly exists in the ELF, I have no idea why the linker is giving me this error message. Can anyone help me understand what I am doing wrong here?

Follow-Up

I noticed that one of the LOAD segments actually overlaps with the DYNAMIC segment.

Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
LOAD           0x00126b 0x0000026b 0x0000026b 0x00149 0x00149 RW  0x1000
DYNAMIC        0x00128c 0x0000028c 0x0000028c 0x000f0 0x000f0 RW  0x4

Could this be causing the DYNAMIC section to be overwritten in memory which is why the linker cannot find it?

Default Linker Script

Assuming the problem was something with my primitive linker script, I tried to compile the program using one of the default Android toolchain linker script found in android-ndk-r10d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/arm-linux-androideabi/lib/ldscripts/. I tried compiling with the various linker scripts here but kept receiving linker script syntax errors for the SORT_ keywords.

android
c
android-ndk
linker
linker-errors
asked on Stack Overflow Apr 30, 2015 by bangelo • edited Apr 30, 2015 by bangelo

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0