feat: support compiler-rt
This commit is contained in:
@@ -907,7 +907,7 @@ define weak void @_start() {
|
|||||||
if !needStart(ctx.buildConf) && isWasmTarget(ctx.buildConf.Goos) {
|
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"
|
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 = ""
|
startDefine = ""
|
||||||
}
|
}
|
||||||
mainCode := fmt.Sprintf(`; ModuleID = 'main'
|
mainCode := fmt.Sprintf(`; ModuleID = 'main'
|
||||||
|
|||||||
99
internal/crosscompile/compile/compile.go
Normal file
99
internal/crosscompile/compile/compile.go
Normal file
@@ -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
|
||||||
|
}
|
||||||
@@ -1,20 +1,22 @@
|
|||||||
package crosscompile
|
package libc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/internal/crosscompile/compile"
|
||||||
)
|
)
|
||||||
|
|
||||||
// getNewlibESP32Config returns configuration for newlib esp32
|
// 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")
|
libcDir := filepath.Join(baseDir, "newlib", "libc")
|
||||||
|
|
||||||
// headerFile, _ := os.Create(filepath.Join(baseDir, "picolibc.h"))
|
// headerFile, _ := os.Create(filepath.Join(baseDir, "picolibc.h"))
|
||||||
// headerFile.Close()
|
// headerFile.Close()
|
||||||
|
|
||||||
return &compileLibcConfig{
|
return &compile.CompileConfig{
|
||||||
Url: "https://github.com/MeteorsLiu/newlib-esp32/archive/refs/heads/esp-4.3.0.zip",
|
Url: "https://github.com/MeteorsLiu/newlib-esp32/archive/refs/heads/esp-4.3.0.zip",
|
||||||
Name: "newlib-esp32",
|
Name: "newlib-esp32",
|
||||||
Groups: []compileGroup{
|
Groups: []compile.CompileGroup{
|
||||||
{
|
{
|
||||||
OutputFileName: "libcrt0.a",
|
OutputFileName: "libcrt0.a",
|
||||||
Files: []string{
|
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", "boards", "esp32", "board.c"),
|
||||||
filepath.Join(baseDir, "libgloss", "xtensa", "crt1-boards.S"),
|
filepath.Join(baseDir, "libgloss", "xtensa", "crt1-boards.S"),
|
||||||
filepath.Join(baseDir, "libgloss", "xtensa", "sleep.S"),
|
filepath.Join(baseDir, "libgloss", "xtensa", "sleep.S"),
|
||||||
filepath.Join(baseDir, "libgloss", "xtensa", "window-vectors.S"),
|
|
||||||
},
|
},
|
||||||
CFlags: []string{
|
CFlags: []string{
|
||||||
"-DHAVE_CONFIG_H",
|
"-DHAVE_CONFIG_H",
|
||||||
@@ -974,7 +975,7 @@ func getNewlibESP32Config(baseDir, arch string) *compileLibcConfig {
|
|||||||
"-I" + filepath.Join(libcDir, "posix"),
|
"-I" + filepath.Join(libcDir, "posix"),
|
||||||
"-I" + filepath.Join(libcDir, "stdlib"),
|
"-I" + filepath.Join(libcDir, "stdlib"),
|
||||||
},
|
},
|
||||||
LDFlags: []string{"-nostdlib", "-L" + baseDir, "-lgloss"},
|
LDFlags: []string{"-nostdlib"},
|
||||||
CCFlags: []string{
|
CCFlags: []string{
|
||||||
"-Oz",
|
"-Oz",
|
||||||
"-fno-builtin",
|
"-fno-builtin",
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
package crosscompile
|
package libc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/internal/crosscompile/compile"
|
||||||
)
|
)
|
||||||
|
|
||||||
// getPicolibcConfig returns configuration for picolibc
|
// getPicolibcConfig returns configuration for picolibc
|
||||||
func getPicolibcConfig(baseDir string) *compileLibcConfig {
|
func GetPicolibcConfig(baseDir string) *compile.CompileConfig {
|
||||||
libcIncludeDir := filepath.Join(baseDir, "libc", "include")
|
libcIncludeDir := filepath.Join(baseDir, "libc", "include")
|
||||||
libmIncludeDir := filepath.Join(baseDir, "libm", "common")
|
libmIncludeDir := filepath.Join(baseDir, "libm", "common")
|
||||||
localeIncludeDir := filepath.Join(baseDir, "libc", "locale")
|
localeIncludeDir := filepath.Join(baseDir, "libc", "locale")
|
||||||
@@ -16,10 +18,10 @@ func getPicolibcConfig(baseDir string) *compileLibcConfig {
|
|||||||
headerFile, _ := os.Create(filepath.Join(baseDir, "picolibc.h"))
|
headerFile, _ := os.Create(filepath.Join(baseDir, "picolibc.h"))
|
||||||
headerFile.Close()
|
headerFile.Close()
|
||||||
|
|
||||||
return &compileLibcConfig{
|
return &compile.CompileConfig{
|
||||||
Url: "https://github.com/picolibc/picolibc/releases/download/1.8.10/picolibc-1.8.10.tar.xz",
|
Url: "https://github.com/picolibc/picolibc/releases/download/1.8.10/picolibc-1.8.10.tar.xz",
|
||||||
Name: "picolibc",
|
Name: "picolibc",
|
||||||
Groups: []compileGroup{
|
Groups: []compile.CompileGroup{
|
||||||
{
|
{
|
||||||
OutputFileName: "libc.a",
|
OutputFileName: "libc.a",
|
||||||
Files: []string{
|
Files: []string{
|
||||||
195
internal/crosscompile/compile/rtlib/compiler_rt.go
Normal file
195
internal/crosscompile/compile/rtlib/compiler_rt.go
Normal file
@@ -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",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/internal/crosscompile/compile"
|
||||||
"github.com/goplus/llgo/internal/env"
|
"github.com/goplus/llgo/internal/env"
|
||||||
"github.com/goplus/llgo/internal/targets"
|
"github.com/goplus/llgo/internal/targets"
|
||||||
"github.com/goplus/llgo/internal/xtool/llvm"
|
"github.com/goplus/llgo/internal/xtool/llvm"
|
||||||
@@ -219,15 +220,8 @@ func ldFlagsFromFileName(fileName string) string {
|
|||||||
return strings.TrimPrefix(strings.TrimSuffix(fileName, ".a"), "lib")
|
return strings.TrimPrefix(strings.TrimSuffix(fileName, ".a"), "lib")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getOrCompileLibc(cc, linkerName, libcName string, exportCCFlags, exportLDFlags []string) (ldflags []string, err error) {
|
func getOrCompileWithConfig(compileConfig *compile.CompileConfig, outputDir, cc, linkerName, libName string, exportCCFlags, exportLDFlags []string) (ldflags []string, err error) {
|
||||||
baseDir := filepath.Join(cacheRoot(), "crosscompile")
|
if err = checkDownloadAndExtractLib(compileConfig, compileConfig.Url, outputDir, compileConfig.ArchiveSrcDir); err != nil {
|
||||||
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 {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ldflags = append(ldflags, "-nostdlib", "-L"+outputDir)
|
ldflags = append(ldflags, "-nostdlib", "-L"+outputDir)
|
||||||
@@ -606,13 +600,38 @@ func useTarget(targetName string) (export Export, err error) {
|
|||||||
|
|
||||||
if config.Libc != "" {
|
if config.Libc != "" {
|
||||||
var libcLDFlags []string
|
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 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ldflags = append(ldflags, libcLDFlags...)
|
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
|
// Combine with config flags and expand template variables
|
||||||
export.CFLAGS = cflags
|
export.CFLAGS = cflags
|
||||||
export.CCFLAGS = ccflags
|
export.CCFLAGS = ccflags
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/internal/crosscompile/compile"
|
||||||
)
|
)
|
||||||
|
|
||||||
// checkDownloadAndExtractWasiSDK downloads and extracts WASI SDK
|
// checkDownloadAndExtractWasiSDK downloads and extracts WASI SDK
|
||||||
@@ -80,7 +82,7 @@ func checkDownloadAndExtractESPClang(platformSuffix, dir string) error {
|
|||||||
return nil
|
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
|
// Check if already exists
|
||||||
if cfg.IsCompiled(dstDir) {
|
if cfg.IsCompiled(dstDir) {
|
||||||
return nil
|
return nil
|
||||||
@@ -107,7 +109,7 @@ func checkDownloadAndExtractLibc(cfg *compileLibcConfig, url, dstDir, internalAr
|
|||||||
if err := downloadAndExtractArchive(url, tempExtractDir, description); err != nil {
|
if err := downloadAndExtractArchive(url, tempExtractDir, description); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// defer os.RemoveAll(tempExtractDir)
|
defer os.RemoveAll(tempExtractDir)
|
||||||
|
|
||||||
srcDir := tempExtractDir
|
srcDir := tempExtractDir
|
||||||
|
|
||||||
@@ -115,6 +117,7 @@ func checkDownloadAndExtractLibc(cfg *compileLibcConfig, url, dstDir, internalAr
|
|||||||
srcDir = filepath.Join(tempExtractDir, internalArchiveSrcDir)
|
srcDir = filepath.Join(tempExtractDir, internalArchiveSrcDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
os.RemoveAll(dstDir)
|
||||||
if err := os.Rename(srcDir, dstDir); err != nil {
|
if err := os.Rename(srcDir, dstDir); err != nil {
|
||||||
return fmt.Errorf("failed to rename libc directory: %w", err)
|
return fmt.Errorf("failed to rename libc directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,105 +2,16 @@ package crosscompile
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
"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 {
|
// GetCompileConfigByName retrieves libc compilation configuration by name
|
||||||
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
|
|
||||||
// Returns compilation file lists and corresponding cflags
|
// Returns compilation file lists and corresponding cflags
|
||||||
func getCompileLibcConfigByName(baseDir, libcName string) (*compileLibcConfig, error) {
|
func getLibcCompileConfigByName(baseDir, libcName string) (*compile.CompileConfig, error) {
|
||||||
if libcName == "" {
|
if libcName == "" {
|
||||||
return nil, fmt.Errorf("libc name cannot be empty")
|
return nil, fmt.Errorf("libc name cannot be empty")
|
||||||
}
|
}
|
||||||
@@ -108,10 +19,24 @@ func getCompileLibcConfigByName(baseDir, libcName string) (*compileLibcConfig, e
|
|||||||
|
|
||||||
switch libcName {
|
switch libcName {
|
||||||
case "picolibc":
|
case "picolibc":
|
||||||
return getPicolibcConfig(libcDir), nil
|
return libc.GetPicolibcConfig(libcDir), nil
|
||||||
case "newlib-esp32":
|
case "newlib-esp32":
|
||||||
return getNewlibESP32Config(libcDir, "xtensa"), nil
|
return libc.GetNewlibESP32Config(libcDir, "xtensa"), nil
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unsupported libc: %s", libcName)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ type Config struct {
|
|||||||
|
|
||||||
// Compiler and linker configuration
|
// Compiler and linker configuration
|
||||||
Libc string `json:"libc"`
|
Libc string `json:"libc"`
|
||||||
|
RTLib string `json:"rtlib"`
|
||||||
Linker string `json:"linker"`
|
Linker string `json:"linker"`
|
||||||
LinkerScript string `json:"linkerscript"`
|
LinkerScript string `json:"linkerscript"`
|
||||||
CFlags []string `json:"cflags"`
|
CFlags []string `json:"cflags"`
|
||||||
|
|||||||
@@ -137,6 +137,9 @@ func (l *Loader) mergeConfig(dst, src *Config) {
|
|||||||
if src.Libc != "" {
|
if src.Libc != "" {
|
||||||
dst.Libc = src.Libc
|
dst.Libc = src.Libc
|
||||||
}
|
}
|
||||||
|
if src.RTLib != "" {
|
||||||
|
dst.RTLib = src.RTLib
|
||||||
|
}
|
||||||
if src.Linker != "" {
|
if src.Linker != "" {
|
||||||
dst.Linker = src.Linker
|
dst.Linker = src.Linker
|
||||||
}
|
}
|
||||||
|
|||||||
130
targets/esp32.rom.newlib-funcs.ld
Normal file
130
targets/esp32.rom.newlib-funcs.ld
Normal file
@@ -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;
|
||||||
Reference in New Issue
Block a user