Solved! This problem is caused by a miscconfigured glibc build with an incorrect --prefix. The absolute paths are picked up from libc.so, which is just a linker script generated by glibc. This linker script must contain paths that are correct for the target system system. Of course, those paths don't work on the cross-compiling system, which is where the catenation with --sysroot comes in. And of course install_root must be used in glibc to avoid actually trying to place files at the fictitious --prefix location. So install_root must match your --sysroot location, and --prefix is just / . Yesterday, I got a mini cross-compiled Linux system to run on real MIPS hardware, starting from scratch, with very little hints from anywhere. I just kept doing the "obvious" steps until I got a shell prompt on the hardware. How did I debug the problem? Well, after my silly patch to binutils, which I can now back out, I got everything to link surely enough. But with the wrong paths. So when I tried to boot the system, my shiny new /sbin/init was able to fetch the dynamic linker /lib/ld.so.1, but the dynamic linker quit, with a message about not being able to find libc.so.6! What? It's right there! So then I went into the kernel, and compiled an extra environment variable into init's env[] array, so that I could set it from the kernel command line. I was then able to "LD_DEBUG=all" on the kernel command line! I rebooted the MIPS board and ld.so nicely dumped out to the serial console that it was trying to use build-system paths to look for the library rather than the correct target-system paths. I band-aided that with a symbolic link, and got the system to boot, then worked out the real solution.