1
我正在编写一个NDK程序,我想用我自己的lds脚本编译它以组织输出的结构。使用.lds脚本编译NDK程序
作为测试程序,这是最简单的问候词样本:
#include <stdio.h>
extern int main(int argc, char *argv[])
{
printf("hello jni\r\n");
return 0;
}
Android.mk的部分:
#LOCAL_LDFLAGS += -fuse-ld=gold
LOCAL_LDFLAGS += -fuse-ld=bfd
LOCAL_LDFLAGS += -T$(LOCAL_PATH)/test.lds
test.lds:
OUTPUT_FORMAT("elf32-littlearm" , "elf32-littlearm" , "elf32-littlearm")
OUTPUT_ARCH(arm)
SECTIONS
{
.text : {
*(.text)
}
.data : {*(.data)}
.bss : {*(.bss)}
}
所以,如果我使用bfd LOCAL_LDFLAGS += -fuse-ld=bfd
进行链接,问题是在lds中定义的所有部分没有链接到输出中: 有10个头偏移量开始0x818c:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 00000000 008000 000013 00 A 0 0 1
[ 2] .dynsym DYNSYM 00000014 008014 000000 10 A 3 1 4
[ 3] .dynstr STRTAB 00000014 008014 000027 00 A 0 0 1
[ 4] .hash HASH 0000003c 00803c 00000c 04 A 2 0 4
[ 5] .got.plt PROGBITS 00000048 008048 00000c 04 WA 0 0 4
[ 6] .dynamic DYNAMIC 00000054 008054 000090 08 WA 3 0 4
[ 7] .comment PROGBITS 00000000 0080e4 000025 01 MS 0 0 1
[ 8] .ARM.attributes ARM_ATTRIBUTES 00000000 008109 00002d 00 0 0 1
[ 9] .shstrtab STRTAB 00000000 008136 000054 00 0 0 1
然后我用ld.gold LOCAL_LDFLAGS += -fuse-ld=gold
链接,更多的问题就出来了。第一个问题是一个链接错误:
[armeabi] Compile++ thumb: testlds <= main.cpp
[armeabi] Executable : testlds
/media/android/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.gold: error: multiple SHT_ARM_EXIDX sections .ARM.exidx.text.startup.main and .ARM.exidx in a non-relocatable link
/media/android/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.gold: warning: unwinding may not work because EXIDX input section 6 of /media/android/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/libgcc.a(unwind-arm.o) is not in EXIDX output section
/media/android/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.gold: warning: unwinding may not work because EXIDX input section 6 of /media/android/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/libgcc.a(pr-support.o) is not in EXIDX output section
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/testlds] Error 1
我搜索与关键字multiple SHT_ARM_EXIDX sections
并找到黄金的来源一些意见:
- Output_section* os = layout->find_output_section(".ARM.exidx");
- if (os != NULL && os->type() == elfcpp::SHT_ARM_EXIDX)
+ Arm_output_section<big_endian>* exidx_output_section = NULL;
+ for (Layout::Section_list::const_iterator p =
+ layout->section_list().begin();
+ p != layout->section_list().end();
+ ++p)
+ if ((*p)->type() == elfcpp::SHT_ARM_EXIDX)
+ {
+ if (exidx_output_section == NULL)
+ exidx_output_section =
+ Arm_output_section<big_endian>::as_arm_output_section(*p);
+ else
+ // We cannot handle this now.
+ gold_error(_("multiple SHT_ARM_EXIDX sections %s and %s in a "
+ "non-relocatable link"),
+ exidx_output_section->name(),
+ (*p)->name());
+ }
然后我修改了LDS一点:
SECTIONS
{
.text : {
*(.text)
*(.ARM.exidx)
}
.data : {*(.data)}
.bss : {*(.bss)}
}
这一次,编译成功了。但我的程序无法执行。我用IDA打开程序,发现输入函数没有正确指向主函数。
我现在完全失去了。我怎样才能用某个ID编译我的NDK程序?