referensing global labels fails

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

referensing global labels fails

2,352 Views
Veter
Contributor I
I am trying to reference global label located in the startup.s source from *.cpp file.
The error message states that label is "Undefined".
 
Assembly code:
.section .init$00,2,C
.global ___init
___init
 
; Linker places .init sections from other modules, containing
; calls to initialize global objects, here.
.section .init$99,2,C
rts   ; Return from ___init.
C++ code:
extern void ___init(void);
 
static int init_main_guts(void)
{
...
 /* initialize constructors    */
 ___init();
...
}
 
What am I doing wrong?
I am using CodeWarrior Development Studio for ColdFire Architectures Version 6.3, Build 14.
My target is MCF5307.
 
Thank you!
Labels (1)
0 Kudos
6 Replies

355 Views
SimonMarsden_de
Contributor II
The CodeWarrior C compiler adds an underscore to the start of every function name, but in assembler you need to add it yourself.

Thus a function in the C source code called foo() needs to be referred to as "_foo" in the assembler source.

It looks like you've got one too many '_' characters in the ___init() call in main.c


Cheers


Simon
0 Kudos

358 Views
Veter
Contributor I
That is correct. There is one extra "_" character. Olso "__init()" does not need parenthesis. The working code has "__init;".
 
Thank you.
0 Kudos

358 Views
CompilerGuru
NXP Employee
NXP Employee


Veter wrote:
Olso "__init()" does not need parenthesis. The working code has "__init;".
Thank you.





__init;

is an statement without any side effect in C. Legal, but useless.
So if you do want __init to be called, add the parenthesis again.
Daniel
0 Kudos

358 Views
Veter
Contributor I
Daniel,
 
If I add parenthesis I get following error:
Link Error   : Undefined : "__init()"
I do not have such error without them.
Any ideas? 
 
0 Kudos

358 Views
CompilerGuru
NXP Employee
NXP Employee
I just noted one little word in the initial post:
C++ code:


Does this mean init_main_gut is contained in a C++ file?
Well, that would explain it. In order to use C (or assembly for that matter) stuff from C++, it has to be explicitly given the C linkage.
#ifdef __cplusplus
extern "C" {
#endif
extern void __init(void);
#ifdef __cplusplus
}
#endif

static int init_main_guts(void)
{
...
 /* initialize constructors    */
 __init();
...
}



Also something to check: can you disassemble both the assembly and the C++ (or C) file,
and compare how the two __init names look like. They have to be identical.
To disassemble, use the context menu in the project window. There is also a preference panel to configure the disassembler.

Daniel
0 Kudos

358 Views
Veter
Contributor I
That was it.
Including 'extern "C" {}' directive solved the problem.
Dissasemblies for both sources look the same now.
 
Thank you!
0 Kudos