2016-12-26 1 views
3

から.relocを使用すると、これは私がAArch64に直面してる問題のカットダウン版です:私はセクションに、いくつかのデータをダンプし続けるこのマクロをしましたアセンブリ

 
#define GEN_DATA(_type) \ 
    .pushsection .mydata_##_type, "aw"; \ 
    .ifndef start; \ 
    start:; \ 
    .endif; \ 
    .word 1; \ 
    .reloc end_loc, R_AARCH64_ABS64, .; \ 
    .popsection 

私は最終的に、このような構造では似たタイプの開始と終了をキャプチャしたかった:

 
    .pushsection .head, "aw" 
    .quad start 
    end_loc: 
    .quad 0 
    .popsection 

セクションでは、start記号で始まる、私は追跡することができます。私はGEN_DATA()の呼び出しがビルドにどれくらいあるかを事前に知らないので、endを定義することはできません。私はどのくらい多くの部分が使用されるかわからないので、ガードシンボルスクリプトを置くことはできません。したがって、私はend_locの再配置エントリを残すことにしました。その結果、リンカは最終的にセクション全体が終了する場所に修正されます。はい、同じend_locの複数の再配置エントリがありますが、それらは絶対的な再配置であるため、競合しないと考えます。

私は勘違いしましたが、最後のバイナリでは、end_locが間違ったアドレスで修正されています。私はそれを複数の再配置エントリに責めますが、奇妙なことは、ダミーの余分な再配置エントリも追加すればすべてがOKです。

 
#define GEN_DATA(_type) \ 
    .pushsection .mydata_##_type, "aw"; \ 
    .ifndef start; \ 
    start:; \ 
    .endif; \ 
    .word 1; \ 
    .reloc end_loc, R_AARCH64_ABS64, .; \ 
    .reloc dummy_loc, R_AARCH64_ABS64, .; \ 
    .popsection 

と::

 
    .pushsection .head, "aw" 
    .quad start 
    end_loc: 
    .quad 0 
    dummy_loc: 
    .quad 0 
    .popsection 

だから私は思ったんだけど:私はするために、上記の構造を変更

  • なぜend_locが誤ってアップ固定なっていますか?複数の絶対再配置エントリがあれば何が問題になりますか?リンカーが順番にそれらを通過すると期待されていない、最後のものが有効になりますか?

  • ダミーの再配置を追加するだけの理由は何ですか?

基本的には何が起こっているのですか?

最後に、試してみることのできる方法がありますか?

EDIT:サンプルコードをGit repositoryにプッシュしました。逆アセンブリを表示するにはmakemake broken=1を使用してください。 Linaro AArch64 tool chain$PATHに必要です。

答えて

0

私は再配置で何が起こっているのか分かりませんが、達成しようとしていることを行う最も簡単な方法はリンカースクリプトを使用することです。これにより、すべての.mydata_XXX_typeセクションをグループ化し、グループ化されたセクションの開始と終了の記号を提供できます。このような何か:

SECTIONS 
{ 
    .mydata : 
    { 
     start = .; 
     *(.mydata*); 
     end_loc = .; 
    } 
} 

あなたは、このようなアセンブリファイルを使用します。

.macro gen_data, type 
    .pushsection .mydata_\()\type\()_type, "aw" 
    .word 1 
    .popsection 
    .endm 

    .text 
    gen_data foo 
    gen_data bar 
    gen_data baz 

    .section .head, "aw" 
    .quad start 
    .quad end_loc 

(私が使用したアセンブラマクロ代わりに、Cマクロの彼らはで動作する方がはるかに簡単だから。)あなたはこのように2つの以上のファイルを使用したい:

as -o test.o test.s 
    ld -o test test.o test.ld 

は、あなたが可能なすべての「型」を知っている場合、あなたはそれを行うという事実に依存することにより、リンカスクリプトを使用せずに、リンカは、未知のセクションを配置します最初に遭遇する注文。たとえば、次のように

.section .mydata_start, "aw" 
start: 
    .section .mydata_foo_type, "aw" 
    .section .mydata_bar_type, "aw" 
    .section .mydata_baz_type, "aw" 
    .section .mydata_end, "aw" 
end_loc: 

    .macro gen_data, type 
    .ifndef .mydata_\()\type\()_type 
    .error "gen_data invoked with unknown type '\type\()'" 
    .endif 
    .pushsection .mydata_\()\type\()_type, "aw" 
    .word 1 
    .popsection 
    .endm 

    .text 
    gen_data foo 
    gen_data bar 
    gen_data baz 
    # gen_data unk 

    .section .head, "aw" 
    .quad start 
    .quad end_loc 

マクロを使用して複数のアセンブラファイルを持っているすべてのアセンブラファイルは、彼らがリンカコマンドラインに表示される順番は関係ありませんので、開始時に上記のよう.sectionのディレクティブを含めることを確認してください。

両方の解決方法でマクロの問題が解決されることに注意してください。他の不明なセクションが、リンカーにこの順番で最初に現れる場合は、.mydata_XXX_typeセクションの間に配置することができます。