2010-02-26 57 views
3

我想更好地理解ARM精靈中的二進制文件。ARM中的ELF怪異和動態鏈接

我需要弄清楚得到我的自制彙編程序輸出ELF可執行文件爲gp2x f200。於是我開始用open2x交叉編譯工具鏈編譯此程序:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
int main(){ 
    chdir("/usr/gp2x"); 
    execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL); 
    return 0; 
} 

它否則看起來像剛剛好,比起86沒什麼特別的。在ELF頭文件中,Flags-field被使用了!我發現了一些ARM精靈規範,但未提及爲什麼需要這些規範。

ELF Header: 
    Magic: 7f 45 4c 46 01 01 01 61 00 00 00 00 00 00 00 00 
    Class:        ELF32 
    Data:        2's complement, little endian 
    Version:       1 (current) 
    OS/ABI:       ARM 
    ABI Version:      0 
    Type:        EXEC (Executable file) 
    Machine:       ARM 
    Version:       0x1 
    Entry point address:    0x82f8 
    Start of program headers:   52 (bytes into file) 
    Start of section headers:   3032 (bytes into file) 
    Flags:        0x202, has entry point, GNU EABI, software FP 
    Size of this header:    52 (bytes) 
    Size of program headers:   32 (bytes) 
    Number of program headers:   6 
    Size of section headers:   40 (bytes) 
    Number of section headers:   31 
    Section header string table index: 28 

現在其他結構看起來與它們在x86上的結構並沒有很大的不同。它實際上看起來非常熟悉!即使是重定位的類型也很熟悉(R_386_JUMP_SLOT和R_ARM_JUMP_SLOT)。雖然這裏開始變得很奇怪。

Relocation section '.rel.plt' at offset 0x280 contains 4 entries: 
Offset  Info Type   Sym.Value Sym. Name 
00010638 00000116 R_ARM_JUMP_SLOT 000082c8 abort 
0001063c 00000416 R_ARM_JUMP_SLOT 000082d4 __libc_start_main 
00010640 00000516 R_ARM_JUMP_SLOT 000082e0 execl 
00010644 00000716 R_ARM_JUMP_SLOT 000082ec chdir 

Disassembly of section .plt: 

000082b4 <.plt>: 
    82b4: e52de004 str lr, [sp, #-4]! 
    82b8: e59fe004 ldr lr, [pc, #4] ; 82c4 <.plt+0x10> 
    82bc: e08fe00e add lr, pc, lr 
    82c0: e5bef008 ldr pc, [lr, #8]! 
    82c4: 00008368 andeq r8, r0, r8, ror #6 
    82c8: e28fc600 add ip, pc, #0 ; 0x0 
    82cc: e28cca08 add ip, ip, #32768 ; 0x8000 
    82d0: e5bcf368 ldr pc, [ip, #872]! 
    82d4: e28fc600 add ip, pc, #0 ; 0x0 
    82d8: e28cca08 add ip, ip, #32768 ; 0x8000 
    82dc: e5bcf360 ldr pc, [ip, #864]! 
    82e0: e28fc600 add ip, pc, #0 ; 0x0 
    82e4: e28cca08 add ip, ip, #32768 ; 0x8000 
    82e8: e5bcf358 ldr pc, [ip, #856]! 
    82ec: e28fc600 add ip, pc, #0 ; 0x0 
    82f0: e28cca08 add ip, ip, #32768 ; 0x8000 
    82f4: e5bcf350 ldr pc, [ip, #848]! 

如果你看看Sym.Value,它指向這個PLT。問題是我不明白這應該如何工作。什麼是R_ARM_JUMP_SLOT在這裏造成的?爲什麼我的PLT包含這些奇怪的指令,我的動態鏈接器如何處理它們?

82ec: e28fc600 add ip, pc, #0 ; 0x0 
    82f0: e28cca08 add ip, ip, #32768 ; 0x8000 
    82f4: e5bcf350 ldr pc, [ip, #848]! 

該程序正在加載到0x8000,所以我有點理解該部分。除了我無法理解,如果我用-fPIC -shared編譯這個,這可能是相同的。

那麼..動態鏈接如何在ARM下工作?

回答

1

我今天晚上自己解決了。 ARM linux上有很多可能的重定位機制。我看着規格,發現了一種相對理智的重新定位:R_ARM_ABS32。我唯一需要做的就是使用它。

與X86 ELF後端相比,除了elf標頭中的字節與我在gcc生成的二進制文件中找到的字節相匹配外,我不需要改變任何其他東西。爲了安全起見,我使用二進制對齊某些結構。

爲了將來我必須提供一種干預分支代碼到我的PLT或採取其他方法我可以生產更大的程序使用共享庫。這是一個彙編設計問題,而不是理解ELF格式的麻煩。

幾分鐘前,我的第一個應用程序在gp2x f200!它使用'system'-libc函數將問候寫入文件並返回到機器的主菜單。 \ o/

+0

你能指向一些文件嗎 – mSO 2014-04-30 05:25:36