简体   繁体   English

使用函数B覆盖弱函数A.

[英]override a weak function A with a function B

For an embedded device, I have file containing an array with function pointers storing interrupt handlers, define like that (I can't modify it): 对于嵌入式设备,我的文件包含一个带有存储中断处理程序的函数指针的数组,这样定义(我不能修改它):

typedef void (*const ISRFunction)(void);

__attribute__((weak)) void ISR0(void){ for(;;); }
__attribute__((weak)) void ISR1(void){ for(;;); }
...
__attribute__((weak)) void ISR78(void){ for(;;); }
...

ISRFunction __vector_table[0x79] = 
{
    (ISRFunction)&ISR0,
    (ISRFunction)&ISR1,
    ...
    (ISRFunction)&ISR78,
    ...
}

I have a second file which defines some functions, which I can't modify. 我有第二个文件,它定义了一些我无法修改的函数。 This file is like: 这个文件是这样的:

void blinkLed(void)
{ ... }

Finally, I have a main source file, with main function and configuration of device. 最后,我有一个主要的源文件, main功能和设备配置。 On interrupt 78, I would like to blink led. 在中断78,我想闪烁领导。 So I write a strong function ISR78 like that: 所以我写了一个强大的功能ISR78

void ISR78(void)
{
    blinkLed();
}

I wondered if there was a solution to override weak function ISR78 directly by blinkLed , ie storing address of blinkLed inside __vector_table without modifying it or rename function? 我想知道是否有一个解决方案直接通过blinkLed覆盖弱函数ISR78__vector_table存储blinkLed地址而不修改它或重命名函数?


EDIT: 编辑:

I actually use GNU gcc 4.9.3 and associated linker (GNU ld 2.24.0). 我实际上使用GNU gcc 4.9.3和相关的链接器(GNU ld 2.24.0)。 I can modify main.c and Makefile associated to project. 我可以修改与项目关联的main.c和Makefile。

The only way I see to achieve what you want to do is to patch the symbol table of the object file containing the blink symbol with the ISR78 symbol. 我看到实现您想要做的唯一方法是使用ISR78符号修补包含blink符号的目标文件的符号表。

objcopy [...] --redefine-sym blink=ISR78 objcopy [...] --redefine-sym blink = ISR78

should do that. 应该这样做。 The linker should then automatically insert the address of the former blink into the vector table. 然后,链接器应自动将前一个blink的地址插入到向量表中。 Obviously, your blink symbol is gone after that and shouldn't be called from other places. 显然,你的blink符号在此之后消失了,不应该从其他地方调用。

I would, however, consider this a hack. 但是,我会认为这是一个黑客。

In case _vector_table is globally accessible and in writable memory (not assumed, that's probably too simple...), you could simply patch it from your own code by 如果_vector_table是全局可访问的并且在可写内存中(未假设,这可能太简单......),您可以简单地从您自己的代码中修补它

_vector_table [0x78] = blink;

at runtime. 在运行时。

tl;dr: you have a working solution already, which appears to be the solution explicitly supported and encouraged by using weak symbols in the first place. tl; dr:你已经有了一个工作解决方案,这似乎是首先使用弱符号明确支持和鼓励的解决方案。 What improvement do you expect from a different solution? 您对其他解决方案有何期望?


Linker symbols are looked up by name, so the only alternatives to using the expected name are: 链接器符号按名称查找,因此使用预期名称的唯一选择是:

  1. tofro's suggestion to modify the link step directly tofro建议直接修改链接步骤
  2. modify the function pointer table yourself 自己修改函数指针表

The whole point of making ISR78 a weak symbol in the first place is to allow exactly the override (by symbol name) you've already used. 首先,使ISR78成为弱符号的重点是允许您已经使用的覆盖(通过符号名称)。

I can't see any way modifying the interrupt vector table is better than just using the expected function name directly, even if it's possible. 我看不出有什么方法修改中断向量表比直接使用预期的函数名更好 ,即使它是可能的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM