Last updated 2 years, 9 months ago
Last updated 2 years, 9 months ago
官方网站 https://www.hwdb.la
客服频道 @kefu
供求频道 @gongqiu
公群频道 @hwgq (好旺公群首字母)
新群 @xinqun
核心大群 @daqun
记账机器人 @hwjz
公司介绍 @hwdbgs
担保流程 @dbliucheng
Last updated 2 weeks, 4 days ago
沉思:
电池健康度的第一个百分点的含金量是否可以类比为油箱里的第一格。
世界上最痛苦的事是 debug CI,世界上第二痛苦的事是 bisect。
https://github.com/flightlessmango/MangoHud/pull/1418
MangoHud MIPS 也修好了!
GitHub
elfhacks: d_un.d_ptr is relative on mips glibc too by Icenowy · Pull Request #1418 · flightlessmango/MangoHud
In GLIBC, this behavior is controlled by per-architecture definition DL\_RO\_DYN\_SECTION, which is only set to 1 on MIPS (according to the comments, it's because of requirements of MIPS ABI) ...
问题是,我实在不知道为什么在且仅在 RISC-V 上 glibc 突然决定遵守规范了,有知道的吗?
后续:
双倍多多冰发现在 glibc 中只有 RISC-V 和 MIPS 的 DL_RO_DYN_SECTION
宏定义为真,表示 dynamic section 是只读的。
在 ld.so 的 elf_get_dynamic_info()
函数中,如果 dynamic section 可写,则会把上文提到的 d_ptr
patch 为绝对地址,所以 RISC-V 和 MIPS 就没有被 patch。
我看你们谁还不承认 RISC-V 是 MIPS 的正统续作
今天需要用 MangoHud 看一下 FPS,发现这玩意在 RISC-V 上竟然不工作!
```
debian@rockos-eswin:~$ mangohud --dlsym glxdemo
MANGOHUD: Can't get dlopen() and dlsym()
```
故事有点长,但是没有 TLDR。
MangoHud 的核心工作原理并不复杂,上面的 mangohud
命令其实只是个 shell 脚本,真正起作用的是 libMangoHud_dlsym.so
,脚本中会通过 LD_PRELOAD
机制替换掉 libc/libdl 的 dlsym()
函数,然后再在自己实现的 dlsym()
中劫持感兴趣 Vulkan/OpenGL 函数,替换成自己的实现,比如通过替换 glxSwapBuffers()
实现在原画面的左上角显示 fps 等信息。
到这就有问题了,MangoHud 要做这些事情,势必要大量用到 dlsym()
,但这个函数已经被自己给替换掉了(??)
MangoHud 解决这个问题的办法就是用 ld.so 提供的函数去内存中找到真正的那个 libc/libdl 中的 dlsym()
,所以这就免不了要做一些 ELF parsing 的工作。
总之最后肯定要去读 libc/libdl 的 PT_DYNAMIC
表,这个表中给出了各种 section 的地址/信息。
```
typedef struct {
Elf64_Sxword d_tag;
union {
Elf64_Xword d_val;
Elf64_Addr d_ptr;
} d_un;
} Elf64_Dyn;
```
比如当 d_tag
是 DT_SYMTAB
时, d_ptr
中保存的就是符号表的地址。
对于 d_ptr
,elf(5) 是这样说的:
```
This member represents program virtual addresses. When interpreting these addresses, the actual address should be computed based on the original file value and memory base address. Files do not contain relocation entries to fixup these addresses.
```
从这个表述中我们可以知道, d_ptr
保存的并不是绝对地址,而是一个相对的地址,要获取绝对地址只需要加上 elf 的基地址即可: obj\->addr + obj\->dynamic[i].d_un.d_ptr
。
只可惜啊,规范是规范,实现是实现。
在 glibc 中, d_ptr
保存的是绝对地址;在 musl 中,则保存的是相对地址。MangoHud 通过 \#ifdef __GLIBC__
解决了这个不一致的问题。
只可惜啊,实现是实现,RISC-V 是 RISC-V。
glibc 在 RISC-V 中突然遵守规范了, d_ptr
里面保存的是一个相对值!所以 MangoHud 在 x86_64、AArch64、LoongArch 上都可以工作,但是在 RISC-V 上炸掉了。
不过,我刚刚修复了这个问题:https://github.com/flightlessmango/MangoHud/pull/1417
问题是,我实在不知道为什么在且仅在 RISC-V 上 glibc 突然决定遵守规范了,有知道的吗?
Last updated 2 years, 9 months ago
Last updated 2 years, 9 months ago
官方网站 https://www.hwdb.la
客服频道 @kefu
供求频道 @gongqiu
公群频道 @hwgq (好旺公群首字母)
新群 @xinqun
核心大群 @daqun
记账机器人 @hwjz
公司介绍 @hwdbgs
担保流程 @dbliucheng
Last updated 2 weeks, 4 days ago