This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Archive (library) which overrides syscalls from toolchain's archive?
- From: Freddie Chopin <freddie_chopin at op dot pl>
- To: binutils at sourceware dot org
- Date: Fri, 25 Sep 2015 15:32:47 +0200
- Subject: Re: Archive (library) which overrides syscalls from toolchain's archive?
- Authentication-results: sourceware.org; auth=none
- References: <2848199 dot YC2cC3yUf3 at infernus> <56052580 dot 9010803 at redhat dot com>
Hello Nick!
First of all thank you for your helpful message which got me further with the
problem!
On Friday 25 of September 2015 11:44:16 Nick Clifton wrote:
> This sounds like a linker command line ordering problem. [Aside: It
> would really help if you posted your linker command line ...]
Yes, that's a good idea, the linking command is:
arm-none-eabi-g++ -L./output/ -T./output/STM32F407VGT.ld -mcpu=cortex-m4 -
mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -g -Wl,-
Map=./output/distortos.map,--cref,--gc-sections <a lot of object files> -
ldistortos -o ./output/distortos.elf
> What is probably happening is that your archive is being placed on the
> linker command line *before* the object file that calls _sbrk_r. So at
> the time that your archive is scanned, there are no undefined references
> to _sbrk_r. So it is discarded. Later on on the command line something
> else does call _sbrk_r, so an unresolved reference is created. Then
> later on still libg.a appears on the command line, this is scanned and
> it provides a definition of _sbrk_r. Hence the version in libg.a is
> pulled in. Unfortunately this version wants to call _sbrk, but no
> further libraries left on the command line provide that function, so the
> linker generates the error message above.
>
> > Is there any (possibly simple and generic) way to solve it?
>
> Probably. Reordering your linker command line ought to work.
The problem is that _sbrk_r() (let's stick to this function as the best
example) from libg.a is pulled by malloc() from libg.a... That's why I don't
think any reordering will help here. Reordering would probably be the simplest
option here (but really fragile as a solution).
> > or forcing _sbrk_r() to be initially undefined with
> > EXTERN(_sbrk_r) in the linker script, but this didn't change much.
>
> Did you try using --undefined=_sbrk_r on the linker command line ?
I've tried that now, and - surprisingly - it worked. Yesterday I had also some
--start-group ... --end-groups in the linker command (basically wrapping all
the objects and libdistortos.a). But today it worked - to completely fix the
link I had to mark _sbrk_r() and _kill_r() as undefined. It also works with
the EXTERN() in the linker script (; The only problem here is that I should
mark all the syscalls (there are 18 of them) as undefined, so that all
possible scenarios would actually work. This forces the right objects to be
linked, but they are linked even if not needed, which is problematic for
targets with small memories. Currently that's not an issue, as most of the
syscalls are just stubs, with the only exception being _sbrk_r(), but in
future syscalls like _open_r() or _read_r() would pull all the I/O code into a
project that might not need them, which would be a real issue...
> > Basically I'm looking for a way to just force some functions to be taken
> > from designated archive.
>
> Have you tried using the --wrap linker command line option ? You could
> wrap calls to _sbrk_r and then provide the wrapped version in your own
> archive.
I didn't know that option (; I didn't try it yet, but it seems that it would
solve the problem that I described above (the functions wouldn't be forced
into the executable if they are not used). The problem I see here is that this
cannot be done with a linker script (or maybe it can be done?), so the link
command would get pretty long and complicated... I'll try that soon and find
out.
> PS. There is also the --whole-archive linker command line option, which
> could be used to force all of your archive to be included in the link,
> but it is probably overkill.
Hmm - I've just tried it and it seems to be the easiest option. It seems to
solve my issue, it doesn't force any functions into the executable if they are
not needed and the commands are pretty short... Why do you think it is
overkill? Does it have some downsides that I'm not aware of? I added "... -
Wl,--whole-archive -ldistortos -Wl,--no-whole-archive ..." to my linker
command and it seems to work fine.
Thanks again!
Regards,
FCh
P.S. Previously I used the wrong e-mail address for my post, now I'm using the
right one.