[U-Boot] GCC 5.2 issue on imx28

Hello folks,
OE-Core is preparing for upgrade to GCC 5.2 as default compiler and mx28 is failing[1] to build with it.
1. http://errors.yoctoproject.org/Errors/Details/13878/
I am not a linker guy so could someone shed any light on this?

Dear Otavio,
In message CAP9ODKqqA6v6Ug4+Cx4fBdCRLchaOxL3SCZN5+iwbbFoKyq-mA@mail.gmail.com you wrote:
OE-Core is preparing for upgrade to GCC 5.2 as default compiler and mx28 is failing[1] to build with it.
I am not a linker guy so could someone shed any light on this?
Does the same problem happen with the pristine mainline U-Boot tree?
The error message looks pretty cleaar to me:
../arch/arm/cpu/arm926ejs/start.S:108: undefined reference to `lowlevel_init'
In your case (mx28evk_config) this would normally come from arch/arm/cpu/arm926ejs/mxs/mxs.c:
inline void lowlevel_init(void) {}
Did you check the compiler release notes for differences in the handling of such inline funtions?
Best regards,
Wolfgang Denk

Otavio Salvador otavio.salvador@ossystems.com.br writes:
Hello folks,
OE-Core is preparing for upgrade to GCC 5.2 as default compiler and mx28 is failing[1] to build with it.
I am not a linker guy so could someone shed any light on this?
There are two errors reports:
1. An undefined reference to the symbol "lowlevel_init" 2. A complaint about the ".rel.plt" section not being handled by the linker script.
The second error is probably caused by the first. A quick grep turns up this snippet in arch/arm/cpu/arm926ejs/mxs/mxs.c:
/* Lowlevel init isn't used on i.MX28, so just have a dummy here */ inline void lowlevel_init(void) {}
The semantics for non-static functions declared inline have changed in gcc5, causing the above (empty) function not to be emitted as an external symbol.
Since that function is only referenced from start.S, it should not be declared inline at all. This patch should thus fix your problem:
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxs.c b/arch/arm/cpu/arm926ejs/mxs/mxs.c index ef130ae..b1d8721 100644 --- a/arch/arm/cpu/arm926ejs/mxs/mxs.c +++ b/arch/arm/cpu/arm926ejs/mxs/mxs.c @@ -24,7 +24,7 @@ DECLARE_GLOBAL_DATA_PTR;
/* Lowlevel init isn't used on i.MX28, so just have a dummy here */ -inline void lowlevel_init(void) {} +void lowlevel_init(void) {}
void reset_cpu(ulong ignored) __attribute__((noreturn));

On Tue, Jul 28, 2015 at 10:39 AM, Måns Rullgård mans@mansr.com wrote: ...
Since that function is only referenced from start.S, it should not be declared inline at all. This patch should thus fix your problem:
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxs.c b/arch/arm/cpu/arm926ejs/mxs/mxs.c index ef130ae..b1d8721 100644 --- a/arch/arm/cpu/arm926ejs/mxs/mxs.c +++ b/arch/arm/cpu/arm926ejs/mxs/mxs.c @@ -24,7 +24,7 @@ DECLARE_GLOBAL_DATA_PTR;
/* Lowlevel init isn't used on i.MX28, so just have a dummy here */ -inline void lowlevel_init(void) {} +void lowlevel_init(void) {}
void reset_cpu(ulong ignored) __attribute__((noreturn));
Works like a charm.
Tested-by: Otavio Salvador otavio@ossystems.com.br

Dear Måns Rullgård, Otavio Salvador,
On Di, 2015-07-28 at 14:39 +0100, Måns Rullgård wrote:
Otavio Salvador otavio.salvador@ossystems.com.br writes:
[snip]
There are two errors reports:
- An undefined reference to the symbol "lowlevel_init"
- A complaint about the ".rel.plt" section not being handled by the linker script.
The second error is probably caused by the first. A quick grep turns up this snippet in arch/arm/cpu/arm926ejs/mxs/mxs.c:
/* Lowlevel init isn't used on i.MX28, so just have a dummy here */ inline void lowlevel_init(void) {}
The semantics for non-static functions declared inline have changed in gcc5, causing the above (empty) function not to be emitted as an external symbol.
Since that function is only referenced from start.S, it should not be declared inline at all. This patch should thus fix your problem:
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxs.c b/arch/arm/cpu/arm926ejs/mxs/mxs.c index ef130ae..b1d8721 100644 --- a/arch/arm/cpu/arm926ejs/mxs/mxs.c +++ b/arch/arm/cpu/arm926ejs/mxs/mxs.c @@ -24,7 +24,7 @@ DECLARE_GLOBAL_DATA_PTR;
/* Lowlevel init isn't used on i.MX28, so just have a dummy here */ -inline void lowlevel_init(void) {} +void lowlevel_init(void) {}
void reset_cpu(ulong ignored) __attribute__((noreturn));
I stumbled over the same problem. Unfortunatly, I did not find this patch before (only the error report from Otavia) and submitted a similar patch [1] which keeps the inline keyword.
Best regards Jörg Krause
[1] "arm: mxs: make inline function compatible for GCC 5" https://patchwork.ozlabs.org/patch/504043/

Jörg Krause joerg.krause@embedded.rocks writes:
Dear Måns Rullgård, Otavio Salvador,
On Di, 2015-07-28 at 14:39 +0100, Måns Rullgård wrote:
Otavio Salvador otavio.salvador@ossystems.com.br writes:
[snip]
There are two errors reports:
- An undefined reference to the symbol "lowlevel_init"
- A complaint about the ".rel.plt" section not being handled by the linker script.
The second error is probably caused by the first. A quick grep turns up this snippet in arch/arm/cpu/arm926ejs/mxs/mxs.c:
/* Lowlevel init isn't used on i.MX28, so just have a dummy here */ inline void lowlevel_init(void) {}
The semantics for non-static functions declared inline have changed in gcc5, causing the above (empty) function not to be emitted as an external symbol.
Since that function is only referenced from start.S, it should not be declared inline at all. This patch should thus fix your problem:
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxs.c b/arch/arm/cpu/arm926ejs/mxs/mxs.c index ef130ae..b1d8721 100644 --- a/arch/arm/cpu/arm926ejs/mxs/mxs.c +++ b/arch/arm/cpu/arm926ejs/mxs/mxs.c @@ -24,7 +24,7 @@ DECLARE_GLOBAL_DATA_PTR;
/* Lowlevel init isn't used on i.MX28, so just have a dummy here */ -inline void lowlevel_init(void) {} +void lowlevel_init(void) {}
void reset_cpu(ulong ignored) __attribute__((noreturn));
I stumbled over the same problem. Unfortunatly, I did not find this patch before (only the error report from Otavia) and submitted a similar patch [1] which keeps the inline keyword.
Best regards Jörg Krause
[1] "arm: mxs: make inline function compatible for GCC 5" https://patchwork.ozlabs.org/patch/504043/
Since the function is only referenced from outside the C file, any use of inline makes little sense to me. While your patch achieves the result of creating a linkable instance of the function, it is more complicated than it needs to be.

On Mi, 2015-08-05 at 20:23 +0100, Måns Rullgård wrote:
Jörg Krause joerg.krause@embedded.rocks writes:
Dear Måns Rullgård, Otavio Salvador,
On Di, 2015-07-28 at 14:39 +0100, Måns Rullgård wrote:
Otavio Salvador otavio.salvador@ossystems.com.br writes:
[snip]
There are two errors reports:
- An undefined reference to the symbol "lowlevel_init"
- A complaint about the ".rel.plt" section not being handled by
the linker script.
The second error is probably caused by the first. A quick grep turns up this snippet in arch/arm/cpu/arm926ejs/mxs/mxs.c:
/* Lowlevel init isn't used on i.MX28, so just have a dummy here */ inline void lowlevel_init(void) {}
The semantics for non-static functions declared inline have changed in gcc5, causing the above (empty) function not to be emitted as an external symbol.
Since that function is only referenced from start.S, it should not be declared inline at all. This patch should thus fix your problem:
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxs.c b/arch/arm/cpu/arm926ejs/mxs/mxs.c index ef130ae..b1d8721 100644 --- a/arch/arm/cpu/arm926ejs/mxs/mxs.c +++ b/arch/arm/cpu/arm926ejs/mxs/mxs.c @@ -24,7 +24,7 @@ DECLARE_GLOBAL_DATA_PTR;
/* Lowlevel init isn't used on i.MX28, so just have a dummy here */ -inline void lowlevel_init(void) {} +void lowlevel_init(void) {}
void reset_cpu(ulong ignored) __attribute__((noreturn));
I stumbled over the same problem. Unfortunatly, I did not find this patch before (only the error report from Otavia) and submitted a similar patch [1] which keeps the inline keyword.
Best regards Jörg Krause
[1] "arm: mxs: make inline function compatible for GCC 5" https://patchwork.ozlabs.org/patch/504043/
Since the function is only referenced from outside the C file, any use of inline makes little sense to me. While your patch achieves the result of creating a linkable instance of the function, it is more complicated than it needs to be.
In my opinion it quite make sense to use inline for functions referenced only from other files. The keyword is just an hint to the compiler and why should it not make sense for other C files? However, in this case it makes really no difference if lowlevel_init is marked as inline, gcc will generate an "BL lowlevel_init" instruction in both cases.
Jörg

Jörg Krause joerg.krause@embedded.rocks writes:
On Mi, 2015-08-05 at 20:23 +0100, Måns Rullgård wrote:
Jörg Krause joerg.krause@embedded.rocks writes:
Dear Måns Rullgård, Otavio Salvador,
On Di, 2015-07-28 at 14:39 +0100, Måns Rullgård wrote:
Otavio Salvador otavio.salvador@ossystems.com.br writes:
[snip]
There are two errors reports:
- An undefined reference to the symbol "lowlevel_init"
- A complaint about the ".rel.plt" section not being handled by
the linker script.
The second error is probably caused by the first. A quick grep turns up this snippet in arch/arm/cpu/arm926ejs/mxs/mxs.c:
/* Lowlevel init isn't used on i.MX28, so just have a dummy here */ inline void lowlevel_init(void) {}
The semantics for non-static functions declared inline have changed in gcc5, causing the above (empty) function not to be emitted as an external symbol.
Since that function is only referenced from start.S, it should not be declared inline at all. This patch should thus fix your problem:
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxs.c b/arch/arm/cpu/arm926ejs/mxs/mxs.c index ef130ae..b1d8721 100644 --- a/arch/arm/cpu/arm926ejs/mxs/mxs.c +++ b/arch/arm/cpu/arm926ejs/mxs/mxs.c @@ -24,7 +24,7 @@ DECLARE_GLOBAL_DATA_PTR;
/* Lowlevel init isn't used on i.MX28, so just have a dummy here */ -inline void lowlevel_init(void) {} +void lowlevel_init(void) {}
void reset_cpu(ulong ignored) __attribute__((noreturn));
I stumbled over the same problem. Unfortunatly, I did not find this patch before (only the error report from Otavia) and submitted a similar patch [1] which keeps the inline keyword.
Best regards Jörg Krause
[1] "arm: mxs: make inline function compatible for GCC 5" https://patchwork.ozlabs.org/patch/504043/
Since the function is only referenced from outside the C file, any use of inline makes little sense to me. While your patch achieves the result of creating a linkable instance of the function, it is more complicated than it needs to be.
In my opinion it quite make sense to use inline for functions referenced only from other files. The keyword is just an hint to the compiler and why should it not make sense for other C files?
If using link-time optimisation, it could make sense, yes. If not, there is no way a function can be inlined across translation units.
However, in this case it makes really no difference if lowlevel_init is marked as inline, gcc will generate an "BL lowlevel_init" instruction in both cases.
Correct. Here the only caller is in an assembly file, which is not subject to link-time optimisations.

On Tue, Jul 28, 2015 at 02:39:49PM +0100, Måns Rullgård wrote:
Otavio Salvador otavio.salvador@ossystems.com.br writes:
Hello folks,
OE-Core is preparing for upgrade to GCC 5.2 as default compiler and mx28 is failing[1] to build with it.
I am not a linker guy so could someone shed any light on this?
There are two errors reports:
- An undefined reference to the symbol "lowlevel_init"
- A complaint about the ".rel.plt" section not being handled by the linker script.
The second error is probably caused by the first. A quick grep turns up this snippet in arch/arm/cpu/arm926ejs/mxs/mxs.c:
/* Lowlevel init isn't used on i.MX28, so just have a dummy here */ inline void lowlevel_init(void) {}
The semantics for non-static functions declared inline have changed in gcc5, causing the above (empty) function not to be emitted as an external symbol.
Since that function is only referenced from start.S, it should not be declared inline at all. This patch should thus fix your problem: Tested-by: Otavio Salvador otavio@ossystems.com.br
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxs.c b/arch/arm/cpu/arm926ejs/mxs/mxs.c index ef130ae..b1d8721 100644
After a bit re-wording of the commit message, applied to u-boot/master, thanks!
participants (5)
-
Jörg Krause
-
Måns Rullgård
-
Otavio Salvador
-
Tom Rini
-
Wolfgang Denk