how to port c/c++ applications to legacy linux kernel versions

前端 未结 2 1848
盖世英雄少女心
盖世英雄少女心 2021-02-07 09:00

Ok, this is just a bit of a fun exercise, but it can\'t be too hard compiling programmes for some older linux systems, or can it?

I have access to a couple of ancient sy

2条回答
  •  生来不讨喜
    2021-02-07 09:36

    Have found the reason for the error message:

    user@ancient $ ./prog
    set_thread_area failed when setting up thread-local storage
    Segmentation fault
    

    It's because glibc makes a system call to a function which is only available since kernel 2.4.20. In a way it can be seen as a bug of glibc as it wrongly claims to be compatible with kernel 2.0.10 when it requires at least kernel 2.4.20.

    The details:

    ./glibc-2.14/nptl/sysdeps/i386/tls.h
    [...]
         /* Install the TLS.  */                                                  \
         asm volatile (TLS_LOAD_EBX                                               \
                       "int $0x80\n\t"                                            \
                       TLS_LOAD_EBX                                               \
                       : "=a" (_result), "=m" (_segdescr.desc.entry_number)       \
                       : "0" (__NR_set_thread_area),                              \
                         TLS_EBX_ARG (&_segdescr.desc), "m" (_segdescr.desc));    \
    [...]
         _result == 0 ? NULL                                                      \
         : "set_thread_area failed when setting up thread-local storage\n"; })
    [...]
    

    The main thing here is, it calls the assembly function int 0x80 which is a system call to the linux kernel which decides what to do based on the value of eax, which is set to __NR_set_thread_area in this case and is defined in

    $ grep __NR_set_thread_area /usr/src/linux-2.4.20/include/asm-i386/unistd.h
    #define __NR_set_thread_area    243
    

    but not in any earlier kernel versions.

    So the good news is that point "3. Compiling glibc with --enable-kernel=2.0.0" will probably produce executables which run on all linux kernels >= 2.4.20.

    The only chance to make this work with older kernels would be to disable tls (thread-local storage) but which is not possible with glibc 2.14, despite the fact it is offered as a configure option.

提交回复
热议问题