爲什麼 uboot 等單個 ELF 也需要 GOT 表?(爲何動態庫內部調用 local func 也要查 GOT ?)
- dukelec
- 帖子: 410
- 注册时间: 2010-08-26 22:20
- 系统: Gentoo
- 来自: Canton
爲什麼 uboot 等單個 ELF 也需要 GOT 表?(爲何動態庫內部調用 local func 也要查 GOT ?)
如果有兩個 ELF: A, B. A 調用了 B 的 func 與 data, 則 A 需要配備 GOT 來記錄所調用 B 的 func 與 data 的地址。
但如果只有 A 自己,不需要 GOT 也可以實現位置無關啊,就算 A 體積比較大,某些地方超出相對 PC 尋址,但其偏移量始終是固定的數,多用條指令也是可以實現跳轉的啊。
求解。
-------------------------
modify title only
但如果只有 A 自己,不需要 GOT 也可以實現位置無關啊,就算 A 體積比較大,某些地方超出相對 PC 尋址,但其偏移量始終是固定的數,多用條指令也是可以實現跳轉的啊。
求解。
-------------------------
modify title only
上次由 dukelec 在 2013-10-22 11:41,总共编辑 5 次。
- adam8157
- 帖子: 2794
- 注册时间: 2009-03-05 16:31
- 联系:
Re: 爲什麼 uboot 等單個 ELF 也需要 GOT 表?
好问题, 不过为啥放到水区啊?
答案是因为uboot是个bootloader, 它需要加载kernel header的一些数据, 例如需要加载的内核大小是多少(x86的实模式内核), 它也需要告诉内核一些信息, 例如kernel command line的地址. 这些就是另外一个elf的data咯.
PS, 是我认为的答案
答案是因为uboot是个bootloader, 它需要加载kernel header的一些数据, 例如需要加载的内核大小是多少(x86的实模式内核), 它也需要告诉内核一些信息, 例如kernel command line的地址. 这些就是另外一个elf的data咯.
PS, 是我认为的答案
- dukelec
- 帖子: 410
- 注册时间: 2010-08-26 22:20
- 系统: Gentoo
- 来自: Canton
Re: 爲什麼 uboot 等單個 ELF 也需要 GOT 表?
通過解析 vmlinux elf header 便可知其加載大小,入口地址等信息;command line 是 uboot 一開始準備好在內存,然後用寄存器傳遞地址給內核。
這些都與 uboot 自身編譯過程無任何關聯,且查看 uboot GOT 全都是 uboot 自身的部分 func 與 data, 與 kernel 無關。
昨天看了 gcc 有 -fpic 與 -fpie 兩種不同的方式(非連接器 -pie, 誤混淆),主程式應該選用 -fpie 參數來實現位置無關,
這樣 local func 與 local data 就會編譯爲直接 PC 偏移尋址,而不用查 GOT(外部 func 與 data 仍然會用 GOT 來查找)。
應該是 -fpie 比較新,以前無,所以才借用動態庫用的 -fpic 參數來編譯主程式。
但仍然不清楚爲何動態庫 local func 與 local data 亦需要 GOT 查表。
我試過將 uboot 編譯選項改爲 -fpie, 結果編譯出來仍然有 GOT 表,且大小翻倍,不知爲何。
這些都與 uboot 自身編譯過程無任何關聯,且查看 uboot GOT 全都是 uboot 自身的部分 func 與 data, 與 kernel 無關。
昨天看了 gcc 有 -fpic 與 -fpie 兩種不同的方式(非連接器 -pie, 誤混淆),主程式應該選用 -fpie 參數來實現位置無關,
這樣 local func 與 local data 就會編譯爲直接 PC 偏移尋址,而不用查 GOT(外部 func 與 data 仍然會用 GOT 來查找)。
應該是 -fpie 比較新,以前無,所以才借用動態庫用的 -fpic 參數來編譯主程式。
但仍然不清楚爲何動態庫 local func 與 local data 亦需要 GOT 查表。
我試過將 uboot 編譯選項改爲 -fpie, 結果編譯出來仍然有 GOT 表,且大小翻倍,不知爲何。
- adam8157
- 帖子: 2794
- 注册时间: 2009-03-05 16:31
- 联系:
Re: 爲什麼 uboot 等單個 ELF 也需要 GOT 表?(爲何動態庫內部調用 local func 也要查 GO
vmlinux elf header里头没有实内核的大小吧, x86比较麻烦需要实模式和保护模式转换.
不过里头都是自身的func和data我不大明白, 难道它自身分成几块儿加载了..........
不过里头都是自身的func和data我不大明白, 难道它自身分成几块儿加载了..........
- adam8157
- 帖子: 2794
- 注册时间: 2009-03-05 16:31
- 联系:
Re: 爲什麼 uboot 等單個 ELF 也需要 GOT 表?(爲何動態庫內部調用 local func 也要查 GO
動態庫內部調用 local func的话如果是extern的它也要做准备被引用吧我猜, 而且动态库要准备被多个进程调用(share), 全局变量啥的要各自维护吧
- dukelec
- 帖子: 410
- 注册时间: 2010-08-26 22:20
- 系统: Gentoo
- 来自: Canton
Re: 爲什麼 uboot 等單個 ELF 也需要 GOT 表?(爲何動態庫內部調用 local func 也要查 GO
不用考慮 x86, 我的 uboot 是 for mipsel 架構。
如果分成多塊就應該有多個 .text 段、.got 段,但實際無。
[SOLVED] Re: statically linked PIEs without GOT [http://comments.gmane.org/gmane.comp.gcc.help/42112]
裏面說:如果一個 c 文件引用一個 extern 變量(來自另一個 c 文件),需要加上 hidden 修飾來避免生成 GOT 查表:
但我寫了測試工程,用 -fpie(or -fPIE) 編出來的 .o 文件,如果用 -static 參數鏈接,不加 hidden 修飾也不會有 GOT 表,
鏈接出來的 ELF 文件 checksum 與不加 -fpie 一樣。
不知道如何才能編譯出 static linked 且 position independent 且無 GOT 的裸跑代碼。
如果分成多塊就應該有多個 .text 段、.got 段,但實際無。
的確有人提到:...內部調用 local func的话如果是extern的它也要做准备被引用吧...
[SOLVED] Re: statically linked PIEs without GOT [http://comments.gmane.org/gmane.comp.gcc.help/42112]
裏面說:如果一個 c 文件引用一個 extern 變量(來自另一個 c 文件),需要加上 hidden 修飾來避免生成 GOT 查表:
代码: 全选
extern __attribute__((visibility("hidden"))) int var;
鏈接出來的 ELF 文件 checksum 與不加 -fpie 一樣。
不知道如何才能編譯出 static linked 且 position independent 且無 GOT 的裸跑代碼。
- adam8157
- 帖子: 2794
- 注册时间: 2009-03-05 16:31
- 联系:
- adam8157
- 帖子: 2794
- 注册时间: 2009-03-05 16:31
- 联系:
Re: 爲什麼 uboot 等單個 ELF 也需要 GOT 表?(爲何動態庫內部調用 local func 也要查 GO
17:15 < adam8157> GOT, 顺便问个问题, uboot的GOT table里为啥都是它自己的func和data, 单个elf为啥要这样?
17:15 < adam8157> GOT不是为了放全局func和data的么, 为啥单个elf的got里都是自己的东西? viewtopic.php?f=15&t=450538
17:16 < amker> 猜测可能是有些代码/数据需要在不同的virtual address运行
17:16 < amker> 比如mmusetup前后, 地址会发生变化
17:17 < adam8157> amker: 哦 有可能 相当于不同的memory map了 所以需要GOT
17:18 < amker> 应该是这个原因
17:15 < adam8157> GOT不是为了放全局func和data的么, 为啥单个elf的got里都是自己的东西? viewtopic.php?f=15&t=450538
17:16 < amker> 猜测可能是有些代码/数据需要在不同的virtual address运行
17:16 < amker> 比如mmusetup前后, 地址会发生变化
17:17 < adam8157> amker: 哦 有可能 相当于不同的memory map了 所以需要GOT
17:18 < amker> 应该是这个原因
-
- 帖子: 4
- 注册时间: 2013-01-13 10:56
- 系统: ubuntu
Re: 爲什麼 uboot 等單個 ELF 也需要 GOT 表?(爲何動態庫內部調用 local func 也要查 GO
u-boot GOT 的用法是为了解决内存大小不同所产生的问题。
如果你不用 GOT 表,那么 U-Boot 的链接地址为了便利多数情况下应该是 RAM 空间的地址,这个地址固定的情况下难免跟保存内核镜像的空间、解压缩内核所需要的空间、以及内核运行所需要空间冲突。
使用 GOT 表之后,链接地址为 ROM 地址,U-Boot 会根据 RAM 的大小自动计算其新的代码、数据等段的地址,然后进行修正,通常放在接近于内存空间的最后(或者你指定空间的最后),这样保留足够大的空间以避免冲突;同时,在 ROM 中的代码也不需要非常小心的计算偏移。
如果你不用 GOT 表,那么 U-Boot 的链接地址为了便利多数情况下应该是 RAM 空间的地址,这个地址固定的情况下难免跟保存内核镜像的空间、解压缩内核所需要的空间、以及内核运行所需要空间冲突。
使用 GOT 表之后,链接地址为 ROM 地址,U-Boot 会根据 RAM 的大小自动计算其新的代码、数据等段的地址,然后进行修正,通常放在接近于内存空间的最后(或者你指定空间的最后),这样保留足够大的空间以避免冲突;同时,在 ROM 中的代码也不需要非常小心的计算偏移。
-
- 帖子: 4
- 注册时间: 2013-01-13 10:56
- 系统: ubuntu
Re: 爲什麼 uboot 等單個 ELF 也需要 GOT 表?(爲何動態庫內部調用 local func 也要查 GO
u-boot GOT 的用法是为了解决内存大小不同所产生的问题。
如果你不用 GOT 表,那么 U-Boot 的链接地址为了便利多数情况下应该是 RAM 空间的地址,这个地址固定的情况下难免跟保存内核镜像的空间、解压缩内核所需要的空间、以及内核运行所需要空间冲突。
使用 GOT 表之后,链接地址为 ROM 地址,U-Boot 会根据 RAM 的大小自动计算其新的代码、数据等段的地址,然后进行修正,通常放在接近于内存空间的最后(或者你指定空间的最后),这样保留足够大的空间以避免冲突;同时,在 ROM 中的代码也不需要非常小心的计算偏移。
如果你不用 GOT 表,那么 U-Boot 的链接地址为了便利多数情况下应该是 RAM 空间的地址,这个地址固定的情况下难免跟保存内核镜像的空间、解压缩内核所需要的空间、以及内核运行所需要空间冲突。
使用 GOT 表之后,链接地址为 ROM 地址,U-Boot 会根据 RAM 的大小自动计算其新的代码、数据等段的地址,然后进行修正,通常放在接近于内存空间的最后(或者你指定空间的最后),这样保留足够大的空间以避免冲突;同时,在 ROM 中的代码也不需要非常小心的计算偏移。
- adam8157
- 帖子: 2794
- 注册时间: 2009-03-05 16:31
- 联系:
Re: 爲什麼 uboot 等單個 ELF 也需要 GOT 表?(爲何動態庫內部調用 local func 也要查 GO
赞, make senseabutter 写了:u-boot GOT 的用法是为了解决内存大小不同所产生的问题。
如果你不用 GOT 表,那么 U-Boot 的链接地址为了便利多数情况下应该是 RAM 空间的地址,这个地址固定的情况下难免跟保存内核镜像的空间、解压缩内核所需要的空间、以及内核运行所需要空间冲突。
使用 GOT 表之后,链接地址为 ROM 地址,U-Boot 会根据 RAM 的大小自动计算其新的代码、数据等段的地址,然后进行修正,通常放在接近于内存空间的最后(或者你指定空间的最后),这样保留足够大的空间以避免冲突;同时,在 ROM 中的代码也不需要非常小心的计算偏移。