有影響,設置或定義一個函數的(相對)地址的方法?也許在鏈接器腳本中有任何可能性來確保函數abc()始終駐留在OFFSET + 0x0034C0處(僅舉例)。 我想以某種方式「控制」的記憶裏面函數的位置,使這些地方的某種參數化的。 目前我正在使用gcc在我的x86上尋找一種方法。但是,真正的應用程序應該在嵌入式設備上運行。如何影響功能的地址?
問候
有影響,設置或定義一個函數的(相對)地址的方法?也許在鏈接器腳本中有任何可能性來確保函數abc()始終駐留在OFFSET + 0x0034C0處(僅舉例)。 我想以某種方式「控制」的記憶裏面函數的位置,使這些地方的某種參數化的。 目前我正在使用gcc在我的x86上尋找一種方法。但是,真正的應用程序應該在嵌入式設備上運行。如何影響功能的地址?
問候
你或許可以做到這一點使用linker script magic與海灣合作委員會,是的。看看如何定義section placement,然後把指令在源放功能在您所選擇的部分(一個或多個)。
不能肯定是否會在x86機器的工作,雖然,因爲操作系統可能有...異議。這更直接用於嵌入式應用。
在完整的操作系統上控制代碼位置的點是什麼?
其實我想創建一些Software-Hardware-Binding-Scheme。某些功能的位置應在軟件開發過程中定義。在執行軟件時,它從用於指導軟件控制流的硬件讀取認證信息。 只有從硬件讀取正確的憑證時,連續的函數調用纔會指向正確的內存地址。否則,他們指向內存中的錯誤位置,軟件停止執行/軟件崩潰。 – user1192748
@ user1192748,我只是通過存儲特定硬件地址(如中斷向量)內容的校驗和來看到類似的結果。 –
@ user1192748 CRC校驗的優點是您可以簡單地檢查該值並在不匹配時不運行。調用未定義的行爲只是一種災難性的方法(即,如果「停止」,您無法控制軟件「停止」的時間/地點/方式) –
一個典型的廣義實施,這將是一個矢量表(我也聽說過這個叫補丁表)。
首先,在你的C文件,寫功能:
void my_first_function(int){ /* do something */ }
void my_second_function(int){ /* do something */ }
然後,在你的C文件創建定義表格的佈局結構:
struct MyVectorTable
{
void (*first_function)(int);
int (*second_function)(float, char);
// all the rest
};
接下來,在你的C文件創建一個靜態表:
static struct MyVectorTable my_vector_table = {
my_first_function,
my_second_function,
};
最後露出地址作爲一個void *
void* get_table_base_address(void) { return &my_vector_table; }
現在你應該能夠得到所有的函數作爲基地址的偏移量。
如果所有的函數具有相同的調用簽名,你可以通過具有函數指針,而不是結構的數組簡化這個。但是,數組和結構都會保存指針,所以指針數學基本相同。
這也允許您使用鏈接器在特定地址找到您的補丁表。
要做到這一點,IMO的最佳方法是將函數放入用戶定義的部分中,如展開已在上面提及。你可以找到一個簡單的例子,在低於4K字節邊界放置一個功能myFunc
:
通過修改鏈接腳本來創建在你的記憶一個新的部分:
/* .my_section will be the name of the section in the final executable */
.my_section : ALIGN (8)
{
. = ALIGN (0x1000);
KEEP(*(.mysection)) /* The section will be called ".mysection" in the
compiled translation unit (.obj) */
. = ALIGN (8);
} >rom
現在,使用gcc的attribute
功能放置功能爲我們剛剛創建的部分:
void myFunc(void) __attribute__ ((section(".mysection"))); // The section name to use
// here is ".mysection",
// not ".my_section"
// Looks like you need to use __attribute__ along with function declaration, rather
// than with the function definition, though I'm not sure why
void myFunc(void)
{
// ...
}
如果你這樣做objdump
現在,你會被持有myFunc
代碼地址0名.my_section
看到部分,而不是在0x12e8
Disassembly of section .my_section:
000012e8 <myFunc-0xd18>:
...
00002000 <myFunc>:
2000: b508 push {r3, lr}
...
該代碼可以使用Codesourcey gcc
套件ARM皮質。我不太確定x86 ...
IMO,如果應用程序在嵌入式設備上運行,我假設某種類型的自定義操作系統,不要試圖使它在x86上工作,然後找出它不能在設備上完成。 (好奇,爲什麼?) – Max
你看過存儲數據結構中函數的指針嗎? – Nocturno
這聽起來非常像一個XY問題,你試圖解決問題X,所以你認爲解決方案涉及Y,所以你問如何去做Y.你能解釋一下你實際上想要做什麼嗎?我認爲使用函數指針或類似的東西是一個很有可能的候選者,但是如果沒有真正理解「我需要我的函數在特殊地址上」的真實想法,很難知道建議的解決方案。 –