Monday, April 18, 2011

Getting dynamic linking to work right is a never-ending series of dumped cores. Today I found two bugs which were actually quite generic (i.e. not architecture-specific) and, to be honest, quite silly.

First a sizeof(ptr) instead of sizeof(*ptr) passed to memset() caused the dyn_info_t structure not to be properly zeroed out. If something in dyn_info_t is not zero, it is assumed to be valid entry present in the dynamic section. Hence mysterious occasional crashes. Luckily thanks to the new memory allocator which has debugging turned on there was a suspicious quantity of dead beef being thrown around which slightly helped me find the problem.

Second, the relocation processing code was dying while trying to fix up references to libc variables in the text segment of the main program, which is stored in a memory area with R-X permissions. Huh? Well, the main program is loaded by loader, instead of dynload. Unlike dynload, loader does not make all loaded segments writable. Bummer.

Dynamic linking takes patience. If you suffer from granumophobia, then stay away.