Lame, nasm, and text relocations (textrels)
March 26th, 2011
Well, this took some debugging.
I’ve filed it all in a nasm bug report. To cut a long story short, if you compile LAME with Nasm 2.09, you’ll end up with TEXTRELs in the resultant libmp3lame.so.
What is a TEXTREL you may ask? Something bad! It stops the code being fully PIC (position independent), which stops the shared object being loaded into memory once and mapped multiple times. But worse, it causes Solaris ld to explode when linking:
gcc -shared -Wl,-h -Wl,libmp3lame.so.0 -o .libs/libmp3lame.so.0.0.0 .libs/VbrTag.o .libs/bitstream.o .libs/encoder.o .libs/fft.o .libs/gain_analysis.o .libs/id3tag.o .libs/lame.o .libs/newmdct.o .libs/presets.o .libs/psymodel.o .libs/quantize.o .libs/quantize_pvt.o .libs/reservoir.o .libs/set_get.o .libs/tables.o .libs/takehiro.o .libs/util.o .libs/vbrquantize.o .libs/version.o .libs/mpglib_interface.o -Wl,-z -Wl,allextract ../libmp3lame/i386/.libs/liblameasmroutines.a ../libmp3lame/vector/.libs/liblamevectorroutines.a ../mpglib/.libs/libmpgdecoder.a -Wl,-z -Wl,defaultextract -lm -lsocket -lnsl -lc -maccumulate-outgoing-args Text relocation remains referenced against symbol offset in file0x6e ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) 0x75 ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) 0x9a ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) 0xa1 ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) 0xa8 ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) 0x12b ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) 0x133 ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) 0x1a0 ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) 0x1aa ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) 0x1b4 ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) 0x1c2 ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) 0x24c ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) 0x25d ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) 0x39 ../libmp3lame/i386/.libs/liblameasmroutines.a(fft3dn.o) 0x56 ../libmp3lame/i386/.libs/liblameasmroutines.a(fft3dn.o) 0x128 ../libmp3lame/i386/.libs/liblameasmroutines.a(fft3dn.o) 0x142 ../libmp3lame/i386/.libs/liblameasmroutines.a(fft3dn.o) 0x26e ../libmp3lame/i386/.libs/liblameasmroutines.a(fft3dn.o) 0x2b9 ../libmp3lame/i386/.libs/liblameasmroutines.a(fft3dn.o) 0x2d6 ../libmp3lame/i386/.libs/liblameasmroutines.a(fft3dn.o) 0x398 ../libmp3lame/i386/.libs/liblameasmroutines.a(fft3dn.o) 0x4ce ../libmp3lame/i386/.libs/liblameasmroutines.a(fft3dn.o) 0x2c ../libmp3lame/i386/.libs/liblameasmroutines.a(fftsse.o) 0x7a ../libmp3lame/i386/.libs/liblameasmroutines.a(fftsse.o) 0x88 ../libmp3lame/i386/.libs/liblameasmroutines.a(fftsse.o) 0xc4 ../libmp3lame/i386/.libs/liblameasmroutines.a(fftsse.o) 0xd9 ../libmp3lame/i386/.libs/liblameasmroutines.a(fftsse.o) 0xe7 ../libmp3lame/i386/.libs/liblameasmroutines.a(fftsse.o) 0x1d0 ../libmp3lame/i386/.libs/liblameasmroutines.a(fftsse.o) 0x1e4 ../libmp3lame/i386/.libs/liblameasmroutines.a(fftsse.o) 0x20b ../libmp3lame/i386/.libs/liblameasmroutines.a(fftsse.o) 0x219 ../libmp3lame/i386/.libs/liblameasmroutines.a(fftsse.o) t1l 0x189 ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) largetbl 0xde ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) largetbl 0x105 ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) largetbl 0x10f ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) table23 0x245 ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) table56 0x256 ../libmp3lame/i386/.libs/liblameasmroutines.a(choose_table.o) ld: fatal: relocations remain against allocatable but non-writable sections collect2: ld returned 1 exit status
The way to fix the problem is to use NASM 2.08 or earlier, or wait until the bug gets fixed (although they might point their finger at LAME). I’m going to try yasm instead of nasm and see if that works, as an alternative.
If you don’t care about TEXTRELs, on Linux you don’t have to do anything (GNU ld allows them by default), but on Solaris you can tell the Solaris linker to allow impure text segments by adding "-mimpure-text -lrt" to your LDFLAGS. Or, you can use the GNU linker. This is quite hard, but I wrote a blog post about it.
Entry Filed under: General

Leave a Comment
Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed