我成功地将一个Android项目的ARM库修改为PIC(位置无关代码),因为我想做一些无关的修复,Android只支持PIC库,因为Lollipop。(我的叉子最新消息来源是
http://github.com/sleekweasel/Beebdroid
)
现在我想在整理和编写一个pull请求之前让x86也工作起来(因为它在原始项目中),但是我的x86比我的ARM知识要弱,Android汇编文章似乎只处理ARM。
我遇到的两个问题是
LEA
和
CALL
:他们导致
ld
发出
warning: shared library text segment is not shareable
如果我把他们说出来的话
./gradlew build
很高兴链接,但显然代码工作得不太好。
以下是这个项目的片段-也许它们会比我的英文描述更清晰。我认为这是一个完整的上下文,因为只有指令和它们与链接器的交互才是问题所在:
应用程序/src/main/jni/6502asm\u x86.S:
.intel_syntax noprefix
.text
.global exec6502
.global acpu
exec6502:
pusha
# Keep CPU* in EBP
lea ebp,acpu // Causes PIC to fail.
// ... code removed ...
lea ebx, fns_asm // Causes PIC to fail.
// ... code removed ...
call do_poll_C // Causes PIC to fail.
// ... code removed ...
popa
ret
// Lots of op-code implementations here - they have no effect on linking
// .section .rodata
.balign 4
fns_asm:
.long 0 // 0x00 BRK
.long 0 - fns_asm + opasm_ora_indzx // 0x01 ORA (,x)
.long 0 - fns_asm + opasm_undef
typedef struct M6502_struct M6502;
struct M6502_struct { ... };
void exec6502(M6502* cpu);
extern void do_poll_C(M6502*, int c);
app/src/main/jni/6502.c号文件
M6502 acpu;
M6502* the_cpu = &acpu;
void do_poll_C(M6502* cpu, int c) {
...
}
JNIEXPORT jint JNICALL Java_com_littlefluffytoys_beebdroid_Beebdroid_bbcRun(JNIEnv * env, jobject obj)
{
// Position independent code, hopefully!
the_cpu->c_fns = &fns; // +40
exec6502(the_cpu);
return the_cpu->pc_trigger_hit;
}
应用程序/src/main/jni/安卓.mk
# ... stuff ...
ifeq ($(TARGET_ARCH),arm)
LOCAL_CFLAGS += -march=armv6t2 -O9 -D_ARM_ -fPIC
LOCAL_SRC_FILES := 6502asm_arm.S
endif
ifeq ($(TARGET_ARCH),x86)
LOCAL_CFLAGS += -m32 -fPIC
LOCAL_SRC_FILES := 6502asm_x86.S
endif
# ... stuff ...
# The ARMv7 is significanly faster due to the use of the hardware FPU
APP_ABI := armeabi-v7a x86
APP_PLATFORM := android-16
ifneq ($(APP_OPTIM),debug)
APP_CFLAGS += -O3 -fPIC
endif
APP_CFLAGS += -fPIC
LOCAL_SRC_FILES += \
6502.c \
main.c \
and_more_files.c
我记得看到了我需要重写的地方
利亚
变成一个
呼叫
指令和目标内存偏移量(也在文本段中):因为只需要文本段中的计算偏移量,所以绕过了链接器。(我只有一个
重写:访问汇编代码中偏移量的跳转表-其他两个将变成输入参数和由该参数指向的块中的指针,就像我为ARM所做的那样。)
我更困惑于
呼叫
to C函数没有被链接器处理,因为ARM的加载程序很乐意重新定位
BL
说明。我已经有了
-fPIC
在C编译标志中。添加
.global do_poll_C
.global
外部C函数的声明。
我知道我可以传入一个用C函数指针初始化的块-我开始对ARM库这样做,但后来发现加载程序不需要这样做。(我甚至可以向汇编语言表添加一个C指针
fns_asm
exec6502
我是否需要x86的函数指针块,或者是否有一些魔法咒语我可以用来要求加载程序处理我的x86调用指令,就像BL‘just works’与ARM一样?
谢谢你的帮助。