GNU ld --wrap limitations

Chris Johns chrisj at rtems.org
Wed Jan 16 01:10:26 UTC 2019


On 15/1/19 5:54 pm, Sebastian Huber wrote:
> On 14/01/2019 23:33, Chris Johns wrote:
>> On 14/1/19 8:22 pm, Sebastian Huber wrote:
>>> while testing the event recording with the libbsd I noticed a GNU ld --wrap
>>> limitation:
>>>
>>> https://www.sourceware.org/ml/binutils/2018-12/msg00210.html
>>>
>> I have been watching the thread. There is a limit to what binutils or any method
>> can do as compiler technology improves.
>>
>> An example we currently build RTEMS with a single C file on the command line, I
>> wonder what RTEMS's score would look like if all C files are passed to the
>> compiler at once and it can optimise over all files as if included in a single
>> source file. A number of externals we current have would not be visible and
>> traceable using this method.
> 
> If I use -flto in my simple test case, then the wrapping via LD doesn't work at
> all.

LTO is a compiler based optimiser run at link time. It is like the example I
gave of compiling all the source with a single gcc command.

> 
>>
>>> It turned out that the wrapping doesn't work for references internal to a
>>> translation unit.
>> The reach for this issue is changing as the push to better optimise the
>> generated code. If the compiler can remove or optimise an external call as an
>> internally reference it will.
> 
> This is not a compiler optimization issue.

I view this as an optimisation to speed up the linking process by not letting it
know there is a reference. :)

> The wrapping doesn't work with -O0
> for all references internal to the translation unit. 

I doubt it would have. This about the generated code. Inlining of code can also
happen where a function instance is present for external linkage and the same
code is internally inlined. You see this with breakpoints that are not hit
because the external instance of the function is the breakpoint.

> You see "call h" and "call puts". The h() function is defined in the translation
> unit. This call is not wrapped.

I have seen this happen but never looked deeper into the exact reason.

> 
>>
>>> My hope was that the RTEMS Trace Linker doesn't have this
>>> limitation, but the documentation says (user manual):
>>>
>>> "The trace linker’s major role is to wrap functions in the existing executable
>>> with trace code. The
>>> directions on how to wrap application functions is provided by the generator
>>> configuration. The
>>> wrapping function uses a GNU linker option called –wrap=symbol."
>>>
>> https://devel.rtems.org/wiki/Developer/Tracing/Trace_Linker#Limitation
>>
>> ... highlights the need for an external reference.
> 
> It says
> 
> "Functions must have external linkage to allow the linker to wrap the symbol."
> 
> this is not the same as
> 
> "highlights the need for an external reference"
> 
> You need an undefined reference to a symbol. References inside a translation
> unit are apparently not undefined references.

Does DWARF give us any better insight and the information needed?

> It took me a while to figure out why the wrapping of ether_input() and
> ether_output() didn't work. 

That is frustrating.

> I tried to improve the LD documentation a bit as a result.

I saw this.

Chris



More information about the devel mailing list