Where is printf defined?

473 Views Asked by At

I've compiled a simple c program that uses printf and ran otool -l on the binary. In it /usr/lib/libSystem.B.dylib is mentioned in the LC_LOAD_DYLIB command. But when I do nm -a /usr/lib/libSystem.B.dylib to list the symbols in that lib I do not find printf. Where is it defined then?

2

There are 2 best solutions below

0
Ken Thomases On BEST ANSWER

First, otool -L is a simpler way to see the list of libraries that an executable links to.

Second, if you apply otool -L to libSystem.B.dylib, you'll see that it, in turn, depends on a bunch of libraries in /usr/lib/system. One of those is libsystem_c.dylib, which is the C library. That defines printf.

Going back to otool -l output for libSystem.B.dylib, you'll see that those dependencies are via the LC_REEXPORT_DYLIB load command. That's how the symbols in the other libraries are exported without actual symbol table entries for them.

I guess, arguably, it's a bug in nm that it doesn't show reexported symbols.

0
Yan Pak On

Saying about MacOS, at nowadays (November 2023) situation is significantly changed about commonly used library files on MacOS platform (BigSur and newer) - system-provided libraries have moved from filesystem to dynamic linker cache.

Despite it otool -L will still show you path for standard C library like it is physically placed in the system path: /usr/lib/libSystem.B.dylib. However this is not true, you will not find library there.

You can run your executable in such way:

> DYLD_PRINT_SEARCHING=1 ./your_executable_file
dyld[46270]: find path "/usr/lib/libSystem.B.dylib"
dyld[46270]:   possible path(original path on disk): "/usr/lib/libSystem.B.dylib"
dyld[46270]:   possible path(cryptex prefix): "/System/Volumes/Preboot/Cryptexes/OS/usr/lib/libSystem.B.dylib"
dyld[46270]:   possible path(original path): "/usr/lib/libSystem.B.dylib"
dyld[46270]:   found: dylib-from-cache: (0x00AB) "/usr/lib/libSystem.B.dylib"

last line says that library was found in cache.

And to adding to above, if you want to find library containing _prinf that used in compilation of your program, you have to had a look at dirs of SDK:

> xcode-select -p
/Library/Developer/CommandLineTools

> nm /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/system/libsystem_c.tbd | grep " _printf"
0000000000000000 D _printf

To understand from where the path came you can run compile driver with -v

> cc -o test test.o test1.o test2.0 -v

Read more about https://developer.apple.com/forums/thread/669094