llvm-mos / llvm-mos-sdk

SDK for developing with the llvm-mos compiler
https://www.llvm-mos.org
Other
279 stars 55 forks source link

Weird behavior of `hello-getchar` example compiled for Atari 8-bit #378

Closed SignumTemporis closed 1 month ago

SignumTemporis commented 1 month ago

Description

hello-getchar.c example compiled for Atari 8-bit works incorrectly (unless I'm doing something wrong).

In my test, for subsequent prompts I enter the following lines of text:

1
2
456
ABCDEFG

It seems to work correctly when compiled with cc65.

I used mostly Atari800 emulator and embedded OS. However, I tried also another emulator - Atari++ (with its own OS). \ Results are the same.

I made also a couple of experiments with other OS ROMs. Sometimes it produced slightly different output but in general it works fine when compiled with cc65 and it works weirdly when compiled with LLVM.

See Details below.

Environment

Details

Using cc65 and XEX binary

Compile

cl65 -t atarixl -C atarixl-xex.cfg -o hello-getchar.xex hello-getchar.c

Run

atari800 -xl -run hello-getchar.xex

Result

ENTER SOME INPUT:
> 1
1
ENTER SOME INPUT:
> 2
2
ENTER SOME INPUT:
> 456
456
ENTER SOME INPUT:
> ABCDEFG
ABCDEFG
ENTER SOME INPUT:
>

It looks good. See also cc65-xex.

Using llvm-mos-sdk and XEX binary

Compile

mos-atari8-dos-clang -o hello-getchar.xex hello-getchar.c

Run

atari800 -xl -run hello-getchar.xex

Result

Weird. llvm-xex.

Using llvm-mos-sdk and standard 8 KB cartridge

Compile

mos-atari8-cart-std-clang -o hello-getchar.car hello-getchar.c

Run

atari800 -xl -cart-type 1 -cart hello-getchar.car

Result

Weird. llvm-cart.

mysterymath commented 1 month ago

Sorry for taking so long to look into this. I was able to reproduce this both at -O0 (the command lines above) and -Os, so it's probably a bug in the minimal getchar implementation. I'll dig into the details later.

mysterymath commented 1 month ago

Actually, this just appears to be incorrect behavior of the hello-getchar example. We don't line buffer getchar by default; it's a direct link to the IOCB routine in the OS. The OS documentation more or less implies that lines must be read as a whole: until the whole line is read, the cursor isn't repositioned onto the next line. The cursor corruption is probably due to it moving when the OS doesn't expect it to.

I'm not 100% certain what to do about this; it's generally assumed by C programs that you can interleave getchar and putchar in this way. I had previously taken the stance that the SDK should provide as direct of access to the underlying OS routines as possible, but the footgun here may be better avoided by providing a single-line buffer in the SDK for the minimal stdio on atari. I'll leave this issue open accordingly.

SignumTemporis commented 1 month ago

I'm trying to use the patch. However, when I follow Development procedure I get an error. What can be wrong?

Procedure:

FROM ubuntu:22.04

ARG SDK_VERSION=20.2.0
ARG SDK_INSTALL_PREFIX=/opt

RUN apt-get update
RUN apt-get install -y git wget xz-utils
RUN apt-get install -y make cmake ninja-build

WORKDIR /tmp

RUN wget https://github.com/llvm-mos/llvm-mos-sdk/releases/download/v${SDK_VERSION}/llvm-mos-linux.tar.xz
RUN tar --no-same-owner -C ${SDK_INSTALL_PREFIX} -xJf llvm-mos-linux.tar.xz

ENV PATH=${SDK_INSTALL_PREFIX}/llvm-mos/bin:${PATH}

RUN git clone --depth 1 https://github.com/llvm-mos/llvm-mos-sdk.git
RUN mkdir llvm-mos-sdk/build
WORKDIR /tmp/llvm-mos-sdk/build
RUN cmake -G "Ninja" -DCMAKE_INSTALL_PREFIX=${SDK_INSTALL_PREFIX}/llvm-mos/ ..
RUN ninja install
WORKDIR /tmp

The procedure fails in step cmake -G "Ninja" ...:

 > [11/13] RUN cmake -G "Ninja" -DCMAKE_INSTALL_PREFIX=/opt/llvm-mos/ ..:
0.416 -- No build type selected, default to MinSizeRel
0.528 -- The C compiler identification is GNU 11.4.0
0.687 -- The CXX compiler identification is Clang 20.0.0
0.706 -- The ASM compiler identification is GNU
0.710 -- Found assembler: /usr/bin/cc
0.726 -- Detecting C compiler ABI info
0.827 -- Detecting C compiler ABI info - done
0.845 -- Check for working C compiler: /usr/bin/cc - skipped
0.846 -- Detecting C compile features
0.847 -- Detecting C compile features - done
0.858 -- Detecting CXX compiler ABI info
0.963 -- Detecting CXX compiler ABI info - failed
0.963 -- Check for working CXX compiler: /opt/llvm-mos/bin/clang++
1.064 -- Check for working CXX compiler: /opt/llvm-mos/bin/clang++ - broken
1.064 CMake Error at /usr/share/cmake-3.22/Modules/CMakeTestCXXCompiler.cmake:62 (message):
1.064   The C++ compiler
1.064 
1.064     "/opt/llvm-mos/bin/clang++"
1.064 
1.064   is not able to compile a simple test program.
1.064 
1.064   It fails with the following output:
1.064 
1.064     Change Dir: /tmp/llvm-mos-sdk/build/CMakeFiles/CMakeTmp
1.064     
1.064     Run Build Command(s):/usr/bin/ninja cmTC_4ff06 && [1/2] Building CXX object CMakeFiles/cmTC_4ff06.dir/testCXXCompiler.cxx.o
1.064     [2/2] Linking CXX executable cmTC_4ff06
1.064     FAILED: cmTC_4ff06 
1.064     : && /opt/llvm-mos/bin/clang++   CMakeFiles/cmTC_4ff06.dir/testCXXCompiler.cxx.o -o cmTC_4ff06   && :
1.064     ld.lld: error: unable to find library -l:crt0.o
1.064     ld.lld: error: unable to find library -lcrt0
1.064     ld.lld: error: unable to find library -lcrt
1.064     ld.lld: error: unable to find library -lc
1.064     ld.lld: error: cannot find linker script link.ld
1.064     clang++: error: ld.lld command failed with exit code 1 (use -v to see invocation)
1.064     ninja: build stopped: subcommand failed.
1.064     
1.064 
1.064   CMake will not be able to correctly generate this project.
1.064 Call Stack (most recent call first):
1.064   CMakeLists.txt:9 (project)
1.064 
1.064 
1.066 -- Configuring incomplete, errors occurred!
1.066 See also "/tmp/llvm-mos-sdk/build/CMakeFiles/CMakeOutput.log".
1.066 See also "/tmp/llvm-mos-sdk/build/CMakeFiles/CMakeError.log".
mysterymath commented 1 month ago

I don't recall ever seeing this before; it's not supposed to check whether the C compiler can produce executables (since it clearly can't without a SDK providing libraries and linker scripts).

EDIT: Maybe try removing llvm-mos from the PATH? I think the compiler might be picking that up as the host clang, which isn't correct.

SignumTemporis commented 1 month ago

I was able to fix the issue of applying the patch. See this comment in #381.

I haven't tested the patch itself yet.

SignumTemporis commented 1 month ago

It works as expected after applying 4fc7b2d patch.