使用 `-Wl,--wrap` 进行函数包装不适用于 ESP8266 上的 `postmortem_report()`

问题描述 投票:0回答:1

我正在开发一个 ESP8266 项目,我需要以一种确保调用我的自定义实现而不是原始实现的方式重写

postmortem_report()
函数。原始函数在 C 文件中定义为
static
,这意味着它具有内部链接并且仅在该文件中可见。

为了实现这一目标,我尝试使用链接器标志

-Wl,--wrap=postmortem_report
来包装函数并将调用重定向到
__wrap_postmortem_report
,这是我在 C++ 代码中定义的。相关代码如下:

原始函数(C 文件中):

extern "C" static void postmortem_report(uint32_t sp_dump) {
    // Original implementation
}

我的自定义包装器(在 C++ 文件中):

extern "C" void __wrap_postmortem_report(uint32_t sp_dump) {
    // Custom implementation
}

构建系统中的链接器标志:

"buildPreferences": [
    [
        "build.extra_flags",
        "-Wl,--wrap=postmortem_report"
    ]

问题:

尽管按照描述的方式设置了所有内容,但当调用

__wrap_postmortem_report()
时,我的 postmortem_report() 函数似乎
 没有被调用
。相反,原来的
postmortem_report()
仍然被执行。

我尝试过的:

  • 验证
    -Wl,--wrap=postmortem_report
    标志是否正确传递给链接器:
    "xtensa-lx106-elf-g++" ... -Wl,--wrap=postmortem_report
  • 使用
    __wrap_postmortem_report
    确保
    extern "C"
    具有外部链接。
  • 尝试了不同的编译器优化(
    -O0
    )以排除与内联或优化相关的问题。
  • 检查符号冲突,以确保项目中只有一个
    postmortem_report
    函数(
    static
    函数)。
  • 检查了链接器步骤是否有任何覆盖,但没有发现任何可能干扰函数包装的内容。

问题:

  1. ESP8266 工具链是否有某些特定内容可能导致此包装机制失败?
  2. 尽管有链接器标志,原始函数中的
    static
    关键字是否会干扰包装过程?
  3. 我应该采取任何其他步骤或注意事项来确保调用
    __wrap_postmortem_report()
    函数而不是原始函数吗?

core_esp8266_postmortem.cpp
文件中的原始代码也引用了程序集中的
postmortem_report()

asm(
    ".section     .text.__wrap_system_restart_local,\"ax\",@progbits\n\t"
    ".literal_position\n\t"
    ".align       4\n\t"
    ".global      __wrap_system_restart_local\n\t"
    ".type        __wrap_system_restart_local, @function\n\t"
    "\n"
"__wrap_system_restart_local:\n\t"
    "mov          a2,     a1\n\t"
    "j            postmortem_report\n\t"
    ".size __wrap_system_restart_local, .-__wrap_system_restart_local\n\t"
);

任何有关可能出现问题以及如何解决问题的见解或建议将不胜感激!

c arduino esp8266 arduino-esp8266 arduino-c++
1个回答
0
投票

由于原始函数被声明为

static
,因此它具有内部链接。对它的引用是在编译期间解析的(包括编译器生成的代码的汇编),而不是由链接器解析。链接器永远不会看到该符号,因此无法包装它。

© www.soinside.com 2019 - 2024. All rights reserved.