ksco 的工作日志
245 subscribers
168 photos
10 videos
4 files
84 links
内容主要取决于我正在做的东西,目前主要是模拟器 / DBT 之类的散乱话题。
Download Telegram
今天看到了一个帖子说他在 HUAWEI 体验店试图向朋友演示 Matebook E Go 的糟糕触控和输入体验时,无意间发现体验店的机器屏幕触控竟然如丝般顺滑,和自己的机器判若两机。

于是拷贝了体验店机器上触控服务的二进制文件回家替换掉了原有的试了一下,发现华为确实修复了触控问题并偷偷使用,并未向终端用户开放。

我也有一台 Matebook E Go,于是我也试了一下,现在的屏幕打字体验的确已经非常舒适,达到了 iPad 水准。这段文字也是我第一次在这台机器上用屏幕键盘打这么多字。

来源:https://bbs.saraba1st.com/2b/thread-2100755-1-1.html
😁14
💘2
第一个在 RISC-V 上运行的 32 位 Linux 程序
👍8
收到神秘快递(不是
😢2
Box64 正在做一个新的功能叫 Box32,用于执行 32 位的 Linux 程序。

对于一个没有 softmmu 的模拟器,这个想法能正常实现的前提就是:程序内所有的指针必须位于 32 位空间,包括 box64 自己。

所以我们使用 -Ttext-segment,0x34800000 来将 box64 自己加载到一个低位的地址空间。不过 -Ttext-segment 在 lld 和 mold 中并不存在,好在可以使用等价的 --image-base 来代替。

今天晚上发现使用 mold 编译出来的 box64 二进制 --image-base 完全没生效,导致 Box32 炸了。研究了一下,发现 mold,lld 和 GNU ld 在这上面的表现各不相同:

1. mold

-Wl,--image-base 必须显式和 -no-pie 一起使用,否则不生效。如果不加 -no-pie 不会有任何报错/警告,只是不生效!

2. lld

-Wl,--image-base 和是否 pie 无关。

3. GNU ld

使用 -Wl,-Ttext-segment 会强制隐含 -no-pie
👍4🤔2
又爆新装备了
👍3
今天需要用 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_tagDT_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 突然决定遵守规范了,有知道的吗?
👍3🤔1
> 问题是,我实在不知道为什么在且仅在 RISC-V 上 glibc 突然决定遵守规范了,有知道的吗?

后续:

双倍多多冰发现在 glibc 中只有 RISC-V 和 MIPS 的 DL_RO_DYN_SECTION 宏定义为真,表示 dynamic section 是只读的。

ld.soelf_get_dynamic_info() 函数中,如果 dynamic section 可写,则会把上文提到的 d_ptr patch 为绝对地址,所以 RISC-V 和 MIPS 就没有被 patch。

我看你们谁还不承认 RISC-V 是 MIPS 的正统续作
👍2
牛肉一斤蔬菜自助,90 元。
🤩3👍1🤯1
中秋节的时候出门散步,在公园捡了一只小狗,取名叫年年。
10😁1
😐1
ksco 的工作日志
尴尬
又… 没了?
🤔2
Forwarded from 刘阳
Box64 adds preliminary XTheadVector support
👌5
新建频道,发点每天吃的东西。

t.me/eatwelleveryday
知矿买矿难道是我的错吗?