2011-11-03 95 views
3

我想知道是否有辦法在運行時在內存中獲取c函數的大小。有什麼辦法可以獲得c函數的大小嗎?

我用這個代碼,但它不工作:

#include <stdio.h> 
#include <stdlib.h> 
#include <stddef.h> 

int main(void) 
{ 
    int t[10]; 
    char c; 
    offsetof(t, p); 
    p: 
    return 0; 
} 
+1

'offsetof'是結構。你爲什麼需要這個? – cnicutar

+0

爲什麼我的代碼無法正常工作 – obo

回答

7

答案一般不是。你不能。其中一個原因是因爲函數在內存中不一定是連續的。所以他們沒有「尺寸」。有時,編譯器(即ICC)將跳出功能的二進制的偏遠地區和跳回

請參閱相關的問題在這裏:

how to find function boundaries in binary code

1

您可以檢查拆卸。反彙編程序適用於大多數環境,通常編譯器本身可以從源爲您生成它們。

3

你是混亂的數據與代碼,變量t在內存地址方面與函數main無關。 t存儲在堆棧中,main位於代碼部分。

至於獲取函數的大小,沒有標準的方法來獲取大小。如果你願意編寫反彙編和靜態代碼分析,你可能會對大小有一個粗略的瞭解,但即使這樣也不是微不足道的,因爲最終的指令可能不是該函數的最後一條指令,比如你從內部返回循環。

您可以分析編譯器/鏈接器輸出數據(PDB,映射文件等)。

但是,那麼,爲什麼你需要知道?

+1

有時您可能想要重新定位某個功能,即將其複製到內存中的其他位置。在其他時候,您可能需要爲包含在函數中的代碼更改頁面保護。或者加密/解密一個函數。你需要知道這些尺寸。所有這些都不是典型的代碼操作。 –

+0

@Alex:如果您需要執行任何這些(實際上)「動態鏈接器」,那麼您需要動態鏈接器使用的額外的特定於實現的信息,並且提問者沒有提及有。 –

+0

@Alex:要重新定位某個功能,需要找到所有調用該功能並更新呼叫地址的地方。我想不出任何可以做到這一點的操作系統。即使是GameBoy墨盒也沒有這樣做(所有東西都被分頁並使用頁面底部的相對偏移量,所以它們從不改變)。加密 - 通常是對整個可執行文件執行的操作(如自解壓縮)。 – Skizz

0

我已經看到了它,但我真的不能想象爲什麼你會需要它。要記住的是如果你減去兩個指針,它會產生一個ptrdiff_t,如果加到第一個指針上會產生第二個指針。這適用於函數指針!那麼怎麼樣:

#include <stdio.h> 

int main (void) { 
    printf("main is %u bytes long\n", (unsigned) (metamain - main)); 
    return 0; 
} 

void metamain (void) { 
} 
+2

您假設metamain和main在內存中是連續的。 – Skizz

相關問題