【问题标题】:preventing "ld -wrap " circular references防止“ld -wrap”循环引用
【发布时间】:2011-03-18 14:53:59
【问题描述】:

我正在使用 GNU ld 的“-wrap”选项来拦截应用程序中的调用,但遇到了实现包装器的代码间接调用被包装函数的场景,从而创建了循环引用。

示例

目标是包装在 Program Foo 中发生的读取调用。此代码可以重新编译/重新链接,但不能修改。

程序Foo

main() {
    ...
    read(fd, buf, size);
    ...
}

这里的包装器会在使用“-wrap read”时拦截对程序Foo中libc读取的调用。

包装器

extern int __real_read(...);
int __wrap_read(...) {
    bar();
    __real_read(...);
}

但是,从 wrapper 调用的 Library Bar 需要使用 libc 的 read() 函数而不经过 wrapper(从而导致循环依赖)。

图书馆栏

void bar(void) {
    read(fd, buf, size)
}

将库栏中的所有包装例程更改为使用 __real_read() 不是一种选择,因为在库栏中对外部库的附加调用中存在的间接级别是任意的。

避免标记

解决此问题的一种方法是使用每线程标志来防止来自库栏的包装读取重新进入库。虽然我不想使用这个解决方案,但我也愿意接受有关如何在包装器和 bar 库中以最少的代码更改来实现它的建议。

理想的解决方案

???这就是我问这个问题的原因:)

谢谢... -n

【问题讨论】:

  • 您能否指示链接器仅将 -wrap 应用于某些目标文件?也许链接器脚本可以让你到达那里。
  • 这不太可能。考虑 bar() 调用另一个对象文件(等等)中的函数的情况,该对象文件又调用 read()。这些间接级别会迅速变大,并且跟踪它很容易出错。

标签: c compiler-construction linker wrapper trace


【解决方案1】:

正如 Nathon 所说,应该可以只为特定的目标文件包装 fhe read() 调用。不确定 linux,但在 windows 中,将导入的函数包装在 DLL 中不会影响其他模块中的导入函数,因此将 Bar 放在单独的 DLL 中并使用 unwrapped read() 可以解决问题。

【讨论】:

  • 您的解决方案等效于手动将所有 read() 调用重命名为 __real_read() 在组成不应包装的目标文件的文件中。正如我所指出的,这还不够,因为调用 read() 是通过未知的间接级别发生的。我当然不是说你的想法行不通,但我不确定它是否涵盖所有基础。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-12
  • 1970-01-01
  • 1970-01-01
  • 2018-03-15
  • 1970-01-01
  • 2013-08-25
相关资源
最近更新 更多