2016-05-17 24 views
5

我想知道gcc鏈接器選項(例如:-Wl,選項)是否可以在編譯的可執行文件中更改彙編程序指令,因爲如果您使用某些gcc優化選項會發生這種情況? 比較編譯後的二進制文件(例如比較簽名)時,是否可以看到使用鏈接器選項而不使用鏈接器選項?gcc鏈接器選項可以在編譯的二進制文件中更改彙編程序指令嗎?

UPDATE

更準確地說我想弄清楚,如果FLIRT簽名更改,當我在編譯過程中使用某些鏈接選項。這些簽名僅使用庫函數來創建簽名。

+1

參見例如'--wrap'。 – Phillip

+0

@Phillip你能更準確地解釋一下嗎? – Maximilian

+0

手冊頁上有關於該選項的詳細信息;它可以用來覆蓋符號,至少對於C目標文件而言,它也可以改變函數的簽名。 – Phillip

回答

4

對於一些連接選項,變化可在生產二進制可以看到,例如:

  • 選項擺脫/保留調試符號(--strip-all--strip-debug--discard-all
  • 選項擺脫/保留未使用的部分,例如一個包含在其他部分中從不被引用的函數的部分。這些部分可以輕鬆刪除。或保留重定位部分/內容。 (--as-needed--emit-relocs
  • 選項以包括一個靜態庫或其他兼容的一個(例如庫版本X.0 VS版本X.1)
  • 的順序中的對象和靜態庫被放置在命令行。例如ld -o foo a.obj b.obj c.objld -o foo a.obj c.obj b.obj可能產生一個不同的二進制文件,如果從c到a函數的調用被解析(來自c.obj的代碼的偏移量並且因此c中的函數的地址將會是可能是不同的)

但即使在鏈接之後,二進制文件的簽名也可能發生變化。例如,在Linux中,當您通過運行優化二進制啓動時間prelink

+0

實際上,我只對功能級別的二進制文件的更改感興趣。如果特定的調試符號被修改,這不會改變函數的彙編代碼。你能想象一個使用鏈接器選項改變彙編代碼的場景嗎? – Maximilian

+3

是的,對其他對象的調用可能會根據它們的順序或靜態庫的順序或庫的不同版本來解析爲不同的偏移量/地址。 – Elijan9

+0

但是靜態庫中的函數將保持不變,對吧? – Maximilian

1

是的,您將看到不同鏈接器選項鍊接的兩個二進制文件上的不同校驗和 - 除非該選項無效,例如當您指定默認選項或不改變二進制文件的選項(-print-map)。

你想弄清楚什麼?這聽起來像是在指定某些鏈接器選項時遇到問題,並且您正在嘗試弄清楚原因。告訴我們更多,也許我們可以給予更好的幫助。

+0

請參閱上面的更新 – Maximilian

相關問題