4

この「アセンブリ」ファイルがあります(ディレクティブのみを含む)

// declare protected region as somewhere within the stack
.equiv prot_start, $stack_top & 0xFFFFFF00 - 0x1400
.equiv prot_end,   $stack_top & 0xFFFFFF00 - 0x0C00

このリンカー スクリプトと組み合わせると、次のようになります。

SECTIONS {
   "$stack_top"   = 0x10000;
}

アセンブルすると、この出力が生成されます

file.s: Assembler messages:
file.s: Error: invalid operands (*UND* and *ABS* sections) for `&' when setting `prot_start'
file.s: Error: invalid operands (*UND* and *ABS* sections) for `&' when setting `prot_end'

どうすればこれを機能させることができますか?

4

2 に答える 2

3

なぜそれが不可能なのですか?

あなたはGASのドキュメントにリンクしていますが、それができない理由は何ですか?

回答: GAS は、ELF オブジェクト ファイルを介して操作をリンカに伝達する必要があります。このように伝達できるのは+、および-(-は単なる+負の値です) だけです。したがって、これは ELF 形式の根本的な制限であり、GAS 開発者の怠慢だけではありません。

GAS がオブジェクト ファイルにコンパイルされると、リンク ステップが続き、シンボルの最終的な値を決定するのは再配置です。

質問:+伝えられるのに、伝えられないのはなぜ&ですか?

回答: なぜなら+は推移的: です(a + b) + c == a + (b + c)+、 と&は「一緒に推移的」: ではありません(a & b) + c!= a & (b + c)

+ELF 形式で がどのように伝えられ、それ&が不可能であると自分自身に納得させるかを見てみましょう。

慣れていない場合は、最初に再配置とは何かを学びます: https://stackoverflow.com/a/30507725/895245

同じエラーを生成する別の例で例を最小化しましょう。

a: .long s
b: .long s + 0x12345678
/* c: .long s & 1 */
s:

コンパイルと逆コンパイル:

as --32 -o main.o main.S
objdump -dzr main.o

出力には次が含まれます。

00000000 <a>:
   0:   08 00                   or     %al,(%eax)
            0: R_386_32 .text
   2:   00 00                   add    %al,(%eax)

00000004 <b>:
   4:   80 56 34 12             adcb   $0x12,0x34(%esi)
            4: R_386_32 .text

これはコードではないため、逆アセンブルは無視して、シンボル、バイト、および再配置だけを見てください。

R_386_32引っ越しが2回あります。System V ABI for IA-32 (ELF フォーマットを定義) から、そのタイプの再配置は次のように計算されます。

S + A

どこ:

  • S:オブジェクトファイルの再配置前の値。

    a再配置前の値== 08 00 00 00==8リトルエンディアン

    b再配置前の値== 80 56 34 12==0x12345680リトルエンディアン

  • A: addend は、再配置エントリのフィールドです0( では示されていませんobjdump)。

移転が発生した場合:

  • a次のものに置き換えられます。

    address of text section + 8
    

    テキスト セクションの 8 番目のバイトである+ 8becauseがあり、その前に 2 つの long があります。s:

  • b次のものに置き換えられます。

     address of text section + (0x12345678 + 8)
     ==
     address of text section + 0x12345680
    

    ああ、それで0x12345680オブジェクトファイルに現れたのです!

先ほど見たよう+に、実際のオフセットに追加するだけで ELF ファイルを表現できます。

しかし&、このメカニズム (または私が知っている他のメカニズム) で表現することはできません。なぜなら、再配置後のテキスト セクションのアドレスがどうなるかがわからないため、適用できない&からです。

于 2015-10-22T08:54:53.427 に答える
1

ダーン:

中置演算子

中置演算子は、両側に 1 つずつ、合計 2 つの引数を取ります。演算子には優先順位がありますが、同じ優先順位の操作は左から右に実行されます。orとは別に、両方の引数は absolute+-でなければならず、結果は絶対です。

于 2013-08-28T19:52:33.677 に答える