链接器双重重定向 (IAR EWARM)
Linker Double Redirect (IAR EWARM)
我有一个 IAR STM32 项目,我需要用一些自定义逻辑包装一个库函数。我没有能力重新编译库本身,所以我想做的是创建一个调用原始 libfunction
的函数 libfunction_shim
。使用 --redirect
链接器选项 (--redirect libfunction=libfunction_shim
),我可以将对原始函数的调用重定向到 shim,包括库本身内部的调用。但是,我需要从 shim 调用原始函数。
如果我添加另一个重定向 (--redirect libfunction_original=libfunction
),它最终会将 libfunction_original
重定向到 libfunction_shim
,而不是原来的 libfunction
。我试过重新排序重定向,但无论顺序如何,它都会做同样的事情。
链接器日志证明了这一点:
Symbol Redirected to Reason
------------- ------ ------
...
libfunction libfunction_shim command line
libfunction_original libfunction_shim command line
我想要的是:
Symbol Redirected to Reason
------------- ------ ------
...
libfunction libfunction_shim command line
libfunction_original libfunction command line
是否可以使用链接器执行此操作?
使用链接器重定向是不可能的,您必须以特定方式编写 shim 函数。手册中提供了完整的描述(8.40.1 版本中的第 225 页),但总结一下:首先将 shim 命名为 $sub$$libfunction
,其中 libfunction
是要隐藏的函数的名称。在 shim 内部,您可以使用 $super$$libfunction
来调用 libfunction
的原始版本。下面显示了一个最小的示例。
extern void $Super$$foo(void);
void $Sub$$foo(void)
{
$Super$$foo(); /* calls the original foo() function */
}
我有一个 IAR STM32 项目,我需要用一些自定义逻辑包装一个库函数。我没有能力重新编译库本身,所以我想做的是创建一个调用原始 libfunction
的函数 libfunction_shim
。使用 --redirect
链接器选项 (--redirect libfunction=libfunction_shim
),我可以将对原始函数的调用重定向到 shim,包括库本身内部的调用。但是,我需要从 shim 调用原始函数。
如果我添加另一个重定向 (--redirect libfunction_original=libfunction
),它最终会将 libfunction_original
重定向到 libfunction_shim
,而不是原来的 libfunction
。我试过重新排序重定向,但无论顺序如何,它都会做同样的事情。
链接器日志证明了这一点:
Symbol Redirected to Reason
------------- ------ ------
...
libfunction libfunction_shim command line
libfunction_original libfunction_shim command line
我想要的是:
Symbol Redirected to Reason
------------- ------ ------
...
libfunction libfunction_shim command line
libfunction_original libfunction command line
是否可以使用链接器执行此操作?
使用链接器重定向是不可能的,您必须以特定方式编写 shim 函数。手册中提供了完整的描述(8.40.1 版本中的第 225 页),但总结一下:首先将 shim 命名为 $sub$$libfunction
,其中 libfunction
是要隐藏的函数的名称。在 shim 内部,您可以使用 $super$$libfunction
来调用 libfunction
的原始版本。下面显示了一个最小的示例。
extern void $Super$$foo(void);
void $Sub$$foo(void)
{
$Super$$foo(); /* calls the original foo() function */
}