Solving Problem with GNU Linker and “referenced in section, defined in discarded section ” Error Message

I have been running recently into an interesting case where the GNU ARM Linker failed to link an application with strange error messages:

referenced in section, defined in discarded section

referenced in section, defined in discarded section

The problem has been reported in a forum, and the error description triggered my interest as it was first around using sprintf(), and I knew that I had seen some issues in case the GNU compiler and linker is replacing some of the calls with more optimized ones.

The user of that forum post was so kind to send me that project, so I had a chance to look into it. The error message from the GNU linker ld was something like this:

`_sbrk' referenced in section `.text._sbrk_r' of arm-none-eabi/lib/armv7e-m/fpu\libg_s.a(lib_a-sbrkr.o): defined in discarded section `.text' of ./utilities/fsl_sbrk.o (symbol from plugin)
`errno' referenced in section `.text._sbrk_r' of arm-none-eabi/lib/armv7e-m/fpu\libg_s.a(lib_a-sbrkr.o): defined in discarded section `.text' of ./middleware/lwip_2.0.0/port/sys_arch.o (symbol from plugin)
collect2.exe: error: ld returned 1 exit status

Well, that error message is really weird, and seemed to happen only in some cases. But I did remember that I have seen something like this when I worked on a FreeRTOS application with the -flto (Link Time Optimization) turned on. And indeed, that application had that option turned on in the project settings:

Link Time Optimizer

Link Time Optimizer

Turning that option off proved that the problem is related to that option. So basically the error message is “I’m sorry, I have removed that symbol and marked it as discarded, but somehow the application code is still using it”. In essence, the linker has removed an object, but it was wrong as that object is still needed :-(.

It seems to me that the -flto linker optimization is more likely to fail in this area if a function or variable is marked as ‘weak’ (e.g. interrupt vectors or routines) or variables which are multiple times defined. This was the case here with _sbrk() overloaded and with the variable ‘error’ defined again in the lwip stack (well, that’s an issue of lwip).

Anyway, to work around the problem, I did the same what I did in other cases like this: adding the attribute ‘used’ to the functions or variables to prevent removal.

To prevent removing a function, add the following to the function definition:

__attribute__ ((noinline, used))
Prevent removing Function by -flto

Prevent removing Function by -flto

To prevent removing a variable by the -flto option in the linker, add the following:

__attribute__ ((used))
preventing Variable Removal

preventing Variable Removal

I hope others facing that same problem might be able to find this article :-).

Happy discarding 🙂

 

 

Advertisements

One thought on “Solving Problem with GNU Linker and “referenced in section, defined in discarded section ” Error Message

  1. I’ve needed to do this quite a bit, and i’d recommend making both of those a macro, for easing portability in future when needed. Like #define ATTRIBUTE_USED __attribute__((used))

    Like

What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s