How to run old linux code (32bit) on a current Ubuntu system (64bit)?

Mike Frysinger
Sun Aug 25 05:06:00 GMT 2013

On Thursday 01 August 2013 01:43:23 Carlos O'Donell wrote:
> On Sat, Jul 27, 2013 at 4:47 PM, Peng Yu wrote:
> > ~$ file y
> > y: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
> > dynamically linked (uses shared libs), for GNU/Linux 2.0.0, not
> > stripped
> > ~$ ./y
> > ./y: relocation error: ./y: symbol errno, version GLIBC_2.0 not
> > defined in file with link time reference
> This is most likely because application `y' incorrectly defined
> errno as `extern int errno;' which is invalid ISO C and breaks
> when glibc switches errno to thread-local storage in later
> versions.

this document might help [inlined below]:


so a bunch of binary-only applications that were written incorrectly may fail
with the latest glibc versions with errors such as:
<file>: symbol errno, version GLIBC_2.0 not defined in file with link 
time reference

you really really should:
 - contact the vendor providing the broken ass application and tell them to
   stop writing shitty code and to give you an update

of course, if you stole this application cause you're a juarez monkey, or
you're intimated easily, or you're lazy and you just want this shit to work,
there is another option

use a LinuxThreads version of glibc that contains no TLS support.

but wtf does that mean ?  well it could be one of two things:


emerge glibc with 'glibc-compat20' and '-nptlonly'.  so something like this
in /etc/portage/package.use: sys-libs/glibc glibc-compat20 -nptlonly
then when you emerge glibc, it should take care of the rest and your 
application should start working again.

while this is an OK solution for some, this sucks in the long run as when 
stops supporting linuxthreads, you're gonna be out of luck again.


grab a few prebuilt glibc libs and wrap your application startup.  the nice
thing about this is you keep the rest of your system running with clean glibc
upgrades and you dont have to worry about your app no longer working.

grab these files:
and put them somewhere useful

then invoke your crappy app like:
/somewhere/useful/ --library-path /somewhere/useful <crappy app>
if you get errors about missing insight libs or something, you'll prob have to
add the paths to those files as well:

/somewhere/useful/ --library-path /somewhere/useful:/other/stuff 
<crappy appy>


the issue is that the application writer did not understand the concept of
using proper header files.  so instead of the correct code:
#include <errno.h>
they probably wrote:
extern int errno;

historically this would "just work" as in reality, errno was an external
integer storage and in the classic non-threaded app, who cares.  the guys
writing threaded applications cared, that's who.  if errno has storage which
is shared across an entire application (and thus threads), then utilizing
errno is no longer thread safe, and that is certainly Not Good At All.  glibc
moved to using Thread Local Storage (TLS) for errno thus solving that problem.

so why did things break ?  well, errno went from being an integer to being an
actual function call.  if you used errno.h, then you never noticed as the
header would rewrite 'errno' to a function call to get the address of the
errno storage and then dereference it.  as the errno symbol itself is now 
TLS storage and marked private, it is not possible to provide the exported
symbol errno@GLIBC_2.0 as that is a non-TLS reference and mixing of TLS/non-
just doesn't fly.  if you feel like checking out the glibc sources, read
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <>

More information about the Libc-help mailing list