llist, a library lister

A few weeks ago now I posted a question to misc@openbsd.org because I was trying to use llround() in something and couldn't get it to link. The answer I got was to use -lm in linking. Now I'm trying to get some of the example programs from the O'Reilly X and Motif books (from the 1990s) to compile and I'm running into similar problems.

man intro (3) will answer some of these questions, but where do you find functions like SmcModifyCallbacks() or XpmReadFileToPixmap()? And I don't know why unix man pages for functions list the header file names, but not the libraries. You're just supposed to know these things or give up, I guess. I've got 686 libraries in my ldhints with who knows how many functions in each. Some people would have written this in Perl but for me Perl is more work because I haven't used in in years.

What this does is to get the current list of hints from ld.so by doing "ldconfig -r" into a pipe connection, then run nm on each of the libray files mentioned. It puts the combined mess into /tmp/functions.txt where it will conveniently get deleted next time you boot. On my machine with a modest 425 packages installed the output is about 17 megs. If you install more things that have libraries you'll need to run it again anyway, which only takes a few seconds.

ldconfig is normally run every time you boot, so if you've installed something since you've booted and you're trying to find it, reboot before you run this.

I started to gather this info into an SQL database using PostgreSQL and there are still remnants of that plan in the code. I cache the output of "ldconfig -r" into an array of structs, then process the lines as I find them anyway. I'm not doing any sorting but supposedly the output of nm is sorted. I use Midnight Commander (mc) for lots of things and looking at the output from this in mc's viewer (hit F3) works fine so I don't think I'll do output to a database.

I you look at the nm manpage, each function line has a type letter and it says "If the symbol is local (non-external), the type letter is in lower case." I'm only taking the lowercase type letters and T: "text segment symbol" but that should be easy enough to change.

Here's a section of typical output. I added the lines with ------ so you can make an easier visual distinction between sections.

T sem_destroy
T sem_getvalue
T sem_init
T sem_post
T sem_trywait
T sem_wait
T sigwait
d static_init_lock
T vfork
--------- -lICE.9.0	/usr/X11R6/lib/libICE.so.9.0 -----------
t AcceptConnection
t AcceptProtocol
t AuthNextPhase
t AuthReply
t AuthRequired
T IceAcceptConnection
T IceAddConnectionWatch
T IceAllocScratch
T IceAppLockConn

The symbol for the library (the -l name you'd put in a Makefile) is on the left, then a tab, then the library's filename and path. I don't have a lot of experience, but it seems like you generally want to leave out the version numbers in a Makefile so this would be just -lICE.

Here's the tarball including a little Makefile. This is mostly meant for OpenBSD, but could possibly be changed for other systems. Tested under OpenBSD 4.7 and 5.0, but it's pretty generic.

AB1JX / calcs