{"record":{"id":"cae0a9c9e3c30d05","repo":"golang/go","slug":"package-using-cgo-has-go-assembly-file-s","errorCode":null,"errorMessage":"package using cgo has Go assembly file %s","messagePattern":"package using cgo has Go assembly file (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/work/exec.go","lineNumber":2546,"sourceCode":"func (noToolchain) cc(b *Builder, a *Action, ofile, cfile string) error {\n\treturn noCompiler()\n}\n\n// gcc runs the gcc C compiler to create an object from a single C file.\nfunc (b *Builder) gcc(a *Action, workdir, out string, flags []string, cfile string) error {\n\tp := a.Package\n\treturn b.ccompile(a, out, flags, cfile, b.GccCmd(p.Dir, workdir))\n}\n\n// gas runs the gcc c compiler to create an object file from a single C assembly file.\nfunc (b *Builder) gas(a *Action, workdir, out string, flags []string, sfile string) error {\n\tp := a.Package\n\tdata, err := os.ReadFile(sfile)\n\tif err == nil {\n\t\tif bytes.HasPrefix(data, []byte(\"TEXT\")) || bytes.Contains(data, []byte(\"\\nTEXT\")) ||\n\t\t\tbytes.HasPrefix(data, []byte(\"DATA\")) || bytes.Contains(data, []byte(\"\\nDATA\")) ||\n\t\t\tbytes.HasPrefix(data, []byte(\"GLOBL\")) || bytes.Contains(data, []byte(\"\\nGLOBL\")) {\n\t\t\treturn fmt.Errorf(\"package using cgo has Go assembly file %s\", sfile)\n\t\t}\n\t}\n\treturn b.ccompile(a, out, flags, sfile, b.GccCmd(p.Dir, workdir))\n}\n\n// gxx runs the g++ C++ compiler to create an object from a single C++ file.\nfunc (b *Builder) gxx(a *Action, workdir, out string, flags []string, cxxfile string) error {\n\tp := a.Package\n\treturn b.ccompile(a, out, flags, cxxfile, b.GxxCmd(p.Dir, workdir))\n}\n\n// gfortran runs the gfortran Fortran compiler to create an object from a single Fortran file.\nfunc (b *Builder) gfortran(a *Action, workdir, out string, flags []string, ffile string) error {\n\tp := a.Package\n\treturn b.ccompile(a, out, flags, ffile, b.gfortranCmd(p.Dir, workdir))\n}\n\n// ccompile runs the given C or C++ compiler and creates an object from a single source file.","sourceCodeStart":2528,"sourceCodeEnd":2564,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/work/exec.go#L2528-L2564","documentation":"For cgo packages, the gas function compiles .s assembly files with gcc (the C assembler). Before doing so it scans each file's bytes for Go-plan9-assembler directives TEXT, DATA, or GLOBL (at the start or after a newline). If any are present, the build aborts because a cgo package cannot mix Go-style assembly with C-style assembly; the flagged file must use GAS syntax instead.","triggerScenarios":"Fires in gas when bytes.HasPrefix or bytes.Contains matches TEXT, DATA, or GLOBL in an assembly file of a package that uses cgo.","commonSituations":"Copying a Go assembly file (from a non-cgo package) into a cgo package, or writing Go-assembler syntax in a .s file that is compiled through the cgo/gcc path.","solutions":["Open the flagged .s file and confirm it uses Go-assembler directives (TEXT/DATA/GLOBL)","Rewrite the file in standard GAS (C) assembly syntax, or remove it","Move the Go assembly into a separate non-cgo package that builds with the gc assembler"],"exampleFix":"// before (Go asm in a cgo package .s file)\nTEXT ·myFunc(SB), $0\n    RET\n// after (GAS syntax, or delete and implement in Go)\nmyfunc:\n    ret","handlingStrategy":"validation","validationCode":"// Scan .s files for Go-assembler directives before a cgo build\nfunc hasGoAsmDirectives(path string) bool {\n    data, err := os.ReadFile(path)\n    if err != nil { return false }\n    for _, d := range []string{\"TEXT\", \"DATA\", \"GLOBL\"} {\n        if bytes.HasPrefix(data, []byte(d)) || bytes.Contains(data, []byte(\"\\n\"+d)) {\n            return true\n        }\n    }\n    return false\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep Go-plan9 assembly (.s with TEXT/DATA/GLOBL) out of cgo packages","Use GAS syntax for assembly in cgo packages, or implement in Go","Audit copied .s files when moving them between cgo and non-cgo packages"],"tags":["go-toolchain","cgo","assembly","compiler"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}