Thanks Quinn. I can almost answer the original question, "from where do I call stat()?", from the link map file - except it describes where symbols are defined, not where they are used. But I can use it to get the names of the archive members that are being included in the binary:
% grep '\.a\[.*\](.*\.o)' app-LinkMap-normal-arm64.txt
...
[256] /usr/local/iphone-arm64/lib/libboost_container.a[6](pool_resource.o)
...
I wasted a lot of time at this point because the nm man page mentions the archive(member) syntax
If an argument is an archive, a listing for each object file in the archive will be produced. File
can be of the form libx.a(x.o), in which case only symbols from that member of the object file are
listed. (The parentheses have to be quoted to get by the shell.)
but it doesn't work:
% objdump --syms '/usr/local/iphone-arm64/lib/libboost_container.a(pool_resource.o)'
...or...
% nm '/usr/local/iphone-arm64/lib/libboost_container.a(pool_resource.o)'
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/objdump: error: '/usr/local/iphone-arm64/lib/libboost_container.a(pool_resource.o)': No such file or directory
However it's not mentioned in the llvm-nm man page; it seems to be nm-classic only (FB13691747), and that's not on my PATH. But if I call it directly it works:
% /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/nm-classic -u '/usr/local/iphone-arm64/lib/libboost_container.a(pool_resource.o)'
So now I can get all my app's undefined symbols, grouped by the object file or archive member in which they are used:
cat app-LinkMap-normal-arm64.txt |
grep '^\[' |
sed 's/^\[[ 0-9]*\] \(.*\)$/\1/' |
sed 's/\[.*\]//' |
while read N
do
echo "$N"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/nm-classic -u "$N"
done
Splendid. I can now see that _stat is called from two places:
libcrypto.a(conf_def.o)
libcrypto.a(loader_file.o)
and _fstat is called from one place also in libcrypto, and that's it.