gpt4 book ai didi

linux - 32 位 LINUX 2.6 可执行文件能否在 LINUX 3.2 机器上可靠运行?

转载 作者:太空狗 更新时间:2023-10-29 11:09:13 25 4
gpt4 key购买 nike

假设 32 位支持已加载到给定的 64 位 LINUX 安装:

  • 32 位 LINUX 2.6 可执行文件能否在 LINUX 3.2 机器上可靠运行? (是的,重述标题)显然不是!
  • 对 32 位程序有哪些限制(就何种程序而言,而不是 4GB 限制等)?
  • 是否有特定的标记文件、可执行文件、系统调用可以检查以确定这一点,以便脚本可以通知用户系统配置不正确?然后我可以编写一个脚本,比如“canirunhere”,它可以让用户清楚地看到它,而不是让一些奇怪的浮点异常崩溃。
  • 尝试运行程序(在脚本中)并查看它是否崩溃是 不是 一个选项,因为程序可能只是被零除!

  • 背景故事:

    我有一个 2.6 LINUX 的 32 位二进制版本,它显示了经典的不兼容堆栈跟踪(见下文)。它适用于某些机器,例如 x86_64 Linux 3.2 机器(在本例中为 3.2.0-8),但不适用于其他机器,例如 AMD64 Linux 3.2 机器(在本例中为 3.2.44-3)。

    必要信息:

    该程序在动态加载器本身中死亡。以下是"file"和“uname -a”信息位:

    文件: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), not stripped
    非功能系统: 3.2.44-3.2.0.3.1-amd64-10846333 #1 SMP Wed May 29 13:08:01 UTC 2013 x86_64 GNU/Linux
    FUNCTIONAL 系统,一个运行 Ubuntu 的 x86_64 虚拟机: 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 17:37:58 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
    请注意,Ubuntu 系统最初不支持 32 位程序,因此 I had to follow the instructions on the (now sadly dead) link in this previous question. (click here)我无法在非功能性机器上执行相同的任务,尽管缺少“找不到文件”错误意味着理论上 32 位支持是存在的。

    堆栈跟踪: Program received signal SIGFPE, Arithmetic exception.
    0xf7feb876 in do_lookup_x () from /lib/ld-linux.so.2
    (gdb) where
    #0 0xf7feb876 in do_lookup_x () from /lib/ld-linux.so.2
    #1 0xf7febc07 in _dl_lookup_symbol_x () from /lib/ld-linux.so.2
    #2 0xf7fed251 in _dl_relocate_object () from /lib/ld-linux.so.2
    #3 0xf7fe7108 in dl_main () from /lib/ld-linux.so.2
    #4 0xf7ff58f1 in _dl_sysdep_start () from /lib/ld-linux.so.2
    #5 0xf7fe3c33 in _dl_start () from /lib/ld-linux.so.2
    #6 0xf7fe3817 in _start () from /lib/ld-linux.so.2

    跟踪输出:
    在响应者的建议下,这是strace的输出(不是完全相同的程序,因此地址会略有不同),这证实了它在动态加载中,希望有助于缩小原因。
    strace ./porgram
    execve("./program", ["./program"...], [/* 63 vars */]) = 0
    brk(0) = 0x80ea000
    access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
    mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf77c5000
    access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
    open("/etc/ld.so.cache", O_RDONLY) = 3
    fstat64(3, {st_mode=S_IFREG|0644, st_size=47552, ...}) = 0
    mmap2(NULL, 47552, PROT_READ, MAP_PRIVATE, 3, 0) = 0xf77b9000
    close(3) = 0
    access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
    open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3
    read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320\222"..., 512) = 512
    fstat64(3, {st_mode=S_IFREG|0755, st_size=1265332, ...}) = 0
    mmap2(NULL, 1275268, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xf7681000
    mmap2(0xf77b2000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x130) = 0xf77b2000
    mmap2(0xf77b6000, 9604, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xf77b6000
    close(3) = 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf7680000
    set_thread_area({entry_number:-1 -> 12, base_addr:0xf76806b0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
    --- SIGFPE (Floating point exception) @ 0 (0) ---

    最佳答案

    Assuming 32-bit support has been loaded on to a given 64-bit LINUX installation



    基本上是的,内核应该支持旧的二进制文件,但在你的情况下,程序是动态链接的,所以它需要特定版本的 glibc 和所有其他动态库。

    您可以尝试将完整的旧 32 位分发包解压到某个子文件夹,然后执行 chroot进入它,然后在 chroot 中运行你的程序。

    另外,检查 ldd二进制文件的输出(如果二进制文件是用非常旧的 glibc 构建的,它可能不起作用,因为有 ld.so aka ld-linux.so.2 程序来加载动态二进制文件并实现 ldd)。

    在 do_lookup_x 中有一个 SIGFPE 的例子(你可以用谷歌搜索它: SIGFPE, Arithmetic exception. do_lookup_x ):

    Floating point exception ( SIGFPE ) on 'int main(){ return(0); }' @stackoverflow.com

    Support for the GNU hash section was added to glibc around 2006, and mainline distros began to be GNU-hash-only around 2007 or 2008. Your Centrino's glibc is from 2003, which predates GNU hashing.

    If the ld.so doesn't understand GNU hash, it will try to use the old ELF hash section instead, which is empty. In particular, I suspect your crash is occurring at this line in elf/do-lookup.h:


     for (symidx = map->l_buckets[hash % map->l_nbuckets];

    Since the linker presumably doesn't understand GNU hashes, l_nbuckets would be 0, resulting in the crash.



    因此,您的 FPE 可能来自较旧的 32 位 linux 上的 glibc 和某些较新发行版中的 32 位 glibc 之间相同的不兼容性。

    关于linux - 32 位 LINUX 2.6 可执行文件能否在 LINUX 3.2 机器上可靠运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22389406/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com