Reputation: 79
During compiling this C code
extern void Default_Handler(void);
void NMI_Handler(void) __attribute__ ((weak, alias ("Default_Handler")));
I've recive this
error: 'NMI_Handler' aliased to undefined symbol 'Default_Handler'
How I can make alias on external defined function?
Compiler:
gcc version 7.2.1 20170904 (release) [ARM/embedded-7-branch revision 255204] (GNU Tools for Arm Embedded Processors 7-2017-q4-major)
Upvotes: 7
Views: 6324
Reputation: 165
It's popular to employee weak and alias attribute to implement override mechanism for native C project especially in cases of firmware projects.
Both of declaration and definition can be noted by __attribute__((weak))
and its linking priority rules is related to if any declaration exists in a head file.
It would be good tactic that just to code and compile it. Then see what would happen when linking is look for its definition. I usually check symbols by -Wl,-trace,-trace-symbol=ANY_FUNCTION_NAME_YOU_WANT
and nm OBJECT_FILE_NAME
.
Usually I just create a weak attribute function definition and let other objects override it. An example shown as below:
In C file:
//non-exported weak attribute definition
__attribute__((weak)) void startup_handler_dummy(void) {
printf("[%s][%s]Entry (NO OVERRIDE HANLDER COMES HERE)\n", __FILE__, __func__);
}
//weak and alias attribute declaration
void startup_handler_dummy_impl(void) __attribute__((weak, alias("startup_handler_dummy")));
//exported weak attribute definition
__attribute__((weak)) void startup_handler(void) {
startup_handler_dummy_impl();
}
In header file:
#ifndef _BOARD_H_
#define _BOARD_H_
#define STARTUP_HANDLER startup_handler //to export symbol
#endif
Hope my code can help :)
And you can see more details and program screen-shots on MyGitHub.
Upvotes: 0
Reputation: 5311
As suggested here, add the following to your linker command file:
PROVIDE(NMI_Handler = Default_Handler);
(And remove the weak alias declaration from the C code.)
Upvotes: 2
Reputation: 454
To alias an external function, you can use objcopy
. Here's an example:
Say I have the definition of a function and I alias it, like in the following program (called myimp.c
):
// myimp.c
int
myadd(int x, int y)
{
return x+y;
}
int
coolguy (int x, int y) __attribute__((alias("myadd")));
If we compile this (but don't link) we get an object file and we can check out its symbols:
# compile
$ cc -c myimp.c
# look at the symbols
$ nm myimp.o
0000000000000000 T coolguy
0000000000000000 T myadd
So we can see that the __attribute__((alias("myadd"))
is simply adding a symbol coolguy
with the same value, 0000000000000000, as myadd
. If you look in the man
page for nm, it will say that T
means it is a global symbol in the .text
section. This makes sense because the function is not static
and comprises instructions (as opposed to data).
So if we have the object file, but not the source, and we want to add a function alias we can do so using objcopy --add-symbol
.
Say we have the object file resulting from compiling this source code:
// myimp2.c
int
myadd(int x, int y)
{
return x+y;
}
Compiling as above, we'll get myimp2.o
, whose symbol table tools like this:
# look at the symbols
$ nm myimp2.o
0000000000000000 T myadd
So we want to add the coolguy
symbol, which we do as follows
# objcopy --add-symbol coolguy=.text:0000000000000000,global myimp2.o myimp2_augmented.o
Look at the documentation on --add-symbol
in the objcopy
man
page. Basically .text
specifies the section, after the colon the value, and then global
I found by passing a bad type and objcopy
failed and told me a list of the valid types, from which I chose global
.
Try running nm
on myimp2_augmented.o
, you'll see that we've added the symbol.
Now you should be able to link with myimp2_augmented.o
instead of myimp.o
and your program can call coolguy
without linking errors.
Upvotes: 8
Reputation: 212
here NMI_Handler has a weak definition attribute means that if NMI_Handler is not defined then definition of Default_Handler will be used for NMI_Handler. generally there are strong definition available for interrupts like NMI_Handler or Default_Handler.you might need to add those file in your compilation to remove error.if you wants to handle NMI_Handler in your own way then you can define it somewhere and that definition will be included instead of weak one.
Upvotes: 1