Closed toncho11 closed 2 years ago
This is my config file. failed_config.txt
Hello @toncho11,
I haven't pulled down the latest compiler build, so I'm going to ask @tkchia what he thinks before doing so.
Hello @tkchia, in this case, ia16-elf-as
is assembling elks/arch/i86/lib/unreal.S, which uses the following line which is causing this error:
.arch i386,nojumps
The reason for this is that, unlike all other files in ELKS, this file is attempting to set unreal mode and requires the 0x66 or 0x67 (address32 or operand32) prefixes to be emitted for various instructions. Has this changed in the latest toolchain?
If so, what would be the recommended method for assembling this file, and would there be a way to keep this compatible with older source, or do all users need to update their toolchain with modified source? Note that -mtune=8086 is still being passed to ia16-elf-as
for this assembly.
Thank you!
Hello @toncho11, hello @ghaerr,
gcc -E -traditional -I/home/toncho/elks/include -I/home/toncho/elks/elks/include -I/home/toncho/elks/libc/include -DUTS_RELEASE=\"0.4.0\" -D__KERNEL__ -o unreal.tmp unreal.S
ia16-elf-as -mtune=i8086 --32-segelf -o unreal.o unreal.tmp
unreal.S: Assembler messages:
unreal.S:32: Error: no such architecture: `'
unreal.S:32: Error: junk at end of line, first unrecognized character is `1'
Hmm... OK... it turns out that this happens because we were (erroneously) using the host GCC to preprocess the unreal.S
file, when we should be using ia16-elf-gcc
. And it seems that @toncho11 was building ELKS on a 32-bit x86 system, so the macro i386
happened to be defined as 1
— along with macros __i386
and __i386__
, which were also defined to be 1
. So
.arch i386,nojumps
was preprocessed into (!)
.arch 1,nojumps
(@ghaerr: If you pass -m32
to the host GCC you should be able to see this in the unreal.tmp
output, and reproduce the problem.)
I am not sure why the makefile rules were using a separate preprocessing pass and were using -traditional
— historical reasons? — but anyway, if we use ia16-elf-gcc
rather than the host GCC, I think we should be able to remove this glitch. This is because ia16-elf-gcc
does not define an i386
macro.
diff --git a/elks/Makefile-rules b/elks/Makefile-rules
index f69d0f1e..36b95408 100644
--- a/elks/Makefile-rules
+++ b/elks/Makefile-rules
@@ -232,7 +232,7 @@ endif
.S.s: ;
.S.o:
- gcc -E -traditional $(INCLUDES) $(CCDEFS) -o $*.tmp $<
+ $(CC) -E -traditional $(INCLUDES) $(CCDEFS) -o $*.tmp $<
$(AS) $(ASFLAGS) -o $*.o $*.tmp
rm $*.tmp
diff --git a/elkscmd/Make.defs b/elkscmd/Make.defs
index 99a95518..72389522 100644
--- a/elkscmd/Make.defs
+++ b/elkscmd/Make.defs
@@ -98,7 +98,7 @@ CFLAGS=$(CFLBASE) $(WARNINGS) $(LOCALFLAGS) $(INCLUDES) -D__ELKS__ -DELKS_VERSIO
# Standard compilation rules.
.S.s:
- gcc -E -traditional $(INCLUDES) $(CCDEFS) -o $*.s $<
+ $(CC) -E -traditional $(INCLUDES) $(CCDEFS) -o $*.s $<
.s.o:
$(AS) $(ASFLAGS) -o $*.o $<
Thank you!
Hello @toncho11, hello @ghaerr,
About these:
unreal.S:341: Warning: stand-alone `addr32' prefix
unreal.S:391: Warning: stand-alone `addr32' prefix
unreal.S:398: Warning: stand-alone `addr32' prefix
These are because the addr32
's, by right, should appear on the same line as the instructions they modify — info gas
specifically mentions this. These are warnings, not fatal errors, and ia16-elf-as
will ultimately do the correct thing anyway.
To address the warnings, instead of saying
addr32 // 32-bit address prefix
rep
movsw // word [ES:EDI++] <- [DS:ESI++], ECX times
just say
addr32 rep movsw // word [ES:EDI++] <- [DS:ESI++], ECX times
(Actually we can also use the same addr32
notation for the CPU bug workaround in the next lines. Instead of
.byte 0x67 // 80386 B1 step chip bug on address size mixing
nop
we can simply write
addr32 nop // 80386 B1 step chip bug on address size mixing
and ia16-elf-as
will output the correct instruction.)
Thank you!
Hello @tkchia, hello @toncho11,
Thanks for your keen observation that this problem is actually the host's C preprocessor substituting '1' for 'i386'!! It makes you wonder what other symbols might be unknowingly changed in .S files. I had wondered what the "first unrecognized character '1'" was about. It might be a good idea to somehow turn off predefined symbols in the $(CC) -E pass if possible, to prevent this (although I suppose some .S might want those symbols for #if statements?)
I'll make all suggested changes and submit a PR. (I'm not able to easily test the '-m32' option since I'm developing solely on macOS.) It does seem somewhat amazing no one except @toncho11 until now has compiled ELKS on a 32-bit Linux system!
Thank you!
Yes, I confirm that it is a 32 bit system. Because it is an old Core2 Duo that I am using for ... ELKS compiling.
It also means that before it was building OK on a 32bit system.
I am using the latest compiler that was downloaded using the build script.