簡體   English   中英

使用 gcc 編譯時 -ffreestanding 和 -nostdlib 之間的區別

[英]Difference between -ffreestanding and -nostdlib when compiling with gcc

我正在使用帶有 x84-elf64-gcc 編譯器的 64 位 linux 機器。 我剛剛開始低級編程,想了解 C 代碼實際上是如何翻譯成二進制的。 這主要用於操作系統開發,因為我知道處理器不理解 ELF 或任何其他格式,只能理解二進制。

例如下面的c文件:

//test.c
int func()
{
    return 0x12345678;
}

當我用 gcc 編譯時:

gcc test.c

我收到以下錯誤:

(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status

所以我猜鏈接器有問題。 我願意:

gcc test.c -c 

我得到了一個 ELF 對象文件,然后我做了一個 objdump 並得到了預期的結果:

0000000000000000 <func>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   b8 78 56 34 12          mov    $0x12345678,%eax
   9:   5d                      pop    %rbp
   a:   c3                      retq   

但是當我使用-m32選項和 objdump “交叉編譯”一個 32 位版本時,我得到:

hello.o:     file format elf32-i386


Disassembly of section .text:

00000000 <func>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   e8 fc ff ff ff          call   4 <func+0x4>
   8:   05 01 00 00 00          add    $0x1,%eax
   d:   b8 78 56 34 12          mov    $0x12345678,%eax
  12:   5d                      pop    %ebp
  13:   c3                      ret    

Disassembly of section .text.__x86.get_pc_thunk.ax:

00000000 <__x86.get_pc_thunk.ax>:
   0:   8b 04 24                mov    (%esp),%eax
   3:   c3                      ret    

我在之前的回答中讀到這與位置無關代碼有關: 未定義引用 gcc 32 位代碼中的“_GLOBAL_OFFSET_TABLE_”,用於一個微不足道的函數,獨立操作系統

為什么在使用 -m32 選項編譯時會有這樣的變化? 此外,我被建議在編譯時使用-ffreestanding選項,但它在這里似乎沒有效果。 我讀過-ffreestanding告訴編譯器沒有標准庫,那么 -nostdlib 是什么?

注意:我對這種硬核c 編程比較陌生,我認為這里的主要問題是我並不真正了解鏈接器/編譯器的工作原理。 :(

我不知道-ffreestanding到底做了什么,那部分是個好問題。

但不幸的是,您的問題對 32 位 PIE 代碼有很大的影響:

為什么在使用 -m32 選項編譯時會有這樣的變化?

因為您遺漏了任何-O優化選項,並且 32 位模式沒有數據的 EIP 相對尋址模式(只有相對跳轉/調用)。 因此,顯然調試模式總是將寄存器設置為 GOT 指針作為尋址靜態數據的基礎,即使在不使用它的函數中也是如此。

除非您特別想讓PIE 可執行,否則始終使用-fno-pie關閉該默認值。

您可能還需要-mcmodel=kernel - 如果您正在編譯 64 位高半內核,這是一個好主意(靜態地址可以用於 32 位符號擴展立即數,但不能用於 32 位零擴展)。 但是 IDK 如果它對 32 位代碼有任何作用的話。

這些選項控制流程的兩個部分:

  • -freestanding向編譯器表明它應該是一個獨立的,AFAIK 唯一的效果是禁用一些內置函數,如memcpy

  • -nostdlib表示默認情況下不應鏈接任何庫和啟動文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM