Correct usage of nosys
Richard Earnshaw (lists)
Richard.Earnshaw@arm.com
Tue Feb 18 13:31:06 GMT 2025
OK, let me use a simple example (printf is quite complex and it depends too much on the specific library you link against, but the principle is the same). I'm using my desktop machine here:
#include <math.h>
void __attribute__((noinline)) f(double)
{}
int main()
{
f(sqrt (4.0));
}
Compiled with
gcc -Wl,-Map=foo test.c -static -O0 -fno-builtin -lm
The map file contains (amongst other stuff):
Archive member included to satisfy reference by file (symbol)
/usr/lib/x86_64-linux-gnu/libm-2.35.a(w_sqrt.o)
/tmp/ccPpkxxR.o (sqrt)
/usr/lib/x86_64-linux-gnu/libm-2.35.a(e_sqrt.o)
/usr/lib/x86_64-linux-gnu/libm-2.35.a(w_sqrt.o) (__ieee754_sqrt)
...
The syntax of each entry is
<archive>(<member-file>) <referencing-file>(<symbol>)
So from this we can establish that __ieee754_sqrt(in e_sqrt.o) was linked in to satisfy a reference from sqrt in file (w_sqrt.o), which was in turn needed because of my reference to sqrt in the original source file.
Note that the call-tree in the map isn't complete. It only lists the first reason for bringing in a new object file from the library, but you can use it to work back most things.
printf() ends up calling isatty and fstat because the io code needs to set up the buffering for the output file - that depends on whether or not the stream is bound to a terminal or not.
Hope that helps,
R.
On 18/02/2025 12:41, Niklas Dusenlund wrote:
> I am calling printf and I have an implementation of `_write` (in the same file that I attempted to add `_fstat`) that works.
>
> I already produce the map file for other purposes. How do I use that to see the "call trees"?
>
>
> - Niklas
>
>
> On Tue, 18 Feb 2025 at 12:54, Richard Earnshaw (lists) <Richard.Earnshaw@arm.com <mailto:Richard.Earnshaw@arm.com>> wrote:
>
> On 18/02/2025 08:18, Niklas Dusenlund wrote:
> > Hi!
> >
> > I'm compiling for ARM cortex-m0. When I enable the nosys specs I get the following warnings:
> >
> > ```
> > /usr/local/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/lib/libc_nano.a(libc_a-fstatr.o): in function `_fstat_r':
> > fstatr.c:(.text._fstat_r+0x1c): warning: _fstat is not implemented and will always fail
> > /usr/local/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/lib/libc_nano.a(libc_a-fstatr.o): note: the message above does not take linker garbage collection into account
> > /usr/local/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/lib/libc_nano.a(libc_a-isattyr.o): in function `_isatty_r':
> > isattyr.c:(.text._isatty_r+0x18): warning: _isatty is not implemented and will always fail
> > /usr/local/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/lib/libc_nano.a(libc_a-isattyr.o): note: the message above does not take linker garbage collection into account
> > ```
> >
> > I have no intention of using fstat or isatty. But if I implement the missing functions like this:
> >
> > ```
> > int _fstat(int fildes, struct stat *st) {
> > errno = ENOSYS;
> > return -1;
> > }
> > int _isatty(int file) { return -1; }
> > ```
> >
> > I get the following errors:
> >
> > ```
> > /usr/local/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/lib/libc_nano.a(libc_a-isattyr.o): in function `_isatty_r':
> > isattyr.c:(.text._isatty_r+0x18): undefined reference to `_isatty'
> > /usr/local/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld: /usr/local/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/lib/libc_nano.a(libc_a-fstatr.o): in function `_fstat_r':
> > fstatr.c:(.text._fstat_r+0x1c): undefined reference to `_fstat'
> > ```
> >
> > If I remove the nosys specs I also get undefined references to _exit and _sbrk.
> >
> > In older versions of newlib I could use nano+nosys without warnings. What is the appropriate way with the latest newlib? If I need to link in my own stubs, how do I actually do that?
> >
> > - Niklas
>
> _fstat_r is the low-level implementation of fstat (), but something else is probably calling that.
>
> This can happen if there is a chain of function calls from your code to this function. To find out why you'll need to get the linker to produce a map file with -Map=<file>. The map will show which function was called that resulted in _fstat_r being needed and you can then recurse back to find which function in your code needed something that resulted in that.
>
> Are you, for example, calling printf somewhere, or using an assert?
>
> R.
>
More information about the Newlib
mailing list