小编Seb*_*der的帖子

我可以通过编程方式更改全局偏移表/ GOT或程序链接表/ PLT吗?

某些特定于平台的功能(如SSE或AVX)的可用性可以在运行时确定,如果不想为不同的功能编译和发送不同的对象,这非常有用.

例如,下面的代码允许我检查AVX并使用gcc编译,它提供了cpuid.h标题:

 #include "stdbool.h"
 #include "cpuid.h"

 bool has_avx(void)
 {
     uint32_t eax, ebx, ecx, edx;
     __get_cpuid(1, &eax, &ebx, &ecx, &edx);
    return ecx & bit_AVX;
 }
Run Code Online (Sandbox Code Playgroud)

通过运行时检查(如上所述)重复执行检查而不是乱丢代码,而不是引入分支(可以缓存检查以减少开销,但仍会有分支),我想我可以使用动态链接器/加载器提供的基础结构.

在具有ELF的平台上调用具有外部链接的功能已经是间接的,并通过程序链接表/ PLT和全局偏移表/ GOT.

假设有两个内部函数,一个基本的_do_something_basic,总是以某种方式优化的版本_do_something_avx,它使用AVX.我可以导出一个通用do_something符号,并将其别名为基本添加:

static void _do_something_basic(…) {
    // Basic implementation
}


static void _do_something_avx(…) {
    // Optimized implementation using AVX
}

void do_something(…) __attribute__((alias("_do_something_basic")));
Run Code Online (Sandbox Code Playgroud)

在我的库或程序的加载时间内,我想检查一次使用AVX的可用性,has_avx并根据do_something符号的检查点的结果_do_something_avx.

如果我能将do_something符号的初始版本指向一个自我修改函数来检查AVX的可用性has_avx并将其替换为_do_something_basic或更好,那就更好了_do_something_avx.

理论上这应该是可能的,但是如何以编程方式找到PLT/GOT的位置?是否有一个ABI/API提供ELF加载器,例如ld-linux.so.2,我可以用它吗?我是否需要链接描述文件来获取PLT/GOT位置?如果我获得指向它的指针,我甚至可以写入PLT/GOT安全考虑因素?

也许有些项目已经完成了这个或者已经非常相似的事情

我完全清楚,解决方案将是高度特定于平台的,但由于我已经不得不处理低级平台特定的细节,例如指令集的功能,这很好.

c assembly gcc elf ld

7
推荐指数
1
解决办法
1141
查看次数

标签 统计

assembly ×1

c ×1

elf ×1

gcc ×1

ld ×1