- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
有没有办法覆盖具有静态范围的函数在对象模块中?
如果我从这样的东西开始,一个模块具有全局符号“foo”的函数调用调用本地符号“baz”的本地符号“bar”
[scameron@localhost ~]$ cat foo.c
#include <stdio.h>
static void baz(void)
{
printf("baz\n");
}
static void bar(void)
{
printf("bar\n");
baz();
}
void foo(void)
{
printf("foo\n");
bar();
}
[scameron@localhost ~]$ gcc -g -c foo.c
[scameron@localhost ~]$ objdump -x foo.o | egrep 'foo|bar|baz'
foo.o: file format elf32-i386
foo.o
00000000 l df *ABS* 00000000 foo.c
00000000 l F .text 00000014 baz
00000014 l F .text 00000019 bar
0000002d g F .text 00000019 foo
它有一个全局变量“foo”和两个本地变量“bar”和“baz”。
假设我想写一些练习 bar 和 baz 的单元测试,我能做到:
[scameron@localhost ~]$ cat barbaz
bar
baz
[scameron@localhost ~]$ objcopy --globalize-symbols=barbaz foo.o foo2.o
[scameron@localhost ~]$ objdump -x foo2.o | egrep 'foo|bar|baz'
foo2.o: file format elf32-i386
foo2.o
00000000 l df *ABS* 00000000 foo.c
00000000 g F .text 00000014 baz
00000014 g F .text 00000019 bar
0000002d g F .text 00000019 foo
[scameron@localhost ~]$
现在 bar 和 baz 是全局符号,可以从模块外。到目前为止一切顺利。
但是如果我想在上面插入我自己的函数怎么办的“baz”,并让“bar”调用我插入的“baz”?
有办法吗?
--wrap 选项似乎没有这样做...
[scameron@localhost ~]$ cat ibaz.c
#include <stdio.h>
extern void foo();
extern void bar();
void __wrap_baz()
{
printf("wrapped baz\n");
}
int main(int argc, char *argv[])
{
foo();
baz();
}
[scameron@localhost ~]$ gcc -o ibaz ibaz.c foo2.o -Xlinker --wrap -Xlinker baz
[scameron@localhost ~]$ ./ibaz
foo
bar
baz
wrapped baz
[scameron@localhost ~]$
从 main() 调用的 baz 被包装了,但是bar 仍然调用本地 baz 而不是包装的 baz。
有没有办法让bar调用wrapped baz?
即使它需要修改目标代码以修改函数调用的地址,如果可以以自动化方式完成,那可能就足够了,但在那种情况下它至少需要在 i386 和 x86_64 上工作.
--史蒂夫
最佳答案
由于 static
是对 C 编译器的 promise ,即函数或变量是文件的本地变量,如果没有它也能获得相同的结果,编译器可以自由删除该代码。
这可能是内联函数调用。这可能意味着用常量替换变量。如果代码位于始终为假的 if
语句中,则该函数甚至可能不存在于编译结果中。
所有这些都意味着您无法可靠地将调用重定向到该函数。
如果使用新的 -lto
选项进行编译,情况会更糟,因为编译器可以自由地重新排序、删除或内联整个项目中的所有代码。
关于c - 是否可以覆盖目标模块(gcc、ld、x86、objcopy)中的静态函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9806282/
我正在尝试创建尽可能小的 ELF。我创建了一个这样的测试文件(NASM 语法): SECTION .text dd 0xdeadbeef 使用此链接描述文件: SECTIONS { .text
GNU LD 链接器命令语言是否有条件语句? 背景:我正在为 arm cortex m0+ 开发固件,该固件由引导加载程序和应用程序组成。两者都在单独的项目中进行编译和刷新,但我使用了一个框架,其中包
我很确定 ld 有一个手册页链接器脚本语法,但我找不到它。 最佳答案 如果您更喜欢比 info 更方便的东西, 这是一个可浏览的 HTML 版本:ld.info: Scripts .但它可能不是完全最
谁能解决这个练习,这样我就能明白我错在哪里,因为有太多的 LOL 变量。 生成一个 C 代码,将其放在以下表达式之前 printf ("% ld% ld% ld \ n", lol, & lol, *
在他关于理解 Linux Kernel Initcall Mechanism 的文章中, Trevor 创建了一个用户空间程序来模拟调用 linux 驱动程序的 init_module() 的机制。
/usr/bin/ld: cannot find -ldlib /usr/bin/ld: cannot find -lcblas /usr/bin/ld: cannot find -llapack 在
我想以 json-ld 格式创建一组人,但我需要保留一些键而不是使用数组,所以我首先尝试了这个: { "@context" : { "@base" : "http://www.exampl
所以我试图围绕 JSON-LD 进行思考,我看到的所有示例主要包括嵌入“链接数据”。但我想提供对链接数据的引用(主要是因为嵌入所有数据可能会产生 10MB 的有效负载)。所以我想知道我这样做是否正确。
我在这里复制了 json-ld standard 中的示例的一部分: { "@context": { "foaf": "http://xmlns.com/foaf/0.1/", "
考虑这样一个程序: #include void foo() __attribute__((__weak__)); int main() { printf("%p\n", (void *)fo
我正在尝试使用一个名为 GLV 的小部件库对于我正在开发的应用程序。我正在运行 Linux Mint 17。我安装了所有库并成功构建了 GLV 库,但是当我尝试运行已构建的示例之一时,出现了此共享库错
在将未编辑的 JSON 数据转换为 JSON-LD 时,使用前缀和数据值为对象构造 IRI 时遇到问题。我运行的示例代码是: { "@context" : { "prefix" : "
假设我有一个 JSON 对象,它在嵌套对象中包含一些属性。 { "title": "My Blog Post", "meta": { "publishedAt": "2
我是 JSON-LD 和 LOD 的新手,所以请原谅我使用的术语。我正致力于在 JSON-LD 中创建数据模型,以描述基于欧洲数据模型 (http://pro.europeana.eu/edm-doc
我有一个玩具 x86 汇编程序,我正在用 as 编写和编译它和 ld : .text .global _start _start: movq $1, %rax movq
我正在尝试创建 Google 的结构化数据,但不知道我在做什么。我将其设置为一个组织,然后将 SD 标记工具用于我的所有产品。我将每个 JSON-LD 产品直接从标记工具而不是嵌套放入它自己的脚本标签
我正在尝试创建 Google 的结构化数据,但不知道我在做什么。我将其设置为一个组织,然后将 SD 标记工具用于我的所有产品。我将每个 JSON-LD 产品直接从标记工具而不是嵌套放入它自己的脚本标签
我正在尝试使用 vcpkg 和 ndk r20 为 android arm 构建 tesseract我必须编辑 CMakeLists.txt 并添加 glob.c 和 glob.h,因为它们不在 nd
长话短说: 有没有办法让我(没有 root 访问权限)使链接器(由 gcc 调用)不知道 /etc/ld.so.conf 中包含的目录的内容 在通过 ldconfig 缓存之后? 详细说明: 我正在尝
我想将/opt/vertica/lib64 添加到系统库路径中,所以我执行以下步骤: (1) 将/opt/vertica/lib64加入/etc/ld.so.conf,运行ldconfig, (2)
我是一名优秀的程序员,十分优秀!