2017-03-21 11 views
0

私はARMのために-fpieでコンパイルされたコードモジュールを持っています。最初に実行されたときにBSSをクリアしたいと思います。しかし、BSSセクションの開始と終了のリンカスクリプトシンボルを参照すると、ローカル変数に絶対アドレスを含むコードが得られます。位置独立コードのリンカ定義シンボルの参照

Disassembly of section .text: 

00180000 <code_entry>: 
    180000: e92d0007 push {r0, r1, r2} 
    180004: e3a00000 mov r0, #0 
    180008: e59f1014 ldr r1, [pc, #20] ; 180024 <loop_bss+0x14> 
    18000c: e59f2014 ldr r2, [pc, #20] ; 180028 <loop_bss+0x18> 

00180010 <loop_bss>: 
    180010: e4810004 str r0, [r1], #4 
    180014: e1510002 cmp r1, r2 
    180018: bafffffc blt 180010 <loop_bss> 
    18001c: e8bd0007 pop {r0, r1, r2} 
    180020: ea00189f b 1862a4 <startPICode> 
    180024: 00194360 andseq r4, r9, r0, ror #6 
    180028: 001950e8 andseq r5, r9, r8, ror #1 

readelfが私のELFファイルが何の再配置を持っていないことを示しています

.section entry_point 

code_entry: 
    # Save arguments to the stack 
    push {r0-r2} 

    # Loop over the BSS section, set it all to 0 
    mov  r0, #0 
    ldr  r1, =__bss_start 
    ldr  r2, =__bss_end 
loop_bss: 
    str  r0, [r1], #4 
    cmp  r1, r2 
    blt  loop_bss 

    # Pop arguments from the stack 
    pop  {r0-r2} 

    # Branch to C code (which will return to caller on its own) 
    b  startPICode 

出力は以下の通りです:

は、ここに私のアセンブリのエントリポイントです。

リンカ記号は常に絶対アドレスである整数に過ぎないと思いますか?もしそうなら、ロード時または実行時にアドレスを修正する方法はありますか?あるいは、このコードのBSSをクリアする別の正しい方法がありますか?

編集: readelf -s出力を追加しています。関連する.SファイルとBSSに関連するすべてがここにあります。

Symbol table '.symtab' contains 812 entries: 
    Num: Value Size Type Bind Vis  Ndx Name 
    0: 00000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 00180000  0 SECTION LOCAL DEFAULT 1 
    2: 0019297c  0 SECTION LOCAL DEFAULT 2 
    3: 00192994  0 SECTION LOCAL DEFAULT 3 
    4: 001929b0  0 SECTION LOCAL DEFAULT 4 
    5: 00193808  0 SECTION LOCAL DEFAULT 5 
    6: 001942dc  0 SECTION LOCAL DEFAULT 6 
    7: 00194350  0 SECTION LOCAL DEFAULT 7 
    8: 00194358  0 SECTION LOCAL DEFAULT 8 
    9: 0019435c  0 SECTION LOCAL DEFAULT 9 
    10: 00194360  0 SECTION LOCAL DEFAULT 10 
    11: 00194360  0 SECTION LOCAL DEFAULT 11 
    12: 001950e8  0 SECTION LOCAL DEFAULT 12 
    13: 001970f0  0 SECTION LOCAL DEFAULT 13 
    14: 00000000  0 SECTION LOCAL DEFAULT 14 
    15: 00000000  0 SECTION LOCAL DEFAULT 15 
    16: 00000000  0 SECTION LOCAL DEFAULT 16 
    17: 00000000  0 SECTION LOCAL DEFAULT 17 
    18: 00000000  0 SECTION LOCAL DEFAULT 18 
    19: 00000000  0 SECTION LOCAL DEFAULT 19 
    20: 00000000  0 SECTION LOCAL DEFAULT 20 
    21: 00000000  0 SECTION LOCAL DEFAULT 21 
    22: 00000000  0 SECTION LOCAL DEFAULT 22 
    23: 00000000  0 SECTION LOCAL DEFAULT 23 
    24: 00000000  0 FILE LOCAL DEFAULT ABS ./src/entry.o 
    25: 00180000  0 NOTYPE LOCAL DEFAULT 1 code_entry 
    26: 00180000  0 NOTYPE LOCAL DEFAULT 1 $a 
    27: 00180010  0 NOTYPE LOCAL DEFAULT 1 loop_bss 
    28: 00180024  0 NOTYPE LOCAL DEFAULT 1 $d 
    29: 00000124  0 NOTYPE LOCAL DEFAULT 17 $d 

    484: 00194360  0 NOTYPE GLOBAL DEFAULT 10 __sbss_start 

    525: 00193804  0 NOTYPE GLOBAL DEFAULT 5 __sbss2_end 

    555: 001950e8  0 NOTYPE GLOBAL DEFAULT 11 __bss_end 

    565: 00194360  0 NOTYPE GLOBAL DEFAULT 10 __tbss_start 

    581: 00194360  0 NOTYPE GLOBAL DEFAULT 10 __sbss_end 

    599: 00193804  0 NOTYPE GLOBAL DEFAULT 5 __sbss2_start 

    667: 00194360  0 NOTYPE GLOBAL DEFAULT 11 __bss_start 

    753: 00194360  0 NOTYPE GLOBAL DEFAULT 10 __tbss_end 
+0

readelf -s を投稿できますか?これはベアメタルですか? – InfinitelyManic

+0

はい、これはベアメタルです。私は完全なreadelfを投稿したくないです。しかし、投稿に役立つ特定のシンボルがありますか? –

+0

* bss * – InfinitelyManic

答えて

0

お客様が作成したコードは再配置可能ではありません。再配置可能にするには、具体的には__bss_start__bss_endの相対アドレスを作成します。例えば:R3で

.section entry_point 

bss_start_rel: 
    .word __bss_start__ - bss_start_rel 
bss_end_rel: 
    .word __bss_end__ - bss_start_rel 

.global code_entry 
code_entry: 
    # Save arguments to the stack 
    push {r0-r2} 

    # Loop over the BSS section, set it all to 0 
    mov  r0, #0 
    adr  r3, bss_start_rel 
    ldr  r1, bss_start_rel 
    ldr  r2, bss_end_rel 
    add  r1, r1, r3 
    add  r2, r2, r3 

    ... 

ADR疑似命令の結果はbss_start_relのアドレスはPC相対演算(例えばsub r3, pc, #24)を用いてロードされます。これは、__bss_start____bss_end__の位置を計算するためのベースとして使用され、相対位置はbss_start_relbss_start_endに格納されます。

+0

まさに私が必要なもの、助けてくれてありがとう! –

関連する問題