Are libraries that have been linked at build time but we haven't called any function in yet included?
Yes: the runtime loader will mmap
every library that your executable directly depends on, before your program starts running.
You can find the list of such libraries by running
readelf -d a.out | grep NEEDED
Does pmaps contain all the libraries used recursively?
Yes: if a library that you directly depend on itself depends on some other library, the runtime loader will mmap
the recursive dependencies as well.
My understanding is the Linux delays linking symbols until the first time they are used
That is mosty correct for function symbols, but false for data symbols, which can't be resolved lazily.
Also, whether the symbols are resolved lazily or not depends on LD_BIND_NOW
environment variable, and on an equivalent setting in the executable dynamic section, controlled by -znow
linker flag.
None of that changes the mmap
pciture though; if you have a DT_NEEDED
entry for foo.so
in your dynamic section, then foo.so
will be mmap
ed (and will show in /proc/self/*map*
) independent of lazy or non-lazy resolution.