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.
User contributions licensed under CC BY-SA 3.0