Open danwalmsley opened 7 years ago
Well, @attribute("weak") @attribute("alias", "defaultExceptionHandler") extern(C) void NMI_Handler();
doesn't even compile with LDC, these are GDC-specific attributes...
I've seen that you have your own minimal gcc.attribute (derived from GDC I assume). This won't work (the compiler needs to know about them, and LDC only detects those in ldc.attributes
). Take a look at the LDC attributes: https://github.com/ldc-developers/druntime/blob/ldc/src/ldc/attributes.d
We have @weak
(not sure whether the semantics are identical to GDC though) and @section("...")
too, but there's no alias and no @naked
.
We have @naked
now; @alias
may be emulatable via pragma(mangle)
.
@alias
may be emulatable viapragma(mangle)
.
No, weak alias can not be emulated via pragma(mangle)
.
This works fine:
extern(C) void DefaultHandler() {...}
@weak extern(C) {
void ResetHandler() { DefaultHandler(); }
void NMIHandler() { DefaultHandler(); }
...
}
but needs extra codespace for every not overridden handler.
This compiles:
extern(C) void DefaultHandler() {...}
@weak extern(C) pragma(mangle, DefaultHandler.mangleof) {
void ResetHandler();
void NMIHandler();
...
}
but weak function overriding stops work. Linker ignores all user defined handlers and always links all handlers to DefaultHandler
.
We definitely need something like __attribute__ ((weak, alias ("target")))
.
See https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes
but needs extra codespace for every not overridden handler
Even with --gc-sections
? It shouldn't when moving each default handler into its own object file, but I get that that's not ideal.
So how would the preferred syntax be? Something like
extern(C):
void DefaultHandler() {}
@weakAlias(DefaultHandler.mangleof)
{
void ResetHandler();
void NMIHandler();
}
but needs extra codespace for every not overridden handler
Even with
--gc-sections
? It shouldn't when moving each default handler into its own object file, but I get that that's not ideal.
How would that help? Interrupt handlers are used to fill the interrupt vector. Therefore, the linker cannot remove default handlers.
So how would the preferred syntax be? Something like
extern(C): void DefaultHandler() {} @weakAlias(DefaultHandler.mangleof) { void ResetHandler(); void NMIHandler(); }
Looks good.
How would that help? Interrupt handlers are used to fill the interrupt vector. Therefore, the linker cannot remove default handlers.
You were worried about code size for the extra tiny default wrappers, e.g., void ResetHandler() @weak { DefaultHandler(); }
. If it's in its own object file and the user overrides it at link time with a custom implementation, it shouldn't be linked in, and you'll save the couple of bytes. My understanding at least, but I've never dealt with interrupt handlers, and only needed @weak
once so far, in the DMD frontend itself.
Edit: Ah sorry, you were worried about the code size of the non-overridden wrappers. Just out of curiosity, how many bytes are we talking about here? ;)
Edit: Ah sorry, you were worried about the code size of the non-overridden wrappers. Just out of curiosity, how many bytes are we talking about here? ;)
Several bytes for every non-overridden handler. In most cases, it is 100-200 bytes in total. :) I should confess, I am more concerned about the fact of such non-optimality, than about the size of the firmware. :)
I am trying to build startup file for bare metal (STM32)
based on this thread: http://forum.dlang.org/post/uiwtphzmxuqgopbbysht@forum.dlang.org
I have this...
@attribute("weak") @attribute("alias", "defaultExceptionHandler") extern(C) void NMI_Handler();
and then later
and it is used like this...
however when linking I get
main.o:(.data..constarray+0x8): undefined reference to
NMI_Handler'`any ideas why this hasn't worked?