From 485dbe402188e4222b13270fba980b38daf83d1b Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Wed, 20 Aug 2025 19:40:08 +0800 Subject: [PATCH 01/46] cl/instr:asm with two situation --- cl/instr.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cl/instr.go b/cl/instr.go index e988bc01..81c4d325 100644 --- a/cl/instr.go +++ b/cl/instr.go @@ -67,14 +67,18 @@ func cstr(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { } // func asm(string) +// func asmFull(string, map[string]any) uintptr func asm(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { if len(args) == 1 { if sv, ok := constStr(args[0]); ok { b.InlineAsm(sv) return llssa.Expr{Type: b.Prog.Void()} } + } else if len(args) == 2 { + // todo(zzy): Implement asmFull logic here + panic("asmFull: not implemented yet") } - panic("asm(): invalid arguments") + panic("asm: invalid arguments - expected asm() or asm(, )") } // ----------------------------------------------------------------------------- From ae36ef4a0e668a50fd9418319186a85ff31a2a9c Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Wed, 20 Aug 2025 19:40:22 +0800 Subject: [PATCH 02/46] cl/instr:replace register & build constraints --- cl/_testrt/asmfull/in.go | 17 +++++ cl/_testrt/asmfull/out.ll | 155 ++++++++++++++++++++++++++++++++++++++ cl/instr.go | 80 ++++++++++++++++++-- 3 files changed, 247 insertions(+), 5 deletions(-) create mode 100644 cl/_testrt/asmfull/in.go create mode 100644 cl/_testrt/asmfull/out.ll diff --git a/cl/_testrt/asmfull/in.go b/cl/_testrt/asmfull/in.go new file mode 100644 index 00000000..e5068fa2 --- /dev/null +++ b/cl/_testrt/asmfull/in.go @@ -0,0 +1,17 @@ +package main + +import _ "unsafe" + +//go:linkname asm llgo.asm +func asm(instruction string) + +//go:linkname asmFull llgo.asm +func asmFull(instruction string, regs map[string]any) uintptr + +func main() { + asm("nop") + result := asmFull("mov {}, {value}", map[string]any{ + "value": uint32(42), + }) + _ = result +} diff --git a/cl/_testrt/asmfull/out.ll b/cl/_testrt/asmfull/out.ll new file mode 100644 index 00000000..68c62ac6 --- /dev/null +++ b/cl/_testrt/asmfull/out.ll @@ -0,0 +1,155 @@ +; ModuleID = 'github.com/goplus/llgo/cl/_testrt/asmfull' +source_filename = "github.com/goplus/llgo/cl/_testrt/asmfull" + +%"github.com/goplus/llgo/runtime/internal/runtime.eface" = type { ptr, ptr } +%"github.com/goplus/llgo/runtime/internal/runtime.String" = type { ptr, i64 } +%"github.com/goplus/llgo/runtime/internal/runtime.Slice" = type { ptr, i64, i64 } +%"github.com/goplus/llgo/runtime/abi.StructField" = type { %"github.com/goplus/llgo/runtime/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/runtime/internal/runtime.String", i1 } + +@"github.com/goplus/llgo/cl/_testrt/asmfull.init$guard" = global i1 false, align 1 +@_llgo_string = linkonce global ptr null, align 8 +@_llgo_any = linkonce global ptr null, align 8 +@0 = private unnamed_addr constant [41 x i8] c"github.com/goplus/llgo/cl/_testrt/asmfull", align 1 +@"map[_llgo_string]_llgo_any" = linkonce global ptr null, align 8 +@1 = private unnamed_addr constant [7 x i8] c"topbits", align 1 +@2 = private unnamed_addr constant [4 x i8] c"keys", align 1 +@3 = private unnamed_addr constant [5 x i8] c"elems", align 1 +@4 = private unnamed_addr constant [8 x i8] c"overflow", align 1 +@_llgo_uint32 = linkonce global ptr null, align 8 +@5 = private unnamed_addr constant [5 x i8] c"value", align 1 + +define void @"github.com/goplus/llgo/cl/_testrt/asmfull.init"() { +_llgo_0: + %0 = load i1, ptr @"github.com/goplus/llgo/cl/_testrt/asmfull.init$guard", align 1 + br i1 %0, label %_llgo_2, label %_llgo_1 + +_llgo_1: ; preds = %_llgo_0 + store i1 true, ptr @"github.com/goplus/llgo/cl/_testrt/asmfull.init$guard", align 1 + call void @"github.com/goplus/llgo/cl/_testrt/asmfull.init$after"() + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +define void @"github.com/goplus/llgo/cl/_testrt/asmfull.main"() { +_llgo_0: + call void asm sideeffect "nop", ""() + %0 = load ptr, ptr @_llgo_string, align 8 + %1 = load ptr, ptr @_llgo_any, align 8 + %2 = load ptr, ptr @"map[_llgo_string]_llgo_any", align 8 + %3 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.MakeMap"(ptr %2, i64 1) + %4 = load ptr, ptr @_llgo_uint32, align 8 + %5 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" undef, ptr %4, 0 + %6 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" %5, ptr inttoptr (i64 42 to ptr), 1 + %7 = load ptr, ptr @"map[_llgo_string]_llgo_any", align 8 + %8 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 16) + store %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @5, i64 5 }, ptr %8, align 8 + %9 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.MapAssign"(ptr %7, ptr %3, ptr %8) + store %"github.com/goplus/llgo/runtime/internal/runtime.eface" %6, ptr %9, align 8 + ret void +} + +define void @"github.com/goplus/llgo/cl/_testrt/asmfull.init$after"() { +_llgo_0: + %0 = load ptr, ptr @_llgo_string, align 8 + %1 = icmp eq ptr %0, null + br i1 %1, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %2 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Basic"(i64 24) + store ptr %2, ptr @_llgo_string, align 8 + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + %3 = load ptr, ptr @_llgo_any, align 8 + %4 = icmp eq ptr %3, null + br i1 %4, label %_llgo_3, label %_llgo_4 + +_llgo_3: ; preds = %_llgo_2 + %5 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 0) + %6 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %5, 0 + %7 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %6, i64 0, 1 + %8 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %7, i64 0, 2 + %9 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Interface"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @0, i64 41 }, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %8) + store ptr %9, ptr @_llgo_any, align 8 + br label %_llgo_4 + +_llgo_4: ; preds = %_llgo_3, %_llgo_2 + %10 = load ptr, ptr @"map[_llgo_string]_llgo_any", align 8 + %11 = icmp eq ptr %10, null + br i1 %11, label %_llgo_5, label %_llgo_6 + +_llgo_5: ; preds = %_llgo_4 + %12 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Basic"(i64 24) + %13 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 0) + %14 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %13, 0 + %15 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %14, i64 0, 1 + %16 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %15, i64 0, 2 + %17 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Interface"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @0, i64 41 }, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %16) + %18 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Basic"(i64 40) + %19 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.ArrayOf"(i64 8, ptr %18) + %20 = call %"github.com/goplus/llgo/runtime/abi.StructField" @"github.com/goplus/llgo/runtime/internal/runtime.StructField"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @1, i64 7 }, ptr %19, i64 0, %"github.com/goplus/llgo/runtime/internal/runtime.String" zeroinitializer, i1 false) + %21 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Basic"(i64 24) + %22 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.ArrayOf"(i64 8, ptr %21) + %23 = call %"github.com/goplus/llgo/runtime/abi.StructField" @"github.com/goplus/llgo/runtime/internal/runtime.StructField"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @2, i64 4 }, ptr %22, i64 8, %"github.com/goplus/llgo/runtime/internal/runtime.String" zeroinitializer, i1 false) + %24 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 0) + %25 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %24, 0 + %26 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %25, i64 0, 1 + %27 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %26, i64 0, 2 + %28 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Interface"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @0, i64 41 }, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %27) + %29 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.ArrayOf"(i64 8, ptr %28) + %30 = call %"github.com/goplus/llgo/runtime/abi.StructField" @"github.com/goplus/llgo/runtime/internal/runtime.StructField"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @3, i64 5 }, ptr %29, i64 136, %"github.com/goplus/llgo/runtime/internal/runtime.String" zeroinitializer, i1 false) + %31 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Basic"(i64 58) + %32 = call %"github.com/goplus/llgo/runtime/abi.StructField" @"github.com/goplus/llgo/runtime/internal/runtime.StructField"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @4, i64 8 }, ptr %31, i64 264, %"github.com/goplus/llgo/runtime/internal/runtime.String" zeroinitializer, i1 false) + %33 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 224) + %34 = getelementptr %"github.com/goplus/llgo/runtime/abi.StructField", ptr %33, i64 0 + store %"github.com/goplus/llgo/runtime/abi.StructField" %20, ptr %34, align 8 + %35 = getelementptr %"github.com/goplus/llgo/runtime/abi.StructField", ptr %33, i64 1 + store %"github.com/goplus/llgo/runtime/abi.StructField" %23, ptr %35, align 8 + %36 = getelementptr %"github.com/goplus/llgo/runtime/abi.StructField", ptr %33, i64 2 + store %"github.com/goplus/llgo/runtime/abi.StructField" %30, ptr %36, align 8 + %37 = getelementptr %"github.com/goplus/llgo/runtime/abi.StructField", ptr %33, i64 3 + store %"github.com/goplus/llgo/runtime/abi.StructField" %32, ptr %37, align 8 + %38 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" undef, ptr %33, 0 + %39 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %38, i64 4, 1 + %40 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %39, i64 4, 2 + %41 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Struct"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @0, i64 41 }, i64 272, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" %40) + %42 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.MapOf"(ptr %12, ptr %17, ptr %41, i64 12) + call void @"github.com/goplus/llgo/runtime/internal/runtime.SetDirectIface"(ptr %42) + store ptr %42, ptr @"map[_llgo_string]_llgo_any", align 8 + br label %_llgo_6 + +_llgo_6: ; preds = %_llgo_5, %_llgo_4 + %43 = load ptr, ptr @_llgo_uint32, align 8 + %44 = icmp eq ptr %43, null + br i1 %44, label %_llgo_7, label %_llgo_8 + +_llgo_7: ; preds = %_llgo_6 + %45 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Basic"(i64 42) + store ptr %45, ptr @_llgo_uint32, align 8 + br label %_llgo_8 + +_llgo_8: ; preds = %_llgo_7, %_llgo_6 + ret void +} + +declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.Basic"(i64) + +declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.Interface"(%"github.com/goplus/llgo/runtime/internal/runtime.String", %"github.com/goplus/llgo/runtime/internal/runtime.Slice") + +declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64) + +declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.MapOf"(ptr, ptr, ptr, i64) + +declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.Struct"(%"github.com/goplus/llgo/runtime/internal/runtime.String", i64, %"github.com/goplus/llgo/runtime/internal/runtime.Slice") + +declare %"github.com/goplus/llgo/runtime/abi.StructField" @"github.com/goplus/llgo/runtime/internal/runtime.StructField"(%"github.com/goplus/llgo/runtime/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/runtime/internal/runtime.String", i1) + +declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.ArrayOf"(i64, ptr) + +declare void @"github.com/goplus/llgo/runtime/internal/runtime.SetDirectIface"(ptr) + +declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.MakeMap"(ptr, i64) + +declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.MapAssign"(ptr, ptr, ptr) diff --git a/cl/instr.go b/cl/instr.go index 81c4d325..8bea9c25 100644 --- a/cl/instr.go +++ b/cl/instr.go @@ -17,9 +17,12 @@ package cl import ( + "fmt" "go/constant" "go/types" "log" + "regexp" + "strings" "golang.org/x/tools/go/ssa" @@ -67,20 +70,87 @@ func cstr(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { } // func asm(string) -// func asmFull(string, map[string]any) uintptr -func asm(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { +// func asmFull(string, map[string]any) +func (p *context) asm(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { if len(args) == 1 { if sv, ok := constStr(args[0]); ok { b.InlineAsm(sv) return llssa.Expr{Type: b.Prog.Void()} } } else if len(args) == 2 { - // todo(zzy): Implement asmFull logic here - panic("asmFull: not implemented yet") + return p.asmFull(b, args) } panic("asm: invalid arguments - expected asm() or asm(, )") } +// asmFull is a compiler builtin which emits inline assembly. +func (p *context) asmFull(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { + asmString, ok := constStr(args[0]) + if !ok { + panic("asmFull: inline assembly requires a constant string") + } + + registers := make(map[string]llssa.Expr) + if registerMap, ok := args[1].(*ssa.MakeMap); ok { + referrers := registerMap.Referrers() + for _, r := range *referrers { + switch r := r.(type) { + case *ssa.MapUpdate: + if r.Block() != registerMap.Block() { + panic("asmFull: register value map must be created in the same basic block") + } + + key, ok := constStr(r.Key) + if !ok { + panic("asmFull: register key must be a string constant") + } + + llvmValue := p.compileValue(b, r.Value.(*ssa.MakeInterface).X) + registers[key] = llvmValue + } + } + } + + finalAsm := asmString + var hasOutput bool + var inputValues []llssa.Expr + var constraints []string + registerNumbers := map[string]int{} + // todo(zzy):output type + _ = hasOutput + + if strings.Contains(finalAsm, "{}") { + finalAsm = strings.ReplaceAll(finalAsm, "{}", "$0") + constraints = append(constraints, "=&r") + registerNumbers[""] = 0 + hasOutput = true + } + + finalAsm = regexp.MustCompile(`\{[a-zA-Z]+\}`).ReplaceAllStringFunc(finalAsm, func(s string) string { + // TODO: skip strings like {r4} etc. that look like ARM push/pop + // instructions. + name := s[1 : len(s)-1] + value, ok := registers[name] + if !ok { + panic("asmFull: register not found: " + name) + } + if _, ok := registerNumbers[name]; !ok { + registerNumbers[name] = len(registerNumbers) + inputValues = append(inputValues, value) + constraints = append(constraints, "r") + } + return fmt.Sprintf("${%v}", registerNumbers[name]) + }) + + constraintStr := strings.Join(constraints, ",") + if debugInstr { + log.Printf("asmFull: %q -> %q, constraints: %q", asmString, finalAsm, constraintStr) + } + + // todo(zzy): call b.InlineAsmFull + return b.Const(constant.MakeInt64(0x1234), b.Prog.Uintptr()) +} + // ----------------------------------------------------------------------------- // func _Cfunc_CString(s string) *int8 @@ -474,7 +544,7 @@ func (p *context) call(b llssa.Builder, act llssa.DoAction, call *ssa.CallCommon case llgoCstr: ret = cstr(b, args) case llgoAsm: - ret = asm(b, args) + ret = p.asm(b, args) case llgoCgoCString: ret = p.cgoCString(b, args) case llgoCgoCBytes: From f5d4f93ed73a0e2c1e6e0d9727945b51d8476927 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Wed, 20 Aug 2025 20:49:55 +0800 Subject: [PATCH 03/46] ssa:inlineAsmFull --- cl/_testrt/asmfull/in.go | 8 ++------ cl/_testrt/asmfull/out.ll | 23 +++++++++++++++++------ cl/instr.go | 5 +---- ssa/expr.go | 22 ++++++++++++++++++++++ 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/cl/_testrt/asmfull/in.go b/cl/_testrt/asmfull/in.go index e5068fa2..b17d87aa 100644 --- a/cl/_testrt/asmfull/in.go +++ b/cl/_testrt/asmfull/in.go @@ -2,16 +2,12 @@ package main import _ "unsafe" -//go:linkname asm llgo.asm -func asm(instruction string) - //go:linkname asmFull llgo.asm func asmFull(instruction string, regs map[string]any) uintptr func main() { - asm("nop") result := asmFull("mov {}, {value}", map[string]any{ - "value": uint32(42), + "value": 42, }) - _ = result + println("Result:", result) } diff --git a/cl/_testrt/asmfull/out.ll b/cl/_testrt/asmfull/out.ll index 68c62ac6..1839d8bc 100644 --- a/cl/_testrt/asmfull/out.ll +++ b/cl/_testrt/asmfull/out.ll @@ -15,8 +15,9 @@ source_filename = "github.com/goplus/llgo/cl/_testrt/asmfull" @2 = private unnamed_addr constant [4 x i8] c"keys", align 1 @3 = private unnamed_addr constant [5 x i8] c"elems", align 1 @4 = private unnamed_addr constant [8 x i8] c"overflow", align 1 -@_llgo_uint32 = linkonce global ptr null, align 8 +@_llgo_int = linkonce global ptr null, align 8 @5 = private unnamed_addr constant [5 x i8] c"value", align 1 +@6 = private unnamed_addr constant [7 x i8] c"Result:", align 1 define void @"github.com/goplus/llgo/cl/_testrt/asmfull.init"() { _llgo_0: @@ -34,12 +35,11 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 define void @"github.com/goplus/llgo/cl/_testrt/asmfull.main"() { _llgo_0: - call void asm sideeffect "nop", ""() %0 = load ptr, ptr @_llgo_string, align 8 %1 = load ptr, ptr @_llgo_any, align 8 %2 = load ptr, ptr @"map[_llgo_string]_llgo_any", align 8 %3 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.MakeMap"(ptr %2, i64 1) - %4 = load ptr, ptr @_llgo_uint32, align 8 + %4 = load ptr, ptr @_llgo_int, align 8 %5 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" undef, ptr %4, 0 %6 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" %5, ptr inttoptr (i64 42 to ptr), 1 %7 = load ptr, ptr @"map[_llgo_string]_llgo_any", align 8 @@ -47,6 +47,11 @@ _llgo_0: store %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @5, i64 5 }, ptr %8, align 8 %9 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.MapAssign"(ptr %7, ptr %3, ptr %8) store %"github.com/goplus/llgo/runtime/internal/runtime.eface" %6, ptr %9, align 8 + %10 = call i64 asm sideeffect "mov $0, ${1}", "=&r,r"(i64 42) + call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintString"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @6, i64 7 }) + call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8 32) + call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintUint"(i64 %10) + call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8 10) ret void } @@ -121,13 +126,13 @@ _llgo_5: ; preds = %_llgo_4 br label %_llgo_6 _llgo_6: ; preds = %_llgo_5, %_llgo_4 - %43 = load ptr, ptr @_llgo_uint32, align 8 + %43 = load ptr, ptr @_llgo_int, align 8 %44 = icmp eq ptr %43, null br i1 %44, label %_llgo_7, label %_llgo_8 _llgo_7: ; preds = %_llgo_6 - %45 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Basic"(i64 42) - store ptr %45, ptr @_llgo_uint32, align 8 + %45 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.Basic"(i64 34) + store ptr %45, ptr @_llgo_int, align 8 br label %_llgo_8 _llgo_8: ; preds = %_llgo_7, %_llgo_6 @@ -153,3 +158,9 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.SetDirectIface"(p declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.MakeMap"(ptr, i64) declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.MapAssign"(ptr, ptr, ptr) + +declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintString"(%"github.com/goplus/llgo/runtime/internal/runtime.String") + +declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8) + +declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintUint"(i64) diff --git a/cl/instr.go b/cl/instr.go index 8bea9c25..5945eb56 100644 --- a/cl/instr.go +++ b/cl/instr.go @@ -116,8 +116,6 @@ func (p *context) asmFull(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { var inputValues []llssa.Expr var constraints []string registerNumbers := map[string]int{} - // todo(zzy):output type - _ = hasOutput if strings.Contains(finalAsm, "{}") { finalAsm = strings.ReplaceAll(finalAsm, "{}", "$0") @@ -147,8 +145,7 @@ func (p *context) asmFull(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { log.Printf("asmFull: %q -> %q, constraints: %q", asmString, finalAsm, constraintStr) } - // todo(zzy): call b.InlineAsmFull - return b.Const(constant.MakeInt64(0x1234), b.Prog.Uintptr()) + return b.InlineAsmFull(finalAsm, constraintStr, hasOutput, inputValues) } // ----------------------------------------------------------------------------- diff --git a/ssa/expr.go b/ssa/expr.go index 6f98cb38..8a34e6b6 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -286,6 +286,28 @@ func (b Builder) InlineAsm(instruction string) { b.impl.CreateCall(typ, asm, nil, "") } +func (b Builder) InlineAsmFull(instruction, constraints string, output bool, exprs []Expr) (ret Expr) { + var rtType llvm.Type + if output { + rtType = b.Prog.Uintptr().ll + } else { + rtType = b.Prog.tyVoid() + } + + typs := make([]llvm.Type, len(exprs)) + vals := make([]llvm.Value, len(exprs)) + for i, expr := range exprs { + typs[i] = expr.Type.ll + vals[i] = expr.impl + } + + typ := llvm.FunctionType(rtType, typs, false) + asm := llvm.InlineAsm(typ, instruction, constraints, true, false, llvm.InlineAsmDialectATT, false) + ret.Type = b.Prog.Uintptr() + ret.impl = b.impl.CreateCall(typ, asm, vals, "") + return +} + // GoString returns a Go string func (b Builder) GoString(v Expr) Expr { fn := b.Pkg.rtFunc("GoString") From 9e0c50dafe216c51c826452c4dee07157bb5b1ea Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Wed, 20 Aug 2025 23:06:11 +0800 Subject: [PATCH 04/46] cl/instr:asmFull test case with input only --- cl/_testrt/asmfull/in.go | 1 + cl/_testrt/asmfull/out.ll | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/cl/_testrt/asmfull/in.go b/cl/_testrt/asmfull/in.go index b17d87aa..473018ac 100644 --- a/cl/_testrt/asmfull/in.go +++ b/cl/_testrt/asmfull/in.go @@ -6,6 +6,7 @@ import _ "unsafe" func asmFull(instruction string, regs map[string]any) uintptr func main() { + asmFull("# test value {value}", map[string]any{"value": 42}) result := asmFull("mov {}, {value}", map[string]any{ "value": 42, }) diff --git a/cl/_testrt/asmfull/out.ll b/cl/_testrt/asmfull/out.ll index 1839d8bc..f83c2c2f 100644 --- a/cl/_testrt/asmfull/out.ll +++ b/cl/_testrt/asmfull/out.ll @@ -47,10 +47,21 @@ _llgo_0: store %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @5, i64 5 }, ptr %8, align 8 %9 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.MapAssign"(ptr %7, ptr %3, ptr %8) store %"github.com/goplus/llgo/runtime/internal/runtime.eface" %6, ptr %9, align 8 - %10 = call i64 asm sideeffect "mov $0, ${1}", "=&r,r"(i64 42) + call void asm sideeffect "# test value ${0}", "r"(i64 42) + %10 = load ptr, ptr @"map[_llgo_string]_llgo_any", align 8 + %11 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.MakeMap"(ptr %10, i64 1) + %12 = load ptr, ptr @_llgo_int, align 8 + %13 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" undef, ptr %12, 0 + %14 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" %13, ptr inttoptr (i64 42 to ptr), 1 + %15 = load ptr, ptr @"map[_llgo_string]_llgo_any", align 8 + %16 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 16) + store %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @5, i64 5 }, ptr %16, align 8 + %17 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.MapAssign"(ptr %15, ptr %11, ptr %16) + store %"github.com/goplus/llgo/runtime/internal/runtime.eface" %14, ptr %17, align 8 + %18 = call i64 asm sideeffect "mov $0, ${1}", "=&r,r"(i64 42) call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintString"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @6, i64 7 }) call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8 32) - call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintUint"(i64 %10) + call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintUint"(i64 %18) call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8 10) ret void } From 6beb50b3676e80940d36f3b5cb5bac1c50b6095c Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Wed, 20 Aug 2025 23:43:25 +0800 Subject: [PATCH 05/46] cl/instr:asmFull test case with multiple input & output --- cl/_testrt/asmfull/in.go | 17 +++++++++++++++-- cl/_testrt/asmfull/out.ll | 26 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/cl/_testrt/asmfull/in.go b/cl/_testrt/asmfull/in.go index 473018ac..4bfa5933 100644 --- a/cl/_testrt/asmfull/in.go +++ b/cl/_testrt/asmfull/in.go @@ -6,9 +6,22 @@ import _ "unsafe" func asmFull(instruction string, regs map[string]any) uintptr func main() { + // no input,no return value + asmFull("nop", nil) + // input only,no return value asmFull("# test value {value}", map[string]any{"value": 42}) - result := asmFull("mov {}, {value}", map[string]any{ + // input with return value + res1 := asmFull("mov {}, {value}", map[string]any{ "value": 42, }) - println("Result:", result) + println("Result:", res1) + // note(zzy): multiple inputs with return value + // only for test register & constraint,not have actual meaning + // the ir compare cannot crossplatform currently + // so just use a comment to test it + res2 := asmFull("# calc {x} + {y} -> {}", map[string]any{ + "x": 25, + "y": 17, + }) + println("Result:", res2) } diff --git a/cl/_testrt/asmfull/out.ll b/cl/_testrt/asmfull/out.ll index f83c2c2f..e7fcf275 100644 --- a/cl/_testrt/asmfull/out.ll +++ b/cl/_testrt/asmfull/out.ll @@ -18,6 +18,8 @@ source_filename = "github.com/goplus/llgo/cl/_testrt/asmfull" @_llgo_int = linkonce global ptr null, align 8 @5 = private unnamed_addr constant [5 x i8] c"value", align 1 @6 = private unnamed_addr constant [7 x i8] c"Result:", align 1 +@7 = private unnamed_addr constant [1 x i8] c"x", align 1 +@8 = private unnamed_addr constant [1 x i8] c"y", align 1 define void @"github.com/goplus/llgo/cl/_testrt/asmfull.init"() { _llgo_0: @@ -35,6 +37,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 define void @"github.com/goplus/llgo/cl/_testrt/asmfull.main"() { _llgo_0: + call void asm sideeffect "nop", ""() %0 = load ptr, ptr @_llgo_string, align 8 %1 = load ptr, ptr @_llgo_any, align 8 %2 = load ptr, ptr @"map[_llgo_string]_llgo_any", align 8 @@ -63,6 +66,29 @@ _llgo_0: call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintUint"(i64 %18) call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8 10) + %19 = load ptr, ptr @"map[_llgo_string]_llgo_any", align 8 + %20 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.MakeMap"(ptr %19, i64 2) + %21 = load ptr, ptr @_llgo_int, align 8 + %22 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" undef, ptr %21, 0 + %23 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" %22, ptr inttoptr (i64 25 to ptr), 1 + %24 = load ptr, ptr @"map[_llgo_string]_llgo_any", align 8 + %25 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 16) + store %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @7, i64 1 }, ptr %25, align 8 + %26 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.MapAssign"(ptr %24, ptr %20, ptr %25) + store %"github.com/goplus/llgo/runtime/internal/runtime.eface" %23, ptr %26, align 8 + %27 = load ptr, ptr @_llgo_int, align 8 + %28 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" undef, ptr %27, 0 + %29 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" %28, ptr inttoptr (i64 17 to ptr), 1 + %30 = load ptr, ptr @"map[_llgo_string]_llgo_any", align 8 + %31 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 16) + store %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @8, i64 1 }, ptr %31, align 8 + %32 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.MapAssign"(ptr %30, ptr %20, ptr %31) + store %"github.com/goplus/llgo/runtime/internal/runtime.eface" %29, ptr %32, align 8 + %33 = call i64 asm sideeffect "# calc ${1} + ${2} -> $0", "=&r,r,r"(i64 25, i64 17) + call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintString"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @6, i64 7 }) + call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8 32) + call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintUint"(i64 %33) + call void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8 10) ret void } From 9dfc6d1d52010f8ad117a3662a5f7d19be2d3175 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 21 Aug 2025 00:15:59 +0800 Subject: [PATCH 06/46] ssa:refine asmFull interface --- cl/instr.go | 9 ++++++++- ssa/expr.go | 20 +++++--------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/cl/instr.go b/cl/instr.go index 5945eb56..5ea09e9a 100644 --- a/cl/instr.go +++ b/cl/instr.go @@ -145,7 +145,14 @@ func (p *context) asmFull(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { log.Printf("asmFull: %q -> %q, constraints: %q", asmString, finalAsm, constraintStr) } - return b.InlineAsmFull(finalAsm, constraintStr, hasOutput, inputValues) + var retType llssa.Type + if hasOutput { + retType = b.Prog.Uintptr() + } else { + retType = b.Prog.Void() + } + + return b.InlineAsmFull(finalAsm, constraintStr, retType, inputValues) } // ----------------------------------------------------------------------------- diff --git a/ssa/expr.go b/ssa/expr.go index 8a34e6b6..b9dafca0 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -286,26 +286,16 @@ func (b Builder) InlineAsm(instruction string) { b.impl.CreateCall(typ, asm, nil, "") } -func (b Builder) InlineAsmFull(instruction, constraints string, output bool, exprs []Expr) (ret Expr) { - var rtType llvm.Type - if output { - rtType = b.Prog.Uintptr().ll - } else { - rtType = b.Prog.tyVoid() - } - +func (b Builder) InlineAsmFull(instruction, constraints string, retType Type, exprs []Expr) Expr { typs := make([]llvm.Type, len(exprs)) vals := make([]llvm.Value, len(exprs)) for i, expr := range exprs { - typs[i] = expr.Type.ll - vals[i] = expr.impl + typs[i], vals[i] = expr.Type.ll, expr.impl } - typ := llvm.FunctionType(rtType, typs, false) - asm := llvm.InlineAsm(typ, instruction, constraints, true, false, llvm.InlineAsmDialectATT, false) - ret.Type = b.Prog.Uintptr() - ret.impl = b.impl.CreateCall(typ, asm, vals, "") - return + ftype := llvm.FunctionType(retType.ll, typs, false) + asm := llvm.InlineAsm(ftype, instruction, constraints, true, false, llvm.InlineAsmDialectATT, false) + return Expr{b.impl.CreateCall(ftype, asm, vals, ""), retType} } // GoString returns a Go string From b428a8af0800da6e83022c89700e2f74295d389a Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 21 Aug 2025 11:04:03 +0800 Subject: [PATCH 07/46] test:asmFull function test --- _demo/asmfullcall/asmfullcall.go | 21 +++++++++++++++++ _demo/asmfullcall/asmfullcall_darwin.go | 31 +++++++++++++++++++++++++ _demo/asmfullcall/asmfullcall_linux.go | 4 ++++ 3 files changed, 56 insertions(+) create mode 100644 _demo/asmfullcall/asmfullcall.go create mode 100644 _demo/asmfullcall/asmfullcall_darwin.go create mode 100644 _demo/asmfullcall/asmfullcall_linux.go diff --git a/_demo/asmfullcall/asmfullcall.go b/_demo/asmfullcall/asmfullcall.go new file mode 100644 index 00000000..5ced4d85 --- /dev/null +++ b/_demo/asmfullcall/asmfullcall.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" +) + +//llgo:link asmFull llgo.asm +func asmFull(instruction string, regs map[string]any) uintptr { return 0 } + +var testVar = 0 + +func main() { + verify() +} + +func check(expected, actual int) { + if expected != actual { + panic(fmt.Sprintf("Expected: %d, Got: %d\n", expected, actual)) + } + fmt.Println("asm check passed:", actual) +} diff --git a/_demo/asmfullcall/asmfullcall_darwin.go b/_demo/asmfullcall/asmfullcall_darwin.go new file mode 100644 index 00000000..5e537a21 --- /dev/null +++ b/_demo/asmfullcall/asmfullcall_darwin.go @@ -0,0 +1,31 @@ +//go:build darwin + +package main + +import "unsafe" + +func verify() { + // 0 output & 0 input + asmFull("nop", nil) + + // 0 output & 1 input with memory address + addr := uintptr(unsafe.Pointer(&testVar)) + asmFull("str {value}, [{addr}]", map[string]any{ + "addr": addr, + "value": 43, + }) + check(43, testVar) + + // 1 output & 1 input + res1 := asmFull("mov {}, {value}", map[string]any{ + "value": 41, + }) + check(41, int(res1)) + + // 1 output & 2 inputs + res2 := asmFull("add {}, {a}, {b}", map[string]any{ + "a": 25, + "b": 17, + }) + check(42, int(res2)) +} diff --git a/_demo/asmfullcall/asmfullcall_linux.go b/_demo/asmfullcall/asmfullcall_linux.go new file mode 100644 index 00000000..b0e60f75 --- /dev/null +++ b/_demo/asmfullcall/asmfullcall_linux.go @@ -0,0 +1,4 @@ +package main + +func verify() { +} From ef1f2bce49b3c25187b4c8d8490983d1b2a18c7c Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 21 Aug 2025 11:46:56 +0800 Subject: [PATCH 08/46] test:linux asmFull function test --- _demo/asmfullcall/asmfullcall_linux.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/_demo/asmfullcall/asmfullcall_linux.go b/_demo/asmfullcall/asmfullcall_linux.go index b0e60f75..8c485c63 100644 --- a/_demo/asmfullcall/asmfullcall_linux.go +++ b/_demo/asmfullcall/asmfullcall_linux.go @@ -1,4 +1,30 @@ +//go:build linux + package main +import "unsafe" + func verify() { + // 0 output & 0 input + asmFull("nop", nil) + + // 0 output & 1 input with memory address + addr := uintptr(unsafe.Pointer(&testVar)) + asmFull("movq {value}, ({addr})", map[string]any{ + "addr": addr, + "value": 43, + }) + check(43, testVar) + + // 1 output & 1 input + res1 := asmFull("movq {value}, {}", map[string]any{ + "value": 41, + }) + check(41, int(res1)) + + res2 := asmFull("movq {a}, {}; addq {b}, {}", map[string]any{ + "a": 25, + "b": 17, + }) + check(42, int(res2)) } From d548671b91a0b723a0605c053b09fabe8e432a45 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 21 Aug 2025 14:25:37 +0800 Subject: [PATCH 09/46] test:linux with leaq to confirm asmFull --- _demo/asmfullcall/asmfullcall_darwin.go | 2 +- _demo/asmfullcall/asmfullcall_linux.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_demo/asmfullcall/asmfullcall_darwin.go b/_demo/asmfullcall/asmfullcall_darwin.go index 5e537a21..3f1fbcbd 100644 --- a/_demo/asmfullcall/asmfullcall_darwin.go +++ b/_demo/asmfullcall/asmfullcall_darwin.go @@ -1,4 +1,4 @@ -//go:build darwin +//go:build darwin && arm64 package main diff --git a/_demo/asmfullcall/asmfullcall_linux.go b/_demo/asmfullcall/asmfullcall_linux.go index 8c485c63..6a3f4a79 100644 --- a/_demo/asmfullcall/asmfullcall_linux.go +++ b/_demo/asmfullcall/asmfullcall_linux.go @@ -1,4 +1,4 @@ -//go:build linux +//go:build linux && amd64 package main @@ -22,7 +22,7 @@ func verify() { }) check(41, int(res1)) - res2 := asmFull("movq {a}, {}; addq {b}, {}", map[string]any{ + res2 := asmFull("leaq ({a},{b}), {}", map[string]any{ "a": 25, "b": 17, }) From 26fb156d6b59d8be2f4875a798daffb31af8bdfd Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 21 Aug 2025 16:30:52 +0800 Subject: [PATCH 10/46] cl/instr:only permit interger at asmfull --- cl/instr.go | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/cl/instr.go b/cl/instr.go index 5ea09e9a..82c3b620 100644 --- a/cl/instr.go +++ b/cl/instr.go @@ -133,9 +133,24 @@ func (p *context) asmFull(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { panic("asmFull: register not found: " + name) } if _, ok := registerNumbers[name]; !ok { - registerNumbers[name] = len(registerNumbers) - inputValues = append(inputValues, value) - constraints = append(constraints, "r") + // Type checking based on Go types - similar to TinyGo's implementation + rawType := value.Type.RawType() + switch typ := rawType.Underlying().(type) { + case *types.Basic: + if typ.Info()&types.IsInteger != 0 { + registerNumbers[name] = len(registerNumbers) + inputValues = append(inputValues, value) + constraints = append(constraints, "r") + } else { + panic("asmFull: unsupported basic type in inline assembly for operand: " + name + ", only integer types are supported") + } + case *types.Pointer: + // Pointer operands support was dropped, following TinyGo 0.23 + panic("asmFull: not support for pointer operands: " + name + ", only integer types are supported") + default: + panic("asmFull: unsupported type in inline assembly for operand: " + name + ", only integer types are supported") + } + } return fmt.Sprintf("${%v}", registerNumbers[name]) }) From f6bc5ac53834edeb111e3f91ac4bb7e9794c167e Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 21 Aug 2025 19:20:09 +0800 Subject: [PATCH 11/46] cl/instr:regexp compile one time --- cl/instr.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cl/instr.go b/cl/instr.go index 82c3b620..42c8ab9e 100644 --- a/cl/instr.go +++ b/cl/instr.go @@ -29,6 +29,8 @@ import ( llssa "github.com/goplus/llgo/ssa" ) +var asmRegisterRegex = regexp.MustCompile(`\{[a-zA-Z]+\}`) + // ----------------------------------------------------------------------------- func constStr(v ssa.Value) (ret string, ok bool) { @@ -124,7 +126,7 @@ func (p *context) asmFull(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { hasOutput = true } - finalAsm = regexp.MustCompile(`\{[a-zA-Z]+\}`).ReplaceAllStringFunc(finalAsm, func(s string) string { + finalAsm = asmRegisterRegex.ReplaceAllStringFunc(finalAsm, func(s string) string { // TODO: skip strings like {r4} etc. that look like ARM push/pop // instructions. name := s[1 : len(s)-1] From 0faef117cac5ed6c0098362942f756ade360a5f8 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 21 Aug 2025 19:57:49 +0800 Subject: [PATCH 12/46] cl/instr:refine register collect --- cl/instr.go | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/cl/instr.go b/cl/instr.go index 42c8ab9e..6f1221a3 100644 --- a/cl/instr.go +++ b/cl/instr.go @@ -97,18 +97,20 @@ func (p *context) asmFull(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { referrers := registerMap.Referrers() for _, r := range *referrers { switch r := r.(type) { + case *ssa.DebugRef, *ssa.Call: + // ignore case *ssa.MapUpdate: if r.Block() != registerMap.Block() { panic("asmFull: register value map must be created in the same basic block") } - key, ok := constStr(r.Key) if !ok { panic("asmFull: register key must be a string constant") } - llvmValue := p.compileValue(b, r.Value.(*ssa.MakeInterface).X) registers[key] = llvmValue + default: + panic("asmFull: don't know how to handle argument to inline assembly: " + r.String()) } } } @@ -135,24 +137,16 @@ func (p *context) asmFull(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { panic("asmFull: register not found: " + name) } if _, ok := registerNumbers[name]; !ok { - // Type checking based on Go types - similar to TinyGo's implementation + // Type checking - only allow integer basic types rawType := value.Type.RawType() - switch typ := rawType.Underlying().(type) { - case *types.Basic: - if typ.Info()&types.IsInteger != 0 { - registerNumbers[name] = len(registerNumbers) - inputValues = append(inputValues, value) - constraints = append(constraints, "r") - } else { - panic("asmFull: unsupported basic type in inline assembly for operand: " + name + ", only integer types are supported") - } - case *types.Pointer: + if basic, ok := rawType.Underlying().(*types.Basic); ok && basic.Info()&types.IsInteger != 0 { + registerNumbers[name] = len(registerNumbers) + inputValues = append(inputValues, value) + constraints = append(constraints, "r") + } else { // Pointer operands support was dropped, following TinyGo 0.23 - panic("asmFull: not support for pointer operands: " + name + ", only integer types are supported") - default: panic("asmFull: unsupported type in inline assembly for operand: " + name + ", only integer types are supported") } - } return fmt.Sprintf("${%v}", registerNumbers[name]) }) From 04f613dd154445cf43ec7bc5fbc9e8d5c0d28a86 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 21 Aug 2025 20:55:20 +0800 Subject: [PATCH 13/46] cl/test:asmFull error --- cl/builtin_test.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/cl/builtin_test.go b/cl/builtin_test.go index dfadaabb..a07e5f39 100644 --- a/cl/builtin_test.go +++ b/cl/builtin_test.go @@ -270,6 +270,52 @@ func TestErrBuiltin(t *testing.T) { test("atomicCmpXchg", func(ctx *context) { ctx.atomicCmpXchg(nil, nil) }) } +func TestErrAsm(t *testing.T) { + test := func(testName string, fn func(ctx *context)) { + defer func() { + if r := recover(); r == nil { + t.Fatal(testName, ": no error?") + } + }() + var ctx context + fn(&ctx) + } + + test("asm(NoArgs)", func(ctx *context) { ctx.asm(nil, []ssa.Value{}) }) + test("asm(Nonconst)", func(ctx *context) { ctx.asm(nil, []ssa.Value{&ssa.Parameter{}}) }) + test("asmFull(Nonconst)", func(ctx *context) { ctx.asm(nil, []ssa.Value{&ssa.Parameter{}, &ssa.Parameter{}}) }) + test("asmFull(NonConstKey)", func(ctx *context) { + makeMap := &ssa.MakeMap{} + nonConstKey := &ssa.Parameter{} + mapUpdate := &ssa.MapUpdate{Key: nonConstKey} + referrers := []ssa.Instruction{mapUpdate} + setRefs(unsafe.Pointer(makeMap), referrers...) + strConst := &ssa.Const{ + Value: constant.MakeString("nop"), + } + ctx.asm(nil, []ssa.Value{strConst, makeMap}) + }) + test("asmFull(RegisterNotFound)", func(ctx *context) { + makeMap := &ssa.MakeMap{} + referrers := []ssa.Instruction{} + setRefs(unsafe.Pointer(makeMap), referrers...) + strConst := &ssa.Const{ + Value: constant.MakeString("test {missing}"), + } + ctx.asm(nil, []ssa.Value{strConst, makeMap}) + }) + test("asmFull(UnknownReferrer)", func(ctx *context) { + makeMap := &ssa.MakeMap{} + unknownRef := &ssa.Return{} + referrers := []ssa.Instruction{unknownRef} + setRefs(unsafe.Pointer(makeMap), referrers...) + strConst := &ssa.Const{ + Value: constant.MakeString("test"), + } + ctx.asm(nil, []ssa.Value{strConst, makeMap}) + }) +} + func TestPkgNoInit(t *testing.T) { pkg := types.NewPackage("foo", "foo") ctx := &context{ From d9dc4d5943236dfc7c5ccee6f321ce35b8e0e781 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 21 Aug 2025 23:24:24 +0800 Subject: [PATCH 14/46] cl/instr:move to one asm --- cl/instr.go | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/cl/instr.go b/cl/instr.go index 6f1221a3..34e9c65a 100644 --- a/cl/instr.go +++ b/cl/instr.go @@ -72,24 +72,19 @@ func cstr(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { } // func asm(string) -// func asmFull(string, map[string]any) +// func asm(string, map[string]any) func (p *context) asm(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { - if len(args) == 1 { - if sv, ok := constStr(args[0]); ok { - b.InlineAsm(sv) - return llssa.Expr{Type: b.Prog.Void()} - } - } else if len(args) == 2 { - return p.asmFull(b, args) + if len(args) == 0 || len(args) > 2 { + panic("asm: invalid arguments - expected asm() or asm(, )") } - panic("asm: invalid arguments - expected asm() or asm(, )") -} -// asmFull is a compiler builtin which emits inline assembly. -func (p *context) asmFull(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { asmString, ok := constStr(args[0]) if !ok { - panic("asmFull: inline assembly requires a constant string") + panic("asm: inline assembly requires a constant string") + } + if len(args) == 1 { + b.InlineAsm(asmString) + return llssa.Expr{Type: b.Prog.Void()} } registers := make(map[string]llssa.Expr) @@ -101,16 +96,16 @@ func (p *context) asmFull(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { // ignore case *ssa.MapUpdate: if r.Block() != registerMap.Block() { - panic("asmFull: register value map must be created in the same basic block") + panic("asm: register value map must be created in the same basic block") } key, ok := constStr(r.Key) if !ok { - panic("asmFull: register key must be a string constant") + panic("asm: register key must be a string constant") } llvmValue := p.compileValue(b, r.Value.(*ssa.MakeInterface).X) registers[key] = llvmValue default: - panic("asmFull: don't know how to handle argument to inline assembly: " + r.String()) + panic(fmt.Sprintf("asm: don't know how to handle argument to inline assembly: %s", r.String())) } } } @@ -134,7 +129,7 @@ func (p *context) asmFull(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { name := s[1 : len(s)-1] value, ok := registers[name] if !ok { - panic("asmFull: register not found: " + name) + panic(fmt.Sprintf("asm: register not found: %s", name)) } if _, ok := registerNumbers[name]; !ok { // Type checking - only allow integer basic types @@ -145,7 +140,7 @@ func (p *context) asmFull(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { constraints = append(constraints, "r") } else { // Pointer operands support was dropped, following TinyGo 0.23 - panic("asmFull: unsupported type in inline assembly for operand: " + name + ", only integer types are supported") + panic(fmt.Sprintf("asm: unsupported type in inline assembly for operand: %s, only integer types are supported", name)) } } return fmt.Sprintf("${%v}", registerNumbers[name]) @@ -153,7 +148,7 @@ func (p *context) asmFull(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { constraintStr := strings.Join(constraints, ",") if debugInstr { - log.Printf("asmFull: %q -> %q, constraints: %q", asmString, finalAsm, constraintStr) + log.Printf("asm: %q -> %q, constraints: %q", asmString, finalAsm, constraintStr) } var retType llssa.Type From 49b9b92790ba6541776720a70a3f6bf2a67955b5 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Fri, 22 Aug 2025 15:01:59 +0800 Subject: [PATCH 15/46] ci/instr:fix asmFull return type to match function signature when no output --- cl/instr.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/cl/instr.go b/cl/instr.go index 34e9c65a..9a39b7e4 100644 --- a/cl/instr.go +++ b/cl/instr.go @@ -151,14 +151,13 @@ func (p *context) asm(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { log.Printf("asm: %q -> %q, constraints: %q", asmString, finalAsm, constraintStr) } - var retType llssa.Type - if hasOutput { - retType = b.Prog.Uintptr() - } else { - retType = b.Prog.Void() + if !hasOutput { + // Make sure we return something valid + b.InlineAsmFull(finalAsm, constraintStr, b.Prog.Void(), inputValues) + return b.Prog.Val((uintptr(0))) } - return b.InlineAsmFull(finalAsm, constraintStr, retType, inputValues) + return b.InlineAsmFull(finalAsm, constraintStr, b.Prog.Uintptr(), inputValues) } // ----------------------------------------------------------------------------- From f3de14da4ba488218657c6af727d70b7ea429831 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Fri, 22 Aug 2025 16:14:51 +0800 Subject: [PATCH 16/46] cl/instr:note for why asm not support pointer type: --- cl/instr.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cl/instr.go b/cl/instr.go index 9a39b7e4..5dabd5f8 100644 --- a/cl/instr.go +++ b/cl/instr.go @@ -139,7 +139,8 @@ func (p *context) asm(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { inputValues = append(inputValues, value) constraints = append(constraints, "r") } else { - // Pointer operands support was dropped, following TinyGo 0.23 + // Pointer operands support was dropped, following TinyGo + // NOTE(tinygo): Memory references require a type starting with LLVM 14, probably as a preparation for opaque pointers. panic(fmt.Sprintf("asm: unsupported type in inline assembly for operand: %s, only integer types are supported", name)) } } From 5587fd2885c9bf29f47f5c20d6946385bb444387 Mon Sep 17 00:00:00 2001 From: Haolan Date: Mon, 25 Aug 2025 19:05:30 +0800 Subject: [PATCH 17/46] feat: add libc --- internal/crosscompile/crosscompile.go | 76 +++++++++++ internal/crosscompile/fetch.go | 42 ++++++ internal/crosscompile/libc.go | 185 ++++++++++++++++++++++++++ internal/targets/config.go | 1 + internal/targets/loader.go | 3 + targets/esp32.ld | 14 +- targets/esp32.rom.newlib-data.ld | 23 ++++ targets/esp32.rom.newlib-funcs.ld | 130 ++++++++++++++++++ targets/esp32.rom.newlib-locale.ld | 19 +++ targets/esp32.rom.newlib-nano.ld | 115 ++++++++++++++++ targets/esp32.rom.newlib-time.ld | 38 ++++++ 11 files changed, 638 insertions(+), 8 deletions(-) create mode 100644 internal/crosscompile/libc.go create mode 100644 targets/esp32.rom.newlib-data.ld create mode 100644 targets/esp32.rom.newlib-funcs.ld create mode 100644 targets/esp32.rom.newlib-locale.ld create mode 100644 targets/esp32.rom.newlib-nano.ld create mode 100644 targets/esp32.rom.newlib-time.ld diff --git a/internal/crosscompile/crosscompile.go b/internal/crosscompile/crosscompile.go index e5f302e3..a4581832 100644 --- a/internal/crosscompile/crosscompile.go +++ b/internal/crosscompile/crosscompile.go @@ -8,8 +8,11 @@ import ( "os/exec" "path/filepath" "runtime" + "slices" "strings" + "github.com/goplus/llgo/internal/clang" + "github.com/goplus/llgo/internal/env" "github.com/goplus/llgo/internal/targets" "github.com/goplus/llgo/internal/xtool/llvm" @@ -215,6 +218,70 @@ func getESPClangPlatform(goos, goarch string) string { return "" } +func getOrCompileLibc(cc, linkerName, libcName string, ccflags, exportLdFlags []string) (ldflags []string, err error) { + baseDir := filepath.Join(cacheRoot(), "crosscompile") + libcDir := filepath.Join(baseDir, libcName) + libcArchive := filepath.Join(libcDir, "libc.a") + // fast-path: compiled already + if _, err = os.Stat(libcArchive); !os.IsNotExist(err) { + ldflags = append(ldflags, "-nostdlib", "-L", libcDir, "-lc") + return ldflags, nil + } + compileConfig, err := getCompileLibcConfigByName(baseDir, libcName) + if err != nil { + return + } + tempDir, err := os.MkdirTemp("", "compile*") + if err != nil { + return + } + defer os.RemoveAll(tempDir) + + fmt.Fprintf(os.Stderr, "%s not found in LLGO_ROOT or cache, will download and compile.\n", libcDir) + if err = checkDownloadAndExtractLibc(compileConfig.Url, libcDir, compileConfig.ArchiveSrcDir); err != nil { + return + } + compileLDFlags := append(slices.Clone(exportLdFlags), compileConfig.LDFlags...) + + cfg := clang.NewConfig(cc, ccflags, compileConfig.CFlags, compileLDFlags, linkerName) + + var objFiles []string + + compiler := clang.NewCompiler(cfg) + linker := clang.NewLinker(cfg) + + compiler.Verbose = true + linker.Verbose = true + fmt.Fprintf(os.Stderr, "Start to compile libc %s to %s...\n", libcName, libcArchive) + + for _, file := range compileConfig.Files { + var tempObjFile *os.File + tempObjFile, err = os.CreateTemp(tempDir, "libc*.o") + if err != nil { + return + } + fmt.Fprintf(os.Stderr, "Compile libc file %s to %s...\n", file, tempObjFile.Name()) + + err = compiler.Compile("-o", tempObjFile.Name(), "-x", "c", "-c", file) + if err != nil { + return + } + + objFiles = append(objFiles, tempObjFile.Name()) + } + + args := []string{"-o", libcArchive} + args = append(args, objFiles...) + + err = linker.Link(args...) + if err != nil { + return + } + ldflags = append(ldflags, "-nostdlib", "-L", libcDir, "-lc") + + return +} + func use(goos, goarch string, wasiThreads bool) (export Export, err error) { targetTriple := llvm.GetTargetTriple(goos, goarch) llgoRoot := env.LLGoROOT() @@ -574,6 +641,15 @@ func useTarget(targetName string) (export Export, err error) { } ldflags = append(ldflags, "-L", env.LLGoROOT()) // search targets/*.ld + if config.Libc != "" { + var libcLDFlags []string + libcLDFlags, err = getOrCompileLibc(export.CC, export.Linker, config.Libc, ccflags, ldflags) + if err != nil { + return + } + ldflags = append(ldflags, libcLDFlags...) + } + // Combine with config flags and expand template variables export.CFLAGS = cflags export.CCFLAGS = ccflags diff --git a/internal/crosscompile/fetch.go b/internal/crosscompile/fetch.go index 3584b38f..ba000df9 100644 --- a/internal/crosscompile/fetch.go +++ b/internal/crosscompile/fetch.go @@ -8,6 +8,7 @@ import ( "net/http" "os" "os/exec" + "path" "path/filepath" "strings" "syscall" @@ -78,6 +79,47 @@ func checkDownloadAndExtractESPClang(platformSuffix, dir string) error { return nil } +func checkDownloadAndExtractLibc(url, dstDir, internalArchiveSrcDir string) error { + // Check if already exists + if _, err := os.Stat(dstDir); err == nil { + return nil + } + + // Create lock file path for the final destination + lockPath := dstDir + ".lock" + lockFile, err := acquireLock(lockPath) + if err != nil { + return fmt.Errorf("failed to acquire lock: %w", err) + } + defer releaseLock(lockFile) + + // Double-check after acquiring lock + if _, err := os.Stat(dstDir); err == nil { + return nil + } + + description := fmt.Sprintf("Libc %s", path.Base(url)) + + // Use temporary extraction directory + tempExtractDir := dstDir + ".extract" + if err := downloadAndExtractArchive(url, tempExtractDir, description); err != nil { + return err + } + defer os.RemoveAll(tempExtractDir) + + srcDir := tempExtractDir + + if internalArchiveSrcDir != "" { + srcDir = filepath.Join(tempExtractDir, internalArchiveSrcDir) + } + + if err := os.Rename(srcDir, dstDir); err != nil { + return fmt.Errorf("failed to rename libc directory: %w", err) + } + + return nil +} + // acquireLock creates and locks a file to prevent concurrent operations func acquireLock(lockPath string) (*os.File, error) { // Ensure the parent directory exists diff --git a/internal/crosscompile/libc.go b/internal/crosscompile/libc.go new file mode 100644 index 00000000..774ea390 --- /dev/null +++ b/internal/crosscompile/libc.go @@ -0,0 +1,185 @@ +package crosscompile + +import ( + "fmt" + "os" + "path/filepath" +) + +// CompileLibcConfig represents libc compilation configuration +type compileLibcConfig struct { + Url string + Name string // Libc name (e.g., "picolibc", "musl", "glibc") + Files []string // List of source files to compile + CFlags []string // C compiler flags specific to this libc + LDFlags []string // Linker flags + ArchiveSrcDir string +} + +// GetCompileLibcConfigByName retrieves libc compilation configuration by name +// Returns compilation file lists and corresponding cflags +func getCompileLibcConfigByName(baseDir, libcName string) (*compileLibcConfig, error) { + if libcName == "" { + return nil, fmt.Errorf("libc name cannot be empty") + } + libcDir := filepath.Join(baseDir, libcName) + + switch libcName { + case "picolibc": + return getPicolibcConfig(libcDir), nil + default: + return nil, fmt.Errorf("unsupported libc: %s", libcName) + } +} + +// getPicolibcConfig returns configuration for picolibc +func getPicolibcConfig(baseDir string) *compileLibcConfig { + libcIncludeDir := filepath.Join(baseDir, "libc", "include") + libmIncludeDir := filepath.Join(baseDir, "libm", "common") + localeIncludeDir := filepath.Join(baseDir, "libc", "locale") + + os.MkdirAll(baseDir, 0700) + + headerFile, _ := os.Create(filepath.Join(baseDir, "picolibc.h")) + headerFile.Close() + + return &compileLibcConfig{ + Url: "https://github.com/picolibc/picolibc/releases/download/1.8.10/picolibc-1.8.10.tar.xz", + Name: "picolibc", + Files: []string{ + filepath.Join(baseDir, "libc", "string", "bcmp.c"), + filepath.Join(baseDir, "libc", "string", "bcopy.c"), + filepath.Join(baseDir, "libc", "string", "bzero.c"), + filepath.Join(baseDir, "libc", "string", "explicit_bzero.c"), + filepath.Join(baseDir, "libc", "string", "ffsl.c"), + filepath.Join(baseDir, "libc", "string", "ffsll.c"), + filepath.Join(baseDir, "libc", "string", "fls.c"), + filepath.Join(baseDir, "libc", "string", "flsl.c"), + filepath.Join(baseDir, "libc", "string", "flsll.c"), + filepath.Join(baseDir, "libc", "string", "gnu_basename.c"), + filepath.Join(baseDir, "libc", "string", "index.c"), + filepath.Join(baseDir, "libc", "string", "memccpy.c"), + filepath.Join(baseDir, "libc", "string", "memchr.c"), + filepath.Join(baseDir, "libc", "string", "memcmp.c"), + filepath.Join(baseDir, "libc", "string", "memcpy.c"), + filepath.Join(baseDir, "libc", "string", "memmem.c"), + filepath.Join(baseDir, "libc", "string", "memmove.c"), + filepath.Join(baseDir, "libc", "string", "mempcpy.c"), + filepath.Join(baseDir, "libc", "string", "memrchr.c"), + filepath.Join(baseDir, "libc", "string", "memset.c"), + filepath.Join(baseDir, "libc", "string", "rawmemchr.c"), + filepath.Join(baseDir, "libc", "string", "rindex.c"), + filepath.Join(baseDir, "libc", "string", "stpcpy.c"), + filepath.Join(baseDir, "libc", "string", "stpncpy.c"), + filepath.Join(baseDir, "libc", "string", "strcasecmp.c"), + filepath.Join(baseDir, "libc", "string", "strcasecmp_l.c"), + filepath.Join(baseDir, "libc", "string", "strcasestr.c"), + filepath.Join(baseDir, "libc", "string", "strcat.c"), + filepath.Join(baseDir, "libc", "string", "strchr.c"), + filepath.Join(baseDir, "libc", "string", "strchrnul.c"), + filepath.Join(baseDir, "libc", "string", "strcmp.c"), + filepath.Join(baseDir, "libc", "string", "strcoll.c"), + filepath.Join(baseDir, "libc", "string", "strcoll_l.c"), + filepath.Join(baseDir, "libc", "string", "strcpy.c"), + filepath.Join(baseDir, "libc", "string", "strcspn.c"), + filepath.Join(baseDir, "libc", "string", "strerror_r.c"), + filepath.Join(baseDir, "libc", "string", "strlcat.c"), + filepath.Join(baseDir, "libc", "string", "strlcpy.c"), + filepath.Join(baseDir, "libc", "string", "strlen.c"), + filepath.Join(baseDir, "libc", "string", "strlwr.c"), + filepath.Join(baseDir, "libc", "string", "strncasecmp.c"), + filepath.Join(baseDir, "libc", "string", "strncasecmp_l.c"), + filepath.Join(baseDir, "libc", "string", "strncat.c"), + filepath.Join(baseDir, "libc", "string", "strncmp.c"), + filepath.Join(baseDir, "libc", "string", "strncpy.c"), + filepath.Join(baseDir, "libc", "string", "strndup.c"), + filepath.Join(baseDir, "libc", "string", "strnlen.c"), + filepath.Join(baseDir, "libc", "string", "strnstr.c"), + filepath.Join(baseDir, "libc", "string", "strpbrk.c"), + filepath.Join(baseDir, "libc", "string", "strrchr.c"), + filepath.Join(baseDir, "libc", "string", "strsep.c"), + filepath.Join(baseDir, "libc", "string", "strsignal.c"), + filepath.Join(baseDir, "libc", "string", "strspn.c"), + filepath.Join(baseDir, "libc", "string", "strstr.c"), + filepath.Join(baseDir, "libc", "string", "strtok.c"), + filepath.Join(baseDir, "libc", "string", "strtok_r.c"), + filepath.Join(baseDir, "libc", "string", "strupr.c"), + filepath.Join(baseDir, "libc", "string", "strverscmp.c"), + filepath.Join(baseDir, "libc", "string", "strxfrm.c"), + filepath.Join(baseDir, "libc", "string", "strxfrm_l.c"), + filepath.Join(baseDir, "libc", "string", "swab.c"), + filepath.Join(baseDir, "libc", "string", "timingsafe_bcmp.c"), + filepath.Join(baseDir, "libc", "string", "timingsafe_memcmp.c"), + filepath.Join(baseDir, "libc", "string", "strerror.c"), + filepath.Join(baseDir, "libc", "string", "wcpcpy.c"), + filepath.Join(baseDir, "libc", "string", "wcpncpy.c"), + filepath.Join(baseDir, "libc", "string", "wcscasecmp.c"), + filepath.Join(baseDir, "libc", "string", "wcscasecmp_l.c"), + filepath.Join(baseDir, "libc", "string", "wcscat.c"), + filepath.Join(baseDir, "libc", "string", "wcschr.c"), + filepath.Join(baseDir, "libc", "string", "wcscmp.c"), + filepath.Join(baseDir, "libc", "string", "wcscoll.c"), + filepath.Join(baseDir, "libc", "string", "wcscoll_l.c"), + filepath.Join(baseDir, "libc", "string", "wcscpy.c"), + filepath.Join(baseDir, "libc", "string", "wcscspn.c"), + filepath.Join(baseDir, "libc", "string", "wcsdup.c"), + filepath.Join(baseDir, "libc", "string", "wcslcat.c"), + filepath.Join(baseDir, "libc", "string", "wcslcpy.c"), + filepath.Join(baseDir, "libc", "string", "wcslen.c"), + filepath.Join(baseDir, "libc", "string", "wcsncasecmp.c"), + filepath.Join(baseDir, "libc", "string", "wcsncasecmp_l.c"), + filepath.Join(baseDir, "libc", "string", "wcsncat.c"), + filepath.Join(baseDir, "libc", "string", "wcsncmp.c"), + filepath.Join(baseDir, "libc", "string", "wcsncpy.c"), + filepath.Join(baseDir, "libc", "string", "wcsnlen.c"), + filepath.Join(baseDir, "libc", "string", "wcspbrk.c"), + filepath.Join(baseDir, "libc", "string", "wcsrchr.c"), + filepath.Join(baseDir, "libc", "string", "wcsspn.c"), + filepath.Join(baseDir, "libc", "string", "wcsstr.c"), + filepath.Join(baseDir, "libc", "string", "wcstok.c"), + filepath.Join(baseDir, "libc", "string", "wcswidth.c"), + filepath.Join(baseDir, "libc", "string", "wcsxfrm.c"), + filepath.Join(baseDir, "libc", "string", "wcsxfrm_l.c"), + filepath.Join(baseDir, "libc", "string", "wcwidth.c"), + filepath.Join(baseDir, "libc", "string", "wmemchr.c"), + filepath.Join(baseDir, "libc", "string", "wmemcmp.c"), + filepath.Join(baseDir, "libc", "string", "wmemcpy.c"), + filepath.Join(baseDir, "libc", "string", "wmemmove.c"), + filepath.Join(baseDir, "libc", "string", "wmempcpy.c"), + filepath.Join(baseDir, "libc", "string", "wmemset.c"), + filepath.Join(baseDir, "libc", "string", "xpg_strerror_r.c"), + + filepath.Join(baseDir, "libc", "stdlib", "nano-calloc.c"), + filepath.Join(baseDir, "libc", "stdlib", "nano-malloc.c"), + filepath.Join(baseDir, "libc", "stdlib", "nano-pvalloc.c"), + filepath.Join(baseDir, "libc", "stdlib", "nano-realloc.c"), + filepath.Join(baseDir, "libc", "stdlib", "nano-valloc.c"), + filepath.Join(baseDir, "libc", "stdlib", "rand.c"), + filepath.Join(baseDir, "libc", "stdlib", "srand.c"), + filepath.Join(baseDir, "libc", "stdlib", "nano-free.c"), + + filepath.Join(baseDir, "libc", "tinystdio", "printf.c"), + filepath.Join(baseDir, "libc", "tinystdio", "putchar.c"), + filepath.Join(baseDir, "libc", "tinystdio", "puts.c"), + }, + CFlags: []string{ + "-D_COMPILING_NEWLIB", + "-D_HAVE_ALIAS_ATTRIBUTE", + "-DTINY_STDIO", + "-DPOSIX_IO", + "-DFORMAT_DEFAULT_INTEGER", + "-D_IEEE_LIBM", + "-D__OBSOLETE_MATH_FLOAT=1", + "-D__OBSOLETE_MATH_DOUBLE=0", + "-D_WANT_IO_C99_FORMATS", + "-nostdlib", + "-isystem" + libcIncludeDir, + "-I" + libmIncludeDir, + "-I" + localeIncludeDir, + "-I" + baseDir, + "-I" + filepath.Join(baseDir, "libc", "tinystdio"), + }, + LDFlags: []string{"-nostdlib"}, + ArchiveSrcDir: filepath.Join("picolibc-1.8.10", "newlib"), + } +} diff --git a/internal/targets/config.go b/internal/targets/config.go index 99938e74..4071e9fe 100644 --- a/internal/targets/config.go +++ b/internal/targets/config.go @@ -16,6 +16,7 @@ type Config struct { GOARCH string `json:"goarch"` // Compiler and linker configuration + Libc string `json:"libc"` Linker string `json:"linker"` LinkerScript string `json:"linkerscript"` CFlags []string `json:"cflags"` diff --git a/internal/targets/loader.go b/internal/targets/loader.go index ebcd0c07..15687ccd 100644 --- a/internal/targets/loader.go +++ b/internal/targets/loader.go @@ -134,6 +134,9 @@ func (l *Loader) mergeConfig(dst, src *Config) { if src.GOARCH != "" { dst.GOARCH = src.GOARCH } + if src.Libc != "" { + dst.Libc = src.Libc + } if src.Linker != "" { dst.Linker = src.Linker } diff --git a/targets/esp32.ld b/targets/esp32.ld index 6818ce31..0d5de614 100644 --- a/targets/esp32.ld +++ b/targets/esp32.ld @@ -97,14 +97,6 @@ _heap_end = ORIGIN(DRAM) + LENGTH(DRAM); _stack_size = 4K; -/* From ESP-IDF: - * components/esp_rom/esp32/ld/esp32.rom.newlib-funcs.ld - * This is the subset that is sometimes used by LLVM during codegen, and thus - * must always be present. - */ -memcpy = 0x4000c2c8; -memmove = 0x4000c3c0; -memset = 0x4000c44c; /* From ESP-IDF: * components/esp_rom/esp32/ld/esp32.rom.libgcc.ld @@ -200,3 +192,9 @@ __umodsi3 = 0x4000c7d0; __umulsidi3 = 0x4000c7d8; __unorddf2 = 0x400637f4; __unordsf2 = 0x40063478; + +INCLUDE "targets/esp32.rom.newlib-data.ld"; +INCLUDE "targets/esp32.rom.newlib-funcs.ld"; +INCLUDE "targets/esp32.rom.newlib-locale.ld"; +INCLUDE "targets/esp32.rom.newlib-nano.ld"; +INCLUDE "targets/esp32.rom.newlib-time.ld"; diff --git a/targets/esp32.rom.newlib-data.ld b/targets/esp32.rom.newlib-data.ld new file mode 100644 index 00000000..ed5795c8 --- /dev/null +++ b/targets/esp32.rom.newlib-data.ld @@ -0,0 +1,23 @@ +/* These are the .bss/.data symbols used by newlib functions present in ESP32 ROM. + See also esp32.rom.newlib-funcs.ld for the list of general newlib functions, + and esp32.rom.newlib-nano.ld for "nano" versions of printf/scanf family of functions. + + Unlike other ROM functions and data which are exported using PROVIDE, which declares + weak symbols, newlib related functions are exported using assignment, + which declares strong symbols. This is done so that ROM functions are always + used instead of the ones provided by libc.a. + */ + +_ctype_ = 0x3ff96354; +__ctype_ptr__ = 0x3ff96350; +environ = 0x3ffae0b4; +_global_impure_ptr = 0x3ffae0b0; +__mb_cur_max = 0x3ff96530; +__sf_fake_stderr = 0x3ff96458; +__sf_fake_stdin = 0x3ff96498; +__sf_fake_stdout = 0x3ff96478; +__wctomb = 0x3ff96540; +__sfp_lock = 0x3ffae0ac; +__sinit_lock = 0x3ffae0a8; +__env_lock_object = 0x3ffae0b8; +__tz_lock_object = 0x3ffae080; diff --git a/targets/esp32.rom.newlib-funcs.ld b/targets/esp32.rom.newlib-funcs.ld new file mode 100644 index 00000000..79d5c5be --- /dev/null +++ b/targets/esp32.rom.newlib-funcs.ld @@ -0,0 +1,130 @@ +/* These are the newlib functions present in ESP32 ROM. + They should not be used when compiling with PSRAM cache workaround enabled. + See also esp32.rom.newlib-data.ld for the list of .data/.bss symbols + used by these functions, and esp32.rom.newlib-nano.ld for "nano" versions + of printf/scanf family of functions. + + Unlike other ROM functions which are exported using PROVIDE, which declares + weak symbols, newlib related functions are exported using assignment, + which declares strong symbols. This is done so that ROM functions are always + used instead of the ones provided by libc.a. + + Time functions were moved to the esp32.rom.newlib-time.ld file. + */ + +abs = 0x40056340; +__ascii_wctomb = 0x40058ef0; +atoi = 0x400566c4; +_atoi_r = 0x400566d4; +atol = 0x400566ec; +_atol_r = 0x400566fc; +bzero = 0x4000c1f4; +_cleanup = 0x40001df8; +_cleanup_r = 0x40001d48; +creat = 0x40000e8c; +div = 0x40056348; +__dummy_lock = 0x4000c728; +__dummy_lock_try = 0x4000c730; +__env_lock = 0x40001fd4; +__env_unlock = 0x40001fe0; +fclose = 0x400020ac; +_fclose_r = 0x40001fec; +fflush = 0x40059394; +_fflush_r = 0x40059320; +_findenv_r = 0x40001f44; +__fp_lock_all = 0x40001f1c; +__fp_unlock_all = 0x40001f30; +__fputwc = 0x40058da0; +fputwc = 0x40058ea8; +_fputwc_r = 0x40058e4c; +_fwalk = 0x4000c738; +_fwalk_reent = 0x4000c770; +_getenv_r = 0x40001fbc; +isalnum = 0x40000f04; +isalpha = 0x40000f18; +isascii = 0x4000c20c; +isblank = 0x40000f2c; +iscntrl = 0x40000f50; +isdigit = 0x40000f64; +isgraph = 0x40000f94; +islower = 0x40000f78; +isprint = 0x40000fa8; +ispunct = 0x40000fc0; +isspace = 0x40000fd4; +isupper = 0x40000fe8; +__itoa = 0x40056678; +itoa = 0x400566b4; +labs = 0x40056370; +ldiv = 0x40056378; +longjmp = 0x400562cc; +memccpy = 0x4000c220; +memchr = 0x4000c244; +memcmp = 0x4000c260; +memcpy = 0x4000c2c8; +memmove = 0x4000c3c0; +memrchr = 0x4000c400; +memset = 0x4000c44c; +qsort = 0x40056424; +rand = 0x40001058; +rand_r = 0x400010d4; +__sccl = 0x4000c498; +__sclose = 0x400011b8; +__seofread = 0x40001148; +setjmp = 0x40056268; +__sflush_r = 0x400591e0; +__sfmoreglue = 0x40001dc8; +__sfp = 0x40001e90; +__sfp_lock_acquire = 0x40001e08; +__sfp_lock_release = 0x40001e14; +__sinit = 0x40001e38; +__sinit_lock_acquire = 0x40001e20; +__sinit_lock_release = 0x40001e2c; +srand = 0x40001004; +__sread = 0x40001118; +__sseek = 0x40001184; +strcasecmp = 0x400011cc; +strcasestr = 0x40001210; +strcat = 0x4000c518; +strchr = 0x4000c53c; +strcmp = 0x40001274; +strcoll = 0x40001398; +strcpy = 0x400013ac; +strcspn = 0x4000c558; +strdup = 0x4000143c; +_strdup_r = 0x40001450; +strlcat = 0x40001470; +strlcpy = 0x4000c584; +strlen = 0x400014c0; +strlwr = 0x40001524; +strncasecmp = 0x40001550; +strncat = 0x4000c5c4; +strncmp = 0x4000c5f4; +strncpy = 0x400015d4; +strndup = 0x400016b0; +_strndup_r = 0x400016c4; +strnlen = 0x4000c628; +strrchr = 0x40001708; +strsep = 0x40001734; +strspn = 0x4000c648; +strstr = 0x4000c674; +__strtok_r = 0x4000c6a8; +strtok_r = 0x4000c70c; +strtol = 0x4005681c; +_strtol_r = 0x40056714; +strtoul = 0x4005692c; +_strtoul_r = 0x40056834; +strupr = 0x4000174c; +__submore = 0x40058f3c; +__swbuf = 0x40058cb4; +__swbuf_r = 0x40058bec; +__swrite = 0x40001150; +toascii = 0x4000c720; +tolower = 0x40001868; +toupper = 0x40001884; +ungetc = 0x400590f4; +_ungetc_r = 0x40058fa0; +__utoa = 0x400561f0; +utoa = 0x40056258; +wcrtomb = 0x40058920; +_wcrtomb_r = 0x400588d8; +_wctomb_r = 0x40058f14; diff --git a/targets/esp32.rom.newlib-locale.ld b/targets/esp32.rom.newlib-locale.ld new file mode 100644 index 00000000..81e22aaf --- /dev/null +++ b/targets/esp32.rom.newlib-locale.ld @@ -0,0 +1,19 @@ +/* These are the locale-related newlib functions present in ESP32 ROM. + ESP32 ROM contains newlib version 2.2.0, and these functions should not be + used when compiling with newlib version 3, since locale implementation is + different there. + + Unlike other ROM functions which are exported using PROVIDE, which declares + weak symbols, newlib related functions are exported using assignment, + which declares strong symbols. This is done so that ROM functions are always + used instead of the ones provided by libc.a. + */ + +__locale_charset = 0x40059540; +__locale_cjk_lang = 0x40059558; +localeconv = 0x4005957c; +_localeconv_r = 0x40059560; +__locale_mb_cur_max = 0x40059548; +__locale_msgcharset = 0x40059550; +setlocale = 0x40059568; +_setlocale_r = 0x4005950c; diff --git a/targets/esp32.rom.newlib-nano.ld b/targets/esp32.rom.newlib-nano.ld new file mode 100644 index 00000000..51d93a1e --- /dev/null +++ b/targets/esp32.rom.newlib-nano.ld @@ -0,0 +1,115 @@ +/* These are the printf/scanf related newlib functions present in ESP32 ROM. + These functions are compiled with newlib "nano" format option. + As such, they don's support 64-bit integer formats. + Floating point formats are supported by setting _printf_float and + _scanf_float entries in syscall table. This is done automatically + by startup code. + These functions should not be used when compiling with PSRAM cache workaround enabled. + See also esp32.rom.newlib-data.ld for the list of .data/.bss symbols + used by newlib functions, and esp32.rom.newlib-funcs.ld for the list + of general newlib functions. + + Unlike other ROM functions which are exported using PROVIDE, which declares + weak symbols, newlib related functions are exported using assignment, + which declares strong symbols. This is done so that ROM functions are always + used instead of the ones provided by libc.a. + */ + +asiprintf = 0x40056d9c; +_asiprintf_r = 0x40056d4c; +asniprintf = 0x40056cd8; +_asniprintf_r = 0x40056c64; +asnprintf = 0x40056cd8; +_asnprintf_r = 0x40056c64; +asprintf = 0x40056d9c; +_asprintf_r = 0x40056d4c; +fiprintf = 0x40056efc; +_fiprintf_r = 0x40056ed8; +fiscanf = 0x40058884; +_fiscanf_r = 0x400588b4; +fprintf = 0x40056efc; +_fprintf_r = 0x40056ed8; +fscanf = 0x40058884; +_fscanf_r = 0x400588b4; +iprintf = 0x40056978; +_iprintf_r = 0x40056944; +iscanf = 0x40058760; +_iscanf_r = 0x4005879c; +printf = 0x40056978; +_printf_common = 0x40057338; +_printf_i = 0x40057404; +_printf_r = 0x40056944; +scanf = 0x40058760; +_scanf_chars = 0x40058384; +_scanf_i = 0x4005845c; +_scanf_r = 0x4005879c; +__sfputs_r = 0x40057790; +siprintf = 0x40056c08; +_siprintf_r = 0x40056bbc; +siscanf = 0x400587d0; +_siscanf_r = 0x40058830; +sniprintf = 0x40056b4c; +_sniprintf_r = 0x40056ae4; +snprintf = 0x40056b4c; +_snprintf_r = 0x40056ae4; +sprintf = 0x40056c08; +_sprintf_r = 0x40056bbc; +__sprint_r = 0x400577e4; +sscanf = 0x400587d0; +_sscanf_r = 0x40058830; +__ssprint_r = 0x40056ff8; +__ssputs_r = 0x40056f2c; +__ssrefill_r = 0x40057fec; +__ssvfiscanf_r = 0x4005802c; +__ssvfscanf_r = 0x4005802c; +_sungetc_r = 0x40057f6c; +_svfiprintf_r = 0x40057100; +__svfiscanf_r = 0x40057b08; +_svfprintf_r = 0x40057100; +__svfscanf = 0x40057f04; +__svfscanf_r = 0x40057b08; +vasiprintf = 0x40056eb8; +_vasiprintf_r = 0x40056e80; +vasniprintf = 0x40056e58; +_vasniprintf_r = 0x40056df8; +vasnprintf = 0x40056e58; +_vasnprintf_r = 0x40056df8; +vasprintf = 0x40056eb8; +_vasprintf_r = 0x40056e80; +vfiprintf = 0x40057ae8; +_vfiprintf_r = 0x40057850; +vfiscanf = 0x40057eb8; +_vfiscanf_r = 0x40057f24; +vfprintf = 0x40057ae8; +_vfprintf_r = 0x40057850; +vfscanf = 0x40057eb8; +_vfscanf_r = 0x40057f24; +viprintf = 0x400569b4; +_viprintf_r = 0x400569e4; +viscanf = 0x40058698; +_viscanf_r = 0x400586c8; +vprintf = 0x400569b4; +_vprintf_r = 0x400569e4; +vscanf = 0x40058698; +_vscanf_r = 0x400586c8; +vsiprintf = 0x40056ac4; +_vsiprintf_r = 0x40056a90; +vsiscanf = 0x40058740; +_vsiscanf_r = 0x400586f8; +vsniprintf = 0x40056a68; +_vsniprintf_r = 0x40056a14; +vsnprintf = 0x40056a68; +_vsnprintf_r = 0x40056a14; +vsprintf = 0x40056ac4; +_vsprintf_r = 0x40056a90; +vsscanf = 0x40058740; +_vsscanf_r = 0x400586f8; + +/* _print_float and _scanf_float functions in ROM are stubs which call + real implementations in IDF through the syscall table. + As such, don't include these ROM symbols. + +_printf_float = 0x4000befc; +_scanf_float = 0x4000bf18; + +*/ diff --git a/targets/esp32.rom.newlib-time.ld b/targets/esp32.rom.newlib-time.ld new file mode 100644 index 00000000..50ec6488 --- /dev/null +++ b/targets/esp32.rom.newlib-time.ld @@ -0,0 +1,38 @@ +/* These are the newlib functions and the .bss/.data symbols necessary for these functions present in ESP32 ROM. + They should not be used when you need to solve the Y2K38 problem. + Because these functions were compiled with 32-bit width for the time_t structure. + */ + +asctime = 0x40059588; +asctime_r = 0x40000ec8; +ctime = 0x400595b0; +ctime_r = 0x400595c4; +__gettzinfo = 0x40001fcc; +__get_current_time_locale = 0x40001834; +gmtime = 0x40059848; +gmtime_r = 0x40059868; +localtime = 0x400595dc; +localtime_r = 0x400595fc; +mktime = 0x4005a5e8; +strftime = 0x40059ab4; +time = 0x40001844; +__time_load_locale = 0x4000183c; +tzset = 0x40001a1c; +_tzset_r = 0x40001a28; +__tzcalc_limits = 0x400018a0; +__tz_lock = 0x40001a04; +__tz_unlock = 0x40001a10; +/* The .bss/.data symbols necessary for these functions */ +_timezone = 0x3ffae0a0; +_tzname = 0x3ffae030; +_daylight = 0x3ffae0a4; +__month_lengths = 0x3ff9609c; + +/* These functions don't use time_t, but use other structures which include time_t. + * For example, 'struct stat' contains time_t. + */ +_isatty_r = 0x40000ea0; +__sfvwrite_r = 0x4005893c; +__smakebuf_r = 0x40059108; +__srefill_r = 0x400593d4; +__swsetup_r = 0x40058cc8; From ab57a13eb15dc1ce0a0a5aa3499b0a5b833d7bb9 Mon Sep 17 00:00:00 2001 From: visualfc Date: Sun, 24 Aug 2025 19:56:19 +0800 Subject: [PATCH 18/46] internal/build: fix warning duplicate -rpath --- internal/build/build.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/internal/build/build.go b/internal/build/build.go index 0a66cad6..0d0c22ee 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -740,16 +740,20 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, global l } if IsFullRpathEnabled() { - exargs := make([]string, 0, ctx.nLibdir<<1) // Treat every link-time library search path, specified by the -L parameter, as a runtime search path as well. // This is to ensure the final executable can locate libraries with a relocatable install_name // (e.g., "@rpath/libfoo.dylib") at runtime. + rpaths := make(map[string]none) for _, arg := range linkArgs { if strings.HasPrefix(arg, "-L") { - exargs = append(exargs, "-rpath", arg[2:]) + path := arg[2:] + if _, ok := rpaths[path]; ok { + continue + } + rpaths[path] = none{} + linkArgs = append(linkArgs, "-rpath", path) } } - linkArgs = append(linkArgs, exargs...) } err = linkObjFiles(ctx, orgApp, objFiles, linkArgs, verbose) From 69fe6d637738e2faaef7968971c1aa9f7ee76490 Mon Sep 17 00:00:00 2001 From: visualfc Date: Tue, 26 Aug 2025 17:15:43 +0800 Subject: [PATCH 19/46] runtime/internal/lib/os: fix readdir for darwin-amd64 --- _demo/readdir/main.go | 10 ++++++ runtime/internal/clite/os/dir.go | 17 ++++++++++ runtime/internal/clite/os/dir_darwin_amd64.go | 17 ++++++++++ runtime/internal/clite/os/dir_unix.go | 20 ++++++++++++ runtime/internal/clite/os/os.go | 6 ---- runtime/internal/clite/os/stat.go | 3 ++ runtime/internal/clite/os/stat_darwin.go | 3 ++ runtime/internal/lib/os/dir.go | 32 ++++--------------- 8 files changed, 76 insertions(+), 32 deletions(-) create mode 100644 runtime/internal/clite/os/dir.go create mode 100644 runtime/internal/clite/os/dir_darwin_amd64.go create mode 100644 runtime/internal/clite/os/dir_unix.go diff --git a/_demo/readdir/main.go b/_demo/readdir/main.go index ed394e64..32899617 100644 --- a/_demo/readdir/main.go +++ b/_demo/readdir/main.go @@ -13,7 +13,17 @@ func main() { if len(entries) == 0 { panic("No files found") } + var check int for _, e := range entries { fmt.Printf("%s isDir[%t]\n", e.Name(), e.IsDir()) + if !e.IsDir() { + switch e.Name() { + case "go.sum", "go.mod": + check++ + } + } + } + if check != 2 { + panic("Bad readdir entries go.mod/go.sum") } } diff --git a/runtime/internal/clite/os/dir.go b/runtime/internal/clite/os/dir.go new file mode 100644 index 00000000..b000aa2f --- /dev/null +++ b/runtime/internal/clite/os/dir.go @@ -0,0 +1,17 @@ +package os + +import ( + _ "unsafe" + + c "github.com/goplus/llgo/runtime/internal/clite" +) + +type DIR struct { + Unused [0]byte +} + +//go:linkname Opendir C.opendir +func Opendir(name *c.Char) *DIR + +//go:linkname Closedir C.closedir +func Closedir(dir *DIR) c.Int diff --git a/runtime/internal/clite/os/dir_darwin_amd64.go b/runtime/internal/clite/os/dir_darwin_amd64.go new file mode 100644 index 00000000..ec9c4b5a --- /dev/null +++ b/runtime/internal/clite/os/dir_darwin_amd64.go @@ -0,0 +1,17 @@ +package os + +import ( + _ "unsafe" + + c "github.com/goplus/llgo/runtime/internal/clite" + "github.com/goplus/llgo/runtime/internal/clite/syscall" +) + +//go:linkname Fdopendir C.fdopendir$INODE64 +func Fdopendir(fd c.Int) *DIR + +//go:linkname Readdir C.readdir$INODE64 +func Readdir(dir *DIR) *syscall.Dirent + +//go:linkname Fstatat C.fstatat$INODE64 +func Fstatat(dirfd c.Int, path *c.Char, buf *StatT, flags c.Int) c.Int diff --git a/runtime/internal/clite/os/dir_unix.go b/runtime/internal/clite/os/dir_unix.go new file mode 100644 index 00000000..734d18ab --- /dev/null +++ b/runtime/internal/clite/os/dir_unix.go @@ -0,0 +1,20 @@ +//go:build !(darwin && amd64) +// +build !darwin !amd64 + +package os + +import ( + _ "unsafe" + + c "github.com/goplus/llgo/runtime/internal/clite" + "github.com/goplus/llgo/runtime/internal/clite/syscall" +) + +//go:linkname Fdopendir C.fdopendir +func Fdopendir(fd c.Int) *DIR + +//go:linkname Readdir C.readdir +func Readdir(dir *DIR) *syscall.Dirent + +//go:linkname Fstatat C.fstatat +func Fstatat(dirfd c.Int, path *c.Char, buf *StatT, flags c.Int) c.Int diff --git a/runtime/internal/clite/os/os.go b/runtime/internal/clite/os/os.go index df9a0b17..ee05d416 100644 --- a/runtime/internal/clite/os/os.go +++ b/runtime/internal/clite/os/os.go @@ -135,9 +135,6 @@ func Fchmodat(dirfd c.Int, path *c.Char, mode ModeT, flags c.Int) c.Int //go:linkname Fchownat C.fchownat func Fchownat(dirfd c.Int, path *c.Char, owner UidT, group GidT, flags c.Int) c.Int -//go:linkname Fstatat C.fstatat -func Fstatat(dirfd c.Int, path *c.Char, buf *StatT, flags c.Int) c.Int - // ----------------------------------------------------------------------------- //go:linkname Open C.open @@ -191,9 +188,6 @@ func Fchmod(fd c.Int, mode ModeT) c.Int //go:linkname Fchown C.fchown func Fchown(fd c.Int, owner UidT, group GidT) c.Int -//go:linkname Fstat C.fstat -func Fstat(fd c.Int, buf *StatT) c.Int - //go:linkname Isatty C.isatty func Isatty(fd c.Int) c.Int diff --git a/runtime/internal/clite/os/stat.go b/runtime/internal/clite/os/stat.go index 2fc00ca6..11c189ed 100644 --- a/runtime/internal/clite/os/stat.go +++ b/runtime/internal/clite/os/stat.go @@ -14,3 +14,6 @@ func Stat(path *c.Char, buf *StatT) c.Int //go:linkname Lstat C.lstat func Lstat(path *c.Char, buf *StatT) c.Int + +//go:linkname Fstat C.fstat +func Fstat(fd c.Int, buf *StatT) c.Int diff --git a/runtime/internal/clite/os/stat_darwin.go b/runtime/internal/clite/os/stat_darwin.go index 0017571e..a0dc6568 100644 --- a/runtime/internal/clite/os/stat_darwin.go +++ b/runtime/internal/clite/os/stat_darwin.go @@ -11,3 +11,6 @@ func Stat(path *c.Char, buf *StatT) c.Int //go:linkname Lstat C.lstat64 func Lstat(path *c.Char, buf *StatT) c.Int + +//go:linkname Fstat C.fstat64 +func Fstat(fd c.Int, buf *StatT) c.Int diff --git a/runtime/internal/lib/os/dir.go b/runtime/internal/lib/os/dir.go index 37840e62..8b353458 100644 --- a/runtime/internal/lib/os/dir.go +++ b/runtime/internal/lib/os/dir.go @@ -82,30 +82,10 @@ func ReadDir(name string) ([]DirEntry, error) { return dirs, err } -//go:linkname c_fdopendir C.fdopendir -func c_fdopendir(fd c.Int) uintptr - -func fdopendir(fd int) (dir uintptr, err error) { - return c_fdopendir(c.Int(fd)), nil -} - -//go:linkname c_closedir C.closedir -func c_closedir(dir uintptr) c.Int - -func closedir(dir uintptr) error { - if c_closedir(dir) != 0 { - return syscall.Errno(os.Errno()) - } - return nil -} - -//go:linkname c_readdir C.readdir -func c_readdir(dir uintptr) *syscall.Dirent - -func readdir(dir uintptr) ([]syscall.Dirent, error) { +func readdir(dir *os.DIR) ([]syscall.Dirent, error) { var entries []syscall.Dirent for { - dirent := c_readdir(dir) + dirent := os.Readdir(dir) if dirent == nil { break } @@ -139,11 +119,11 @@ func (f *File) ReadDir(n int) (dirents []DirEntry, err error) { } // Open directory using file descriptor - dir, err := fdopendir(int(f.fd)) - if err != nil { - return nil, err + dir := os.Fdopendir(c.Int(f.fd)) + if dir == nil { + return nil, syscall.Errno(os.Errno()) } - defer closedir(dir) + defer os.Closedir(dir) // Match Readdir and Readdirnames: don't return nil slices. dirents = []DirEntry{} From 0935d10edf6e292645547092d386ca8c25aac3ed Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Wed, 27 Aug 2025 19:36:46 +0800 Subject: [PATCH 20/46] xtool/safesplit:properly handle consecutive short flags --- internal/clang/clang_test.go | 6 ++++++ xtool/safesplit/safesplit.go | 7 +++++++ xtool/safesplit/safesplit_test.go | 12 +++++++++--- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/internal/clang/clang_test.go b/internal/clang/clang_test.go index 390bcb1b..fecaf256 100644 --- a/internal/clang/clang_test.go +++ b/internal/clang/clang_test.go @@ -446,6 +446,12 @@ func TestFlagMergingScenarios(t *testing.T) { expectComp: []string{"-O3", "-fPIC", "-Wall", "-Wextra", "-std=c11"}, expectLink: []string{"-O3", "-lm", "-lpthread", "-static"}, }, + { + // case from https://github.com/goplus/llgo/issues/1244 + name: "issue 1244", + envCFlags: "-w -pipe -mmacosx-version-min=15 -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk", + expectComp: []string{"-w", "-pipe", "-mmacosx-version-min=15", "-isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk"}, + }, } // Save original environment diff --git a/xtool/safesplit/safesplit.go b/xtool/safesplit/safesplit.go index 58f2c242..71783bcd 100644 --- a/xtool/safesplit/safesplit.go +++ b/xtool/safesplit/safesplit.go @@ -49,6 +49,13 @@ func SplitPkgConfigFlags(s string) []string { for i < len(s) && (s[i] == ' ' || s[i] == '\t') { i++ } + + // Check if next character is another flag (short flag with no argument) + if i < len(s) && s[i] == '-' { + // This is a short flag with no argument, finish current flag + continue + } + // Read content until next space for i < len(s) { if s[i] == '\\' && i+1 < len(s) && (s[i+1] == ' ' || s[i+1] == '\t') { diff --git a/xtool/safesplit/safesplit_test.go b/xtool/safesplit/safesplit_test.go index cbb8c9cc..ccc60318 100644 --- a/xtool/safesplit/safesplit_test.go +++ b/xtool/safesplit/safesplit_test.go @@ -50,8 +50,8 @@ func TestSplitPkgConfigFlags(t *testing.T) { }) t.Run("consecutive_flags", func(t *testing.T) { - ftest("-I -L", `["-I-L"]`) - ftest("-I -L /usr/lib", `["-I-L /usr/lib"]`) + ftest("-I -L", `["-I" "-L"]`) + ftest("-I -L /usr/lib", `["-I" "-L/usr/lib"]`) }) t.Run("edge_cases", func(t *testing.T) { @@ -59,7 +59,7 @@ func TestSplitPkgConfigFlags(t *testing.T) { ftest(" ", "[]") ftest("-", `["-"]`) ftest("-I", `["-I"]`) - ftest("-I -", `["-I-"]`) + ftest("-I -", `["-I" "-"]`) }) t.Run("escaped_spaces", func(t *testing.T) { @@ -77,6 +77,12 @@ func TestSplitPkgConfigFlags(t *testing.T) { ftest("-DVERSION=2.1 -DDEBUG=1", `["-DVERSION=2.1" "-DDEBUG=1"]`) ftest("-D VERSION=2.1 -D DEBUG=1", `["-DVERSION=2.1" "-DDEBUG=1"]`) }) + + // case for https://github.com/goplus/llgo/issues/1244 + t.Run("w_pipe", func(t *testing.T) { + ftest("-w -pipe", `["-w" "-pipe"]`) + ftest("-Os -w -pipe", `["-Os" "-w" "-pipe"]`) + }) } func toString(ss []string) string { From b68686e5423c70db1b7ce3f652c44817378c83cc Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 28 Aug 2025 11:06:42 +0800 Subject: [PATCH 21/46] internal/target:read targets use LLGoROOT --- internal/targets/resolver.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/internal/targets/resolver.go b/internal/targets/resolver.go index d144bc18..6d50ffa4 100644 --- a/internal/targets/resolver.go +++ b/internal/targets/resolver.go @@ -3,7 +3,8 @@ package targets import ( "fmt" "path/filepath" - "runtime" + + "github.com/goplus/llgo/internal/env" ) // Resolver provides high-level interface for target configuration resolution @@ -20,10 +21,8 @@ func NewResolver(targetsDir string) *Resolver { // NewDefaultResolver creates a resolver with default targets directory func NewDefaultResolver() *Resolver { - // Assume targets directory is relative to this package - _, filename, _, _ := runtime.Caller(0) - projectRoot := filepath.Dir(filepath.Dir(filepath.Dir(filename))) - targetsDir := filepath.Join(projectRoot, "targets") + llgoRoot := env.LLGoROOT() + targetsDir := filepath.Join(llgoRoot, "targets") return NewResolver(targetsDir) } From f3ecce86ee1a51a1b609e29cc466bee18d79b599 Mon Sep 17 00:00:00 2001 From: Haolan Date: Thu, 28 Aug 2025 20:11:13 +0800 Subject: [PATCH 22/46] feat: support libc for small devices --- internal/build/build.go | 1 + internal/crosscompile/crosscompile.go | 67 +- internal/crosscompile/fetch.go | 57 +- internal/crosscompile/libc.go | 244 +++---- internal/crosscompile/newlibesp.go | 990 ++++++++++++++++++++++++++ internal/crosscompile/picolibc.go | 166 +++++ targets/esp32.app.elf.ld | 185 +++++ targets/esp32.json | 21 +- targets/esp32.ld | 200 ------ targets/esp32.memory.elf.ld | 26 + targets/esp32.rom.newlib-data.ld | 23 - targets/esp32.rom.newlib-funcs.ld | 130 ---- targets/esp32.rom.newlib-locale.ld | 19 - targets/esp32.rom.newlib-nano.ld | 115 --- targets/esp32.rom.newlib-time.ld | 38 - 15 files changed, 1536 insertions(+), 746 deletions(-) create mode 100644 internal/crosscompile/newlibesp.go create mode 100644 internal/crosscompile/picolibc.go create mode 100755 targets/esp32.app.elf.ld delete mode 100644 targets/esp32.ld create mode 100755 targets/esp32.memory.elf.ld delete mode 100644 targets/esp32.rom.newlib-data.ld delete mode 100644 targets/esp32.rom.newlib-funcs.ld delete mode 100644 targets/esp32.rom.newlib-locale.ld delete mode 100644 targets/esp32.rom.newlib-nano.ld delete mode 100644 targets/esp32.rom.newlib-time.ld diff --git a/internal/build/build.go b/internal/build/build.go index 2b2ce4f0..b13fac77 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -826,6 +826,7 @@ func linkObjFiles(ctx *context, app string, objFiles, linkArgs []string, verbose if IsDbgSymsEnabled() { buildArgs = append(buildArgs, "-gdwarf-4") } + buildArgs = append(buildArgs, "--cref", "--Map=t.map") buildArgs = append(buildArgs, objFiles...) diff --git a/internal/crosscompile/crosscompile.go b/internal/crosscompile/crosscompile.go index a4581832..79749534 100644 --- a/internal/crosscompile/crosscompile.go +++ b/internal/crosscompile/crosscompile.go @@ -8,11 +8,8 @@ import ( "os/exec" "path/filepath" "runtime" - "slices" "strings" - "github.com/goplus/llgo/internal/clang" - "github.com/goplus/llgo/internal/env" "github.com/goplus/llgo/internal/targets" "github.com/goplus/llgo/internal/xtool/llvm" @@ -218,67 +215,33 @@ func getESPClangPlatform(goos, goarch string) string { return "" } -func getOrCompileLibc(cc, linkerName, libcName string, ccflags, exportLdFlags []string) (ldflags []string, err error) { +func ldFlagsFromFileName(fileName string) string { + return strings.TrimPrefix(strings.TrimSuffix(fileName, ".a"), "lib") +} + +func getOrCompileLibc(cc, linkerName, libcName string, exportCCFlags, exportLDFlags []string) (ldflags []string, err error) { baseDir := filepath.Join(cacheRoot(), "crosscompile") - libcDir := filepath.Join(baseDir, libcName) - libcArchive := filepath.Join(libcDir, "libc.a") - // fast-path: compiled already - if _, err = os.Stat(libcArchive); !os.IsNotExist(err) { - ldflags = append(ldflags, "-nostdlib", "-L", libcDir, "-lc") - return ldflags, nil - } + outputDir := filepath.Join(baseDir, libcName) + compileConfig, err := getCompileLibcConfigByName(baseDir, libcName) if err != nil { return } - tempDir, err := os.MkdirTemp("", "compile*") - if err != nil { + if err = checkDownloadAndExtractLibc(compileConfig, compileConfig.Url, outputDir, compileConfig.ArchiveSrcDir); err != nil { return } - defer os.RemoveAll(tempDir) + ldflags = append(ldflags, "-nostdlib", "-L"+outputDir) - fmt.Fprintf(os.Stderr, "%s not found in LLGO_ROOT or cache, will download and compile.\n", libcDir) - if err = checkDownloadAndExtractLibc(compileConfig.Url, libcDir, compileConfig.ArchiveSrcDir); err != nil { - return - } - compileLDFlags := append(slices.Clone(exportLdFlags), compileConfig.LDFlags...) - - cfg := clang.NewConfig(cc, ccflags, compileConfig.CFlags, compileLDFlags, linkerName) - - var objFiles []string - - compiler := clang.NewCompiler(cfg) - linker := clang.NewLinker(cfg) - - compiler.Verbose = true - linker.Verbose = true - fmt.Fprintf(os.Stderr, "Start to compile libc %s to %s...\n", libcName, libcArchive) - - for _, file := range compileConfig.Files { - var tempObjFile *os.File - tempObjFile, err = os.CreateTemp(tempDir, "libc*.o") + for _, group := range compileConfig.Groups { + err = group.Compile(outputDir, cc, linkerName, exportCCFlags, exportLDFlags) if err != nil { - return + break } - fmt.Fprintf(os.Stderr, "Compile libc file %s to %s...\n", file, tempObjFile.Name()) - - err = compiler.Compile("-o", tempObjFile.Name(), "-x", "c", "-c", file) - if err != nil { - return + if filepath.Ext(group.OutputFileName) == ".o" { + continue } - - objFiles = append(objFiles, tempObjFile.Name()) + ldflags = append(ldflags, "-l"+ldFlagsFromFileName(group.OutputFileName)) } - - args := []string{"-o", libcArchive} - args = append(args, objFiles...) - - err = linker.Link(args...) - if err != nil { - return - } - ldflags = append(ldflags, "-nostdlib", "-L", libcDir, "-lc") - return } diff --git a/internal/crosscompile/fetch.go b/internal/crosscompile/fetch.go index ba000df9..cc676662 100644 --- a/internal/crosscompile/fetch.go +++ b/internal/crosscompile/fetch.go @@ -2,6 +2,7 @@ package crosscompile import ( "archive/tar" + "archive/zip" "compress/gzip" "fmt" "io" @@ -79,9 +80,9 @@ func checkDownloadAndExtractESPClang(platformSuffix, dir string) error { return nil } -func checkDownloadAndExtractLibc(url, dstDir, internalArchiveSrcDir string) error { +func checkDownloadAndExtractLibc(cfg *compileLibcConfig, url, dstDir, internalArchiveSrcDir string) error { // Check if already exists - if _, err := os.Stat(dstDir); err == nil { + if cfg.IsCompiled(dstDir) { return nil } @@ -94,9 +95,10 @@ func checkDownloadAndExtractLibc(url, dstDir, internalArchiveSrcDir string) erro defer releaseLock(lockFile) // Double-check after acquiring lock - if _, err := os.Stat(dstDir); err == nil { + if cfg.IsCompiled(dstDir) { return nil } + fmt.Fprintf(os.Stderr, "%s not found in LLGO_ROOT or cache, will download and compile.\n", dstDir) description := fmt.Sprintf("Libc %s", path.Base(url)) @@ -105,7 +107,7 @@ func checkDownloadAndExtractLibc(url, dstDir, internalArchiveSrcDir string) erro if err := downloadAndExtractArchive(url, tempExtractDir, description); err != nil { return err } - defer os.RemoveAll(tempExtractDir) + // defer os.RemoveAll(tempExtractDir) srcDir := tempExtractDir @@ -182,10 +184,14 @@ func downloadAndExtractArchive(url, destDir, description string) error { if err != nil { return fmt.Errorf("failed to extract %s archive: %w", description, err) } + } else if strings.HasSuffix(filename, ".zip") { + err := extractZip(localFile, tempDir) + if err != nil { + return fmt.Errorf("failed to extract %s archive: %w", description, err) + } } else { return fmt.Errorf("unsupported archive format: %s", filename) } - // Rename temp directory to target directory if err := os.Rename(tempDir, destDir); err != nil { return fmt.Errorf("failed to rename directory: %w", err) @@ -265,3 +271,44 @@ func extractTarXz(tarXzFile, dest string) error { cmd := exec.Command("tar", "-xf", tarXzFile, "-C", dest) return cmd.Run() } + +func extractZip(zipFile, dest string) error { + r, err := zip.OpenReader(zipFile) + if err != nil { + return err + } + defer r.Close() + decompress := func(file *zip.File) error { + path := filepath.Join(dest, file.Name) + + if file.FileInfo().IsDir() { + return os.MkdirAll(path, 0700) + } + + fs, err := file.Open() + if err != nil { + return err + } + defer fs.Close() + + w, err := os.Create(path) + if err != nil { + return err + } + if _, err := io.Copy(w, fs); err != nil { + w.Close() + return err + } + if err := w.Close(); err != nil { + return err + } + return nil + } + + for _, file := range r.File { + if err = decompress(file); err != nil { + break + } + } + return err +} diff --git a/internal/crosscompile/libc.go b/internal/crosscompile/libc.go index 774ea390..d9fe64bc 100644 --- a/internal/crosscompile/libc.go +++ b/internal/crosscompile/libc.go @@ -3,19 +3,101 @@ package crosscompile import ( "fmt" "os" + "os/exec" "path/filepath" + "slices" + "strings" + + "github.com/goplus/llgo/internal/clang" ) +type compileGroup struct { + OutputFileName string + Files []string // List of source files to compile + CFlags []string // C compiler flags specific to this libc + CCFlags []string + LDFlags []string // Linker flags +} + +func (g compileGroup) IsCompiled(outputDir string) bool { + libcArchive := filepath.Join(outputDir, g.OutputFileName) + _, err := os.Stat(libcArchive) + return !os.IsNotExist(err) +} + +func (g compileGroup) Compile(outputDir, cc, linkerName string, extraCCFlags, extraLDFlags []string) (err error) { + if g.IsCompiled(outputDir) { + return + } + tmpCompileDir, err := os.MkdirTemp("", "compile-libc-group*") + if err != nil { + return + } + defer os.RemoveAll(tmpCompileDir) + + compileLDFlags := append(slices.Clone(extraLDFlags), g.LDFlags...) + compileCCFlags := append(slices.Clone(extraCCFlags), g.CCFlags...) + cfg := clang.NewConfig(cc, compileCCFlags, g.CFlags, compileLDFlags, linkerName) + + var objFiles []string + + compiler := clang.NewCompiler(cfg) + + compiler.Verbose = true + + libcArchive := filepath.Join(outputDir, g.OutputFileName) + fmt.Fprintf(os.Stderr, "Start to compile libc group %s to %s...\n", g.OutputFileName, libcArchive) + + for _, file := range g.Files { + var tempObjFile *os.File + tempObjFile, err = os.CreateTemp(tmpCompileDir, fmt.Sprintf("%s*.o", strings.ReplaceAll(file, string(os.PathSeparator), "-"))) + if err != nil { + return + } + fmt.Fprintf(os.Stderr, "Compile libc file %s to %s...\n", file, tempObjFile.Name()) + + lang := "c" + if filepath.Ext(file) == ".S" { + lang = "assembler-with-cpp" + } + err = compiler.Compile("-o", tempObjFile.Name(), "-x", lang, "-c", file) + if err != nil { + return + } + + objFiles = append(objFiles, tempObjFile.Name()) + } + + args := []string{"rcs", libcArchive} + args = append(args, objFiles...) + + ccDir := filepath.Dir(cc) + llvmAr := filepath.Join(ccDir, "llvm-ar") + + cmd := exec.Command(llvmAr, args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Run() + return +} + // CompileLibcConfig represents libc compilation configuration type compileLibcConfig struct { Url string - Name string // Libc name (e.g., "picolibc", "musl", "glibc") - Files []string // List of source files to compile - CFlags []string // C compiler flags specific to this libc - LDFlags []string // Linker flags + Name string // Libc name (e.g., "picolibc", "musl", "glibc") + Groups []compileGroup ArchiveSrcDir string } +func (c compileLibcConfig) IsCompiled(outputDir string) bool { + for _, group := range c.Groups { + if !group.IsCompiled(outputDir) { + return false + } + } + return true +} + // GetCompileLibcConfigByName retrieves libc compilation configuration by name // Returns compilation file lists and corresponding cflags func getCompileLibcConfigByName(baseDir, libcName string) (*compileLibcConfig, error) { @@ -27,159 +109,9 @@ func getCompileLibcConfigByName(baseDir, libcName string) (*compileLibcConfig, e switch libcName { case "picolibc": return getPicolibcConfig(libcDir), nil + case "newlib-esp32": + return getNewlibESP32Config(libcDir, "xtensa"), nil default: return nil, fmt.Errorf("unsupported libc: %s", libcName) } } - -// getPicolibcConfig returns configuration for picolibc -func getPicolibcConfig(baseDir string) *compileLibcConfig { - libcIncludeDir := filepath.Join(baseDir, "libc", "include") - libmIncludeDir := filepath.Join(baseDir, "libm", "common") - localeIncludeDir := filepath.Join(baseDir, "libc", "locale") - - os.MkdirAll(baseDir, 0700) - - headerFile, _ := os.Create(filepath.Join(baseDir, "picolibc.h")) - headerFile.Close() - - return &compileLibcConfig{ - Url: "https://github.com/picolibc/picolibc/releases/download/1.8.10/picolibc-1.8.10.tar.xz", - Name: "picolibc", - Files: []string{ - filepath.Join(baseDir, "libc", "string", "bcmp.c"), - filepath.Join(baseDir, "libc", "string", "bcopy.c"), - filepath.Join(baseDir, "libc", "string", "bzero.c"), - filepath.Join(baseDir, "libc", "string", "explicit_bzero.c"), - filepath.Join(baseDir, "libc", "string", "ffsl.c"), - filepath.Join(baseDir, "libc", "string", "ffsll.c"), - filepath.Join(baseDir, "libc", "string", "fls.c"), - filepath.Join(baseDir, "libc", "string", "flsl.c"), - filepath.Join(baseDir, "libc", "string", "flsll.c"), - filepath.Join(baseDir, "libc", "string", "gnu_basename.c"), - filepath.Join(baseDir, "libc", "string", "index.c"), - filepath.Join(baseDir, "libc", "string", "memccpy.c"), - filepath.Join(baseDir, "libc", "string", "memchr.c"), - filepath.Join(baseDir, "libc", "string", "memcmp.c"), - filepath.Join(baseDir, "libc", "string", "memcpy.c"), - filepath.Join(baseDir, "libc", "string", "memmem.c"), - filepath.Join(baseDir, "libc", "string", "memmove.c"), - filepath.Join(baseDir, "libc", "string", "mempcpy.c"), - filepath.Join(baseDir, "libc", "string", "memrchr.c"), - filepath.Join(baseDir, "libc", "string", "memset.c"), - filepath.Join(baseDir, "libc", "string", "rawmemchr.c"), - filepath.Join(baseDir, "libc", "string", "rindex.c"), - filepath.Join(baseDir, "libc", "string", "stpcpy.c"), - filepath.Join(baseDir, "libc", "string", "stpncpy.c"), - filepath.Join(baseDir, "libc", "string", "strcasecmp.c"), - filepath.Join(baseDir, "libc", "string", "strcasecmp_l.c"), - filepath.Join(baseDir, "libc", "string", "strcasestr.c"), - filepath.Join(baseDir, "libc", "string", "strcat.c"), - filepath.Join(baseDir, "libc", "string", "strchr.c"), - filepath.Join(baseDir, "libc", "string", "strchrnul.c"), - filepath.Join(baseDir, "libc", "string", "strcmp.c"), - filepath.Join(baseDir, "libc", "string", "strcoll.c"), - filepath.Join(baseDir, "libc", "string", "strcoll_l.c"), - filepath.Join(baseDir, "libc", "string", "strcpy.c"), - filepath.Join(baseDir, "libc", "string", "strcspn.c"), - filepath.Join(baseDir, "libc", "string", "strerror_r.c"), - filepath.Join(baseDir, "libc", "string", "strlcat.c"), - filepath.Join(baseDir, "libc", "string", "strlcpy.c"), - filepath.Join(baseDir, "libc", "string", "strlen.c"), - filepath.Join(baseDir, "libc", "string", "strlwr.c"), - filepath.Join(baseDir, "libc", "string", "strncasecmp.c"), - filepath.Join(baseDir, "libc", "string", "strncasecmp_l.c"), - filepath.Join(baseDir, "libc", "string", "strncat.c"), - filepath.Join(baseDir, "libc", "string", "strncmp.c"), - filepath.Join(baseDir, "libc", "string", "strncpy.c"), - filepath.Join(baseDir, "libc", "string", "strndup.c"), - filepath.Join(baseDir, "libc", "string", "strnlen.c"), - filepath.Join(baseDir, "libc", "string", "strnstr.c"), - filepath.Join(baseDir, "libc", "string", "strpbrk.c"), - filepath.Join(baseDir, "libc", "string", "strrchr.c"), - filepath.Join(baseDir, "libc", "string", "strsep.c"), - filepath.Join(baseDir, "libc", "string", "strsignal.c"), - filepath.Join(baseDir, "libc", "string", "strspn.c"), - filepath.Join(baseDir, "libc", "string", "strstr.c"), - filepath.Join(baseDir, "libc", "string", "strtok.c"), - filepath.Join(baseDir, "libc", "string", "strtok_r.c"), - filepath.Join(baseDir, "libc", "string", "strupr.c"), - filepath.Join(baseDir, "libc", "string", "strverscmp.c"), - filepath.Join(baseDir, "libc", "string", "strxfrm.c"), - filepath.Join(baseDir, "libc", "string", "strxfrm_l.c"), - filepath.Join(baseDir, "libc", "string", "swab.c"), - filepath.Join(baseDir, "libc", "string", "timingsafe_bcmp.c"), - filepath.Join(baseDir, "libc", "string", "timingsafe_memcmp.c"), - filepath.Join(baseDir, "libc", "string", "strerror.c"), - filepath.Join(baseDir, "libc", "string", "wcpcpy.c"), - filepath.Join(baseDir, "libc", "string", "wcpncpy.c"), - filepath.Join(baseDir, "libc", "string", "wcscasecmp.c"), - filepath.Join(baseDir, "libc", "string", "wcscasecmp_l.c"), - filepath.Join(baseDir, "libc", "string", "wcscat.c"), - filepath.Join(baseDir, "libc", "string", "wcschr.c"), - filepath.Join(baseDir, "libc", "string", "wcscmp.c"), - filepath.Join(baseDir, "libc", "string", "wcscoll.c"), - filepath.Join(baseDir, "libc", "string", "wcscoll_l.c"), - filepath.Join(baseDir, "libc", "string", "wcscpy.c"), - filepath.Join(baseDir, "libc", "string", "wcscspn.c"), - filepath.Join(baseDir, "libc", "string", "wcsdup.c"), - filepath.Join(baseDir, "libc", "string", "wcslcat.c"), - filepath.Join(baseDir, "libc", "string", "wcslcpy.c"), - filepath.Join(baseDir, "libc", "string", "wcslen.c"), - filepath.Join(baseDir, "libc", "string", "wcsncasecmp.c"), - filepath.Join(baseDir, "libc", "string", "wcsncasecmp_l.c"), - filepath.Join(baseDir, "libc", "string", "wcsncat.c"), - filepath.Join(baseDir, "libc", "string", "wcsncmp.c"), - filepath.Join(baseDir, "libc", "string", "wcsncpy.c"), - filepath.Join(baseDir, "libc", "string", "wcsnlen.c"), - filepath.Join(baseDir, "libc", "string", "wcspbrk.c"), - filepath.Join(baseDir, "libc", "string", "wcsrchr.c"), - filepath.Join(baseDir, "libc", "string", "wcsspn.c"), - filepath.Join(baseDir, "libc", "string", "wcsstr.c"), - filepath.Join(baseDir, "libc", "string", "wcstok.c"), - filepath.Join(baseDir, "libc", "string", "wcswidth.c"), - filepath.Join(baseDir, "libc", "string", "wcsxfrm.c"), - filepath.Join(baseDir, "libc", "string", "wcsxfrm_l.c"), - filepath.Join(baseDir, "libc", "string", "wcwidth.c"), - filepath.Join(baseDir, "libc", "string", "wmemchr.c"), - filepath.Join(baseDir, "libc", "string", "wmemcmp.c"), - filepath.Join(baseDir, "libc", "string", "wmemcpy.c"), - filepath.Join(baseDir, "libc", "string", "wmemmove.c"), - filepath.Join(baseDir, "libc", "string", "wmempcpy.c"), - filepath.Join(baseDir, "libc", "string", "wmemset.c"), - filepath.Join(baseDir, "libc", "string", "xpg_strerror_r.c"), - - filepath.Join(baseDir, "libc", "stdlib", "nano-calloc.c"), - filepath.Join(baseDir, "libc", "stdlib", "nano-malloc.c"), - filepath.Join(baseDir, "libc", "stdlib", "nano-pvalloc.c"), - filepath.Join(baseDir, "libc", "stdlib", "nano-realloc.c"), - filepath.Join(baseDir, "libc", "stdlib", "nano-valloc.c"), - filepath.Join(baseDir, "libc", "stdlib", "rand.c"), - filepath.Join(baseDir, "libc", "stdlib", "srand.c"), - filepath.Join(baseDir, "libc", "stdlib", "nano-free.c"), - - filepath.Join(baseDir, "libc", "tinystdio", "printf.c"), - filepath.Join(baseDir, "libc", "tinystdio", "putchar.c"), - filepath.Join(baseDir, "libc", "tinystdio", "puts.c"), - }, - CFlags: []string{ - "-D_COMPILING_NEWLIB", - "-D_HAVE_ALIAS_ATTRIBUTE", - "-DTINY_STDIO", - "-DPOSIX_IO", - "-DFORMAT_DEFAULT_INTEGER", - "-D_IEEE_LIBM", - "-D__OBSOLETE_MATH_FLOAT=1", - "-D__OBSOLETE_MATH_DOUBLE=0", - "-D_WANT_IO_C99_FORMATS", - "-nostdlib", - "-isystem" + libcIncludeDir, - "-I" + libmIncludeDir, - "-I" + localeIncludeDir, - "-I" + baseDir, - "-I" + filepath.Join(baseDir, "libc", "tinystdio"), - }, - LDFlags: []string{"-nostdlib"}, - ArchiveSrcDir: filepath.Join("picolibc-1.8.10", "newlib"), - } -} diff --git a/internal/crosscompile/newlibesp.go b/internal/crosscompile/newlibesp.go new file mode 100644 index 00000000..d70723f1 --- /dev/null +++ b/internal/crosscompile/newlibesp.go @@ -0,0 +1,990 @@ +package crosscompile + +import ( + "path/filepath" +) + +// getNewlibESP32Config returns configuration for newlib esp32 +func getNewlibESP32Config(baseDir, arch string) *compileLibcConfig { + libcDir := filepath.Join(baseDir, "newlib", "libc") + + // headerFile, _ := os.Create(filepath.Join(baseDir, "picolibc.h")) + // headerFile.Close() + + return &compileLibcConfig{ + Url: "https://github.com/MeteorsLiu/newlib-esp32/archive/refs/heads/esp-4.3.0.zip", + Name: "newlib-esp32", + Groups: []compileGroup{ + { + OutputFileName: "libcrt0.a", + Files: []string{ + filepath.Join(baseDir, "libgloss", "xtensa", "clibrary_init.c"), + filepath.Join(baseDir, "libgloss", "xtensa", "syscalls.c"), + filepath.Join(baseDir, "libgloss", "xtensa", "boards", "esp32", "board.c"), + filepath.Join(baseDir, "libgloss", "xtensa", "crt1-boards.S"), + filepath.Join(baseDir, "libgloss", "xtensa", "sleep.S"), + filepath.Join(baseDir, "libgloss", "xtensa", "window-vectors.S"), + }, + CFlags: []string{ + "-DHAVE_CONFIG_H", + "-D_LIBGLOSS", + "-isystem" + filepath.Join(libcDir, "include"), + "-I" + filepath.Join(baseDir, "libgloss"), + // TODO(MeteorsLiu): support riscv + "-I" + filepath.Join(baseDir, "libgloss", "xtensa", "include"), + "-I" + filepath.Join(baseDir, "libgloss", "xtensa", "boards", "esp32", "include"), + }, + LDFlags: []string{"-nostdlib"}, + CCFlags: []string{ + "-Oz", + }, + }, + { + OutputFileName: "libgloss.a", + Files: []string{ + filepath.Join(baseDir, "libgloss", "libnosys", "chown.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "close.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "environ.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "errno.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "execve.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "fork.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "fstat.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "getpid.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "gettod.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "isatty.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "kill.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "link.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "lseek.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "open.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "read.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "readlink.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "sbrk.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "stat.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "symlink.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "times.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "unlink.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "wait.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "write.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "getentropy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "_exit.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "getreent.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "time.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "fcntl.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "chdir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "chmod.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "closedir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "dirfd.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "ftw.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "getcwd.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "mkdir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "nftw.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "opendir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pathconf.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "readdir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "rewinddir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "scandir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "seekdir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "telldir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "rename.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "_pthread_cleanup_pop.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "_pthread_cleanup_pop_restore.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "_pthread_cleanup_push.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "_pthread_cleanup_push_defer.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_atfork.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getaffinity_np.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getdetachstate.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getguardsize.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getinheritsched.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getschedparam.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getschedpolicy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getscope.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getstack.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getstackaddr.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getstacksize.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setaffinity_np.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setdetachstate.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setguardsize.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setinheritsched.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setschedparam.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setschedpolicy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setscope.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setstack.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setstackaddr.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setstacksize.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_barrier_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_barrier_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_barrier_wait.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_barrierattr_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_barrierattr_getpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_barrierattr_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_barrierattr_setpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cancel.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cond_broadcast.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cond_clockwait.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cond_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cond_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cond_signal.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cond_timedwait.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cond_wait.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_condattr_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_condattr_getclock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_condattr_getpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_condattr_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_condattr_setclock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_condattr_setpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_create.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_detach.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_equal.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_exit.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_getaffinity_np.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_getattr_np.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_getconcurrency.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_getcpuclockid.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_getname_np.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_getschedparam.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_getspecific.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_join.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_key_create.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_key_delete.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_clocklock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_getprioceiling.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_lock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_setprioceiling.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_timedlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_trylock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_unlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_getprioceiling.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_getprotocol.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_getpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_gettype.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_setprioceiling.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_setprotocol.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_setpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_settype.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_once.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_clockrdlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_clockwrlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_rdlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_timedrdlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_timedwrlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_tryrdlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_trywrlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_unlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_wrlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlockattr_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlockattr_getpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlockattr_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlockattr_setpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_self.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setaffinity_np.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setcancelstate.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setcanceltype.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setconcurrency.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setname_np.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setschedparam.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setschedprio.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setspecific.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_spin_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_spin_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_spin_lock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_spin_trylock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_spin_unlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_testcancel.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_yield.c"), + }, + CFlags: []string{ + "-D__NO_SYSCALLS__", + "-D_NO_GETUT", + "-DHAVE_CONFIG_H", + "-D_LIBC", + "-D_NO_GLOB", + "-D_NO_GETPWENT", + "-D_NO_SIGSET", + "-D__ESP__", + "-D_NO_GETPASS", + "-D_NO_POSIX_SPAWN", + "-DHAVE_FCNTL", + "-DHAVE_BLKSIZE", + "-DHAVE_OPENDIR", + "-D_GNU_SOURCE", + "-D_LIBGLOSS", + "-D_NO_EXECVE", + "-D_NO_GETLOGIN", + "-D_NO_WORDEXP", + "-D_NO_POPEN", + "-DHAVE_RENAME", + "-DGETREENT_PROVIDED", + "-DSIGNAL_PROVIDED", + "-isystem" + filepath.Join(libcDir, "include"), + "-I" + libcDir, + "-I" + filepath.Join(libcDir, "xtensa"), + "-I" + filepath.Join(baseDir, "libgloss"), + // TODO(MeteorsLiu): support riscv + "-I" + filepath.Join(baseDir, "libgloss", "xtensa", "include"), + "-I" + filepath.Join(baseDir, "libgloss", "xtensa", "boards", "esp32", "include"), + }, + LDFlags: []string{"-nostdlib"}, + CCFlags: []string{ + "-Oz", + }, + }, + { + OutputFileName: "libc.a", + Files: []string{ + filepath.Join(libcDir, "argz", "argz_add.c"), + filepath.Join(libcDir, "argz", "argz_add_sep.c"), + filepath.Join(libcDir, "argz", "argz_append.c"), + filepath.Join(libcDir, "argz", "argz_count.c"), + filepath.Join(libcDir, "argz", "argz_create.c"), + filepath.Join(libcDir, "argz", "argz_create_sep.c"), + filepath.Join(libcDir, "argz", "argz_delete.c"), + filepath.Join(libcDir, "argz", "argz_extract.c"), + filepath.Join(libcDir, "argz", "argz_insert.c"), + filepath.Join(libcDir, "argz", "argz_next.c"), + filepath.Join(libcDir, "argz", "argz_replace.c"), + filepath.Join(libcDir, "argz", "argz_stringify.c"), + filepath.Join(libcDir, "argz", "buf_findstr.c"), + filepath.Join(libcDir, "argz", "envz_entry.c"), + filepath.Join(libcDir, "argz", "envz_get.c"), + filepath.Join(libcDir, "argz", "envz_add.c"), + filepath.Join(libcDir, "argz", "envz_remove.c"), + filepath.Join(libcDir, "argz", "envz_merge.c"), + filepath.Join(libcDir, "argz", "envz_strip.c"), + filepath.Join(libcDir, "stdlib", "__adjust.c"), + filepath.Join(libcDir, "stdlib", "__atexit.c"), + filepath.Join(libcDir, "stdlib", "__call_atexit.c"), + filepath.Join(libcDir, "stdlib", "__exp10.c"), + filepath.Join(libcDir, "stdlib", "__ten_mu.c"), + filepath.Join(libcDir, "stdlib", "_Exit.c"), + filepath.Join(libcDir, "stdlib", "abort.c"), + filepath.Join(libcDir, "stdlib", "abs.c"), + filepath.Join(libcDir, "stdlib", "aligned_alloc.c"), + filepath.Join(libcDir, "stdlib", "assert.c"), + filepath.Join(libcDir, "stdlib", "atexit.c"), + filepath.Join(libcDir, "stdlib", "atof.c"), + filepath.Join(libcDir, "stdlib", "atoff.c"), + filepath.Join(libcDir, "stdlib", "atoi.c"), + filepath.Join(libcDir, "stdlib", "atol.c"), + filepath.Join(libcDir, "stdlib", "calloc.c"), + filepath.Join(libcDir, "stdlib", "callocr.c"), + filepath.Join(libcDir, "stdlib", "cfreer.c"), + filepath.Join(libcDir, "stdlib", "div.c"), + filepath.Join(libcDir, "stdlib", "dtoa.c"), + filepath.Join(libcDir, "stdlib", "dtoastub.c"), + filepath.Join(libcDir, "stdlib", "environ.c"), + filepath.Join(libcDir, "stdlib", "envlock.c"), + filepath.Join(libcDir, "stdlib", "eprintf.c"), + filepath.Join(libcDir, "stdlib", "exit.c"), + filepath.Join(libcDir, "stdlib", "freer.c"), + filepath.Join(libcDir, "stdlib", "gdtoa-gethex.c"), + filepath.Join(libcDir, "stdlib", "gdtoa-hexnan.c"), + filepath.Join(libcDir, "stdlib", "getenv.c"), + filepath.Join(libcDir, "stdlib", "getenv_r.c"), + filepath.Join(libcDir, "stdlib", "imaxabs.c"), + filepath.Join(libcDir, "stdlib", "imaxdiv.c"), + filepath.Join(libcDir, "stdlib", "itoa.c"), + filepath.Join(libcDir, "stdlib", "labs.c"), + filepath.Join(libcDir, "stdlib", "ldiv.c"), + filepath.Join(libcDir, "stdlib", "ldtoa.c"), + filepath.Join(libcDir, "stdlib", "gdtoa-ldtoa.c"), + filepath.Join(libcDir, "stdlib", "gdtoa-gdtoa.c"), + filepath.Join(libcDir, "stdlib", "gdtoa-dmisc.c"), + filepath.Join(libcDir, "stdlib", "gdtoa-gmisc.c"), + filepath.Join(libcDir, "stdlib", "mallinfor.c"), + filepath.Join(libcDir, "stdlib", "malloc.c"), + filepath.Join(libcDir, "stdlib", "mallocr.c"), + filepath.Join(libcDir, "stdlib", "mallstatsr.c"), + filepath.Join(libcDir, "stdlib", "mblen.c"), + filepath.Join(libcDir, "stdlib", "mblen_r.c"), + filepath.Join(libcDir, "stdlib", "mbstowcs.c"), + filepath.Join(libcDir, "stdlib", "mbstowcs_r.c"), + filepath.Join(libcDir, "stdlib", "mbtowc.c"), + filepath.Join(libcDir, "stdlib", "mbtowc_r.c"), + filepath.Join(libcDir, "stdlib", "mlock.c"), + filepath.Join(libcDir, "stdlib", "mprec.c"), + filepath.Join(libcDir, "stdlib", "msizer.c"), + filepath.Join(libcDir, "stdlib", "mstats.c"), + filepath.Join(libcDir, "stdlib", "on_exit_args.c"), + filepath.Join(libcDir, "stdlib", "quick_exit.c"), + filepath.Join(libcDir, "stdlib", "rand.c"), + filepath.Join(libcDir, "stdlib", "rand_r.c"), + filepath.Join(libcDir, "stdlib", "random.c"), + filepath.Join(libcDir, "stdlib", "realloc.c"), + filepath.Join(libcDir, "stdlib", "reallocarray.c"), + filepath.Join(libcDir, "stdlib", "reallocf.c"), + filepath.Join(libcDir, "stdlib", "reallocr.c"), + filepath.Join(libcDir, "stdlib", "sb_charsets.c"), + filepath.Join(libcDir, "stdlib", "strtod.c"), + filepath.Join(libcDir, "stdlib", "strtoimax.c"), + filepath.Join(libcDir, "stdlib", "strtol.c"), + filepath.Join(libcDir, "stdlib", "strtoul.c"), + filepath.Join(libcDir, "stdlib", "strtoumax.c"), + filepath.Join(libcDir, "stdlib", "utoa.c"), + filepath.Join(libcDir, "stdlib", "wcstod.c"), + filepath.Join(libcDir, "stdlib", "wcstoimax.c"), + filepath.Join(libcDir, "stdlib", "wcstol.c"), + filepath.Join(libcDir, "stdlib", "wcstoul.c"), + filepath.Join(libcDir, "stdlib", "wcstoumax.c"), + filepath.Join(libcDir, "stdlib", "wcstombs.c"), + filepath.Join(libcDir, "stdlib", "wcstombs_r.c"), + filepath.Join(libcDir, "stdlib", "wctomb.c"), + filepath.Join(libcDir, "stdlib", "wctomb_r.c"), + filepath.Join(libcDir, "stdlib", "strtodg.c"), + filepath.Join(libcDir, "stdlib", "strtold.c"), + filepath.Join(libcDir, "stdlib", "strtorx.c"), + filepath.Join(libcDir, "stdlib", "wcstold.c"), + filepath.Join(libcDir, "stdlib", "arc4random.c"), + filepath.Join(libcDir, "stdlib", "arc4random_uniform.c"), + filepath.Join(libcDir, "stdlib", "cxa_atexit.c"), + filepath.Join(libcDir, "stdlib", "cxa_finalize.c"), + filepath.Join(libcDir, "stdlib", "drand48.c"), + filepath.Join(libcDir, "stdlib", "ecvtbuf.c"), + filepath.Join(libcDir, "stdlib", "efgcvt.c"), + filepath.Join(libcDir, "stdlib", "erand48.c"), + filepath.Join(libcDir, "stdlib", "jrand48.c"), + filepath.Join(libcDir, "stdlib", "lcong48.c"), + filepath.Join(libcDir, "stdlib", "lrand48.c"), + filepath.Join(libcDir, "stdlib", "mrand48.c"), + filepath.Join(libcDir, "stdlib", "msize.c"), + filepath.Join(libcDir, "stdlib", "mtrim.c"), + filepath.Join(libcDir, "stdlib", "nrand48.c"), + filepath.Join(libcDir, "stdlib", "rand48.c"), + filepath.Join(libcDir, "stdlib", "seed48.c"), + filepath.Join(libcDir, "stdlib", "srand48.c"), + filepath.Join(libcDir, "stdlib", "strtoll.c"), + filepath.Join(libcDir, "stdlib", "strtoll_r.c"), + filepath.Join(libcDir, "stdlib", "strtoull.c"), + filepath.Join(libcDir, "stdlib", "strtoull_r.c"), + filepath.Join(libcDir, "stdlib", "wcstoll.c"), + filepath.Join(libcDir, "stdlib", "wcstoll_r.c"), + filepath.Join(libcDir, "stdlib", "wcstoull.c"), + filepath.Join(libcDir, "stdlib", "wcstoull_r.c"), + filepath.Join(libcDir, "stdlib", "atoll.c"), + filepath.Join(libcDir, "stdlib", "llabs.c"), + filepath.Join(libcDir, "stdlib", "lldiv.c"), + filepath.Join(libcDir, "stdlib", "a64l.c"), + filepath.Join(libcDir, "stdlib", "btowc.c"), + filepath.Join(libcDir, "stdlib", "getopt.c"), + filepath.Join(libcDir, "stdlib", "getsubopt.c"), + filepath.Join(libcDir, "stdlib", "l64a.c"), + filepath.Join(libcDir, "stdlib", "malign.c"), + filepath.Join(libcDir, "stdlib", "malignr.c"), + filepath.Join(libcDir, "stdlib", "malloptr.c"), + filepath.Join(libcDir, "stdlib", "mbrlen.c"), + filepath.Join(libcDir, "stdlib", "mbrtowc.c"), + filepath.Join(libcDir, "stdlib", "mbsinit.c"), + filepath.Join(libcDir, "stdlib", "mbsnrtowcs.c"), + filepath.Join(libcDir, "stdlib", "mbsrtowcs.c"), + filepath.Join(libcDir, "stdlib", "on_exit.c"), + filepath.Join(libcDir, "stdlib", "pvallocr.c"), + filepath.Join(libcDir, "stdlib", "valloc.c"), + filepath.Join(libcDir, "stdlib", "vallocr.c"), + filepath.Join(libcDir, "stdlib", "wcrtomb.c"), + filepath.Join(libcDir, "stdlib", "wcsnrtombs.c"), + filepath.Join(libcDir, "stdlib", "wcsrtombs.c"), + filepath.Join(libcDir, "stdlib", "wctob.c"), + filepath.Join(libcDir, "stdlib", "putenv.c"), + filepath.Join(libcDir, "stdlib", "putenv_r.c"), + filepath.Join(libcDir, "stdlib", "setenv.c"), + filepath.Join(libcDir, "stdlib", "setenv_r.c"), + filepath.Join(libcDir, "stdlib", "rpmatch.c"), + filepath.Join(libcDir, "stdlib", "system.c"), + filepath.Join(libcDir, "ctype", "ctype_.c"), + filepath.Join(libcDir, "ctype", "isalnum.c"), + filepath.Join(libcDir, "ctype", "isalpha.c"), + filepath.Join(libcDir, "ctype", "iscntrl.c"), + filepath.Join(libcDir, "ctype", "isdigit.c"), + filepath.Join(libcDir, "ctype", "islower.c"), + filepath.Join(libcDir, "ctype", "isupper.c"), + filepath.Join(libcDir, "ctype", "isprint.c"), + filepath.Join(libcDir, "ctype", "ispunct.c"), + filepath.Join(libcDir, "ctype", "isspace.c"), + filepath.Join(libcDir, "ctype", "isxdigit.c"), + filepath.Join(libcDir, "ctype", "tolower.c"), + filepath.Join(libcDir, "ctype", "toupper.c"), + filepath.Join(libcDir, "ctype", "categories.c"), + filepath.Join(libcDir, "ctype", "isalnum_l.c"), + filepath.Join(libcDir, "ctype", "isalpha_l.c"), + filepath.Join(libcDir, "ctype", "isascii.c"), + filepath.Join(libcDir, "ctype", "isascii_l.c"), + filepath.Join(libcDir, "ctype", "isblank.c"), + filepath.Join(libcDir, "ctype", "isblank_l.c"), + filepath.Join(libcDir, "ctype", "iscntrl_l.c"), + filepath.Join(libcDir, "ctype", "isdigit_l.c"), + filepath.Join(libcDir, "ctype", "islower_l.c"), + filepath.Join(libcDir, "ctype", "isupper_l.c"), + filepath.Join(libcDir, "ctype", "isprint_l.c"), + filepath.Join(libcDir, "ctype", "ispunct_l.c"), + filepath.Join(libcDir, "ctype", "isspace_l.c"), + filepath.Join(libcDir, "ctype", "iswalnum.c"), + filepath.Join(libcDir, "ctype", "iswalnum_l.c"), + filepath.Join(libcDir, "ctype", "iswalpha.c"), + filepath.Join(libcDir, "ctype", "iswalpha_l.c"), + filepath.Join(libcDir, "ctype", "iswblank.c"), + filepath.Join(libcDir, "ctype", "iswblank_l.c"), + filepath.Join(libcDir, "ctype", "iswcntrl.c"), + filepath.Join(libcDir, "ctype", "iswcntrl_l.c"), + filepath.Join(libcDir, "ctype", "iswctype.c"), + filepath.Join(libcDir, "ctype", "iswctype_l.c"), + filepath.Join(libcDir, "ctype", "iswdigit.c"), + filepath.Join(libcDir, "ctype", "iswdigit_l.c"), + filepath.Join(libcDir, "ctype", "iswgraph.c"), + filepath.Join(libcDir, "ctype", "iswgraph_l.c"), + filepath.Join(libcDir, "ctype", "iswlower.c"), + filepath.Join(libcDir, "ctype", "iswlower_l.c"), + filepath.Join(libcDir, "ctype", "iswprint.c"), + filepath.Join(libcDir, "ctype", "iswprint_l.c"), + filepath.Join(libcDir, "ctype", "iswpunct.c"), + filepath.Join(libcDir, "ctype", "iswpunct_l.c"), + filepath.Join(libcDir, "ctype", "iswspace.c"), + filepath.Join(libcDir, "ctype", "iswspace_l.c"), + filepath.Join(libcDir, "ctype", "iswupper.c"), + filepath.Join(libcDir, "ctype", "iswupper_l.c"), + filepath.Join(libcDir, "ctype", "iswxdigit.c"), + filepath.Join(libcDir, "ctype", "iswxdigit_l.c"), + filepath.Join(libcDir, "ctype", "isxdigit_l.c"), + filepath.Join(libcDir, "ctype", "jp2uc.c"), + filepath.Join(libcDir, "ctype", "toascii.c"), + filepath.Join(libcDir, "ctype", "toascii_l.c"), + filepath.Join(libcDir, "ctype", "tolower_l.c"), + filepath.Join(libcDir, "ctype", "toupper_l.c"), + filepath.Join(libcDir, "ctype", "towctrans.c"), + filepath.Join(libcDir, "ctype", "towctrans_l.c"), + filepath.Join(libcDir, "ctype", "towlower.c"), + filepath.Join(libcDir, "ctype", "towlower_l.c"), + filepath.Join(libcDir, "ctype", "towupper.c"), + filepath.Join(libcDir, "ctype", "towupper_l.c"), + filepath.Join(libcDir, "ctype", "wctrans.c"), + filepath.Join(libcDir, "ctype", "wctrans_l.c"), + filepath.Join(libcDir, "ctype", "wctype.c"), + filepath.Join(libcDir, "ctype", "wctype_l.c"), + filepath.Join(libcDir, "search", "bsearch.c"), + filepath.Join(libcDir, "search", "ndbm.c"), + filepath.Join(libcDir, "search", "qsort.c"), + filepath.Join(libcDir, "search", "hash.c"), + filepath.Join(libcDir, "search", "hash_bigkey.c"), + filepath.Join(libcDir, "search", "hash_buf.c"), + filepath.Join(libcDir, "search", "hash_func.c"), + filepath.Join(libcDir, "search", "hash_log2.c"), + filepath.Join(libcDir, "search", "hash_page.c"), + filepath.Join(libcDir, "search", "hcreate.c"), + filepath.Join(libcDir, "search", "hcreate_r.c"), + filepath.Join(libcDir, "search", "tdelete.c"), + filepath.Join(libcDir, "search", "tdestroy.c"), + filepath.Join(libcDir, "search", "tfind.c"), + filepath.Join(libcDir, "search", "tsearch.c"), + filepath.Join(libcDir, "search", "twalk.c"), + filepath.Join(libcDir, "search", "bsd_qsort_r.c"), + filepath.Join(libcDir, "search", "qsort_r.c"), + filepath.Join(libcDir, "stdio", "nano-vfprintf_float.c"), + filepath.Join(libcDir, "stdio", "nano-svfprintf.c"), + filepath.Join(libcDir, "stdio", "nano-svfscanf.c"), + filepath.Join(libcDir, "stdio", "nano-vfprintf.c"), + filepath.Join(libcDir, "stdio", "nano-vfprintf_i.c"), + filepath.Join(libcDir, "stdio", "nano-vfscanf.c"), + filepath.Join(libcDir, "stdio", "nano-vfscanf_i.c"), + filepath.Join(libcDir, "stdio", "nano-vfscanf_float.c"), + filepath.Join(libcDir, "stdio", "clearerr.c"), + filepath.Join(libcDir, "stdio", "fclose.c"), + filepath.Join(libcDir, "stdio", "fdopen.c"), + filepath.Join(libcDir, "stdio", "feof.c"), + filepath.Join(libcDir, "stdio", "ferror.c"), + filepath.Join(libcDir, "stdio", "fflush.c"), + filepath.Join(libcDir, "stdio", "fgetc.c"), + filepath.Join(libcDir, "stdio", "fgetpos.c"), + filepath.Join(libcDir, "stdio", "fgets.c"), + filepath.Join(libcDir, "stdio", "fileno.c"), + filepath.Join(libcDir, "stdio", "findfp.c"), + filepath.Join(libcDir, "stdio", "flags.c"), + filepath.Join(libcDir, "stdio", "fopen.c"), + filepath.Join(libcDir, "stdio", "fprintf.c"), + filepath.Join(libcDir, "stdio", "fputc.c"), + filepath.Join(libcDir, "stdio", "fputs.c"), + filepath.Join(libcDir, "stdio", "fread.c"), + filepath.Join(libcDir, "stdio", "freopen.c"), + filepath.Join(libcDir, "stdio", "fscanf.c"), + filepath.Join(libcDir, "stdio", "fseek.c"), + filepath.Join(libcDir, "stdio", "fsetpos.c"), + filepath.Join(libcDir, "stdio", "ftell.c"), + filepath.Join(libcDir, "stdio", "fvwrite.c"), + filepath.Join(libcDir, "stdio", "fwalk.c"), + filepath.Join(libcDir, "stdio", "fwrite.c"), + filepath.Join(libcDir, "stdio", "getc.c"), + filepath.Join(libcDir, "stdio", "getchar.c"), + filepath.Join(libcDir, "stdio", "getc_u.c"), + filepath.Join(libcDir, "stdio", "getchar_u.c"), + filepath.Join(libcDir, "stdio", "getdelim.c"), + filepath.Join(libcDir, "stdio", "getline.c"), + filepath.Join(libcDir, "stdio", "gets.c"), + filepath.Join(libcDir, "stdio", "makebuf.c"), + filepath.Join(libcDir, "stdio", "perror.c"), + filepath.Join(libcDir, "stdio", "printf.c"), + filepath.Join(libcDir, "stdio", "putc.c"), + filepath.Join(libcDir, "stdio", "putchar.c"), + filepath.Join(libcDir, "stdio", "putc_u.c"), + filepath.Join(libcDir, "stdio", "putchar_u.c"), + filepath.Join(libcDir, "stdio", "puts.c"), + filepath.Join(libcDir, "stdio", "refill.c"), + filepath.Join(libcDir, "stdio", "remove.c"), + filepath.Join(libcDir, "stdio", "rename.c"), + filepath.Join(libcDir, "stdio", "rewind.c"), + filepath.Join(libcDir, "stdio", "rget.c"), + filepath.Join(libcDir, "stdio", "scanf.c"), + filepath.Join(libcDir, "stdio", "sccl.c"), + filepath.Join(libcDir, "stdio", "setbuf.c"), + filepath.Join(libcDir, "stdio", "setbuffer.c"), + filepath.Join(libcDir, "stdio", "setlinebuf.c"), + filepath.Join(libcDir, "stdio", "setvbuf.c"), + filepath.Join(libcDir, "stdio", "snprintf.c"), + filepath.Join(libcDir, "stdio", "sprintf.c"), + filepath.Join(libcDir, "stdio", "sscanf.c"), + filepath.Join(libcDir, "stdio", "stdio.c"), + filepath.Join(libcDir, "stdio", "svfiwprintf.c"), + filepath.Join(libcDir, "stdio", "svfiwscanf.c"), + filepath.Join(libcDir, "stdio", "svfwprintf.c"), + filepath.Join(libcDir, "stdio", "svfwscanf.c"), + filepath.Join(libcDir, "stdio", "tmpfile.c"), + filepath.Join(libcDir, "stdio", "tmpnam.c"), + filepath.Join(libcDir, "stdio", "ungetc.c"), + filepath.Join(libcDir, "stdio", "vdprintf.c"), + filepath.Join(libcDir, "stdio", "vfiwprintf.c"), + filepath.Join(libcDir, "stdio", "vfiwscanf.c"), + filepath.Join(libcDir, "stdio", "vfwscanf.c"), + filepath.Join(libcDir, "stdio", "vprintf.c"), + filepath.Join(libcDir, "stdio", "vscanf.c"), + filepath.Join(libcDir, "stdio", "vsnprintf.c"), + filepath.Join(libcDir, "stdio", "vsprintf.c"), + filepath.Join(libcDir, "stdio", "vsscanf.c"), + filepath.Join(libcDir, "stdio", "wbuf.c"), + filepath.Join(libcDir, "stdio", "wsetup.c"), + filepath.Join(libcDir, "stdio", "asprintf.c"), + filepath.Join(libcDir, "stdio", "fcloseall.c"), + filepath.Join(libcDir, "stdio", "fseeko.c"), + filepath.Join(libcDir, "stdio", "ftello.c"), + filepath.Join(libcDir, "stdio", "getw.c"), + filepath.Join(libcDir, "stdio", "mktemp.c"), + filepath.Join(libcDir, "stdio", "putw.c"), + filepath.Join(libcDir, "stdio", "vasprintf.c"), + filepath.Join(libcDir, "stdio", "asnprintf.c"), + filepath.Join(libcDir, "stdio", "clearerr_u.c"), + filepath.Join(libcDir, "stdio", "dprintf.c"), + filepath.Join(libcDir, "stdio", "feof_u.c"), + filepath.Join(libcDir, "stdio", "ferror_u.c"), + filepath.Join(libcDir, "stdio", "fflush_u.c"), + filepath.Join(libcDir, "stdio", "fgetc_u.c"), + filepath.Join(libcDir, "stdio", "fgets_u.c"), + filepath.Join(libcDir, "stdio", "fgetwc.c"), + filepath.Join(libcDir, "stdio", "fgetwc_u.c"), + filepath.Join(libcDir, "stdio", "fgetws.c"), + filepath.Join(libcDir, "stdio", "fgetws_u.c"), + filepath.Join(libcDir, "stdio", "fileno_u.c"), + filepath.Join(libcDir, "stdio", "fmemopen.c"), + filepath.Join(libcDir, "stdio", "fopencookie.c"), + filepath.Join(libcDir, "stdio", "fpurge.c"), + filepath.Join(libcDir, "stdio", "fputc_u.c"), + filepath.Join(libcDir, "stdio", "fputs_u.c"), + filepath.Join(libcDir, "stdio", "fputwc.c"), + filepath.Join(libcDir, "stdio", "fputwc_u.c"), + filepath.Join(libcDir, "stdio", "fputws.c"), + filepath.Join(libcDir, "stdio", "fputws_u.c"), + filepath.Join(libcDir, "stdio", "fread_u.c"), + filepath.Join(libcDir, "stdio", "fsetlocking.c"), + filepath.Join(libcDir, "stdio", "funopen.c"), + filepath.Join(libcDir, "stdio", "fwide.c"), + filepath.Join(libcDir, "stdio", "fwprintf.c"), + filepath.Join(libcDir, "stdio", "fwrite_u.c"), + filepath.Join(libcDir, "stdio", "fwscanf.c"), + filepath.Join(libcDir, "stdio", "getwc.c"), + filepath.Join(libcDir, "stdio", "getwc_u.c"), + filepath.Join(libcDir, "stdio", "getwchar.c"), + filepath.Join(libcDir, "stdio", "getwchar_u.c"), + filepath.Join(libcDir, "stdio", "open_memstream.c"), + filepath.Join(libcDir, "stdio", "putwc.c"), + filepath.Join(libcDir, "stdio", "putwc_u.c"), + filepath.Join(libcDir, "stdio", "putwchar.c"), + filepath.Join(libcDir, "stdio", "putwchar_u.c"), + filepath.Join(libcDir, "stdio", "stdio_ext.c"), + filepath.Join(libcDir, "stdio", "swprintf.c"), + filepath.Join(libcDir, "stdio", "swscanf.c"), + filepath.Join(libcDir, "stdio", "ungetwc.c"), + filepath.Join(libcDir, "stdio", "vasnprintf.c"), + filepath.Join(libcDir, "stdio", "vswprintf.c"), + filepath.Join(libcDir, "stdio", "vswscanf.c"), + filepath.Join(libcDir, "stdio", "vwprintf.c"), + filepath.Join(libcDir, "stdio", "vwscanf.c"), + filepath.Join(libcDir, "stdio", "wprintf.c"), + filepath.Join(libcDir, "stdio", "wscanf.c"), + filepath.Join(libcDir, "string", "bcopy.c"), + filepath.Join(libcDir, "string", "bzero.c"), + filepath.Join(libcDir, "string", "explicit_bzero.c"), + filepath.Join(libcDir, "string", "ffsl.c"), + filepath.Join(libcDir, "string", "ffsll.c"), + filepath.Join(libcDir, "string", "fls.c"), + filepath.Join(libcDir, "string", "flsl.c"), + filepath.Join(libcDir, "string", "flsll.c"), + filepath.Join(libcDir, "string", "index.c"), + filepath.Join(libcDir, "string", "memchr.c"), + filepath.Join(libcDir, "string", "memcmp.c"), + filepath.Join(libcDir, "string", "memmove.c"), + filepath.Join(libcDir, "string", "rindex.c"), + filepath.Join(libcDir, "string", "strcasecmp.c"), + filepath.Join(libcDir, "string", "strcat.c"), + filepath.Join(libcDir, "string", "strchr.c"), + filepath.Join(libcDir, "string", "strcoll.c"), + filepath.Join(libcDir, "string", "strcspn.c"), + filepath.Join(libcDir, "string", "strdup.c"), + filepath.Join(libcDir, "string", "strdup_r.c"), + filepath.Join(libcDir, "string", "strerror.c"), + filepath.Join(libcDir, "string", "strerror_r.c"), + filepath.Join(libcDir, "string", "strlcat.c"), + filepath.Join(libcDir, "string", "strlcpy.c"), + filepath.Join(libcDir, "string", "strlwr.c"), + filepath.Join(libcDir, "string", "strncasecmp.c"), + filepath.Join(libcDir, "string", "strncat.c"), + filepath.Join(libcDir, "string", "strncmp.c"), + filepath.Join(libcDir, "string", "strnlen.c"), + filepath.Join(libcDir, "string", "strnstr.c"), + filepath.Join(libcDir, "string", "strpbrk.c"), + filepath.Join(libcDir, "string", "strrchr.c"), + filepath.Join(libcDir, "string", "strsep.c"), + filepath.Join(libcDir, "string", "strsignal.c"), + filepath.Join(libcDir, "string", "strspn.c"), + filepath.Join(libcDir, "string", "strtok.c"), + filepath.Join(libcDir, "string", "strtok_r.c"), + filepath.Join(libcDir, "string", "strupr.c"), + filepath.Join(libcDir, "string", "strxfrm.c"), + filepath.Join(libcDir, "string", "strstr.c"), + filepath.Join(libcDir, "string", "swab.c"), + filepath.Join(libcDir, "string", "timingsafe_bcmp.c"), + filepath.Join(libcDir, "string", "timingsafe_memcmp.c"), + filepath.Join(libcDir, "string", "u_strerr.c"), + filepath.Join(libcDir, "string", "wcscat.c"), + filepath.Join(libcDir, "string", "wcschr.c"), + filepath.Join(libcDir, "string", "wcscmp.c"), + filepath.Join(libcDir, "string", "wcscoll.c"), + filepath.Join(libcDir, "string", "wcscpy.c"), + filepath.Join(libcDir, "string", "wcscspn.c"), + filepath.Join(libcDir, "string", "wcslcat.c"), + filepath.Join(libcDir, "string", "wcslcpy.c"), + filepath.Join(libcDir, "string", "wcslen.c"), + filepath.Join(libcDir, "string", "wcsncat.c"), + filepath.Join(libcDir, "string", "wcsncmp.c"), + filepath.Join(libcDir, "string", "wcsncpy.c"), + filepath.Join(libcDir, "string", "wcsnlen.c"), + filepath.Join(libcDir, "string", "wcspbrk.c"), + filepath.Join(libcDir, "string", "wcsrchr.c"), + filepath.Join(libcDir, "string", "wcsspn.c"), + filepath.Join(libcDir, "string", "wcsstr.c"), + filepath.Join(libcDir, "string", "wcstok.c"), + filepath.Join(libcDir, "string", "wcswidth.c"), + filepath.Join(libcDir, "string", "wcsxfrm.c"), + filepath.Join(libcDir, "string", "wcwidth.c"), + filepath.Join(libcDir, "string", "wmemchr.c"), + filepath.Join(libcDir, "string", "wmemcmp.c"), + filepath.Join(libcDir, "string", "wmemcpy.c"), + filepath.Join(libcDir, "string", "wmemmove.c"), + filepath.Join(libcDir, "string", "wmemset.c"), + filepath.Join(libcDir, "string", "xpg_strerror_r.c"), + filepath.Join(libcDir, "string", "bcmp.c"), + filepath.Join(libcDir, "string", "memccpy.c"), + filepath.Join(libcDir, "string", "mempcpy.c"), + filepath.Join(libcDir, "string", "stpcpy.c"), + filepath.Join(libcDir, "string", "stpncpy.c"), + filepath.Join(libcDir, "string", "strndup.c"), + filepath.Join(libcDir, "string", "strcasestr.c"), + filepath.Join(libcDir, "string", "strchrnul.c"), + filepath.Join(libcDir, "string", "strndup_r.c"), + filepath.Join(libcDir, "string", "wcpcpy.c"), + filepath.Join(libcDir, "string", "wcpncpy.c"), + filepath.Join(libcDir, "string", "wcsdup.c"), + filepath.Join(libcDir, "string", "gnu_basename.c"), + filepath.Join(libcDir, "string", "memmem.c"), + filepath.Join(libcDir, "string", "memrchr.c"), + filepath.Join(libcDir, "string", "rawmemchr.c"), + filepath.Join(libcDir, "string", "strcasecmp_l.c"), + filepath.Join(libcDir, "string", "strcoll_l.c"), + filepath.Join(libcDir, "string", "strncasecmp_l.c"), + filepath.Join(libcDir, "string", "strverscmp.c"), + filepath.Join(libcDir, "string", "strxfrm_l.c"), + filepath.Join(libcDir, "string", "wcscasecmp.c"), + filepath.Join(libcDir, "string", "wcscasecmp_l.c"), + filepath.Join(libcDir, "string", "wcscoll_l.c"), + filepath.Join(libcDir, "string", "wcsncasecmp.c"), + filepath.Join(libcDir, "string", "wcsncasecmp_l.c"), + filepath.Join(libcDir, "string", "wcsxfrm_l.c"), + filepath.Join(libcDir, "string", "wmempcpy.c"), + filepath.Join(libcDir, "signal", "psignal.c"), + filepath.Join(libcDir, "signal", "raise.c"), + filepath.Join(libcDir, "signal", "signal.c"), + filepath.Join(libcDir, "signal", "sig2str.c"), + filepath.Join(libcDir, "time", "asctime.c"), + filepath.Join(libcDir, "time", "asctime_r.c"), + filepath.Join(libcDir, "time", "clock.c"), + filepath.Join(libcDir, "time", "ctime.c"), + filepath.Join(libcDir, "time", "ctime_r.c"), + filepath.Join(libcDir, "time", "difftime.c"), + filepath.Join(libcDir, "time", "gettzinfo.c"), + filepath.Join(libcDir, "time", "gmtime.c"), + filepath.Join(libcDir, "time", "gmtime_r.c"), + filepath.Join(libcDir, "time", "lcltime.c"), + filepath.Join(libcDir, "time", "lcltime_r.c"), + filepath.Join(libcDir, "time", "mktime.c"), + filepath.Join(libcDir, "time", "month_lengths.c"), + filepath.Join(libcDir, "time", "strftime.c"), + filepath.Join(libcDir, "time", "strptime.c"), + filepath.Join(libcDir, "time", "time.c"), + filepath.Join(libcDir, "time", "tzcalc_limits.c"), + filepath.Join(libcDir, "time", "tzlock.c"), + filepath.Join(libcDir, "time", "tzset.c"), + filepath.Join(libcDir, "time", "tzset_r.c"), + filepath.Join(libcDir, "time", "tzvars.c"), + filepath.Join(libcDir, "time", "wcsftime.c"), + filepath.Join(libcDir, "locale", "locale.c"), + filepath.Join(libcDir, "locale", "localeconv.c"), + filepath.Join(libcDir, "locale", "duplocale.c"), + filepath.Join(libcDir, "locale", "freelocale.c"), + filepath.Join(libcDir, "locale", "lctype.c"), + filepath.Join(libcDir, "locale", "lmessages.c"), + filepath.Join(libcDir, "locale", "lnumeric.c"), + filepath.Join(libcDir, "locale", "lmonetary.c"), + filepath.Join(libcDir, "locale", "newlocale.c"), + filepath.Join(libcDir, "locale", "nl_langinfo.c"), + filepath.Join(libcDir, "locale", "timelocal.c"), + filepath.Join(libcDir, "locale", "uselocale.c"), + filepath.Join(libcDir, "reent", "closer.c"), + filepath.Join(libcDir, "reent", "reent.c"), + filepath.Join(libcDir, "reent", "impure.c"), + filepath.Join(libcDir, "reent", "fcntlr.c"), + filepath.Join(libcDir, "reent", "fstatr.c"), + filepath.Join(libcDir, "reent", "getentropyr.c"), + filepath.Join(libcDir, "reent", "getreent.c"), + filepath.Join(libcDir, "reent", "gettimeofdayr.c"), + filepath.Join(libcDir, "reent", "isattyr.c"), + filepath.Join(libcDir, "reent", "linkr.c"), + filepath.Join(libcDir, "reent", "lseekr.c"), + filepath.Join(libcDir, "reent", "mkdirr.c"), + filepath.Join(libcDir, "reent", "openr.c"), + filepath.Join(libcDir, "reent", "readr.c"), + filepath.Join(libcDir, "reent", "renamer.c"), + filepath.Join(libcDir, "reent", "signalr.c"), + filepath.Join(libcDir, "reent", "signgam.c"), + filepath.Join(libcDir, "reent", "sbrkr.c"), + filepath.Join(libcDir, "reent", "statr.c"), + filepath.Join(libcDir, "reent", "timesr.c"), + filepath.Join(libcDir, "reent", "unlinkr.c"), + filepath.Join(libcDir, "reent", "writer.c"), + filepath.Join(libcDir, "reent", "execr.c"), + filepath.Join(libcDir, "errno", "errno.c"), + filepath.Join(libcDir, "misc", "__dprintf.c"), + filepath.Join(libcDir, "misc", "unctrl.c"), + filepath.Join(libcDir, "misc", "ffs.c"), + filepath.Join(libcDir, "misc", "init.c"), + filepath.Join(libcDir, "misc", "fini.c"), + filepath.Join(libcDir, "misc", "lock.c"), + filepath.Join(libcDir, "posix", "closedir.c"), + filepath.Join(libcDir, "posix", "collate.c"), + filepath.Join(libcDir, "posix", "collcmp.c"), + filepath.Join(libcDir, "posix", "creat.c"), + filepath.Join(libcDir, "posix", "dirfd.c"), + // filepath.Join(libcDir, "posix", "fnmatch.c"), + filepath.Join(libcDir, "posix", "glob.c"), + filepath.Join(libcDir, "posix", "opendir.c"), + filepath.Join(libcDir, "posix", "readdir.c"), + filepath.Join(libcDir, "posix", "readdir_r.c"), + filepath.Join(libcDir, "posix", "regcomp.c"), + filepath.Join(libcDir, "posix", "regerror.c"), + filepath.Join(libcDir, "posix", "regexec.c"), + filepath.Join(libcDir, "posix", "regfree.c"), + filepath.Join(libcDir, "posix", "rewinddir.c"), + filepath.Join(libcDir, "posix", "sleep.c"), + filepath.Join(libcDir, "posix", "usleep.c"), + filepath.Join(libcDir, "posix", "telldir.c"), + filepath.Join(libcDir, "posix", "ftw.c"), + filepath.Join(libcDir, "posix", "nftw.c"), + filepath.Join(libcDir, "posix", "scandir.c"), + filepath.Join(libcDir, "posix", "seekdir.c"), + filepath.Join(libcDir, "posix", "execl.c"), + filepath.Join(libcDir, "posix", "execle.c"), + filepath.Join(libcDir, "posix", "execlp.c"), + filepath.Join(libcDir, "posix", "execv.c"), + filepath.Join(libcDir, "posix", "execve.c"), + filepath.Join(libcDir, "posix", "execvp.c"), + filepath.Join(libcDir, "posix", "wordexp.c"), + filepath.Join(libcDir, "posix", "wordfree.c"), + filepath.Join(libcDir, "posix", "popen.c"), + filepath.Join(libcDir, "posix", "posix_spawn.c"), + filepath.Join(libcDir, "syscalls", "sysclose.c"), + filepath.Join(libcDir, "syscalls", "sysfcntl.c"), + filepath.Join(libcDir, "syscalls", "sysfstat.c"), + filepath.Join(libcDir, "syscalls", "sysgetentropy.c"), + filepath.Join(libcDir, "syscalls", "sysgetpid.c"), + filepath.Join(libcDir, "syscalls", "sysgettod.c"), + filepath.Join(libcDir, "syscalls", "sysisatty.c"), + filepath.Join(libcDir, "syscalls", "syskill.c"), + filepath.Join(libcDir, "syscalls", "syslink.c"), + filepath.Join(libcDir, "syscalls", "syslseek.c"), + filepath.Join(libcDir, "syscalls", "sysopen.c"), + filepath.Join(libcDir, "syscalls", "sysread.c"), + filepath.Join(libcDir, "syscalls", "syssbrk.c"), + filepath.Join(libcDir, "syscalls", "sysstat.c"), + filepath.Join(libcDir, "syscalls", "systimes.c"), + filepath.Join(libcDir, "syscalls", "sysunlink.c"), + filepath.Join(libcDir, "syscalls", "syswrite.c"), + filepath.Join(libcDir, "syscalls", "sysexecve.c"), + filepath.Join(libcDir, "syscalls", "sysfork.c"), + filepath.Join(libcDir, "syscalls", "syswait.c"), + filepath.Join(libcDir, "iconv", "ces", "utf-8.c"), + filepath.Join(libcDir, "iconv", "ces", "utf-16.c"), + filepath.Join(libcDir, "iconv", "ces", "ucs-2.c"), + filepath.Join(libcDir, "iconv", "ces", "us-ascii.c"), + filepath.Join(libcDir, "iconv", "ces", "ucs-4.c"), + filepath.Join(libcDir, "iconv", "ces", "ucs-2-internal.c"), + filepath.Join(libcDir, "iconv", "ces", "ucs-4-internal.c"), + filepath.Join(libcDir, "iconv", "ces", "cesbi.c"), + filepath.Join(libcDir, "iconv", "ces", "table.c"), + filepath.Join(libcDir, "iconv", "ces", "table-pcs.c"), + filepath.Join(libcDir, "iconv", "ces", "euc.c"), + filepath.Join(libcDir, "iconv", "ccs", "ccsbi.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_10.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_13.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_14.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_15.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_1.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_2.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_3.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_4.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_5.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_6.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_7.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_8.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_9.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_11.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1250.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1252.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1254.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1256.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1258.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1251.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1253.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1255.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1257.c"), + filepath.Join(libcDir, "iconv", "ccs", "koi8_r.c"), + filepath.Join(libcDir, "iconv", "ccs", "koi8_u.c"), + filepath.Join(libcDir, "iconv", "ccs", "koi8_ru.c"), + filepath.Join(libcDir, "iconv", "ccs", "koi8_uni.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_ir_111.c"), + filepath.Join(libcDir, "iconv", "ccs", "big5.c"), + filepath.Join(libcDir, "iconv", "ccs", "cp775.c"), + filepath.Join(libcDir, "iconv", "ccs", "cp850.c"), + filepath.Join(libcDir, "iconv", "ccs", "cp852.c"), + filepath.Join(libcDir, "iconv", "ccs", "cp855.c"), + filepath.Join(libcDir, "iconv", "ccs", "cp866.c"), + filepath.Join(libcDir, "iconv", "ccs", "jis_x0212_1990.c"), + filepath.Join(libcDir, "iconv", "ccs", "jis_x0201_1976.c"), + filepath.Join(libcDir, "iconv", "ccs", "jis_x0208_1990.c"), + filepath.Join(libcDir, "iconv", "ccs", "ksx1001.c"), + filepath.Join(libcDir, "iconv", "ccs", "cns11643_plane1.c"), + filepath.Join(libcDir, "iconv", "ccs", "cns11643_plane2.c"), + filepath.Join(libcDir, "iconv", "ccs", "cns11643_plane14.c"), + filepath.Join(libcDir, "iconv", "lib", "aliasesi.c"), + filepath.Join(libcDir, "iconv", "lib", "ucsconv.c"), + filepath.Join(libcDir, "iconv", "lib", "nullconv.c"), + filepath.Join(libcDir, "iconv", "lib", "iconv.c"), + filepath.Join(libcDir, "iconv", "lib", "aliasesbi.c"), + filepath.Join(libcDir, "iconv", "lib", "iconvnls.c"), + filepath.Join(libcDir, "ssp", "chk_fail.c"), + filepath.Join(libcDir, "ssp", "stack_protector.c"), + filepath.Join(libcDir, "ssp", "memcpy_chk.c"), + filepath.Join(libcDir, "ssp", "memmove_chk.c"), + filepath.Join(libcDir, "ssp", "mempcpy_chk.c"), + filepath.Join(libcDir, "ssp", "memset_chk.c"), + filepath.Join(libcDir, "ssp", "stpcpy_chk.c"), + filepath.Join(libcDir, "ssp", "stpncpy_chk.c"), + filepath.Join(libcDir, "ssp", "strcat_chk.c"), + filepath.Join(libcDir, "ssp", "strcpy_chk.c"), + filepath.Join(libcDir, "ssp", "strncat_chk.c"), + filepath.Join(libcDir, "ssp", "strncpy_chk.c"), + filepath.Join(libcDir, "ssp", "gets_chk.c"), + filepath.Join(libcDir, "ssp", "snprintf_chk.c"), + filepath.Join(libcDir, "ssp", "sprintf_chk.c"), + filepath.Join(libcDir, "ssp", "vsnprintf_chk.c"), + filepath.Join(libcDir, "ssp", "vsprintf_chk.c"), + // TODO(MeteorsLiu): support riscv + filepath.Join(libcDir, "machine", "xtensa", "memcpy.S"), + filepath.Join(libcDir, "machine", "xtensa", "memset.S"), + filepath.Join(libcDir, "machine", "xtensa", "setjmp.S"), + filepath.Join(libcDir, "machine", "xtensa", "strcmp.S"), + filepath.Join(libcDir, "machine", "xtensa", "strcpy.S"), + filepath.Join(libcDir, "machine", "xtensa", "strlen.S"), + filepath.Join(libcDir, "machine", "xtensa", "strncpy.S"), + }, + CFlags: []string{ + "-DHAVE_CONFIG_H", + "-D_LIBC", + "-D__NO_SYSCALLS__", + "-D_NO_GLOB", + "-D_NO_EXECVE", + "-D_NO_GETLOGIN", + "-D_NO_GETPWENT", + "-D_NO_GETUT", + "-D_NO_GETPASS", + "-D_NO_SIGSET", + "-D_NO_WORDEXP", + "-D_NO_POPEN", + "-D_NO_POSIX_SPAWN", + "-DHAVE_FCNTL", + "-DHAVE_BLKSIZE", + "-DHAVE_OPENDIR", + "-DHAVE_RENAME", + "-DGETREENT_PROVIDED", + "-DSIGNAL_PROVIDED", + "-D__ESP__", + "-isystem" + filepath.Join(libcDir, "include"), + "-I" + filepath.Join(baseDir, "newlib"), + "-I" + libcDir, + "-I" + filepath.Join(libcDir, "xtensa"), + "-I" + filepath.Join(baseDir, "libgloss"), + // TODO(MeteorsLiu): support riscv + "-idirafter" + filepath.Join(baseDir, "include"), + "-I" + filepath.Join(libcDir, "ssp"), + "-I" + filepath.Join(libcDir, "locale"), + "-I" + filepath.Join(libcDir, "errno"), + "-I" + filepath.Join(libcDir, "syscalls"), + "-I" + filepath.Join(libcDir, "iconv", "lib"), + "-I" + filepath.Join(libcDir, "argz"), + "-I" + filepath.Join(libcDir, "stdio"), + "-I" + filepath.Join(libcDir, "iconv", "ccs"), + "-I" + filepath.Join(libcDir, "ctype"), + "-I" + filepath.Join(libcDir, "signal"), + "-I" + filepath.Join(libcDir, "time"), + "-I" + filepath.Join(libcDir, "reent"), + "-I" + filepath.Join(libcDir, "machine", "xtensa", "include"), + "-I" + filepath.Join(libcDir, "string"), + "-I" + filepath.Join(libcDir, "iconv", "ces"), + "-I" + filepath.Join(libcDir, "search"), + "-I" + filepath.Join(libcDir, "misc"), + "-I" + filepath.Join(libcDir, "posix"), + "-I" + filepath.Join(libcDir, "stdlib"), + }, + LDFlags: []string{"-nostdlib", "-L" + baseDir, "-lgloss"}, + CCFlags: []string{ + "-Oz", + "-fno-builtin", + "-ffreestanding", + "-Wno-implicit-function-declaration", + "-Wno-int-conversion", + "-Wno-unused-command-line-argument", + }, + }, + }, + ArchiveSrcDir: "newlib-esp32-esp-4.3.0", + } +} diff --git a/internal/crosscompile/picolibc.go b/internal/crosscompile/picolibc.go new file mode 100644 index 00000000..b31405d6 --- /dev/null +++ b/internal/crosscompile/picolibc.go @@ -0,0 +1,166 @@ +package crosscompile + +import ( + "os" + "path/filepath" +) + +// getPicolibcConfig returns configuration for picolibc +func getPicolibcConfig(baseDir string) *compileLibcConfig { + libcIncludeDir := filepath.Join(baseDir, "libc", "include") + libmIncludeDir := filepath.Join(baseDir, "libm", "common") + localeIncludeDir := filepath.Join(baseDir, "libc", "locale") + + os.MkdirAll(baseDir, 0700) + + headerFile, _ := os.Create(filepath.Join(baseDir, "picolibc.h")) + headerFile.Close() + + return &compileLibcConfig{ + Url: "https://github.com/picolibc/picolibc/releases/download/1.8.10/picolibc-1.8.10.tar.xz", + Name: "picolibc", + Groups: []compileGroup{ + { + OutputFileName: "libc.a", + Files: []string{ + filepath.Join(baseDir, "libc", "string", "bcmp.c"), + filepath.Join(baseDir, "libc", "string", "bcopy.c"), + filepath.Join(baseDir, "libc", "string", "bzero.c"), + filepath.Join(baseDir, "libc", "string", "explicit_bzero.c"), + filepath.Join(baseDir, "libc", "string", "ffsl.c"), + filepath.Join(baseDir, "libc", "string", "ffsll.c"), + filepath.Join(baseDir, "libc", "string", "fls.c"), + filepath.Join(baseDir, "libc", "string", "flsl.c"), + filepath.Join(baseDir, "libc", "string", "flsll.c"), + filepath.Join(baseDir, "libc", "string", "gnu_basename.c"), + filepath.Join(baseDir, "libc", "string", "index.c"), + filepath.Join(baseDir, "libc", "string", "memccpy.c"), + filepath.Join(baseDir, "libc", "string", "memchr.c"), + filepath.Join(baseDir, "libc", "string", "memcmp.c"), + filepath.Join(baseDir, "libc", "string", "memcpy.c"), + filepath.Join(baseDir, "libc", "string", "memmem.c"), + filepath.Join(baseDir, "libc", "string", "memmove.c"), + filepath.Join(baseDir, "libc", "string", "mempcpy.c"), + filepath.Join(baseDir, "libc", "string", "memrchr.c"), + filepath.Join(baseDir, "libc", "string", "memset.c"), + filepath.Join(baseDir, "libc", "string", "rawmemchr.c"), + filepath.Join(baseDir, "libc", "string", "rindex.c"), + filepath.Join(baseDir, "libc", "string", "stpcpy.c"), + filepath.Join(baseDir, "libc", "string", "stpncpy.c"), + filepath.Join(baseDir, "libc", "string", "strcasecmp.c"), + filepath.Join(baseDir, "libc", "string", "strcasecmp_l.c"), + filepath.Join(baseDir, "libc", "string", "strcasestr.c"), + filepath.Join(baseDir, "libc", "string", "strcat.c"), + filepath.Join(baseDir, "libc", "string", "strchr.c"), + filepath.Join(baseDir, "libc", "string", "strchrnul.c"), + filepath.Join(baseDir, "libc", "string", "strcmp.c"), + filepath.Join(baseDir, "libc", "string", "strcoll.c"), + filepath.Join(baseDir, "libc", "string", "strcoll_l.c"), + filepath.Join(baseDir, "libc", "string", "strcpy.c"), + filepath.Join(baseDir, "libc", "string", "strcspn.c"), + filepath.Join(baseDir, "libc", "string", "strerror_r.c"), + filepath.Join(baseDir, "libc", "string", "strlcat.c"), + filepath.Join(baseDir, "libc", "string", "strlcpy.c"), + filepath.Join(baseDir, "libc", "string", "strlen.c"), + filepath.Join(baseDir, "libc", "string", "strlwr.c"), + filepath.Join(baseDir, "libc", "string", "strncasecmp.c"), + filepath.Join(baseDir, "libc", "string", "strncasecmp_l.c"), + filepath.Join(baseDir, "libc", "string", "strncat.c"), + filepath.Join(baseDir, "libc", "string", "strncmp.c"), + filepath.Join(baseDir, "libc", "string", "strncpy.c"), + filepath.Join(baseDir, "libc", "string", "strndup.c"), + filepath.Join(baseDir, "libc", "string", "strnlen.c"), + filepath.Join(baseDir, "libc", "string", "strnstr.c"), + filepath.Join(baseDir, "libc", "string", "strpbrk.c"), + filepath.Join(baseDir, "libc", "string", "strrchr.c"), + filepath.Join(baseDir, "libc", "string", "strsep.c"), + filepath.Join(baseDir, "libc", "string", "strsignal.c"), + filepath.Join(baseDir, "libc", "string", "strspn.c"), + filepath.Join(baseDir, "libc", "string", "strstr.c"), + filepath.Join(baseDir, "libc", "string", "strtok.c"), + filepath.Join(baseDir, "libc", "string", "strtok_r.c"), + filepath.Join(baseDir, "libc", "string", "strupr.c"), + filepath.Join(baseDir, "libc", "string", "strverscmp.c"), + filepath.Join(baseDir, "libc", "string", "strxfrm.c"), + filepath.Join(baseDir, "libc", "string", "strxfrm_l.c"), + filepath.Join(baseDir, "libc", "string", "swab.c"), + filepath.Join(baseDir, "libc", "string", "timingsafe_bcmp.c"), + filepath.Join(baseDir, "libc", "string", "timingsafe_memcmp.c"), + filepath.Join(baseDir, "libc", "string", "strerror.c"), + filepath.Join(baseDir, "libc", "string", "wcpcpy.c"), + filepath.Join(baseDir, "libc", "string", "wcpncpy.c"), + filepath.Join(baseDir, "libc", "string", "wcscasecmp.c"), + filepath.Join(baseDir, "libc", "string", "wcscasecmp_l.c"), + filepath.Join(baseDir, "libc", "string", "wcscat.c"), + filepath.Join(baseDir, "libc", "string", "wcschr.c"), + filepath.Join(baseDir, "libc", "string", "wcscmp.c"), + filepath.Join(baseDir, "libc", "string", "wcscoll.c"), + filepath.Join(baseDir, "libc", "string", "wcscoll_l.c"), + filepath.Join(baseDir, "libc", "string", "wcscpy.c"), + filepath.Join(baseDir, "libc", "string", "wcscspn.c"), + filepath.Join(baseDir, "libc", "string", "wcsdup.c"), + filepath.Join(baseDir, "libc", "string", "wcslcat.c"), + filepath.Join(baseDir, "libc", "string", "wcslcpy.c"), + filepath.Join(baseDir, "libc", "string", "wcslen.c"), + filepath.Join(baseDir, "libc", "string", "wcsncasecmp.c"), + filepath.Join(baseDir, "libc", "string", "wcsncasecmp_l.c"), + filepath.Join(baseDir, "libc", "string", "wcsncat.c"), + filepath.Join(baseDir, "libc", "string", "wcsncmp.c"), + filepath.Join(baseDir, "libc", "string", "wcsncpy.c"), + filepath.Join(baseDir, "libc", "string", "wcsnlen.c"), + filepath.Join(baseDir, "libc", "string", "wcspbrk.c"), + filepath.Join(baseDir, "libc", "string", "wcsrchr.c"), + filepath.Join(baseDir, "libc", "string", "wcsspn.c"), + filepath.Join(baseDir, "libc", "string", "wcsstr.c"), + filepath.Join(baseDir, "libc", "string", "wcstok.c"), + filepath.Join(baseDir, "libc", "string", "wcswidth.c"), + filepath.Join(baseDir, "libc", "string", "wcsxfrm.c"), + filepath.Join(baseDir, "libc", "string", "wcsxfrm_l.c"), + filepath.Join(baseDir, "libc", "string", "wcwidth.c"), + filepath.Join(baseDir, "libc", "string", "wmemchr.c"), + filepath.Join(baseDir, "libc", "string", "wmemcmp.c"), + filepath.Join(baseDir, "libc", "string", "wmemcpy.c"), + filepath.Join(baseDir, "libc", "string", "wmemmove.c"), + filepath.Join(baseDir, "libc", "string", "wmempcpy.c"), + filepath.Join(baseDir, "libc", "string", "wmemset.c"), + filepath.Join(baseDir, "libc", "string", "xpg_strerror_r.c"), + + filepath.Join(baseDir, "libc", "stdlib", "nano-calloc.c"), + filepath.Join(baseDir, "libc", "stdlib", "nano-malloc.c"), + filepath.Join(baseDir, "libc", "stdlib", "nano-pvalloc.c"), + filepath.Join(baseDir, "libc", "stdlib", "nano-realloc.c"), + filepath.Join(baseDir, "libc", "stdlib", "nano-valloc.c"), + filepath.Join(baseDir, "libc", "stdlib", "rand.c"), + filepath.Join(baseDir, "libc", "stdlib", "srand.c"), + filepath.Join(baseDir, "libc", "stdlib", "nano-free.c"), + + filepath.Join(baseDir, "libc", "tinystdio", "printf.c"), + filepath.Join(baseDir, "libc", "tinystdio", "putchar.c"), + filepath.Join(baseDir, "libc", "tinystdio", "puts.c"), + }, + CFlags: []string{ + "-D_COMPILING_NEWLIB", + "-D_HAVE_ALIAS_ATTRIBUTE", + "-DTINY_STDIO", + "-DPOSIX_IO", + "-DFORMAT_DEFAULT_INTEGER", + "-D_IEEE_LIBM", + "-D__OBSOLETE_MATH_FLOAT=1", + "-D__OBSOLETE_MATH_DOUBLE=0", + "-D_WANT_IO_C99_FORMATS", + "-nostdlib", + "-isystem" + libcIncludeDir, + "-I" + libmIncludeDir, + "-I" + localeIncludeDir, + "-I" + baseDir, + "-I" + filepath.Join(baseDir, "libc", "tinystdio"), + }, + LDFlags: []string{"-nostdlib"}, + CCFlags: []string{ + "-Oz", + }, + }, + }, + ArchiveSrcDir: filepath.Join("picolibc-1.8.10", "newlib"), + } +} diff --git a/targets/esp32.app.elf.ld b/targets/esp32.app.elf.ld new file mode 100755 index 00000000..88e6cf26 --- /dev/null +++ b/targets/esp32.app.elf.ld @@ -0,0 +1,185 @@ +__stack = ORIGIN(dram_seg) + LENGTH(dram_seg); +__MIN_STACK_SIZE = 0x2000; + +ENTRY(_start) +SECTIONS +{ + . = SEGMENT_START("iram_seg", 0); + .vectors : + { + _vector_table = ABSOLUTE(.); + KEEP(*(.WindowVectors.text)); + KEEP(*(.Level2InterruptVector.text)); + KEEP(*(.Level3InterruptVector.text)); + KEEP(*(.Level4InterruptVector.text)); + KEEP(*(.Level5InterruptVector.text)); + KEEP(*(.DebugExceptionVector.text)); + KEEP(*(.NMIExceptionVector.text)); + KEEP(*(.KernelExceptionVector.text)); + KEEP(*(.UserExceptionVector.text)); + KEEP(*(.DoubleExceptionVector.text)); + KEEP(*(.ResetVector.text)); + *(.*Vector.literal) + . = ALIGN (16); + } > iram_seg + + text : + { + KEEP (*(.init.literal)) + KEEP (*(SORT_NONE(.init))) + *(.literal .text .stub .literal.* .text.* .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + KEEP (*(.fini.literal)) + KEEP (*(SORT_NONE(.fini))) + } > iram_seg + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + + + .rodata : + { + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) + } + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + + _data_start = .; + .data : + { + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + *(.data1) + } + _edata = .; PROVIDE (edata = .); + . = .; + __bss_start = .; + .bss : + { + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we do not + pad the .data section. */ + . = ALIGN(. != 0 ? 32 / 8 : 1); + } + . = ALIGN(32 / 8); + . = ALIGN(32 / 8); + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(. <= __stack - __MIN_STACK_SIZE, "region DRAM overflowed by .data and .bss sections") + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .debug_addr 0 : { *(.debug_addr) } + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} + + +_sbss = __bss_start; +_ebss = _end; + diff --git a/targets/esp32.json b/targets/esp32.json index 841c7d41..5ba0c390 100644 --- a/targets/esp32.json +++ b/targets/esp32.json @@ -1,20 +1,25 @@ { - "inherits": ["xtensa"], + "inherits": [ + "xtensa" + ], "cpu": "esp32", "features": "+atomctl,+bool,+clamps,+coprocessor,+debug,+density,+dfpaccel,+div32,+exception,+fp,+highpriinterrupts,+interrupt,+loop,+mac16,+memctl,+minmax,+miscsr,+mul32,+mul32high,+nsa,+prid,+regprotect,+rvector,+s32c1i,+sext,+threadptr,+timerint,+windowed", - "build-tags": ["esp32", "esp"], + "build-tags": [ + "esp32", + "esp" + ], "scheduler": "tasks", "serial": "uart", "linker": "ld.lld", "default-stack-size": 2048, "rtlib": "compiler-rt", - "libc": "picolibc", - "linkerscript": "targets/esp32.ld", - "extra-files": [ - "targets/device/esp/esp32.S" - ], + "libc": "newlib-esp32", + "linkerscript": "targets/esp32.memory.elf.ld", + "extra-files": [], "binary-format": "esp32", "flash-command": "esptool.py --chip=esp32 --port {port} write_flash 0x1000 {bin} -ff 80m -fm dout", "emulator": "qemu-system-xtensa -machine esp32 -nographic -drive file={img},if=mtd,format=raw", - "gdb": ["xtensa-esp32-elf-gdb"] + "gdb": [ + "xtensa-esp32-elf-gdb" + ] } diff --git a/targets/esp32.ld b/targets/esp32.ld deleted file mode 100644 index 0d5de614..00000000 --- a/targets/esp32.ld +++ /dev/null @@ -1,200 +0,0 @@ -/* Linker script for the ESP32 */ - -MEMORY -{ - /* Data RAM. Allows byte access. - * There are various data RAM regions: - * SRAM2: 0x3FFA_E000..0x3FFD_FFFF (72 + 128 = 200K) - * SRAM1: 0x3FFE_0000..0x3FFF_FFFF (128K) - * This gives us 328K of contiguous RAM, which is the largest span possible. - * SRAM1 has other addresses as well but the datasheet seems to indicate - * these are aliases. - */ - DRAM (rw) : ORIGIN = 0x3FFAE000, LENGTH = 200K + 128K /* Internal SRAM 1 + 2 */ - - /* Instruction RAM. */ - IRAM (x) : ORIGIN = 0x40080000, LENGTH = 128K /* Internal SRAM 0 */ -} - -/* The entry point. It is set in the image flashed to the chip, so must be - * defined. - */ -ENTRY(call_start_cpu0) - -SECTIONS -{ - /* Constant literals and code. Loaded into IRAM for now. Eventually, most - * code should be executed directly from flash. - * Note that literals must be before code for the l32r instruction to work. - */ - .text : ALIGN(4) - { - *(.literal.call_start_cpu0) - *(.text.call_start_cpu0) - *(.literal .text) - *(.literal.* .text.*) - } >IRAM - - /* Put the stack at the bottom of DRAM, so that the application will - * crash on stack overflow instead of silently corrupting memory. - * See: http://blog.japaric.io/stack-overflow-protection/ */ - .stack (NOLOAD) : - { - . = ALIGN(16); - . += _stack_size; - _stack_top = .; - } >DRAM - - /* Constant global variables. - * They are loaded in DRAM for ease of use. Eventually they should be stored - * in flash and loaded directly from there but they're kept in RAM to make - * sure they can always be accessed (even in interrupts). - */ - .rodata : ALIGN(4) - { - *(.rodata) - *(.rodata.*) - } >DRAM - - /* Mutable global variables. - */ - .data : ALIGN(4) - { - _sdata = ABSOLUTE(.); - *(.data) - *(.data.*) - _edata = ABSOLUTE(.); - } >DRAM - - /* Check that the boot ROM stack (for the APP CPU) does not overlap with the - * data that is loaded by the boot ROM. There may be ways to avoid this - * issue if it occurs in practice. - * The magic value here is _stack_sentry in the boot ROM ELF file. - */ - ASSERT(_edata < 0x3ffe1320, "the .data section overlaps with the stack used by the boot ROM, possibly causing corruption at startup") - - /* Global variables that are mutable and zero-initialized. - * These must be zeroed at startup (unlike data, which is loaded by the - * bootloader). - */ - .bss (NOLOAD) : ALIGN(4) - { - . = ALIGN (4); - _sbss = ABSOLUTE(.); - *(.bss) - *(.bss.*) - . = ALIGN (4); - _ebss = ABSOLUTE(.); - } >DRAM -} - -/* For the garbage collector. - */ -_globals_start = _sdata; -_globals_end = _ebss; -_heap_start = _ebss; -_heap_end = ORIGIN(DRAM) + LENGTH(DRAM); - -_stack_size = 4K; - - -/* From ESP-IDF: - * components/esp_rom/esp32/ld/esp32.rom.libgcc.ld - * These are called from LLVM during codegen. The original license is Apache - * 2.0, but I believe that a list of function names and addresses can't really - * be copyrighted. - */ -__absvdi2 = 0x4006387c; -__absvsi2 = 0x40063868; -__adddf3 = 0x40002590; -__addsf3 = 0x400020e8; -__addvdi3 = 0x40002cbc; -__addvsi3 = 0x40002c98; -__ashldi3 = 0x4000c818; -__ashrdi3 = 0x4000c830; -__bswapdi2 = 0x40064b08; -__bswapsi2 = 0x40064ae0; -__clrsbdi2 = 0x40064b7c; -__clrsbsi2 = 0x40064b64; -__clzdi2 = 0x4000ca50; -__clzsi2 = 0x4000c7e8; -__cmpdi2 = 0x40063820; -__ctzdi2 = 0x4000ca64; -__ctzsi2 = 0x4000c7f0; -__divdc3 = 0x400645a4; -__divdf3 = 0x40002954; -__divdi3 = 0x4000ca84; -__divsi3 = 0x4000c7b8; -__eqdf2 = 0x400636a8; -__eqsf2 = 0x40063374; -__extendsfdf2 = 0x40002c34; -__ffsdi2 = 0x4000ca2c; -__ffssi2 = 0x4000c804; -__fixdfdi = 0x40002ac4; -__fixdfsi = 0x40002a78; -__fixsfdi = 0x4000244c; -__fixsfsi = 0x4000240c; -__fixunsdfsi = 0x40002b30; -__fixunssfdi = 0x40002504; -__fixunssfsi = 0x400024ac; -__floatdidf = 0x4000c988; -__floatdisf = 0x4000c8c0; -__floatsidf = 0x4000c944; -__floatsisf = 0x4000c870; -__floatundidf = 0x4000c978; -__floatundisf = 0x4000c8b0; -__floatunsidf = 0x4000c938; -__floatunsisf = 0x4000c864; -__gcc_bcmp = 0x40064a70; -__gedf2 = 0x40063768; -__gesf2 = 0x4006340c; -__gtdf2 = 0x400636dc; -__gtsf2 = 0x400633a0; -__ledf2 = 0x40063704; -__lesf2 = 0x400633c0; -__lshrdi3 = 0x4000c84c; -__ltdf2 = 0x40063790; -__ltsf2 = 0x4006342c; -__moddi3 = 0x4000cd4c; -__modsi3 = 0x4000c7c0; -__muldc3 = 0x40063c90; -__muldf3 = 0x4006358c; -__muldi3 = 0x4000c9fc; -__mulsf3 = 0x400632c8; -__mulsi3 = 0x4000c7b0; -__mulvdi3 = 0x40002d78; -__mulvsi3 = 0x40002d60; -__nedf2 = 0x400636a8; -__negdf2 = 0x400634a0; -__negdi2 = 0x4000ca14; -__negsf2 = 0x400020c0; -__negvdi2 = 0x40002e98; -__negvsi2 = 0x40002e78; -__nesf2 = 0x40063374; -__nsau_data = 0x3ff96544; -__paritysi2 = 0x40002f3c; -__popcount_tab = 0x3ff96544; -__popcountdi2 = 0x40002ef8; -__popcountsi2 = 0x40002ed0; -__powidf2 = 0x400638e4; -__subdf3 = 0x400026e4; -__subsf3 = 0x400021d0; -__subvdi3 = 0x40002d20; -__subvsi3 = 0x40002cf8; -__truncdfsf2 = 0x40002b90; -__ucmpdi2 = 0x40063840; -__udiv_w_sdiv = 0x40064bec; -__udivdi3 = 0x4000cff8; -__udivmoddi4 = 0x40064bf4; -__udivsi3 = 0x4000c7c8; -__umoddi3 = 0x4000d280; -__umodsi3 = 0x4000c7d0; -__umulsidi3 = 0x4000c7d8; -__unorddf2 = 0x400637f4; -__unordsf2 = 0x40063478; - -INCLUDE "targets/esp32.rom.newlib-data.ld"; -INCLUDE "targets/esp32.rom.newlib-funcs.ld"; -INCLUDE "targets/esp32.rom.newlib-locale.ld"; -INCLUDE "targets/esp32.rom.newlib-nano.ld"; -INCLUDE "targets/esp32.rom.newlib-time.ld"; diff --git a/targets/esp32.memory.elf.ld b/targets/esp32.memory.elf.ld new file mode 100755 index 00000000..65976719 --- /dev/null +++ b/targets/esp32.memory.elf.ld @@ -0,0 +1,26 @@ +/* + * IROM/DRAM definition in QEMU: + * [ESP32_MEMREGION_IROM] = { 0x40000000, 0x70000 }, + * [ESP32_MEMREGION_DRAM] = { 0x3ffae000, 0x52000 }, + * + * In theory we could use whole DRAM section, but I had some faults when using + * memory in range 0x3ffae000 - 0x3ffb0000 + * + * But used memory range for data such as esp-idf for ESP32 to satisfy user's + * expectation on chip emulation + * + * Pass '--defsym=entire_dram_seg=1' to linker script to use whole DRAM + * + */ + +MEMORY +{ + iram_seg (X) : org = 0x40078000, len = 0x28000 +/* 64k at the end of DRAM, after ROM bootloader stack + * or entire DRAM (for QEMU only) + */ + dram_seg (RW) : org = 0x3FFF0000 , + len = 0x10000 +} + +INCLUDE "targets/esp32.app.elf.ld"; diff --git a/targets/esp32.rom.newlib-data.ld b/targets/esp32.rom.newlib-data.ld deleted file mode 100644 index ed5795c8..00000000 --- a/targets/esp32.rom.newlib-data.ld +++ /dev/null @@ -1,23 +0,0 @@ -/* These are the .bss/.data symbols used by newlib functions present in ESP32 ROM. - See also esp32.rom.newlib-funcs.ld for the list of general newlib functions, - and esp32.rom.newlib-nano.ld for "nano" versions of printf/scanf family of functions. - - Unlike other ROM functions and data which are exported using PROVIDE, which declares - weak symbols, newlib related functions are exported using assignment, - which declares strong symbols. This is done so that ROM functions are always - used instead of the ones provided by libc.a. - */ - -_ctype_ = 0x3ff96354; -__ctype_ptr__ = 0x3ff96350; -environ = 0x3ffae0b4; -_global_impure_ptr = 0x3ffae0b0; -__mb_cur_max = 0x3ff96530; -__sf_fake_stderr = 0x3ff96458; -__sf_fake_stdin = 0x3ff96498; -__sf_fake_stdout = 0x3ff96478; -__wctomb = 0x3ff96540; -__sfp_lock = 0x3ffae0ac; -__sinit_lock = 0x3ffae0a8; -__env_lock_object = 0x3ffae0b8; -__tz_lock_object = 0x3ffae080; diff --git a/targets/esp32.rom.newlib-funcs.ld b/targets/esp32.rom.newlib-funcs.ld deleted file mode 100644 index 79d5c5be..00000000 --- a/targets/esp32.rom.newlib-funcs.ld +++ /dev/null @@ -1,130 +0,0 @@ -/* These are the newlib functions present in ESP32 ROM. - They should not be used when compiling with PSRAM cache workaround enabled. - See also esp32.rom.newlib-data.ld for the list of .data/.bss symbols - used by these functions, and esp32.rom.newlib-nano.ld for "nano" versions - of printf/scanf family of functions. - - Unlike other ROM functions which are exported using PROVIDE, which declares - weak symbols, newlib related functions are exported using assignment, - which declares strong symbols. This is done so that ROM functions are always - used instead of the ones provided by libc.a. - - Time functions were moved to the esp32.rom.newlib-time.ld file. - */ - -abs = 0x40056340; -__ascii_wctomb = 0x40058ef0; -atoi = 0x400566c4; -_atoi_r = 0x400566d4; -atol = 0x400566ec; -_atol_r = 0x400566fc; -bzero = 0x4000c1f4; -_cleanup = 0x40001df8; -_cleanup_r = 0x40001d48; -creat = 0x40000e8c; -div = 0x40056348; -__dummy_lock = 0x4000c728; -__dummy_lock_try = 0x4000c730; -__env_lock = 0x40001fd4; -__env_unlock = 0x40001fe0; -fclose = 0x400020ac; -_fclose_r = 0x40001fec; -fflush = 0x40059394; -_fflush_r = 0x40059320; -_findenv_r = 0x40001f44; -__fp_lock_all = 0x40001f1c; -__fp_unlock_all = 0x40001f30; -__fputwc = 0x40058da0; -fputwc = 0x40058ea8; -_fputwc_r = 0x40058e4c; -_fwalk = 0x4000c738; -_fwalk_reent = 0x4000c770; -_getenv_r = 0x40001fbc; -isalnum = 0x40000f04; -isalpha = 0x40000f18; -isascii = 0x4000c20c; -isblank = 0x40000f2c; -iscntrl = 0x40000f50; -isdigit = 0x40000f64; -isgraph = 0x40000f94; -islower = 0x40000f78; -isprint = 0x40000fa8; -ispunct = 0x40000fc0; -isspace = 0x40000fd4; -isupper = 0x40000fe8; -__itoa = 0x40056678; -itoa = 0x400566b4; -labs = 0x40056370; -ldiv = 0x40056378; -longjmp = 0x400562cc; -memccpy = 0x4000c220; -memchr = 0x4000c244; -memcmp = 0x4000c260; -memcpy = 0x4000c2c8; -memmove = 0x4000c3c0; -memrchr = 0x4000c400; -memset = 0x4000c44c; -qsort = 0x40056424; -rand = 0x40001058; -rand_r = 0x400010d4; -__sccl = 0x4000c498; -__sclose = 0x400011b8; -__seofread = 0x40001148; -setjmp = 0x40056268; -__sflush_r = 0x400591e0; -__sfmoreglue = 0x40001dc8; -__sfp = 0x40001e90; -__sfp_lock_acquire = 0x40001e08; -__sfp_lock_release = 0x40001e14; -__sinit = 0x40001e38; -__sinit_lock_acquire = 0x40001e20; -__sinit_lock_release = 0x40001e2c; -srand = 0x40001004; -__sread = 0x40001118; -__sseek = 0x40001184; -strcasecmp = 0x400011cc; -strcasestr = 0x40001210; -strcat = 0x4000c518; -strchr = 0x4000c53c; -strcmp = 0x40001274; -strcoll = 0x40001398; -strcpy = 0x400013ac; -strcspn = 0x4000c558; -strdup = 0x4000143c; -_strdup_r = 0x40001450; -strlcat = 0x40001470; -strlcpy = 0x4000c584; -strlen = 0x400014c0; -strlwr = 0x40001524; -strncasecmp = 0x40001550; -strncat = 0x4000c5c4; -strncmp = 0x4000c5f4; -strncpy = 0x400015d4; -strndup = 0x400016b0; -_strndup_r = 0x400016c4; -strnlen = 0x4000c628; -strrchr = 0x40001708; -strsep = 0x40001734; -strspn = 0x4000c648; -strstr = 0x4000c674; -__strtok_r = 0x4000c6a8; -strtok_r = 0x4000c70c; -strtol = 0x4005681c; -_strtol_r = 0x40056714; -strtoul = 0x4005692c; -_strtoul_r = 0x40056834; -strupr = 0x4000174c; -__submore = 0x40058f3c; -__swbuf = 0x40058cb4; -__swbuf_r = 0x40058bec; -__swrite = 0x40001150; -toascii = 0x4000c720; -tolower = 0x40001868; -toupper = 0x40001884; -ungetc = 0x400590f4; -_ungetc_r = 0x40058fa0; -__utoa = 0x400561f0; -utoa = 0x40056258; -wcrtomb = 0x40058920; -_wcrtomb_r = 0x400588d8; -_wctomb_r = 0x40058f14; diff --git a/targets/esp32.rom.newlib-locale.ld b/targets/esp32.rom.newlib-locale.ld deleted file mode 100644 index 81e22aaf..00000000 --- a/targets/esp32.rom.newlib-locale.ld +++ /dev/null @@ -1,19 +0,0 @@ -/* These are the locale-related newlib functions present in ESP32 ROM. - ESP32 ROM contains newlib version 2.2.0, and these functions should not be - used when compiling with newlib version 3, since locale implementation is - different there. - - Unlike other ROM functions which are exported using PROVIDE, which declares - weak symbols, newlib related functions are exported using assignment, - which declares strong symbols. This is done so that ROM functions are always - used instead of the ones provided by libc.a. - */ - -__locale_charset = 0x40059540; -__locale_cjk_lang = 0x40059558; -localeconv = 0x4005957c; -_localeconv_r = 0x40059560; -__locale_mb_cur_max = 0x40059548; -__locale_msgcharset = 0x40059550; -setlocale = 0x40059568; -_setlocale_r = 0x4005950c; diff --git a/targets/esp32.rom.newlib-nano.ld b/targets/esp32.rom.newlib-nano.ld deleted file mode 100644 index 51d93a1e..00000000 --- a/targets/esp32.rom.newlib-nano.ld +++ /dev/null @@ -1,115 +0,0 @@ -/* These are the printf/scanf related newlib functions present in ESP32 ROM. - These functions are compiled with newlib "nano" format option. - As such, they don's support 64-bit integer formats. - Floating point formats are supported by setting _printf_float and - _scanf_float entries in syscall table. This is done automatically - by startup code. - These functions should not be used when compiling with PSRAM cache workaround enabled. - See also esp32.rom.newlib-data.ld for the list of .data/.bss symbols - used by newlib functions, and esp32.rom.newlib-funcs.ld for the list - of general newlib functions. - - Unlike other ROM functions which are exported using PROVIDE, which declares - weak symbols, newlib related functions are exported using assignment, - which declares strong symbols. This is done so that ROM functions are always - used instead of the ones provided by libc.a. - */ - -asiprintf = 0x40056d9c; -_asiprintf_r = 0x40056d4c; -asniprintf = 0x40056cd8; -_asniprintf_r = 0x40056c64; -asnprintf = 0x40056cd8; -_asnprintf_r = 0x40056c64; -asprintf = 0x40056d9c; -_asprintf_r = 0x40056d4c; -fiprintf = 0x40056efc; -_fiprintf_r = 0x40056ed8; -fiscanf = 0x40058884; -_fiscanf_r = 0x400588b4; -fprintf = 0x40056efc; -_fprintf_r = 0x40056ed8; -fscanf = 0x40058884; -_fscanf_r = 0x400588b4; -iprintf = 0x40056978; -_iprintf_r = 0x40056944; -iscanf = 0x40058760; -_iscanf_r = 0x4005879c; -printf = 0x40056978; -_printf_common = 0x40057338; -_printf_i = 0x40057404; -_printf_r = 0x40056944; -scanf = 0x40058760; -_scanf_chars = 0x40058384; -_scanf_i = 0x4005845c; -_scanf_r = 0x4005879c; -__sfputs_r = 0x40057790; -siprintf = 0x40056c08; -_siprintf_r = 0x40056bbc; -siscanf = 0x400587d0; -_siscanf_r = 0x40058830; -sniprintf = 0x40056b4c; -_sniprintf_r = 0x40056ae4; -snprintf = 0x40056b4c; -_snprintf_r = 0x40056ae4; -sprintf = 0x40056c08; -_sprintf_r = 0x40056bbc; -__sprint_r = 0x400577e4; -sscanf = 0x400587d0; -_sscanf_r = 0x40058830; -__ssprint_r = 0x40056ff8; -__ssputs_r = 0x40056f2c; -__ssrefill_r = 0x40057fec; -__ssvfiscanf_r = 0x4005802c; -__ssvfscanf_r = 0x4005802c; -_sungetc_r = 0x40057f6c; -_svfiprintf_r = 0x40057100; -__svfiscanf_r = 0x40057b08; -_svfprintf_r = 0x40057100; -__svfscanf = 0x40057f04; -__svfscanf_r = 0x40057b08; -vasiprintf = 0x40056eb8; -_vasiprintf_r = 0x40056e80; -vasniprintf = 0x40056e58; -_vasniprintf_r = 0x40056df8; -vasnprintf = 0x40056e58; -_vasnprintf_r = 0x40056df8; -vasprintf = 0x40056eb8; -_vasprintf_r = 0x40056e80; -vfiprintf = 0x40057ae8; -_vfiprintf_r = 0x40057850; -vfiscanf = 0x40057eb8; -_vfiscanf_r = 0x40057f24; -vfprintf = 0x40057ae8; -_vfprintf_r = 0x40057850; -vfscanf = 0x40057eb8; -_vfscanf_r = 0x40057f24; -viprintf = 0x400569b4; -_viprintf_r = 0x400569e4; -viscanf = 0x40058698; -_viscanf_r = 0x400586c8; -vprintf = 0x400569b4; -_vprintf_r = 0x400569e4; -vscanf = 0x40058698; -_vscanf_r = 0x400586c8; -vsiprintf = 0x40056ac4; -_vsiprintf_r = 0x40056a90; -vsiscanf = 0x40058740; -_vsiscanf_r = 0x400586f8; -vsniprintf = 0x40056a68; -_vsniprintf_r = 0x40056a14; -vsnprintf = 0x40056a68; -_vsnprintf_r = 0x40056a14; -vsprintf = 0x40056ac4; -_vsprintf_r = 0x40056a90; -vsscanf = 0x40058740; -_vsscanf_r = 0x400586f8; - -/* _print_float and _scanf_float functions in ROM are stubs which call - real implementations in IDF through the syscall table. - As such, don't include these ROM symbols. - -_printf_float = 0x4000befc; -_scanf_float = 0x4000bf18; - -*/ diff --git a/targets/esp32.rom.newlib-time.ld b/targets/esp32.rom.newlib-time.ld deleted file mode 100644 index 50ec6488..00000000 --- a/targets/esp32.rom.newlib-time.ld +++ /dev/null @@ -1,38 +0,0 @@ -/* These are the newlib functions and the .bss/.data symbols necessary for these functions present in ESP32 ROM. - They should not be used when you need to solve the Y2K38 problem. - Because these functions were compiled with 32-bit width for the time_t structure. - */ - -asctime = 0x40059588; -asctime_r = 0x40000ec8; -ctime = 0x400595b0; -ctime_r = 0x400595c4; -__gettzinfo = 0x40001fcc; -__get_current_time_locale = 0x40001834; -gmtime = 0x40059848; -gmtime_r = 0x40059868; -localtime = 0x400595dc; -localtime_r = 0x400595fc; -mktime = 0x4005a5e8; -strftime = 0x40059ab4; -time = 0x40001844; -__time_load_locale = 0x4000183c; -tzset = 0x40001a1c; -_tzset_r = 0x40001a28; -__tzcalc_limits = 0x400018a0; -__tz_lock = 0x40001a04; -__tz_unlock = 0x40001a10; -/* The .bss/.data symbols necessary for these functions */ -_timezone = 0x3ffae0a0; -_tzname = 0x3ffae030; -_daylight = 0x3ffae0a4; -__month_lengths = 0x3ff9609c; - -/* These functions don't use time_t, but use other structures which include time_t. - * For example, 'struct stat' contains time_t. - */ -_isatty_r = 0x40000ea0; -__sfvwrite_r = 0x4005893c; -__smakebuf_r = 0x40059108; -__srefill_r = 0x400593d4; -__swsetup_r = 0x40058cc8; From 5810b293729e397b7f5987832159b671cc76d74c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Aug 2025 00:12:37 +0000 Subject: [PATCH 23/46] build(deps): bump github.com/goplus/lib from 0.2.0 to 0.3.0 Bumps [github.com/goplus/lib](https://github.com/goplus/lib) from 0.2.0 to 0.3.0. - [Release notes](https://github.com/goplus/lib/releases) - [Commits](https://github.com/goplus/lib/compare/v0.2.0...v0.3.0) --- updated-dependencies: - dependency-name: github.com/goplus/lib dependency-version: 0.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dcdf7f39..0324e027 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ toolchain go1.24.1 require ( github.com/goplus/cobra v1.9.12 //gop:class github.com/goplus/gogen v1.19.1 - github.com/goplus/lib v0.2.0 + github.com/goplus/lib v0.3.0 github.com/goplus/llgo/runtime v0.0.0-00010101000000-000000000000 github.com/goplus/llvm v0.8.5 github.com/goplus/mod v0.17.1 diff --git a/go.sum b/go.sum index 6dbac84e..b5da526b 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ github.com/goplus/cobra v1.9.12 h1:0F9EdEbeGyITGz+mqoHoJ5KpUw97p1CkxV74IexHw5s= github.com/goplus/cobra v1.9.12/go.mod h1:p4LhfNJDKEpiGjGiNn0crUXL5dUPA5DX2ztYpEJR34E= github.com/goplus/gogen v1.19.1 h1:L7jz60azeowj8zUq48tozETriTPBLqHb0nDj6PheANc= github.com/goplus/gogen v1.19.1/go.mod h1:owX2e1EyU5WD+Nm6oH2m/GXjLdlBYcwkLO4wN8HHXZI= -github.com/goplus/lib v0.2.0 h1:AjqkN1XK5H23wZMMlpaUYAMCDAdSBQ2NMFrLtSh7W4g= -github.com/goplus/lib v0.2.0/go.mod h1:SgJv3oPqLLHCu0gcL46ejOP3x7/2ry2Jtxu7ta32kp0= +github.com/goplus/lib v0.3.0 h1:y0ZGb5Q/RikW1oMMB4Di7XIZIpuzh/7mlrR8HNbxXCA= +github.com/goplus/lib v0.3.0/go.mod h1:SgJv3oPqLLHCu0gcL46ejOP3x7/2ry2Jtxu7ta32kp0= github.com/goplus/llvm v0.8.5 h1:DUnFeYC3Rco622tBEKGg8xkigRAV2fh5ZIfBCt7gOSs= github.com/goplus/llvm v0.8.5/go.mod h1:PeVK8GgzxwAYCiMiUAJb5wJR6xbhj989tu9oulKLLT4= github.com/goplus/mod v0.17.1 h1:ITovxDcc5zbURV/Wrp3/SBsYLgC1KrxY6pq1zMM2V94= From 4639ee13e7f7fa59315de0fe1e472c1b1afd67ad Mon Sep 17 00:00:00 2001 From: Haolan Date: Fri, 29 Aug 2025 11:30:25 +0800 Subject: [PATCH 24/46] feat: support compiler-rt --- internal/build/build.go | 2 +- internal/crosscompile/compile/compile.go | 99 +++++++++ .../{ => compile/libc}/newlibesp.go | 13 +- .../{ => compile/libc}/picolibc.go | 10 +- .../crosscompile/compile/rtlib/compiler_rt.go | 195 ++++++++++++++++++ internal/crosscompile/crosscompile.go | 39 +++- internal/crosscompile/fetch.go | 7 +- internal/crosscompile/libc.go | 117 ++--------- internal/targets/config.go | 1 + internal/targets/loader.go | 3 + targets/esp32.rom.newlib-funcs.ld | 130 ++++++++++++ 11 files changed, 497 insertions(+), 119 deletions(-) create mode 100644 internal/crosscompile/compile/compile.go rename internal/crosscompile/{ => compile/libc}/newlibesp.go (99%) rename internal/crosscompile/{ => compile/libc}/picolibc.go (97%) create mode 100644 internal/crosscompile/compile/rtlib/compiler_rt.go create mode 100644 targets/esp32.rom.newlib-funcs.ld diff --git a/internal/build/build.go b/internal/build/build.go index b13fac77..8892e084 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -907,7 +907,7 @@ define weak void @_start() { if !needStart(ctx.buildConf) && isWasmTarget(ctx.buildConf.Goos) { mainDefine = "define hidden noundef i32 @__main_argc_argv(i32 noundef %0, ptr nocapture noundef readnone %1) local_unnamed_addr" } - if !needStart(ctx.buildConf) { + if true { startDefine = "" } mainCode := fmt.Sprintf(`; ModuleID = 'main' diff --git a/internal/crosscompile/compile/compile.go b/internal/crosscompile/compile/compile.go new file mode 100644 index 00000000..5165b39f --- /dev/null +++ b/internal/crosscompile/compile/compile.go @@ -0,0 +1,99 @@ +package compile + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "slices" + "strings" + + "github.com/goplus/llgo/internal/clang" +) + +type CompileGroup struct { + OutputFileName string + Files []string // List of source files to compile + CFlags []string // C compiler flags + CCFlags []string + LDFlags []string // Linker flags +} + +func (g CompileGroup) IsCompiled(outputDir string) bool { + archive := filepath.Join(outputDir, g.OutputFileName) + _, err := os.Stat(archive) + return !os.IsNotExist(err) +} + +func (g CompileGroup) Compile(outputDir, cc, linkerName string, extraCCFlags, extraLDFlags []string) (err error) { + if g.IsCompiled(outputDir) { + return + } + tmpCompileDir, err := os.MkdirTemp("", "compile-group*") + if err != nil { + return + } + defer os.RemoveAll(tmpCompileDir) + + compileLDFlags := append(slices.Clone(extraLDFlags), g.LDFlags...) + compileCCFlags := append(slices.Clone(extraCCFlags), g.CCFlags...) + cfg := clang.NewConfig(cc, compileCCFlags, g.CFlags, compileLDFlags, linkerName) + + var objFiles []string + + compiler := clang.NewCompiler(cfg) + + compiler.Verbose = true + + archive := filepath.Join(outputDir, g.OutputFileName) + fmt.Fprintf(os.Stderr, "Start to compile group %s to %s...\n", g.OutputFileName, archive) + + for _, file := range g.Files { + var tempObjFile *os.File + tempObjFile, err = os.CreateTemp(tmpCompileDir, fmt.Sprintf("%s*.o", strings.ReplaceAll(file, string(os.PathSeparator), "-"))) + if err != nil { + return + } + fmt.Fprintf(os.Stderr, "Compile file %s to %s...\n", file, tempObjFile.Name()) + + lang := "c" + if filepath.Ext(file) == ".S" { + lang = "assembler-with-cpp" + } + err = compiler.Compile("-o", tempObjFile.Name(), "-x", lang, "-c", file) + if err != nil { + return + } + + objFiles = append(objFiles, tempObjFile.Name()) + } + + args := []string{"rcs", archive} + args = append(args, objFiles...) + + ccDir := filepath.Dir(cc) + llvmAr := filepath.Join(ccDir, "llvm-ar") + + cmd := exec.Command(llvmAr, args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err = cmd.Run() + return +} + +// CompileConfig represents compilation configuration +type CompileConfig struct { + Url string + Name string // compile name (e.g., "picolibc", "musl", "glibc") + Groups []CompileGroup + ArchiveSrcDir string +} + +func (c CompileConfig) IsCompiled(outputDir string) bool { + for _, group := range c.Groups { + if !group.IsCompiled(outputDir) { + return false + } + } + return true +} diff --git a/internal/crosscompile/newlibesp.go b/internal/crosscompile/compile/libc/newlibesp.go similarity index 99% rename from internal/crosscompile/newlibesp.go rename to internal/crosscompile/compile/libc/newlibesp.go index d70723f1..7dc99059 100644 --- a/internal/crosscompile/newlibesp.go +++ b/internal/crosscompile/compile/libc/newlibesp.go @@ -1,20 +1,22 @@ -package crosscompile +package libc import ( "path/filepath" + + "github.com/goplus/llgo/internal/crosscompile/compile" ) // getNewlibESP32Config returns configuration for newlib esp32 -func getNewlibESP32Config(baseDir, arch string) *compileLibcConfig { +func GetNewlibESP32Config(baseDir, arch string) *compile.CompileConfig { libcDir := filepath.Join(baseDir, "newlib", "libc") // headerFile, _ := os.Create(filepath.Join(baseDir, "picolibc.h")) // headerFile.Close() - return &compileLibcConfig{ + return &compile.CompileConfig{ Url: "https://github.com/MeteorsLiu/newlib-esp32/archive/refs/heads/esp-4.3.0.zip", Name: "newlib-esp32", - Groups: []compileGroup{ + Groups: []compile.CompileGroup{ { OutputFileName: "libcrt0.a", Files: []string{ @@ -23,7 +25,6 @@ func getNewlibESP32Config(baseDir, arch string) *compileLibcConfig { filepath.Join(baseDir, "libgloss", "xtensa", "boards", "esp32", "board.c"), filepath.Join(baseDir, "libgloss", "xtensa", "crt1-boards.S"), filepath.Join(baseDir, "libgloss", "xtensa", "sleep.S"), - filepath.Join(baseDir, "libgloss", "xtensa", "window-vectors.S"), }, CFlags: []string{ "-DHAVE_CONFIG_H", @@ -974,7 +975,7 @@ func getNewlibESP32Config(baseDir, arch string) *compileLibcConfig { "-I" + filepath.Join(libcDir, "posix"), "-I" + filepath.Join(libcDir, "stdlib"), }, - LDFlags: []string{"-nostdlib", "-L" + baseDir, "-lgloss"}, + LDFlags: []string{"-nostdlib"}, CCFlags: []string{ "-Oz", "-fno-builtin", diff --git a/internal/crosscompile/picolibc.go b/internal/crosscompile/compile/libc/picolibc.go similarity index 97% rename from internal/crosscompile/picolibc.go rename to internal/crosscompile/compile/libc/picolibc.go index b31405d6..319fbad2 100644 --- a/internal/crosscompile/picolibc.go +++ b/internal/crosscompile/compile/libc/picolibc.go @@ -1,12 +1,14 @@ -package crosscompile +package libc import ( "os" "path/filepath" + + "github.com/goplus/llgo/internal/crosscompile/compile" ) // getPicolibcConfig returns configuration for picolibc -func getPicolibcConfig(baseDir string) *compileLibcConfig { +func GetPicolibcConfig(baseDir string) *compile.CompileConfig { libcIncludeDir := filepath.Join(baseDir, "libc", "include") libmIncludeDir := filepath.Join(baseDir, "libm", "common") localeIncludeDir := filepath.Join(baseDir, "libc", "locale") @@ -16,10 +18,10 @@ func getPicolibcConfig(baseDir string) *compileLibcConfig { headerFile, _ := os.Create(filepath.Join(baseDir, "picolibc.h")) headerFile.Close() - return &compileLibcConfig{ + return &compile.CompileConfig{ Url: "https://github.com/picolibc/picolibc/releases/download/1.8.10/picolibc-1.8.10.tar.xz", Name: "picolibc", - Groups: []compileGroup{ + Groups: []compile.CompileGroup{ { OutputFileName: "libc.a", Files: []string{ diff --git a/internal/crosscompile/compile/rtlib/compiler_rt.go b/internal/crosscompile/compile/rtlib/compiler_rt.go new file mode 100644 index 00000000..5ffa0ba0 --- /dev/null +++ b/internal/crosscompile/compile/rtlib/compiler_rt.go @@ -0,0 +1,195 @@ +package rtlib + +import ( + "path/filepath" + + "github.com/goplus/llgo/internal/crosscompile/compile" +) + +func GetCompilerRTConfig(baseDir, arch string) *compile.CompileConfig { + return &compile.CompileConfig{ + Url: "https://github.com/MeteorsLiu/llvm-project/archive/refs/heads/compiler-rt.zip", + ArchiveSrcDir: "llvm-project-compiler-rt", + Groups: []compile.CompileGroup{ + { + OutputFileName: "libclang_builtins.a", + Files: []string{ + filepath.Join(baseDir, "lib", "builtins", "xtensa/ieee754_sqrtf.S"), + filepath.Join(baseDir, "lib", "builtins", "absvdi2.c"), + filepath.Join(baseDir, "lib", "builtins", "absvsi2.c"), + filepath.Join(baseDir, "lib", "builtins", "absvti2.c"), + filepath.Join(baseDir, "lib", "builtins", "adddf3.c"), + filepath.Join(baseDir, "lib", "builtins", "addsf3.c"), + filepath.Join(baseDir, "lib", "builtins", "addvdi3.c"), + filepath.Join(baseDir, "lib", "builtins", "addvsi3.c"), + filepath.Join(baseDir, "lib", "builtins", "addvti3.c"), + filepath.Join(baseDir, "lib", "builtins", "apple_versioning.c"), + filepath.Join(baseDir, "lib", "builtins", "ashldi3.c"), + filepath.Join(baseDir, "lib", "builtins", "ashlti3.c"), + filepath.Join(baseDir, "lib", "builtins", "ashrdi3.c"), + filepath.Join(baseDir, "lib", "builtins", "ashrti3.c"), + filepath.Join(baseDir, "lib", "builtins", "bswapdi2.c"), + filepath.Join(baseDir, "lib", "builtins", "bswapsi2.c"), + filepath.Join(baseDir, "lib", "builtins", "clzdi2.c"), + filepath.Join(baseDir, "lib", "builtins", "clzsi2.c"), + filepath.Join(baseDir, "lib", "builtins", "clzti2.c"), + filepath.Join(baseDir, "lib", "builtins", "cmpdi2.c"), + filepath.Join(baseDir, "lib", "builtins", "cmpti2.c"), + filepath.Join(baseDir, "lib", "builtins", "comparedf2.c"), + filepath.Join(baseDir, "lib", "builtins", "comparesf2.c"), + filepath.Join(baseDir, "lib", "builtins", "ctzdi2.c"), + filepath.Join(baseDir, "lib", "builtins", "ctzsi2.c"), + filepath.Join(baseDir, "lib", "builtins", "ctzti2.c"), + filepath.Join(baseDir, "lib", "builtins", "divdc3.c"), + filepath.Join(baseDir, "lib", "builtins", "divdf3.c"), + filepath.Join(baseDir, "lib", "builtins", "divdi3.c"), + filepath.Join(baseDir, "lib", "builtins", "divmoddi4.c"), + filepath.Join(baseDir, "lib", "builtins", "divmodsi4.c"), + filepath.Join(baseDir, "lib", "builtins", "divmodti4.c"), + filepath.Join(baseDir, "lib", "builtins", "divsc3.c"), + filepath.Join(baseDir, "lib", "builtins", "divsf3.c"), + filepath.Join(baseDir, "lib", "builtins", "divsi3.c"), + filepath.Join(baseDir, "lib", "builtins", "divti3.c"), + filepath.Join(baseDir, "lib", "builtins", "extendsfdf2.c"), + filepath.Join(baseDir, "lib", "builtins", "extendhfsf2.c"), + filepath.Join(baseDir, "lib", "builtins", "ffsdi2.c"), + filepath.Join(baseDir, "lib", "builtins", "ffssi2.c"), + filepath.Join(baseDir, "lib", "builtins", "ffsti2.c"), + filepath.Join(baseDir, "lib", "builtins", "fixdfdi.c"), + filepath.Join(baseDir, "lib", "builtins", "fixdfsi.c"), + filepath.Join(baseDir, "lib", "builtins", "fixdfti.c"), + filepath.Join(baseDir, "lib", "builtins", "fixsfdi.c"), + filepath.Join(baseDir, "lib", "builtins", "fixsfsi.c"), + filepath.Join(baseDir, "lib", "builtins", "fixsfti.c"), + filepath.Join(baseDir, "lib", "builtins", "fixunsdfdi.c"), + filepath.Join(baseDir, "lib", "builtins", "fixunsdfsi.c"), + filepath.Join(baseDir, "lib", "builtins", "fixunsdfti.c"), + filepath.Join(baseDir, "lib", "builtins", "fixunssfdi.c"), + filepath.Join(baseDir, "lib", "builtins", "fixunssfsi.c"), + filepath.Join(baseDir, "lib", "builtins", "fixunssfti.c"), + filepath.Join(baseDir, "lib", "builtins", "floatdidf.c"), + filepath.Join(baseDir, "lib", "builtins", "floatdisf.c"), + filepath.Join(baseDir, "lib", "builtins", "floatsidf.c"), + filepath.Join(baseDir, "lib", "builtins", "floatsisf.c"), + filepath.Join(baseDir, "lib", "builtins", "floattidf.c"), + filepath.Join(baseDir, "lib", "builtins", "floattisf.c"), + filepath.Join(baseDir, "lib", "builtins", "floatundidf.c"), + filepath.Join(baseDir, "lib", "builtins", "floatundisf.c"), + filepath.Join(baseDir, "lib", "builtins", "floatunsidf.c"), + filepath.Join(baseDir, "lib", "builtins", "floatunsisf.c"), + filepath.Join(baseDir, "lib", "builtins", "floatuntidf.c"), + filepath.Join(baseDir, "lib", "builtins", "floatuntisf.c"), + filepath.Join(baseDir, "lib", "builtins", "fp_mode.c"), + filepath.Join(baseDir, "lib", "builtins", "int_util.c"), + filepath.Join(baseDir, "lib", "builtins", "lshrdi3.c"), + filepath.Join(baseDir, "lib", "builtins", "lshrti3.c"), + filepath.Join(baseDir, "lib", "builtins", "moddi3.c"), + filepath.Join(baseDir, "lib", "builtins", "modsi3.c"), + filepath.Join(baseDir, "lib", "builtins", "modti3.c"), + filepath.Join(baseDir, "lib", "builtins", "muldc3.c"), + filepath.Join(baseDir, "lib", "builtins", "muldf3.c"), + filepath.Join(baseDir, "lib", "builtins", "muldi3.c"), + filepath.Join(baseDir, "lib", "builtins", "mulodi4.c"), + filepath.Join(baseDir, "lib", "builtins", "mulosi4.c"), + filepath.Join(baseDir, "lib", "builtins", "muloti4.c"), + filepath.Join(baseDir, "lib", "builtins", "mulsc3.c"), + filepath.Join(baseDir, "lib", "builtins", "mulsf3.c"), + filepath.Join(baseDir, "lib", "builtins", "multi3.c"), + filepath.Join(baseDir, "lib", "builtins", "mulvdi3.c"), + filepath.Join(baseDir, "lib", "builtins", "mulvsi3.c"), + filepath.Join(baseDir, "lib", "builtins", "mulvti3.c"), + filepath.Join(baseDir, "lib", "builtins", "negdf2.c"), + filepath.Join(baseDir, "lib", "builtins", "negdi2.c"), + filepath.Join(baseDir, "lib", "builtins", "negsf2.c"), + filepath.Join(baseDir, "lib", "builtins", "negti2.c"), + filepath.Join(baseDir, "lib", "builtins", "negvdi2.c"), + filepath.Join(baseDir, "lib", "builtins", "negvsi2.c"), + filepath.Join(baseDir, "lib", "builtins", "negvti2.c"), + filepath.Join(baseDir, "lib", "builtins", "os_version_check.c"), + filepath.Join(baseDir, "lib", "builtins", "paritydi2.c"), + filepath.Join(baseDir, "lib", "builtins", "paritysi2.c"), + filepath.Join(baseDir, "lib", "builtins", "parityti2.c"), + filepath.Join(baseDir, "lib", "builtins", "popcountdi2.c"), + filepath.Join(baseDir, "lib", "builtins", "popcountsi2.c"), + filepath.Join(baseDir, "lib", "builtins", "popcountti2.c"), + filepath.Join(baseDir, "lib", "builtins", "powidf2.c"), + filepath.Join(baseDir, "lib", "builtins", "powisf2.c"), + filepath.Join(baseDir, "lib", "builtins", "subdf3.c"), + filepath.Join(baseDir, "lib", "builtins", "subsf3.c"), + filepath.Join(baseDir, "lib", "builtins", "subvdi3.c"), + filepath.Join(baseDir, "lib", "builtins", "subvsi3.c"), + filepath.Join(baseDir, "lib", "builtins", "subvti3.c"), + filepath.Join(baseDir, "lib", "builtins", "trampoline_setup.c"), + filepath.Join(baseDir, "lib", "builtins", "truncdfhf2.c"), + filepath.Join(baseDir, "lib", "builtins", "truncdfsf2.c"), + filepath.Join(baseDir, "lib", "builtins", "truncsfhf2.c"), + filepath.Join(baseDir, "lib", "builtins", "ucmpdi2.c"), + filepath.Join(baseDir, "lib", "builtins", "ucmpti2.c"), + filepath.Join(baseDir, "lib", "builtins", "udivdi3.c"), + filepath.Join(baseDir, "lib", "builtins", "udivmoddi4.c"), + filepath.Join(baseDir, "lib", "builtins", "udivmodsi4.c"), + filepath.Join(baseDir, "lib", "builtins", "udivmodti4.c"), + filepath.Join(baseDir, "lib", "builtins", "udivsi3.c"), + filepath.Join(baseDir, "lib", "builtins", "udivti3.c"), + filepath.Join(baseDir, "lib", "builtins", "umoddi3.c"), + filepath.Join(baseDir, "lib", "builtins", "umodsi3.c"), + filepath.Join(baseDir, "lib", "builtins", "umodti3.c"), + filepath.Join(baseDir, "lib", "builtins", "gcc_personality_v0.c"), + filepath.Join(baseDir, "lib", "builtins", "clear_cache.c"), + filepath.Join(baseDir, "lib", "builtins", "addtf3.c"), + filepath.Join(baseDir, "lib", "builtins", "comparetf2.c"), + filepath.Join(baseDir, "lib", "builtins", "divtc3.c"), + filepath.Join(baseDir, "lib", "builtins", "divtf3.c"), + filepath.Join(baseDir, "lib", "builtins", "extenddftf2.c"), + filepath.Join(baseDir, "lib", "builtins", "extendhftf2.c"), + filepath.Join(baseDir, "lib", "builtins", "extendsftf2.c"), + filepath.Join(baseDir, "lib", "builtins", "fixtfdi.c"), + filepath.Join(baseDir, "lib", "builtins", "fixtfsi.c"), + filepath.Join(baseDir, "lib", "builtins", "fixtfti.c"), + filepath.Join(baseDir, "lib", "builtins", "fixunstfdi.c"), + filepath.Join(baseDir, "lib", "builtins", "fixunstfsi.c"), + filepath.Join(baseDir, "lib", "builtins", "fixunstfti.c"), + filepath.Join(baseDir, "lib", "builtins", "floatditf.c"), + filepath.Join(baseDir, "lib", "builtins", "floatsitf.c"), + filepath.Join(baseDir, "lib", "builtins", "floattitf.c"), + filepath.Join(baseDir, "lib", "builtins", "floatunditf.c"), + filepath.Join(baseDir, "lib", "builtins", "floatunsitf.c"), + filepath.Join(baseDir, "lib", "builtins", "floatuntitf.c"), + filepath.Join(baseDir, "lib", "builtins", "multc3.c"), + filepath.Join(baseDir, "lib", "builtins", "multf3.c"), + filepath.Join(baseDir, "lib", "builtins", "powitf2.c"), + filepath.Join(baseDir, "lib", "builtins", "subtf3.c"), + filepath.Join(baseDir, "lib", "builtins", "trunctfdf2.c"), + filepath.Join(baseDir, "lib", "builtins", "trunctfhf2.c"), + filepath.Join(baseDir, "lib", "builtins", "trunctfsf2.c"), + }, + CFlags: []string{ + "-DNDEBUG", + "-DVISIBILITY_HIDDEN", + }, + CCFlags: []string{ + "-Oz", + "-fno-ident", + "-Wno-unused-parameter", + "-fno-lto", + "-Werror=array-bounds", + "-Werror=uninitialized", + "-Werror=shadow", + "-Werror=empty-body", + "-Werror=sizeof-pointer-memaccess", + "-Werror=sizeof-array-argument", + "-Werror=suspicious-memaccess", + "-Werror=builtin-memcpy-chk-size", + "-Werror=array-bounds-pointer-arithmetic", + "-Werror=return-stack-address", + "-Werror=sizeof-array-decay", + "-Werror=format-insufficient-args", + "-Wformat -std=c11", + "-fno-builtin", + "-fvisibility=hidden", + "-fomit-frame-pointer", + }, + }, + }, + } +} diff --git a/internal/crosscompile/crosscompile.go b/internal/crosscompile/crosscompile.go index 79749534..f6e2664e 100644 --- a/internal/crosscompile/crosscompile.go +++ b/internal/crosscompile/crosscompile.go @@ -10,6 +10,7 @@ import ( "runtime" "strings" + "github.com/goplus/llgo/internal/crosscompile/compile" "github.com/goplus/llgo/internal/env" "github.com/goplus/llgo/internal/targets" "github.com/goplus/llgo/internal/xtool/llvm" @@ -219,15 +220,8 @@ func ldFlagsFromFileName(fileName string) string { return strings.TrimPrefix(strings.TrimSuffix(fileName, ".a"), "lib") } -func getOrCompileLibc(cc, linkerName, libcName string, exportCCFlags, exportLDFlags []string) (ldflags []string, err error) { - baseDir := filepath.Join(cacheRoot(), "crosscompile") - outputDir := filepath.Join(baseDir, libcName) - - compileConfig, err := getCompileLibcConfigByName(baseDir, libcName) - if err != nil { - return - } - if err = checkDownloadAndExtractLibc(compileConfig, compileConfig.Url, outputDir, compileConfig.ArchiveSrcDir); err != nil { +func getOrCompileWithConfig(compileConfig *compile.CompileConfig, outputDir, cc, linkerName, libName string, exportCCFlags, exportLDFlags []string) (ldflags []string, err error) { + if err = checkDownloadAndExtractLib(compileConfig, compileConfig.Url, outputDir, compileConfig.ArchiveSrcDir); err != nil { return } ldflags = append(ldflags, "-nostdlib", "-L"+outputDir) @@ -606,13 +600,38 @@ func useTarget(targetName string) (export Export, err error) { if config.Libc != "" { var libcLDFlags []string - libcLDFlags, err = getOrCompileLibc(export.CC, export.Linker, config.Libc, ccflags, ldflags) + var compileConfig *compile.CompileConfig + baseDir := filepath.Join(cacheRoot(), "crosscompile") + outputDir := filepath.Join(baseDir, config.Libc) + + compileConfig, err = getLibcCompileConfigByName(baseDir, config.Libc) + if err != nil { + return + } + libcLDFlags, err = getOrCompileWithConfig(compileConfig, outputDir, export.CC, export.Linker, config.Libc, ccflags, ldflags) if err != nil { return } ldflags = append(ldflags, libcLDFlags...) } + if config.RTLib != "" { + var rtLibLDFlags []string + var compileConfig *compile.CompileConfig + baseDir := filepath.Join(cacheRoot(), "crosscompile") + outputDir := filepath.Join(baseDir, config.RTLib) + + compileConfig, err = getRTCompileConfigByName(baseDir, config.RTLib) + if err != nil { + return + } + rtLibLDFlags, err = getOrCompileWithConfig(compileConfig, outputDir, export.CC, export.Linker, config.RTLib, ccflags, ldflags) + if err != nil { + return + } + ldflags = append(ldflags, rtLibLDFlags...) + } + // Combine with config flags and expand template variables export.CFLAGS = cflags export.CCFLAGS = ccflags diff --git a/internal/crosscompile/fetch.go b/internal/crosscompile/fetch.go index cc676662..950ca19b 100644 --- a/internal/crosscompile/fetch.go +++ b/internal/crosscompile/fetch.go @@ -13,6 +13,8 @@ import ( "path/filepath" "strings" "syscall" + + "github.com/goplus/llgo/internal/crosscompile/compile" ) // checkDownloadAndExtractWasiSDK downloads and extracts WASI SDK @@ -80,7 +82,7 @@ func checkDownloadAndExtractESPClang(platformSuffix, dir string) error { return nil } -func checkDownloadAndExtractLibc(cfg *compileLibcConfig, url, dstDir, internalArchiveSrcDir string) error { +func checkDownloadAndExtractLib(cfg *compile.CompileConfig, url, dstDir, internalArchiveSrcDir string) error { // Check if already exists if cfg.IsCompiled(dstDir) { return nil @@ -107,7 +109,7 @@ func checkDownloadAndExtractLibc(cfg *compileLibcConfig, url, dstDir, internalAr if err := downloadAndExtractArchive(url, tempExtractDir, description); err != nil { return err } - // defer os.RemoveAll(tempExtractDir) + defer os.RemoveAll(tempExtractDir) srcDir := tempExtractDir @@ -115,6 +117,7 @@ func checkDownloadAndExtractLibc(cfg *compileLibcConfig, url, dstDir, internalAr srcDir = filepath.Join(tempExtractDir, internalArchiveSrcDir) } + os.RemoveAll(dstDir) if err := os.Rename(srcDir, dstDir); err != nil { return fmt.Errorf("failed to rename libc directory: %w", err) } diff --git a/internal/crosscompile/libc.go b/internal/crosscompile/libc.go index d9fe64bc..8bd96e85 100644 --- a/internal/crosscompile/libc.go +++ b/internal/crosscompile/libc.go @@ -2,105 +2,16 @@ package crosscompile import ( "fmt" - "os" - "os/exec" "path/filepath" - "slices" - "strings" - "github.com/goplus/llgo/internal/clang" + "github.com/goplus/llgo/internal/crosscompile/compile" + "github.com/goplus/llgo/internal/crosscompile/compile/libc" + "github.com/goplus/llgo/internal/crosscompile/compile/rtlib" ) -type compileGroup struct { - OutputFileName string - Files []string // List of source files to compile - CFlags []string // C compiler flags specific to this libc - CCFlags []string - LDFlags []string // Linker flags -} - -func (g compileGroup) IsCompiled(outputDir string) bool { - libcArchive := filepath.Join(outputDir, g.OutputFileName) - _, err := os.Stat(libcArchive) - return !os.IsNotExist(err) -} - -func (g compileGroup) Compile(outputDir, cc, linkerName string, extraCCFlags, extraLDFlags []string) (err error) { - if g.IsCompiled(outputDir) { - return - } - tmpCompileDir, err := os.MkdirTemp("", "compile-libc-group*") - if err != nil { - return - } - defer os.RemoveAll(tmpCompileDir) - - compileLDFlags := append(slices.Clone(extraLDFlags), g.LDFlags...) - compileCCFlags := append(slices.Clone(extraCCFlags), g.CCFlags...) - cfg := clang.NewConfig(cc, compileCCFlags, g.CFlags, compileLDFlags, linkerName) - - var objFiles []string - - compiler := clang.NewCompiler(cfg) - - compiler.Verbose = true - - libcArchive := filepath.Join(outputDir, g.OutputFileName) - fmt.Fprintf(os.Stderr, "Start to compile libc group %s to %s...\n", g.OutputFileName, libcArchive) - - for _, file := range g.Files { - var tempObjFile *os.File - tempObjFile, err = os.CreateTemp(tmpCompileDir, fmt.Sprintf("%s*.o", strings.ReplaceAll(file, string(os.PathSeparator), "-"))) - if err != nil { - return - } - fmt.Fprintf(os.Stderr, "Compile libc file %s to %s...\n", file, tempObjFile.Name()) - - lang := "c" - if filepath.Ext(file) == ".S" { - lang = "assembler-with-cpp" - } - err = compiler.Compile("-o", tempObjFile.Name(), "-x", lang, "-c", file) - if err != nil { - return - } - - objFiles = append(objFiles, tempObjFile.Name()) - } - - args := []string{"rcs", libcArchive} - args = append(args, objFiles...) - - ccDir := filepath.Dir(cc) - llvmAr := filepath.Join(ccDir, "llvm-ar") - - cmd := exec.Command(llvmAr, args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Run() - return -} - -// CompileLibcConfig represents libc compilation configuration -type compileLibcConfig struct { - Url string - Name string // Libc name (e.g., "picolibc", "musl", "glibc") - Groups []compileGroup - ArchiveSrcDir string -} - -func (c compileLibcConfig) IsCompiled(outputDir string) bool { - for _, group := range c.Groups { - if !group.IsCompiled(outputDir) { - return false - } - } - return true -} - -// GetCompileLibcConfigByName retrieves libc compilation configuration by name +// GetCompileConfigByName retrieves libc compilation configuration by name // Returns compilation file lists and corresponding cflags -func getCompileLibcConfigByName(baseDir, libcName string) (*compileLibcConfig, error) { +func getLibcCompileConfigByName(baseDir, libcName string) (*compile.CompileConfig, error) { if libcName == "" { return nil, fmt.Errorf("libc name cannot be empty") } @@ -108,10 +19,24 @@ func getCompileLibcConfigByName(baseDir, libcName string) (*compileLibcConfig, e switch libcName { case "picolibc": - return getPicolibcConfig(libcDir), nil + return libc.GetPicolibcConfig(libcDir), nil case "newlib-esp32": - return getNewlibESP32Config(libcDir, "xtensa"), nil + return libc.GetNewlibESP32Config(libcDir, "xtensa"), nil default: return nil, fmt.Errorf("unsupported libc: %s", libcName) } } + +func getRTCompileConfigByName(baseDir, rtName string) (*compile.CompileConfig, error) { + if rtName == "" { + return nil, fmt.Errorf("rt name cannot be empty") + } + rtDir := filepath.Join(baseDir, rtName) + + switch rtName { + case "compiler-rt": + return rtlib.GetCompilerRTConfig(rtDir, "xtensa"), nil + default: + return nil, fmt.Errorf("unsupported rt: %s", rtName) + } +} diff --git a/internal/targets/config.go b/internal/targets/config.go index 4071e9fe..d75d1f45 100644 --- a/internal/targets/config.go +++ b/internal/targets/config.go @@ -17,6 +17,7 @@ type Config struct { // Compiler and linker configuration Libc string `json:"libc"` + RTLib string `json:"rtlib"` Linker string `json:"linker"` LinkerScript string `json:"linkerscript"` CFlags []string `json:"cflags"` diff --git a/internal/targets/loader.go b/internal/targets/loader.go index 15687ccd..95d1e73a 100644 --- a/internal/targets/loader.go +++ b/internal/targets/loader.go @@ -137,6 +137,9 @@ func (l *Loader) mergeConfig(dst, src *Config) { if src.Libc != "" { dst.Libc = src.Libc } + if src.RTLib != "" { + dst.RTLib = src.RTLib + } if src.Linker != "" { dst.Linker = src.Linker } diff --git a/targets/esp32.rom.newlib-funcs.ld b/targets/esp32.rom.newlib-funcs.ld new file mode 100644 index 00000000..79d5c5be --- /dev/null +++ b/targets/esp32.rom.newlib-funcs.ld @@ -0,0 +1,130 @@ +/* These are the newlib functions present in ESP32 ROM. + They should not be used when compiling with PSRAM cache workaround enabled. + See also esp32.rom.newlib-data.ld for the list of .data/.bss symbols + used by these functions, and esp32.rom.newlib-nano.ld for "nano" versions + of printf/scanf family of functions. + + Unlike other ROM functions which are exported using PROVIDE, which declares + weak symbols, newlib related functions are exported using assignment, + which declares strong symbols. This is done so that ROM functions are always + used instead of the ones provided by libc.a. + + Time functions were moved to the esp32.rom.newlib-time.ld file. + */ + +abs = 0x40056340; +__ascii_wctomb = 0x40058ef0; +atoi = 0x400566c4; +_atoi_r = 0x400566d4; +atol = 0x400566ec; +_atol_r = 0x400566fc; +bzero = 0x4000c1f4; +_cleanup = 0x40001df8; +_cleanup_r = 0x40001d48; +creat = 0x40000e8c; +div = 0x40056348; +__dummy_lock = 0x4000c728; +__dummy_lock_try = 0x4000c730; +__env_lock = 0x40001fd4; +__env_unlock = 0x40001fe0; +fclose = 0x400020ac; +_fclose_r = 0x40001fec; +fflush = 0x40059394; +_fflush_r = 0x40059320; +_findenv_r = 0x40001f44; +__fp_lock_all = 0x40001f1c; +__fp_unlock_all = 0x40001f30; +__fputwc = 0x40058da0; +fputwc = 0x40058ea8; +_fputwc_r = 0x40058e4c; +_fwalk = 0x4000c738; +_fwalk_reent = 0x4000c770; +_getenv_r = 0x40001fbc; +isalnum = 0x40000f04; +isalpha = 0x40000f18; +isascii = 0x4000c20c; +isblank = 0x40000f2c; +iscntrl = 0x40000f50; +isdigit = 0x40000f64; +isgraph = 0x40000f94; +islower = 0x40000f78; +isprint = 0x40000fa8; +ispunct = 0x40000fc0; +isspace = 0x40000fd4; +isupper = 0x40000fe8; +__itoa = 0x40056678; +itoa = 0x400566b4; +labs = 0x40056370; +ldiv = 0x40056378; +longjmp = 0x400562cc; +memccpy = 0x4000c220; +memchr = 0x4000c244; +memcmp = 0x4000c260; +memcpy = 0x4000c2c8; +memmove = 0x4000c3c0; +memrchr = 0x4000c400; +memset = 0x4000c44c; +qsort = 0x40056424; +rand = 0x40001058; +rand_r = 0x400010d4; +__sccl = 0x4000c498; +__sclose = 0x400011b8; +__seofread = 0x40001148; +setjmp = 0x40056268; +__sflush_r = 0x400591e0; +__sfmoreglue = 0x40001dc8; +__sfp = 0x40001e90; +__sfp_lock_acquire = 0x40001e08; +__sfp_lock_release = 0x40001e14; +__sinit = 0x40001e38; +__sinit_lock_acquire = 0x40001e20; +__sinit_lock_release = 0x40001e2c; +srand = 0x40001004; +__sread = 0x40001118; +__sseek = 0x40001184; +strcasecmp = 0x400011cc; +strcasestr = 0x40001210; +strcat = 0x4000c518; +strchr = 0x4000c53c; +strcmp = 0x40001274; +strcoll = 0x40001398; +strcpy = 0x400013ac; +strcspn = 0x4000c558; +strdup = 0x4000143c; +_strdup_r = 0x40001450; +strlcat = 0x40001470; +strlcpy = 0x4000c584; +strlen = 0x400014c0; +strlwr = 0x40001524; +strncasecmp = 0x40001550; +strncat = 0x4000c5c4; +strncmp = 0x4000c5f4; +strncpy = 0x400015d4; +strndup = 0x400016b0; +_strndup_r = 0x400016c4; +strnlen = 0x4000c628; +strrchr = 0x40001708; +strsep = 0x40001734; +strspn = 0x4000c648; +strstr = 0x4000c674; +__strtok_r = 0x4000c6a8; +strtok_r = 0x4000c70c; +strtol = 0x4005681c; +_strtol_r = 0x40056714; +strtoul = 0x4005692c; +_strtoul_r = 0x40056834; +strupr = 0x4000174c; +__submore = 0x40058f3c; +__swbuf = 0x40058cb4; +__swbuf_r = 0x40058bec; +__swrite = 0x40001150; +toascii = 0x4000c720; +tolower = 0x40001868; +toupper = 0x40001884; +ungetc = 0x400590f4; +_ungetc_r = 0x40058fa0; +__utoa = 0x400561f0; +utoa = 0x40056258; +wcrtomb = 0x40058920; +_wcrtomb_r = 0x400588d8; +_wctomb_r = 0x40058f14; From 3f2fe8371818c3f1af654c224c3f1b97557c5264 Mon Sep 17 00:00:00 2001 From: Haolan Date: Fri, 29 Aug 2025 16:02:23 +0800 Subject: [PATCH 25/46] fix: check needStart by libc name --- internal/build/build.go | 15 +- .../crosscompile/compile/libc/newlibesp.go | 1 + targets/esp32.rom.newlib-funcs.ld | 130 ------------------ 3 files changed, 9 insertions(+), 137 deletions(-) delete mode 100644 targets/esp32.rom.newlib-funcs.ld diff --git a/internal/build/build.go b/internal/build/build.go index 8892e084..096e0cc3 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -839,15 +839,16 @@ func isWasmTarget(goos string) bool { return slices.Contains([]string{"wasi", "js", "wasip1"}, goos) } -func needStart(conf *Config) bool { - if conf.Target == "" { - return !isWasmTarget(conf.Goos) +func needStart(ctx *context) bool { + if ctx.buildConf.Target == "" { + return !isWasmTarget(ctx.buildConf.Goos) } - switch conf.Target { + switch ctx.buildConf.Target { case "wasip2": return false default: - return true + // since newlib-esp32 provides _start, we don't need to provide a fake _start function + return ctx.crossCompile.Libc != "newlib-esp32" } } @@ -904,10 +905,10 @@ define weak void @_start() { } ` mainDefine := "define i32 @main(i32 noundef %0, ptr nocapture noundef readnone %1) local_unnamed_addr" - if !needStart(ctx.buildConf) && isWasmTarget(ctx.buildConf.Goos) { + if !needStart(ctx) && isWasmTarget(ctx.buildConf.Goos) { mainDefine = "define hidden noundef i32 @__main_argc_argv(i32 noundef %0, ptr nocapture noundef readnone %1) local_unnamed_addr" } - if true { + if !needStart(ctx) { startDefine = "" } mainCode := fmt.Sprintf(`; ModuleID = 'main' diff --git a/internal/crosscompile/compile/libc/newlibesp.go b/internal/crosscompile/compile/libc/newlibesp.go index 7dc99059..6b354885 100644 --- a/internal/crosscompile/compile/libc/newlibesp.go +++ b/internal/crosscompile/compile/libc/newlibesp.go @@ -25,6 +25,7 @@ func GetNewlibESP32Config(baseDir, arch string) *compile.CompileConfig { filepath.Join(baseDir, "libgloss", "xtensa", "boards", "esp32", "board.c"), filepath.Join(baseDir, "libgloss", "xtensa", "crt1-boards.S"), filepath.Join(baseDir, "libgloss", "xtensa", "sleep.S"), + filepath.Join(baseDir, "libgloss", "xtensa", "window-vectors.S"), }, CFlags: []string{ "-DHAVE_CONFIG_H", diff --git a/targets/esp32.rom.newlib-funcs.ld b/targets/esp32.rom.newlib-funcs.ld deleted file mode 100644 index 79d5c5be..00000000 --- a/targets/esp32.rom.newlib-funcs.ld +++ /dev/null @@ -1,130 +0,0 @@ -/* These are the newlib functions present in ESP32 ROM. - They should not be used when compiling with PSRAM cache workaround enabled. - See also esp32.rom.newlib-data.ld for the list of .data/.bss symbols - used by these functions, and esp32.rom.newlib-nano.ld for "nano" versions - of printf/scanf family of functions. - - Unlike other ROM functions which are exported using PROVIDE, which declares - weak symbols, newlib related functions are exported using assignment, - which declares strong symbols. This is done so that ROM functions are always - used instead of the ones provided by libc.a. - - Time functions were moved to the esp32.rom.newlib-time.ld file. - */ - -abs = 0x40056340; -__ascii_wctomb = 0x40058ef0; -atoi = 0x400566c4; -_atoi_r = 0x400566d4; -atol = 0x400566ec; -_atol_r = 0x400566fc; -bzero = 0x4000c1f4; -_cleanup = 0x40001df8; -_cleanup_r = 0x40001d48; -creat = 0x40000e8c; -div = 0x40056348; -__dummy_lock = 0x4000c728; -__dummy_lock_try = 0x4000c730; -__env_lock = 0x40001fd4; -__env_unlock = 0x40001fe0; -fclose = 0x400020ac; -_fclose_r = 0x40001fec; -fflush = 0x40059394; -_fflush_r = 0x40059320; -_findenv_r = 0x40001f44; -__fp_lock_all = 0x40001f1c; -__fp_unlock_all = 0x40001f30; -__fputwc = 0x40058da0; -fputwc = 0x40058ea8; -_fputwc_r = 0x40058e4c; -_fwalk = 0x4000c738; -_fwalk_reent = 0x4000c770; -_getenv_r = 0x40001fbc; -isalnum = 0x40000f04; -isalpha = 0x40000f18; -isascii = 0x4000c20c; -isblank = 0x40000f2c; -iscntrl = 0x40000f50; -isdigit = 0x40000f64; -isgraph = 0x40000f94; -islower = 0x40000f78; -isprint = 0x40000fa8; -ispunct = 0x40000fc0; -isspace = 0x40000fd4; -isupper = 0x40000fe8; -__itoa = 0x40056678; -itoa = 0x400566b4; -labs = 0x40056370; -ldiv = 0x40056378; -longjmp = 0x400562cc; -memccpy = 0x4000c220; -memchr = 0x4000c244; -memcmp = 0x4000c260; -memcpy = 0x4000c2c8; -memmove = 0x4000c3c0; -memrchr = 0x4000c400; -memset = 0x4000c44c; -qsort = 0x40056424; -rand = 0x40001058; -rand_r = 0x400010d4; -__sccl = 0x4000c498; -__sclose = 0x400011b8; -__seofread = 0x40001148; -setjmp = 0x40056268; -__sflush_r = 0x400591e0; -__sfmoreglue = 0x40001dc8; -__sfp = 0x40001e90; -__sfp_lock_acquire = 0x40001e08; -__sfp_lock_release = 0x40001e14; -__sinit = 0x40001e38; -__sinit_lock_acquire = 0x40001e20; -__sinit_lock_release = 0x40001e2c; -srand = 0x40001004; -__sread = 0x40001118; -__sseek = 0x40001184; -strcasecmp = 0x400011cc; -strcasestr = 0x40001210; -strcat = 0x4000c518; -strchr = 0x4000c53c; -strcmp = 0x40001274; -strcoll = 0x40001398; -strcpy = 0x400013ac; -strcspn = 0x4000c558; -strdup = 0x4000143c; -_strdup_r = 0x40001450; -strlcat = 0x40001470; -strlcpy = 0x4000c584; -strlen = 0x400014c0; -strlwr = 0x40001524; -strncasecmp = 0x40001550; -strncat = 0x4000c5c4; -strncmp = 0x4000c5f4; -strncpy = 0x400015d4; -strndup = 0x400016b0; -_strndup_r = 0x400016c4; -strnlen = 0x4000c628; -strrchr = 0x40001708; -strsep = 0x40001734; -strspn = 0x4000c648; -strstr = 0x4000c674; -__strtok_r = 0x4000c6a8; -strtok_r = 0x4000c70c; -strtol = 0x4005681c; -_strtol_r = 0x40056714; -strtoul = 0x4005692c; -_strtoul_r = 0x40056834; -strupr = 0x4000174c; -__submore = 0x40058f3c; -__swbuf = 0x40058cb4; -__swbuf_r = 0x40058bec; -__swrite = 0x40001150; -toascii = 0x4000c720; -tolower = 0x40001868; -toupper = 0x40001884; -ungetc = 0x400590f4; -_ungetc_r = 0x40058fa0; -__utoa = 0x400561f0; -utoa = 0x40056258; -wcrtomb = 0x40058920; -_wcrtomb_r = 0x400588d8; -_wctomb_r = 0x40058f14; From 61143a6ff001cd9816e4ee74ec0a6b86ebdd3e09 Mon Sep 17 00:00:00 2001 From: Haolan Date: Fri, 29 Aug 2025 16:27:23 +0800 Subject: [PATCH 26/46] fix: newlib url and rt url --- .../crosscompile/compile/libc/newlibesp.go | 7 ++----- .../crosscompile/compile/rtlib/compiler_rt.go | 4 ++-- internal/crosscompile/crosscompile.go | 19 +++++++++++++++---- internal/crosscompile/fetch.go | 2 +- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/internal/crosscompile/compile/libc/newlibesp.go b/internal/crosscompile/compile/libc/newlibesp.go index 6b354885..7beb902c 100644 --- a/internal/crosscompile/compile/libc/newlibesp.go +++ b/internal/crosscompile/compile/libc/newlibesp.go @@ -10,11 +10,8 @@ import ( func GetNewlibESP32Config(baseDir, arch string) *compile.CompileConfig { libcDir := filepath.Join(baseDir, "newlib", "libc") - // headerFile, _ := os.Create(filepath.Join(baseDir, "picolibc.h")) - // headerFile.Close() - return &compile.CompileConfig{ - Url: "https://github.com/MeteorsLiu/newlib-esp32/archive/refs/heads/esp-4.3.0.zip", + Url: "https://github.com/goplus/newlib/archive/refs/tags/v0.1.0.tar.gz", Name: "newlib-esp32", Groups: []compile.CompileGroup{ { @@ -987,6 +984,6 @@ func GetNewlibESP32Config(baseDir, arch string) *compile.CompileConfig { }, }, }, - ArchiveSrcDir: "newlib-esp32-esp-4.3.0", + ArchiveSrcDir: "newlib-0.1.0", } } diff --git a/internal/crosscompile/compile/rtlib/compiler_rt.go b/internal/crosscompile/compile/rtlib/compiler_rt.go index 5ffa0ba0..6de99715 100644 --- a/internal/crosscompile/compile/rtlib/compiler_rt.go +++ b/internal/crosscompile/compile/rtlib/compiler_rt.go @@ -8,8 +8,8 @@ import ( func GetCompilerRTConfig(baseDir, arch string) *compile.CompileConfig { return &compile.CompileConfig{ - Url: "https://github.com/MeteorsLiu/llvm-project/archive/refs/heads/compiler-rt.zip", - ArchiveSrcDir: "llvm-project-compiler-rt", + Url: "https://github.com/goplus/compiler-rt/archive/refs/tags/v0.1.0.tar.gz", + ArchiveSrcDir: "compiler-rt-0.1.0", Groups: []compile.CompileGroup{ { OutputFileName: "libclang_builtins.a", diff --git a/internal/crosscompile/crosscompile.go b/internal/crosscompile/crosscompile.go index f6e2664e..fbfa8935 100644 --- a/internal/crosscompile/crosscompile.go +++ b/internal/crosscompile/crosscompile.go @@ -26,6 +26,7 @@ type Export struct { BuildTags []string GOOS string GOARCH string + Libc string Linker string // Linker to use (e.g., "ld.lld", "avr-ld") ExtraFiles []string // Extra files to compile and link (e.g., .s, .c files) ClangRoot string // Root directory of custom clang installation @@ -220,8 +221,16 @@ func ldFlagsFromFileName(fileName string) string { return strings.TrimPrefix(strings.TrimSuffix(fileName, ".a"), "lib") } -func getOrCompileWithConfig(compileConfig *compile.CompileConfig, outputDir, cc, linkerName, libName string, exportCCFlags, exportLDFlags []string) (ldflags []string, err error) { - if err = checkDownloadAndExtractLib(compileConfig, compileConfig.Url, outputDir, compileConfig.ArchiveSrcDir); err != nil { +func getOrCompileWithConfig( + compileConfig *compile.CompileConfig, + outputDir, cc, linkerName string, + exportCCFlags, exportLDFlags []string, +) (ldflags []string, err error) { + if err = checkDownloadAndExtractLib( + compileConfig, + compileConfig.Url, outputDir, + compileConfig.ArchiveSrcDir, + ); err != nil { return } ldflags = append(ldflags, "-nostdlib", "-L"+outputDir) @@ -608,11 +617,13 @@ func useTarget(targetName string) (export Export, err error) { if err != nil { return } - libcLDFlags, err = getOrCompileWithConfig(compileConfig, outputDir, export.CC, export.Linker, config.Libc, ccflags, ldflags) + libcLDFlags, err = getOrCompileWithConfig(compileConfig, outputDir, export.CC, export.Linker, ccflags, ldflags) if err != nil { return } ldflags = append(ldflags, libcLDFlags...) + + export.Libc = config.Libc } if config.RTLib != "" { @@ -625,7 +636,7 @@ func useTarget(targetName string) (export Export, err error) { if err != nil { return } - rtLibLDFlags, err = getOrCompileWithConfig(compileConfig, outputDir, export.CC, export.Linker, config.RTLib, ccflags, ldflags) + rtLibLDFlags, err = getOrCompileWithConfig(compileConfig, outputDir, export.CC, export.Linker, ccflags, ldflags) if err != nil { return } diff --git a/internal/crosscompile/fetch.go b/internal/crosscompile/fetch.go index 950ca19b..4c21ff5f 100644 --- a/internal/crosscompile/fetch.go +++ b/internal/crosscompile/fetch.go @@ -102,7 +102,7 @@ func checkDownloadAndExtractLib(cfg *compile.CompileConfig, url, dstDir, interna } fmt.Fprintf(os.Stderr, "%s not found in LLGO_ROOT or cache, will download and compile.\n", dstDir) - description := fmt.Sprintf("Libc %s", path.Base(url)) + description := fmt.Sprintf("Lib %s", path.Base(url)) // Use temporary extraction directory tempExtractDir := dstDir + ".extract" From 19ddee02410d53ed1c5eb03d762f3a2a4eadfaed Mon Sep 17 00:00:00 2001 From: Haolan Date: Fri, 29 Aug 2025 17:48:34 +0800 Subject: [PATCH 27/46] test: add compile test --- internal/crosscompile/compile/compile.go | 7 +- internal/crosscompile/compile/compile_test.go | 142 ++++++++++++++++++ internal/crosscompile/fetch_test.go | 2 +- 3 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 internal/crosscompile/compile/compile_test.go diff --git a/internal/crosscompile/compile/compile.go b/internal/crosscompile/compile/compile.go index 5165b39f..20b52aa1 100644 --- a/internal/crosscompile/compile/compile.go +++ b/internal/crosscompile/compile/compile.go @@ -43,7 +43,7 @@ func (g CompileGroup) Compile(outputDir, cc, linkerName string, extraCCFlags, ex compiler := clang.NewCompiler(cfg) - compiler.Verbose = true + compiler.Verbose = false archive := filepath.Join(outputDir, g.OutputFileName) fmt.Fprintf(os.Stderr, "Start to compile group %s to %s...\n", g.OutputFileName, archive) @@ -75,8 +75,9 @@ func (g CompileGroup) Compile(outputDir, cc, linkerName string, extraCCFlags, ex llvmAr := filepath.Join(ccDir, "llvm-ar") cmd := exec.Command(llvmAr, args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr + // TODO(MeteorsLiu): support verbose + // cmd.Stdout = os.Stdout + // cmd.Stderr = os.Stderr err = cmd.Run() return } diff --git a/internal/crosscompile/compile/compile_test.go b/internal/crosscompile/compile/compile_test.go new file mode 100644 index 00000000..9995c555 --- /dev/null +++ b/internal/crosscompile/compile/compile_test.go @@ -0,0 +1,142 @@ +package compile + +import ( + "os" + "strings" + "testing" + + "github.com/goplus/llgo/xtool/nm" +) + +func TestIsCompile(t *testing.T) { + t.Run("IsCompile Not Exists", func(t *testing.T) { + cfg := CompileConfig{ + Groups: []CompileGroup{ + { + OutputFileName: "fakefile1.a", + }, + }, + } + + if cfg.IsCompiled(".") || cfg.Groups[0].IsCompiled(".") { + t.Errorf("unexpected result: should false") + } + }) + t.Run("IsCompile Exists", func(t *testing.T) { + tmpFile, err := os.CreateTemp(".", "test*.a") + if err != nil { + t.Error(err) + return + } + defer os.Remove(tmpFile.Name()) + cfg := CompileConfig{ + Groups: []CompileGroup{ + { + OutputFileName: tmpFile.Name(), + }, + }, + } + + if !cfg.IsCompiled(".") && !cfg.Groups[0].IsCompiled(".") { + t.Errorf("unexpected result: should true") + } + }) +} + +func TestCompile(t *testing.T) { + t.Run("Skip compile", func(t *testing.T) { + tmpFile, err := os.CreateTemp(".", "test*.a") + if err != nil { + t.Error(err) + return + } + defer os.Remove(tmpFile.Name()) + group := CompileGroup{ + OutputFileName: tmpFile.Name(), + } + err = group.Compile(".", "clang", "lld", nil, nil) + if err != nil { + t.Errorf("unexpected result: should nil") + } + }) + + t.Run("TmpDir Fail", func(t *testing.T) { + err := os.Mkdir("test-compile", 0) + if err != nil { + t.Error(err) + return + } + defer os.RemoveAll("test-compile") + + os.Setenv("TMPDIR", "test-compile") + defer os.Unsetenv("TMPDIR") + + group := CompileGroup{ + OutputFileName: "nop.a", + } + err = group.Compile(".", "clang", "lld", nil, nil) + if err == nil { + t.Errorf("unexpected result: should not nil") + } + }) + + t.Run("Compile", func(t *testing.T) { + tmpFile, err := os.CreateTemp("", "test*.c") + if err != nil { + t.Error(err) + return + } + defer os.Remove(tmpFile.Name()) + + _, err = tmpFile.Write([]byte(`#include + void Foo() { + double x = 2.0; + double y = sqrt(x); + (void) y ; + } + `)) + if err != nil { + t.Error(err) + return + } + + group := CompileGroup{ + OutputFileName: "nop.a", + Files: []string{tmpFile.Name()}, + } + err = group.Compile(".", "clang", "lld", []string{"-nostdinc"}, nil) + if err == nil { + t.Errorf("unexpected result: should not nil") + } + err = group.Compile(".", "clang", "lld", nil, nil) + if err != nil { + t.Errorf("unexpected result: should not nil") + } + if _, err := os.Stat("nop.a"); os.IsNotExist(err) { + t.Error("unexpected result: compiled nop.a not found") + return + } + defer os.Remove("nop.a") + + items, err := nm.New("").List("nop.a") + if err != nil { + t.Error(err) + return + } + + want := "Foo" + found := false + loop: + for _, item := range items { + for _, sym := range item.Symbols { + if strings.Contains(sym.Name, want) { + found = true + break loop + } + } + } + if !found { + t.Errorf("cannot find symbol Foo") + } + }) +} diff --git a/internal/crosscompile/fetch_test.go b/internal/crosscompile/fetch_test.go index 9bd2c496..7f5d2af9 100644 --- a/internal/crosscompile/fetch_test.go +++ b/internal/crosscompile/fetch_test.go @@ -287,7 +287,7 @@ func TestDownloadAndExtractArchive(t *testing.T) { func TestDownloadAndExtractArchiveUnsupportedFormat(t *testing.T) { server := createTestServer(t, map[string]string{ - "test.zip": "fake zip content", + "test.7z": "fake zip content", }) defer server.Close() From 53e22488c83855ac5ea72f473047adc0ce386f53 Mon Sep 17 00:00:00 2001 From: Haolan Date: Fri, 29 Aug 2025 17:54:08 +0800 Subject: [PATCH 28/46] fix: remove debug compiler options --- internal/build/build.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/build/build.go b/internal/build/build.go index 096e0cc3..83365ffa 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -826,7 +826,6 @@ func linkObjFiles(ctx *context, app string, objFiles, linkArgs []string, verbose if IsDbgSymsEnabled() { buildArgs = append(buildArgs, "-gdwarf-4") } - buildArgs = append(buildArgs, "--cref", "--Map=t.map") buildArgs = append(buildArgs, objFiles...) From 1b3889ebc937d7fd69ace2b8a7e16d42e5bd7372 Mon Sep 17 00:00:00 2001 From: Haolan Date: Fri, 29 Aug 2025 19:25:09 +0800 Subject: [PATCH 29/46] feat: add target name design --- internal/crosscompile/compile/libc/newlibesp.go | 9 +++++---- internal/crosscompile/compile/libc/picolibc.go | 5 +++-- internal/crosscompile/compile/rtlib/compiler_rt.go | 5 +++-- internal/crosscompile/crosscompile.go | 5 ++--- internal/crosscompile/fetch.go | 13 ++++--------- internal/crosscompile/libc.go | 10 +++++----- 6 files changed, 22 insertions(+), 25 deletions(-) diff --git a/internal/crosscompile/compile/libc/newlibesp.go b/internal/crosscompile/compile/libc/newlibesp.go index 7beb902c..b310c618 100644 --- a/internal/crosscompile/compile/libc/newlibesp.go +++ b/internal/crosscompile/compile/libc/newlibesp.go @@ -1,13 +1,14 @@ package libc import ( + "fmt" "path/filepath" "github.com/goplus/llgo/internal/crosscompile/compile" ) // getNewlibESP32Config returns configuration for newlib esp32 -func GetNewlibESP32Config(baseDir, arch string) *compile.CompileConfig { +func GetNewlibESP32Config(baseDir, target string) *compile.CompileConfig { libcDir := filepath.Join(baseDir, "newlib", "libc") return &compile.CompileConfig{ @@ -15,7 +16,7 @@ func GetNewlibESP32Config(baseDir, arch string) *compile.CompileConfig { Name: "newlib-esp32", Groups: []compile.CompileGroup{ { - OutputFileName: "libcrt0.a", + OutputFileName: fmt.Sprintf("libcrt0-%s.a", target), Files: []string{ filepath.Join(baseDir, "libgloss", "xtensa", "clibrary_init.c"), filepath.Join(baseDir, "libgloss", "xtensa", "syscalls.c"), @@ -39,7 +40,7 @@ func GetNewlibESP32Config(baseDir, arch string) *compile.CompileConfig { }, }, { - OutputFileName: "libgloss.a", + OutputFileName: fmt.Sprintf("libgloss-%s.a", target), Files: []string{ filepath.Join(baseDir, "libgloss", "libnosys", "chown.c"), filepath.Join(baseDir, "libgloss", "libnosys", "close.c"), @@ -236,7 +237,7 @@ func GetNewlibESP32Config(baseDir, arch string) *compile.CompileConfig { }, }, { - OutputFileName: "libc.a", + OutputFileName: fmt.Sprintf("libc-%s.a", target), Files: []string{ filepath.Join(libcDir, "argz", "argz_add.c"), filepath.Join(libcDir, "argz", "argz_add_sep.c"), diff --git a/internal/crosscompile/compile/libc/picolibc.go b/internal/crosscompile/compile/libc/picolibc.go index 319fbad2..a7efa2da 100644 --- a/internal/crosscompile/compile/libc/picolibc.go +++ b/internal/crosscompile/compile/libc/picolibc.go @@ -1,6 +1,7 @@ package libc import ( + "fmt" "os" "path/filepath" @@ -8,7 +9,7 @@ import ( ) // getPicolibcConfig returns configuration for picolibc -func GetPicolibcConfig(baseDir string) *compile.CompileConfig { +func GetPicolibcConfig(baseDir, target string) *compile.CompileConfig { libcIncludeDir := filepath.Join(baseDir, "libc", "include") libmIncludeDir := filepath.Join(baseDir, "libm", "common") localeIncludeDir := filepath.Join(baseDir, "libc", "locale") @@ -23,7 +24,7 @@ func GetPicolibcConfig(baseDir string) *compile.CompileConfig { Name: "picolibc", Groups: []compile.CompileGroup{ { - OutputFileName: "libc.a", + OutputFileName: fmt.Sprintf("libc-%s.a", target), Files: []string{ filepath.Join(baseDir, "libc", "string", "bcmp.c"), filepath.Join(baseDir, "libc", "string", "bcopy.c"), diff --git a/internal/crosscompile/compile/rtlib/compiler_rt.go b/internal/crosscompile/compile/rtlib/compiler_rt.go index 6de99715..d8926918 100644 --- a/internal/crosscompile/compile/rtlib/compiler_rt.go +++ b/internal/crosscompile/compile/rtlib/compiler_rt.go @@ -1,18 +1,19 @@ package rtlib import ( + "fmt" "path/filepath" "github.com/goplus/llgo/internal/crosscompile/compile" ) -func GetCompilerRTConfig(baseDir, arch string) *compile.CompileConfig { +func GetCompilerRTConfig(baseDir, target string) *compile.CompileConfig { return &compile.CompileConfig{ Url: "https://github.com/goplus/compiler-rt/archive/refs/tags/v0.1.0.tar.gz", ArchiveSrcDir: "compiler-rt-0.1.0", Groups: []compile.CompileGroup{ { - OutputFileName: "libclang_builtins.a", + OutputFileName: fmt.Sprintf("libclang_builtins-%s.a", target), Files: []string{ filepath.Join(baseDir, "lib", "builtins", "xtensa/ieee754_sqrtf.S"), filepath.Join(baseDir, "lib", "builtins", "absvdi2.c"), diff --git a/internal/crosscompile/crosscompile.go b/internal/crosscompile/crosscompile.go index fbfa8935..13e69de3 100644 --- a/internal/crosscompile/crosscompile.go +++ b/internal/crosscompile/crosscompile.go @@ -227,7 +227,6 @@ func getOrCompileWithConfig( exportCCFlags, exportLDFlags []string, ) (ldflags []string, err error) { if err = checkDownloadAndExtractLib( - compileConfig, compileConfig.Url, outputDir, compileConfig.ArchiveSrcDir, ); err != nil { @@ -613,7 +612,7 @@ func useTarget(targetName string) (export Export, err error) { baseDir := filepath.Join(cacheRoot(), "crosscompile") outputDir := filepath.Join(baseDir, config.Libc) - compileConfig, err = getLibcCompileConfigByName(baseDir, config.Libc) + compileConfig, err = getLibcCompileConfigByName(baseDir, config.Libc, config.LLVMTarget) if err != nil { return } @@ -632,7 +631,7 @@ func useTarget(targetName string) (export Export, err error) { baseDir := filepath.Join(cacheRoot(), "crosscompile") outputDir := filepath.Join(baseDir, config.RTLib) - compileConfig, err = getRTCompileConfigByName(baseDir, config.RTLib) + compileConfig, err = getRTCompileConfigByName(baseDir, config.RTLib, config.LLVMTarget) if err != nil { return } diff --git a/internal/crosscompile/fetch.go b/internal/crosscompile/fetch.go index 4c21ff5f..40db05f5 100644 --- a/internal/crosscompile/fetch.go +++ b/internal/crosscompile/fetch.go @@ -13,8 +13,6 @@ import ( "path/filepath" "strings" "syscall" - - "github.com/goplus/llgo/internal/crosscompile/compile" ) // checkDownloadAndExtractWasiSDK downloads and extracts WASI SDK @@ -82,9 +80,9 @@ func checkDownloadAndExtractESPClang(platformSuffix, dir string) error { return nil } -func checkDownloadAndExtractLib(cfg *compile.CompileConfig, url, dstDir, internalArchiveSrcDir string) error { +func checkDownloadAndExtractLib(url, dstDir, internalArchiveSrcDir string) error { // Check if already exists - if cfg.IsCompiled(dstDir) { + if _, err := os.Stat(dstDir); err == nil { return nil } @@ -97,7 +95,7 @@ func checkDownloadAndExtractLib(cfg *compile.CompileConfig, url, dstDir, interna defer releaseLock(lockFile) // Double-check after acquiring lock - if cfg.IsCompiled(dstDir) { + if _, err := os.Stat(dstDir); err == nil { return nil } fmt.Fprintf(os.Stderr, "%s not found in LLGO_ROOT or cache, will download and compile.\n", dstDir) @@ -117,10 +115,7 @@ func checkDownloadAndExtractLib(cfg *compile.CompileConfig, url, dstDir, interna srcDir = filepath.Join(tempExtractDir, internalArchiveSrcDir) } - os.RemoveAll(dstDir) - if err := os.Rename(srcDir, dstDir); err != nil { - return fmt.Errorf("failed to rename libc directory: %w", err) - } + os.Rename(srcDir, dstDir) return nil } diff --git a/internal/crosscompile/libc.go b/internal/crosscompile/libc.go index 8bd96e85..f3d27f4d 100644 --- a/internal/crosscompile/libc.go +++ b/internal/crosscompile/libc.go @@ -11,7 +11,7 @@ import ( // GetCompileConfigByName retrieves libc compilation configuration by name // Returns compilation file lists and corresponding cflags -func getLibcCompileConfigByName(baseDir, libcName string) (*compile.CompileConfig, error) { +func getLibcCompileConfigByName(baseDir, libcName, target string) (*compile.CompileConfig, error) { if libcName == "" { return nil, fmt.Errorf("libc name cannot be empty") } @@ -19,15 +19,15 @@ func getLibcCompileConfigByName(baseDir, libcName string) (*compile.CompileConfi switch libcName { case "picolibc": - return libc.GetPicolibcConfig(libcDir), nil + return libc.GetPicolibcConfig(libcDir, target), nil case "newlib-esp32": - return libc.GetNewlibESP32Config(libcDir, "xtensa"), nil + return libc.GetNewlibESP32Config(libcDir, target), nil default: return nil, fmt.Errorf("unsupported libc: %s", libcName) } } -func getRTCompileConfigByName(baseDir, rtName string) (*compile.CompileConfig, error) { +func getRTCompileConfigByName(baseDir, rtName, target string) (*compile.CompileConfig, error) { if rtName == "" { return nil, fmt.Errorf("rt name cannot be empty") } @@ -35,7 +35,7 @@ func getRTCompileConfigByName(baseDir, rtName string) (*compile.CompileConfig, e switch rtName { case "compiler-rt": - return rtlib.GetCompilerRTConfig(rtDir, "xtensa"), nil + return rtlib.GetCompilerRTConfig(rtDir, target), nil default: return nil, fmt.Errorf("unsupported rt: %s", rtName) } From 997ea2849b557f994ad332f80558ee4bf66bd8b3 Mon Sep 17 00:00:00 2001 From: Haolan Date: Mon, 1 Sep 2025 14:48:54 +0800 Subject: [PATCH 30/46] feat: support riscv32 --- .../crosscompile/compile/libc/newlibesp.go | 1074 ++++++++++++++++- .../crosscompile/compile/rtlib/compiler_rt.go | 29 +- internal/crosscompile/crosscompile.go | 6 +- internal/crosscompile/libc.go | 4 +- targets/esp32-riscv.app.elf.ld | 195 +++ targets/esp32c2.memory.ld | 33 + targets/esp32c3.json | 30 +- targets/esp32c3.memory.ld | 26 + targets/esp32c5.memory.ld | 22 + targets/esp32c6.memory.ld | 22 + targets/esp32c61.memory.ld | 21 + targets/esp32h2.memory.ld | 22 + targets/esp32h21.memory.ld | 21 + targets/esp32p4.memory.ld | 23 + targets/xtensa.json | 14 +- 15 files changed, 1518 insertions(+), 24 deletions(-) create mode 100644 targets/esp32-riscv.app.elf.ld create mode 100644 targets/esp32c2.memory.ld create mode 100644 targets/esp32c3.memory.ld create mode 100644 targets/esp32c5.memory.ld create mode 100644 targets/esp32c6.memory.ld create mode 100644 targets/esp32c61.memory.ld create mode 100644 targets/esp32h2.memory.ld create mode 100644 targets/esp32h21.memory.ld create mode 100644 targets/esp32p4.memory.ld diff --git a/internal/crosscompile/compile/libc/newlibesp.go b/internal/crosscompile/compile/libc/newlibesp.go index b310c618..1c0e4760 100644 --- a/internal/crosscompile/compile/libc/newlibesp.go +++ b/internal/crosscompile/compile/libc/newlibesp.go @@ -3,12 +3,1073 @@ package libc import ( "fmt" "path/filepath" + "strings" "github.com/goplus/llgo/internal/crosscompile/compile" ) -// getNewlibESP32Config returns configuration for newlib esp32 -func GetNewlibESP32Config(baseDir, target string) *compile.CompileConfig { +func getNewlibESP32ConfigRISCV(baseDir, target string) *compile.CompileConfig { + libcDir := filepath.Join(baseDir, "newlib", "libc") + + return &compile.CompileConfig{ + Url: "https://github.com/goplus/newlib/archive/refs/tags/v0.2.0.tar.gz", + Name: "newlib-esp32", + Groups: []compile.CompileGroup{ + { + OutputFileName: fmt.Sprintf("libcrt0-%s.a", target), + Files: []string{ + filepath.Join(baseDir, "libgloss", "riscv", "esp", "esp_board.c"), + filepath.Join(baseDir, "libgloss", "riscv", "esp", "syscalls.c"), + filepath.Join(baseDir, "libgloss", "riscv", "esp", "crt1-board.S"), + }, + CFlags: []string{ + "-DHAVE_CONFIG_H", + "-isystem" + filepath.Join(libcDir, "include"), + "-I" + filepath.Join(baseDir, "libgloss"), + // TODO(MeteorsLiu): support riscv + "-I" + filepath.Join(baseDir, "libgloss", "riscv"), + "-I" + filepath.Join(baseDir, "libgloss", "riscv", "esp"), + }, + LDFlags: []string{"-nostdlib"}, + CCFlags: []string{ + "-Oz", + }, + }, + { + OutputFileName: fmt.Sprintf("libgloss-%s.a", target), + Files: []string{ + filepath.Join(baseDir, "libgloss", "libnosys", "chown.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "close.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "environ.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "errno.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "execve.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "fork.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "fstat.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "getpid.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "gettod.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "isatty.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "kill.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "link.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "lseek.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "open.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "read.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "readlink.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "sbrk.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "stat.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "symlink.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "times.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "unlink.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "wait.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "write.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "getentropy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "_exit.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "getreent.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "time.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "fcntl.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "chdir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "chmod.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "closedir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "dirfd.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "ftw.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "getcwd.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "mkdir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "nftw.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "opendir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pathconf.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "readdir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "rewinddir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "scandir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "seekdir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "telldir.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "rename.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "_pthread_cleanup_pop.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "_pthread_cleanup_pop_restore.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "_pthread_cleanup_push.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "_pthread_cleanup_push_defer.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_atfork.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getaffinity_np.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getdetachstate.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getguardsize.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getinheritsched.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getschedparam.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getschedpolicy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getscope.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getstack.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getstackaddr.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_getstacksize.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setaffinity_np.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setdetachstate.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setguardsize.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setinheritsched.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setschedparam.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setschedpolicy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setscope.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setstack.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setstackaddr.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_attr_setstacksize.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_barrier_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_barrier_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_barrier_wait.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_barrierattr_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_barrierattr_getpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_barrierattr_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_barrierattr_setpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cancel.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cond_broadcast.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cond_clockwait.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cond_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cond_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cond_signal.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cond_timedwait.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_cond_wait.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_condattr_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_condattr_getclock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_condattr_getpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_condattr_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_condattr_setclock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_condattr_setpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_create.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_detach.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_equal.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_exit.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_getaffinity_np.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_getattr_np.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_getconcurrency.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_getcpuclockid.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_getname_np.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_getschedparam.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_getspecific.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_join.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_key_create.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_key_delete.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_clocklock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_getprioceiling.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_lock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_setprioceiling.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_timedlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_trylock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutex_unlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_getprioceiling.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_getprotocol.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_getpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_gettype.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_setprioceiling.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_setprotocol.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_setpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_mutexattr_settype.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_once.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_clockrdlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_clockwrlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_rdlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_timedrdlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_timedwrlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_tryrdlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_trywrlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_unlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlock_wrlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlockattr_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlockattr_getpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlockattr_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_rwlockattr_setpshared.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_self.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setaffinity_np.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setcancelstate.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setcanceltype.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setconcurrency.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setname_np.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setschedparam.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setschedprio.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_setspecific.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_spin_destroy.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_spin_init.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_spin_lock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_spin_trylock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_spin_unlock.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_testcancel.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "pthread_yield.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_access.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_chdir.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_chmod.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_chown.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_close.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_conv_stat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_execve.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_exit.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_faccessat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_fork.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_fstat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_fstatat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_ftime.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_getcwd.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_getpid.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_getreent.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_gettimeofday.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_isatty.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_kill.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_link.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_lseek.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_lstat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_open.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_openat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_read.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_sbrk.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_stat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_sysconf.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_times.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_unlink.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_utime.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_wait.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_write.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_access.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_chdir.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_chmod.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_chown.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_close.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_conv_stat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_execve.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_exit.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_faccessat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_fork.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_fstat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_fstatat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_ftime.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_getcwd.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_getpid.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_getreent.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_gettimeofday.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_isatty.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_kill.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_link.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_lseek.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_lstat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_open.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_openat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_read.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_sbrk.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_stat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_sysconf.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_times.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_unlink.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_utime.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_wait.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_write.c"), + filepath.Join(baseDir, "libgloss", "riscv", "nanosleep.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_chdir.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_chmod.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_chown.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_execve.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_fork.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_getcwd.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_getpid.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_getreent.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_kill.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_utime.c"), + filepath.Join(baseDir, "libgloss", "riscv", "sys_wait.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_close.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_exit.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_fdtable.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_fstat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_ftime.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_isatty.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_link.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_lseek.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_open.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_read.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_sbrk.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_stat.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_stat_common.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_unlink.c"), + filepath.Join(baseDir, "libgloss", "riscv", "semihost-sys_write.c"), + }, + CFlags: []string{ + "-DHAVE_CONFIG_H", + "-isystem" + filepath.Join(libcDir, "include"), + "-I" + libcDir, + "-I" + filepath.Join(libcDir, "riscv"), + "-I" + filepath.Join(baseDir, "libgloss"), + "-I" + filepath.Join(baseDir, "libgloss", "riscv"), + "-I" + filepath.Join(baseDir, "libgloss", "riscv", "esp"), + }, + LDFlags: []string{"-nostdlib"}, + CCFlags: []string{ + "-Oz", + }, + }, + { + OutputFileName: fmt.Sprintf("libc-%s.a", target), + Files: []string{ + filepath.Join(libcDir, "argz", "argz_add.c"), + filepath.Join(libcDir, "argz", "argz_add_sep.c"), + filepath.Join(libcDir, "argz", "argz_append.c"), + filepath.Join(libcDir, "argz", "argz_count.c"), + filepath.Join(libcDir, "argz", "argz_create.c"), + filepath.Join(libcDir, "argz", "argz_create_sep.c"), + filepath.Join(libcDir, "argz", "argz_delete.c"), + filepath.Join(libcDir, "argz", "argz_extract.c"), + filepath.Join(libcDir, "argz", "argz_insert.c"), + filepath.Join(libcDir, "argz", "argz_next.c"), + filepath.Join(libcDir, "argz", "argz_replace.c"), + filepath.Join(libcDir, "argz", "argz_stringify.c"), + filepath.Join(libcDir, "argz", "buf_findstr.c"), + filepath.Join(libcDir, "argz", "envz_entry.c"), + filepath.Join(libcDir, "argz", "envz_get.c"), + filepath.Join(libcDir, "argz", "envz_add.c"), + filepath.Join(libcDir, "argz", "envz_remove.c"), + filepath.Join(libcDir, "argz", "envz_merge.c"), + filepath.Join(libcDir, "argz", "envz_strip.c"), + filepath.Join(libcDir, "stdlib", "__adjust.c"), + filepath.Join(libcDir, "stdlib", "__atexit.c"), + filepath.Join(libcDir, "stdlib", "__call_atexit.c"), + filepath.Join(libcDir, "stdlib", "__exp10.c"), + filepath.Join(libcDir, "stdlib", "__ten_mu.c"), + filepath.Join(libcDir, "stdlib", "_Exit.c"), + filepath.Join(libcDir, "stdlib", "abort.c"), + filepath.Join(libcDir, "stdlib", "abs.c"), + filepath.Join(libcDir, "stdlib", "aligned_alloc.c"), + filepath.Join(libcDir, "stdlib", "assert.c"), + filepath.Join(libcDir, "stdlib", "atexit.c"), + filepath.Join(libcDir, "stdlib", "atof.c"), + filepath.Join(libcDir, "stdlib", "atoff.c"), + filepath.Join(libcDir, "stdlib", "atoi.c"), + filepath.Join(libcDir, "stdlib", "atol.c"), + filepath.Join(libcDir, "stdlib", "calloc.c"), + filepath.Join(libcDir, "stdlib", "callocr.c"), + filepath.Join(libcDir, "stdlib", "cfreer.c"), + filepath.Join(libcDir, "stdlib", "div.c"), + filepath.Join(libcDir, "stdlib", "dtoa.c"), + filepath.Join(libcDir, "stdlib", "dtoastub.c"), + filepath.Join(libcDir, "stdlib", "environ.c"), + filepath.Join(libcDir, "stdlib", "envlock.c"), + filepath.Join(libcDir, "stdlib", "eprintf.c"), + filepath.Join(libcDir, "stdlib", "exit.c"), + filepath.Join(libcDir, "stdlib", "freer.c"), + filepath.Join(libcDir, "stdlib", "gdtoa-gethex.c"), + filepath.Join(libcDir, "stdlib", "gdtoa-hexnan.c"), + filepath.Join(libcDir, "stdlib", "getenv.c"), + filepath.Join(libcDir, "stdlib", "getenv_r.c"), + filepath.Join(libcDir, "stdlib", "imaxabs.c"), + filepath.Join(libcDir, "stdlib", "imaxdiv.c"), + filepath.Join(libcDir, "stdlib", "itoa.c"), + filepath.Join(libcDir, "stdlib", "labs.c"), + filepath.Join(libcDir, "stdlib", "ldiv.c"), + filepath.Join(libcDir, "stdlib", "ldtoa.c"), + filepath.Join(libcDir, "stdlib", "gdtoa-ldtoa.c"), + filepath.Join(libcDir, "stdlib", "gdtoa-gdtoa.c"), + filepath.Join(libcDir, "stdlib", "gdtoa-dmisc.c"), + filepath.Join(libcDir, "stdlib", "gdtoa-gmisc.c"), + filepath.Join(libcDir, "stdlib", "mallinfor.c"), + filepath.Join(libcDir, "stdlib", "malloc.c"), + filepath.Join(libcDir, "stdlib", "mallocr.c"), + filepath.Join(libcDir, "stdlib", "mallstatsr.c"), + filepath.Join(libcDir, "stdlib", "mblen.c"), + filepath.Join(libcDir, "stdlib", "mblen_r.c"), + filepath.Join(libcDir, "stdlib", "mbstowcs.c"), + filepath.Join(libcDir, "stdlib", "mbstowcs_r.c"), + filepath.Join(libcDir, "stdlib", "mbtowc.c"), + filepath.Join(libcDir, "stdlib", "mbtowc_r.c"), + filepath.Join(libcDir, "stdlib", "mlock.c"), + filepath.Join(libcDir, "stdlib", "mprec.c"), + filepath.Join(libcDir, "stdlib", "msizer.c"), + filepath.Join(libcDir, "stdlib", "mstats.c"), + filepath.Join(libcDir, "stdlib", "on_exit_args.c"), + filepath.Join(libcDir, "stdlib", "quick_exit.c"), + filepath.Join(libcDir, "stdlib", "rand.c"), + filepath.Join(libcDir, "stdlib", "rand_r.c"), + filepath.Join(libcDir, "stdlib", "random.c"), + filepath.Join(libcDir, "stdlib", "realloc.c"), + filepath.Join(libcDir, "stdlib", "reallocarray.c"), + filepath.Join(libcDir, "stdlib", "reallocf.c"), + filepath.Join(libcDir, "stdlib", "reallocr.c"), + filepath.Join(libcDir, "stdlib", "sb_charsets.c"), + filepath.Join(libcDir, "stdlib", "strtod.c"), + filepath.Join(libcDir, "stdlib", "strtoimax.c"), + filepath.Join(libcDir, "stdlib", "strtol.c"), + filepath.Join(libcDir, "stdlib", "strtoul.c"), + filepath.Join(libcDir, "stdlib", "strtoumax.c"), + filepath.Join(libcDir, "stdlib", "utoa.c"), + filepath.Join(libcDir, "stdlib", "wcstod.c"), + filepath.Join(libcDir, "stdlib", "wcstoimax.c"), + filepath.Join(libcDir, "stdlib", "wcstol.c"), + filepath.Join(libcDir, "stdlib", "wcstoul.c"), + filepath.Join(libcDir, "stdlib", "wcstoumax.c"), + filepath.Join(libcDir, "stdlib", "wcstombs.c"), + filepath.Join(libcDir, "stdlib", "wcstombs_r.c"), + filepath.Join(libcDir, "stdlib", "wctomb.c"), + filepath.Join(libcDir, "stdlib", "wctomb_r.c"), + filepath.Join(libcDir, "stdlib", "strtodg.c"), + filepath.Join(libcDir, "stdlib", "strtold.c"), + filepath.Join(libcDir, "stdlib", "strtorx.c"), + filepath.Join(libcDir, "stdlib", "wcstold.c"), + filepath.Join(libcDir, "stdlib", "arc4random.c"), + filepath.Join(libcDir, "stdlib", "arc4random_uniform.c"), + filepath.Join(libcDir, "stdlib", "cxa_atexit.c"), + filepath.Join(libcDir, "stdlib", "cxa_finalize.c"), + filepath.Join(libcDir, "stdlib", "drand48.c"), + filepath.Join(libcDir, "stdlib", "ecvtbuf.c"), + filepath.Join(libcDir, "stdlib", "efgcvt.c"), + filepath.Join(libcDir, "stdlib", "erand48.c"), + filepath.Join(libcDir, "stdlib", "jrand48.c"), + filepath.Join(libcDir, "stdlib", "lcong48.c"), + filepath.Join(libcDir, "stdlib", "lrand48.c"), + filepath.Join(libcDir, "stdlib", "mrand48.c"), + filepath.Join(libcDir, "stdlib", "msize.c"), + filepath.Join(libcDir, "stdlib", "mtrim.c"), + filepath.Join(libcDir, "stdlib", "nrand48.c"), + filepath.Join(libcDir, "stdlib", "rand48.c"), + filepath.Join(libcDir, "stdlib", "seed48.c"), + filepath.Join(libcDir, "stdlib", "srand48.c"), + filepath.Join(libcDir, "stdlib", "strtoll.c"), + filepath.Join(libcDir, "stdlib", "strtoll_r.c"), + filepath.Join(libcDir, "stdlib", "strtoull.c"), + filepath.Join(libcDir, "stdlib", "strtoull_r.c"), + filepath.Join(libcDir, "stdlib", "wcstoll.c"), + filepath.Join(libcDir, "stdlib", "wcstoll_r.c"), + filepath.Join(libcDir, "stdlib", "wcstoull.c"), + filepath.Join(libcDir, "stdlib", "wcstoull_r.c"), + filepath.Join(libcDir, "stdlib", "atoll.c"), + filepath.Join(libcDir, "stdlib", "llabs.c"), + filepath.Join(libcDir, "stdlib", "lldiv.c"), + filepath.Join(libcDir, "stdlib", "a64l.c"), + filepath.Join(libcDir, "stdlib", "btowc.c"), + filepath.Join(libcDir, "stdlib", "getopt.c"), + filepath.Join(libcDir, "stdlib", "getsubopt.c"), + filepath.Join(libcDir, "stdlib", "l64a.c"), + filepath.Join(libcDir, "stdlib", "malign.c"), + filepath.Join(libcDir, "stdlib", "malignr.c"), + filepath.Join(libcDir, "stdlib", "malloptr.c"), + filepath.Join(libcDir, "stdlib", "mbrlen.c"), + filepath.Join(libcDir, "stdlib", "mbrtowc.c"), + filepath.Join(libcDir, "stdlib", "mbsinit.c"), + filepath.Join(libcDir, "stdlib", "mbsnrtowcs.c"), + filepath.Join(libcDir, "stdlib", "mbsrtowcs.c"), + filepath.Join(libcDir, "stdlib", "on_exit.c"), + filepath.Join(libcDir, "stdlib", "pvallocr.c"), + filepath.Join(libcDir, "stdlib", "valloc.c"), + filepath.Join(libcDir, "stdlib", "vallocr.c"), + filepath.Join(libcDir, "stdlib", "wcrtomb.c"), + filepath.Join(libcDir, "stdlib", "wcsnrtombs.c"), + filepath.Join(libcDir, "stdlib", "wcsrtombs.c"), + filepath.Join(libcDir, "stdlib", "wctob.c"), + filepath.Join(libcDir, "stdlib", "putenv.c"), + filepath.Join(libcDir, "stdlib", "putenv_r.c"), + filepath.Join(libcDir, "stdlib", "setenv.c"), + filepath.Join(libcDir, "stdlib", "setenv_r.c"), + filepath.Join(libcDir, "stdlib", "rpmatch.c"), + filepath.Join(libcDir, "stdlib", "system.c"), + filepath.Join(libcDir, "ctype", "ctype_.c"), + filepath.Join(libcDir, "ctype", "isalnum.c"), + filepath.Join(libcDir, "ctype", "isalpha.c"), + filepath.Join(libcDir, "ctype", "iscntrl.c"), + filepath.Join(libcDir, "ctype", "isdigit.c"), + filepath.Join(libcDir, "ctype", "islower.c"), + filepath.Join(libcDir, "ctype", "isupper.c"), + filepath.Join(libcDir, "ctype", "isprint.c"), + filepath.Join(libcDir, "ctype", "ispunct.c"), + filepath.Join(libcDir, "ctype", "isspace.c"), + filepath.Join(libcDir, "ctype", "isxdigit.c"), + filepath.Join(libcDir, "ctype", "tolower.c"), + filepath.Join(libcDir, "ctype", "toupper.c"), + filepath.Join(libcDir, "ctype", "categories.c"), + filepath.Join(libcDir, "ctype", "isalnum_l.c"), + filepath.Join(libcDir, "ctype", "isalpha_l.c"), + filepath.Join(libcDir, "ctype", "isascii.c"), + filepath.Join(libcDir, "ctype", "isascii_l.c"), + filepath.Join(libcDir, "ctype", "isblank.c"), + filepath.Join(libcDir, "ctype", "isblank_l.c"), + filepath.Join(libcDir, "ctype", "iscntrl_l.c"), + filepath.Join(libcDir, "ctype", "isdigit_l.c"), + filepath.Join(libcDir, "ctype", "islower_l.c"), + filepath.Join(libcDir, "ctype", "isupper_l.c"), + filepath.Join(libcDir, "ctype", "isprint_l.c"), + filepath.Join(libcDir, "ctype", "ispunct_l.c"), + filepath.Join(libcDir, "ctype", "isspace_l.c"), + filepath.Join(libcDir, "ctype", "iswalnum.c"), + filepath.Join(libcDir, "ctype", "iswalnum_l.c"), + filepath.Join(libcDir, "ctype", "iswalpha.c"), + filepath.Join(libcDir, "ctype", "iswalpha_l.c"), + filepath.Join(libcDir, "ctype", "iswblank.c"), + filepath.Join(libcDir, "ctype", "iswblank_l.c"), + filepath.Join(libcDir, "ctype", "iswcntrl.c"), + filepath.Join(libcDir, "ctype", "iswcntrl_l.c"), + filepath.Join(libcDir, "ctype", "iswctype.c"), + filepath.Join(libcDir, "ctype", "iswctype_l.c"), + filepath.Join(libcDir, "ctype", "iswdigit.c"), + filepath.Join(libcDir, "ctype", "iswdigit_l.c"), + filepath.Join(libcDir, "ctype", "iswgraph.c"), + filepath.Join(libcDir, "ctype", "iswgraph_l.c"), + filepath.Join(libcDir, "ctype", "iswlower.c"), + filepath.Join(libcDir, "ctype", "iswlower_l.c"), + filepath.Join(libcDir, "ctype", "iswprint.c"), + filepath.Join(libcDir, "ctype", "iswprint_l.c"), + filepath.Join(libcDir, "ctype", "iswpunct.c"), + filepath.Join(libcDir, "ctype", "iswpunct_l.c"), + filepath.Join(libcDir, "ctype", "iswspace.c"), + filepath.Join(libcDir, "ctype", "iswspace_l.c"), + filepath.Join(libcDir, "ctype", "iswupper.c"), + filepath.Join(libcDir, "ctype", "iswupper_l.c"), + filepath.Join(libcDir, "ctype", "iswxdigit.c"), + filepath.Join(libcDir, "ctype", "iswxdigit_l.c"), + filepath.Join(libcDir, "ctype", "isxdigit_l.c"), + filepath.Join(libcDir, "ctype", "jp2uc.c"), + filepath.Join(libcDir, "ctype", "toascii.c"), + filepath.Join(libcDir, "ctype", "toascii_l.c"), + filepath.Join(libcDir, "ctype", "tolower_l.c"), + filepath.Join(libcDir, "ctype", "toupper_l.c"), + filepath.Join(libcDir, "ctype", "towctrans.c"), + filepath.Join(libcDir, "ctype", "towctrans_l.c"), + filepath.Join(libcDir, "ctype", "towlower.c"), + filepath.Join(libcDir, "ctype", "towlower_l.c"), + filepath.Join(libcDir, "ctype", "towupper.c"), + filepath.Join(libcDir, "ctype", "towupper_l.c"), + filepath.Join(libcDir, "ctype", "wctrans.c"), + filepath.Join(libcDir, "ctype", "wctrans_l.c"), + filepath.Join(libcDir, "ctype", "wctype.c"), + filepath.Join(libcDir, "ctype", "wctype_l.c"), + filepath.Join(libcDir, "search", "bsearch.c"), + filepath.Join(libcDir, "search", "ndbm.c"), + filepath.Join(libcDir, "search", "qsort.c"), + filepath.Join(libcDir, "search", "hash.c"), + filepath.Join(libcDir, "search", "hash_bigkey.c"), + filepath.Join(libcDir, "search", "hash_buf.c"), + filepath.Join(libcDir, "search", "hash_func.c"), + filepath.Join(libcDir, "search", "hash_log2.c"), + filepath.Join(libcDir, "search", "hash_page.c"), + filepath.Join(libcDir, "search", "hcreate.c"), + filepath.Join(libcDir, "search", "hcreate_r.c"), + filepath.Join(libcDir, "search", "tdelete.c"), + filepath.Join(libcDir, "search", "tdestroy.c"), + filepath.Join(libcDir, "search", "tfind.c"), + filepath.Join(libcDir, "search", "tsearch.c"), + filepath.Join(libcDir, "search", "twalk.c"), + filepath.Join(libcDir, "search", "bsd_qsort_r.c"), + filepath.Join(libcDir, "search", "qsort_r.c"), + filepath.Join(libcDir, "stdio", "nano-vfprintf_float.c"), + filepath.Join(libcDir, "stdio", "nano-svfprintf.c"), + filepath.Join(libcDir, "stdio", "nano-svfscanf.c"), + filepath.Join(libcDir, "stdio", "nano-vfprintf.c"), + filepath.Join(libcDir, "stdio", "nano-vfprintf_i.c"), + filepath.Join(libcDir, "stdio", "nano-vfscanf.c"), + filepath.Join(libcDir, "stdio", "nano-vfscanf_i.c"), + filepath.Join(libcDir, "stdio", "nano-vfscanf_float.c"), + filepath.Join(libcDir, "stdio", "clearerr.c"), + filepath.Join(libcDir, "stdio", "fclose.c"), + filepath.Join(libcDir, "stdio", "fdopen.c"), + filepath.Join(libcDir, "stdio", "feof.c"), + filepath.Join(libcDir, "stdio", "ferror.c"), + filepath.Join(libcDir, "stdio", "fflush.c"), + filepath.Join(libcDir, "stdio", "fgetc.c"), + filepath.Join(libcDir, "stdio", "fgetpos.c"), + filepath.Join(libcDir, "stdio", "fgets.c"), + filepath.Join(libcDir, "stdio", "fileno.c"), + filepath.Join(libcDir, "stdio", "findfp.c"), + filepath.Join(libcDir, "stdio", "flags.c"), + filepath.Join(libcDir, "stdio", "fopen.c"), + filepath.Join(libcDir, "stdio", "fprintf.c"), + filepath.Join(libcDir, "stdio", "fputc.c"), + filepath.Join(libcDir, "stdio", "fputs.c"), + filepath.Join(libcDir, "stdio", "fread.c"), + filepath.Join(libcDir, "stdio", "freopen.c"), + filepath.Join(libcDir, "stdio", "fscanf.c"), + filepath.Join(libcDir, "stdio", "fseek.c"), + filepath.Join(libcDir, "stdio", "fsetpos.c"), + filepath.Join(libcDir, "stdio", "ftell.c"), + filepath.Join(libcDir, "stdio", "fvwrite.c"), + filepath.Join(libcDir, "stdio", "fwalk.c"), + filepath.Join(libcDir, "stdio", "fwrite.c"), + filepath.Join(libcDir, "stdio", "getc.c"), + filepath.Join(libcDir, "stdio", "getchar.c"), + filepath.Join(libcDir, "stdio", "getc_u.c"), + filepath.Join(libcDir, "stdio", "getchar_u.c"), + filepath.Join(libcDir, "stdio", "getdelim.c"), + filepath.Join(libcDir, "stdio", "getline.c"), + filepath.Join(libcDir, "stdio", "gets.c"), + filepath.Join(libcDir, "stdio", "makebuf.c"), + filepath.Join(libcDir, "stdio", "perror.c"), + filepath.Join(libcDir, "stdio", "printf.c"), + filepath.Join(libcDir, "stdio", "putc.c"), + filepath.Join(libcDir, "stdio", "putchar.c"), + filepath.Join(libcDir, "stdio", "putc_u.c"), + filepath.Join(libcDir, "stdio", "putchar_u.c"), + filepath.Join(libcDir, "stdio", "puts.c"), + filepath.Join(libcDir, "stdio", "refill.c"), + filepath.Join(libcDir, "stdio", "remove.c"), + filepath.Join(libcDir, "stdio", "rename.c"), + filepath.Join(libcDir, "stdio", "rewind.c"), + filepath.Join(libcDir, "stdio", "rget.c"), + filepath.Join(libcDir, "stdio", "scanf.c"), + filepath.Join(libcDir, "stdio", "sccl.c"), + filepath.Join(libcDir, "stdio", "setbuf.c"), + filepath.Join(libcDir, "stdio", "setbuffer.c"), + filepath.Join(libcDir, "stdio", "setlinebuf.c"), + filepath.Join(libcDir, "stdio", "setvbuf.c"), + filepath.Join(libcDir, "stdio", "snprintf.c"), + filepath.Join(libcDir, "stdio", "sprintf.c"), + filepath.Join(libcDir, "stdio", "sscanf.c"), + filepath.Join(libcDir, "stdio", "stdio.c"), + filepath.Join(libcDir, "stdio", "svfiwprintf.c"), + filepath.Join(libcDir, "stdio", "svfiwscanf.c"), + filepath.Join(libcDir, "stdio", "svfwprintf.c"), + filepath.Join(libcDir, "stdio", "svfwscanf.c"), + filepath.Join(libcDir, "stdio", "tmpfile.c"), + filepath.Join(libcDir, "stdio", "tmpnam.c"), + filepath.Join(libcDir, "stdio", "ungetc.c"), + filepath.Join(libcDir, "stdio", "vdprintf.c"), + filepath.Join(libcDir, "stdio", "vfiwprintf.c"), + filepath.Join(libcDir, "stdio", "vfiwscanf.c"), + filepath.Join(libcDir, "stdio", "vfwscanf.c"), + filepath.Join(libcDir, "stdio", "vprintf.c"), + filepath.Join(libcDir, "stdio", "vscanf.c"), + filepath.Join(libcDir, "stdio", "vsnprintf.c"), + filepath.Join(libcDir, "stdio", "vsprintf.c"), + filepath.Join(libcDir, "stdio", "vsscanf.c"), + filepath.Join(libcDir, "stdio", "wbuf.c"), + filepath.Join(libcDir, "stdio", "wsetup.c"), + filepath.Join(libcDir, "stdio", "asprintf.c"), + filepath.Join(libcDir, "stdio", "fcloseall.c"), + filepath.Join(libcDir, "stdio", "fseeko.c"), + filepath.Join(libcDir, "stdio", "ftello.c"), + filepath.Join(libcDir, "stdio", "getw.c"), + filepath.Join(libcDir, "stdio", "mktemp.c"), + filepath.Join(libcDir, "stdio", "putw.c"), + filepath.Join(libcDir, "stdio", "vasprintf.c"), + filepath.Join(libcDir, "stdio", "asnprintf.c"), + filepath.Join(libcDir, "stdio", "clearerr_u.c"), + filepath.Join(libcDir, "stdio", "dprintf.c"), + filepath.Join(libcDir, "stdio", "feof_u.c"), + filepath.Join(libcDir, "stdio", "ferror_u.c"), + filepath.Join(libcDir, "stdio", "fflush_u.c"), + filepath.Join(libcDir, "stdio", "fgetc_u.c"), + filepath.Join(libcDir, "stdio", "fgets_u.c"), + filepath.Join(libcDir, "stdio", "fgetwc.c"), + filepath.Join(libcDir, "stdio", "fgetwc_u.c"), + filepath.Join(libcDir, "stdio", "fgetws.c"), + filepath.Join(libcDir, "stdio", "fgetws_u.c"), + filepath.Join(libcDir, "stdio", "fileno_u.c"), + filepath.Join(libcDir, "stdio", "fmemopen.c"), + filepath.Join(libcDir, "stdio", "fopencookie.c"), + filepath.Join(libcDir, "stdio", "fpurge.c"), + filepath.Join(libcDir, "stdio", "fputc_u.c"), + filepath.Join(libcDir, "stdio", "fputs_u.c"), + filepath.Join(libcDir, "stdio", "fputwc.c"), + filepath.Join(libcDir, "stdio", "fputwc_u.c"), + filepath.Join(libcDir, "stdio", "fputws.c"), + filepath.Join(libcDir, "stdio", "fputws_u.c"), + filepath.Join(libcDir, "stdio", "fread_u.c"), + filepath.Join(libcDir, "stdio", "fsetlocking.c"), + filepath.Join(libcDir, "stdio", "funopen.c"), + filepath.Join(libcDir, "stdio", "fwide.c"), + filepath.Join(libcDir, "stdio", "fwprintf.c"), + filepath.Join(libcDir, "stdio", "fwrite_u.c"), + filepath.Join(libcDir, "stdio", "fwscanf.c"), + filepath.Join(libcDir, "stdio", "getwc.c"), + filepath.Join(libcDir, "stdio", "getwc_u.c"), + filepath.Join(libcDir, "stdio", "getwchar.c"), + filepath.Join(libcDir, "stdio", "getwchar_u.c"), + filepath.Join(libcDir, "stdio", "open_memstream.c"), + filepath.Join(libcDir, "stdio", "putwc.c"), + filepath.Join(libcDir, "stdio", "putwc_u.c"), + filepath.Join(libcDir, "stdio", "putwchar.c"), + filepath.Join(libcDir, "stdio", "putwchar_u.c"), + filepath.Join(libcDir, "stdio", "stdio_ext.c"), + filepath.Join(libcDir, "stdio", "swprintf.c"), + filepath.Join(libcDir, "stdio", "swscanf.c"), + filepath.Join(libcDir, "stdio", "ungetwc.c"), + filepath.Join(libcDir, "stdio", "vasnprintf.c"), + filepath.Join(libcDir, "stdio", "vswprintf.c"), + filepath.Join(libcDir, "stdio", "vswscanf.c"), + filepath.Join(libcDir, "stdio", "vwprintf.c"), + filepath.Join(libcDir, "stdio", "vwscanf.c"), + filepath.Join(libcDir, "stdio", "wprintf.c"), + filepath.Join(libcDir, "stdio", "wscanf.c"), + filepath.Join(libcDir, "string", "bcopy.c"), + filepath.Join(libcDir, "string", "bzero.c"), + filepath.Join(libcDir, "string", "explicit_bzero.c"), + filepath.Join(libcDir, "string", "ffsl.c"), + filepath.Join(libcDir, "string", "ffsll.c"), + filepath.Join(libcDir, "string", "fls.c"), + filepath.Join(libcDir, "string", "flsl.c"), + filepath.Join(libcDir, "string", "flsll.c"), + filepath.Join(libcDir, "string", "index.c"), + filepath.Join(libcDir, "string", "memchr.c"), + filepath.Join(libcDir, "string", "memcmp.c"), + filepath.Join(libcDir, "string", "memcpy.c"), + filepath.Join(libcDir, "string", "memmove.c"), + filepath.Join(libcDir, "string", "memset.c"), + filepath.Join(libcDir, "string", "rindex.c"), + filepath.Join(libcDir, "string", "strcasecmp.c"), + filepath.Join(libcDir, "string", "strcat.c"), + filepath.Join(libcDir, "string", "strchr.c"), + filepath.Join(libcDir, "string", "strcmp.c"), + filepath.Join(libcDir, "string", "strcoll.c"), + filepath.Join(libcDir, "string", "strcpy.c"), + filepath.Join(libcDir, "string", "strcspn.c"), + filepath.Join(libcDir, "string", "strdup.c"), + filepath.Join(libcDir, "string", "strdup_r.c"), + filepath.Join(libcDir, "string", "strerror.c"), + filepath.Join(libcDir, "string", "strerror_r.c"), + filepath.Join(libcDir, "string", "strlcat.c"), + filepath.Join(libcDir, "string", "strlcpy.c"), + filepath.Join(libcDir, "string", "strlen.c"), + filepath.Join(libcDir, "string", "strlwr.c"), + filepath.Join(libcDir, "string", "strncasecmp.c"), + filepath.Join(libcDir, "string", "strncat.c"), + filepath.Join(libcDir, "string", "strncmp.c"), + filepath.Join(libcDir, "string", "strncpy.c"), + filepath.Join(libcDir, "string", "strnlen.c"), + filepath.Join(libcDir, "string", "strnstr.c"), + filepath.Join(libcDir, "string", "strpbrk.c"), + filepath.Join(libcDir, "string", "strrchr.c"), + filepath.Join(libcDir, "string", "strsep.c"), + filepath.Join(libcDir, "string", "strsignal.c"), + filepath.Join(libcDir, "string", "strspn.c"), + filepath.Join(libcDir, "string", "strtok.c"), + filepath.Join(libcDir, "string", "strtok_r.c"), + filepath.Join(libcDir, "string", "strupr.c"), + filepath.Join(libcDir, "string", "strxfrm.c"), + filepath.Join(libcDir, "string", "strstr.c"), + filepath.Join(libcDir, "string", "swab.c"), + filepath.Join(libcDir, "string", "timingsafe_bcmp.c"), + filepath.Join(libcDir, "string", "timingsafe_memcmp.c"), + filepath.Join(libcDir, "string", "u_strerr.c"), + filepath.Join(libcDir, "string", "wcscat.c"), + filepath.Join(libcDir, "string", "wcschr.c"), + filepath.Join(libcDir, "string", "wcscmp.c"), + filepath.Join(libcDir, "string", "wcscoll.c"), + filepath.Join(libcDir, "string", "wcscpy.c"), + filepath.Join(libcDir, "string", "wcscspn.c"), + filepath.Join(libcDir, "string", "wcslcat.c"), + filepath.Join(libcDir, "string", "wcslcpy.c"), + filepath.Join(libcDir, "string", "wcslen.c"), + filepath.Join(libcDir, "string", "wcsncat.c"), + filepath.Join(libcDir, "string", "wcsncmp.c"), + filepath.Join(libcDir, "string", "wcsncpy.c"), + filepath.Join(libcDir, "string", "wcsnlen.c"), + filepath.Join(libcDir, "string", "wcspbrk.c"), + filepath.Join(libcDir, "string", "wcsrchr.c"), + filepath.Join(libcDir, "string", "wcsspn.c"), + filepath.Join(libcDir, "string", "wcsstr.c"), + filepath.Join(libcDir, "string", "wcstok.c"), + filepath.Join(libcDir, "string", "wcswidth.c"), + filepath.Join(libcDir, "string", "wcsxfrm.c"), + filepath.Join(libcDir, "string", "wcwidth.c"), + filepath.Join(libcDir, "string", "wmemchr.c"), + filepath.Join(libcDir, "string", "wmemcmp.c"), + filepath.Join(libcDir, "string", "wmemcpy.c"), + filepath.Join(libcDir, "string", "wmemmove.c"), + filepath.Join(libcDir, "string", "wmemset.c"), + filepath.Join(libcDir, "string", "xpg_strerror_r.c"), + filepath.Join(libcDir, "string", "bcmp.c"), + filepath.Join(libcDir, "string", "memccpy.c"), + filepath.Join(libcDir, "string", "mempcpy.c"), + filepath.Join(libcDir, "string", "stpcpy.c"), + filepath.Join(libcDir, "string", "stpncpy.c"), + filepath.Join(libcDir, "string", "strndup.c"), + filepath.Join(libcDir, "string", "strcasestr.c"), + filepath.Join(libcDir, "string", "strchrnul.c"), + filepath.Join(libcDir, "string", "strndup_r.c"), + filepath.Join(libcDir, "string", "wcpcpy.c"), + filepath.Join(libcDir, "string", "wcpncpy.c"), + filepath.Join(libcDir, "string", "wcsdup.c"), + filepath.Join(libcDir, "string", "gnu_basename.c"), + filepath.Join(libcDir, "string", "memmem.c"), + filepath.Join(libcDir, "string", "memrchr.c"), + filepath.Join(libcDir, "string", "rawmemchr.c"), + filepath.Join(libcDir, "string", "strcasecmp_l.c"), + filepath.Join(libcDir, "string", "strcoll_l.c"), + filepath.Join(libcDir, "string", "strncasecmp_l.c"), + filepath.Join(libcDir, "string", "strverscmp.c"), + filepath.Join(libcDir, "string", "strxfrm_l.c"), + filepath.Join(libcDir, "string", "wcscasecmp.c"), + filepath.Join(libcDir, "string", "wcscasecmp_l.c"), + filepath.Join(libcDir, "string", "wcscoll_l.c"), + filepath.Join(libcDir, "string", "wcsncasecmp.c"), + filepath.Join(libcDir, "string", "wcsncasecmp_l.c"), + filepath.Join(libcDir, "string", "wcsxfrm_l.c"), + filepath.Join(libcDir, "string", "wmempcpy.c"), + filepath.Join(libcDir, "signal", "psignal.c"), + filepath.Join(libcDir, "signal", "raise.c"), + filepath.Join(libcDir, "signal", "signal.c"), + filepath.Join(libcDir, "signal", "sig2str.c"), + filepath.Join(libcDir, "time", "asctime.c"), + filepath.Join(libcDir, "time", "asctime_r.c"), + filepath.Join(libcDir, "time", "clock.c"), + filepath.Join(libcDir, "time", "ctime.c"), + filepath.Join(libcDir, "time", "ctime_r.c"), + filepath.Join(libcDir, "time", "difftime.c"), + filepath.Join(libcDir, "time", "gettzinfo.c"), + filepath.Join(libcDir, "time", "gmtime.c"), + filepath.Join(libcDir, "time", "gmtime_r.c"), + filepath.Join(libcDir, "time", "lcltime.c"), + filepath.Join(libcDir, "time", "lcltime_r.c"), + filepath.Join(libcDir, "time", "mktime.c"), + filepath.Join(libcDir, "time", "month_lengths.c"), + filepath.Join(libcDir, "time", "strftime.c"), + filepath.Join(libcDir, "time", "strptime.c"), + filepath.Join(libcDir, "time", "time.c"), + filepath.Join(libcDir, "time", "tzcalc_limits.c"), + filepath.Join(libcDir, "time", "tzlock.c"), + filepath.Join(libcDir, "time", "tzset.c"), + filepath.Join(libcDir, "time", "tzset_r.c"), + filepath.Join(libcDir, "time", "tzvars.c"), + filepath.Join(libcDir, "time", "wcsftime.c"), + filepath.Join(libcDir, "locale", "locale.c"), + filepath.Join(libcDir, "locale", "localeconv.c"), + filepath.Join(libcDir, "locale", "duplocale.c"), + filepath.Join(libcDir, "locale", "freelocale.c"), + filepath.Join(libcDir, "locale", "lctype.c"), + filepath.Join(libcDir, "locale", "lmessages.c"), + filepath.Join(libcDir, "locale", "lnumeric.c"), + filepath.Join(libcDir, "locale", "lmonetary.c"), + filepath.Join(libcDir, "locale", "newlocale.c"), + filepath.Join(libcDir, "locale", "nl_langinfo.c"), + filepath.Join(libcDir, "locale", "timelocal.c"), + filepath.Join(libcDir, "locale", "uselocale.c"), + filepath.Join(libcDir, "reent", "closer.c"), + filepath.Join(libcDir, "reent", "reent.c"), + filepath.Join(libcDir, "reent", "impure.c"), + filepath.Join(libcDir, "reent", "fcntlr.c"), + filepath.Join(libcDir, "reent", "fstatr.c"), + filepath.Join(libcDir, "reent", "getentropyr.c"), + filepath.Join(libcDir, "reent", "getreent.c"), + filepath.Join(libcDir, "reent", "gettimeofdayr.c"), + filepath.Join(libcDir, "reent", "isattyr.c"), + filepath.Join(libcDir, "reent", "linkr.c"), + filepath.Join(libcDir, "reent", "lseekr.c"), + filepath.Join(libcDir, "reent", "mkdirr.c"), + filepath.Join(libcDir, "reent", "openr.c"), + filepath.Join(libcDir, "reent", "readr.c"), + filepath.Join(libcDir, "reent", "renamer.c"), + filepath.Join(libcDir, "reent", "signalr.c"), + filepath.Join(libcDir, "reent", "signgam.c"), + filepath.Join(libcDir, "reent", "sbrkr.c"), + filepath.Join(libcDir, "reent", "statr.c"), + filepath.Join(libcDir, "reent", "timesr.c"), + filepath.Join(libcDir, "reent", "unlinkr.c"), + filepath.Join(libcDir, "reent", "writer.c"), + filepath.Join(libcDir, "reent", "execr.c"), + filepath.Join(libcDir, "errno", "errno.c"), + filepath.Join(libcDir, "misc", "__dprintf.c"), + filepath.Join(libcDir, "misc", "unctrl.c"), + filepath.Join(libcDir, "misc", "ffs.c"), + filepath.Join(libcDir, "misc", "init.c"), + filepath.Join(libcDir, "misc", "fini.c"), + filepath.Join(libcDir, "misc", "lock.c"), + filepath.Join(libcDir, "posix", "closedir.c"), + filepath.Join(libcDir, "posix", "collate.c"), + filepath.Join(libcDir, "posix", "collcmp.c"), + filepath.Join(libcDir, "posix", "creat.c"), + filepath.Join(libcDir, "posix", "dirfd.c"), + // filepath.Join(libcDir, "posix", "fnmatch.c"), + filepath.Join(libcDir, "posix", "glob.c"), + filepath.Join(libcDir, "posix", "_isatty.c"), + filepath.Join(libcDir, "posix", "isatty.c"), + filepath.Join(libcDir, "posix", "opendir.c"), + filepath.Join(libcDir, "posix", "readdir.c"), + filepath.Join(libcDir, "posix", "readdir_r.c"), + filepath.Join(libcDir, "posix", "regcomp.c"), + filepath.Join(libcDir, "posix", "regerror.c"), + filepath.Join(libcDir, "posix", "regexec.c"), + filepath.Join(libcDir, "posix", "regfree.c"), + filepath.Join(libcDir, "posix", "rewinddir.c"), + filepath.Join(libcDir, "posix", "sleep.c"), + filepath.Join(libcDir, "posix", "usleep.c"), + filepath.Join(libcDir, "posix", "telldir.c"), + filepath.Join(libcDir, "posix", "ftw.c"), + filepath.Join(libcDir, "posix", "nftw.c"), + filepath.Join(libcDir, "posix", "scandir.c"), + filepath.Join(libcDir, "posix", "seekdir.c"), + filepath.Join(libcDir, "posix", "execl.c"), + filepath.Join(libcDir, "posix", "execle.c"), + filepath.Join(libcDir, "posix", "execlp.c"), + filepath.Join(libcDir, "posix", "execv.c"), + filepath.Join(libcDir, "posix", "execve.c"), + filepath.Join(libcDir, "posix", "execvp.c"), + filepath.Join(libcDir, "posix", "wordexp.c"), + filepath.Join(libcDir, "posix", "wordfree.c"), + filepath.Join(libcDir, "posix", "popen.c"), + filepath.Join(libcDir, "posix", "posix_spawn.c"), + filepath.Join(libcDir, "syscalls", "sysclose.c"), + filepath.Join(libcDir, "syscalls", "sysfcntl.c"), + filepath.Join(libcDir, "syscalls", "sysfstat.c"), + filepath.Join(libcDir, "syscalls", "sysgetentropy.c"), + filepath.Join(libcDir, "syscalls", "sysgetpid.c"), + filepath.Join(libcDir, "syscalls", "sysgettod.c"), + filepath.Join(libcDir, "syscalls", "sysisatty.c"), + filepath.Join(libcDir, "syscalls", "syskill.c"), + filepath.Join(libcDir, "syscalls", "syslink.c"), + filepath.Join(libcDir, "syscalls", "syslseek.c"), + filepath.Join(libcDir, "syscalls", "sysopen.c"), + filepath.Join(libcDir, "syscalls", "sysread.c"), + filepath.Join(libcDir, "syscalls", "syssbrk.c"), + filepath.Join(libcDir, "syscalls", "sysstat.c"), + filepath.Join(libcDir, "syscalls", "systimes.c"), + filepath.Join(libcDir, "syscalls", "sysunlink.c"), + filepath.Join(libcDir, "syscalls", "syswrite.c"), + filepath.Join(libcDir, "syscalls", "sysexecve.c"), + filepath.Join(libcDir, "syscalls", "sysfork.c"), + filepath.Join(libcDir, "syscalls", "syswait.c"), + filepath.Join(libcDir, "iconv", "ces", "utf-8.c"), + filepath.Join(libcDir, "iconv", "ces", "utf-16.c"), + filepath.Join(libcDir, "iconv", "ces", "ucs-2.c"), + filepath.Join(libcDir, "iconv", "ces", "us-ascii.c"), + filepath.Join(libcDir, "iconv", "ces", "ucs-4.c"), + filepath.Join(libcDir, "iconv", "ces", "ucs-2-internal.c"), + filepath.Join(libcDir, "iconv", "ces", "ucs-4-internal.c"), + filepath.Join(libcDir, "iconv", "ces", "cesbi.c"), + filepath.Join(libcDir, "iconv", "ces", "table.c"), + filepath.Join(libcDir, "iconv", "ces", "table-pcs.c"), + filepath.Join(libcDir, "iconv", "ces", "euc.c"), + filepath.Join(libcDir, "iconv", "ccs", "ccsbi.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_10.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_13.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_14.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_15.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_1.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_2.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_3.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_4.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_5.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_6.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_7.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_8.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_9.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_8859_11.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1250.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1252.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1254.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1256.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1258.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1251.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1253.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1255.c"), + filepath.Join(libcDir, "iconv", "ccs", "win_1257.c"), + filepath.Join(libcDir, "iconv", "ccs", "koi8_r.c"), + filepath.Join(libcDir, "iconv", "ccs", "koi8_u.c"), + filepath.Join(libcDir, "iconv", "ccs", "koi8_ru.c"), + filepath.Join(libcDir, "iconv", "ccs", "koi8_uni.c"), + filepath.Join(libcDir, "iconv", "ccs", "iso_ir_111.c"), + filepath.Join(libcDir, "iconv", "ccs", "big5.c"), + filepath.Join(libcDir, "iconv", "ccs", "cp775.c"), + filepath.Join(libcDir, "iconv", "ccs", "cp850.c"), + filepath.Join(libcDir, "iconv", "ccs", "cp852.c"), + filepath.Join(libcDir, "iconv", "ccs", "cp855.c"), + filepath.Join(libcDir, "iconv", "ccs", "cp866.c"), + filepath.Join(libcDir, "iconv", "ccs", "jis_x0212_1990.c"), + filepath.Join(libcDir, "iconv", "ccs", "jis_x0201_1976.c"), + filepath.Join(libcDir, "iconv", "ccs", "jis_x0208_1990.c"), + filepath.Join(libcDir, "iconv", "ccs", "ksx1001.c"), + filepath.Join(libcDir, "iconv", "ccs", "cns11643_plane1.c"), + filepath.Join(libcDir, "iconv", "ccs", "cns11643_plane2.c"), + filepath.Join(libcDir, "iconv", "ccs", "cns11643_plane14.c"), + filepath.Join(libcDir, "iconv", "lib", "aliasesi.c"), + filepath.Join(libcDir, "iconv", "lib", "ucsconv.c"), + filepath.Join(libcDir, "iconv", "lib", "nullconv.c"), + filepath.Join(libcDir, "iconv", "lib", "iconv.c"), + filepath.Join(libcDir, "iconv", "lib", "aliasesbi.c"), + filepath.Join(libcDir, "iconv", "lib", "iconvnls.c"), + filepath.Join(libcDir, "ssp", "chk_fail.c"), + filepath.Join(libcDir, "ssp", "stack_protector.c"), + filepath.Join(libcDir, "ssp", "memcpy_chk.c"), + filepath.Join(libcDir, "ssp", "memmove_chk.c"), + filepath.Join(libcDir, "ssp", "mempcpy_chk.c"), + filepath.Join(libcDir, "ssp", "memset_chk.c"), + filepath.Join(libcDir, "ssp", "stpcpy_chk.c"), + filepath.Join(libcDir, "ssp", "stpncpy_chk.c"), + filepath.Join(libcDir, "ssp", "strcat_chk.c"), + filepath.Join(libcDir, "ssp", "strcpy_chk.c"), + filepath.Join(libcDir, "ssp", "strncat_chk.c"), + filepath.Join(libcDir, "ssp", "strncpy_chk.c"), + filepath.Join(libcDir, "ssp", "gets_chk.c"), + filepath.Join(libcDir, "ssp", "snprintf_chk.c"), + filepath.Join(libcDir, "ssp", "sprintf_chk.c"), + filepath.Join(libcDir, "ssp", "vsnprintf_chk.c"), + filepath.Join(libcDir, "ssp", "vsprintf_chk.c"), + filepath.Join(libcDir, "machine", "riscv", "memmove.S"), + filepath.Join(libcDir, "machine", "riscv", "memmove-stub.c"), + filepath.Join(libcDir, "machine", "riscv", "memset.S"), + filepath.Join(libcDir, "machine", "riscv", "memcpy-asm.S"), + filepath.Join(libcDir, "machine", "riscv", "memcpy.c"), + filepath.Join(libcDir, "machine", "riscv", "strlen.c"), + filepath.Join(libcDir, "machine", "riscv", "strcpy.c"), + filepath.Join(libcDir, "machine", "riscv", "strcmp.S"), + filepath.Join(libcDir, "machine", "riscv", "setjmp.S"), + filepath.Join(libcDir, "machine", "riscv", "ieeefp.c"), + filepath.Join(libcDir, "machine", "riscv", "ffs.c"), + }, + CFlags: []string{ + "-DHAVE_CONFIG_H", + "-D_LIBC", + "-DHAVE_NANOSLEEP", + "-D__NO_SYSCALLS__", + "-D_NO_GLOB", + "-D_NO_EXECVE", + "-D_NO_GETLOGIN", + "-D_NO_GETPWENT", + "-D_NO_GETUT", + "-D_NO_GETPASS", + "-D_NO_SIGSET", + "-D_NO_WORDEXP", + "-D_NO_POPEN", + "-D_NO_POSIX_SPAWN", + "-DHAVE_FCNTL", + "-DHAVE_BLKSIZE", + "-DHAVE_OPENDIR", + "-DHAVE_RENAME", + "-DGETREENT_PROVIDED", + "-DSIGNAL_PROVIDED", + "-D__ESP__", + "-isystem" + filepath.Join(libcDir, "include"), + "-I" + filepath.Join(baseDir, "newlib"), + "-I" + libcDir, + "-I" + filepath.Join(libcDir, "riscv"), + "-I" + filepath.Join(baseDir, "libgloss"), + // TODO(MeteorsLiu): support riscv + "-idirafter" + filepath.Join(baseDir, "include"), + "-I" + filepath.Join(libcDir, "ssp"), + "-I" + filepath.Join(libcDir, "locale"), + "-I" + filepath.Join(libcDir, "errno"), + "-I" + filepath.Join(libcDir, "syscalls"), + "-I" + filepath.Join(libcDir, "iconv", "lib"), + "-I" + filepath.Join(libcDir, "argz"), + "-I" + filepath.Join(libcDir, "stdio"), + "-I" + filepath.Join(libcDir, "iconv", "ces"), + "-I" + filepath.Join(libcDir, "iconv", "ccs"), + "-I" + filepath.Join(libcDir, "ctype"), + "-I" + filepath.Join(libcDir, "signal"), + "-I" + filepath.Join(libcDir, "time"), + "-I" + filepath.Join(libcDir, "reent"), + "-I" + filepath.Join(libcDir, "machine", "riscv", "include"), + "-I" + filepath.Join(libcDir, "string"), + "-I" + filepath.Join(libcDir, "iconv", "ces"), + "-I" + filepath.Join(libcDir, "search"), + "-I" + filepath.Join(libcDir, "misc"), + "-I" + filepath.Join(libcDir, "posix"), + "-I" + filepath.Join(libcDir, "stdlib"), + }, + LDFlags: []string{"-nostdlib"}, + CCFlags: []string{ + "-Oz", + "-fno-builtin", + "-ffreestanding", + "-Wno-implicit-function-declaration", + "-Wno-int-conversion", + "-Wno-unused-command-line-argument", + }, + }, + }, + ArchiveSrcDir: "newlib-0.2.0", + } +} + +func getNewlibESP32ConfigXtensa(baseDir, target string) *compile.CompileConfig { libcDir := filepath.Join(baseDir, "newlib", "libc") return &compile.CompileConfig{ @@ -988,3 +2049,12 @@ func GetNewlibESP32Config(baseDir, target string) *compile.CompileConfig { ArchiveSrcDir: "newlib-0.1.0", } } + +// getNewlibESP32Config returns configuration for newlib esp32 +func GetNewlibESP32Config(baseDir, target, mcpu string) *compile.CompileConfig { + if strings.Contains(target, "riscv32") { + fmt.Println(target) + return getNewlibESP32ConfigRISCV(baseDir, target) + } + return getNewlibESP32ConfigXtensa(baseDir, target) +} diff --git a/internal/crosscompile/compile/rtlib/compiler_rt.go b/internal/crosscompile/compile/rtlib/compiler_rt.go index d8926918..6446e9b9 100644 --- a/internal/crosscompile/compile/rtlib/compiler_rt.go +++ b/internal/crosscompile/compile/rtlib/compiler_rt.go @@ -3,10 +3,33 @@ package rtlib import ( "fmt" "path/filepath" + "strings" "github.com/goplus/llgo/internal/crosscompile/compile" ) +func platformSpecifiedFiles(builtinsDir, target string) []string { + switch { + case strings.Contains(target, "riscv32"): + return []string{ + filepath.Join(builtinsDir, "riscv", "mulsi3.S"), + filepath.Join(builtinsDir, "riscv", "fp_mode.c"), + filepath.Join(builtinsDir, "riscv", "save.S"), + filepath.Join(builtinsDir, "riscv", "restore.S"), + } + case target == "xtensa": + return []string{ + filepath.Join(builtinsDir, "xtensa", "ieee754_sqrtf.S"), + } + } + return nil +} + +func withPlatformSpecifiedFiles(baseDir, target string, files []string) []string { + builtinsDir := filepath.Join(baseDir, "lib", "builtins") + return append(files, platformSpecifiedFiles(builtinsDir, target)...) +} + func GetCompilerRTConfig(baseDir, target string) *compile.CompileConfig { return &compile.CompileConfig{ Url: "https://github.com/goplus/compiler-rt/archive/refs/tags/v0.1.0.tar.gz", @@ -14,8 +37,7 @@ func GetCompilerRTConfig(baseDir, target string) *compile.CompileConfig { Groups: []compile.CompileGroup{ { OutputFileName: fmt.Sprintf("libclang_builtins-%s.a", target), - Files: []string{ - filepath.Join(baseDir, "lib", "builtins", "xtensa/ieee754_sqrtf.S"), + Files: withPlatformSpecifiedFiles(baseDir, target, []string{ filepath.Join(baseDir, "lib", "builtins", "absvdi2.c"), filepath.Join(baseDir, "lib", "builtins", "absvsi2.c"), filepath.Join(baseDir, "lib", "builtins", "absvti2.c"), @@ -163,7 +185,8 @@ func GetCompilerRTConfig(baseDir, target string) *compile.CompileConfig { filepath.Join(baseDir, "lib", "builtins", "trunctfdf2.c"), filepath.Join(baseDir, "lib", "builtins", "trunctfhf2.c"), filepath.Join(baseDir, "lib", "builtins", "trunctfsf2.c"), - }, + filepath.Join(baseDir, "lib", "builtins", "atomic.c"), + }), CFlags: []string{ "-DNDEBUG", "-DVISIBILITY_HIDDEN", diff --git a/internal/crosscompile/crosscompile.go b/internal/crosscompile/crosscompile.go index 13e69de3..3c8285ca 100644 --- a/internal/crosscompile/crosscompile.go +++ b/internal/crosscompile/crosscompile.go @@ -317,12 +317,12 @@ func use(goos, goarch string, wasiThreads bool) (export Export, err error) { export.CCFLAGS = append( export.CCFLAGS, "-fdata-sections", - "-ffunction-sections", + // "-ffunction-sections", ) export.LDFLAGS = append( export.LDFLAGS, "-fdata-sections", - "-ffunction-sections", + // "-ffunction-sections", "-Xlinker", "--gc-sections", "-lm", @@ -612,7 +612,7 @@ func useTarget(targetName string) (export Export, err error) { baseDir := filepath.Join(cacheRoot(), "crosscompile") outputDir := filepath.Join(baseDir, config.Libc) - compileConfig, err = getLibcCompileConfigByName(baseDir, config.Libc, config.LLVMTarget) + compileConfig, err = getLibcCompileConfigByName(baseDir, config.Libc, config.LLVMTarget, config.CPU) if err != nil { return } diff --git a/internal/crosscompile/libc.go b/internal/crosscompile/libc.go index f3d27f4d..fdbb7307 100644 --- a/internal/crosscompile/libc.go +++ b/internal/crosscompile/libc.go @@ -11,7 +11,7 @@ import ( // GetCompileConfigByName retrieves libc compilation configuration by name // Returns compilation file lists and corresponding cflags -func getLibcCompileConfigByName(baseDir, libcName, target string) (*compile.CompileConfig, error) { +func getLibcCompileConfigByName(baseDir, libcName, target, mcpu string) (*compile.CompileConfig, error) { if libcName == "" { return nil, fmt.Errorf("libc name cannot be empty") } @@ -21,7 +21,7 @@ func getLibcCompileConfigByName(baseDir, libcName, target string) (*compile.Comp case "picolibc": return libc.GetPicolibcConfig(libcDir, target), nil case "newlib-esp32": - return libc.GetNewlibESP32Config(libcDir, target), nil + return libc.GetNewlibESP32Config(libcDir, target, mcpu), nil default: return nil, fmt.Errorf("unsupported libc: %s", libcName) } diff --git a/targets/esp32-riscv.app.elf.ld b/targets/esp32-riscv.app.elf.ld new file mode 100644 index 00000000..7f6ab8f6 --- /dev/null +++ b/targets/esp32-riscv.app.elf.ld @@ -0,0 +1,195 @@ +__stack = ORIGIN(dram_seg) + LENGTH(dram_seg); +__MIN_STACK_SIZE = 0x1000; +_stack_top = __stack; + +/* Default entry point */ +ENTRY(_start) +SECTIONS +{ + .text : + { + _iram_start = .; + + /* Place the _start function at the beginning of IRAM. + * Just in case some versions of QEMU ignore the entry address when loading the ELF file. */ + KEEP(*(.text._start)) + + KEEP (*(SORT_NONE(.init))) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + KEEP (*(SORT_NONE(.fini))) + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + } > iram_seg + + .rodata : + { + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) + . = ALIGN(4); + __cpu_frequency = .; + LONG(CPU_FREQUENCY); + __uart0_clkdiv_reg = .; + LONG(UART0_CLKDIV_REG); + __uart0_clkdiv_val = .; + LONG(UART0_CLKDIV_VAL); + __uart0_tx_addr = .; + LONG(UART0_TX_ADDR); + __uart0_status = .; + LONG(UART0_STATUS); + } > iram_seg + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } > iram_seg + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } > iram_seg + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } > iram_seg + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } > iram_seg + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + _iram_end = .; + } > iram_seg + + /** + * This section is required to skip .iram0.text area because iram0_0_seg and + * dram0_0_seg reflect the same address space on different buses. + */ + .dram0.dummy (NOLOAD): + { + /* Add a gap only in case we have separate iram/dram regions */ + . += ORIGIN(iram_seg) == ORIGIN(dram_seg) ? 0 : _iram_end - _iram_start; + } > dram_seg + + .data : + { + _data_start = .; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } > dram_seg + .data1 : { *(.data1) } > dram_seg + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : + { + PROVIDE(__global_pointer$ = . + 0x800); + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + _edata = .; PROVIDE (edata = .); + . = .; + } > dram_seg + + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } > dram_seg + .eh_frame : { KEEP (*(.eh_frame)) *(.eh_frame.*) } > dram_seg + + .bss (NOLOAD) : + { + __bss_start = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we do not + pad the .data section. */ + . = ALIGN(. != 0 ? 32 / 8 : 1); + + . = ALIGN(32 / 8); + . = ALIGN(32 / 8); + _end = .; PROVIDE (end = .); + } > dram_seg + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(_end <= __stack - __MIN_STACK_SIZE, "region DRAM overflowed by .data and .bss sections") + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .debug_addr 0 : { *(.debug_addr) } + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} diff --git a/targets/esp32c2.memory.ld b/targets/esp32c2.memory.ld new file mode 100644 index 00000000..0e5ce025 --- /dev/null +++ b/targets/esp32c2.memory.ld @@ -0,0 +1,33 @@ +# See "System Structure and Address Mapping" figure at +# https://www.espressif.com/sites/default/files/documentation/esp8684_technical_reference_manual_en.pdf + +ICACHE_SIZE = 0x4000; +# Skip possible ICACHE area +IRAM_START_ADDRESS = 0x4037C000 + ICACHE_SIZE; +IRAM_LEN = 0x40000 - ICACHE_SIZE; + +DRAM_START_ADDRESS = 0x3FCA0000; +DRAM_LEN = 0x40000; + +# Docs say that: +# The default console baud rate on ESP32-C2: +# - 115200 when a 40 MHz XTAL is used +# - 74880 when a 26 MHz XTAL is used +# +# It seems something wrong with CPU_FREQUENCY and UART0_BAUD definitions, +# but UART0_CLKDIV_VAL == 173 gives expected baud rate 74880 on 26 MHz XTAL. +CPU_FREQUENCY = 20000000; +UART0_BAUD = 115200; + +UART0_CLKDIV_REG = 0x60000014; +UART0_CLKDIV_VAL = CPU_FREQUENCY / UART0_BAUD; +UART0_STATUS = 0x6000001C; +UART0_TX_ADDR = 0x60000000; + +MEMORY +{ + iram_seg (RX) : org = IRAM_START_ADDRESS, len = IRAM_LEN + dram_seg (RW) : org = DRAM_START_ADDRESS, len = DRAM_LEN +} + +INCLUDE "targets/esp32-riscv.app.elf.ld"; diff --git a/targets/esp32c3.json b/targets/esp32c3.json index b9586bef..01f2211a 100644 --- a/targets/esp32c3.json +++ b/targets/esp32c3.json @@ -1,23 +1,31 @@ { - "inherits": ["riscv32"], + "inherits": [ + "riscv32" + ], "features": "+32bit,+c,+m,+zmmul,-a,-b,-d,-e,-experimental-smmpm,-experimental-smnpm,-experimental-ssnpm,-experimental-sspm,-experimental-ssqosid,-experimental-supm,-experimental-zacas,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-f,-h,-relax,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smepmp,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b", - "build-tags": ["esp32c3", "esp"], + "build-tags": [ + "esp32c3", + "esp" + ], "serial": "usb", "rtlib": "compiler-rt", - "libc": "picolibc", + "libc": "newlib-esp32", "cflags": [ "-march=rv32imc" ], - "linkerscript": "targets/esp32c3.ld", - "extra-files": [ - "targets/device/esp/esp32c3.S" - ], + "linkerscript": "targets/esp32c3.memory.ld", + "extra-files": [], "binary-format": "esp32c3", "flash-command": "esptool.py --chip=esp32c3 --port {port} write_flash 0x0 {bin}", - "serial-port": ["303a:1001"], + "serial-port": [ + "303a:1001" + ], "openocd-interface": "esp_usb_jtag", "openocd-target": "esp32c3", - "openocd-commands": ["gdb_memory_map disable"], - "gdb": ["riscv32-esp-elf-gdb"] + "openocd-commands": [ + "gdb_memory_map disable" + ], + "gdb": [ + "riscv32-esp-elf-gdb" + ] } - diff --git a/targets/esp32c3.memory.ld b/targets/esp32c3.memory.ld new file mode 100644 index 00000000..91f6803c --- /dev/null +++ b/targets/esp32c3.memory.ld @@ -0,0 +1,26 @@ +# See "System Structure and Address Mapping" figure at +# https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf + +ICACHE_SIZE = 0x4000; +# Skip possible ICACHE area +IRAM_START_ADDRESS = 0x4037C000 + ICACHE_SIZE; +IRAM_LEN = 0x64000 - ICACHE_SIZE; + +DRAM_START_ADDRESS = 0x3FC80000; +DRAM_LEN = 0x40000; + +CPU_FREQUENCY = 20000000; +UART0_BAUD = 115200; + +UART0_CLKDIV_REG = 0x60000014; +UART0_CLKDIV_VAL = CPU_FREQUENCY / UART0_BAUD; +UART0_STATUS = 0x6000001C; +UART0_TX_ADDR = 0x60000000; + +MEMORY +{ + iram_seg (RX) : org = IRAM_START_ADDRESS, len = IRAM_LEN + dram_seg (RW) : org = DRAM_START_ADDRESS, len = DRAM_LEN +} + +INCLUDE "targets/esp32-riscv.app.elf.ld"; diff --git a/targets/esp32c5.memory.ld b/targets/esp32c5.memory.ld new file mode 100644 index 00000000..75a00839 --- /dev/null +++ b/targets/esp32c5.memory.ld @@ -0,0 +1,22 @@ +# Memory layout obtained from IDF linker files. + +SRAM_START_ADDRESS = 0x40800000; +SRAM_LEN = 0x60000; + +CPU_FREQUENCY = 40000000; +UART0_BAUD = 115200; + +UART0_CLKDIV_REG = 0x60000014; +UART0_CLKDIV_VAL = CPU_FREQUENCY / UART0_BAUD; +UART0_STATUS = 0x6000001C; +UART0_TX_ADDR = 0x60000000; + +MEMORY +{ + sram_seg (RWX) : org = SRAM_START_ADDRESS, len = SRAM_LEN +} + +REGION_ALIAS("iram_seg", sram_seg); +REGION_ALIAS("dram_seg", sram_seg); + +INCLUDE "targets/esp32-riscv.app.elf.ld"; diff --git a/targets/esp32c6.memory.ld b/targets/esp32c6.memory.ld new file mode 100644 index 00000000..98d10b5f --- /dev/null +++ b/targets/esp32c6.memory.ld @@ -0,0 +1,22 @@ +# See "System Structure and Address Mapping" figure at +# https://www.espressif.com/sites/default/files/documentation/esp32-c6_technical_reference_manual_en.pdf + +SRAM_START_ADDRESS = 0x40800000; +SRAM_LEN = 0x80000; + +CPU_FREQUENCY = 40000000; +UART0_BAUD = 115200; + +UART0_CLKDIV_REG = 0x60000014; +UART0_CLKDIV_VAL = CPU_FREQUENCY / UART0_BAUD; +UART0_STATUS = 0x6000001C; +UART0_TX_ADDR = 0x60000000; + +MEMORY +{ + sram_seg (RWX) : org = SRAM_START_ADDRESS, len = SRAM_LEN +} + +REGION_ALIAS("iram_seg", sram_seg); +REGION_ALIAS("dram_seg", sram_seg); +INCLUDE "targets/esp32-riscv.app.elf.ld"; diff --git a/targets/esp32c61.memory.ld b/targets/esp32c61.memory.ld new file mode 100644 index 00000000..34cd39ff --- /dev/null +++ b/targets/esp32c61.memory.ld @@ -0,0 +1,21 @@ +# Memory layout obtained from IDF linker files. + +SRAM_START_ADDRESS = 0x40800000; +SRAM_LEN = 0x50000; + +CPU_FREQUENCY = 40000000; +UART0_BAUD = 115200; + +UART0_CLKDIV_REG = 0x60000014; +UART0_CLKDIV_VAL = CPU_FREQUENCY / UART0_BAUD; +UART0_STATUS = 0x6000001C; +UART0_TX_ADDR = 0x60000000; + +MEMORY +{ + sram_seg (RWX) : org = SRAM_START_ADDRESS, len = SRAM_LEN +} + +REGION_ALIAS("iram_seg", sram_seg); +REGION_ALIAS("dram_seg", sram_seg); +INCLUDE "targets/esp32-riscv.app.elf.ld"; diff --git a/targets/esp32h2.memory.ld b/targets/esp32h2.memory.ld new file mode 100644 index 00000000..c55526bb --- /dev/null +++ b/targets/esp32h2.memory.ld @@ -0,0 +1,22 @@ +# See "System Structure and Address Mapping" figure at +# https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf + +SRAM_START_ADDRESS = 0x40800000; +SRAM_LEN = 0x50000; + +CPU_FREQUENCY = 40000000; +UART0_BAUD = 115200; + +UART0_CLKDIV_REG = 0x60000014; +UART0_CLKDIV_VAL = CPU_FREQUENCY / UART0_BAUD; +UART0_STATUS = 0x6000001C; +UART0_TX_ADDR = 0x60000000; + +MEMORY +{ + sram_seg (RWX) : org = SRAM_START_ADDRESS, len = SRAM_LEN +} + +REGION_ALIAS("iram_seg", sram_seg); +REGION_ALIAS("dram_seg", sram_seg); +INCLUDE "targets/esp32-riscv.app.elf.ld"; diff --git a/targets/esp32h21.memory.ld b/targets/esp32h21.memory.ld new file mode 100644 index 00000000..34cd39ff --- /dev/null +++ b/targets/esp32h21.memory.ld @@ -0,0 +1,21 @@ +# Memory layout obtained from IDF linker files. + +SRAM_START_ADDRESS = 0x40800000; +SRAM_LEN = 0x50000; + +CPU_FREQUENCY = 40000000; +UART0_BAUD = 115200; + +UART0_CLKDIV_REG = 0x60000014; +UART0_CLKDIV_VAL = CPU_FREQUENCY / UART0_BAUD; +UART0_STATUS = 0x6000001C; +UART0_TX_ADDR = 0x60000000; + +MEMORY +{ + sram_seg (RWX) : org = SRAM_START_ADDRESS, len = SRAM_LEN +} + +REGION_ALIAS("iram_seg", sram_seg); +REGION_ALIAS("dram_seg", sram_seg); +INCLUDE "targets/esp32-riscv.app.elf.ld"; diff --git a/targets/esp32p4.memory.ld b/targets/esp32p4.memory.ld new file mode 100644 index 00000000..3fe96558 --- /dev/null +++ b/targets/esp32p4.memory.ld @@ -0,0 +1,23 @@ +# Memory layout obtained from IDF linker files. + +L2_CACHE_SIZE = 0x40000; + +SRAM_START_ADDRESS = 0x4FF00000; +SRAM_LEN = 0xC0000 - L2_CACHE_SIZE; + +CPU_FREQUENCY = 40000000; +UART0_BAUD = 115200; + +UART0_CLKDIV_REG = 0x500CA014; +UART0_CLKDIV_VAL = CPU_FREQUENCY / UART0_BAUD; +UART0_STATUS = 0x500CA01C; +UART0_TX_ADDR = 0x500CA000; + +MEMORY +{ + sram_seg (RWX) : org = SRAM_START_ADDRESS, len = SRAM_LEN +} + +REGION_ALIAS("iram_seg", sram_seg); +REGION_ALIAS("dram_seg", sram_seg); +INCLUDE "targets/esp32-riscv.app.elf.ld"; diff --git a/targets/xtensa.json b/targets/xtensa.json index 893a3eb7..42424d92 100644 --- a/targets/xtensa.json +++ b/targets/xtensa.json @@ -2,15 +2,23 @@ "llvm-target": "xtensa", "goos": "linux", "goarch": "arm", - "build-tags": ["xtensa", "baremetal", "linux", "arm"], + "build-tags": [ + "xtensa", + "baremetal", + "linux", + "arm" + ], "gc": "conservative", "scheduler": "none", "cflags": [ "-Werror", "-fshort-enums", "-Wno-macro-redefined", - "-fno-exceptions", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables", - "-ffunction-sections", "-fdata-sections" + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-asynchronous-unwind-tables", + "-ffunction-sections", + "-fdata-sections" ], "ldflags": [ "--gc-sections" From 012a5d7d690cd568420a228d309986d461d6e38f Mon Sep 17 00:00:00 2001 From: Haolan Date: Mon, 1 Sep 2025 14:49:37 +0800 Subject: [PATCH 31/46] fix: remove unused file --- targets/esp32c3.ld | 2238 -------------------------------------------- 1 file changed, 2238 deletions(-) delete mode 100644 targets/esp32c3.ld diff --git a/targets/esp32c3.ld b/targets/esp32c3.ld deleted file mode 100644 index 81a8c4f2..00000000 --- a/targets/esp32c3.ld +++ /dev/null @@ -1,2238 +0,0 @@ -/* Linker script for the ESP32-C3 - * - * The ESP32-C3 has a rather funky memory layout, more like its Xtensa - * predecessors than like other RISC-V chips: - * - It has 384kB of regular RAM. This RAM can be used both as data RAM and - * instruction RAM, but needs to be accessed via a different address space - * (DRAM/IRAM). - * - It has another 16kB of RAM, that could be used as regular RAM but is - * normally used by the flash cache. - * - It has 8MB of address space for the DROM and IROM, but for some reason - * this address space is shared. So it isn't possible to map all DROM at - * 0x3C000000 and all DRAM at 0x42000000: they would overlap. - * - The MMU works in pages of 64kB, which means the bottom 16 bits of the - * address in flash and the address in DROM/IROM need to match. - * - Memory in DRAM and IRAM is loaded at reset by the ROM bootloader. - * Luckily, this doesn't have significant alignment requirements. - * - * This linker script has been written to carefully work around (or with) these - * limitations: - * - It adds dummy sections so that the bottom 16 bits of the virtual address - * and the physical address (in the generated firmware image) match. - * - It also offsets sections that share an address space using those same - * dummy sections. - * - It sorts the sections by load address, to avoid surprises as esptool.py - * also does it. - * This way, it's possible to create a very small firmware image that still - * conforms to the expectations of esptool.py and the ROM bootloader. - */ - -MEMORY -{ - /* Note: DRAM and IRAM below are actually in the same 384K address space. */ - DRAM (rw) : ORIGIN = 0x3FC80000, LENGTH = 384K /* Internal SRAM 1 (data bus) */ - IRAM (x) : ORIGIN = 0x40380000, LENGTH = 384K /* Internal SRAM 1 (instruction bus) */ - - /* Note: DROM and IROM below are actually in the same 8M address space. */ - DROM (r) : ORIGIN = 0x3C000000, LENGTH = 8M /* Data bus (read-only) */ - IROM (rx) : ORIGIN = 0x42000000, LENGTH = 8M /* Instruction bus */ -} - -/* The entry point. It is set in the image flashed to the chip, so must be - * defined. - */ -ENTRY(call_start_cpu0) - -SECTIONS -{ - /* Dummy section to make sure the .rodata section starts exactly behind the - * image header. - */ - .rodata_dummy (NOLOAD): ALIGN(4) - { - . += 0x18; /* image header at start of flash: esp_image_header_t */ - . += 0x8; /* DROM segment header (8 bytes) */ - } > DROM - - /* Constant global variables, stored in DROM. - */ - .rodata : ALIGN(4) - { - *(.rodata*) - . = ALIGN (4); - } >DROM - - /* Put the stack at the bottom of DRAM, so that the application will - * crash on stack overflow instead of silently corrupting memory. - * See: http://blog.japaric.io/stack-overflow-protection/ - * TODO: this might not actually work because memory protection hasn't been set up. - */ - .stack (NOLOAD) : - { - . = ALIGN(16); - . += _stack_size; - _stack_top = .; - } >DRAM - - /* Global variables that are mutable and zero-initialized. - * These must be zeroed at startup (unlike data, which is loaded by the - * bootloader). - */ - .bss (NOLOAD) : ALIGN(4) - { - . = ALIGN (4); - _sbss = ABSOLUTE(.); - *(.sbss) - *(.bss .bss.*) - . = ALIGN (4); - _ebss = ABSOLUTE(.); - } >DRAM - - /* Mutable global variables. This data (in the DRAM segment) is initialized - * by the ROM bootloader. - */ - .data : ALIGN(4) - { - . = ALIGN (4); - _sdata = ABSOLUTE(.); - *(.sdata) - *(.data .data.*) - *(.dram*) - . = ALIGN (4); - _edata = ABSOLUTE(.); - } >DRAM - - /* Dummy section to make sure the .init section (in the IRAM segment) is just - * behind the DRAM segment. For IRAM and DRAM, we luckily don't have to - * worry about 64kB pages or image headers as they're loaded in RAM by the - * bootloader (not mapped from flash). - */ - .iram_dummy (NOLOAD): ALIGN(4) - { - . += SIZEOF(.stack); - . += SIZEOF(.bss); - . += SIZEOF(.data); - } > IRAM - - /* IRAM segment. This contains some functions that always need to be loaded - * in IRAM, and contains initialization code. - * The initialization code is later reclaimed for the heap, so no RAM is - * wasted. - */ - .iram : ALIGN(4) - { - *(.iram*) - *(.wifislprxiram*) - *(.wifiextrairam*) - *(.wifi0iram*) - *(.wifislpiram*) - *(.wifirxiram*) - __init_start = .; - *(.init) - __init_end = .; - } >IRAM - - /* Dummy section to put the IROM segment exactly behind the IRAM segment. - * This has to follow the app image format exactly. - */ - .text_dummy (NOLOAD): ALIGN(4) - { - /* Note: DRAM and DROM are not always present so the header should only - * be inserted if it actually exists. - */ - . += 0x18; /* esp_image_header_t */ - . += SIZEOF(.rodata) + ((SIZEOF(.rodata) != 0) ? 0x8 : 0); /* DROM segment (optional) */ - . += SIZEOF(.data) + ((SIZEOF(.data) != 0) ? 0x8 : 0); /* DRAM segment (optional) */ - . += SIZEOF(.iram) + 0x8; /* IRAM segment */ - . += 0x8; /* IROM segment header */ - } > IROM - - /* IROM segment. This contains all the actual code and is placed right after - * the DROM segment. - */ - .text : ALIGN(4) - { - . = ALIGN (256); - *(.text.exception_vectors) - . = ALIGN (4); - *(.text .text.*) - } >IROM - - /DISCARD/ : - { - *(.eh_frame) /* causes 'no memory region specified' error in lld */ - } - - /* Check that the boot ROM stack (for the APP CPU) does not overlap with the - * data that is loaded by the boot ROM. This is unlikely to happen in - * practice. - * The magic value comes from here: - * https://github.com/espressif/esp-idf/blob/61299f879e/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld#L191 - */ - ASSERT((_edata + SIZEOF(.iram)) < 0x3FCDE710, "the .iram section overlaps with the stack used by the boot ROM, possibly causing corruption at startup") -} - -/* For the garbage collector. - * Note that _heap_start starts after _edata + most of the IRAM section. - * It starts just before the initialisation code, which isn't necessary anymore - * after startup and can thus be overwritten by the heap. - */ -_globals_start = _sbss; -_globals_end = _edata; -_heap_start = _edata + SIZEOF(.iram) - (__init_end - __init_start); -_heap_end = ORIGIN(DRAM) + LENGTH(DRAM); - -_stack_size = 4K; - -/* ROM functions used for setting up the flash mapping. - */ -Cache_Invalidate_ICache_All = 0x400004d8; -Cache_Suspend_ICache = 0x40000524; -Cache_Resume_ICache = 0x40000528; -Cache_MMU_Init = 0x4000055c; -Cache_Dbus_MMU_Set = 0x40000564; - -/* From ESP-IDF: - * components/esp_rom/esp32c3/ld/esp32c3.rom.libgcc.ld - * These are called from LLVM during codegen. The original license is Apache - * 2.0. - */ -__absvdi2 = 0x40000764; -__absvsi2 = 0x40000768; -__adddf3 = 0x4000076c; -__addsf3 = 0x40000770; -__addvdi3 = 0x40000774; -__addvsi3 = 0x40000778; -__ashldi3 = 0x4000077c; -__ashrdi3 = 0x40000780; -__bswapdi2 = 0x40000784; -__bswapsi2 = 0x40000788; -__clear_cache = 0x4000078c; -__clrsbdi2 = 0x40000790; -__clrsbsi2 = 0x40000794; -__clzdi2 = 0x40000798; -__clzsi2 = 0x4000079c; -__cmpdi2 = 0x400007a0; -__ctzdi2 = 0x400007a4; -__ctzsi2 = 0x400007a8; -__divdc3 = 0x400007ac; -__divdf3 = 0x400007b0; -__divdi3 = 0x400007b4; -__divsc3 = 0x400007b8; -__divsf3 = 0x400007bc; -__divsi3 = 0x400007c0; -__eqdf2 = 0x400007c4; -__eqsf2 = 0x400007c8; -__extendsfdf2 = 0x400007cc; -__ffsdi2 = 0x400007d0; -__ffssi2 = 0x400007d4; -__fixdfdi = 0x400007d8; -__fixdfsi = 0x400007dc; -__fixsfdi = 0x400007e0; -__fixsfsi = 0x400007e4; -__fixunsdfsi = 0x400007e8; -__fixunssfdi = 0x400007ec; -__fixunssfsi = 0x400007f0; -__floatdidf = 0x400007f4; -__floatdisf = 0x400007f8; -__floatsidf = 0x400007fc; -__floatsisf = 0x40000800; -__floatundidf = 0x40000804; -__floatundisf = 0x40000808; -__floatunsidf = 0x4000080c; -__floatunsisf = 0x40000810; -__gcc_bcmp = 0x40000814; -__gedf2 = 0x40000818; -__gesf2 = 0x4000081c; -__gtdf2 = 0x40000820; -__gtsf2 = 0x40000824; -__ledf2 = 0x40000828; -__lesf2 = 0x4000082c; -__lshrdi3 = 0x40000830; -__ltdf2 = 0x40000834; -__ltsf2 = 0x40000838; -__moddi3 = 0x4000083c; -__modsi3 = 0x40000840; -__muldc3 = 0x40000844; -__muldf3 = 0x40000848; -__muldi3 = 0x4000084c; -__mulsc3 = 0x40000850; -__mulsf3 = 0x40000854; -__mulsi3 = 0x40000858; -__mulvdi3 = 0x4000085c; -__mulvsi3 = 0x40000860; -__nedf2 = 0x40000864; -__negdf2 = 0x40000868; -__negdi2 = 0x4000086c; -__negsf2 = 0x40000870; -__negvdi2 = 0x40000874; -__negvsi2 = 0x40000878; -__nesf2 = 0x4000087c; -__paritysi2 = 0x40000880; -__popcountdi2 = 0x40000884; -__popcountsi2 = 0x40000888; -__powidf2 = 0x4000088c; -__powisf2 = 0x40000890; -__subdf3 = 0x40000894; -__subsf3 = 0x40000898; -__subvdi3 = 0x4000089c; -__subvsi3 = 0x400008a0; -__truncdfsf2 = 0x400008a4; -__ucmpdi2 = 0x400008a8; -__udivdi3 = 0x400008ac; -__udivmoddi4 = 0x400008b0; -__udivsi3 = 0x400008b4; -__udiv_w_sdiv = 0x400008b8; -__umoddi3 = 0x400008bc; -__umodsi3 = 0x400008c0; -__unorddf2 = 0x400008c4; -__unordsf2 = 0x400008c8; - -/* From ESP-IDF: - * components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld - * These are called during codegen and thus it's a good idea to make them always - * available. ROM functions may also be faster than functions in IROM (that go - * through the flash cache) and are always available in interrupts. - */ -memset = 0x40000354; -memcpy = 0x40000358; -memmove = 0x4000035c; - - -/* From ESP-IDF: - * components/esp_rom/esp32c3/ld/esp32c3.rom.ld - * These are needed for wifi/BLE support and are available on the Apache 2.0 - * license. - */ -/* ROM function interface esp32c3.rom.ld for esp32c3 - * - * - * Generated from ./interface-esp32c3.yml md5sum 93b28a9e1fe42d212018eb4336849208 - * - * Compatible with ROM where ECO version equal or greater to 0. - * - * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. - */ - -/*************************************** - Group common - ***************************************/ - -/* Functions */ -rtc_get_reset_reason = 0x40000018; -analog_super_wdt_reset_happened = 0x4000001c; -jtag_cpu_reset_happened = 0x40000020; -rtc_get_wakeup_cause = 0x40000024; -rtc_boot_control = 0x40000028; -rtc_select_apb_bridge = 0x4000002c; -rtc_unhold_all_pads = 0x40000030; -set_rtc_memory_crc = 0x40000034; -cacl_rtc_memory_crc = 0x40000038; -ets_is_print_boot = 0x4000003c; -ets_printf = 0x40000040; -ets_install_putc1 = 0x40000044; -ets_install_uart_printf = 0x40000048; -ets_install_putc2 = 0x4000004c; -PROVIDE( ets_delay_us = 0x40000050 ); -ets_get_stack_info = 0x40000054; -ets_install_lock = 0x40000058; -ets_backup_dma_copy = 0x4000005c; -ets_apb_backup_init_lock_func = 0x40000060; -UartRxString = 0x40000064; -uart_tx_one_char = 0x40000068; -uart_tx_one_char2 = 0x4000006c; -uart_rx_one_char = 0x40000070; -uart_rx_one_char_block = 0x40000074; -uart_rx_readbuff = 0x40000078; -uartAttach = 0x4000007c; -uart_tx_flush = 0x40000080; -uart_tx_wait_idle = 0x40000084; -uart_div_modify = 0x40000088; -multofup = 0x4000008c; -software_reset = 0x40000090; -software_reset_cpu = 0x40000094; -assist_debug_clock_enable = 0x40000098; -assist_debug_record_enable = 0x4000009c; -clear_super_wdt_reset_flag = 0x400000a0; -disable_default_watchdog = 0x400000a4; -send_packet = 0x400000a8; -recv_packet = 0x400000ac; -GetUartDevice = 0x400000b0; -UartDwnLdProc = 0x400000b4; -Uart_Init = 0x400000b8; -ets_set_user_start = 0x400000bc; -/* Data (.data, .bss, .rodata) */ -ets_rom_layout_p = 0x3ff1fffc; -ets_ops_table_ptr = 0x3fcdfffc; - - -/*************************************** - Group miniz - ***************************************/ - -/* Functions */ -mz_adler32 = 0x400000c0; -mz_crc32 = 0x400000c4; -mz_free = 0x400000c8; -tdefl_compress = 0x400000cc; -tdefl_compress_buffer = 0x400000d0; -tdefl_compress_mem_to_heap = 0x400000d4; -tdefl_compress_mem_to_mem = 0x400000d8; -tdefl_compress_mem_to_output = 0x400000dc; -tdefl_get_adler32 = 0x400000e0; -tdefl_get_prev_return_status = 0x400000e4; -tdefl_init = 0x400000e8; -tdefl_write_image_to_png_file_in_memory = 0x400000ec; -tdefl_write_image_to_png_file_in_memory_ex = 0x400000f0; -tinfl_decompress = 0x400000f4; -tinfl_decompress_mem_to_callback = 0x400000f8; -tinfl_decompress_mem_to_heap = 0x400000fc; -tinfl_decompress_mem_to_mem = 0x40000100; - - -/*************************************** - Group tjpgd - ***************************************/ - -/* Functions */ -PROVIDE( jd_prepare = 0x40000104 ); -PROVIDE( jd_decomp = 0x40000108 ); - - -/*************************************** - Group spiflash_legacy - ***************************************/ - -/* Functions */ -PROVIDE( esp_rom_spiflash_wait_idle = 0x4000010c ); -PROVIDE( esp_rom_spiflash_write_encrypted = 0x40000110 ); -PROVIDE( esp_rom_spiflash_write_encrypted_dest = 0x40000114 ); -PROVIDE( esp_rom_spiflash_write_encrypted_enable = 0x40000118 ); -PROVIDE( esp_rom_spiflash_write_encrypted_disable = 0x4000011c ); -PROVIDE( esp_rom_spiflash_erase_chip = 0x40000120 ); -PROVIDE( esp_rom_spiflash_erase_block = 0x40000124 ); -PROVIDE( esp_rom_spiflash_erase_sector = 0x40000128 ); -PROVIDE( esp_rom_spiflash_write = 0x4000012c ); -PROVIDE( esp_rom_spiflash_read = 0x40000130 ); -PROVIDE( esp_rom_spiflash_config_param = 0x40000134 ); -PROVIDE( esp_rom_spiflash_read_user_cmd = 0x40000138 ); -PROVIDE( esp_rom_spiflash_select_qio_pins = 0x4000013c ); -PROVIDE( esp_rom_spiflash_unlock = 0x40000140 ); -PROVIDE( esp_rom_spi_flash_auto_sus_res = 0x40000144 ); -PROVIDE( esp_rom_spi_flash_send_resume = 0x40000148 ); -PROVIDE( esp_rom_spi_flash_update_id = 0x4000014c ); -PROVIDE( esp_rom_spiflash_config_clk = 0x40000150 ); -PROVIDE( esp_rom_spiflash_config_readmode = 0x40000154 ); -PROVIDE( esp_rom_spiflash_read_status = 0x40000158 ); -PROVIDE( esp_rom_spiflash_read_statushigh = 0x4000015c ); -PROVIDE( esp_rom_spiflash_write_status = 0x40000160 ); -PROVIDE( esp_rom_spiflash_attach = 0x40000164 ); -PROVIDE( spi_flash_get_chip_size = 0x40000168 ); -PROVIDE( spi_flash_guard_set = 0x4000016c ); -PROVIDE( spi_flash_guard_get = 0x40000170 ); -PROVIDE( spi_flash_write_config_set = 0x40000174 ); -PROVIDE( spi_flash_write_config_get = 0x40000178 ); -PROVIDE( spi_flash_safe_write_address_func_set = 0x4000017c ); -PROVIDE( spi_flash_unlock = 0x40000180 ); -PROVIDE( spi_flash_erase_range = 0x40000184 ); -PROVIDE( spi_flash_erase_sector = 0x40000188 ); -PROVIDE( spi_flash_write = 0x4000018c ); -PROVIDE( spi_flash_read = 0x40000190 ); -PROVIDE( spi_flash_write_encrypted = 0x40000194 ); -PROVIDE( spi_flash_read_encrypted = 0x40000198 ); -PROVIDE( spi_flash_mmap_os_func_set = 0x4000019c ); -PROVIDE( spi_flash_mmap_page_num_init = 0x400001a0 ); -PROVIDE( spi_flash_mmap = 0x400001a4 ); -PROVIDE( spi_flash_mmap_pages = 0x400001a8 ); -PROVIDE( spi_flash_munmap = 0x400001ac ); -PROVIDE( spi_flash_mmap_dump = 0x400001b0 ); -PROVIDE( spi_flash_check_and_flush_cache = 0x400001b4 ); -PROVIDE( spi_flash_mmap_get_free_pages = 0x400001b8 ); -PROVIDE( spi_flash_cache2phys = 0x400001bc ); -PROVIDE( spi_flash_phys2cache = 0x400001c0 ); -PROVIDE( spi_flash_disable_cache = 0x400001c4 ); -PROVIDE( spi_flash_restore_cache = 0x400001c8 ); -PROVIDE( spi_flash_cache_enabled = 0x400001cc ); -PROVIDE( spi_flash_enable_cache = 0x400001d0 ); -PROVIDE( spi_cache_mode_switch = 0x400001d4 ); -PROVIDE( spi_common_set_dummy_output = 0x400001d8 ); -PROVIDE( spi_common_set_flash_cs_timing = 0x400001dc ); -PROVIDE( esp_enable_cache_flash_wrap = 0x400001e0 ); -PROVIDE( SPIEraseArea = 0x400001e4 ); -PROVIDE( SPILock = 0x400001e8 ); -PROVIDE( SPIMasterReadModeCnfig = 0x400001ec ); -PROVIDE( SPI_Common_Command = 0x400001f0 ); -PROVIDE( SPI_WakeUp = 0x400001f4 ); -PROVIDE( SPI_block_erase = 0x400001f8 ); -PROVIDE( SPI_chip_erase = 0x400001fc ); -PROVIDE( SPI_init = 0x40000200 ); -PROVIDE( SPI_page_program = 0x40000204 ); -PROVIDE( SPI_read_data = 0x40000208 ); -PROVIDE( SPI_sector_erase = 0x4000020c ); -PROVIDE( SPI_write_enable = 0x40000210 ); -PROVIDE( SelectSpiFunction = 0x40000214 ); -PROVIDE( SetSpiDrvs = 0x40000218 ); -PROVIDE( Wait_SPI_Idle = 0x4000021c ); -PROVIDE( spi_dummy_len_fix = 0x40000220 ); -PROVIDE( Disable_QMode = 0x40000224 ); -PROVIDE( Enable_QMode = 0x40000228 ); -/* Data (.data, .bss, .rodata) */ -PROVIDE( rom_spiflash_legacy_funcs = 0x3fcdfff4 ); -PROVIDE( rom_spiflash_legacy_data = 0x3fcdfff0 ); -PROVIDE( g_flash_guard_ops = 0x3fcdfff8 ); - - -/*************************************** - Group spi_flash_hal - ***************************************/ - -/* Functions */ -PROVIDE( spi_flash_hal_poll_cmd_done = 0x4000022c ); -PROVIDE( spi_flash_hal_device_config = 0x40000230 ); -PROVIDE( spi_flash_hal_configure_host_io_mode = 0x40000234 ); -PROVIDE( spi_flash_hal_common_command = 0x40000238 ); -PROVIDE( spi_flash_hal_read = 0x4000023c ); -PROVIDE( spi_flash_hal_erase_chip = 0x40000240 ); -PROVIDE( spi_flash_hal_erase_sector = 0x40000244 ); -PROVIDE( spi_flash_hal_erase_block = 0x40000248 ); -PROVIDE( spi_flash_hal_program_page = 0x4000024c ); -PROVIDE( spi_flash_hal_set_write_protect = 0x40000250 ); -PROVIDE( spi_flash_hal_host_idle = 0x40000254 ); - - -/*************************************** - Group spi_flash_chips - ***************************************/ - -/* Functions */ -PROVIDE( spi_flash_chip_generic_probe = 0x40000258 ); -PROVIDE( spi_flash_chip_generic_detect_size = 0x4000025c ); -PROVIDE( spi_flash_chip_generic_write = 0x40000260 ); -PROVIDE( spi_flash_chip_generic_write_encrypted = 0x40000264 ); -PROVIDE( spi_flash_chip_generic_set_write_protect = 0x40000268 ); -PROVIDE( spi_flash_common_write_status_16b_wrsr = 0x4000026c ); -PROVIDE( spi_flash_chip_generic_reset = 0x40000270 ); -PROVIDE( spi_flash_chip_generic_erase_chip = 0x40000274 ); -PROVIDE( spi_flash_chip_generic_erase_sector = 0x40000278 ); -PROVIDE( spi_flash_chip_generic_erase_block = 0x4000027c ); -PROVIDE( spi_flash_chip_generic_page_program = 0x40000280 ); -PROVIDE( spi_flash_chip_generic_get_write_protect = 0x40000284 ); -PROVIDE( spi_flash_common_read_status_16b_rdsr_rdsr2 = 0x40000288 ); -PROVIDE( spi_flash_chip_generic_read_reg = 0x4000028c ); -PROVIDE( spi_flash_chip_generic_yield = 0x40000290 ); -PROVIDE( spi_flash_generic_wait_host_idle = 0x40000294 ); -PROVIDE( spi_flash_chip_generic_wait_idle = 0x40000298 ); -PROVIDE( spi_flash_chip_generic_config_host_io_mode = 0x4000029c ); -PROVIDE( spi_flash_chip_generic_read = 0x400002a0 ); -PROVIDE( spi_flash_common_read_status_8b_rdsr2 = 0x400002a4 ); -PROVIDE( spi_flash_chip_generic_get_io_mode = 0x400002a8 ); -PROVIDE( spi_flash_common_read_status_8b_rdsr = 0x400002ac ); -PROVIDE( spi_flash_common_write_status_8b_wrsr = 0x400002b0 ); -PROVIDE( spi_flash_common_write_status_8b_wrsr2 = 0x400002b4 ); -PROVIDE( spi_flash_common_set_io_mode = 0x400002b8 ); -PROVIDE( spi_flash_chip_generic_set_io_mode = 0x400002bc ); -PROVIDE( spi_flash_chip_gd_get_io_mode = 0x400002c0 ); -PROVIDE( spi_flash_chip_gd_probe = 0x400002c4 ); -PROVIDE( spi_flash_chip_gd_set_io_mode = 0x400002c8 ); -/* Data (.data, .bss, .rodata) */ -PROVIDE( spi_flash_chip_generic_config_data = 0x3fcdffec ); - - -/*************************************** - Group memspi_host - ***************************************/ - -/* Functions */ -PROVIDE( memspi_host_read_id_hs = 0x400002cc ); -PROVIDE( memspi_host_read_status_hs = 0x400002d0 ); -PROVIDE( memspi_host_flush_cache = 0x400002d4 ); -PROVIDE( memspi_host_erase_chip = 0x400002d8 ); -PROVIDE( memspi_host_erase_sector = 0x400002dc ); -PROVIDE( memspi_host_erase_block = 0x400002e0 ); -PROVIDE( memspi_host_program_page = 0x400002e4 ); -PROVIDE( memspi_host_read = 0x400002e8 ); -PROVIDE( memspi_host_set_write_protect = 0x400002ec ); -PROVIDE( memspi_host_set_max_read_len = 0x400002f0 ); -PROVIDE( memspi_host_read_data_slicer = 0x400002f4 ); -PROVIDE( memspi_host_write_data_slicer = 0x400002f8 ); - - -/*************************************** - Group esp_flash - ***************************************/ - -/* Functions */ -PROVIDE( esp_flash_chip_driver_initialized = 0x400002fc ); -PROVIDE( esp_flash_read_id = 0x40000300 ); -PROVIDE( esp_flash_get_size = 0x40000304 ); -PROVIDE( esp_flash_erase_chip = 0x40000308 ); -PROVIDE( rom_esp_flash_erase_region = 0x4000030c ); -PROVIDE( esp_flash_get_chip_write_protect = 0x40000310 ); -PROVIDE( esp_flash_set_chip_write_protect = 0x40000314 ); -PROVIDE( esp_flash_get_protectable_regions = 0x40000318 ); -PROVIDE( esp_flash_get_protected_region = 0x4000031c ); -PROVIDE( esp_flash_set_protected_region = 0x40000320 ); -PROVIDE( esp_flash_read = 0x40000324 ); -PROVIDE( esp_flash_write = 0x40000328 ); -PROVIDE( esp_flash_write_encrypted = 0x4000032c ); -PROVIDE( esp_flash_read_encrypted = 0x40000330 ); -PROVIDE( esp_flash_get_io_mode = 0x40000334 ); -PROVIDE( esp_flash_set_io_mode = 0x40000338 ); -PROVIDE( spi_flash_boot_attach = 0x4000033c ); -PROVIDE( spi_flash_dump_counters = 0x40000340 ); -PROVIDE( spi_flash_get_counters = 0x40000344 ); -PROVIDE( spi_flash_op_counters_config = 0x40000348 ); -PROVIDE( spi_flash_reset_counters = 0x4000034c ); -/* Data (.data, .bss, .rodata) */ -PROVIDE( esp_flash_default_chip = 0x3fcdffe8 ); -PROVIDE( esp_flash_api_funcs = 0x3fcdffe4 ); - - -/*************************************** - Group cache - ***************************************/ - -/* Functions */ -PROVIDE( Cache_Get_ICache_Line_Size = 0x400004b0 ); -PROVIDE( Cache_Get_Mode = 0x400004b4 ); -PROVIDE( Cache_Address_Through_IBus = 0x400004b8 ); -PROVIDE( Cache_Address_Through_DBus = 0x400004bc ); -PROVIDE( Cache_Set_Default_Mode = 0x400004c0 ); -PROVIDE( Cache_Enable_Defalut_ICache_Mode = 0x400004c4 ); -PROVIDE( ROM_Boot_Cache_Init = 0x400004c8 ); -PROVIDE( Cache_Invalidate_ICache_Items = 0x400004cc ); -PROVIDE( Cache_Op_Addr = 0x400004d0 ); -PROVIDE( Cache_Invalidate_Addr = 0x400004d4 ); -PROVIDE( Cache_Invalidate_ICache_All = 0x400004d8 ); -PROVIDE( Cache_Mask_All = 0x400004dc ); -PROVIDE( Cache_UnMask_Dram0 = 0x400004e0 ); -PROVIDE( Cache_Suspend_ICache_Autoload = 0x400004e4 ); -PROVIDE( Cache_Resume_ICache_Autoload = 0x400004e8 ); -PROVIDE( Cache_Start_ICache_Preload = 0x400004ec ); -PROVIDE( Cache_ICache_Preload_Done = 0x400004f0 ); -PROVIDE( Cache_End_ICache_Preload = 0x400004f4 ); -PROVIDE( Cache_Config_ICache_Autoload = 0x400004f8 ); -PROVIDE( Cache_Enable_ICache_Autoload = 0x400004fc ); -PROVIDE( Cache_Disable_ICache_Autoload = 0x40000500 ); -PROVIDE( Cache_Enable_ICache_PreLock = 0x40000504 ); -PROVIDE( Cache_Disable_ICache_PreLock = 0x40000508 ); -PROVIDE( Cache_Lock_ICache_Items = 0x4000050c ); -PROVIDE( Cache_Unlock_ICache_Items = 0x40000510 ); -PROVIDE( Cache_Lock_Addr = 0x40000514 ); -PROVIDE( Cache_Unlock_Addr = 0x40000518 ); -PROVIDE( Cache_Disable_ICache = 0x4000051c ); -PROVIDE( Cache_Enable_ICache = 0x40000520 ); -PROVIDE( Cache_Suspend_ICache = 0x40000524 ); -PROVIDE( Cache_Resume_ICache = 0x40000528 ); -PROVIDE( Cache_Freeze_ICache_Enable = 0x4000052c ); -PROVIDE( Cache_Freeze_ICache_Disable = 0x40000530 ); -PROVIDE( Cache_Pms_Lock = 0x40000534 ); -PROVIDE( Cache_Ibus_Pms_Set_Addr = 0x40000538 ); -PROVIDE( Cache_Ibus_Pms_Set_Attr = 0x4000053c ); -PROVIDE( Cache_Dbus_Pms_Set_Addr = 0x40000540 ); -PROVIDE( Cache_Dbus_Pms_Set_Attr = 0x40000544 ); -PROVIDE( Cache_Set_IDROM_MMU_Size = 0x40000548 ); -PROVIDE( Cache_Get_IROM_MMU_End = 0x4000054c ); -PROVIDE( Cache_Get_DROM_MMU_End = 0x40000550 ); -PROVIDE( Cache_Owner_Init = 0x40000554 ); -PROVIDE( Cache_Occupy_ICache_MEMORY = 0x40000558 ); -PROVIDE( Cache_MMU_Init = 0x4000055c ); -PROVIDE( Cache_Ibus_MMU_Set = 0x40000560 ); -PROVIDE( Cache_Dbus_MMU_Set = 0x40000564 ); -PROVIDE( Cache_Count_Flash_Pages = 0x40000568 ); -PROVIDE( Cache_Travel_Tag_Memory = 0x4000056c ); -PROVIDE( Cache_Get_Virtual_Addr = 0x40000570 ); -PROVIDE( Cache_Get_Memory_BaseAddr = 0x40000574 ); -PROVIDE( Cache_Get_Memory_Addr = 0x40000578 ); -PROVIDE( Cache_Get_Memory_value = 0x4000057c ); -/* Data (.data, .bss, .rodata) */ -PROVIDE( rom_cache_op_cb = 0x3fcdffd8 ); -PROVIDE( rom_cache_internal_table_ptr = 0x3fcdffd4 ); - - -/*************************************** - Group clock - ***************************************/ - -/* Functions */ -ets_get_apb_freq = 0x40000580; -ets_get_cpu_frequency = 0x40000584; -ets_update_cpu_frequency = 0x40000588; -ets_get_printf_channel = 0x4000058c; -ets_get_xtal_div = 0x40000590; -ets_set_xtal_div = 0x40000594; -ets_get_xtal_freq = 0x40000598; - - -/*************************************** - Group gpio - ***************************************/ - -/* Functions */ -gpio_input_get = 0x4000059c; -gpio_matrix_in = 0x400005a0; -gpio_matrix_out = 0x400005a4; -gpio_output_disable = 0x400005a8; -gpio_output_enable = 0x400005ac; -gpio_output_set = 0x400005b0; -gpio_pad_hold = 0x400005b4; -gpio_pad_input_disable = 0x400005b8; -gpio_pad_input_enable = 0x400005bc; -gpio_pad_pulldown = 0x400005c0; -gpio_pad_pullup = 0x400005c4; -gpio_pad_select_gpio = 0x400005c8; -gpio_pad_set_drv = 0x400005cc; -gpio_pad_unhold = 0x400005d0; -gpio_pin_wakeup_disable = 0x400005d4; -gpio_pin_wakeup_enable = 0x400005d8; -gpio_bypass_matrix_in = 0x400005dc; - - -/*************************************** - Group interrupts - ***************************************/ - -/* Functions */ -esprv_intc_int_set_priority = 0x400005e0; -esprv_intc_int_set_threshold = 0x400005e4; -esprv_intc_int_enable = 0x400005e8; -esprv_intc_int_disable = 0x400005ec; -esprv_intc_int_set_type = 0x400005f0; -intr_matrix_set = 0x400005f4; -ets_intr_lock = 0x400005f8; -ets_intr_unlock = 0x400005fc; -PROVIDE( intr_handler_set = 0x40000600 ); -ets_isr_attach = 0x40000604; -ets_isr_mask = 0x40000608; -ets_isr_unmask = 0x4000060c; - - -/*************************************** - Group crypto - ***************************************/ - -/* Functions */ -md5_vector = 0x40000610; -MD5Init = 0x40000614; -MD5Update = 0x40000618; -MD5Final = 0x4000061c; -hmac_md5_vector = 0x40000620; -hmac_md5 = 0x40000624; -crc32_le = 0x40000628; -crc32_be = 0x4000062c; -crc16_le = 0x40000630; -crc16_be = 0x40000634; -crc8_le = 0x40000638; -crc8_be = 0x4000063c; -esp_crc8 = 0x40000640; -ets_sha_enable = 0x40000644; -ets_sha_disable = 0x40000648; -ets_sha_get_state = 0x4000064c; -ets_sha_init = 0x40000650; -ets_sha_process = 0x40000654; -ets_sha_starts = 0x40000658; -ets_sha_update = 0x4000065c; -ets_sha_finish = 0x40000660; -ets_sha_clone = 0x40000664; -ets_hmac_enable = 0x40000668; -ets_hmac_disable = 0x4000066c; -ets_hmac_calculate_message = 0x40000670; -ets_hmac_calculate_downstream = 0x40000674; -ets_hmac_invalidate_downstream = 0x40000678; -ets_jtag_enable_temporarily = 0x4000067c; -ets_aes_enable = 0x40000680; -ets_aes_disable = 0x40000684; -ets_aes_setkey = 0x40000688; -ets_aes_block = 0x4000068c; -ets_bigint_enable = 0x40000690; -ets_bigint_disable = 0x40000694; -ets_bigint_multiply = 0x40000698; -ets_bigint_modmult = 0x4000069c; -ets_bigint_modexp = 0x400006a0; -ets_bigint_wait_finish = 0x400006a4; -ets_bigint_getz = 0x400006a8; -ets_ds_enable = 0x400006ac; -ets_ds_disable = 0x400006b0; -ets_ds_start_sign = 0x400006b4; -ets_ds_is_busy = 0x400006b8; -ets_ds_finish_sign = 0x400006bc; -ets_ds_encrypt_params = 0x400006c0; -ets_aes_setkey_dec = 0x400006c4; -ets_aes_setkey_enc = 0x400006c8; -ets_mgf1_sha256 = 0x400006cc; - - -/*************************************** - Group efuse - ***************************************/ - -/* Functions */ -ets_efuse_read = 0x400006d0; -ets_efuse_program = 0x400006d4; -ets_efuse_clear_program_registers = 0x400006d8; -ets_efuse_write_key = 0x400006dc; -ets_efuse_get_read_register_address = 0x400006e0; -ets_efuse_get_key_purpose = 0x400006e4; -ets_efuse_key_block_unused = 0x400006e8; -ets_efuse_find_unused_key_block = 0x400006ec; -ets_efuse_rs_calculate = 0x400006f0; -ets_efuse_count_unused_key_blocks = 0x400006f4; -ets_efuse_secure_boot_enabled = 0x400006f8; -ets_efuse_secure_boot_aggressive_revoke_enabled = 0x400006fc; -ets_efuse_cache_encryption_enabled = 0x40000700; -ets_efuse_download_modes_disabled = 0x40000704; -ets_efuse_find_purpose = 0x40000708; -ets_efuse_flash_opi_5pads_power_sel_vddspi = 0x4000070c; -ets_efuse_force_send_resume = 0x40000710; -ets_efuse_get_flash_delay_us = 0x40000714; -ets_efuse_get_mac = 0x40000718; -ets_efuse_get_spiconfig = 0x4000071c; -ets_efuse_usb_print_is_disabled = 0x40000720; -/*ets_efuse_get_uart_print_channel = 0x40000724;*/ -ets_efuse_usb_serial_jtag_print_is_disabled = 0x40000724; -ets_efuse_get_uart_print_control = 0x40000728; -ets_efuse_get_wp_pad = 0x4000072c; -ets_efuse_legacy_spi_boot_mode_disabled = 0x40000730; -ets_efuse_security_download_modes_enabled = 0x40000734; -ets_efuse_set_timing = 0x40000738; -ets_efuse_jtag_disabled = 0x4000073c; -ets_efuse_usb_download_mode_disabled = 0x40000740; -ets_efuse_usb_module_disabled = 0x40000744; -ets_efuse_usb_device_disabled = 0x40000748; - - -/*************************************** - Group secureboot - ***************************************/ - -/* Functions */ -ets_emsa_pss_verify = 0x4000074c; -ets_rsa_pss_verify = 0x40000750; -ets_secure_boot_verify_bootloader_with_keys = 0x40000754; -ets_secure_boot_verify_signature = 0x40000758; -ets_secure_boot_read_key_digests = 0x4000075c; -ets_secure_boot_revoke_public_key_digest = 0x40000760; - - -/*************************************** - Group usb_uart - ***************************************/ - -/* Functions */ -PROVIDE( usb_uart_rx_one_char = 0x400008cc ); -PROVIDE( usb_uart_rx_one_char_block = 0x400008d0 ); -PROVIDE( usb_uart_tx_flush = 0x400008d4 ); -PROVIDE( usb_uart_tx_one_char = 0x400008d8 ); -/* Data (.data, .bss, .rodata) */ -PROVIDE( g_uart_print = 0x3fcdffd1 ); -PROVIDE( g_usb_print = 0x3fcdffd0 ); - - -/*************************************** - Group bluetooth - ***************************************/ - -/* Functions */ -bt_rf_coex_get_dft_cfg = 0x400008dc; -bt_rf_coex_hooks_p_set = 0x400008e0; -btdm_con_maxevtime_cal_impl = 0x400008e4; -btdm_controller_get_compile_version_impl = 0x400008e8; -btdm_controller_rom_data_init = 0x400008ec; -btdm_dis_privacy_err_report_impl = 0x400008f0; -btdm_disable_adv_delay_impl = 0x400008f4; -btdm_enable_scan_continue_impl = 0x400008f8; -btdm_enable_scan_forever_impl = 0x400008fc; -btdm_get_power_state_impl = 0x40000900; -btdm_get_prevent_sleep_flag_impl = 0x40000904; -btdm_power_state_active_impl = 0x40000908; -btdm_switch_phy_coded_impl = 0x4000090c; -hci_acl_data_handler = 0x40000910; -hci_disconnect_cmd_handler = 0x40000914; -hci_le_con_upd_cmd_handler = 0x40000918; -hci_le_ltk_req_neg_reply_cmd_handler = 0x4000091c; -hci_le_ltk_req_reply_cmd_handler = 0x40000920; -hci_le_rd_chnl_map_cmd_handler = 0x40000924; -hci_le_rd_phy_cmd_handler = 0x40000928; -hci_le_rd_rem_feats_cmd_handler = 0x4000092c; -hci_le_rem_con_param_req_neg_reply_cmd_handler = 0x40000930; -hci_le_rem_con_param_req_reply_cmd_handler = 0x40000934; -hci_le_set_data_len_cmd_handler = 0x40000938; -hci_le_set_phy_cmd_handler = 0x4000093c; -hci_le_start_enc_cmd_handler = 0x40000940; -hci_rd_auth_payl_to_cmd_handler = 0x40000944; -hci_rd_rem_ver_info_cmd_handler = 0x40000948; -hci_rd_rssi_cmd_handler = 0x4000094c; -hci_rd_tx_pwr_lvl_cmd_handler = 0x40000950; -hci_vs_set_pref_slave_evt_dur_cmd_handler = 0x40000954; -hci_vs_set_pref_slave_latency_cmd_handler = 0x40000958; -hci_wr_auth_payl_to_cmd_handler = 0x4000095c; -ll_channel_map_ind_handler = 0x40000960; -ll_connection_param_req_handler = 0x40000964; -ll_connection_param_rsp_handler = 0x40000968; -ll_connection_update_ind_handler = 0x4000096c; -ll_enc_req_handler = 0x40000970; -ll_enc_rsp_handler = 0x40000974; -ll_feature_req_handler = 0x40000978; -ll_feature_rsp_handler = 0x4000097c; -ll_length_req_handler = 0x40000980; -ll_length_rsp_handler = 0x40000984; -ll_min_used_channels_ind_handler = 0x40000988; -ll_pause_enc_req_handler = 0x4000098c; -ll_pause_enc_rsp_handler = 0x40000990; -ll_phy_req_handler = 0x40000994; -ll_phy_rsp_handler = 0x40000998; -ll_phy_update_ind_handler = 0x4000099c; -ll_ping_req_handler = 0x400009a0; -ll_ping_rsp_handler = 0x400009a4; -ll_slave_feature_req_handler = 0x400009a8; -ll_start_enc_req_handler = 0x400009ac; -ll_start_enc_rsp_handler = 0x400009b0; -ll_terminate_ind_handler = 0x400009b4; -ll_version_ind_handler = 0x400009b8; -llc_auth_payl_nearly_to_handler = 0x400009bc; -llc_auth_payl_real_to_handler = 0x400009c0; -llc_encrypt_ind_handler = 0x400009c4; -llc_hci_command_handler_wrapper = 0x400009c8; -llc_ll_connection_param_req_pdu_send = 0x400009cc; -llc_ll_connection_param_rsp_pdu_send = 0x400009d0; -llc_ll_connection_update_ind_pdu_send = 0x400009d4; -llc_ll_enc_req_pdu_send = 0x400009d8; -llc_ll_enc_rsp_pdu_send = 0x400009dc; -llc_ll_feature_req_pdu_send = 0x400009e0; -llc_ll_feature_rsp_pdu_send = 0x400009e4; -llc_ll_length_req_pdu_send = 0x400009e8; -llc_ll_length_rsp_pdu_send = 0x400009ec; -llc_ll_pause_enc_req_pdu_send = 0x400009f0; -llc_ll_pause_enc_rsp_pdu_send = 0x400009f4; -llc_ll_phy_req_pdu_send = 0x400009f8; -llc_ll_phy_rsp_pdu_send = 0x400009fc; -llc_ll_ping_req_pdu_send = 0x40000a00; -llc_ll_ping_rsp_pdu_send = 0x40000a04; -llc_ll_start_enc_req_pdu_send = 0x40000a08; -llc_ll_start_enc_rsp_pdu_send = 0x40000a0c; -llc_ll_terminate_ind_pdu_send = 0x40000a10; -llc_ll_unknown_rsp_pdu_send = 0x40000a14; -llc_llcp_ch_map_update_ind_pdu_send = 0x40000a18; -llc_llcp_phy_upd_ind_pdu_send = 0x40000a1c; -llc_llcp_version_ind_pdu_send = 0x40000a20; -llc_op_ch_map_upd_ind_handler = 0x40000a24; -llc_op_con_upd_ind_handler = 0x40000a28; -llc_op_disconnect_ind_handler = 0x40000a2c; -llc_op_dl_upd_ind_handler = 0x40000a30; -llc_op_encrypt_ind_handler = 0x40000a34; -llc_op_feats_exch_ind_handler = 0x40000a38; -llc_op_le_ping_ind_handler = 0x40000a3c; -llc_op_phy_upd_ind_handler = 0x40000a40; -llc_op_ver_exch_ind_handler = 0x40000a44; -llc_stopped_ind_handler = 0x40000a48; -lld_acl_rx_ind_handler = 0x40000a4c; -lld_acl_tx_cfm_handler = 0x40000a50; -lld_adv_end_ind_handler = 0x40000a54; -lld_adv_rep_ind_handler = 0x40000a58; -lld_ch_map_upd_cfm_handler = 0x40000a5c; -lld_con_estab_ind_handler = 0x40000a60; -lld_con_evt_sd_evt_time_set = 0x40000a64; -lld_con_offset_upd_ind_handler = 0x40000a68; -lld_con_param_upd_cfm_handler = 0x40000a6c; -lld_disc_ind_handler = 0x40000a70; -lld_init_end_ind_handler = 0x40000a74; -lld_llcp_rx_ind_handler_wrapper = 0x40000a78; -lld_llcp_tx_cfm_handler = 0x40000a7c; -lld_per_adv_end_ind_handler = 0x40000a80; -lld_per_adv_rep_ind_handler = 0x40000a84; -lld_per_adv_rx_end_ind_handler = 0x40000a88; -lld_phy_coded_500k_get = 0x40000a8c; -lld_phy_upd_cfm_handler = 0x40000a90; -lld_scan_end_ind_handler = 0x40000a94; -lld_scan_req_ind_handler = 0x40000a98; -lld_sync_start_req_handler = 0x40000a9c; -lld_test_end_ind_handler = 0x40000aa0; -lld_update_rxbuf_handler = 0x40000aa4; -llm_ch_map_update_ind_handler = 0x40000aa8; -llm_hci_command_handler_wrapper = 0x40000aac; -llm_scan_period_to_handler = 0x40000ab0; -r_Add2SelfBigHex256 = 0x40000ab4; -r_AddBigHex256 = 0x40000ab8; -r_AddBigHexModP256 = 0x40000abc; -r_AddP256 = 0x40000ac0; -r_AddPdiv2_256 = 0x40000ac4; -r_GF_Jacobian_Point_Addition256 = 0x40000ac8; -r_GF_Jacobian_Point_Double256 = 0x40000acc; -r_GF_Point_Jacobian_To_Affine256 = 0x40000ad0; -r_MultiplyBigHexByUint32_256 = 0x40000ad4; -r_MultiplyBigHexModP256 = 0x40000ad8; -r_MultiplyByU16ModP256 = 0x40000adc; -r_SubtractBigHex256 = 0x40000ae0; -r_SubtractBigHexMod256 = 0x40000ae4; -r_SubtractBigHexUint32_256 = 0x40000ae8; -r_SubtractFromSelfBigHex256 = 0x40000aec; -r_SubtractFromSelfBigHexSign256 = 0x40000af0; -r_aes_alloc = 0x40000af4; -r_aes_ccm_continue = 0x40000af8; -r_aes_ccm_process_e = 0x40000afc; -r_aes_ccm_xor_128_lsb = 0x40000b00; -r_aes_ccm_xor_128_msb = 0x40000b04; -r_aes_cmac_continue = 0x40000b08; -r_aes_cmac_start = 0x40000b0c; -r_aes_k1_continue = 0x40000b10; -r_aes_k2_continue = 0x40000b14; -r_aes_k3_continue = 0x40000b18; -r_aes_k4_continue = 0x40000b1c; -r_aes_shift_left_128 = 0x40000b20; -r_aes_start = 0x40000b24; -r_aes_xor_128 = 0x40000b28; -r_assert_err = 0x40000b2c; -r_assert_param = 0x40000b30; -r_assert_warn = 0x40000b34; -r_bigHexInversion256 = 0x40000b38; -r_ble_sw_cca_check_isr = 0x40000b3c; -r_ble_util_buf_acl_tx_alloc = 0x40000b40; -r_ble_util_buf_acl_tx_elt_get = 0x40000b44; -r_ble_util_buf_acl_tx_free = 0x40000b48; -r_ble_util_buf_acl_tx_free_in_isr = 0x40000b4c; -r_ble_util_buf_adv_tx_alloc = 0x40000b50; -r_ble_util_buf_adv_tx_free = 0x40000b54; -r_ble_util_buf_adv_tx_free_in_isr = 0x40000b58; -r_ble_util_buf_env_deinit = 0x40000b5c; -r_ble_util_buf_env_init = 0x40000b60; -r_ble_util_buf_get_rx_buf_nb = 0x40000b64; -r_ble_util_buf_get_rx_buf_size = 0x40000b68; -r_ble_util_buf_llcp_tx_alloc = 0x40000b6c; -r_ble_util_buf_llcp_tx_free = 0x40000b70; -r_ble_util_buf_rx_alloc = 0x40000b74; -r_ble_util_buf_rx_alloc_in_isr = 0x40000b78; -r_ble_util_buf_rx_free = 0x40000b7c; -r_ble_util_buf_rx_free_in_isr = 0x40000b80; -r_ble_util_buf_set_rx_buf_nb = 0x40000b84; -r_ble_util_buf_set_rx_buf_size = 0x40000b88; -r_ble_util_data_rx_buf_reset = 0x40000b8c; -r_bt_bb_get_intr_mask = 0x40000b90; -r_bt_bb_intr_clear = 0x40000b94; -r_bt_bb_intr_mask_set = 0x40000b98; -r_bt_rf_coex_cfg_set = 0x40000ba0; -r_bt_rf_coex_conn_dynamic_pti_en_get = 0x40000ba4; -r_bt_rf_coex_ext_adv_dynamic_pti_en_get = 0x40000bac; -r_bt_rf_coex_ext_scan_dynamic_pti_en_get = 0x40000bb0; -r_bt_rf_coex_legacy_adv_dynamic_pti_en_get = 0x40000bb4; -r_bt_rf_coex_per_adv_dynamic_pti_en_get = 0x40000bb8; -r_bt_rf_coex_pti_table_get = 0x40000bbc; -r_bt_rf_coex_st_param_get = 0x40000bc0; -r_bt_rf_coex_st_param_set = 0x40000bc4; -r_bt_rf_coex_sync_scan_dynamic_pti_en_get = 0x40000bc8; -r_bt_rma_apply_rule_cs_fmt = 0x40000bcc; -r_bt_rma_apply_rule_cs_idx = 0x40000bd0; -r_bt_rma_configure = 0x40000bd4; -r_bt_rma_deregister_rule_cs_fmt = 0x40000bd8; -r_bt_rma_deregister_rule_cs_idx = 0x40000bdc; -r_bt_rma_get_ant_by_act = 0x40000be0; -r_bt_rma_init = 0x40000be4; -r_bt_rma_register_rule_cs_fmt = 0x40000be8; -r_bt_rma_register_rule_cs_idx = 0x40000bec; -r_bt_rtp_apply_rule_cs_fmt = 0x40000bf0; -r_bt_rtp_apply_rule_cs_idx = 0x40000bf4; -r_bt_rtp_deregister_rule_cs_fmt = 0x40000bf8; -r_bt_rtp_deregister_rule_cs_idx = 0x40000bfc; -r_bt_rtp_init = 0x40000c04; -r_bt_rtp_register_rule_cs_fmt = 0x40000c08; -r_bt_rtp_register_rule_cs_idx = 0x40000c0c; -r_btdm_isr = 0x40000c10; -r_cali_phase_match_p = 0x40000c20; -r_cmp_abs_time = 0x40000c24; -r_cmp_dest_id = 0x40000c28; -r_cmp_timer_id = 0x40000c2c; -r_co_bdaddr_compare = 0x40000c30; -r_co_ble_pkt_dur_in_us = 0x40000c34; -r_co_list_extract = 0x40000c38; -r_co_list_extract_after = 0x40000c3c; -r_co_list_extract_sublist = 0x40000c40; -r_co_list_find = 0x40000c44; -r_co_list_init = 0x40000c48; -r_co_list_insert_after = 0x40000c4c; -r_co_list_insert_before = 0x40000c50; -r_co_list_merge = 0x40000c54; -r_co_list_pool_init = 0x40000c58; -r_co_list_pop_front = 0x40000c5c; -r_co_list_push_back = 0x40000c60; -r_co_list_push_back_sublist = 0x40000c64; -r_co_list_push_front = 0x40000c68; -r_co_list_size = 0x40000c6c; -r_co_nb_good_le_channels = 0x40000c70; -r_co_util_pack = 0x40000c74; -r_co_util_read_array_size = 0x40000c78; -r_co_util_unpack = 0x40000c7c; -r_dbg_env_deinit = 0x40000c80; -r_dbg_env_init = 0x40000c84; -r_dbg_platform_reset_complete = 0x40000c88; -r_dl_upd_proc_start = 0x40000c8c; -r_dump_data = 0x40000c90; -r_ecc_abort_key256_generation = 0x40000c94; -r_ecc_gen_new_public_key = 0x40000c98; -r_ecc_gen_new_secret_key = 0x40000c9c; -r_ecc_generate_key256 = 0x40000ca0; -r_ecc_get_debug_Keys = 0x40000ca4; -r_ecc_init = 0x40000ca8; -r_ecc_is_valid_point = 0x40000cac; -r_ecc_multiplication_event_handler = 0x40000cb0; -r_ecc_point_multiplication_win_256 = 0x40000cb4; -r_emi_alloc_em_mapping_by_offset = 0x40000cb8; -r_emi_base_reg_lut_show = 0x40000cbc; -r_emi_em_base_reg_show = 0x40000cc0; -r_emi_free_em_mapping_by_offset = 0x40000cc4; -r_emi_get_em_mapping_idx_by_offset = 0x40000cc8; -r_emi_get_mem_addr_by_offset = 0x40000ccc; -r_emi_overwrite_em_mapping_by_offset = 0x40000cd0; -r_esp_vendor_hci_command_handler = 0x40000cd4; -r_get_stack_usage = 0x40000cd8; -r_h4tl_acl_hdr_rx_evt_handler = 0x40000cdc; -r_h4tl_cmd_hdr_rx_evt_handler = 0x40000ce0; -r_h4tl_cmd_pld_rx_evt_handler = 0x40000ce4; -r_h4tl_eif_io_event_post = 0x40000ce8; -r_h4tl_eif_register = 0x40000cec; -r_h4tl_init = 0x40000cf0; -r_h4tl_out_of_sync = 0x40000cf4; -r_h4tl_out_of_sync_check = 0x40000cf8; -r_h4tl_read_hdr = 0x40000cfc; -r_h4tl_read_next_out_of_sync = 0x40000d00; -r_h4tl_read_payl = 0x40000d04; -r_h4tl_read_start = 0x40000d08; -r_h4tl_rx_acl_hdr_extract = 0x40000d0c; -r_h4tl_rx_cmd_hdr_extract = 0x40000d10; -r_h4tl_rx_done = 0x40000d14; -r_h4tl_start = 0x40000d18; -r_h4tl_stop = 0x40000d1c; -r_h4tl_tx_done = 0x40000d20; -r_h4tl_tx_evt_handler = 0x40000d24; -r_h4tl_write = 0x40000d28; -r_hci_acl_tx_data_alloc = 0x40000d2c; -r_hci_acl_tx_data_received = 0x40000d30; -r_hci_basic_cmd_send_2_controller = 0x40000d34; -r_hci_ble_adv_report_filter_check = 0x40000d38; -r_hci_ble_adv_report_tx_check = 0x40000d3c; -r_hci_ble_conhdl_register = 0x40000d40; -r_hci_ble_conhdl_unregister = 0x40000d44; -r_hci_build_acl_data = 0x40000d48; -r_hci_build_cc_evt = 0x40000d4c; -r_hci_build_cs_evt = 0x40000d50; -r_hci_build_evt = 0x40000d54; -r_hci_build_le_evt = 0x40000d58; -r_hci_cmd_get_max_param_size = 0x40000d5c; -r_hci_cmd_received = 0x40000d60; -r_hci_cmd_reject = 0x40000d64; -r_hci_evt_mask_check = 0x40000d68; -r_hci_evt_mask_set = 0x40000d6c; -r_hci_fc_acl_buf_size_set = 0x40000d70; -r_hci_fc_acl_en = 0x40000d74; -r_hci_fc_acl_packet_sent = 0x40000d78; -r_hci_fc_check_host_available_nb_acl_packets = 0x40000d7c; -r_hci_fc_host_nb_acl_pkts_complete = 0x40000d80; -r_hci_fc_init = 0x40000d84; -r_hci_look_for_cmd_desc = 0x40000d88; -r_hci_look_for_evt_desc = 0x40000d8c; -r_hci_look_for_le_evt_desc = 0x40000d90; -r_hci_look_for_le_evt_desc_esp = 0x40000d94; -r_hci_pack_bytes = 0x40000d98; -r_hci_send_2_controller = 0x40000da0; -r_hci_send_2_host = 0x40000da4; -r_hci_tl_c2h_data_flow_on = 0x40000da8; -r_hci_tl_cmd_hdr_rx_evt_handler = 0x40000dac; -r_hci_tl_cmd_pld_rx_evt_handler = 0x40000db0; -r_hci_tl_get_pkt = 0x40000db4; -r_hci_tl_hci_pkt_handler = 0x40000db8; -r_hci_tl_hci_tx_done_evt_handler = 0x40000dbc; -r_hci_tl_inc_nb_h2c_cmd_pkts = 0x40000dc0; -r_hci_tl_save_pkt = 0x40000dc4; -r_hci_tl_send = 0x40000dc8; -r_hci_tx_done = 0x40000dcc; -r_hci_tx_start = 0x40000dd0; -r_hci_tx_trigger = 0x40000dd4; -r_isValidSecretKey_256 = 0x40000dd8; -r_ke_check_malloc = 0x40000ddc; -r_ke_event_callback_set = 0x40000de0; -r_ke_event_clear = 0x40000de4; -r_ke_event_flush = 0x40000de8; -r_ke_event_get = 0x40000dec; -r_ke_event_get_all = 0x40000df0; -r_ke_event_init = 0x40000df4; -r_ke_event_schedule = 0x40000df8; -r_ke_event_set = 0x40000dfc; -r_ke_flush = 0x40000e00; -r_ke_free = 0x40000e04; -r_ke_handler_search = 0x40000e08; -r_ke_init = 0x40000e0c; -r_ke_is_free = 0x40000e10; -r_ke_malloc = 0x40000e14; -r_ke_mem_init = 0x40000e18; -r_ke_mem_is_empty = 0x40000e1c; -r_ke_mem_is_in_heap = 0x40000e20; -r_ke_msg_alloc = 0x40000e24; -r_ke_msg_dest_id_get = 0x40000e28; -r_ke_msg_discard = 0x40000e2c; -r_ke_msg_forward = 0x40000e30; -r_ke_msg_forward_new_id = 0x40000e34; -r_ke_msg_free = 0x40000e38; -r_ke_msg_in_queue = 0x40000e3c; -r_ke_msg_save = 0x40000e40; -r_ke_msg_send = 0x40000e44; -r_ke_msg_send_basic = 0x40000e48; -r_ke_msg_src_id_get = 0x40000e4c; -r_ke_queue_extract = 0x40000e50; -r_ke_queue_insert = 0x40000e54; -r_ke_sleep_check = 0x40000e58; -r_ke_state_get = 0x40000e5c; -r_ke_state_set = 0x40000e60; -r_ke_task_check = 0x40000e64; -r_ke_task_create = 0x40000e68; -r_ke_task_delete = 0x40000e6c; -r_ke_task_handler_get = 0x40000e70; -r_ke_task_init = 0x40000e74; -r_ke_task_msg_flush = 0x40000e78; -r_ke_task_saved_update = 0x40000e7c; -r_ke_time = 0x40000e84; -r_ke_time_cmp = 0x40000e88; -r_ke_time_past = 0x40000e8c; -r_ke_timer_active = 0x40000e90; -r_ke_timer_adjust_all = 0x40000e94; -r_ke_timer_clear = 0x40000e98; -r_ke_timer_init = 0x40000e9c; -r_ke_timer_schedule = 0x40000ea0; -r_ke_timer_set = 0x40000ea4; -r_led_init = 0x40000ea8; -r_led_set_all = 0x40000eac; -r_llc_aes_res_cb = 0x40000eb0; -r_llc_ch_map_up_proc_err_cb = 0x40000eb4; -r_llc_cleanup = 0x40000eb8; -r_llc_cmd_cmp_send = 0x40000ebc; -r_llc_cmd_stat_send = 0x40000ec0; -r_llc_con_move_cbk = 0x40000ec4; -r_llc_con_plan_set_update = 0x40000ec8; -r_llc_con_upd_param_in_range = 0x40000ecc; -r_llc_disconnect = 0x40000ed0; -r_llc_disconnect_end = 0x40000ed4; -r_llc_disconnect_proc_continue = 0x40000ed8; -r_llc_disconnect_proc_err_cb = 0x40000edc; -r_llc_dl_chg_check = 0x40000ee0; -r_llc_dle_proc_err_cb = 0x40000ee4; -r_llc_feats_exch_proc_err_cb = 0x40000ee8; -r_llc_hci_cmd_handler_tab_p_get = 0x40000eec; -r_llc_hci_con_param_req_evt_send = 0x40000ef4; -r_llc_hci_con_upd_info_send = 0x40000ef8; -r_llc_hci_disconnected_dis = 0x40000efc; -r_llc_hci_dl_upd_info_send = 0x40000f00; -r_llc_hci_enc_evt_send = 0x40000f04; -r_llc_hci_feats_info_send = 0x40000f08; -r_llc_hci_le_phy_upd_cmp_evt_send = 0x40000f0c; -r_llc_hci_ltk_request_evt_send = 0x40000f10; -r_llc_hci_nb_cmp_pkts_evt_send = 0x40000f14; -r_llc_hci_version_info_send = 0x40000f18; -r_llc_init_term_proc = 0x40000f1c; -r_llc_iv_skd_rand_gen = 0x40000f20; -r_llc_le_ping_proc_continue = 0x40000f24; -r_llc_le_ping_proc_err_cb = 0x40000f28; -r_llc_le_ping_restart = 0x40000f2c; -r_llc_le_ping_set = 0x40000f30; -r_llc_ll_pause_enc_rsp_ack_handler = 0x40000f34; -r_llc_ll_reject_ind_ack_handler = 0x40000f38; -r_llc_ll_reject_ind_pdu_send = 0x40000f3c; -r_llc_ll_start_enc_rsp_ack_handler = 0x40000f40; -r_llc_ll_terminate_ind_ack = 0x40000f44; -r_llc_ll_unknown_ind_handler = 0x40000f48; -r_llc_llcp_send = 0x40000f4c; -r_llc_llcp_state_set = 0x40000f50; -r_llc_llcp_trans_timer_set = 0x40000f54; -r_llc_llcp_tx_check = 0x40000f58; -r_llc_loc_ch_map_proc_continue = 0x40000f5c; -r_llc_loc_con_upd_proc_err_cb = 0x40000f64; -r_llc_loc_dl_upd_proc_continue = 0x40000f68; -r_llc_loc_encrypt_proc_continue = 0x40000f6c; -r_llc_loc_encrypt_proc_err_cb = 0x40000f70; -r_llc_loc_feats_exch_proc_continue = 0x40000f74; -r_llc_loc_phy_upd_proc_err_cb = 0x40000f7c; -r_llc_msg_handler_tab_p_get = 0x40000f80; -r_llc_pref_param_compute = 0x40000f84; -r_llc_proc_collision_check = 0x40000f88; -r_llc_proc_err_ind = 0x40000f8c; -r_llc_proc_get = 0x40000f90; -r_llc_proc_id_get = 0x40000f94; -r_llc_proc_reg = 0x40000f98; -r_llc_proc_state_get = 0x40000f9c; -r_llc_proc_state_set = 0x40000fa0; -r_llc_proc_timer_pause_set = 0x40000fa4; -r_llc_proc_timer_set = 0x40000fa8; -r_llc_proc_unreg = 0x40000fac; -r_llc_rem_ch_map_proc_continue = 0x40000fb0; -r_llc_rem_con_upd_proc_err_cb = 0x40000fb8; -r_llc_rem_dl_upd_proc = 0x40000fbc; -r_llc_rem_encrypt_proc_continue = 0x40000fc0; -r_llc_rem_encrypt_proc_err_cb = 0x40000fc4; -r_llc_rem_phy_upd_proc_continue = 0x40000fc8; -r_llc_rem_phy_upd_proc_err_cb = 0x40000fcc; -r_llc_role_get = 0x40000fd0; -r_llc_sk_gen = 0x40000fd4; -r_llc_start = 0x40000fd8; -r_llc_stop = 0x40000fdc; -r_llc_ver_exch_loc_proc_continue = 0x40000fe0; -r_llc_ver_proc_err_cb = 0x40000fe4; -r_llcp_pdu_handler_tab_p_get = 0x40000fe8; -r_lld_aa_gen = 0x40000fec; -r_lld_adv_adv_data_set = 0x40000ff0; -r_lld_adv_adv_data_update = 0x40000ff4; -r_lld_adv_aux_ch_idx_set = 0x40000ff8; -r_lld_adv_aux_evt_canceled_cbk = 0x40000ffc; -r_lld_adv_aux_evt_start_cbk = 0x40001000; -r_lld_adv_coex_check_ext_adv_synced = 0x40001004; -r_lld_adv_coex_env_reset = 0x40001008; -r_lld_adv_duration_update = 0x4000100c; -r_lld_adv_dynamic_pti_process = 0x40001010; -r_lld_adv_end = 0x40001014; -r_lld_adv_evt_canceled_cbk = 0x40001018; -r_lld_adv_evt_start_cbk = 0x4000101c; -r_lld_adv_ext_chain_construct = 0x40001020; -r_lld_adv_ext_pkt_prepare = 0x40001024; -r_lld_adv_frm_cbk = 0x40001028; -r_lld_adv_frm_isr = 0x4000102c; -r_lld_adv_frm_skip_isr = 0x40001030; -r_lld_adv_init = 0x40001034; -r_lld_adv_pkt_rx = 0x40001038; -r_lld_adv_pkt_rx_connect_ind = 0x4000103c; -r_lld_adv_pkt_rx_send_scan_req_evt = 0x40001040; -r_lld_adv_rand_addr_update = 0x40001044; -r_lld_adv_restart = 0x40001048; -r_lld_adv_scan_rsp_data_set = 0x4000104c; -r_lld_adv_scan_rsp_data_update = 0x40001050; -r_lld_adv_set_tx_power = 0x40001054; -r_lld_adv_start = 0x40001058; -r_lld_adv_stop = 0x4000105c; -r_lld_adv_sync_info_set = 0x40001060; -r_lld_adv_sync_info_update = 0x40001064; -r_lld_calc_aux_rx = 0x40001068; -r_lld_cca_alloc = 0x4000106c; -r_lld_cca_data_reset = 0x40001070; -r_lld_cca_free = 0x40001074; -r_lld_ch_assess_data_get = 0x40001078; -r_lld_ch_idx_get = 0x4000107c; -r_lld_ch_map_set = 0x40001080; -r_lld_channel_assess = 0x40001084; -r_lld_con_activity_act_offset_compute = 0x40001088; -r_lld_con_activity_offset_compute = 0x4000108c; -r_lld_con_ch_map_update = 0x40001090; -r_lld_con_cleanup = 0x40001094; -r_lld_con_current_tx_power_get = 0x40001098; -r_lld_con_data_flow_set = 0x4000109c; -r_lld_con_data_len_update = 0x400010a0; -r_lld_con_data_tx = 0x400010a4; -r_lld_con_enc_key_load = 0x400010a8; -r_lld_con_event_counter_get = 0x400010ac; -r_lld_con_evt_canceled_cbk = 0x400010b0; -r_lld_con_evt_duration_min_get = 0x400010b4; -r_lld_con_evt_max_eff_time_cal = 0x400010b8; -r_lld_con_evt_sd_evt_time_get = 0x400010bc; -r_lld_con_evt_start_cbk = 0x400010c0; -r_lld_con_evt_time_update = 0x400010c4; -r_lld_con_free_all_tx_buf = 0x400010c8; -r_lld_con_frm_cbk = 0x400010cc; -r_lld_con_frm_isr = 0x400010d0; -r_lld_con_frm_skip_isr = 0x400010d4; -r_lld_con_init = 0x400010d8; -r_lld_con_llcp_tx = 0x400010dc; -r_lld_con_max_lat_calc = 0x400010e0; -r_lld_con_offset_get = 0x400010e4; -r_lld_con_param_update = 0x400010e8; -r_lld_con_phys_update = 0x400010ec; -r_lld_con_pref_slave_evt_dur_set = 0x400010f0; -r_lld_con_pref_slave_latency_set = 0x400010f4; -r_lld_con_rssi_get = 0x400010f8; -r_lld_con_rx = 0x400010fc; -r_lld_con_rx_channel_assess = 0x40001100; -r_lld_con_rx_enc = 0x40001104; -r_lld_con_rx_isr = 0x40001108; -r_lld_con_rx_link_info_check = 0x4000110c; -r_lld_con_rx_llcp_check = 0x40001110; -r_lld_con_rx_sync_time_update = 0x40001114; -r_lld_con_set_tx_power = 0x4000111c; -r_lld_con_start = 0x40001120; -r_lld_con_tx = 0x40001128; -r_lld_con_tx_enc = 0x4000112c; -r_lld_con_tx_isr = 0x40001130; -r_lld_con_tx_len_update = 0x40001134; -r_lld_con_tx_len_update_for_intv = 0x40001138; -r_lld_con_tx_len_update_for_rate = 0x4000113c; -r_lld_con_tx_prog = 0x40001140; -r_lld_conn_dynamic_pti_process = 0x40001144; -r_lld_continue_scan_rx_isr_end_process = 0x40001148; -r_lld_ext_scan_dynamic_pti_process = 0x4000114c; -r_lld_hw_cca_end_isr = 0x40001150; -r_lld_hw_cca_evt_handler = 0x40001154; -r_lld_hw_cca_isr = 0x40001158; -r_lld_init_cal_anchor_point = 0x4000115c; -r_lld_init_compute_winoffset = 0x40001160; -r_lld_init_connect_req_pack = 0x40001164; -r_lld_init_end = 0x40001168; -r_lld_init_evt_canceled_cbk = 0x4000116c; -r_lld_init_evt_start_cbk = 0x40001170; -r_lld_init_frm_cbk = 0x40001174; -r_lld_init_frm_eof_isr = 0x40001178; -r_lld_init_frm_skip_isr = 0x4000117c; -r_lld_init_init = 0x40001180; -r_lld_init_process_pkt_rx = 0x40001184; -r_lld_init_process_pkt_rx_adv_ext_ind = 0x40001188; -r_lld_init_process_pkt_rx_adv_ind_or_direct_ind = 0x4000118c; -r_lld_init_process_pkt_rx_aux_connect_rsp = 0x40001190; -r_lld_init_process_pkt_tx = 0x40001194; -r_lld_init_process_pkt_tx_cal_con_timestamp = 0x40001198; -r_lld_init_sched = 0x4000119c; -r_lld_init_set_tx_power = 0x400011a0; -r_lld_init_start = 0x400011a4; -r_lld_init_stop = 0x400011a8; -r_lld_instant_proc_end = 0x400011ac; -r_lld_per_adv_ch_map_update = 0x400011b4; -r_lld_per_adv_chain_construct = 0x400011b8; -r_lld_per_adv_cleanup = 0x400011bc; -r_lld_per_adv_coex_env_reset = 0x400011c0; -r_lld_per_adv_data_set = 0x400011c4; -r_lld_per_adv_data_update = 0x400011c8; -r_lld_per_adv_dynamic_pti_process = 0x400011cc; -r_lld_per_adv_evt_canceled_cbk = 0x400011d0; -r_lld_per_adv_evt_start_cbk = 0x400011d4; -r_lld_per_adv_ext_pkt_prepare = 0x400011d8; -r_lld_per_adv_frm_cbk = 0x400011dc; -r_lld_per_adv_frm_isr = 0x400011e0; -r_lld_per_adv_frm_skip_isr = 0x400011e4; -r_lld_per_adv_init = 0x400011e8; -r_lld_per_adv_init_info_get = 0x400011ec; -r_lld_per_adv_list_add = 0x400011f0; -r_lld_per_adv_list_rem = 0x400011f4; -r_lld_per_adv_set_tx_power = 0x400011fc; -r_lld_per_adv_start = 0x40001200; -r_lld_per_adv_stop = 0x40001204; -r_lld_per_adv_sync_info_get = 0x40001208; -r_lld_process_cca_data = 0x4000120c; -r_lld_ral_search = 0x40001210; -r_lld_read_clock = 0x40001214; -r_lld_res_list_add = 0x40001218; -r_lld_res_list_is_empty = 0x40001220; -r_lld_res_list_local_rpa_get = 0x40001224; -r_lld_res_list_peer_rpa_get = 0x40001228; -r_lld_res_list_peer_update = 0x4000122c; -r_lld_res_list_priv_mode_update = 0x40001230; -r_lld_reset_reg = 0x40001238; -r_lld_rpa_renew = 0x4000123c; -r_lld_rpa_renew_evt_canceled_cbk = 0x40001240; -r_lld_rpa_renew_evt_start_cbk = 0x40001244; -r_lld_rpa_renew_instant_cbk = 0x40001248; -r_lld_rxdesc_check = 0x4000124c; -r_lld_rxdesc_free = 0x40001250; -r_lld_scan_create_sync = 0x40001254; -r_lld_scan_create_sync_cancel = 0x40001258; -r_lld_scan_end = 0x4000125c; -r_lld_scan_evt_canceled_cbk = 0x40001260; -r_lld_scan_evt_start_cbk = 0x40001264; -r_lld_scan_frm_cbk = 0x40001268; -r_lld_scan_frm_eof_isr = 0x4000126c; -r_lld_scan_frm_rx_isr = 0x40001270; -r_lld_scan_frm_skip_isr = 0x40001274; -r_lld_scan_init = 0x40001278; -r_lld_scan_params_update = 0x4000127c; -r_lld_scan_process_pkt_rx_aux_adv_ind = 0x40001288; -r_lld_scan_process_pkt_rx_aux_chain_ind = 0x4000128c; -r_lld_scan_process_pkt_rx_aux_scan_rsp = 0x40001290; -r_lld_scan_process_pkt_rx_ext_adv = 0x40001294; -r_lld_scan_process_pkt_rx_ext_adv_ind = 0x40001298; -r_lld_scan_process_pkt_rx_legacy_adv = 0x4000129c; -r_lld_scan_restart = 0x400012a0; -r_lld_scan_sched = 0x400012a4; -r_lld_scan_set_tx_power = 0x400012a8; -r_lld_scan_start = 0x400012ac; -r_lld_scan_stop = 0x400012b0; -r_lld_scan_sync_accept = 0x400012b4; -r_lld_scan_sync_info_unpack = 0x400012b8; -r_lld_scan_trunc_ind = 0x400012bc; -r_lld_sw_cca_evt_handler = 0x400012c0; -r_lld_sw_cca_isr = 0x400012c4; -r_lld_sync_ch_map_update = 0x400012c8; -r_lld_sync_cleanup = 0x400012cc; -r_lld_sync_evt_canceled_cbk = 0x400012d0; -r_lld_sync_evt_start_cbk = 0x400012d4; -r_lld_sync_frm_cbk = 0x400012d8; -r_lld_sync_frm_eof_isr = 0x400012dc; -r_lld_sync_frm_rx_isr = 0x400012e0; -r_lld_sync_frm_skip_isr = 0x400012e4; -r_lld_sync_init = 0x400012e8; -r_lld_sync_process_pkt_rx = 0x400012ec; -r_lld_sync_process_pkt_rx_aux_sync_ind = 0x400012f0; -r_lld_sync_process_pkt_rx_pkt_check = 0x400012f4; -r_lld_sync_scan_dynamic_pti_process = 0x400012f8; -r_lld_sync_sched = 0x400012fc; -r_lld_sync_start = 0x40001300; -r_lld_sync_stop = 0x40001304; -r_lld_sync_trunc_ind = 0x40001308; -r_lld_test_cleanup = 0x4000130c; -r_lld_test_evt_canceled_cbk = 0x40001310; -r_lld_test_evt_start_cbk = 0x40001314; -r_lld_test_freq2chnl = 0x40001318; -r_lld_test_frm_cbk = 0x4000131c; -r_lld_test_frm_isr = 0x40001320; -r_lld_test_init = 0x40001324; -r_lld_test_rx_isr = 0x40001328; -r_lld_test_set_tx_power = 0x4000132c; -r_lld_test_start = 0x40001330; -r_lld_test_stop = 0x40001334; -r_lld_update_rxbuf = 0x40001338; -r_lld_update_rxbuf_isr = 0x4000133c; -r_lld_white_list_add = 0x40001340; -r_lld_white_list_rem = 0x40001344; -r_llm_activity_free_get = 0x40001348; -r_llm_activity_free_set = 0x4000134c; -r_llm_activity_syncing_get = 0x40001350; -r_llm_adv_con_len_check = 0x40001354; -r_llm_adv_hdl_to_id = 0x40001358; -r_llm_adv_rep_flow_control_check = 0x4000135c; -r_llm_adv_rep_flow_control_update = 0x40001360; -r_llm_adv_reports_list_check = 0x40001364; -r_llm_adv_set_all_release = 0x40001368; -r_llm_adv_set_dft_params = 0x4000136c; -r_llm_adv_set_release = 0x40001370; -r_llm_aes_res_cb = 0x40001374; -r_llm_ble_update_adv_flow_control = 0x40001378; -r_llm_ch_map_update = 0x4000137c; -r_llm_cmd_cmp_send = 0x40001380; -r_llm_cmd_stat_send = 0x40001384; -r_llm_dev_list_empty_entry = 0x40001388; -r_llm_dev_list_search = 0x4000138c; -r_llm_env_adv_dup_filt_deinit = 0x40001390; -r_llm_env_adv_dup_filt_init = 0x40001394; -r_llm_init_ble_adv_report_flow_contol = 0x40001398; -r_llm_is_dev_connected = 0x4000139c; -r_llm_is_dev_synced = 0x400013a0; -r_llm_is_non_con_act_ongoing_check = 0x400013a4; -r_llm_is_wl_accessible = 0x400013a8; -r_llm_le_evt_mask_check = 0x400013ac; -r_llm_link_disc = 0x400013b4; -r_llm_master_ch_map_get = 0x400013b8; -r_llm_msg_handler_tab_p_get = 0x400013bc; -r_llm_no_activity = 0x400013c0; -r_llm_per_adv_slot_dur = 0x400013c4; -r_llm_plan_elt_get = 0x400013c8; -r_llm_rx_path_comp_get = 0x400013cc; -r_llm_scan_start = 0x400013d0; -r_llm_scan_sync_acad_attach = 0x400013d4; -r_llm_scan_sync_acad_detach = 0x400013d8; -r_llm_send_adv_lost_event_to_host = 0x400013dc; -r_llm_tx_path_comp_get = 0x400013e0; -r_misc_deinit = 0x400013e4; -r_misc_free_em_buf_in_isr = 0x400013e8; -r_misc_init = 0x400013ec; -r_misc_msg_handler_tab_p_get = 0x400013f0; -r_notEqual256 = 0x400013f4; -r_phy_upd_proc_start = 0x400013f8; -r_platform_reset = 0x400013fc; -r_rf_em_init = 0x40001404; -r_rf_force_agc_enable = 0x40001408; -r_rf_reg_rd = 0x4000140c; -r_rf_reg_wr = 0x40001410; -r_rf_reset = 0x40001414; -r_rf_rssi_convert = 0x40001418; -r_rf_rw_v9_le_disable = 0x4000141c; -r_rf_rw_v9_le_enable = 0x40001420; -r_rf_sleep = 0x40001424; -r_rf_util_cs_fmt_convert = 0x40001430; -r_rw_crypto_aes_ccm = 0x40001434; -r_rw_crypto_aes_encrypt = 0x40001438; -r_rw_crypto_aes_init = 0x4000143c; -r_rw_crypto_aes_k1 = 0x40001440; -r_rw_crypto_aes_k2 = 0x40001444; -r_rw_crypto_aes_k3 = 0x40001448; -r_rw_crypto_aes_k4 = 0x4000144c; -r_rw_crypto_aes_rand = 0x40001450; -r_rw_crypto_aes_result_handler = 0x40001454; -r_rw_crypto_aes_s1 = 0x40001458; -r_rw_cryto_aes_cmac = 0x4000145c; -r_rw_v9_init_em_radio_table = 0x40001460; -r_rwble_sleep_enter = 0x40001468; -r_rwble_sleep_wakeup_end = 0x4000146c; -r_rwbtdm_isr_wrapper = 0x40001470; -r_rwip_active_check = 0x40001474; -r_rwip_aes_encrypt = 0x40001478; -r_rwip_assert = 0x4000147c; -r_rwip_crypt_evt_handler = 0x40001480; -r_rwip_crypt_isr_handler = 0x40001484; -r_rwip_eif_get = 0x40001488; -r_rwip_half_slot_2_lpcycles = 0x4000148c; -r_rwip_hus_2_lpcycles = 0x40001490; -r_rwip_isr = 0x40001494; -r_rwip_lpcycles_2_hus = 0x40001498; -r_rwip_prevent_sleep_clear = 0x4000149c; -r_rwip_prevent_sleep_set = 0x400014a0; -r_rwip_schedule = 0x400014a4; -r_rwip_sleep = 0x400014a8; -r_rwip_sw_int_handler = 0x400014ac; -r_rwip_sw_int_req = 0x400014b0; -r_rwip_time_get = 0x400014b4; -r_rwip_timer_10ms_handler = 0x400014b8; -r_rwip_timer_10ms_set = 0x400014bc; -r_rwip_timer_hs_handler = 0x400014c0; -r_rwip_timer_hs_set = 0x400014c4; -r_rwip_timer_hus_handler = 0x400014c8; -r_rwip_timer_hus_set = 0x400014cc; -r_rwip_wakeup = 0x400014d0; -r_rwip_wakeup_end = 0x400014d4; -r_rwip_wlcoex_set = 0x400014d8; -r_sch_alarm_clear = 0x400014dc; -r_sch_alarm_init = 0x400014e0; -r_sch_alarm_prog = 0x400014e4; -r_sch_alarm_set = 0x400014e8; -r_sch_alarm_timer_isr = 0x400014ec; -r_sch_arb_conflict_check = 0x400014f0; -r_sch_arb_elt_cancel = 0x400014f4; -r_sch_arb_init = 0x400014fc; -r_sch_arb_insert = 0x40001500; -r_sch_arb_prog_timer = 0x40001504; -r_sch_arb_remove = 0x40001508; -r_sch_arb_sw_isr = 0x4000150c; -r_sch_plan_chk = 0x40001510; -r_sch_plan_clock_wrap_offset_update = 0x40001514; -r_sch_plan_init = 0x40001518; -r_sch_plan_interval_req = 0x4000151c; -r_sch_plan_offset_max_calc = 0x40001520; -r_sch_plan_offset_req = 0x40001524; -r_sch_plan_position_range_compute = 0x40001528; -r_sch_plan_rem = 0x4000152c; -r_sch_plan_req = 0x40001530; -r_sch_prog_init = 0x4000153c; -r_sch_prog_push = 0x40001540; -r_sch_prog_rx_isr = 0x40001544; -r_sch_prog_skip_isr = 0x40001548; -r_sch_prog_tx_isr = 0x4000154c; -r_sch_slice_bg_add = 0x40001550; -r_sch_slice_bg_remove = 0x40001554; -r_sch_slice_compute = 0x40001558; -r_sch_slice_fg_add = 0x4000155c; -r_sch_slice_fg_remove = 0x40001560; -r_sch_slice_init = 0x40001564; -r_sch_slice_per_add = 0x40001568; -r_sch_slice_per_remove = 0x4000156c; -r_sdk_config_get_bt_sleep_enable = 0x40001570; -r_sdk_config_get_hl_derived_opts = 0x40001574; -r_sdk_config_get_opts = 0x40001578; -r_sdk_config_get_priv_opts = 0x4000157c; -r_sdk_config_set_bt_sleep_enable = 0x40001580; -r_sdk_config_set_hl_derived_opts = 0x40001584; -r_sdk_config_set_opts = 0x40001588; -r_specialModP256 = 0x4000158c; -r_unloaded_area_init = 0x40001590; -r_vhci_flow_off = 0x40001594; -r_vhci_flow_on = 0x40001598; -r_vhci_notify_host_send_available = 0x4000159c; -r_vhci_send_to_host = 0x400015a0; -r_vnd_hci_command_handler = 0x400015a4; -r_vshci_init = 0x400015a8; -vnd_hci_command_handler_wrapper = 0x400015ac; -/* Data (.data, .bss, .rodata) */ -bt_rf_coex_cfg_p = 0x3fcdffcc; -bt_rf_coex_hooks_p = 0x3fcdffc8; -btdm_env_p = 0x3fcdffc4; -g_rw_controller_task_handle = 0x3fcdffc0; -g_rw_init_sem = 0x3fcdffbc; -g_rw_schd_queue = 0x3fcdffb8; -lld_init_env = 0x3fcdffb4; -lld_rpa_renew_env = 0x3fcdffb0; -lld_scan_env = 0x3fcdffac; -lld_scan_sync_env = 0x3fcdffa8; -lld_test_env = 0x3fcdffa4; -p_ble_util_buf_env = 0x3fcdffa0; -p_lld_env = 0x3fcdff9c; -p_llm_env = 0x3fcdff98; -r_h4tl_eif_p = 0x3fcdff94; -r_hli_funcs_p = 0x3fcdff90; -r_ip_funcs_p = 0x3fcdff8c; -r_modules_funcs_p = 0x3fcdff88; -r_osi_funcs_p = 0x3fcdff84; -r_plf_funcs_p = 0x3fcdff80; -vhci_env_p = 0x3fcdff7c; -aa_gen = 0x3fcdff78; -aes_env = 0x3fcdff6c; -bt_rf_coex_cfg_cb = 0x3fcdff1c; -btdm_pwr_state = 0x3fcdff18; -btdm_slp_err = 0x3fcdff14; -ecc_env = 0x3fcdff0c; -esp_handler = 0x3fcdff04; -esp_vendor_cmd = 0x3fcdfefc; -g_adv_delay_dis = 0x3fcdfef8; -g_conflict_elt = 0x3fcdfef4; -g_eif_api = 0x3fcdfee4; -g_event_empty = 0x3fcdfed8; -g_llc_state = 0x3fcdfecc; -g_llm_state = 0x3fcdfec8; -g_max_evt_env = 0x3fcdfec4; -g_misc_state = 0x3fcdfec0; -g_rma_rule_db = 0x3fcdfea4; -g_rtp_rule_db = 0x3fcdfe88; -g_scan_forever = 0x3fcdfe85; -g_time_msb = 0x3fcdfe84; -h4tl_env = 0x3fcdfe5c; -hci_env = 0x3fcdfe38; -hci_ext_host = 0x3fcdfe34; -hci_fc_env = 0x3fcdfe2c; -hci_tl_env = 0x3fcdfe00; -ke_env = 0x3fcdfdd0; -ke_event_env = 0x3fcdfd90; -ke_task_env = 0x3fcdfd14; -llc_env = 0x3fcdfcec; -lld_adv_env = 0x3fcdfcc4; -lld_con_env = 0x3fcdfc9c; -lld_exp_sync_pos_tab = 0x3fcdfc94; -lld_per_adv_env = 0x3fcdfc6c; -lld_sync_env = 0x3fcdfc44; -llm_le_adv_flow_env = 0x3fcdfc38; -rw_sleep_enable = 0x3fcdfc34; -rwble_env = 0x3fcdfc2c; -rwip_env = 0x3fcdfc10; -rwip_param = 0x3fcdfc04; -rwip_prog_delay = 0x3fcdfc00; -rwip_rf = 0x3fcdfbc8; -sch_alarm_env = 0x3fcdfbc0; -sch_arb_env = 0x3fcdfbac; -sch_plan_env = 0x3fcdfba4; -sch_prog_env = 0x3fcdfaa0; -sch_slice_env = 0x3fcdfa40; -sch_slice_params = 0x3fcdfa38; -timer_env = 0x3fcdfa30; -unloaded_area = 0x3fcdfa2c; -vshci_state = 0x3fcdfa28; -TASK_DESC_LLC = 0x3fcdfa1c; -TASK_DESC_LLM = 0x3fcdfa10; -TASK_DESC_VSHCI = 0x3fcdfa04; -co_default_bdaddr = 0x3fcdf9fc; -dbg_assert_block = 0x3fcdf9f8; -g_bt_plf_log_level = 0x3fcdf9f4; -hci_cmd_desc_tab_vs_esp = 0x3fcdf9d0; -hci_command_handler_tab_esp = 0x3fcdf9b8; -privacy_en = 0x3fcdf9b4; -sdk_cfg_priv_opts = 0x3fcdf96c; -BasePoint_x_256 = 0x3ff1ffdc; -BasePoint_y_256 = 0x3ff1ffbc; -DebugE256PublicKey_x = 0x3ff1ff9c; -DebugE256PublicKey_y = 0x3ff1ff7c; -DebugE256SecretKey = 0x3ff1ff5c; -ECC_4Win_Look_up_table = 0x3ff1f7a0; -LLM_AA_CT1 = 0x3ff1f79c; -LLM_AA_CT2 = 0x3ff1f798; -RF_TX_PW_CONV_TBL = 0x3ff1f790; -TASK_DESC_MISC = 0x3ff1f784; -adv_evt_prop2type = 0x3ff1f768; -adv_evt_type2prop = 0x3ff1f760; -aes_cmac_zero = 0x3ff1f750; -aes_k2_salt = 0x3ff1f740; -aes_k3_id64 = 0x3ff1f738; -aes_k3_salt = 0x3ff1f728; -aes_k4_id6 = 0x3ff1f724; -aes_k4_salt = 0x3ff1f714; -bigHexP256 = 0x3ff1f6e8; -byte_tx_time = 0x3ff1f6e0; -co_null_bdaddr = 0x3ff1f6d8; -co_phy_mask_to_rate = 0x3ff1f6d0; -co_phy_mask_to_value = 0x3ff1f6c8; -co_phy_to_rate = 0x3ff1f6c4; -co_phy_value_to_mask = 0x3ff1f6c0; -co_rate_to_byte_dur_us = 0x3ff1f6b8; -co_rate_to_phy = 0x3ff1f6b0; -co_rate_to_phy_mask = 0x3ff1f6ac; -co_sca2ppm = 0x3ff1f69c; -coef_B = 0x3ff1f670; -connect_req_dur_tab = 0x3ff1f668; -ecc_Jacobian_InfinityPoint256 = 0x3ff1f5e4; -em_base_reg_lut = 0x3ff1f518; -fixed_tx_time = 0x3ff1f510; -h4tl_msgtype2hdrlen = 0x3ff1f508; -hci_cmd_desc_root_tab = 0x3ff1f4d8; -hci_cmd_desc_tab_ctrl_bb = 0x3ff1f46c; -hci_cmd_desc_tab_info_par = 0x3ff1f43c; -hci_cmd_desc_tab_le = 0x3ff1f0a0; -hci_cmd_desc_tab_lk_ctrl = 0x3ff1f088; -hci_cmd_desc_tab_stat_par = 0x3ff1f07c; -hci_cmd_desc_tab_vs = 0x3ff1f040; -hci_evt_desc_tab = 0x3ff1eff8; -hci_evt_le_desc_tab = 0x3ff1ef58; -hci_evt_le_desc_tab_esp = 0x3ff1ef50; -hci_rsvd_evt_msk = 0x3ff1ef48; -lld_aux_phy_to_rate = 0x3ff1ef44; -lld_init_max_aux_dur_tab = 0x3ff1ef3c; -lld_scan_map_legacy_pdu_to_evt_type = 0x3ff1ef34; -lld_scan_max_aux_dur_tab = 0x3ff1ef2c; -lld_sync_max_aux_dur_tab = 0x3ff1ef24; -llm_local_le_feats = 0x3ff1ef1c; -llm_local_le_states = 0x3ff1ef14; -llm_local_supp_cmds = 0x3ff1eeec; -maxSecretKey_256 = 0x3ff1eecc; -max_data_tx_time = 0x3ff1eec4; -one_bits = 0x3ff1eeb4; -rwip_coex_cfg = 0x3ff1eeac; -rwip_priority = 0x3ff1ee94; -veryBigHexP256 = 0x3ff1ee48; - -/* bluetooth hook funcs */ -r_llc_loc_encrypt_proc_continue_hook = 0x40001c60; -r_llc_loc_phy_upd_proc_continue_hook = 0x40001c64; -r_llc_rem_phy_upd_proc_continue_hook = 0x40001c68; -r_lld_scan_frm_eof_isr_hook = 0x40001c6c; -r_lld_scan_evt_start_cbk_hook = 0x40001c70; -r_lld_scan_process_pkt_rx_ext_adv_hook = 0x40001c78; -r_lld_scan_sched_hook = 0x40001c7c; -r_lld_adv_evt_start_cbk_hook = 0x40001c84; -r_lld_adv_aux_evt_start_cbk_hook = 0x40001c88; -r_lld_adv_frm_isr_hook = 0x40001c8c; -r_lld_adv_start_init_evt_param_hook = 0x40001c90; -r_lld_con_evt_canceled_cbk_hook = 0x40001c94; -r_lld_con_frm_isr_hook = 0x40001c98; -r_lld_con_tx_hook = 0x40001c9c; -r_lld_con_rx_hook = 0x40001ca0; -r_lld_con_evt_start_cbk_hook = 0x40001ca4; -r_lld_con_tx_prog_new_packet_hook = 0x40001cac; -r_lld_init_frm_eof_isr_hook = 0x40001cb0; -r_lld_init_evt_start_cbk_hook = 0x40001cb4; -r_lld_init_sched_hook = 0x40001cbc; -r_lld_init_process_pkt_tx_hook = 0x40001cc0; -r_lld_per_adv_evt_start_cbk_hook = 0x40001cc4; -r_lld_per_adv_frm_isr_hook = 0x40001cc8; -r_lld_per_adv_start_hook = 0x40001ccc; -r_lld_sync_frm_eof_isr_hook = 0x40001cd0; -r_lld_sync_evt_start_cbk_hook = 0x40001cd4; -r_lld_sync_start_hook = 0x40001cd8; -r_lld_sync_process_pkt_rx_pkt_check_hook = 0x40001cdc; -r_sch_arb_insert_hook = 0x40001ce0; -r_sch_plan_offset_req_hook = 0x40001ce4; - -/*************************************** - Group rom_pp - ***************************************/ - -/* Functions */ -esp_pp_rom_version_get = 0x400015b0; -RC_GetBlockAckTime = 0x400015b4; -ebuf_list_remove = 0x400015b8; -/*esf_buf_alloc = 0x400015bc;*/ -GetAccess = 0x400015c8; -hal_mac_is_low_rate_enabled = 0x400015cc; -hal_mac_tx_get_blockack = 0x400015d0; -/* hal_mac_tx_set_ppdu = 0x400015d4;*/ -ic_get_trc = 0x400015d8; -/* ic_mac_deinit = 0x400015dc; */ -ic_mac_init = 0x400015e0; -ic_interface_enabled = 0x400015e4; -is_lmac_idle = 0x400015e8; -/*lmacAdjustTimestamp = 0x400015ec;*/ -lmacDiscardAgedMSDU = 0x400015f0; -/*lmacDiscardMSDU = 0x400015f4;*/ -lmacEndFrameExchangeSequence = 0x400015f8; -lmacIsIdle = 0x400015fc; -lmacIsLongFrame = 0x40001600; -/*lmacMSDUAged = 0x40001604;*/ -lmacPostTxComplete = 0x40001608; -lmacProcessAllTxTimeout = 0x4000160c; -lmacProcessCollisions = 0x40001610; -lmacProcessRxSucData = 0x40001614; -lmacReachLongLimit = 0x40001618; -lmacReachShortLimit = 0x4000161c; -lmacRecycleMPDU = 0x40001620; -lmacRxDone = 0x40001624; -/*lmacSetTxFrame = 0x40001628;*/ -/*lmacTxFrame = 0x40001630;*/ -mac_tx_set_duration = 0x40001634; -/* mac_tx_set_htsig = 0x40001638;*/ -mac_tx_set_plcp0 = 0x4000163c; -/* mac_tx_set_plcp1 = 0x40001640;*/ -mac_tx_set_plcp2 = 0x40001644; -/* pm_check_state = 0x40001648; */ -pm_disable_dream_timer = 0x4000164c; -pm_disable_sleep_delay_timer = 0x40001650; -pm_dream = 0x40001654; -pm_mac_wakeup = 0x40001658; -pm_mac_sleep = 0x4000165c; -pm_enable_active_timer = 0x40001660; -pm_enable_sleep_delay_timer = 0x40001664; -pm_local_tsf_process = 0x40001668; -pm_set_beacon_filter = 0x4000166c; -pm_is_in_wifi_slice_threshold = 0x40001670; -pm_is_waked = 0x40001674; -pm_keep_alive = 0x40001678; -/* pm_on_beacon_rx = 0x4000167c; */ -pm_on_data_rx = 0x40001680; -pm_on_tbtt = 0x40001684; -/* pm_parse_beacon = 0x40001688;*/ -/* pm_process_tim = 0x4000168c; */ -/*pm_rx_beacon_process = 0x40001690;*/ -/* pm_rx_data_process = 0x40001694; */ -/*pm_sleep = 0x40001698;*/ -pm_sleep_for = 0x4000169c; -/* pm_tbtt_process = 0x400016a0; */ -ppAMPDU2Normal = 0x400016a4; -/*ppAssembleAMPDU = 0x400016a8;*/ -ppCalFrameTimes = 0x400016ac; -ppCalSubFrameLength = 0x400016b0; -/*ppCalTxAMPDULength = 0x400016b4;*/ -ppCheckTxAMPDUlength = 0x400016b8; -ppDequeueRxq_Locked = 0x400016bc; -ppDequeueTxQ = 0x400016c0; -ppEmptyDelimiterLength = 0x400016c4; -ppEnqueueRxq = 0x400016c8; -ppEnqueueTxDone = 0x400016cc; -ppGetTxQFirstAvail_Locked = 0x400016d0; -ppGetTxframe = 0x400016d4; -ppProcessRxPktHdr = 0x400016e0; -ppProcessTxQ = 0x400016e4; -ppRecordBarRRC = 0x400016e8; -lmacRequestTxopQueue = 0x400016ec; -lmacReleaseTxopQueue = 0x400016f0; -ppRecycleAmpdu = 0x400016f4; -ppRecycleRxPkt = 0x400016f8; -ppResortTxAMPDU = 0x400016fc; -ppResumeTxAMPDU = 0x40001700; -/* ppRxFragmentProc = 0x40001704; */ -/* ppRxPkt = 0x40001708; */ -ppRxProtoProc = 0x4000170c; -ppSearchTxQueue = 0x40001710; -ppSearchTxframe = 0x40001714; -ppSelectNextQueue = 0x40001718; -ppSubFromAMPDU = 0x4000171c; -ppTask = 0x40001720; -ppTxPkt = 0x40001724; -ppTxProtoProc = 0x40001728; -ppTxqUpdateBitmap = 0x4000172c; -pp_coex_tx_request = 0x40001730; -pp_hdrsize = 0x40001734; -pp_post = 0x40001738; -pp_process_hmac_waiting_txq = 0x4000173c; -rcGetAmpduSched = 0x40001740; -rcUpdateRxDone = 0x40001744; -rc_get_trc = 0x40001748; -rc_get_trc_by_index = 0x4000174c; -rcAmpduLowerRate = 0x40001750; -rcampduuprate = 0x40001754; -rcClearCurAMPDUSched = 0x40001758; -rcClearCurSched = 0x4000175c; -rcClearCurStat = 0x40001760; -rcLowerSched = 0x40001768; -rcSetTxAmpduLimit = 0x4000176c; -/* rcTxUpdatePer = 0x40001770;*/ -rcUpdateAckSnr = 0x40001774; -/*rcUpdateRate = 0x40001778;*/ -/* rcUpdateTxDone = 0x4000177c; */ -rcUpdateTxDoneAmpdu2 = 0x40001780; -rcUpSched = 0x40001784; -rssi_margin = 0x40001788; -rx11NRate2AMPDULimit = 0x4000178c; -TRC_AMPDU_PER_DOWN_THRESHOLD = 0x40001790; -TRC_AMPDU_PER_UP_THRESHOLD = 0x40001794; -trc_calc_duration = 0x40001798; -trc_isTxAmpduOperational = 0x4000179c; -trc_onAmpduOp = 0x400017a0; -TRC_PER_IS_GOOD = 0x400017a4; -trc_SetTxAmpduState = 0x400017a8; -trc_tid_isTxAmpduOperational = 0x400017ac; -trcAmpduSetState = 0x400017b0; -wDev_AppendRxBlocks = 0x400017b8; -wDev_DiscardFrame = 0x400017bc; -wDev_GetNoiseFloor = 0x400017c0; -wDev_IndicateAmpdu = 0x400017c4; -/*wDev_IndicateFrame = 0x400017c8;*/ -wdev_bank_store = 0x400017cc; -wdev_bank_load = 0x400017d0; -wdev_mac_reg_load = 0x400017d4; -wdev_mac_reg_store = 0x400017d8; -wdev_mac_special_reg_load = 0x400017dc; -wdev_mac_special_reg_store = 0x400017e0; -wdev_mac_wakeup = 0x400017e4; -wdev_mac_sleep = 0x400017e8; -hal_mac_is_dma_enable = 0x400017ec; -/*wDev_ProcessFiq = 0x400017f0;*/ -/*wDev_ProcessRxSucData = 0x400017f4;*/ -wdevProcessRxSucDataAll = 0x400017f8; -wdev_csi_len_align = 0x400017fc; -ppDequeueTxDone_Locked = 0x40001800; -/*pm_tx_data_done_process = 0x40001808;*/ -config_is_cache_tx_buf_enabled = 0x4000180c; -//ppMapWaitTxq = 0x40001810; -ppProcessWaitingQueue = 0x40001814; -ppDisableQueue = 0x40001818; -pm_allow_tx = 0x4000181c; -/* Data (.data, .bss, .rodata) */ -our_instances_ptr = 0x3ff1ee44; -pTxRx = 0x3fcdf968; -lmacConfMib_ptr = 0x3fcdf964; -our_wait_eb = 0x3fcdf960; -our_tx_eb = 0x3fcdf95c; -pp_wdev_funcs = 0x3fcdf958; -g_osi_funcs_p = 0x3fcdf954; -wDevCtrl_ptr = 0x3fcdf950; -g_wdev_last_desc_reset_ptr = 0x3ff1ee40; -wDevMacSleep_ptr = 0x3fcdf94c; -g_lmac_cnt_ptr = 0x3fcdf948; -our_controls_ptr = 0x3ff1ee3c; -pp_sig_cnt_ptr = 0x3fcdf944; -g_eb_list_desc_ptr = 0x3fcdf940; -s_fragment_ptr = 0x3fcdf93c; -if_ctrl_ptr = 0x3fcdf938; -g_intr_lock_mux = 0x3fcdf934; -g_wifi_global_lock = 0x3fcdf930; -s_wifi_queue = 0x3fcdf92c; -pp_task_hdl = 0x3fcdf928; -s_pp_task_create_sem = 0x3fcdf924; -s_pp_task_del_sem = 0x3fcdf920; -g_wifi_menuconfig_ptr = 0x3fcdf91c; -xphyQueue = 0x3fcdf918; -ap_no_lr_ptr = 0x3fcdf914; -rc11BSchedTbl_ptr = 0x3fcdf910; -rc11NSchedTbl_ptr = 0x3fcdf90c; -rcLoRaSchedTbl_ptr = 0x3fcdf908; -BasicOFDMSched_ptr = 0x3fcdf904; -trc_ctl_ptr = 0x3fcdf900; -g_pm_cnt_ptr = 0x3fcdf8fc; -g_pm_ptr = 0x3fcdf8f8; -g_pm_cfg_ptr = 0x3fcdf8f4; -g_esp_mesh_quick_funcs_ptr = 0x3fcdf8f0; -g_txop_queue_status_ptr = 0x3fcdf8ec; -g_mac_sleep_en_ptr = 0x3fcdf8e8; -g_mesh_is_root_ptr = 0x3fcdf8e4; -g_mesh_topology_ptr = 0x3fcdf8e0; -g_mesh_init_ps_type_ptr = 0x3fcdf8dc; -g_mesh_is_started_ptr = 0x3fcdf8d8; -g_config_func = 0x3fcdf8d4; -g_net80211_tx_func = 0x3fcdf8d0; -g_timer_func = 0x3fcdf8cc; -s_michael_mic_failure_cb = 0x3fcdf8c8; -wifi_sta_rx_probe_req = 0x3fcdf8c4; -g_tx_done_cb_func = 0x3fcdf8c0; -g_per_conn_trc = 0x3fcdf874; -s_encap_amsdu_func = 0x3fcdf870; - - -/*************************************** - Group rom_net80211 - ***************************************/ - -/* Functions */ -esp_net80211_rom_version_get = 0x40001820; -ampdu_dispatch = 0x40001824; -ampdu_dispatch_all = 0x40001828; -ampdu_dispatch_as_many_as_possible = 0x4000182c; -ampdu_dispatch_movement = 0x40001830; -ampdu_dispatch_upto = 0x40001834; -chm_is_at_home_channel = 0x40001838; -cnx_node_is_existing = 0x4000183c; -cnx_node_search = 0x40001840; -ic_ebuf_recycle_rx = 0x40001844; -ic_ebuf_recycle_tx = 0x40001848; -ic_reset_rx_ba = 0x4000184c; -ieee80211_align_eb = 0x40001850; -ieee80211_ampdu_reorder = 0x40001854; -ieee80211_ampdu_start_age_timer = 0x40001858; -/*ieee80211_encap_esfbuf = 0x4000185c;*/ -ieee80211_is_tx_allowed = 0x40001860; -ieee80211_output_pending_eb = 0x40001864; -/*ieee80211_output_process = 0x40001868;*/ -ieee80211_set_tx_desc = 0x4000186c; -rom_sta_input = 0x40001870; -wifi_get_macaddr = 0x40001874; -wifi_rf_phy_disable = 0x40001878; -wifi_rf_phy_enable = 0x4000187c; -ic_ebuf_alloc = 0x40001880; -ieee80211_classify = 0x40001884; -ieee80211_copy_eb_header = 0x40001888; -ieee80211_recycle_cache_eb = 0x4000188c; -ieee80211_search_node = 0x40001890; -roundup2 = 0x40001894; -ieee80211_crypto_encap = 0x40001898; -/* ieee80211_crypto_decap = 0x4000189c; */ -/* ieee80211_decap = 0x400018a0; */ -ieee80211_set_tx_pti = 0x400018a4; -wifi_is_started = 0x400018a8; -/* Data (.data, .bss, .rodata) */ -net80211_funcs = 0x3fcdf86c; -g_scan = 0x3fcdf868; -g_chm = 0x3fcdf864; -g_ic_ptr = 0x3fcdf860; -g_hmac_cnt_ptr = 0x3fcdf85c; -g_tx_cacheq_ptr = 0x3fcdf858; -s_netstack_free = 0x3fcdf854; -mesh_rxcb = 0x3fcdf850; -sta_rxcb = 0x3fcdf84c; - - -/*************************************** - Group rom_coexist - ***************************************/ - -/* Functions */ -esp_coex_rom_version_get = 0x400018ac; -coex_bt_release = 0x400018b0; -coex_bt_request = 0x400018b4; -coex_core_ble_conn_dyn_prio_get = 0x400018b8; -coex_core_event_duration_get = 0x400018bc; -coex_core_pti_get = 0x400018c0; -coex_core_release = 0x400018c4; -coex_core_request = 0x400018c8; -coex_core_status_get = 0x400018cc; -/*coex_core_timer_idx_get = 0x400018d0;*/ -coex_event_duration_get = 0x400018d4; -coex_hw_timer_disable = 0x400018d8; -coex_hw_timer_enable = 0x400018dc; -coex_hw_timer_set = 0x400018e0; -coex_schm_interval_set = 0x400018e4; -coex_schm_lock = 0x400018e8; -coex_schm_unlock = 0x400018ec; -coex_status_get = 0x400018f0; -coex_wifi_release = 0x400018f4; -esp_coex_ble_conn_dynamic_prio_get = 0x400018f8; -/* Data (.data, .bss, .rodata) */ -coex_env_ptr = 0x3fcdf848; -coex_pti_tab_ptr = 0x3fcdf844; -coex_schm_env_ptr = 0x3fcdf840; -coexist_funcs = 0x3fcdf83c; -g_coa_funcs_p = 0x3fcdf838; -g_coex_param_ptr = 0x3fcdf834; - - -/*************************************** - Group rom_phy - ***************************************/ - -/* Functions */ -phy_get_romfuncs = 0x400018fc; -rom_abs_temp = 0x40001900; -rom_bb_bss_cbw40_dig = 0x40001904; -rom_bb_wdg_test_en = 0x40001908; -rom_bb_wdt_get_status = 0x4000190c; -rom_bb_wdt_int_enable = 0x40001910; -rom_bb_wdt_rst_enable = 0x40001914; -rom_bb_wdt_timeout_clear = 0x40001918; -rom_cbw2040_cfg = 0x4000191c; -rom_check_noise_floor = 0x40001920; -rom_chip_i2c_readReg = 0x40001924; -rom_chip_i2c_writeReg = 0x40001928; -rom_correct_rf_ana_gain = 0x4000192c; -rom_dc_iq_est = 0x40001930; -rom_disable_agc = 0x40001934; -rom_en_pwdet = 0x40001938; -rom_enable_agc = 0x4000193c; -rom_get_bbgain_db = 0x40001940; -rom_get_data_sat = 0x40001944; -rom_get_i2c_read_mask = 0x40001948; -rom_get_pwctrl_correct = 0x4000194c; -rom_get_rf_gain_qdb = 0x40001950; -rom_i2c_readReg = 0x40001954; -rom_i2c_readReg_Mask = 0x40001958; -rom_i2c_writeReg = 0x4000195c; -rom_i2c_writeReg_Mask = 0x40001960; -/* rom_index_to_txbbgain = 0x40001964; */ -rom_iq_est_disable = 0x40001968; -rom_iq_est_enable = 0x4000196c; -rom_linear_to_db = 0x40001970; -rom_loopback_mode_en = 0x40001974; -rom_mhz2ieee = 0x40001978; -rom_noise_floor_auto_set = 0x4000197c; -rom_pbus_debugmode = 0x40001980; -rom_pbus_force_mode = 0x40001984; -rom_pbus_force_test = 0x40001988; -rom_pbus_rd = 0x4000198c; -rom_pbus_rd_addr = 0x40001990; -rom_pbus_rd_shift = 0x40001994; -rom_pbus_set_dco = 0x40001998; -rom_pbus_set_rxgain = 0x4000199c; -rom_pbus_workmode = 0x400019a0; -rom_pbus_xpd_rx_off = 0x400019a4; -rom_pbus_xpd_rx_on = 0x400019a8; -rom_pbus_xpd_tx_off = 0x400019ac; -/* rom_pbus_xpd_tx_on = 0x400019b0; */ -rom_phy_byte_to_word = 0x400019b4; -rom_phy_disable_cca = 0x400019b8; -rom_phy_enable_cca = 0x400019bc; -rom_phy_get_noisefloor = 0x400019c0; -rom_phy_get_rx_freq = 0x400019c4; -rom_phy_set_bbfreq_init = 0x400019c8; -rom_pow_usr = 0x400019cc; -rom_pwdet_sar2_init = 0x400019d0; -rom_read_hw_noisefloor = 0x400019d4; -rom_read_sar_dout = 0x400019d8; -rom_set_cal_rxdc = 0x400019dc; -rom_set_chan_cal_interp = 0x400019e0; -rom_set_loopback_gain = 0x400019e4; -rom_set_noise_floor = 0x400019e8; -rom_set_rxclk_en = 0x400019ec; -/* rom_set_tx_dig_gain = 0x400019f0; */ -/* rom_set_txcap_reg = 0x400019f4; */ -rom_set_txclk_en = 0x400019f8; -rom_spur_cal = 0x400019fc; -rom_spur_reg_write_one_tone = 0x40001a00; -rom_target_power_add_backoff = 0x40001a04; -rom_tx_pwctrl_bg_init = 0x40001a08; -/* rom_txbbgain_to_index = 0x40001a0c; */ -rom_wifi_11g_rate_chg = 0x40001a10; -rom_write_gain_mem = 0x40001a14; -chip726_phyrom_version = 0x40001a18; -rom_disable_wifi_agc = 0x40001a1c; -rom_enable_wifi_agc = 0x40001a20; -rom_set_tx_gain_table = 0x40001a24; -rom_bt_index_to_bb = 0x40001a28; -rom_bt_bb_to_index = 0x40001a2c; -rom_wr_bt_tx_atten = 0x40001a30; -rom_wr_bt_tx_gain_mem = 0x40001a34; -rom_spur_coef_cfg = 0x40001a38; -rom_bb_bss_cbw40 = 0x40001a3c; -rom_set_cca = 0x40001a40; -rom_tx_paon_set = 0x40001a44; -rom_i2cmst_reg_init = 0x40001a48; -rom_iq_corr_enable = 0x40001a4c; -rom_fe_reg_init = 0x40001a50; -/* rom_agc_reg_init = 0x40001a54; */ -/* rom_bb_reg_init = 0x40001a58; */ -rom_mac_enable_bb = 0x40001a5c; -rom_bb_wdg_cfg = 0x40001a60; -rom_force_txon = 0x40001a64; -rom_fe_txrx_reset = 0x40001a68; -rom_set_rx_comp = 0x40001a6c; -/* rom_set_pbus_reg = 0x40001a70; */ -rom_write_chan_freq = 0x40001a74; -/* rom_phy_xpd_rf = 0x40001a78; */ -rom_set_xpd_sar = 0x40001a7c; -rom_write_dac_gain2 = 0x40001a80; -rom_rtc_sar2_init = 0x40001a84; -rom_get_target_power_offset = 0x40001a88; -/* rom_write_txrate_power_offset = 0x40001a8c; */ -rom_get_rate_fcc_index = 0x40001a90; -rom_get_rate_target_power = 0x40001a94; -rom_write_wifi_dig_gain = 0x40001a98; -rom_bt_correct_rf_ana_gain = 0x40001a9c; -rom_pkdet_vol_start = 0x40001aa0; -rom_read_sar2_code = 0x40001aa4; -rom_get_sar2_vol = 0x40001aa8; -rom_get_pll_vol = 0x40001aac; -rom_get_phy_target_power = 0x40001ab0; -/* rom_temp_to_power = 0x40001ab4; */ -rom_phy_track_pll_cap = 0x40001ab8; -rom_phy_pwdet_always_en = 0x40001abc; -rom_phy_pwdet_onetime_en = 0x40001ac0; -rom_get_i2c_mst0_mask = 0x40001ac4; -rom_get_i2c_hostid = 0x40001ac8; -rom_enter_critical_phy = 0x40001acc; -rom_exit_critical_phy = 0x40001ad0; -rom_chip_i2c_readReg_org = 0x40001ad4; -rom_i2c_paral_set_mst0 = 0x40001ad8; -rom_i2c_paral_set_read = 0x40001adc; -rom_i2c_paral_read = 0x40001ae0; -rom_i2c_paral_write = 0x40001ae4; -rom_i2c_paral_write_num = 0x40001ae8; -rom_i2c_paral_write_mask = 0x40001aec; -rom_bb_bss_cbw40_ana = 0x40001af0; -rom_chan_to_freq = 0x40001af4; -/* rom_open_i2c_xpd = 0x40001af8; */ -rom_dac_rate_set = 0x40001afc; -/* rom_tsens_read_init = 0x40001b00; */ -/* rom_tsens_code_read = 0x40001b04; */ -rom_tsens_index_to_dac = 0x40001b08; -rom_tsens_index_to_offset = 0x40001b0c; -/* rom_tsens_dac_cal = 0x40001b10; */ -rom_code_to_temp = 0x40001b14; -rom_write_pll_cap_mem = 0x40001b18; -rom_pll_correct_dcap = 0x40001b1c; -rom_phy_en_hw_set_freq = 0x40001b20; -rom_phy_dis_hw_set_freq = 0x40001b24; -/* rom_pll_vol_cal = 0x40001b28; */ From 8ecbfe9ade19c02ee0d43e753b0d99f36666a517 Mon Sep 17 00:00:00 2001 From: Haolan Date: Mon, 1 Sep 2025 16:33:19 +0800 Subject: [PATCH 32/46] feat: support arm/risc64/avr for compiler rt --- internal/crosscompile/compile/compile.go | 1 - .../crosscompile/compile/rtlib/compiler_rt.go | 72 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/internal/crosscompile/compile/compile.go b/internal/crosscompile/compile/compile.go index 20b52aa1..20f72e2c 100644 --- a/internal/crosscompile/compile/compile.go +++ b/internal/crosscompile/compile/compile.go @@ -54,7 +54,6 @@ func (g CompileGroup) Compile(outputDir, cc, linkerName string, extraCCFlags, ex if err != nil { return } - fmt.Fprintf(os.Stderr, "Compile file %s to %s...\n", file, tempObjFile.Name()) lang := "c" if filepath.Ext(file) == ".S" { diff --git a/internal/crosscompile/compile/rtlib/compiler_rt.go b/internal/crosscompile/compile/rtlib/compiler_rt.go index 6446e9b9..7e165241 100644 --- a/internal/crosscompile/compile/rtlib/compiler_rt.go +++ b/internal/crosscompile/compile/rtlib/compiler_rt.go @@ -8,6 +8,11 @@ import ( "github.com/goplus/llgo/internal/crosscompile/compile" ) +// Builtins needed specifically for windows/386. +var windowsI386Builtins = []string{ + "i386/chkstk.S", // also _alloca +} + func platformSpecifiedFiles(builtinsDir, target string) []string { switch { case strings.Contains(target, "riscv32"): @@ -17,6 +22,73 @@ func platformSpecifiedFiles(builtinsDir, target string) []string { filepath.Join(builtinsDir, "riscv", "save.S"), filepath.Join(builtinsDir, "riscv", "restore.S"), } + case strings.Contains(target, "riscv64"): + return []string{ + "addtf3.c", + "comparetf2.c", + "divtc3.c", + "divtf3.c", + "extenddftf2.c", + "extendhftf2.c", + "extendsftf2.c", + "fixtfdi.c", + "fixtfsi.c", + "fixtfti.c", + "fixunstfdi.c", + "fixunstfsi.c", + "fixunstfti.c", + "floatditf.c", + "floatsitf.c", + "floattitf.c", + "floatunditf.c", + "floatunsitf.c", + "floatuntitf.c", + "multc3.c", + "multf3.c", + "powitf2.c", + "subtf3.c", + "trunctfdf2.c", + "trunctfhf2.c", + "trunctfsf2.c", + } + case strings.Contains(target, "arm"): + return []string{ + filepath.Join(builtinsDir, "arm", "aeabi_cdcmp.S"), + filepath.Join(builtinsDir, "arm", "aeabi_cdcmpeq_check_nan.c"), + filepath.Join(builtinsDir, "arm", "aeabi_cfcmp.S"), + filepath.Join(builtinsDir, "arm", "aeabi_cfcmpeq_check_nan.c"), + filepath.Join(builtinsDir, "arm", "aeabi_dcmp.S"), + filepath.Join(builtinsDir, "arm", "aeabi_div0.c"), + filepath.Join(builtinsDir, "arm", "aeabi_drsub.c"), + filepath.Join(builtinsDir, "arm", "aeabi_fcmp.S"), + filepath.Join(builtinsDir, "arm", "aeabi_frsub.c"), + filepath.Join(builtinsDir, "arm", "aeabi_idivmod.S"), + filepath.Join(builtinsDir, "arm", "aeabi_ldivmod.S"), + filepath.Join(builtinsDir, "arm", "aeabi_memcmp.S"), + filepath.Join(builtinsDir, "arm", "aeabi_memcpy.S"), + filepath.Join(builtinsDir, "arm", "aeabi_memmove.S"), + filepath.Join(builtinsDir, "arm", "aeabi_memset.S"), + filepath.Join(builtinsDir, "arm", "aeabi_uidivmod.S"), + filepath.Join(builtinsDir, "arm", "aeabi_uldivmod.S"), + + // These two are not technically EABI builtins but are used by them and only + // seem to be used on ARM. LLVM seems to use __divsi3 and __modsi3 on most + // other architectures. + // Most importantly, they have a different calling convention on AVR so + // should not be used on AVR. + filepath.Join(builtinsDir, "divmodsi4.c"), + filepath.Join(builtinsDir, "udivmodsi4.c"), + } + case strings.Contains(target, "avr"): + return []string{ + filepath.Join("avr", "divmodhi4.S"), + filepath.Join("avr", "divmodqi4.S"), + filepath.Join("avr", "mulhi3.S"), + filepath.Join("avr", "mulqi3.S"), + filepath.Join("avr", "udivmodhi4.S"), + filepath.Join("avr", "udivmodqi4.S"), + } + case target == "xtensa": return []string{ filepath.Join(builtinsDir, "xtensa", "ieee754_sqrtf.S"), From 96c5ce90e4f225f24a13c4e3e09a26d69c5f2355 Mon Sep 17 00:00:00 2001 From: Haolan Date: Mon, 1 Sep 2025 16:36:58 +0800 Subject: [PATCH 33/46] fix: compiler rt file path --- .../crosscompile/compile/rtlib/compiler_rt.go | 69 +++++++++---------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/internal/crosscompile/compile/rtlib/compiler_rt.go b/internal/crosscompile/compile/rtlib/compiler_rt.go index 7e165241..1a1e403a 100644 --- a/internal/crosscompile/compile/rtlib/compiler_rt.go +++ b/internal/crosscompile/compile/rtlib/compiler_rt.go @@ -8,11 +8,6 @@ import ( "github.com/goplus/llgo/internal/crosscompile/compile" ) -// Builtins needed specifically for windows/386. -var windowsI386Builtins = []string{ - "i386/chkstk.S", // also _alloca -} - func platformSpecifiedFiles(builtinsDir, target string) []string { switch { case strings.Contains(target, "riscv32"): @@ -24,32 +19,32 @@ func platformSpecifiedFiles(builtinsDir, target string) []string { } case strings.Contains(target, "riscv64"): return []string{ - "addtf3.c", - "comparetf2.c", - "divtc3.c", - "divtf3.c", - "extenddftf2.c", - "extendhftf2.c", - "extendsftf2.c", - "fixtfdi.c", - "fixtfsi.c", - "fixtfti.c", - "fixunstfdi.c", - "fixunstfsi.c", - "fixunstfti.c", - "floatditf.c", - "floatsitf.c", - "floattitf.c", - "floatunditf.c", - "floatunsitf.c", - "floatuntitf.c", - "multc3.c", - "multf3.c", - "powitf2.c", - "subtf3.c", - "trunctfdf2.c", - "trunctfhf2.c", - "trunctfsf2.c", + filepath.Join(builtinsDir, "addtf3.c"), + filepath.Join(builtinsDir, "comparetf2.c"), + filepath.Join(builtinsDir, "divtc3.c"), + filepath.Join(builtinsDir, "divtf3.c"), + filepath.Join(builtinsDir, "extenddftf2.c"), + filepath.Join(builtinsDir, "extendhftf2.c"), + filepath.Join(builtinsDir, "extendsftf2.c"), + filepath.Join(builtinsDir, "fixtfdi.c"), + filepath.Join(builtinsDir, "fixtfsi.c"), + filepath.Join(builtinsDir, "fixtfti.c"), + filepath.Join(builtinsDir, "fixunstfdi.c"), + filepath.Join(builtinsDir, "fixunstfsi.c"), + filepath.Join(builtinsDir, "fixunstfti.c"), + filepath.Join(builtinsDir, "floatditf.c"), + filepath.Join(builtinsDir, "floatsitf.c"), + filepath.Join(builtinsDir, "floattitf.c"), + filepath.Join(builtinsDir, "floatunditf.c"), + filepath.Join(builtinsDir, "floatunsitf.c"), + filepath.Join(builtinsDir, "floatuntitf.c"), + filepath.Join(builtinsDir, "multc3.c"), + filepath.Join(builtinsDir, "multf3.c"), + filepath.Join(builtinsDir, "powitf2.c"), + filepath.Join(builtinsDir, "subtf3.c"), + filepath.Join(builtinsDir, "trunctfdf2.c"), + filepath.Join(builtinsDir, "trunctfhf2.c"), + filepath.Join(builtinsDir, "trunctfsf2.c"), } case strings.Contains(target, "arm"): return []string{ @@ -81,12 +76,12 @@ func platformSpecifiedFiles(builtinsDir, target string) []string { } case strings.Contains(target, "avr"): return []string{ - filepath.Join("avr", "divmodhi4.S"), - filepath.Join("avr", "divmodqi4.S"), - filepath.Join("avr", "mulhi3.S"), - filepath.Join("avr", "mulqi3.S"), - filepath.Join("avr", "udivmodhi4.S"), - filepath.Join("avr", "udivmodqi4.S"), + filepath.Join(builtinsDir, "avr", "divmodhi4.S"), + filepath.Join(builtinsDir, "avr", "divmodqi4.S"), + filepath.Join(builtinsDir, "avr", "mulhi3.S"), + filepath.Join(builtinsDir, "avr", "mulqi3.S"), + filepath.Join(builtinsDir, "avr", "udivmodhi4.S"), + filepath.Join(builtinsDir, "avr", "udivmodqi4.S"), } case target == "xtensa": From 5997a296c22c884c239d01713bca66e761a6b1f3 Mon Sep 17 00:00:00 2001 From: Haolan Date: Mon, 1 Sep 2025 16:54:12 +0800 Subject: [PATCH 34/46] fix: update url --- internal/crosscompile/compile/libc/newlibesp.go | 3 +-- internal/crosscompile/crosscompile.go | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/internal/crosscompile/compile/libc/newlibesp.go b/internal/crosscompile/compile/libc/newlibesp.go index 1c0e4760..86e5651a 100644 --- a/internal/crosscompile/compile/libc/newlibesp.go +++ b/internal/crosscompile/compile/libc/newlibesp.go @@ -1073,7 +1073,7 @@ func getNewlibESP32ConfigXtensa(baseDir, target string) *compile.CompileConfig { libcDir := filepath.Join(baseDir, "newlib", "libc") return &compile.CompileConfig{ - Url: "https://github.com/goplus/newlib/archive/refs/tags/v0.1.0.tar.gz", + Url: "https://github.com/goplus/newlib/archive/refs/tags/v0.2.0.tar.gz", Name: "newlib-esp32", Groups: []compile.CompileGroup{ { @@ -2053,7 +2053,6 @@ func getNewlibESP32ConfigXtensa(baseDir, target string) *compile.CompileConfig { // getNewlibESP32Config returns configuration for newlib esp32 func GetNewlibESP32Config(baseDir, target, mcpu string) *compile.CompileConfig { if strings.Contains(target, "riscv32") { - fmt.Println(target) return getNewlibESP32ConfigRISCV(baseDir, target) } return getNewlibESP32ConfigXtensa(baseDir, target) diff --git a/internal/crosscompile/crosscompile.go b/internal/crosscompile/crosscompile.go index 3c8285ca..a53fff57 100644 --- a/internal/crosscompile/crosscompile.go +++ b/internal/crosscompile/crosscompile.go @@ -317,12 +317,12 @@ func use(goos, goarch string, wasiThreads bool) (export Export, err error) { export.CCFLAGS = append( export.CCFLAGS, "-fdata-sections", - // "-ffunction-sections", + "-ffunction-sections", ) export.LDFLAGS = append( export.LDFLAGS, "-fdata-sections", - // "-ffunction-sections", + "-ffunction-sections", "-Xlinker", "--gc-sections", "-lm", From cb2fa5dd2df927f5e79ff114dbf81153d800aacb Mon Sep 17 00:00:00 2001 From: Haolan Date: Mon, 1 Sep 2025 17:19:32 +0800 Subject: [PATCH 35/46] fix: picolibc.h --- internal/crosscompile/compile/libc/picolibc.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/internal/crosscompile/compile/libc/picolibc.go b/internal/crosscompile/compile/libc/picolibc.go index a7efa2da..0e35d9a4 100644 --- a/internal/crosscompile/compile/libc/picolibc.go +++ b/internal/crosscompile/compile/libc/picolibc.go @@ -2,7 +2,6 @@ package libc import ( "fmt" - "os" "path/filepath" "github.com/goplus/llgo/internal/crosscompile/compile" @@ -14,13 +13,8 @@ func GetPicolibcConfig(baseDir, target string) *compile.CompileConfig { libmIncludeDir := filepath.Join(baseDir, "libm", "common") localeIncludeDir := filepath.Join(baseDir, "libc", "locale") - os.MkdirAll(baseDir, 0700) - - headerFile, _ := os.Create(filepath.Join(baseDir, "picolibc.h")) - headerFile.Close() - return &compile.CompileConfig{ - Url: "https://github.com/picolibc/picolibc/releases/download/1.8.10/picolibc-1.8.10.tar.xz", + Url: "https://github.com/goplus/picolibc/archive/refs/heads/main.zip", Name: "picolibc", Groups: []compile.CompileGroup{ { @@ -164,6 +158,6 @@ func GetPicolibcConfig(baseDir, target string) *compile.CompileConfig { }, }, }, - ArchiveSrcDir: filepath.Join("picolibc-1.8.10", "newlib"), + ArchiveSrcDir: filepath.Join("picolibc-main", "newlib"), } } From 0cac1c8a9db243324ccff7ad6aa96e0540c540e0 Mon Sep 17 00:00:00 2001 From: Li Jie Date: Mon, 1 Sep 2025 20:18:31 +0800 Subject: [PATCH 36/46] fix #1252 check LLGO_ROOT with pkg github.com/goplus/llgo/runtime --- internal/env/env.go | 4 ++-- internal/env/env_test.go | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/internal/env/env.go b/internal/env/env.go index 5d602e90..3f6feec8 100644 --- a/internal/env/env.go +++ b/internal/env/env.go @@ -97,12 +97,12 @@ func isLLGoRoot(root string) (string, bool) { return "", false } // Check for go.mod - data, err := os.ReadFile(filepath.Join(root, "go.mod")) + data, err := os.ReadFile(filepath.Join(root, LLGoRuntimePkgName, "go.mod")) if err != nil { return "", false } // Check module name - if !strings.Contains(string(data), "module "+LLGoCompilerPkg+"\n") { + if !strings.Contains(string(data), "module "+LLGoRuntimePkg+"\n") { return "", false } return root, true diff --git a/internal/env/env_test.go b/internal/env/env_test.go index 0a0d43f2..80773cad 100644 --- a/internal/env/env_test.go +++ b/internal/env/env_test.go @@ -41,8 +41,10 @@ func TestLLGoRuntimeDir(t *testing.T) { defer os.Setenv("LLGO_ROOT", origLLGoRoot) tmpDir := t.TempDir() - goModContent := []byte("module github.com/goplus/llgo\n") - if err := os.WriteFile(filepath.Join(tmpDir, "go.mod"), goModContent, 0644); err != nil { + runtimeDir := filepath.Join(tmpDir, "runtime") + os.MkdirAll(runtimeDir, 0755) + goModContent := []byte("module github.com/goplus/llgo/runtime\n") + if err := os.WriteFile(filepath.Join(runtimeDir, "go.mod"), goModContent, 0644); err != nil { t.Fatal(err) } @@ -92,8 +94,10 @@ func TestLLGoROOT(t *testing.T) { defer os.Setenv("LLGO_ROOT", origLLGoRoot) tmpDir := t.TempDir() - goModContent := []byte("module github.com/goplus/llgo\n") - if err := os.WriteFile(filepath.Join(tmpDir, "go.mod"), goModContent, 0644); err != nil { + runtimeDir := filepath.Join(tmpDir, "runtime") + os.MkdirAll(runtimeDir, 0755) + goModContent := []byte("module github.com/goplus/llgo/runtime\n") + if err := os.WriteFile(filepath.Join(runtimeDir, "go.mod"), goModContent, 0644); err != nil { t.Fatal(err) } @@ -170,8 +174,10 @@ func TestIsLLGoRoot(t *testing.T) { // Test with valid path and valid go.mod t.Run("valid path and go.mod", func(t *testing.T) { tmpDir := t.TempDir() - goModContent := []byte("module github.com/goplus/llgo\n") - if err := os.WriteFile(filepath.Join(tmpDir, "go.mod"), goModContent, 0644); err != nil { + runtimeDir := filepath.Join(tmpDir, "runtime") + os.MkdirAll(runtimeDir, 0755) + goModContent := []byte("module github.com/goplus/llgo/runtime\n") + if err := os.WriteFile(filepath.Join(runtimeDir, "go.mod"), goModContent, 0644); err != nil { t.Fatal(err) } From 1d3ecb287aceed50ce04683ad0408c1fb00d2fe1 Mon Sep 17 00:00:00 2001 From: Haolan Date: Mon, 1 Sep 2025 17:28:01 +0800 Subject: [PATCH 37/46] fix: export libc cflags for compiler-rt fix: libc include dir fix: xtensa internal src dir fix: xtensa internal src dir fix: ignore wasm target fix: export libc cflags to global cflags fix: rtlib libc include dir fix: ignore some errors for libc fix: don's search system path for libc fix: adjust compiling options ci: add libc fix: libc cflags fix: test path fix: libc cflags fix: libc cflags --- .github/actions/setup-deps/action.yml | 2 +- internal/crosscompile/compile/compile.go | 34 +-- internal/crosscompile/compile/compile_test.go | 28 +- .../crosscompile/compile/libc/newlibesp.go | 88 +++--- .../crosscompile/compile/libc/picolibc.go | 250 +++++++++--------- .../crosscompile/compile/rtlib/compiler_rt.go | 4 +- internal/crosscompile/crosscompile.go | 26 +- internal/crosscompile/fetch_test.go | 2 +- 8 files changed, 246 insertions(+), 188 deletions(-) diff --git a/.github/actions/setup-deps/action.yml b/.github/actions/setup-deps/action.yml index 7a0669c8..8d877e97 100644 --- a/.github/actions/setup-deps/action.yml +++ b/.github/actions/setup-deps/action.yml @@ -34,7 +34,7 @@ runs: echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-${{inputs.llvm-version}} main" | sudo tee /etc/apt/sources.list.d/llvm.list wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - sudo apt-get update - sudo apt-get install -y llvm-${{inputs.llvm-version}}-dev clang-${{inputs.llvm-version}} libclang-${{inputs.llvm-version}}-dev lld-${{inputs.llvm-version}} libunwind-${{inputs.llvm-version}}-dev libc++-${{inputs.llvm-version}}-dev pkg-config libgc-dev libssl-dev zlib1g-dev libffi-dev libcjson-dev libuv1-dev + sudo apt-get install -y llvm-${{inputs.llvm-version}}-dev clang-${{inputs.llvm-version}} libclang-${{inputs.llvm-version}}-dev lld-${{inputs.llvm-version}} libunwind-${{inputs.llvm-version}}-dev libc-dev libc++-${{inputs.llvm-version}}-dev pkg-config libgc-dev libssl-dev zlib1g-dev libffi-dev libcjson-dev libuv1-dev echo "PATH=/usr/lib/llvm-${{inputs.llvm-version}}/bin:$PATH" >> $GITHUB_ENV # Install optional deps for demos. diff --git a/internal/crosscompile/compile/compile.go b/internal/crosscompile/compile/compile.go index 20f72e2c..9699ac1d 100644 --- a/internal/crosscompile/compile/compile.go +++ b/internal/crosscompile/compile/compile.go @@ -11,6 +11,14 @@ import ( "github.com/goplus/llgo/internal/clang" ) +type CompileOptions struct { + CC string // Compiler to use + Linker string + CCFLAGS []string + CFLAGS []string + LDFLAGS []string +} + type CompileGroup struct { OutputFileName string Files []string // List of source files to compile @@ -25,7 +33,9 @@ func (g CompileGroup) IsCompiled(outputDir string) bool { return !os.IsNotExist(err) } -func (g CompileGroup) Compile(outputDir, cc, linkerName string, extraCCFlags, extraLDFlags []string) (err error) { +func (g CompileGroup) Compile( + outputDir string, options CompileOptions, +) (err error) { if g.IsCompiled(outputDir) { return } @@ -35,15 +45,17 @@ func (g CompileGroup) Compile(outputDir, cc, linkerName string, extraCCFlags, ex } defer os.RemoveAll(tmpCompileDir) - compileLDFlags := append(slices.Clone(extraLDFlags), g.LDFlags...) - compileCCFlags := append(slices.Clone(extraCCFlags), g.CCFlags...) - cfg := clang.NewConfig(cc, compileCCFlags, g.CFlags, compileLDFlags, linkerName) + compileLDFlags := append(slices.Clone(options.LDFLAGS), g.LDFlags...) + compileCCFlags := append(slices.Clone(options.CCFLAGS), g.CCFlags...) + compileCFFlags := append(slices.Clone(options.CFLAGS), g.CFlags...) + + cfg := clang.NewConfig(options.CC, compileCCFlags, compileCFFlags, compileLDFlags, options.Linker) var objFiles []string compiler := clang.NewCompiler(cfg) - compiler.Verbose = false + compiler.Verbose = true archive := filepath.Join(outputDir, g.OutputFileName) fmt.Fprintf(os.Stderr, "Start to compile group %s to %s...\n", g.OutputFileName, archive) @@ -70,7 +82,7 @@ func (g CompileGroup) Compile(outputDir, cc, linkerName string, extraCCFlags, ex args := []string{"rcs", archive} args = append(args, objFiles...) - ccDir := filepath.Dir(cc) + ccDir := filepath.Dir(options.CC) llvmAr := filepath.Join(ccDir, "llvm-ar") cmd := exec.Command(llvmAr, args...) @@ -87,13 +99,5 @@ type CompileConfig struct { Name string // compile name (e.g., "picolibc", "musl", "glibc") Groups []CompileGroup ArchiveSrcDir string -} - -func (c CompileConfig) IsCompiled(outputDir string) bool { - for _, group := range c.Groups { - if !group.IsCompiled(outputDir) { - return false - } - } - return true + LibcCFlags []string } diff --git a/internal/crosscompile/compile/compile_test.go b/internal/crosscompile/compile/compile_test.go index 9995c555..74039a9d 100644 --- a/internal/crosscompile/compile/compile_test.go +++ b/internal/crosscompile/compile/compile_test.go @@ -2,6 +2,7 @@ package compile import ( "os" + "path/filepath" "strings" "testing" @@ -18,12 +19,12 @@ func TestIsCompile(t *testing.T) { }, } - if cfg.IsCompiled(".") || cfg.Groups[0].IsCompiled(".") { + if cfg.Groups[0].IsCompiled(".") { t.Errorf("unexpected result: should false") } }) t.Run("IsCompile Exists", func(t *testing.T) { - tmpFile, err := os.CreateTemp(".", "test*.a") + tmpFile, err := os.CreateTemp("", "test*.a") if err != nil { t.Error(err) return @@ -37,7 +38,7 @@ func TestIsCompile(t *testing.T) { }, } - if !cfg.IsCompiled(".") && !cfg.Groups[0].IsCompiled(".") { + if cfg.Groups[0].IsCompiled(filepath.Dir(tmpFile.Name())) { t.Errorf("unexpected result: should true") } }) @@ -54,7 +55,10 @@ func TestCompile(t *testing.T) { group := CompileGroup{ OutputFileName: tmpFile.Name(), } - err = group.Compile(".", "clang", "lld", nil, nil) + err = group.Compile(".", CompileOptions{ + CC: "clang", + Linker: "lld", + }) if err != nil { t.Errorf("unexpected result: should nil") } @@ -74,7 +78,10 @@ func TestCompile(t *testing.T) { group := CompileGroup{ OutputFileName: "nop.a", } - err = group.Compile(".", "clang", "lld", nil, nil) + err = group.Compile(".", CompileOptions{ + CC: "clang", + Linker: "lld", + }) if err == nil { t.Errorf("unexpected result: should not nil") } @@ -104,11 +111,18 @@ func TestCompile(t *testing.T) { OutputFileName: "nop.a", Files: []string{tmpFile.Name()}, } - err = group.Compile(".", "clang", "lld", []string{"-nostdinc"}, nil) + err = group.Compile(".", CompileOptions{ + CC: "clang", + Linker: "lld", + CCFLAGS: []string{"-nostdinc"}, + }) if err == nil { t.Errorf("unexpected result: should not nil") } - err = group.Compile(".", "clang", "lld", nil, nil) + err = group.Compile(".", CompileOptions{ + CC: "clang", + Linker: "lld", + }) if err != nil { t.Errorf("unexpected result: should not nil") } diff --git a/internal/crosscompile/compile/libc/newlibesp.go b/internal/crosscompile/compile/libc/newlibesp.go index 86e5651a..23d7930d 100644 --- a/internal/crosscompile/compile/libc/newlibesp.go +++ b/internal/crosscompile/compile/libc/newlibesp.go @@ -8,12 +8,42 @@ import ( "github.com/goplus/llgo/internal/crosscompile/compile" ) +var _libcLDFlags = []string{ + "-nostdlib", + "-ffunction-sections", + "-fdata-sections", +} + +var _libcCCFlags = []string{ + "-Oz", + "-fno-builtin", + // freestanding tells compiler this is a baremental project + "-ffreestanding", +} + +const ( + _newlibUrl = "https://github.com/goplus/newlib/archive/refs/tags/v0.2.0.tar.gz" + _archiveInternalSrcDir = "newlib-0.2.0" +) + +func withDefaultCCFlags(ccflags []string) []string { + return append(ccflags, _libcCCFlags...) +} + func getNewlibESP32ConfigRISCV(baseDir, target string) *compile.CompileConfig { libcDir := filepath.Join(baseDir, "newlib", "libc") + libcIncludeDir := []string{ + "-isystem" + filepath.Join(libcDir, "include"), + "-I" + filepath.Join(baseDir, "newlib"), + "-I" + libcDir, + } + return &compile.CompileConfig{ - Url: "https://github.com/goplus/newlib/archive/refs/tags/v0.2.0.tar.gz", - Name: "newlib-esp32", + Url: _newlibUrl, + Name: "newlib-esp32", + LibcCFlags: libcIncludeDir, + ArchiveSrcDir: _archiveInternalSrcDir, Groups: []compile.CompileGroup{ { OutputFileName: fmt.Sprintf("libcrt0-%s.a", target), @@ -30,10 +60,8 @@ func getNewlibESP32ConfigRISCV(baseDir, target string) *compile.CompileConfig { "-I" + filepath.Join(baseDir, "libgloss", "riscv"), "-I" + filepath.Join(baseDir, "libgloss", "riscv", "esp"), }, - LDFlags: []string{"-nostdlib"}, - CCFlags: []string{ - "-Oz", - }, + LDFlags: _libcLDFlags, + CCFlags: _libcCCFlags, }, { OutputFileName: fmt.Sprintf("libgloss-%s.a", target), @@ -298,10 +326,8 @@ func getNewlibESP32ConfigRISCV(baseDir, target string) *compile.CompileConfig { "-I" + filepath.Join(baseDir, "libgloss", "riscv"), "-I" + filepath.Join(baseDir, "libgloss", "riscv", "esp"), }, - LDFlags: []string{"-nostdlib"}, - CCFlags: []string{ - "-Oz", - }, + LDFlags: _libcLDFlags, + CCFlags: _libcCCFlags, }, { OutputFileName: fmt.Sprintf("libc-%s.a", target), @@ -1054,27 +1080,32 @@ func getNewlibESP32ConfigRISCV(baseDir, target string) *compile.CompileConfig { "-I" + filepath.Join(libcDir, "posix"), "-I" + filepath.Join(libcDir, "stdlib"), }, - LDFlags: []string{"-nostdlib"}, - CCFlags: []string{ - "-Oz", + LDFlags: _libcLDFlags, + CCFlags: withDefaultCCFlags([]string{ "-fno-builtin", - "-ffreestanding", "-Wno-implicit-function-declaration", "-Wno-int-conversion", "-Wno-unused-command-line-argument", - }, + }), }, }, - ArchiveSrcDir: "newlib-0.2.0", } } func getNewlibESP32ConfigXtensa(baseDir, target string) *compile.CompileConfig { libcDir := filepath.Join(baseDir, "newlib", "libc") + libcIncludeDir := []string{ + "-I" + filepath.Join(libcDir, "include"), + "-I" + filepath.Join(baseDir, "newlib"), + "-I" + libcDir, + } + return &compile.CompileConfig{ - Url: "https://github.com/goplus/newlib/archive/refs/tags/v0.2.0.tar.gz", - Name: "newlib-esp32", + Url: _newlibUrl, + Name: "newlib-esp32", + ArchiveSrcDir: _archiveInternalSrcDir, + LibcCFlags: libcIncludeDir, Groups: []compile.CompileGroup{ { OutputFileName: fmt.Sprintf("libcrt0-%s.a", target), @@ -1095,10 +1126,8 @@ func getNewlibESP32ConfigXtensa(baseDir, target string) *compile.CompileConfig { "-I" + filepath.Join(baseDir, "libgloss", "xtensa", "include"), "-I" + filepath.Join(baseDir, "libgloss", "xtensa", "boards", "esp32", "include"), }, - LDFlags: []string{"-nostdlib"}, - CCFlags: []string{ - "-Oz", - }, + LDFlags: _libcLDFlags, + CCFlags: _libcCCFlags, }, { OutputFileName: fmt.Sprintf("libgloss-%s.a", target), @@ -1292,10 +1321,8 @@ func getNewlibESP32ConfigXtensa(baseDir, target string) *compile.CompileConfig { "-I" + filepath.Join(baseDir, "libgloss", "xtensa", "include"), "-I" + filepath.Join(baseDir, "libgloss", "xtensa", "boards", "esp32", "include"), }, - LDFlags: []string{"-nostdlib"}, - CCFlags: []string{ - "-Oz", - }, + LDFlags: _libcLDFlags, + CCFlags: _libcCCFlags, }, { OutputFileName: fmt.Sprintf("libc-%s.a", target), @@ -2035,18 +2062,15 @@ func getNewlibESP32ConfigXtensa(baseDir, target string) *compile.CompileConfig { "-I" + filepath.Join(libcDir, "posix"), "-I" + filepath.Join(libcDir, "stdlib"), }, - LDFlags: []string{"-nostdlib"}, - CCFlags: []string{ - "-Oz", + LDFlags: _libcLDFlags, + CCFlags: withDefaultCCFlags([]string{ "-fno-builtin", - "-ffreestanding", "-Wno-implicit-function-declaration", "-Wno-int-conversion", "-Wno-unused-command-line-argument", - }, + }), }, }, - ArchiveSrcDir: "newlib-0.1.0", } } diff --git a/internal/crosscompile/compile/libc/picolibc.go b/internal/crosscompile/compile/libc/picolibc.go index 0e35d9a4..7736ccf7 100644 --- a/internal/crosscompile/compile/libc/picolibc.go +++ b/internal/crosscompile/compile/libc/picolibc.go @@ -9,131 +9,132 @@ import ( // getPicolibcConfig returns configuration for picolibc func GetPicolibcConfig(baseDir, target string) *compile.CompileConfig { - libcIncludeDir := filepath.Join(baseDir, "libc", "include") - libmIncludeDir := filepath.Join(baseDir, "libm", "common") - localeIncludeDir := filepath.Join(baseDir, "libc", "locale") - return &compile.CompileConfig{ Url: "https://github.com/goplus/picolibc/archive/refs/heads/main.zip", Name: "picolibc", + LibcCFlags: []string{ + "-I" + baseDir, + "-isystem" + filepath.Join(baseDir, "newlib", "libc", "include"), + }, + Groups: []compile.CompileGroup{ { OutputFileName: fmt.Sprintf("libc-%s.a", target), Files: []string{ - filepath.Join(baseDir, "libc", "string", "bcmp.c"), - filepath.Join(baseDir, "libc", "string", "bcopy.c"), - filepath.Join(baseDir, "libc", "string", "bzero.c"), - filepath.Join(baseDir, "libc", "string", "explicit_bzero.c"), - filepath.Join(baseDir, "libc", "string", "ffsl.c"), - filepath.Join(baseDir, "libc", "string", "ffsll.c"), - filepath.Join(baseDir, "libc", "string", "fls.c"), - filepath.Join(baseDir, "libc", "string", "flsl.c"), - filepath.Join(baseDir, "libc", "string", "flsll.c"), - filepath.Join(baseDir, "libc", "string", "gnu_basename.c"), - filepath.Join(baseDir, "libc", "string", "index.c"), - filepath.Join(baseDir, "libc", "string", "memccpy.c"), - filepath.Join(baseDir, "libc", "string", "memchr.c"), - filepath.Join(baseDir, "libc", "string", "memcmp.c"), - filepath.Join(baseDir, "libc", "string", "memcpy.c"), - filepath.Join(baseDir, "libc", "string", "memmem.c"), - filepath.Join(baseDir, "libc", "string", "memmove.c"), - filepath.Join(baseDir, "libc", "string", "mempcpy.c"), - filepath.Join(baseDir, "libc", "string", "memrchr.c"), - filepath.Join(baseDir, "libc", "string", "memset.c"), - filepath.Join(baseDir, "libc", "string", "rawmemchr.c"), - filepath.Join(baseDir, "libc", "string", "rindex.c"), - filepath.Join(baseDir, "libc", "string", "stpcpy.c"), - filepath.Join(baseDir, "libc", "string", "stpncpy.c"), - filepath.Join(baseDir, "libc", "string", "strcasecmp.c"), - filepath.Join(baseDir, "libc", "string", "strcasecmp_l.c"), - filepath.Join(baseDir, "libc", "string", "strcasestr.c"), - filepath.Join(baseDir, "libc", "string", "strcat.c"), - filepath.Join(baseDir, "libc", "string", "strchr.c"), - filepath.Join(baseDir, "libc", "string", "strchrnul.c"), - filepath.Join(baseDir, "libc", "string", "strcmp.c"), - filepath.Join(baseDir, "libc", "string", "strcoll.c"), - filepath.Join(baseDir, "libc", "string", "strcoll_l.c"), - filepath.Join(baseDir, "libc", "string", "strcpy.c"), - filepath.Join(baseDir, "libc", "string", "strcspn.c"), - filepath.Join(baseDir, "libc", "string", "strerror_r.c"), - filepath.Join(baseDir, "libc", "string", "strlcat.c"), - filepath.Join(baseDir, "libc", "string", "strlcpy.c"), - filepath.Join(baseDir, "libc", "string", "strlen.c"), - filepath.Join(baseDir, "libc", "string", "strlwr.c"), - filepath.Join(baseDir, "libc", "string", "strncasecmp.c"), - filepath.Join(baseDir, "libc", "string", "strncasecmp_l.c"), - filepath.Join(baseDir, "libc", "string", "strncat.c"), - filepath.Join(baseDir, "libc", "string", "strncmp.c"), - filepath.Join(baseDir, "libc", "string", "strncpy.c"), - filepath.Join(baseDir, "libc", "string", "strndup.c"), - filepath.Join(baseDir, "libc", "string", "strnlen.c"), - filepath.Join(baseDir, "libc", "string", "strnstr.c"), - filepath.Join(baseDir, "libc", "string", "strpbrk.c"), - filepath.Join(baseDir, "libc", "string", "strrchr.c"), - filepath.Join(baseDir, "libc", "string", "strsep.c"), - filepath.Join(baseDir, "libc", "string", "strsignal.c"), - filepath.Join(baseDir, "libc", "string", "strspn.c"), - filepath.Join(baseDir, "libc", "string", "strstr.c"), - filepath.Join(baseDir, "libc", "string", "strtok.c"), - filepath.Join(baseDir, "libc", "string", "strtok_r.c"), - filepath.Join(baseDir, "libc", "string", "strupr.c"), - filepath.Join(baseDir, "libc", "string", "strverscmp.c"), - filepath.Join(baseDir, "libc", "string", "strxfrm.c"), - filepath.Join(baseDir, "libc", "string", "strxfrm_l.c"), - filepath.Join(baseDir, "libc", "string", "swab.c"), - filepath.Join(baseDir, "libc", "string", "timingsafe_bcmp.c"), - filepath.Join(baseDir, "libc", "string", "timingsafe_memcmp.c"), - filepath.Join(baseDir, "libc", "string", "strerror.c"), - filepath.Join(baseDir, "libc", "string", "wcpcpy.c"), - filepath.Join(baseDir, "libc", "string", "wcpncpy.c"), - filepath.Join(baseDir, "libc", "string", "wcscasecmp.c"), - filepath.Join(baseDir, "libc", "string", "wcscasecmp_l.c"), - filepath.Join(baseDir, "libc", "string", "wcscat.c"), - filepath.Join(baseDir, "libc", "string", "wcschr.c"), - filepath.Join(baseDir, "libc", "string", "wcscmp.c"), - filepath.Join(baseDir, "libc", "string", "wcscoll.c"), - filepath.Join(baseDir, "libc", "string", "wcscoll_l.c"), - filepath.Join(baseDir, "libc", "string", "wcscpy.c"), - filepath.Join(baseDir, "libc", "string", "wcscspn.c"), - filepath.Join(baseDir, "libc", "string", "wcsdup.c"), - filepath.Join(baseDir, "libc", "string", "wcslcat.c"), - filepath.Join(baseDir, "libc", "string", "wcslcpy.c"), - filepath.Join(baseDir, "libc", "string", "wcslen.c"), - filepath.Join(baseDir, "libc", "string", "wcsncasecmp.c"), - filepath.Join(baseDir, "libc", "string", "wcsncasecmp_l.c"), - filepath.Join(baseDir, "libc", "string", "wcsncat.c"), - filepath.Join(baseDir, "libc", "string", "wcsncmp.c"), - filepath.Join(baseDir, "libc", "string", "wcsncpy.c"), - filepath.Join(baseDir, "libc", "string", "wcsnlen.c"), - filepath.Join(baseDir, "libc", "string", "wcspbrk.c"), - filepath.Join(baseDir, "libc", "string", "wcsrchr.c"), - filepath.Join(baseDir, "libc", "string", "wcsspn.c"), - filepath.Join(baseDir, "libc", "string", "wcsstr.c"), - filepath.Join(baseDir, "libc", "string", "wcstok.c"), - filepath.Join(baseDir, "libc", "string", "wcswidth.c"), - filepath.Join(baseDir, "libc", "string", "wcsxfrm.c"), - filepath.Join(baseDir, "libc", "string", "wcsxfrm_l.c"), - filepath.Join(baseDir, "libc", "string", "wcwidth.c"), - filepath.Join(baseDir, "libc", "string", "wmemchr.c"), - filepath.Join(baseDir, "libc", "string", "wmemcmp.c"), - filepath.Join(baseDir, "libc", "string", "wmemcpy.c"), - filepath.Join(baseDir, "libc", "string", "wmemmove.c"), - filepath.Join(baseDir, "libc", "string", "wmempcpy.c"), - filepath.Join(baseDir, "libc", "string", "wmemset.c"), - filepath.Join(baseDir, "libc", "string", "xpg_strerror_r.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "bcmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "bcopy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "bzero.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "explicit_bzero.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "ffsl.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "ffsll.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "fls.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "flsl.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "flsll.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "gnu_basename.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "index.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "memccpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "memchr.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "memcmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "memcpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "memmem.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "memmove.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "mempcpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "memrchr.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "memset.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "rawmemchr.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "rindex.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "stpcpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "stpncpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strcasecmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strcasecmp_l.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strcasestr.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strcat.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strchr.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strchrnul.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strcmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strcoll.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strcoll_l.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strcpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strcspn.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strerror_r.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strlcat.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strlcpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strlen.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strlwr.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strncasecmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strncasecmp_l.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strncat.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strncmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strncpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strndup.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strnlen.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strnstr.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strpbrk.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strrchr.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strsep.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strsignal.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strspn.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strstr.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strtok.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strtok_r.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strupr.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strverscmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strxfrm.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strxfrm_l.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "swab.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "timingsafe_bcmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "timingsafe_memcmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strerror.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcpcpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcpncpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcscasecmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcscasecmp_l.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcscat.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcschr.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcscmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcscoll.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcscoll_l.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcscpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcscspn.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcsdup.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcslcat.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcslcpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcslen.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcsncasecmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcsncasecmp_l.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcsncat.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcsncmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcsncpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcsnlen.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcspbrk.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcsrchr.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcsspn.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcsstr.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcstok.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcswidth.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcsxfrm.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcsxfrm_l.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wcwidth.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wmemchr.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wmemcmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wmemcpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wmemmove.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wmempcpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "wmemset.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "xpg_strerror_r.c"), - filepath.Join(baseDir, "libc", "stdlib", "nano-calloc.c"), - filepath.Join(baseDir, "libc", "stdlib", "nano-malloc.c"), - filepath.Join(baseDir, "libc", "stdlib", "nano-pvalloc.c"), - filepath.Join(baseDir, "libc", "stdlib", "nano-realloc.c"), - filepath.Join(baseDir, "libc", "stdlib", "nano-valloc.c"), - filepath.Join(baseDir, "libc", "stdlib", "rand.c"), - filepath.Join(baseDir, "libc", "stdlib", "srand.c"), - filepath.Join(baseDir, "libc", "stdlib", "nano-free.c"), + filepath.Join(baseDir, "newlib", "libc", "stdlib", "nano-calloc.c"), + filepath.Join(baseDir, "newlib", "libc", "stdlib", "nano-malloc.c"), + filepath.Join(baseDir, "newlib", "libc", "stdlib", "nano-pvalloc.c"), + filepath.Join(baseDir, "newlib", "libc", "stdlib", "nano-realloc.c"), + filepath.Join(baseDir, "newlib", "libc", "stdlib", "nano-valloc.c"), + filepath.Join(baseDir, "newlib", "libc", "stdlib", "rand.c"), + filepath.Join(baseDir, "newlib", "libc", "stdlib", "srand.c"), + filepath.Join(baseDir, "newlib", "libc", "stdlib", "nano-free.c"), - filepath.Join(baseDir, "libc", "tinystdio", "printf.c"), - filepath.Join(baseDir, "libc", "tinystdio", "putchar.c"), - filepath.Join(baseDir, "libc", "tinystdio", "puts.c"), + filepath.Join(baseDir, "newlib", "libc", "tinystdio", "printf.c"), + filepath.Join(baseDir, "newlib", "libc", "tinystdio", "putchar.c"), + filepath.Join(baseDir, "newlib", "libc", "tinystdio", "puts.c"), }, CFlags: []string{ "-D_COMPILING_NEWLIB", @@ -146,18 +147,17 @@ func GetPicolibcConfig(baseDir, target string) *compile.CompileConfig { "-D__OBSOLETE_MATH_DOUBLE=0", "-D_WANT_IO_C99_FORMATS", "-nostdlib", - "-isystem" + libcIncludeDir, - "-I" + libmIncludeDir, - "-I" + localeIncludeDir, "-I" + baseDir, - "-I" + filepath.Join(baseDir, "libc", "tinystdio"), - }, - LDFlags: []string{"-nostdlib"}, - CCFlags: []string{ - "-Oz", + "-isystem" + filepath.Join(baseDir, "newlib", "libc", "include"), + "-I" + filepath.Join(baseDir, "newlib", "libm", "common"), + "-I" + filepath.Join(baseDir, "newlib", "libc", "locale"), + + "-I" + filepath.Join(baseDir, "newlib", "libc", "tinystdio"), }, + LDFlags: _libcLDFlags, + CCFlags: _libcCCFlags, }, }, - ArchiveSrcDir: filepath.Join("picolibc-main", "newlib"), + ArchiveSrcDir: "picolibc-main", } } diff --git a/internal/crosscompile/compile/rtlib/compiler_rt.go b/internal/crosscompile/compile/rtlib/compiler_rt.go index 1a1e403a..d307132c 100644 --- a/internal/crosscompile/compile/rtlib/compiler_rt.go +++ b/internal/crosscompile/compile/rtlib/compiler_rt.go @@ -16,6 +16,7 @@ func platformSpecifiedFiles(builtinsDir, target string) []string { filepath.Join(builtinsDir, "riscv", "fp_mode.c"), filepath.Join(builtinsDir, "riscv", "save.S"), filepath.Join(builtinsDir, "riscv", "restore.S"), + filepath.Join(builtinsDir, "atomic.c"), } case strings.Contains(target, "riscv64"): return []string{ @@ -45,6 +46,7 @@ func platformSpecifiedFiles(builtinsDir, target string) []string { filepath.Join(builtinsDir, "trunctfdf2.c"), filepath.Join(builtinsDir, "trunctfhf2.c"), filepath.Join(builtinsDir, "trunctfsf2.c"), + filepath.Join(builtinsDir, "atomic.c"), } case strings.Contains(target, "arm"): return []string{ @@ -87,6 +89,7 @@ func platformSpecifiedFiles(builtinsDir, target string) []string { case target == "xtensa": return []string{ filepath.Join(builtinsDir, "xtensa", "ieee754_sqrtf.S"), + filepath.Join(builtinsDir, "atomic.c"), } } return nil @@ -252,7 +255,6 @@ func GetCompilerRTConfig(baseDir, target string) *compile.CompileConfig { filepath.Join(baseDir, "lib", "builtins", "trunctfdf2.c"), filepath.Join(baseDir, "lib", "builtins", "trunctfhf2.c"), filepath.Join(baseDir, "lib", "builtins", "trunctfsf2.c"), - filepath.Join(baseDir, "lib", "builtins", "atomic.c"), }), CFlags: []string{ "-DNDEBUG", diff --git a/internal/crosscompile/crosscompile.go b/internal/crosscompile/crosscompile.go index a53fff57..c128d8f1 100644 --- a/internal/crosscompile/crosscompile.go +++ b/internal/crosscompile/crosscompile.go @@ -223,8 +223,7 @@ func ldFlagsFromFileName(fileName string) string { func getOrCompileWithConfig( compileConfig *compile.CompileConfig, - outputDir, cc, linkerName string, - exportCCFlags, exportLDFlags []string, + outputDir string, options compile.CompileOptions, ) (ldflags []string, err error) { if err = checkDownloadAndExtractLib( compileConfig.Url, outputDir, @@ -235,7 +234,7 @@ func getOrCompileWithConfig( ldflags = append(ldflags, "-nostdlib", "-L"+outputDir) for _, group := range compileConfig.Groups { - err = group.Compile(outputDir, cc, linkerName, exportCCFlags, exportLDFlags) + err = group.Compile(outputDir, options) if err != nil { break } @@ -606,6 +605,8 @@ func useTarget(targetName string) (export Export, err error) { } ldflags = append(ldflags, "-L", env.LLGoROOT()) // search targets/*.ld + var libcIncludeDir []string + if config.Libc != "" { var libcLDFlags []string var compileConfig *compile.CompileConfig @@ -616,12 +617,19 @@ func useTarget(targetName string) (export Export, err error) { if err != nil { return } - libcLDFlags, err = getOrCompileWithConfig(compileConfig, outputDir, export.CC, export.Linker, ccflags, ldflags) + libcLDFlags, err = getOrCompileWithConfig(compileConfig, outputDir, compile.CompileOptions{ + CC: export.CC, + Linker: export.Linker, + CCFLAGS: ccflags, + LDFLAGS: ldflags, + }) if err != nil { return } + cflags = append(cflags, compileConfig.LibcCFlags...) ldflags = append(ldflags, libcLDFlags...) + libcIncludeDir = compileConfig.LibcCFlags export.Libc = config.Libc } @@ -635,7 +643,13 @@ func useTarget(targetName string) (export Export, err error) { if err != nil { return } - rtLibLDFlags, err = getOrCompileWithConfig(compileConfig, outputDir, export.CC, export.Linker, ccflags, ldflags) + rtLibLDFlags, err = getOrCompileWithConfig(compileConfig, outputDir, compile.CompileOptions{ + CC: export.CC, + Linker: export.Linker, + CCFLAGS: ccflags, + LDFLAGS: ldflags, + CFLAGS: libcIncludeDir, + }) if err != nil { return } @@ -654,7 +668,7 @@ func useTarget(targetName string) (export Export, err error) { // Use extends the original Use function to support target-based configuration // If targetName is provided, it takes precedence over goos/goarch func Use(goos, goarch string, wasiThreads bool, targetName string) (export Export, err error) { - if targetName != "" { + if targetName != "" && !strings.HasPrefix(targetName, "wasm") && !strings.HasPrefix(targetName, "wasi") { return useTarget(targetName) } return use(goos, goarch, wasiThreads) diff --git a/internal/crosscompile/fetch_test.go b/internal/crosscompile/fetch_test.go index 7f5d2af9..380cbaea 100644 --- a/internal/crosscompile/fetch_test.go +++ b/internal/crosscompile/fetch_test.go @@ -294,7 +294,7 @@ func TestDownloadAndExtractArchiveUnsupportedFormat(t *testing.T) { tempDir := t.TempDir() destDir := filepath.Join(tempDir, "extracted") - err := downloadAndExtractArchive(server.URL+"/test.zip", destDir, "Test Archive") + err := downloadAndExtractArchive(server.URL+"/test.7z", destDir, "Test Archive") if err == nil { t.Error("Expected error for unsupported format, got nil") } From f875347ad9ee15910e40b134926af52daf54b7d0 Mon Sep 17 00:00:00 2001 From: Haolan Date: Tue, 2 Sep 2025 09:45:42 +0800 Subject: [PATCH 38/46] test: fix compile test test: add asm test test: add libc.go test test: add DownloadAndExtractLibInternalDir test test: fix checkDownload test test: fix asm test fix: check isCompile fix: remove debug fix: remove debug --- internal/crosscompile/compile/compile.go | 6 +- internal/crosscompile/compile/compile_test.go | 95 ++++++++--- internal/crosscompile/crosscompile_test.go | 19 ++- internal/crosscompile/fetch.go | 6 +- internal/crosscompile/fetch_test.go | 158 ++++++++++++++++++ internal/crosscompile/libc_test.go | 107 ++++++++++++ 6 files changed, 355 insertions(+), 36 deletions(-) create mode 100644 internal/crosscompile/libc_test.go diff --git a/internal/crosscompile/compile/compile.go b/internal/crosscompile/compile/compile.go index 9699ac1d..0fc7d79a 100644 --- a/internal/crosscompile/compile/compile.go +++ b/internal/crosscompile/compile/compile.go @@ -28,9 +28,9 @@ type CompileGroup struct { } func (g CompileGroup) IsCompiled(outputDir string) bool { - archive := filepath.Join(outputDir, g.OutputFileName) + archive := filepath.Join(outputDir, filepath.Base(g.OutputFileName)) _, err := os.Stat(archive) - return !os.IsNotExist(err) + return err == nil } func (g CompileGroup) Compile( @@ -57,7 +57,7 @@ func (g CompileGroup) Compile( compiler.Verbose = true - archive := filepath.Join(outputDir, g.OutputFileName) + archive := filepath.Join(outputDir, filepath.Base(g.OutputFileName)) fmt.Fprintf(os.Stderr, "Start to compile group %s to %s...\n", g.OutputFileName, archive) for _, file := range g.Files { diff --git a/internal/crosscompile/compile/compile_test.go b/internal/crosscompile/compile/compile_test.go index 74039a9d..7ffb56b5 100644 --- a/internal/crosscompile/compile/compile_test.go +++ b/internal/crosscompile/compile/compile_test.go @@ -38,7 +38,7 @@ func TestIsCompile(t *testing.T) { }, } - if cfg.Groups[0].IsCompiled(filepath.Dir(tmpFile.Name())) { + if !cfg.Groups[0].IsCompiled(filepath.Dir(tmpFile.Name())) { t.Errorf("unexpected result: should true") } }) @@ -46,39 +46,48 @@ func TestIsCompile(t *testing.T) { func TestCompile(t *testing.T) { t.Run("Skip compile", func(t *testing.T) { - tmpFile, err := os.CreateTemp(".", "test*.a") + tmpDir, err := os.MkdirTemp("", "test-compile*") + if err != nil { + t.Error(err) + return + } + defer os.RemoveAll(tmpDir) + + tmpFile, err := os.CreateTemp(tmpDir, "test*.a") if err != nil { t.Error(err) return } - defer os.Remove(tmpFile.Name()) group := CompileGroup{ OutputFileName: tmpFile.Name(), } - err = group.Compile(".", CompileOptions{ + err = group.Compile(tmpDir, CompileOptions{ CC: "clang", Linker: "lld", }) if err != nil { - t.Errorf("unexpected result: should nil") + t.Errorf("unexpected result: should nil: %v", err) } }) t.Run("TmpDir Fail", func(t *testing.T) { - err := os.Mkdir("test-compile", 0) + tmpDir := filepath.Join(t.TempDir(), "test-compile") + os.RemoveAll(tmpDir) + + err := os.Mkdir(tmpDir, 0) if err != nil { t.Error(err) return } - defer os.RemoveAll("test-compile") + defer os.RemoveAll(tmpDir) - os.Setenv("TMPDIR", "test-compile") + os.Setenv("TMPDIR", tmpDir) defer os.Unsetenv("TMPDIR") group := CompileGroup{ OutputFileName: "nop.a", } - err = group.Compile(".", CompileOptions{ + err = group.Compile(tmpDir, CompileOptions{ CC: "clang", Linker: "lld", }) @@ -88,20 +97,26 @@ func TestCompile(t *testing.T) { }) t.Run("Compile", func(t *testing.T) { - tmpFile, err := os.CreateTemp("", "test*.c") + tmpDir, err := os.MkdirTemp("", "test-compile*") + if err != nil { + t.Error(err) + return + } + defer os.RemoveAll(tmpDir) + + tmpFile, err := os.CreateTemp(tmpDir, "test*.c") if err != nil { t.Error(err) return } - defer os.Remove(tmpFile.Name()) _, err = tmpFile.Write([]byte(`#include - void Foo() { - double x = 2.0; - double y = sqrt(x); - (void) y ; - } - `)) + void Foo() { + double x = 2.0; + double y = sqrt(x); + (void) y ; + } + `)) if err != nil { t.Error(err) return @@ -111,7 +126,7 @@ func TestCompile(t *testing.T) { OutputFileName: "nop.a", Files: []string{tmpFile.Name()}, } - err = group.Compile(".", CompileOptions{ + err = group.Compile(tmpDir, CompileOptions{ CC: "clang", Linker: "lld", CCFLAGS: []string{"-nostdinc"}, @@ -119,20 +134,19 @@ func TestCompile(t *testing.T) { if err == nil { t.Errorf("unexpected result: should not nil") } - err = group.Compile(".", CompileOptions{ + err = group.Compile(tmpDir, CompileOptions{ CC: "clang", Linker: "lld", }) if err != nil { t.Errorf("unexpected result: should not nil") } - if _, err := os.Stat("nop.a"); os.IsNotExist(err) { + if _, err := os.Stat(filepath.Join(tmpDir, "nop.a")); os.IsNotExist(err) { t.Error("unexpected result: compiled nop.a not found") return } - defer os.Remove("nop.a") - items, err := nm.New("").List("nop.a") + items, err := nm.New("").List(filepath.Join(tmpDir, "nop.a")) if err != nil { t.Error(err) return @@ -153,4 +167,41 @@ func TestCompile(t *testing.T) { t.Errorf("cannot find symbol Foo") } }) + + t.Run("Compile Asm", func(t *testing.T) { + tmpDir, err := os.MkdirTemp("", "test-compile*") + if err != nil { + t.Error(err) + return + } + defer os.RemoveAll(tmpDir) + tmpFile, err := os.CreateTemp(tmpDir, "test*.S") + if err != nil { + t.Error(err) + return + } + defer os.Remove(tmpFile.Name()) + + _, err = tmpFile.Write([]byte(` + .text + .globl _test + `)) + if err != nil { + t.Error(err) + return + } + + group := CompileGroup{ + OutputFileName: "nop.a", + Files: []string{tmpFile.Name()}, + } + err = group.Compile(tmpDir, CompileOptions{ + CC: "clang", + Linker: "lld", + CCFLAGS: []string{"--target=x86_64-linux-gnu"}, + }) + if err != nil { + t.Errorf("unexpected result: should nil %v", err) + } + }) } diff --git a/internal/crosscompile/crosscompile_test.go b/internal/crosscompile/crosscompile_test.go index ded63e0e..8ea3f146 100644 --- a/internal/crosscompile/crosscompile_test.go +++ b/internal/crosscompile/crosscompile_test.go @@ -176,13 +176,14 @@ func TestUseTarget(t *testing.T) { expectLLVM string expectCPU string }{ - { - name: "WASI Target", - targetName: "wasi", - expectError: false, - expectLLVM: "", - expectCPU: "generic", - }, + // FIXME(MeteorsLiu): wasi in useTarget + // { + // name: "WASI Target", + // targetName: "wasi", + // expectError: false, + // expectLLVM: "", + // expectCPU: "generic", + // }, { name: "RP2040 Target", targetName: "rp2040", @@ -279,13 +280,13 @@ func TestUseTarget(t *testing.T) { func TestUseWithTarget(t *testing.T) { // Test target-based configuration takes precedence - export, err := Use("linux", "amd64", false, "wasi") + export, err := Use("linux", "amd64", false, "esp32") if err != nil { t.Fatalf("Unexpected error: %v", err) } // Check if LLVM target is in CCFLAGS - found := slices.Contains(export.CCFLAGS, "-mcpu=generic") + found := slices.Contains(export.CCFLAGS, "-mcpu=esp32") if !found { t.Errorf("Expected CPU generic in CCFLAGS, got %v", export.CCFLAGS) } diff --git a/internal/crosscompile/fetch.go b/internal/crosscompile/fetch.go index 40db05f5..d32003ba 100644 --- a/internal/crosscompile/fetch.go +++ b/internal/crosscompile/fetch.go @@ -100,7 +100,7 @@ func checkDownloadAndExtractLib(url, dstDir, internalArchiveSrcDir string) error } fmt.Fprintf(os.Stderr, "%s not found in LLGO_ROOT or cache, will download and compile.\n", dstDir) - description := fmt.Sprintf("Lib %s", path.Base(url)) + description := fmt.Sprintf("lib %s", path.Base(url)) // Use temporary extraction directory tempExtractDir := dstDir + ".extract" @@ -115,7 +115,9 @@ func checkDownloadAndExtractLib(url, dstDir, internalArchiveSrcDir string) error srcDir = filepath.Join(tempExtractDir, internalArchiveSrcDir) } - os.Rename(srcDir, dstDir) + if err := os.Rename(srcDir, dstDir); err != nil { + return fmt.Errorf("failed to rename lib directory: %w", err) + } return nil } diff --git a/internal/crosscompile/fetch_test.go b/internal/crosscompile/fetch_test.go index 380cbaea..a9f45b4f 100644 --- a/internal/crosscompile/fetch_test.go +++ b/internal/crosscompile/fetch_test.go @@ -6,9 +6,11 @@ package crosscompile import ( "archive/tar" "compress/gzip" + "fmt" "net/http" "net/http/httptest" "os" + "os/exec" "path/filepath" "strings" "sync" @@ -303,6 +305,162 @@ func TestDownloadAndExtractArchiveUnsupportedFormat(t *testing.T) { } } +func TestCheckDownloadAndExtractLib(t *testing.T) { + files := map[string]string{ + "lib-src/file1.c": "int func1() { return 1; }", + "lib-src/file2.c": "int func2() { return 2; }", + "lib-src/include/lib.h": "#define LIB_VERSION 1", + } + + archivePath := createTestTarGz(t, files) + defer os.Remove(archivePath) + + archiveContent, err := os.ReadFile(archivePath) + if err != nil { + t.Fatalf("Failed to read test archive: %v", err) + } + + server := createTestServer(t, map[string]string{ + "test-lib.tar.gz": string(archiveContent), + }) + defer server.Close() + + tempDir := t.TempDir() + destDir := filepath.Join(tempDir, "test-lib") + + t.Run("LibAlreadyExists", func(t *testing.T) { + if err := os.MkdirAll(destDir, 0755); err != nil { + t.Fatalf("Failed to create existing lib dir: %v", err) + } + + err := checkDownloadAndExtractLib(server.URL+"/test-lib.tar.gz", destDir, "") + if err != nil { + t.Errorf("Expected no error when lib exists, got: %v", err) + } + }) + + t.Run("DownloadAndExtractWithoutInternalDir", func(t *testing.T) { + os.RemoveAll(destDir) + + err := checkDownloadAndExtractLib(server.URL+"/test-lib.tar.gz", destDir, "lib-src") + if err != nil { + t.Fatalf("Failed to download and extract lib: %v", err) + } + cmd := exec.Command("ls", destDir) + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + cmd.Run() + + for name, expectedContent := range files { + relPath := strings.TrimPrefix(name, "lib-src/") + filePath := filepath.Join(destDir, relPath) + + fmt.Println(filePath, destDir) + content, err := os.ReadFile(filePath) + if err != nil { + t.Errorf("Failed to read extracted file %s: %v", relPath, err) + continue + } + if string(content) != expectedContent { + t.Errorf("File %s: expected content %q, got %q", relPath, expectedContent, string(content)) + } + } + }) + + t.Run("DownloadAndExtractWithInternalDir", func(t *testing.T) { + os.RemoveAll(destDir) + + err := checkDownloadAndExtractLib(server.URL+"/test-lib.tar.gz", destDir, "lib-src") + if err != nil { + t.Fatalf("Failed to download and extract lib: %v", err) + } + + for name, expectedContent := range files { + relPath := strings.TrimPrefix(name, "lib-src/") + filePath := filepath.Join(destDir, relPath) + content, err := os.ReadFile(filePath) + if err != nil { + t.Errorf("Failed to read extracted file %s: %v", relPath, err) + continue + } + if string(content) != expectedContent { + t.Errorf("File %s: expected content %q, got %q", relPath, expectedContent, string(content)) + } + } + }) + + t.Run("DownloadFailure", func(t *testing.T) { + os.RemoveAll(destDir) + + err := checkDownloadAndExtractLib(server.URL+"/nonexistent.tar.gz", destDir, "") + if err == nil { + t.Error("Expected error for non-existent archive, got nil") + } + }) + + t.Run("RenameFailure", func(t *testing.T) { + os.RemoveAll(destDir) + + err := checkDownloadAndExtractLib(server.URL+"/test-lib.tar.gz", destDir, "lib-src222") + if err == nil { + t.Error("Expected error for rename failure, got nil") + } + }) +} + +func TestCheckDownloadAndExtractLibInternalDir(t *testing.T) { + files := map[string]string{ + "project-1.0.0/src/file1.c": "int func1() { return 1; }", + "project-1.0.0/include/lib.h": "#define LIB_VERSION 1", + "project-1.0.0/README.md": "Project documentation", + } + + archivePath := createTestTarGz(t, files) + defer os.Remove(archivePath) + + archiveContent, err := os.ReadFile(archivePath) + if err != nil { + t.Fatalf("Failed to read test archive: %v", err) + } + + server := createTestServer(t, map[string]string{ + "project.tar.gz": string(archiveContent), + }) + defer server.Close() + + tempDir := t.TempDir() + destDir := filepath.Join(tempDir, "project-lib") + + t.Run("CorrectInternalDir", func(t *testing.T) { + err := checkDownloadAndExtractLib(server.URL+"/project.tar.gz", destDir, "project-1.0.0") + if err != nil { + t.Fatalf("Failed to download and extract lib: %v", err) + } + + for name, expectedContent := range files { + relPath := strings.TrimPrefix(name, "project-1.0.0/") + filePath := filepath.Join(destDir, relPath) + content, err := os.ReadFile(filePath) + if err != nil { + t.Errorf("Failed to read extracted file %s: %v", relPath, err) + continue + } + if string(content) != expectedContent { + t.Errorf("File %s: expected content %q, got %q", relPath, expectedContent, string(content)) + } + } + }) + + t.Run("IncorrectInternalDir", func(t *testing.T) { + os.RemoveAll(destDir) + + err := checkDownloadAndExtractLib(server.URL+"/project.tar.gz", destDir, "wrong-dir") + if err == nil { + t.Error("Expected error for missing internal dir, got nil") + } + }) +} + // Mock test for WASI SDK (without actual download) func TestWasiSDKExtractionLogic(t *testing.T) { tempDir := t.TempDir() diff --git a/internal/crosscompile/libc_test.go b/internal/crosscompile/libc_test.go new file mode 100644 index 00000000..15f5a5b3 --- /dev/null +++ b/internal/crosscompile/libc_test.go @@ -0,0 +1,107 @@ +package crosscompile + +import ( + "path/filepath" + "slices" + "testing" +) + +func TestGetLibcCompileConfigByName(t *testing.T) { + baseDir := "/test/base" + target := "armv7" + mcpu := "cortex-m4" + + t.Run("EmptyName", func(t *testing.T) { + _, err := getLibcCompileConfigByName(baseDir, "", target, mcpu) + if err == nil || err.Error() != "libc name cannot be empty" { + t.Errorf("Expected empty name error, got: %v", err) + } + }) + + t.Run("UnsupportedLibc", func(t *testing.T) { + _, err := getLibcCompileConfigByName(baseDir, "invalid", target, mcpu) + if err == nil || err.Error() != "unsupported libc: invalid" { + t.Errorf("Expected unsupported libc error, got: %v", err) + } + }) + + t.Run("Picolibc", func(t *testing.T) { + cfg, err := getLibcCompileConfigByName(baseDir, "picolibc", target, mcpu) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + if len(cfg.Groups) != 1 { + t.Fatalf("Expected 1 group, got %d", len(cfg.Groups)) + } + group := cfg.Groups[0] + + expectedFile := filepath.Join(baseDir, "picolibc", "newlib", "libc", "string", "memmem.c") + if !slices.Contains(group.Files, expectedFile) { + t.Errorf("Expected files [%s], got: %v", expectedFile, group.Files) + } + + expectedFlag := "-I" + filepath.Join("/test", "base", "picolibc") + if !slices.Contains(group.CFlags, expectedFlag) { + t.Errorf("Expected flags [%s], got: %v", expectedFlag, group.CFlags) + } + }) + + t.Run("NewlibESP32", func(t *testing.T) { + cfg, err := getLibcCompileConfigByName(baseDir, "newlib-esp32", target, mcpu) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + if len(cfg.Groups) != 3 { + t.Fatalf("Expected 3 group, got %d", len(cfg.Groups)) + } + group := cfg.Groups[0] + + expectedFile := filepath.Join(baseDir, "newlib-esp32", "libgloss", "xtensa", "crt1-boards.S") + if !slices.Contains(group.Files, expectedFile) { + t.Errorf("Expected files [%s], got: %v", expectedFile, group.Files) + } + + expectedFlags := "-I" + filepath.Join(baseDir, "newlib-esp32", "libgloss") + if !slices.Contains(group.CFlags, expectedFlags) { + t.Errorf("Expected flags %v, got: %v", expectedFlags, group.CFlags) + } + }) +} + +func TestGetRTCompileConfigByName(t *testing.T) { + baseDir := "/test/base" + target := "wasm32" + + t.Run("EmptyName", func(t *testing.T) { + _, err := getRTCompileConfigByName(baseDir, "", target) + if err == nil || err.Error() != "rt name cannot be empty" { + t.Errorf("Expected empty name error, got: %v", err) + } + }) + + t.Run("UnsupportedRT", func(t *testing.T) { + _, err := getRTCompileConfigByName(baseDir, "invalid", target) + if err == nil || err.Error() != "unsupported rt: invalid" { + t.Errorf("Expected unsupported rt error, got: %v", err) + } + }) + + t.Run("CompilerRT", func(t *testing.T) { + cfg, err := getRTCompileConfigByName(baseDir, "compiler-rt", target) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + if len(cfg.Groups) != 1 { + t.Fatalf("Expected 1 group, got %d", len(cfg.Groups)) + } + group := cfg.Groups[0] + + expectedFile := filepath.Join(baseDir, "compiler-rt", "lib", "builtins", "absvdi2.c") + if !slices.Contains(group.Files, expectedFile) { + t.Errorf("Expected files [%s], got: %v", expectedFile, group.Files) + } + }) +} From a8bc617e18bc477a470402f3f4e0fdacb51b863d Mon Sep 17 00:00:00 2001 From: Haolan Date: Tue, 2 Sep 2025 17:16:55 +0800 Subject: [PATCH 39/46] test: skip llgo test --- internal/crosscompile/compile/compile_test.go | 2 ++ internal/crosscompile/libc_test.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/internal/crosscompile/compile/compile_test.go b/internal/crosscompile/compile/compile_test.go index 7ffb56b5..d2125e5a 100644 --- a/internal/crosscompile/compile/compile_test.go +++ b/internal/crosscompile/compile/compile_test.go @@ -1,3 +1,5 @@ +//go:build !llgo + package compile import ( diff --git a/internal/crosscompile/libc_test.go b/internal/crosscompile/libc_test.go index 15f5a5b3..5953d56c 100644 --- a/internal/crosscompile/libc_test.go +++ b/internal/crosscompile/libc_test.go @@ -1,3 +1,5 @@ +//go:build !llgo + package crosscompile import ( From 4b383b179a4f9a6783fa08c6b7f9fa4efc27104b Mon Sep 17 00:00:00 2001 From: Haolan Date: Tue, 2 Sep 2025 17:18:25 +0800 Subject: [PATCH 40/46] ci: revert --- .github/actions/setup-deps/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/setup-deps/action.yml b/.github/actions/setup-deps/action.yml index 8d877e97..7a0669c8 100644 --- a/.github/actions/setup-deps/action.yml +++ b/.github/actions/setup-deps/action.yml @@ -34,7 +34,7 @@ runs: echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-${{inputs.llvm-version}} main" | sudo tee /etc/apt/sources.list.d/llvm.list wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - sudo apt-get update - sudo apt-get install -y llvm-${{inputs.llvm-version}}-dev clang-${{inputs.llvm-version}} libclang-${{inputs.llvm-version}}-dev lld-${{inputs.llvm-version}} libunwind-${{inputs.llvm-version}}-dev libc-dev libc++-${{inputs.llvm-version}}-dev pkg-config libgc-dev libssl-dev zlib1g-dev libffi-dev libcjson-dev libuv1-dev + sudo apt-get install -y llvm-${{inputs.llvm-version}}-dev clang-${{inputs.llvm-version}} libclang-${{inputs.llvm-version}}-dev lld-${{inputs.llvm-version}} libunwind-${{inputs.llvm-version}}-dev libc++-${{inputs.llvm-version}}-dev pkg-config libgc-dev libssl-dev zlib1g-dev libffi-dev libcjson-dev libuv1-dev echo "PATH=/usr/lib/llvm-${{inputs.llvm-version}}/bin:$PATH" >> $GITHUB_ENV # Install optional deps for demos. From b99c073cca869c41a46cff7afd53a04b48edd89d Mon Sep 17 00:00:00 2001 From: Haolan Date: Tue, 2 Sep 2025 18:04:35 +0800 Subject: [PATCH 41/46] test: add test for compile options --- .../crosscompile/compile/libc/libc_test.go | 630 ++++++++++++++++++ 1 file changed, 630 insertions(+) create mode 100644 internal/crosscompile/compile/libc/libc_test.go diff --git a/internal/crosscompile/compile/libc/libc_test.go b/internal/crosscompile/compile/libc/libc_test.go new file mode 100644 index 00000000..20022229 --- /dev/null +++ b/internal/crosscompile/compile/libc/libc_test.go @@ -0,0 +1,630 @@ +package libc + +import ( + "path/filepath" + "testing" +) + +func TestGetPicolibcConfig(t *testing.T) { + baseDir := "/test/base" + target := "test-target" + + config := GetPicolibcConfig(baseDir, target) + + if config.Name != "picolibc" { + t.Errorf("Expected Name 'picolibc', got '%s'", config.Name) + } + if config.ArchiveSrcDir != "picolibc-main" { + t.Errorf("Expected ArchiveSrcDir 'picolibc-main', got '%s'", config.ArchiveSrcDir) + } + + // Test LibcCFlags + if len(config.LibcCFlags) != 2 { + t.Errorf("Expected 2 LibcCFlags, got %d", len(config.LibcCFlags)) + } else { + expected := "-I" + baseDir + if config.LibcCFlags[0] != expected { + t.Errorf("Expected LibcCFlags[0] to be '%s', got '%s'", expected, config.LibcCFlags[0]) + } + + expected = "-isystem" + filepath.Join(baseDir, "newlib", "libc", "include") + if config.LibcCFlags[1] != expected { + t.Errorf("Expected LibcCFlags[1] to be '%s', got '%s'", expected, config.LibcCFlags[1]) + } + } + + // Test Groups configuration + if len(config.Groups) != 1 { + t.Errorf("Expected 1 group, got %d", len(config.Groups)) + } else { + group := config.Groups[0] + + // Test output file name + expectedOutput := "libc-" + target + ".a" + if group.OutputFileName != expectedOutput { + t.Errorf("Expected OutputFileName '%s', got '%s'", expectedOutput, group.OutputFileName) + } + + // Test files list + if len(group.Files) == 0 { + t.Error("Expected non-empty files list") + } else { + // Check a few sample files + sampleFiles := []string{ + filepath.Join(baseDir, "newlib", "libc", "string", "bcmp.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "memcpy.c"), + filepath.Join(baseDir, "newlib", "libc", "string", "strlen.c"), + filepath.Join(baseDir, "newlib", "libc", "stdlib", "nano-malloc.c"), + filepath.Join(baseDir, "newlib", "libc", "tinystdio", "printf.c"), + } + + for _, sample := range sampleFiles { + found := false + for _, file := range group.Files { + if file == sample { + found = true + break + } + } + if !found { + t.Errorf("Expected file '%s' not found in group files", sample) + } + } + } + + // Test CFlags + expectedCFlags := []string{ + "-D_COMPILING_NEWLIB", + "-D_HAVE_ALIAS_ATTRIBUTE", + "-DTINY_STDIO", + "-DPOSIX_IO", + "-DFORMAT_DEFAULT_INTEGER", + "-D_IEEE_LIBM", + "-D__OBSOLETE_MATH_FLOAT=1", + "-D__OBSOLETE_MATH_DOUBLE=0", + "-D_WANT_IO_C99_FORMATS", + "-nostdlib", + "-I" + baseDir, + "-isystem" + filepath.Join(baseDir, "newlib", "libc", "include"), + "-I" + filepath.Join(baseDir, "newlib", "libm", "common"), + "-I" + filepath.Join(baseDir, "newlib", "libc", "locale"), + "-I" + filepath.Join(baseDir, "newlib", "libc", "tinystdio"), + } + + if len(group.CFlags) != len(expectedCFlags) { + t.Errorf("Expected %d CFlags, got %d", len(expectedCFlags), len(group.CFlags)) + } else { + for i, expected := range expectedCFlags { + if group.CFlags[i] != expected { + t.Errorf("CFlags[%d] mismatch. Expected '%s', got '%s'", i, expected, group.CFlags[i]) + } + } + } + + // Test LDFlags and CCFlags + if len(group.LDFlags) == 0 { + t.Error("Expected non-empty LDFlags") + } + if len(group.CCFlags) == 0 { + t.Error("Expected non-empty CCFlags") + } + } +} + +func TestGetPicolibcConfig_EdgeCases(t *testing.T) { + t.Run("EmptyBaseDir", func(t *testing.T) { + config := GetPicolibcConfig("", "test-target") + + // Check that paths are constructed correctly even with empty baseDir + expected := "-I" + if config.LibcCFlags[0] != expected { + t.Errorf("Expected LibcCFlags[0] to be '%s', got '%s'", expected, config.LibcCFlags[0]) + } + + expected = "-isystem" + filepath.Join("", "newlib", "libc", "include") + if config.LibcCFlags[1] != expected { + t.Errorf("Expected LibcCFlags[1] to be '%s', got '%s'", expected, config.LibcCFlags[1]) + } + }) + + t.Run("EmptyTarget", func(t *testing.T) { + config := GetPicolibcConfig("/test/base", "") + + // Check output file name formatting + expectedOutput := "libc-.a" + if config.Groups[0].OutputFileName != expectedOutput { + t.Errorf("Expected OutputFileName '%s', got '%s'", expectedOutput, config.Groups[0].OutputFileName) + } + }) +} + +func TestGetNewlibESP32ConfigRISCV(t *testing.T) { + baseDir := "/test/base" + target := "riscv32-unknown-elf" + + config := getNewlibESP32ConfigRISCV(baseDir, target) + + // Test basic configuration + if config.Url != _newlibUrl { + t.Errorf("Expected URL '%s', got '%s'", _newlibUrl, config.Url) + } + if config.Name != "newlib-esp32" { + t.Errorf("Expected Name 'newlib-esp32', got '%s'", config.Name) + } + if config.ArchiveSrcDir != _archiveInternalSrcDir { + t.Errorf("Expected ArchiveSrcDir '%s', got '%s'", _archiveInternalSrcDir, config.ArchiveSrcDir) + } + + // Test LibcCFlags + libcDir := filepath.Join(baseDir, "newlib", "libc") + expectedCFlags := []string{ + "-isystem" + filepath.Join(libcDir, "include"), + "-I" + filepath.Join(baseDir, "newlib"), + "-I" + libcDir, + } + if len(config.LibcCFlags) != len(expectedCFlags) { + t.Errorf("Expected %d LibcCFlags, got %d", len(expectedCFlags), len(config.LibcCFlags)) + } else { + for i, expected := range expectedCFlags { + if config.LibcCFlags[i] != expected { + t.Errorf("LibcCFlags[%d] mismatch. Expected '%s', got '%s'", i, expected, config.LibcCFlags[i]) + } + } + } + + // Test Groups configuration + if len(config.Groups) != 3 { + t.Errorf("Expected 3 groups, got %d", len(config.Groups)) + } else { + // Group 0: libcrt0 + group0 := config.Groups[0] + expectedOutput0 := "libcrt0-" + target + ".a" + if group0.OutputFileName != expectedOutput0 { + t.Errorf("Group0 OutputFileName expected '%s', got '%s'", expectedOutput0, group0.OutputFileName) + } + + // Check sample files in group0 + sampleFiles0 := []string{ + filepath.Join(baseDir, "libgloss", "riscv", "esp", "esp_board.c"), + filepath.Join(baseDir, "libgloss", "riscv", "esp", "crt1-board.S"), + } + for _, sample := range sampleFiles0 { + found := false + for _, file := range group0.Files { + if file == sample { + found = true + break + } + } + if !found { + t.Errorf("Expected file '%s' not found in group0 files", sample) + } + } + + // Group 1: libgloss + group1 := config.Groups[1] + expectedOutput1 := "libgloss-" + target + ".a" + if group1.OutputFileName != expectedOutput1 { + t.Errorf("Group1 OutputFileName expected '%s', got '%s'", expectedOutput1, group1.OutputFileName) + } + + // Check sample files in group1 + sampleFiles1 := []string{ + filepath.Join(baseDir, "libgloss", "libnosys", "close.c"), + filepath.Join(baseDir, "libgloss", "libnosys", "sbrk.c"), + } + for _, sample := range sampleFiles1 { + found := false + for _, file := range group1.Files { + if file == sample { + found = true + break + } + } + if !found { + t.Errorf("Expected file '%s' not found in group1 files", sample) + } + } + + // Group 2: libc + group2 := config.Groups[2] + expectedOutput2 := "libc-" + target + ".a" + if group2.OutputFileName != expectedOutput2 { + t.Errorf("Group2 OutputFileName expected '%s', got '%s'", expectedOutput2, group2.OutputFileName) + } + + // Check sample files in group2 + sampleFiles2 := []string{ + filepath.Join(libcDir, "string", "memcpy.c"), + filepath.Join(libcDir, "stdlib", "malloc.c"), + } + for _, sample := range sampleFiles2 { + found := false + for _, file := range group2.Files { + if file == sample { + found = true + break + } + } + if !found { + t.Errorf("Expected file '%s' not found in group2 files", sample) + } + } + + // Test CFlags for group2 + expectedCFlagsGroup2 := []string{ + "-DHAVE_CONFIG_H", + "-D_LIBC", + "-DHAVE_NANOSLEEP", + "-D__NO_SYSCALLS__", + // ... (other expected flags) + } + for _, expectedFlag := range expectedCFlagsGroup2 { + found := false + for _, flag := range group2.CFlags { + if flag == expectedFlag { + found = true + break + } + } + if !found { + t.Errorf("Expected flag '%s' not found in group2 CFlags", expectedFlag) + } + } + + // Test LDFlags and CCFlags + if len(group0.LDFlags) == 0 { + t.Error("Expected non-empty LDFlags in group0") + } + if len(group0.CCFlags) == 0 { + t.Error("Expected non-empty CCFlags in group0") + } + } +} + +func TestGetNewlibESP32ConfigXtensa(t *testing.T) { + baseDir := "/test/base" + target := "xtensa-esp32-elf" + + config := getNewlibESP32ConfigXtensa(baseDir, target) + + // Test basic configuration + if config.Url != _newlibUrl { + t.Errorf("Expected URL '%s', got '%s'", _newlibUrl, config.Url) + } + if config.Name != "newlib-esp32" { + t.Errorf("Expected Name 'newlib-esp32', got '%s'", config.Name) + } + if config.ArchiveSrcDir != _archiveInternalSrcDir { + t.Errorf("Expected ArchiveSrcDir '%s', got '%s'", _archiveInternalSrcDir, config.ArchiveSrcDir) + } + + // Test LibcCFlags + libcDir := filepath.Join(baseDir, "newlib", "libc") + expectedCFlags := []string{ + "-I" + filepath.Join(libcDir, "include"), + "-I" + filepath.Join(baseDir, "newlib"), + "-I" + libcDir, + } + if len(config.LibcCFlags) != len(expectedCFlags) { + t.Errorf("Expected %d LibcCFlags, got %d", len(expectedCFlags), len(config.LibcCFlags)) + } else { + for i, expected := range expectedCFlags { + if config.LibcCFlags[i] != expected { + t.Errorf("LibcCFlags[%d] mismatch. Expected '%s', got '%s'", i, expected, config.LibcCFlags[i]) + } + } + } + + // Test Groups configuration + if len(config.Groups) != 3 { + t.Errorf("Expected 2 groups, got %d", len(config.Groups)) + } else { + // Group 0: libcrt0 + group0 := config.Groups[0] + expectedOutput0 := "libcrt0-" + target + ".a" + if group0.OutputFileName != expectedOutput0 { + t.Errorf("Group0 OutputFileName expected '%s', got '%s'", expectedOutput0, group0.OutputFileName) + } + + // Check sample files in group0 + sampleFiles0 := []string{ + filepath.Join(baseDir, "libgloss", "xtensa", "clibrary_init.c"), + filepath.Join(baseDir, "libgloss", "xtensa", "crt1-boards.S"), + } + for _, sample := range sampleFiles0 { + found := false + for _, file := range group0.Files { + if file == sample { + found = true + break + } + } + if !found { + t.Errorf("Expected file '%s' not found in group0 files", sample) + } + } + + // Group 1: libgloss + libc + group1 := config.Groups[1] + expectedOutput1 := "libgloss-" + target + ".a" + if group1.OutputFileName != expectedOutput1 { + t.Errorf("Group1 OutputFileName expected '%s', got '%s'", expectedOutput1, group1.OutputFileName) + } + + // Check sample files in group1 + sampleFiles1 := []string{ + filepath.Join(baseDir, "libgloss", "libnosys", "close.c"), + } + for _, sample := range sampleFiles1 { + found := false + for _, file := range group1.Files { + if file == sample { + found = true + break + } + } + if !found { + t.Errorf("Expected file '%s' not found in group1 files", sample) + } + } + + // Test CFlags for group1 + expectedCFlagsGroup1 := []string{ + "-D__NO_SYSCALLS__", + "-D_NO_GETUT", + "-DHAVE_CONFIG_H", + "-D_LIBC", + // ... (other expected flags) + } + for _, expectedFlag := range expectedCFlagsGroup1 { + found := false + for _, flag := range group1.CFlags { + if flag == expectedFlag { + found = true + break + } + } + if !found { + t.Errorf("Expected flag '%s' not found in group1 CFlags", expectedFlag) + } + } + + // Test LDFlags and CCFlags + if len(group0.LDFlags) == 0 { + t.Error("Expected non-empty LDFlags in group0") + } + if len(group0.CCFlags) == 0 { + t.Error("Expected non-empty CCFlags in group0") + } + } +} + +func TestEdgeCases(t *testing.T) { + t.Run("EmptyBaseDir_RISCV", func(t *testing.T) { + config := getNewlibESP32ConfigRISCV("", "test-target") + libcDir := filepath.Join("", "newlib", "libc") + + // Check that paths are constructed correctly + expected := "-isystem" + filepath.Join(libcDir, "include") + if config.LibcCFlags[0] != expected { + t.Errorf("Expected LibcCFlags[0] to be '%s', got '%s'", expected, config.LibcCFlags[0]) + } + }) + + t.Run("EmptyTarget_RISCV", func(t *testing.T) { + config := getNewlibESP32ConfigRISCV("/test/base", "") + + // Check output file name formatting + expectedOutput := "libcrt0-.a" + if config.Groups[0].OutputFileName != expectedOutput { + t.Errorf("Expected OutputFileName '%s', got '%s'", expectedOutput, config.Groups[0].OutputFileName) + } + }) + + t.Run("EmptyBaseDir_Xtensa", func(t *testing.T) { + config := getNewlibESP32ConfigXtensa("", "test-target") + libcDir := filepath.Join("", "newlib", "libc") + + // Check that paths are constructed correctly + expected := "-I" + filepath.Join(libcDir, "include") + if config.LibcCFlags[0] != expected { + t.Errorf("Expected LibcCFlags[0] to be '%s', got '%s'", expected, config.LibcCFlags[0]) + } + }) + + t.Run("EmptyTarget_Xtensa", func(t *testing.T) { + config := getNewlibESP32ConfigXtensa("/test/base", "") + + // Check output file name formatting + expectedOutput := "libcrt0-.a" + if config.Groups[0].OutputFileName != expectedOutput { + t.Errorf("Expected OutputFileName '%s', got '%s'", expectedOutput, config.Groups[0].OutputFileName) + } + }) +} + +func TestGroupConfiguration(t *testing.T) { + baseDir := "/test/base" + target := "test-target" + + t.Run("RISCV_GroupCount", func(t *testing.T) { + config := getNewlibESP32ConfigRISCV(baseDir, target) + if len(config.Groups) != 3 { + t.Errorf("Expected 3 groups for RISCV, got %d", len(config.Groups)) + } + }) + + t.Run("Xtensa_GroupCount", func(t *testing.T) { + config := getNewlibESP32ConfigXtensa(baseDir, target) + if len(config.Groups) != 3 { + t.Errorf("Expected 2 groups for Xtensa, got %d", len(config.Groups)) + } + }) + + t.Run("RISCV_GroupNames", func(t *testing.T) { + config := getNewlibESP32ConfigRISCV(baseDir, target) + expectedNames := []string{ + "libcrt0-" + target + ".a", + "libgloss-" + target + ".a", + "libc-" + target + ".a", + } + + for i, group := range config.Groups { + if group.OutputFileName != expectedNames[i] { + t.Errorf("Group %d expected name '%s', got '%s'", i, expectedNames[i], group.OutputFileName) + } + } + }) + + t.Run("Xtensa_GroupNames", func(t *testing.T) { + config := getNewlibESP32ConfigXtensa(baseDir, target) + expectedNames := []string{ + "libcrt0-" + target + ".a", + "libgloss-" + target + ".a", + } + + for i, group := range config.Groups { + if i >= len(expectedNames) { + return + } + if group.OutputFileName != expectedNames[i] { + t.Errorf("Group %d expected name '%s', got '%s'", i, expectedNames[i], group.OutputFileName) + } + } + }) +} + +func TestCompilerFlags(t *testing.T) { + baseDir := "/test/base" + target := "test-target" + + t.Run("RISCV_CFlags", func(t *testing.T) { + config := getNewlibESP32ConfigRISCV(baseDir, target) + group := config.Groups[2] // libc group + + requiredFlags := []string{ + "-DHAVE_CONFIG_H", + "-D_LIBC", + "-D__NO_SYSCALLS__", + "-isystem" + filepath.Join(baseDir, "newlib", "libc", "include"), + } + + for _, flag := range requiredFlags { + found := false + for _, cflag := range group.CFlags { + if cflag == flag { + found = true + break + } + } + if !found { + t.Errorf("Required flag '%s' not found in RISCV CFlags", flag) + } + } + }) + + t.Run("Xtensa_CFlags", func(t *testing.T) { + config := getNewlibESP32ConfigXtensa(baseDir, target) + group := config.Groups[1] // libgloss+libc group + + requiredFlags := []string{ + "-D__NO_SYSCALLS__", + "-DHAVE_CONFIG_H", + "-D_LIBC", + "-isystem" + filepath.Join(baseDir, "newlib", "libc", "include"), + } + + for _, flag := range requiredFlags { + found := false + for _, cflag := range group.CFlags { + if cflag == flag { + found = true + break + } + } + if !found { + t.Errorf("Required flag '%s' not found in Xtensa CFlags", flag) + } + } + }) + + t.Run("CommonFlags", func(t *testing.T) { + configRISCV := getNewlibESP32ConfigRISCV(baseDir, target) + configXtensa := getNewlibESP32ConfigXtensa(baseDir, target) + + // Test LDFlags + expectedLDFlags := []string{ + "-nostdlib", + "-ffunction-sections", + "-fdata-sections", + } + + for _, group := range configRISCV.Groups { + for _, expected := range expectedLDFlags { + found := false + for _, flag := range group.LDFlags { + if flag == expected { + found = true + break + } + } + if !found { + t.Errorf("Required LDFlag '%s' not found in RISCV group", expected) + } + } + } + + for _, group := range configXtensa.Groups { + for _, expected := range expectedLDFlags { + found := false + for _, flag := range group.LDFlags { + if flag == expected { + found = true + break + } + } + if !found { + t.Errorf("Required LDFlag '%s' not found in Xtensa group", expected) + } + } + } + + // Test CCFlags + expectedCCFlags := []string{ + "-Oz", + "-fno-builtin", + "-ffreestanding", + } + + for _, group := range configRISCV.Groups { + for _, expected := range expectedCCFlags { + found := false + for _, flag := range group.CCFlags { + if flag == expected { + found = true + break + } + } + if !found { + t.Errorf("Required CCFlag '%s' not found in RISCV group", expected) + } + } + } + + for _, group := range configXtensa.Groups { + for _, expected := range expectedCCFlags { + found := false + for _, flag := range group.CCFlags { + if flag == expected { + found = true + break + } + } + if !found { + t.Errorf("Required CCFlag '%s' not found in Xtensa group", expected) + } + } + } + }) +} From 82bb6e84d07d46d36d0e54cf5f3960c92e088162 Mon Sep 17 00:00:00 2001 From: Haolan Date: Tue, 2 Sep 2025 18:23:28 +0800 Subject: [PATCH 42/46] test: add rt test --- .../crosscompile/compile/rtlib/rt_test.go | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 internal/crosscompile/compile/rtlib/rt_test.go diff --git a/internal/crosscompile/compile/rtlib/rt_test.go b/internal/crosscompile/compile/rtlib/rt_test.go new file mode 100644 index 00000000..58aeb05e --- /dev/null +++ b/internal/crosscompile/compile/rtlib/rt_test.go @@ -0,0 +1,124 @@ +package rtlib + +import ( + "strings" + "testing" +) + +func TestPlatformSpecifiedFiles(t *testing.T) { + tests := []struct { + target string + expected int // Number of expected files + }{ + {"riscv32-unknown-elf", 5}, + {"riscv64-unknown-elf", 27}, + {"arm-none-eabi", 19}, + {"avr-unknown-elf", 6}, + {"xtensa", 2}, + {"x86_64-pc-windows", 0}, + } + + builtinsDir := "/test/builtins" + for _, tt := range tests { + t.Run(tt.target, func(t *testing.T) { + result := platformSpecifiedFiles(builtinsDir, tt.target) + if len(result) != tt.expected { + t.Errorf("For target %s, expected %d files, got %d", tt.target, tt.expected, len(result)) + } + }) + } +} + +func TestWithPlatformSpecifiedFiles(t *testing.T) { + baseDir := "/test/base" + target := "riscv32-unknown-elf" + inputFiles := []string{"file1.c", "file2.c"} + + result := withPlatformSpecifiedFiles(baseDir, target, inputFiles) + + // Should have input files + platform specific files + if len(result) <= len(inputFiles) { + t.Errorf("Expected more files than input, got %d", len(result)) + } + + // Check that input files are preserved + for _, inputFile := range inputFiles { + found := false + for _, resultFile := range result { + if resultFile == inputFile { + found = true + break + } + } + if !found { + t.Errorf("Input file %s not found in result", inputFile) + } + } +} + +func TestGetCompilerRTConfig(t *testing.T) { + baseDir := "/test/base" + target := "riscv32-unknown-elf" + + config := GetCompilerRTConfig(baseDir, target) + + // Test groups configuration + if len(config.Groups) != 1 { + t.Errorf("Expected 1 group, got %d", len(config.Groups)) + } else { + group := config.Groups[0] + expectedOutput := "libclang_builtins-" + target + ".a" + if group.OutputFileName != expectedOutput { + t.Errorf("Expected output file %s, got %s", expectedOutput, group.OutputFileName) + } + + // Check that files list contains platform-specific files + if len(group.Files) == 0 { + t.Error("Expected non-empty files list") + } + + // Check that CFlags are set + if len(group.CFlags) == 0 { + t.Error("Expected non-empty CFlags") + } + + // Check that CCFlags are set + if len(group.CCFlags) == 0 { + t.Error("Expected non-empty CCFlags") + } + } +} + +func TestGetCompilerRTConfig_DifferentTargets(t *testing.T) { + targets := []string{ + "riscv32-unknown-elf", + "riscv64-unknown-elf", + "arm-none-eabi", + "avr-unknown-elf", + "xtensa", + } + + baseDir := "/test/base" + for _, target := range targets { + t.Run(target, func(t *testing.T) { + config := GetCompilerRTConfig(baseDir, target) + + // Basic validation + if config.Url == "" { + t.Error("URL should not be empty") + } + if config.ArchiveSrcDir == "" { + t.Error("ArchiveSrcDir should not be empty") + } + if len(config.Groups) == 0 { + t.Error("Should have at least one group") + } + + // Check output filename contains target + group := config.Groups[0] + if !strings.Contains(group.OutputFileName, target) { + t.Errorf("Output filename %s should contain target %s", group.OutputFileName, target) + } + }) + } +} From 5a4c83ef850568f2445cb2511ea246656891d916 Mon Sep 17 00:00:00 2001 From: Haolan Date: Tue, 2 Sep 2025 18:27:59 +0800 Subject: [PATCH 43/46] test: add _embdemo print test --- _embdemo/hello/main.go | 11 +++ _embdemo/hello/uart.go | 4 + internal/crosscompile/fetch_test.go | 128 ++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 _embdemo/hello/main.go create mode 100644 _embdemo/hello/uart.go diff --git a/_embdemo/hello/main.go b/_embdemo/hello/main.go new file mode 100644 index 00000000..3cf6a208 --- /dev/null +++ b/_embdemo/hello/main.go @@ -0,0 +1,11 @@ +package main + +func myprint(s string) { + for i := 0; i < len(s); i++ { + WriteByte(s[i]) + } +} + +func main() { + myprint("hello world") +} diff --git a/_embdemo/hello/uart.go b/_embdemo/hello/uart.go new file mode 100644 index 00000000..682443fb --- /dev/null +++ b/_embdemo/hello/uart.go @@ -0,0 +1,4 @@ +package main + +//go:linkname WriteByte C.board_uart_write_char +func WriteByte(b byte) diff --git a/internal/crosscompile/fetch_test.go b/internal/crosscompile/fetch_test.go index a9f45b4f..d5e4bc57 100644 --- a/internal/crosscompile/fetch_test.go +++ b/internal/crosscompile/fetch_test.go @@ -5,6 +5,7 @@ package crosscompile import ( "archive/tar" + "archive/zip" "compress/gzip" "fmt" "net/http" @@ -648,3 +649,130 @@ func TestESPClangDownloadWhenNotExists(t *testing.T) { } } } + +func TestExtractZip(t *testing.T) { + // Create temporary test directory + tempDir := t.TempDir() + zipPath := filepath.Join(tempDir, "test.zip") + destDir := filepath.Join(tempDir, "extracted") + + // 1. Test successful extraction + t.Run("SuccessfulExtraction", func(t *testing.T) { + // Create test ZIP file + if err := createTestZip(zipPath); err != nil { + t.Fatalf("Failed to create test zip: %v", err) + } + + // Execute extraction + if err := extractZip(zipPath, destDir); err != nil { + t.Fatalf("extractZip failed: %v", err) + } + + // Verify extraction results + verifyExtraction(t, destDir) + }) + + // 2. Test invalid ZIP file + t.Run("InvalidZipFile", func(t *testing.T) { + // Create invalid ZIP file (actually a text file) + if err := os.WriteFile(zipPath, []byte("not a zip file"), 0644); err != nil { + t.Fatal(err) + } + + // Execute extraction and expect error + if err := extractZip(zipPath, destDir); err == nil { + t.Error("Expected error for invalid zip file, got nil") + } + }) + + // 3. Test non-writable destination + t.Run("UnwritableDestination", func(t *testing.T) { + // Create test ZIP file + if err := createTestZip(zipPath); err != nil { + t.Fatal(err) + } + + // Create read-only destination directory + readOnlyDir := filepath.Join(tempDir, "readonly") + if err := os.MkdirAll(readOnlyDir, 0400); err != nil { + t.Fatal(err) + } + + // Execute extraction and expect error + if err := extractZip(zipPath, readOnlyDir); err == nil { + t.Error("Expected error for unwritable destination, got nil") + } + }) +} + +// Create test ZIP file +func createTestZip(zipPath string) error { + // Create ZIP file + zipFile, err := os.Create(zipPath) + if err != nil { + return err + } + defer zipFile.Close() + + zipWriter := zip.NewWriter(zipFile) + defer zipWriter.Close() + + // Add directory + dirHeader := &zip.FileHeader{ + Name: "testdir/", + Method: zip.Deflate, + Modified: time.Now(), + } + dirHeader.SetMode(os.ModeDir | 0755) + if _, err := zipWriter.CreateHeader(dirHeader); err != nil { + return err + } + + // Add file1 + file1, err := zipWriter.Create("file1.txt") + if err != nil { + return err + } + if _, err := file1.Write([]byte("Hello from file1")); err != nil { + return err + } + + // Add nested file + nestedFile, err := zipWriter.Create("testdir/nested.txt") + if err != nil { + return err + } + if _, err := nestedFile.Write([]byte("Nested content")); err != nil { + return err + } + + return nil +} + +// Verify extraction results +func verifyExtraction(t *testing.T, destDir string) { + // Verify directory exists + if _, err := os.Stat(filepath.Join(destDir, "testdir")); err != nil { + t.Errorf("Directory not extracted: %v", err) + } + + // Verify file1 content + file1Path := filepath.Join(destDir, "file1.txt") + content, err := os.ReadFile(file1Path) + if err != nil { + t.Errorf("Failed to read file1: %v", err) + } + if string(content) != "Hello from file1" { + t.Errorf("File1 content mismatch. Got: %s", content) + } + + // Verify nested file content + nestedPath := filepath.Join(destDir, "testdir", "nested.txt") + content, err = os.ReadFile(nestedPath) + if err != nil { + t.Errorf("Failed to read nested file: %v", err) + } + if string(content) != "Nested content" { + t.Errorf("Nested file content mismatch. Got: %s", content) + } +} From 1bd9ceb44450b94a9f5eb6b784d2c27445f4cbb3 Mon Sep 17 00:00:00 2001 From: Haolan Date: Tue, 2 Sep 2025 20:06:48 +0800 Subject: [PATCH 44/46] test: fix _embdemo --- _embdemo/hello-esp32/main.go | 16 ++++++++++++++++ _embdemo/hello-esp32/uart.go | 13 +++++++++++++ _embdemo/hello/main.go | 11 ----------- _embdemo/hello/uart.go | 4 ---- _embdemo/write-esp32/main.go | 12 ++++++++++++ 5 files changed, 41 insertions(+), 15 deletions(-) create mode 100644 _embdemo/hello-esp32/main.go create mode 100644 _embdemo/hello-esp32/uart.go delete mode 100644 _embdemo/hello/main.go delete mode 100644 _embdemo/hello/uart.go create mode 100644 _embdemo/write-esp32/main.go diff --git a/_embdemo/hello-esp32/main.go b/_embdemo/hello-esp32/main.go new file mode 100644 index 00000000..9b36080c --- /dev/null +++ b/_embdemo/hello-esp32/main.go @@ -0,0 +1,16 @@ +package main + +import "github.com/goplus/lib/c" + +func myprint(s *c.Char) { + for i := 0; i < int(c.Strlen(s)); i++ { + WriteByte(byte(c.Index(s, i))) + } +} + +func main() { + for { + myprint(c.Str("hello world")) + sleep(1) + } +} diff --git a/_embdemo/hello-esp32/uart.go b/_embdemo/hello-esp32/uart.go new file mode 100644 index 00000000..1cd3a5ab --- /dev/null +++ b/_embdemo/hello-esp32/uart.go @@ -0,0 +1,13 @@ +package main + +import ( + _ "unsafe" + + "github.com/goplus/lib/c" +) + +//go:linkname WriteByte C.board_uart_write_char +func WriteByte(b byte) + +//go:linkname sleep sleep +func sleep(c c.Int) diff --git a/_embdemo/hello/main.go b/_embdemo/hello/main.go deleted file mode 100644 index 3cf6a208..00000000 --- a/_embdemo/hello/main.go +++ /dev/null @@ -1,11 +0,0 @@ -package main - -func myprint(s string) { - for i := 0; i < len(s); i++ { - WriteByte(s[i]) - } -} - -func main() { - myprint("hello world") -} diff --git a/_embdemo/hello/uart.go b/_embdemo/hello/uart.go deleted file mode 100644 index 682443fb..00000000 --- a/_embdemo/hello/uart.go +++ /dev/null @@ -1,4 +0,0 @@ -package main - -//go:linkname WriteByte C.board_uart_write_char -func WriteByte(b byte) diff --git a/_embdemo/write-esp32/main.go b/_embdemo/write-esp32/main.go new file mode 100644 index 00000000..dd59a86c --- /dev/null +++ b/_embdemo/write-esp32/main.go @@ -0,0 +1,12 @@ +package main + +import "github.com/goplus/lib/c" + +func main() { + buf := c.Malloc(6) + c.Memset(buf, 0, 6) + c.Strncpy((*c.Char)(buf), c.Str("abcde"), 5) + + write(1, (*c.Char)(buf), 5) + +} From dd3c1f923dd891265efed5c85d983d0a3e3903c7 Mon Sep 17 00:00:00 2001 From: Haolan Date: Tue, 2 Sep 2025 22:25:27 +0800 Subject: [PATCH 45/46] test: fix _embdemo write test --- _embdemo/write-esp32/main.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/_embdemo/write-esp32/main.go b/_embdemo/write-esp32/main.go index dd59a86c..9bebb933 100644 --- a/_embdemo/write-esp32/main.go +++ b/_embdemo/write-esp32/main.go @@ -1,6 +1,12 @@ package main -import "github.com/goplus/lib/c" +import ( + _ "unsafe" + "github.com/goplus/lib/c" +) + +//go:linkname write C.write +func write(fd c.Int, *c.Char, c.SizeT) int func main() { buf := c.Malloc(6) @@ -8,5 +14,4 @@ func main() { c.Strncpy((*c.Char)(buf), c.Str("abcde"), 5) write(1, (*c.Char)(buf), 5) - } From 977806affc3b2302d02f7496d16789222535d5a5 Mon Sep 17 00:00:00 2001 From: Haolan Date: Tue, 2 Sep 2025 22:35:08 +0800 Subject: [PATCH 46/46] test: add more libc test --- _embdemo/write-esp32/main.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/_embdemo/write-esp32/main.go b/_embdemo/write-esp32/main.go index 9bebb933..253af7ad 100644 --- a/_embdemo/write-esp32/main.go +++ b/_embdemo/write-esp32/main.go @@ -2,16 +2,30 @@ package main import ( _ "unsafe" + "github.com/goplus/lib/c" ) //go:linkname write C.write -func write(fd c.Int, *c.Char, c.SizeT) int +func write(c.Int, *c.Char, c.SizeT) int func main() { buf := c.Malloc(6) c.Memset(buf, 0, 6) c.Strncpy((*c.Char)(buf), c.Str("abcde"), 5) + if c.Strcmp((*c.Char)(buf), c.Str("abcde")) == 0 { + write(1, c.Str("pass strcmp"), 11) + } + + if byte(c.Index((*c.Char)(buf), 0)) == 'a' { + write(1, c.Str("pass index"), 10) + } + + c.Memset(buf, c.Int('A'), 5) + if c.Strcmp((*c.Char)(buf), c.Str("AAAAA")) == 0 { + write(1, c.Str("pass memeset"), 11) + } + write(1, (*c.Char)(buf), 5) }