ptitSeb / box64

Box64 - Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices
https://box86.org
MIT License
3.9k stars 288 forks source link

Symbol _Unwind_GetRegionStart not found (and others) on Raspberry Pi OS x64 #1269

Open ZirakC opened 9 months ago

ZirakC commented 9 months ago
Dynarec for ARM64, with extension: ASIMD AES CRC32 PMULL ATOMICS SHA1 SHA2 PageSize:16384 Running on Cortex-A76 with 4 Cores
Params database has 57 entries
Box64 with Dynarec v0.2.7 5924a8ec built on Feb 16 2024 15:52:58
BOX64: Detected 48bits at least of address space
Counted 44 Env var
BOX64 LIB PATH: ./:lib/:lib64/:x86_64/:bin64/:libs64/:/lib/x86_64-linux-gnu/:/usr/lib/x86_64-linux-gnu/
BOX64 BIN PATH: ./:bin/:/usr/local/sbin/:/usr/local/bin/:/usr/sbin/:/usr/bin/:/sbin/:/bin/:/usr/local/games/:/usr/games/
Looking for CustomApp
argv[1]="2024"
Rename process to "CustomApp"
Using native(wrapped) libpthread.so.0
Using native(wrapped) libdl.so.2
Using native(wrapped) libz.so.1
Using native(wrapped) libm.so.6
Using native(wrapped) librt.so.1
Using emulated /lib/x86_64-linux-gnu/libgcc_s.so.1
Using emulated /lib/x86_64-linux-gnu/libstdc++.so.6
Using native(wrapped) libc.so.6
Using native(wrapped) ld-linux-x86-64.so.2
Using native(wrapped) libutil.so.1
Using native(wrapped) libbsd.so.0
Warning: Weak Symbol __gmon_start__ not found, cannot apply R_X86_64_JUMP_SLOT @0x100a57a18 (0xa277e6)
Warning: Weak Symbol _ZTH12t_ThreadType not found, cannot apply R_X86_64_JUMP_SLOT @0x100a57ec8 (0xa28146)
Warning: Weak Symbol _ZTH27t_pStackWalkerWalkingThread not found, cannot apply R_X86_64_JUMP_SLOT @0x100a57ed0 (0xa28156)
Warning: Weak Symbol _ZTHN9StressLog19t_pCurrentThreadLogE not found, cannot apply R_X86_64_JUMP_SLOT @0x100a57ee8 (0xa28186)
Warning: Weak Symbol _ZTH15t_CantStopCount not found, cannot apply R_X86_64_JUMP_SLOT @0x100a57ef0 (0xa28196)
Warning: Weak Symbol _ZTH16t_CantAllocCount not found, cannot apply R_X86_64_JUMP_SLOT @0x100a57f58 (0xa28266)
Error loading needed lib liblttng-ust-tracepoint.so.0
Warning: Cannot dlopen("liblttng-ust-tracepoint.so.0"/0x10009e034, 102)
Error loading needed lib liblttng-ust-tracepoint.so.0
Warning: Cannot dlopen("liblttng-ust-tracepoint.so.0"/0x10009e034, 102)
Error loading needed lib libicuuc.so.85
Warning: Cannot dlopen("libicuuc.so.85"/0x7ffef9c1cb50, 1)
Error loading needed lib libicuuc.so.84
Warning: Cannot dlopen("libicuuc.so.84"/0x7ffef9c1cb50, 1)
Error loading needed lib libicuuc.so.83
Warning: Cannot dlopen("libicuuc.so.83"/0x7ffef9c1cb50, 1)
Error loading needed lib libicuuc.so.82
Warning: Cannot dlopen("libicuuc.so.82"/0x7ffef9c1cb50, 1)
Error loading needed lib libicuuc.so.81
Warning: Cannot dlopen("libicuuc.so.81"/0x7ffef9c1cb50, 1)
Error loading needed lib libicuuc.so.80
Warning: Cannot dlopen("libicuuc.so.80"/0x7ffef9c1cb50, 1)
Error loading needed lib libicuuc.so.79
Warning: Cannot dlopen("libicuuc.so.79"/0x7ffef9c1cb50, 1)
Error loading needed lib libicuuc.so.78
Warning: Cannot dlopen("libicuuc.so.78"/0x7ffef9c1cb50, 1)
Error loading needed lib libicuuc.so.77
Warning: Cannot dlopen("libicuuc.so.77"/0x7ffef9c1cb50, 1)
Error loading needed lib libicuuc.so.76
Warning: Cannot dlopen("libicuuc.so.76"/0x7ffef9c1cb50, 1)
Error loading needed lib libicuuc.so.75
Warning: Cannot dlopen("libicuuc.so.75"/0x7ffef9c1cb50, 1)
Error initializing native libicuuc.so.74 (last dlerror is libicuuc.so.74: cannot open shared object file: No such file or directory)
Error loading needed lib libicuuc.so.74
Warning: Cannot dlopen("libicuuc.so.74"/0x7ffef9c1cb50, 1)
Error loading needed lib libicuuc.so.73
Warning: Cannot dlopen("libicuuc.so.73"/0x7ffef9c1cb50, 1)
Using native(wrapped) libicuuc.so.72
Using native(wrapped) libicui18n.so.72
[2/16/2024 4:34:23 PM] Loading TestLib_x64.so...
Using emulated /home/zirak/Test/TestLib_x64.so
Error: Global Symbol _Unwind_Resume not found, cannot apply R_X86_64_GLOB_DAT @0x7fff02dcf6a0 ((nil)) in /home/zirak/Test/TestLib_x64.so
Error: Symbol _Unwind_GetRegionStart not found, cannot apply R_X86_64_JUMP_SLOT @0x7fff02dcf0d8 (0xdcc7da) in /home/zirak/Test/TestLib_x64.so
Error: Symbol _Unwind_RaiseException not found, cannot apply R_X86_64_JUMP_SLOT @0x7fff02dcf100 (0xe44823) in /home/zirak/Test/TestLib_x64.so
Error: Symbol _Unwind_SetIP not found, cannot apply R_X86_64_JUMP_SLOT @0x7fff02dcf120 (0xa3167f) in /home/zirak/Test/TestLib_x64.so
Error: Symbol _Unwind_GetLanguageSpecificData not found, cannot apply R_X86_64_JUMP_SLOT @0x7fff02dcf128 (0xe4d93c) in /home/zirak/Test/TestLib_x64.so
Error: Symbol _Unwind_GetTextRelBase not found, cannot apply R_X86_64_JUMP_SLOT @0x7fff02dcf168 (0xe053ff) in /home/zirak/Test/TestLib_x64.so
Warning: Weak Symbol __gmon_start__ not found, cannot apply R_X86_64_JUMP_SLOT @0x7fff02dcf240 (0xa362ad)
Error: Symbol _Unwind_Resume not found, cannot apply R_X86_64_JUMP_SLOT @0x7fff02dcf2c8 (0xd7fcb5) in /home/zirak/Test/TestLib_x64.so
Error: Symbol _Unwind_SetGR not found, cannot apply R_X86_64_JUMP_SLOT @0x7fff02dcf2d8 (0xd4e50e) in /home/zirak/Test/TestLib_x64.so
Error: Symbol __udivti3 not found, cannot apply R_X86_64_JUMP_SLOT @0x7fff02dcf308 (0xe972b9) in /home/zirak/Test/TestLib_x64.so
Error: Symbol _Unwind_DeleteException not found, cannot apply R_X86_64_JUMP_SLOT @0x7fff02dcf330 (0xe71355) in /home/zirak/Test/TestLib_x64.so
Error: Symbol _Unwind_GetDataRelBase not found, cannot apply R_X86_64_JUMP_SLOT @0x7fff02dcf350 (0xf7a05f) in /home/zirak/Test/TestLib_x64.so
Warning: Weak Symbol __gmon_start__ not found, cannot apply R_X86_64_JUMP_SLOT @0x7fff02dcf3a0 (0xdb2a52)
Error: relocating Plt symbols in elf TestLib_x64.so
Error initializing needed lib /home/zirak/Test/TestLib_x64.so

Issue loading TestLib_x64.so (This is a precompiled binary that I am trying to load, I don't have access to the code). This is happening on Raspberry Pi 5 on Raspberry Pi OS x64

ptitSeb commented 9 months ago

Those symbols comes from libunwind. There is an x86_64 copy shipped with box64. What is strange is that it's notloaded as needed, if it's needed? You can try to preload it, like with BOX64_LD_PRELOAD=libunwind.so.8

ZirakC commented 9 months ago

BOX64_LD_PRELOAD=libunwind.so.8 did the trick, but it appears like Error: Symbol __udivti3 not found still causes an error. It did resolve all the Unwind errors.

Edit: What's strange is that I figured "__udivti3" is apart of libgcc_s.so.1, and it appears to be using the emulated version of it based on the logs.

I tried force loading it this way as well and it still resulted in the same error: BOX64_LD_PRELOAD=libgcc_s.so.1:libunwind.so.8 ./CustomApp 2024

Edit2: After additional debugging I can see it tries to load the __udivti3 symbol from libstdc++.so.6 and libgcc_s.so.1, but it doesn't appear to be used

  /lib/x86_64-linux-gnu/libgcc_s.so.1:DynSym[62] = "__udivti3", value=0x7330, size=256, info/other=18/0 index=13 (optver=2/GCC_3.0)
  /lib/x86_64-linux-gnu/libstdc++.so.6:DynSym[66] = "__udivti3", value=(nil), size=0, info/other=18/0 index=0 (optver=56/GCC_3.0)
  /lib/x86_64-linux-gnu/libstdc++.so.6:PLT[367] = 0x24fb78 (0x4200000007: type: R_X86_64_JUMP_SLOT, sym=0x42/__udivti3) Addend=0x0
Preparing (if needed) STB_GLOBAL R_X86_64_JUMP_SLOT @0x7fff0224fb78 (0x9d726->0x7fff0209d726) with sym=__udivti3 to be apply later (addend=0)
  /home/zirak/Test/TestLib_x64.so:DynSym[61] = "__udivti3", value=(nil), size=0, info/other=16/0 index=0 (ver=0/*local*)
  /home/zirak/Test/TestLib_x64.so:PLT[236] = 0x242778 (0x3D00000007: type: R_X86_64_JUMP_SLOT, sym=0x3D/__udivti3) Addend=0x0
Error: Symbol __udivti3 not found, cannot apply R_X86_64_JUMP_SLOT @0x7fff08642778 (0xa2c6) in /home/zirak/Test/TestLib_x64.so

I'm not sure if this is the correct symbol, but even then it complains about it not being found...

Edit 3: I can call the "__udivti3" function successfully through my wrapper program, so it doesn't make sense why box64 can't find it for the lib, I checked the function parameters in the library via IDA and it appears to be correct. Any ideas @ptitSeb?

ZirakC commented 9 months ago

I ended up doing a hack solution to box64 since I couldn't figure it out what the actual root cause was. I ended up just saving the "__udivti3" during the "preparing" step and then use that offset for the actual bind. This appears to work for my use case.

case R_X86_64_JUMP_SLOT:
    // apply immediatly for gobject closure marshal or for LOCAL binding. Also, apply immediatly if it doesn't jump in the got
    tmp = (uintptr_t)(*p);
    if (bind==STB_LOCAL 
      || ((symname && strstr(symname, "g_cclosure_marshal_")==symname)) 
      || ((symname && strstr(symname, "__pthread_unwind_next")==symname)) 
      || !tmp
      || !((tmp>=head->plt && tmp<head->plt_end) || (tmp>=head->gotplt && tmp<head->gotplt_end))
      || !need_resolv
      || bindnow
      ) {
        if (!offs) {
            if(bind==STB_WEAK) {
                printf_log(LOG_INFO, "Warning: Weak Symbol %s not found, cannot apply R_X86_64_JUMP_SLOT @%p (%p)\n", symname, p, *(void**)p);
            } else {
                printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply R_X86_64_JUMP_SLOT @%p (%p) in %s\n", symname, p, *(void**)p, head->name);
                if (strstr(symname, "__udivti3") == symname) {
                    if (p) {
                        printf_log(LOG_INFO, "Using offs: %p\n", symname, p, *(void**)p, offs);
                        offs = g_offs;
                        printf_log(LOG_INFO, "Force Apply %s R_X86_64_JUMP_SLOT @%p with sym=%s (%p -> %p / %s (%sver=%d / %s))\n",
                            BindSym(bind), p, symname, *(void**)p, (void*)(offs + rela[i].r_addend), sym_elf ? sym_elf->name : "native", veropt ? "opt" : "", version, vername ? vername : "(none)");

                        *p = offs + rela[i].r_addend;
                        if (sym_elf && sym_elf != last_elf && sym_elf != head) last_elf = checkElfLib(head, sym_elf->lib);
                    } else {
                        ret_ok = 1;
                        printf_log(LOG_NONE, "Error: Symbol %s Jump Slot Offset is NULL\n", symname);
                    }
                } else {
                    ret_ok = 1;
                }
            }
        } else {
            if(p) {
                printf_dump(LOG_NEVER, "Apply %s R_X86_64_JUMP_SLOT @%p with sym=%s (%p -> %p / %s (%sver=%d / %s))\n", 
                    BindSym(bind), p, symname, *(void**)p, (void*)(offs+rela[i].r_addend), sym_elf?sym_elf->name:"native", veropt?"opt":"", version, vername?vername:"(none)");
                *p = offs + rela[i].r_addend;
                if(sym_elf && sym_elf!=last_elf && sym_elf!=head) last_elf = checkElfLib(head, sym_elf->lib);
            } else {
                printf_log(LOG_INFO, "Warning, Symbol %s found, but Jump Slot Offset is NULL \n", symname);
            }
        }
    } else {
        printf_dump(LOG_NEVER, "Preparing (if needed) %s R_X86_64_JUMP_SLOT @%p (0x%lx->0x%0lx) with sym=%s to be apply later (addend=%ld)\n", 
            BindSym(bind), p, *p, *p+head->delta, symname, rela[i].r_addend);

        if (strstr(symname, "__udivti3") == symname) {
            printf_log(LOG_INFO, "INFO: Symbol %s storing offs for R_X86_64_JUMP_SLOT @%p (%p) offs: %p\n", symname, p, *(void**)p, offs);
            g_offs = offs;
        }

        *p += head->delta;
        *need_resolv = 1;
    }
    break;