2016-08-12 14 views
1

私は手動でシンボルを上書きする必要がある組み込みシステム(xtensaプロセッサ)の状況にありますが、シンボルは別のシンボルの真ん中にあることがあります。私が-Wl,--wrap=symbolを使用しようとすると、シンボルはそれ自身のものではないので動作しません。GCCコードの手動再配置を指定するにはどうすればよいですか?

私がする必要があるのは、コードが終了する場所(GCC .Sでは、.cは大丈夫ですが)です。実際のシンボルはコンパイラによってどこかにランダムに配置されますが、私はmemcpyのコードを正しい場所に挿入します。

40101388 <replacement_user_vect>: 40101388: 13d100 wsr.excsave1 a0 4010138b: 002020 esync 4010138e: 011fc5 call0 4010258c <_UserExceptionVector_1>

私の問題は、GCCは、それがフラッシュである最終的な位置は、割り込みベクタに固定される一方のコードは、配置されると仮定すると、相対ジャンプとのアセンブリを作成しています。どのようにGCC/GNUに「あなたが好きな場所にコードを入れても、実際にはここから実行すると信じて」

私のコードは0x40101388(GCCが決める)になりますが、 0x40100050から。私はそれを伝えることでGCCをだますにはどうすればよい「HEREコードを入れて、」しかし、それは「HERE」位置しているふり

EDIT:私は開催されました、それは結局のところ、この周りを私が修正するために必要な機能を得ることができましたリンカースクリプトでは、個別に私はリンカスクリプトでそれを切り替えることができました。私はまだ答えを知りたいのですが、今は回避策があります。

+1

gccまたはガスでコードを再配置しないでください。彼らはリンカーではありません。 **相対**ジャンプは定義によって位置に依存しません。あなたの問題が何であるか(そして、「別のシンボルの真ん中」は何を意味するのか)明確ではありません。 [ask]を参照し、十分な情報を提供してください。 – Olaf

+0

'' 'as'''で特定のシンボルを定義することができます。これはコードのどこかに現れます。リンカーはそれを再配置することはできませんが、私は理由は分かりません。私のテストでは、関数のように完全に独立したシンボルを再配置するように見えるかもしれませんが、関数の途中で何かが見えたら再配置しません。理由は分かりません。 –

+4

あなたの最初の段落は意味をなさないが、私がそれを無視すれば、自分のセクションのどこかにコピーしたいコードを置いてから、リンカースクリプトを使ってどこにコピーするかをリンカーに伝えることで、 。 Linuxカーネルがhttp://lxr.free-electrons.com/source/arch/xtensa/kernel/vmlinux.lds.Sの 'SECTION_VECTOR'マクロを正確に見ているようです。 –

答えて

3

リンカスクリプトでは、各出力セクションに2つの関連するアドレスVMAとLMA(コードがリンクされているアドレスとコードがロードされるアドレス)があります。

別のセクションに再配置する必要のあるコードを配置し、出力セクションを希望のVMAとLMAでリンカースクリプトに追加し、コードセクションの名前と一致する入力セクションを配置します。

など。

SECTIONS { 
    ... 
    .some_section : { ... } 
    .relocatable1 VMA : AT(LOADADDR(.some_section) + SIZEOF(.some_section)) { 
    _relocatable1_vma_start = . ; 
    *(.relocatable1.literal .relocatable1.text) ; 
    _relocatable1_vma_end = . ; 
    } 
    _relocatable1_lma = LOADADDR(.relocatable1) ; 
    ... 
} 

所望の目標コードの位置で置換VMAでのldスクリプトの以下の部分、と次のCコード一緒

void f(void) __attribute__((section(".relocatable1.text"))) 
{ 
    ... 
} 

extern char _relocatable1_lma[]; 
extern char _relocatable1_vma_start[]; 
extern char _relocatable1_vma_end[]; 

void relocatable1_copy(void) 
{ 
     memcpy(_relocatable1_vma_start, _relocatable1_lma, 
       _relocatable1_vma_end - _relocatable1_vma_start); 
} 

は、あなたが欲しいものを行う必要があります。

関連する問題