embeddedartistry / libc

libc targeted for embedded systems usage. Reduced set of functionality (due to embedded nature). Chosen for portability and quick bringup.
MIT License
524 stars 67 forks source link

Building for aarch64 using the aarch64-none-elf-gcc cross-compiler. #191

Open ptrk8 opened 1 year ago

ptrk8 commented 1 year ago

I'm trying to build this libc implementation for aarch64 using the aarch64-none-elf-gcc cross-compiler.

I modified the arm.txt cross-compiler file in the following (quick and dirty) way:

[binaries]
c = 'aarch64-none-elf-gcc'
cpp = 'aarch64-none-elf-c++'
ar = 'aarch64-none-elf-gcc-ar'
strip = 'aarch64-none-elf-strip'

[properties]
objcopy = 'aarch64-none-elf-objcopy'
get_supported_link_arg_flags = ['--specs=nosys.specs']
needs_exe_wrapper = true
c_args = [ '-mcpu=cortex-a53']
c_link_args = [ '-mcpu=cortex-a53']
cpp_args = [ '-mcpu=cortex-a53']
cpp_link_args = [ '-mcpu=cortex-a53']

[host_machine]
system = 'none'
cpu_family = 'aarch64'
cpu = 'cortex-a53'
endian = 'little'

I then ran the following command:

meson buildresults --cross-file build/cross/arm.txt

And then I ran:

make

However, I got the following compiler error:

ninja: Entering directory `buildresults'
[2/540] Compiling C++ object printf_tests.p/printf_test_test_suite.cpp.o
../printf/test/test_suite.cpp: In function ‘void ____C_A_T_C_H____T_E_S_T____50()’:
../printf/test/test_suite.cpp:346:56: warning: reading through null pointer (argument 4) [-Wformat=]
   ret = snprintf_(buffer, 6, "0%s", (const char *) NULL);
                                                        ^
../printf/test/test_suite_main_testcases.hpp: In function ‘void ____C_A_T_C_H____T_E_S_T____354()’:
../printf/test/test_suite.cpp:88:32: warning: reading through null pointer (argument 3) [-Wformat=]
   printer_(buffer_, __VA_ARGS__);                                \
                                ^
../printf/test/test_suite_main_testcases.hpp:245:3: note: in expansion of macro ‘PRINTING_CHECK’
   PRINTING_CHECK("(null)",               ==, sprintf_, buffer, "%s", (const char *) nullptr);
   ^~~~~~~~~~~~~~
../printf/test/test_suite_main_testcases.hpp: In function ‘void ____C_A_T_C_H____T_E_S_T____1552()’:
../printf/test/test_suite.cpp:88:32: warning: reading through null pointer (argument 4) [-Wformat=]
   printer_(buffer_, __VA_ARGS__);                                \
                                ^
../printf/test/test_suite_main_testcases.hpp:937:3: note: in expansion of macro ‘PRINTING_CHECK’
   PRINTING_CHECK("(null)", ==, sprintf_, buffer, "%.*s", 3, (const char *) NULL);
   ^~~~~~~~~~~~~~
In file included from ../printf/test/test_suite.cpp:412:
../printf/test/test_suite_main_testcases.hpp: In function ‘void ____C_A_T_C_H____T_E_S_T____1582()’:
../printf/test/test_suite_main_testcases.hpp:979:49: warning: reading through null pointer (argument 4) [-Wformat=]
   snprintf_(buffer, 2, "%s", (const char *) NULL);
                                                 ^
[43/540] Compiling C object src/libc.a.p/gdtoa_src_misc.c.o
../src/gdtoa/src/misc.c: In function 'multadd':
../src/gdtoa/src/misc.c:180:10: warning: conversion to 'uint64_t' {aka 'long unsigned int'} from 'long long unsigned int' may change the sign of the result [-Wsign-conversion]
  180 |  carry = (unsigned long long)a;
      |          ^
[163/540] Compiling C object src/libc.a.p/crt_crt.c.o
../src/crt/crt.c:35:1: warning: 'no_stack_protector' attribute directive ignored [-Wattributes]
   35 | {
      | ^
../src/crt/crt.c:60:1: warning: 'no_stack_protector' attribute directive ignored [-Wattributes]
   60 | {
      | ^
[165/540] Compiling C object src/libc.a.p/crt_stack_protection.c.o
../src/crt/stack_protection.c:30:1: warning: 'no_stack_protector' attribute directive ignored [-Wattributes]
   30 | {
      | ^
[168/540] Compiling C object src/libc.a.p/.._arch_aarch64_src_crt0.S.o
FAILED: src/libc.a.p/.._arch_aarch64_src_crt0.S.o
aarch64-none-elf-gcc -Isrc/libc.a.p -Isrc -I../src -I../include -I../src/gdtoa/include -I../arch/aarch64/include -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Wpedantic -std=c11 -O2 -fdiagnostics-show-option -ffunction-sections -fdata-sections -fdevirtualize -Wno-unknown-pragmas -Wno-padded -Wfloat-equal -Wconversion -Wlogical-op -Wundef -Wredundant-decls -Wshadow -Wstrict-overflow=2 -Wwrite-strings -Wpointer-arith -Wcast-qual -Wformat=2 -Wformat-truncation -Wmissing-include-dirs -Wcast-align -Wswitch-enum -Wsign-conversion -Wdisabled-optimization -Winvalid-pch -Wmissing-declarations -Wdouble-promotion -Wshadow -Wtrampolines -Wvector-operation-performance -Wshift-overflow=2 -Wnull-dereference -Wduplicated-cond -Wshift-overflow=2 -Wnull-dereference -Wduplicated-cond -Wcast-align=strict -Wno-nonnull -Wno-nonnull-compare -Wno-pedantic -mcpu=cortex-a53 -fPIC -DPRINTF_ALIAS_STANDARD_FUNCTION_NAMES=1 -DPRINTF_INCLUDE_CONFIG_H=0 -isystem../openlibm/src -isystem../openlibm/include -isystem../printf/src -isystem../printf/src/printf -DNO_ERRNO -DIFNAN_CHECK -DGDTOA_NO_ASSERT -DNO_FENV_H -nostdinc -fno-builtin -MD -MQ src/libc.a.p/.._arch_aarch64_src_crt0.S.o -MF src/libc.a.p/.._arch_aarch64_src_crt0.S.o.d -o src/libc.a.p/.._arch_aarch64_src_crt0.S.o -c ../arch/aarch64/src/crt0.S
../arch/aarch64/src/crt0.S:3:5: warning: "__thumb2__" is not defined, evaluates to 0 [-Wundef]
    3 | #if __thumb2__ || (__thumb__ && !__ARM_ARCH_ISA_ARM)
      |     ^~~~~~~~~~
../arch/aarch64/src/crt0.S:3:20: warning: "__thumb__" is not defined, evaluates to 0 [-Wundef]
    3 | #if __thumb2__ || (__thumb__ && !__ARM_ARCH_ISA_ARM)
      |                    ^~~~~~~~~
../arch/aarch64/src/crt0.S:8:5: warning: "__ARM_ARCH_ISA_THUMB" is not defined, evaluates to 0 [-Wundef]
    8 | #if __ARM_ARCH_ISA_THUMB == 1 && !__ARM_ARCH_ISA_ARM
      |     ^~~~~~~~~~~~~~~~~~~~
../arch/aarch64/src/crt0.S:16:6: warning: "__ARM_ARCH_ISA_ARM" is not defined, evaluates to 0 [-Wundef]
   16 | #if !__ARM_ARCH_ISA_ARM && !__ARM_ARCH_7__
      |      ^~~~~~~~~~~~~~~~~~
../arch/aarch64/src/crt0.S:16:29: warning: "__ARM_ARCH_7__" is not defined, evaluates to 0 [-Wundef]
   16 | #if !__ARM_ARCH_ISA_ARM && !__ARM_ARCH_7__
      |                             ^~~~~~~~~~~~~~
../arch/aarch64/src/crt0.S:217:5: warning: "__thumb__" is not defined, evaluates to 0 [-Wundef]
  217 | #if __thumb__ && !defined(PREFER_THUMB)
      |     ^~~~~~~~~
../arch/aarch64/src/crt0.S: Assembler messages:
../arch/aarch64/src/crt0.S:65: Error: unknown pseudo-op: `.syntax'
../arch/aarch64/src/crt0.S:74: Error: unknown pseudo-op: `.code'
../arch/aarch64/src/crt0.S:95: Error: unknown pseudo-op: `.fnstart'
../arch/aarch64/src/crt0.S:111: Error: operand 1 must be an integer register -- `ldr r3,.Lstack'
../arch/aarch64/src/crt0.S:112: Error: operand 1 must be an integer or stack pointer register -- `cmp r3,#0'
../arch/aarch64/src/crt0.S:121: Error: unknown mnemonic `ldreq' -- `ldreq r3,.LC0'
../arch/aarch64/src/crt0.S:131: Error: operand 1 must be an integer register -- `mrs r2,CPSR'
../arch/aarch64/src/crt0.S:132: Error: operand 1 must be an integer register -- `tst r2,#0x0F'
../arch/aarch64/src/crt0.S:134: Error: unknown or missing system register name at operand 1 -- `msr CPSR_c,#0xD1'
../arch/aarch64/src/crt0.S:136: Error: operand 1 must be an integer or stack pointer register -- `sub sl,sp,#0x1000'
../arch/aarch64/src/crt0.S:138: Error: operand 1 must be an integer register -- `mov r3,sl'
../arch/aarch64/src/crt0.S:139: Error: unknown or missing system register name at operand 1 -- `msr CPSR_c,#0xD7'
../arch/aarch64/src/crt0.S:141: Error: operand 1 must be an integer or stack pointer register -- `sub r3,r3,#0x1000'
../arch/aarch64/src/crt0.S:143: Error: unknown or missing system register name at operand 1 -- `msr CPSR_c,#0xDB'
../arch/aarch64/src/crt0.S:145: Error: operand 1 must be an integer or stack pointer register -- `sub r3,r3,#0x1000'
../arch/aarch64/src/crt0.S:147: Error: unknown or missing system register name at operand 1 -- `msr CPSR_c,#0xD2'
../arch/aarch64/src/crt0.S:149: Error: operand 1 must be an integer or stack pointer register -- `sub r3,r3,#0x2000'
../arch/aarch64/src/crt0.S:151: Error: unknown or missing system register name at operand 1 -- `msr CPSR_c,#0xD3'
../arch/aarch64/src/crt0.S:154: Error: operand 1 must be an integer or stack pointer register -- `sub r3,r3,#0x8000'
../arch/aarch64/src/crt0.S:155: Error: operand 1 must be a SIMD vector register -- `bic r3,r3,#0x00FF'
../arch/aarch64/src/crt0.S:156: Error: operand 1 must be a SIMD vector register -- `bic r3,r3,#0xFF00'
../arch/aarch64/src/crt0.S:158: Error: operand 1 must be an integer register -- `str r3,[r3,#-4]'
../arch/aarch64/src/crt0.S:159: Error: unknown mnemonic `ldmdb' -- `ldmdb r3,{sp}^'
../arch/aarch64/src/crt0.S:160: Error: operand 1 must be a SIMD vector register -- `orr r2,r2,#0xC0'
../arch/aarch64/src/crt0.S:161: Error: unknown or missing system register name at operand 1 -- `msr CPSR_c,r2'
../arch/aarch64/src/crt0.S:177: Error: operand 1 must be an integer or stack pointer register -- `sub sl,r3,#64<<10'
../arch/aarch64/src/crt0.S:206: Error: operand 1 must be an SVE predicate register -- `movs r0,#0'
../arch/aarch64/src/crt0.S:207: Error: operand 1 must be an SVE predicate register -- `movs r1,#0'
../arch/aarch64/src/crt0.S:263: Error: unknown pseudo-op: `.cantunwind'
../arch/aarch64/src/crt0.S:264: Error: unknown pseudo-op: `.fnend'
../arch/aarch64/src/crt0.S:127: Error: undefined symbol r3 used as an immediate value
../arch/aarch64/src/crt0.S:135: Error: undefined symbol r3 used as an immediate value
../arch/aarch64/src/crt0.S:140: Error: undefined symbol r3 used as an immediate value
../arch/aarch64/src/crt0.S:144: Error: undefined symbol r3 used as an immediate value
../arch/aarch64/src/crt0.S:148: Error: undefined symbol r3 used as an immediate value
../arch/aarch64/src/crt0.S:153: Error: undefined symbol r3 used as an immediate value
[173/540] Compiling C object src/libc.a.p/.._printf_src_printf_printf.c.o
ninja: build stopped: subcommand failed.
Makefile:56: recipe for target 'default' failed
make: *** [default] Error 1

As per the the compiler error, it seems that the assembly code in crt0.S is invalid for aarch64.

I then came across the following issues regarding aarch64:

https://github.com/embeddedartistry/libc/issues/133 https://github.com/embeddedartistry/libc/issues/131

Is my understanding correct that this repo isn't ready to be built for aarch64 yet? If it is possible to compile for aarch64, I would really appreciate it if you could let me know how!

phillipjohnston commented 1 year ago

Sorry for the delay. It is not ready, but I thought it was more ready than that. I will need to go over my branches this week, maybe I missed a merge.

phillipjohnston commented 1 year ago

I am also ordering an M1 Mac Mini, so I will have an an aarch64 system to play with soon.

ptrk8 commented 1 year ago

Sorry for the delay. It is not ready, but I thought it was more ready than that. I will need to go over my branches this week, maybe I missed a merge.

No worries! Were you able to find this branch? :)

I am also ordering an M1 Mac Mini, so I will have an an aarch64 system to play with soon.

Exciting! Let me know if you need a hand with testing. I'm pretty keen to have this working on aarch64 mainly because I'd like to use your libcpp library which uses this libc implementation by default. In the meantime, I might try building libcpp with a different libc implementation.

Is the main outstanding item to ensure all the files in arch/aarch64/src contain valid aarch64 assembly code or is there more to getting it to work on aarch64?

klokik commented 1 year ago

Building with clang is fairly broken too

 "/usr/bin/clang-16" -cc1as -triple aarch64-none-unknown-eabi -filetype obj -main-file-name crt0.S -target-cpu cortex-a53 -target-feature +v8a -target-feature +crc -target-feature +crypto -target-feature +fp-armv8 -target-feature +neon -target-feature +sha2 -target-feature +aes -I subprojects/libc/src/libc.a.p -I subprojects/libc/src -I ../subprojects/libc/src -I ../subprojects/libc/include -I ../subprojects/libc/src/gdtoa/include -I ../subprojects/libc/arch/aarch64/include -fdebug-compilation-dir=/home/klokik/Dev/Embedded/bareboot-meson/builddir -dwarf-debug-producer "clang version 16.0.6" -I subprojects/libc/src/libc.a.p -I subprojects/libc/src -I ../subprojects/libc/src -I ../subprojects/libc/include -I ../subprojects/libc/src/gdtoa/include -I ../subprojects/libc/arch/aarch64/include -debug-info-kind=constructor -dwarf-version=5 -mrelocation-model pic -object-file-name=/home/klokik/Dev/Embedded/bareboot-meson/builddir/subprojects/libc/src/libc.a.p/.._arch_aarch64_src_crt0.S.o -o subprojects/libc/src/libc.a.p/.._arch_aarch64_src_crt0.S.o /tmp/crt0-ae5319.s
../subprojects/libc/arch/aarch64/src/crt0.S:65:2: error: unknown directive
 .syntax unified
 ^
../subprojects/libc/arch/aarch64/src/crt0.S:74:2: error: unknown directive
 .code 32
 ^
../subprojects/libc/arch/aarch64/src/crt0.S:95:2: error: unknown directive
 .fnstart
 ^
../subprojects/libc/arch/aarch64/src/crt0.S:111:6: error: invalid operand for instruction
 ldr r3, .Lstack
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:112:6: error: invalid operand for instruction
 cmp r3, #0
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:114:2: error: unrecognized instruction mnemonic, did you mean: ldr?
 ldreq r3, .LC0
 ^
../subprojects/libc/arch/aarch64/src/crt0.S:120:10: error: expected compatible register or logical immediate
 mov sp, r3
         ^
../subprojects/libc/arch/aarch64/src/crt0.S:124:6: error: invalid operand for instruction
 mrs r2, CPSR
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:125:6: error: invalid operand for instruction
 tst r2, #0x0F
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:127:6: error: expected writable system register or pstate
 msr CPSR_c, #0xD1
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:128:10: error: expected compatible register or logical immediate
 mov sp, r3
         ^
../subprojects/libc/arch/aarch64/src/crt0.S:129:6: error: invalid operand for instruction
 sub sl, sp, #0x1000
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:131:6: error: invalid operand for instruction
 mov r3, sl
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:132:6: error: expected writable system register or pstate
 msr CPSR_c, #0xD7
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:133:10: error: expected compatible register or logical immediate
 mov sp, r3
         ^
../subprojects/libc/arch/aarch64/src/crt0.S:134:6: error: invalid operand for instruction
 sub r3, r3, #0x1000
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:136:6: error: expected writable system register or pstate
 msr CPSR_c, #0xDB
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:137:10: error: expected compatible register or logical immediate
 mov sp, r3
         ^
../subprojects/libc/arch/aarch64/src/crt0.S:138:6: error: invalid operand for instruction
 sub r3, r3, #0x1000
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:140:6: error: expected writable system register or pstate
 msr CPSR_c, #0xD2
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:141:10: error: expected compatible register or logical immediate
 mov sp, r3
         ^
../subprojects/libc/arch/aarch64/src/crt0.S:142:6: error: invalid operand for instruction
 sub r3, r3, #0x2000
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:144:6: error: expected writable system register or pstate
 msr CPSR_c, #0xD3
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:146:10: error: expected compatible register or logical immediate
 mov sp, r3
         ^
../subprojects/libc/arch/aarch64/src/crt0.S:147:6: error: invalid operand for instruction
 sub r3, r3, #0x8000
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:148:6: error: invalid operand for instruction
 bic r3, r3, #0x00FF
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:149:6: error: invalid operand for instruction
 bic r3, r3, #0xFF00
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:151:6: error: invalid operand for instruction
 str r3, [r3, #-4]
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:152:13: error: vector register expected
 ldmdb r3, {sp}^
            ^
../subprojects/libc/arch/aarch64/src/crt0.S:152:15: error: unknown token in expression
 ldmdb r3, {sp}^
              ^
../subprojects/libc/arch/aarch64/src/crt0.S:152:15: error: invalid operand
 ldmdb r3, {sp}^
              ^
../subprojects/libc/arch/aarch64/src/crt0.S:153:6: error: invalid operand for instruction
 orr r2, r2, #0xC0
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:154:6: error: expected writable system register or pstate
 msr CPSR_c, r2
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:177:6: error: invalid operand for instruction
 sub sl, r3, #64 << 10
     ^
../subprojects/libc/arch/aarch64/src/crt0.S:180:7: error: invalid operand for instruction
 movs r0, #0
      ^
../subprojects/libc/arch/aarch64/src/crt0.S:181:7: error: invalid operand for instruction
 movs r1, #0
      ^
../subprojects/libc/arch/aarch64/src/crt0.S:263:2: error: unknown directive
 .cantunwind
 ^
../subprojects/libc/arch/aarch64/src/crt0.S:264:2: error: unknown directive
 .fnend
 ^
phillipjohnston commented 1 year ago

I don't expect Clang to be any different really.

Good news is that I received an m2 machine last week, got it set up, and revived my old branch. Have a couple of last issues to get through but expecting to get initial aarch64 support out sometime this week.

phillipjohnston commented 1 year ago

Master now has initial aarch64 support. I have built with XCode's clang, "real" clang, and GCC-13. I haven't tried cross-compilation yet, but I don't anticipate any problems given that it works with GCC on an arm64.

For now, crt0.S is not being built at all. For MacOS, it's not necessary. I'm unclear whether it's really needed on Linux or not - haven't set up a linux environment for testing yet. It would be needed for bare metal, but that would surprise me somewhat if that's what y'all were doing with the arm64 :)