cosmopolitan icon indicating copy to clipboard operation
cosmopolitan copied to clipboard

blinkenlights loader for dynamic executables

Open kyx0r opened this issue 3 years ago • 5 comments

Hello, I happen to be interested in more in blinkenlights debugging capability rather than the comopolitan project as a whole.

But for some reason everytime I try to run any dynamically linked musl executable I get this :

https://user-images.githubusercontent.com/33268383/109694520-d0901300-7b82-11eb-892b-9a8cb961a275.mp4

The vi is my program, source here: https://github.com/kyx0r/neatvi

And the sh is part of busybox : https://github.com/mirror/busybox/tree/master/shell

The undefined instruction might make sense due to native optimizations from compiler and something not handled by the debugger, but the segfault at _start, I have no idea. I guess it does not work well with dynamic linking, because it seems to work fine with .com objects.

kyx0r avatar Mar 02 '21 18:03 kyx0r

Sorry for cropped video, It's kinda hard to find non sucky recording software that I can compile right now. But I hope this gets to the point. Also I am pretty new to this project, so unsure on what to expect.

kyx0r avatar Mar 02 '21 18:03 kyx0r

I'm so excited you're using Blinkenlights since that's our flagship demo. Your Musl binary was most likely built with -march=native since it's using the BMI1 instruction ANDN which surprasses the Blinkenlights support vector, which is -march=k8 -msse3 -mssse3.

$ xed -64 -de c4e2d0f2e8
C4E2D0F2E8
ICLASS:     ANDN
CATEGORY:   BMI1
EXTENSION:  BMI1
IFORM:      ANDN_VGPR64q_VGPR64q_VGPR64q
ISA_SET:    BMI1
ATTRIBUTES:
SHORT:      andn rbp, rbp, rax
Encodable! C4E2D0F2E8
Identical re-encoding
#### Intel CPU Line
#
# - 2003 P6 M           SSE SSE2
# - 2004 prescott       SSE3 SSSE3 (-march=prescott)
# - 2006 core           X64
# ------------- BLINKENLIGHTS SUPPORT STOPS HERE --------------
# - 2006 core           X64 SSE4.1 (only on 45nm variety) (-march=core2)
# - 2008 nehalem        SSE4.2 VT-x VT-d (-march=nehalem)
# - 2010 westmere       CLMUL AES (-march=westmere)
# - 2011 sandybridge    AVX TXT (-march=sandybridge)
# - 2012 ivybridge      F16C MOVBE (-march=ivybridge)
# - 2013 haswell        AVX2 TSX BMI1 BMI2 FMA (-march=haswell)
# - 2014 broadwell      RDSEED ADX PREFETCHW (-march=broadwell - works on trusty gcc4.9)
# - 2015 skylake        SGX ADX MPX AVX-512[xeon-only] (-march=skylake / -march=skylake-avx512 - needs gcc7)
# - 2018 cannonlake     AVX-512 SHA (-march=cannonlake - needs clang5)
#
#### AMD CPU Line
#
# - 2003 k8             SSE SSE2 (-march=k8)
# - 2005 k8 (Venus)     SSE3 (-march=k8-sse3)
# - 2008 barcelona      SSE4a?! (-march=barcelona)
# - 2011 bulldozer      SSSE3 SSE4.1 SSE4.2 CLMUL AVX AES FMA4?! (-march=bdver1)
# - 2011 piledriver     BMI1 FMA (-march=bdver2)
# - 2015 excavator      AVX2 BMI2 MOVBE (-march=bdver4)
# - 2017 ryzen          F16C SHA ADX (-march=bdver4)

What that means is Blinkenlights just helped you discover a bug in your program. Consider doing dispatching based on CPUID. Blinkenlights correctly reports its capabilities. The nice thing about it is that if your code runs correctly on Blinkenlights then you have a better idea that it's going to work when you ship binaries to people using old hardware.

Contributions are also welcome if you want to add support for newer ISAs. See https://github.com/jart/cosmopolitan/blob/master/tool/build/lib/machine.c

jart avatar Mar 02 '21 19:03 jart

@jart Sorry might of been a bit ambigous in my wording but this is not a bug in my application. The part with invalid instruction is understandable (where I run sh), but the libc crash is not. Here is a more simple example.

https://user-images.githubusercontent.com/33268383/109704619-b5c39b80-7b8e-11eb-9545-15cecc4efccc.mp4

There is no way test.c can have bugs, the bug happens in the libc init. It tries to make jumps to some dynamic plt table, probably init some dynamic symbols, but it jumps to random undefined memory region and crashes. So I am trying to figure out if this is normal or not for it to not work on regularly compiled elf binaries?

EDIT: It does not seem like it runs any vector instructions in _start function, or they are just wrongly encoded ?

kyx0r avatar Mar 02 '21 19:03 kyx0r

https://user-images.githubusercontent.com/33268383/109706308-b1987d80-7b90-11eb-8384-9578a156425a.mp4

Here is a look with gdb, blinking lights does not take the required libc jump. Which is this: __libc_start_main@plt: jmp QWORD PTR [rip+0x2ff2] # 0x555555558018 [email protected]

Is QWORD PTR not supported or there is a bug in something else ?

kyx0r avatar Mar 02 '21 19:03 kyx0r

I understand now. It would be wonderful if Blinkenlights could load dynamic executables, since all we have to do is load the system libc interpreter shared object and then it takes care of the rest. Here's the code we're currently using to load PT_LOAD segments:

https://github.com/jart/cosmopolitan/blob/32e289b1d87fd825da29f6bfd6d7038287c9f6d3/tool/build/lib/loader.c#L40-L109

If I understand correctly, supporting PT_DYNAMIC basically entails iterating over a list of these, in order to recompute pointers and stuff:

https://github.com/jart/cosmopolitan/blob/32e289b1d87fd825da29f6bfd6d7038287c9f6d3/libc/elf/struct/dyn.h#L6-L12

Would you be interested in contributing this functionality?

jart avatar Mar 02 '21 20:03 jart