]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile, cmd/link: use libFuzzer 8-bit instead of extra counters
authorKhaled Yakdan <yakdan@code-intelligence.com>
Wed, 18 May 2022 08:54:30 +0000 (08:54 +0000)
committerKeith Randall <khr@golang.org>
Fri, 20 May 2022 21:32:57 +0000 (21:32 +0000)
By using libFuzzer’s 8-bit counters instead of extra counters, the
coverage instrumentation in libFuzzer mode is improved in three ways:
  1- 8-bit counters are supported on all platforms, including macOS and
     Windows, with all relevant versions of libFuzzer, whereas extra
     counters are a Linux-only feature that only recently received
     support on Windows.
  2- Newly covered blocks are now properly reported as new coverage by
     libFuzzer, not only as new features.
  3- The NeverZero strategy is used to ensure that coverage counters
     never become 0 again after having been positive once. This resolves
     issues encountered when fuzzing loops with iteration counts that
     are multiples of 256 (e.g., larger powers of two).

Change-Id: I9021210d7fbffd07c891ad08750402ee91cb3df5
GitHub-Last-Rev: 9057e4b21d146ce9ffb3993982bfb84b96705989
GitHub-Pull-Request: golang/go#51318
Reviewed-on: https://go-review.googlesource.com/c/go/+/387334
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
14 files changed:
src/cmd/compile/internal/gc/obj.go
src/cmd/compile/internal/ir/name.go
src/cmd/compile/internal/ssa/writebarrier.go
src/cmd/compile/internal/walk/order.go
src/cmd/internal/objabi/symkind.go
src/cmd/internal/objabi/symkind_string.go
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/elf.go
src/cmd/link/internal/ld/xcoff.go
src/cmd/link/internal/sym/symkind.go
src/cmd/link/internal/sym/symkind_string.go
src/runtime/libfuzzer.go
src/runtime/libfuzzer_amd64.s
src/runtime/libfuzzer_arm64.s

index e33f726e347a0d5a3cd1469e0d681e4a0824a796..5008aa212aa72782ae1560723226463c168f9618 100644 (file)
@@ -313,8 +313,8 @@ func ggloblnod(nam *ir.Name) {
        } else {
                base.Ctxt.Globl(s, size, flags)
        }
-       if nam.LibfuzzerExtraCounter() {
-               s.Type = objabi.SLIBFUZZER_EXTRA_COUNTER
+       if nam.Libfuzzer8BitCounter() {
+               s.Type = objabi.SLIBFUZZER_8BIT_COUNTER
        }
        if nam.Sym().Linkname != "" {
                // Make sure linkname'd symbol is non-package. When a symbol is
index 59269ff271cdd9ea599216d0e1dd649ee156b295..711d1dedc56ec1819e954cc4bbb9fbc9ab7e0dfd 100644 (file)
@@ -235,7 +235,7 @@ const (
        nameInlFormal                // PAUTO created by inliner, derived from callee formal
        nameInlLocal                 // PAUTO created by inliner, derived from callee local
        nameOpenDeferSlot            // if temporary var storing info for open-coded defers
-       nameLibfuzzerExtraCounter    // if PEXTERN should be assigned to __libfuzzer_extra_counters section
+       nameLibfuzzer8BitCounter     // if PEXTERN should be assigned to __sancov_cntrs section
        nameAlias                    // is type name an alias
 )
 
@@ -250,7 +250,7 @@ func (n *Name) Addrtaken() bool                { return n.flags&nameAddrtaken !=
 func (n *Name) InlFormal() bool                { return n.flags&nameInlFormal != 0 }
 func (n *Name) InlLocal() bool                 { return n.flags&nameInlLocal != 0 }
 func (n *Name) OpenDeferSlot() bool            { return n.flags&nameOpenDeferSlot != 0 }
-func (n *Name) LibfuzzerExtraCounter() bool    { return n.flags&nameLibfuzzerExtraCounter != 0 }
+func (n *Name) Libfuzzer8BitCounter() bool     { return n.flags&nameLibfuzzer8BitCounter != 0 }
 
 func (n *Name) setReadonly(b bool)                 { n.flags.set(nameReadonly, b) }
 func (n *Name) SetNeedzero(b bool)                 { n.flags.set(nameNeedzero, b) }
@@ -263,7 +263,7 @@ func (n *Name) SetAddrtaken(b bool)                { n.flags.set(nameAddrtaken,
 func (n *Name) SetInlFormal(b bool)                { n.flags.set(nameInlFormal, b) }
 func (n *Name) SetInlLocal(b bool)                 { n.flags.set(nameInlLocal, b) }
 func (n *Name) SetOpenDeferSlot(b bool)            { n.flags.set(nameOpenDeferSlot, b) }
-func (n *Name) SetLibfuzzerExtraCounter(b bool)    { n.flags.set(nameLibfuzzerExtraCounter, b) }
+func (n *Name) SetLibfuzzer8BitCounter(b bool)     { n.flags.set(nameLibfuzzer8BitCounter, b) }
 
 // OnStack reports whether variable n may reside on the stack.
 func (n *Name) OnStack() bool {
index 86ae583eab21d71ab0f56747f979908418260049..42ecde1d239c4bee454c0c38eb2d6d5ceeb01d8c 100644 (file)
@@ -658,7 +658,7 @@ func IsSanitizerSafeAddr(v *Value) bool {
                // read-only once initialized.
                return true
        case OpAddr:
-               return v.Aux.(*obj.LSym).Type == objabi.SRODATA || v.Aux.(*obj.LSym).Type == objabi.SLIBFUZZER_EXTRA_COUNTER
+               return v.Aux.(*obj.LSym).Type == objabi.SRODATA || v.Aux.(*obj.LSym).Type == objabi.SLIBFUZZER_8BIT_COUNTER
        }
        return false
 }
index d4abd1af777d1208d5ea2f855037e60f5051152a..8d1089dcc1f51d72d51f256382e8df2d1f4be9ad 100644 (file)
@@ -446,21 +446,31 @@ func (o *orderState) edge() {
                return
        }
 
-       // Create a new uint8 counter to be allocated in section
-       // __libfuzzer_extra_counters.
+       // Create a new uint8 counter to be allocated in section __sancov_cntrs
        counter := staticinit.StaticName(types.Types[types.TUINT8])
-       counter.SetLibfuzzerExtraCounter(true)
-       // As well as setting SetLibfuzzerExtraCounter, we preemptively set the
-       // symbol type to SLIBFUZZER_EXTRA_COUNTER so that the race detector
+       counter.SetLibfuzzer8BitCounter(true)
+       // As well as setting SetLibfuzzer8BitCounter, we preemptively set the
+       // symbol type to SLIBFUZZER_8BIT_COUNTER so that the race detector
        // instrumentation pass (which does not have access to the flags set by
-       // SetLibfuzzerExtraCounter) knows to ignore them. This information is
-       // lost by the time it reaches the compile step, so SetLibfuzzerExtraCounter
+       // SetLibfuzzer8BitCounter) knows to ignore them. This information is
+       // lost by the time it reaches the compile step, so SetLibfuzzer8BitCounter
        // is still necessary.
-       counter.Linksym().Type = objabi.SLIBFUZZER_EXTRA_COUNTER
-
-       // counter += 1
-       incr := ir.NewAssignOpStmt(base.Pos, ir.OADD, counter, ir.NewInt(1))
-       o.append(incr)
+       counter.Linksym().Type = objabi.SLIBFUZZER_8BIT_COUNTER
+
+       // We guarantee that the counter never becomes zero again once it has been
+       // incremented once. This implementation follows the NeverZero optimization
+       // presented by the paper:
+       // "AFL++: Combining Incremental Steps of Fuzzing Research"
+       // The NeverZero policy avoids the overflow to 0 by setting the counter to one
+       // after it reaches 255 and so, if an edge is executed at least one time, the entry is
+       // never 0.
+       // Another policy presented in the paper is the Saturated Counters policy which
+       // freezes the counter when it reaches the value of 255. However, a range
+       // of experiments showed that that decreases overall performance.
+       o.append(ir.NewIfStmt(base.Pos,
+               ir.NewBinaryExpr(base.Pos, ir.OEQ, counter, ir.NewInt(0xff)),
+               []ir.Node{ir.NewAssignStmt(base.Pos, counter, ir.NewInt(1))},
+               []ir.Node{ir.NewAssignOpStmt(base.Pos, ir.OADD, counter, ir.NewInt(1))}))
 }
 
 // orderBlock orders the block of statements in n into a new slice,
index dba23a54bd022c84af180dc74fe8f7b9d3db5373..ba1e4d50d684cb3b409e71f77d9ca408986b9684 100644 (file)
@@ -67,7 +67,7 @@ const (
        SDWARFLOC
        SDWARFLINES
        // Coverage instrumentation counter for libfuzzer.
-       SLIBFUZZER_EXTRA_COUNTER
+       SLIBFUZZER_8BIT_COUNTER
        // Update cmd/link/internal/sym/AbiSymKindToSymKind for new SymKind values.
 
 )
index c90cf43b502ef12e55c1ab54bb802e716f36c74e..d0606aa2daf2268cdce5a3341ff8616fa7f718c3 100644 (file)
@@ -1,4 +1,4 @@
-// Code generated by "stringer -type=SymKind"; DO NOT EDIT.
+// Code generated by "stringer -type=SymKind symkind.go"; DO NOT EDIT.
 
 package objabi
 
@@ -25,12 +25,12 @@ func _() {
        _ = x[SDWARFRANGE-14]
        _ = x[SDWARFLOC-15]
        _ = x[SDWARFLINES-16]
-       _ = x[SLIBFUZZER_EXTRA_COUNTER-17]
+       _ = x[SLIBFUZZER_8BIT_COUNTER-17]
 }
 
-const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINESSLIBFUZZER_EXTRA_COUNTER"
+const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINESSLIBFUZZER_8BIT_COUNTER"
 
-var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 63, 74, 83, 95, 105, 114, 125, 134, 145, 169}
+var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 63, 74, 83, 95, 105, 114, 125, 134, 145, 168}
 
 func (i SymKind) String() string {
        if i >= SymKind(len(_SymKind_index)-1) {
index 43f71c0400fb13fe527e4e52ab17456e3f465f59..503a9cd20c8177ec3ecc8d9e3c1a11be52b384a3 100644 (file)
@@ -1782,10 +1782,10 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
        ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.end", 0), sect)
 
        // Coverage instrumentation counters for libfuzzer.
-       if len(state.data[sym.SLIBFUZZER_EXTRA_COUNTER]) > 0 {
-               sect := state.allocateNamedSectionAndAssignSyms(&Segdata, "__libfuzzer_extra_counters", sym.SLIBFUZZER_EXTRA_COUNTER, sym.Sxxx, 06)
-               ldr.SetSymSect(ldr.LookupOrCreateSym("internal/fuzz._counters", 0), sect)
-               ldr.SetSymSect(ldr.LookupOrCreateSym("internal/fuzz._ecounters", 0), sect)
+       if len(state.data[sym.SLIBFUZZER_8BIT_COUNTER]) > 0 {
+               sect := state.allocateNamedSectionAndAssignSyms(&Segdata, "__sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, sym.Sxxx, 06)
+               ldr.SetSymSect(ldr.LookupOrCreateSym("__start___sancov_cntrs", 0), sect)
+               ldr.SetSymSect(ldr.LookupOrCreateSym("__stop___sancov_cntrs", 0), sect)
        }
 
        if len(state.data[sym.STLSBSS]) > 0 {
@@ -2558,7 +2558,7 @@ func (ctxt *Link) address() []*sym.Segment {
                        bss = s
                case ".noptrbss":
                        noptrbss = s
-               case "__libfuzzer_extra_counters":
+               case "__sancov_cntrs":
                        fuzzCounters = s
                }
        }
@@ -2677,8 +2677,8 @@ func (ctxt *Link) address() []*sym.Segment {
        ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length))
 
        if fuzzCounters != nil {
-               ctxt.xdefine("internal/fuzz._counters", sym.SLIBFUZZER_EXTRA_COUNTER, int64(fuzzCounters.Vaddr))
-               ctxt.xdefine("internal/fuzz._ecounters", sym.SLIBFUZZER_EXTRA_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
+               ctxt.xdefine("__start___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
+               ctxt.xdefine("__stop___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
        }
 
        if ctxt.IsSolaris() {
index e57071d4eeeb1d617fc391ff7bdd1ee18c90d069..2566ded58db8243079806ad2d3cc5e1eb48e7f6c 100644 (file)
@@ -1304,7 +1304,7 @@ func (ctxt *Link) doelf() {
        shstrtab.Addstring(".data")
        shstrtab.Addstring(".bss")
        shstrtab.Addstring(".noptrbss")
-       shstrtab.Addstring("__libfuzzer_extra_counters")
+       shstrtab.Addstring("__sancov_cntrs")
        shstrtab.Addstring(".go.buildinfo")
        if ctxt.IsMIPS() {
                shstrtab.Addstring(".MIPS.abiflags")
index 955289b7af4e13f582505f2c1f824908602889b2..259db131af8698d8815764a0900e06391d1ddd2d 100644 (file)
@@ -1117,7 +1117,7 @@ func (f *xcoffFile) asmaixsym(ctxt *Link) {
                                putaixsym(ctxt, s, TLSSym)
                        }
 
-               case st == sym.SBSS, st == sym.SNOPTRBSS, st == sym.SLIBFUZZER_EXTRA_COUNTER:
+               case st == sym.SBSS, st == sym.SNOPTRBSS, st == sym.SLIBFUZZER_8BIT_COUNTER:
                        if ldr.AttrReachable(s) {
                                data := ldr.Data(s)
                                if len(data) > 0 {
index 3ed04c49af995ba981c579c1e47ff79787d64a8b..0f8fbed8785cd20079a66b41d4a66dd360d2e5ce 100644 (file)
@@ -97,7 +97,7 @@ const (
        SXCOFFTOC
        SBSS
        SNOPTRBSS
-       SLIBFUZZER_EXTRA_COUNTER
+       SLIBFUZZER_8BIT_COUNTER
        STLSBSS
        SXREF
        SMACHOSYMSTR
@@ -126,24 +126,24 @@ const (
 // AbiSymKindToSymKind maps values read from object files (which are
 // of type cmd/internal/objabi.SymKind) to values of type SymKind.
 var AbiSymKindToSymKind = [...]SymKind{
-       objabi.Sxxx:                     Sxxx,
-       objabi.STEXT:                    STEXT,
-       objabi.SRODATA:                  SRODATA,
-       objabi.SNOPTRDATA:               SNOPTRDATA,
-       objabi.SDATA:                    SDATA,
-       objabi.SBSS:                     SBSS,
-       objabi.SNOPTRBSS:                SNOPTRBSS,
-       objabi.STLSBSS:                  STLSBSS,
-       objabi.SDWARFCUINFO:             SDWARFCUINFO,
-       objabi.SDWARFCONST:              SDWARFCONST,
-       objabi.SDWARFFCN:                SDWARFFCN,
-       objabi.SDWARFABSFCN:             SDWARFABSFCN,
-       objabi.SDWARFTYPE:               SDWARFTYPE,
-       objabi.SDWARFVAR:                SDWARFVAR,
-       objabi.SDWARFRANGE:              SDWARFRANGE,
-       objabi.SDWARFLOC:                SDWARFLOC,
-       objabi.SDWARFLINES:              SDWARFLINES,
-       objabi.SLIBFUZZER_EXTRA_COUNTER: SLIBFUZZER_EXTRA_COUNTER,
+       objabi.Sxxx:                    Sxxx,
+       objabi.STEXT:                   STEXT,
+       objabi.SRODATA:                 SRODATA,
+       objabi.SNOPTRDATA:              SNOPTRDATA,
+       objabi.SDATA:                   SDATA,
+       objabi.SBSS:                    SBSS,
+       objabi.SNOPTRBSS:               SNOPTRBSS,
+       objabi.STLSBSS:                 STLSBSS,
+       objabi.SDWARFCUINFO:            SDWARFCUINFO,
+       objabi.SDWARFCONST:             SDWARFCONST,
+       objabi.SDWARFFCN:               SDWARFFCN,
+       objabi.SDWARFABSFCN:            SDWARFABSFCN,
+       objabi.SDWARFTYPE:              SDWARFTYPE,
+       objabi.SDWARFVAR:               SDWARFVAR,
+       objabi.SDWARFRANGE:             SDWARFRANGE,
+       objabi.SDWARFLOC:               SDWARFLOC,
+       objabi.SDWARFLINES:             SDWARFLINES,
+       objabi.SLIBFUZZER_8BIT_COUNTER: SLIBFUZZER_8BIT_COUNTER,
 }
 
 // ReadOnly are the symbol kinds that form read-only sections. In some
index bf8eda713ec847a8de27a0af78f3eb1aca8b5fed..14b57db41f0484521c87961d16276c864aad265f 100644 (file)
@@ -1,4 +1,4 @@
-// Code generated by "stringer -type=SymKind"; DO NOT EDIT.
+// Code generated by "stringer -type=SymKind symkind.go"; DO NOT EDIT.
 
 package sym
 
@@ -44,7 +44,7 @@ func _() {
        _ = x[SXCOFFTOC-33]
        _ = x[SBSS-34]
        _ = x[SNOPTRBSS-35]
-       _ = x[SLIBFUZZER_EXTRA_COUNTER-36]
+       _ = x[SLIBFUZZER_8BIT_COUNTER-36]
        _ = x[STLSBSS-37]
        _ = x[SXREF-38]
        _ = x[SMACHOSYMSTR-39]
@@ -67,9 +67,9 @@ func _() {
        _ = x[SDWARFLINES-56]
 }
 
-const _SymKind_name = "SxxxSTEXTSELFRXSECTSMACHOPLTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSFirstWritableSBUILDINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASXCOFFTOCSBSSSNOPTRBSSSLIBFUZZER_EXTRA_COUNTERSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILEPATHSDYNIMPORTSHOSTOBJSUNDEFEXTSDWARFSECTSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINES"
+const _SymKind_name = "SxxxSTEXTSELFRXSECTSMACHOPLTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSFirstWritableSBUILDINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASXCOFFTOCSBSSSNOPTRBSSSLIBFUZZER_8BIT_COUNTERSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILEPATHSDYNIMPORTSHOSTOBJSUNDEFEXTSDWARFSECTSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINES"
 
-var _SymKind_index = [...]uint16{0, 4, 9, 19, 28, 33, 40, 49, 56, 63, 70, 78, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 220, 230, 238, 244, 253, 261, 268, 278, 286, 291, 300, 304, 313, 337, 344, 349, 361, 373, 390, 407, 416, 426, 434, 443, 453, 465, 476, 485, 497, 507, 516, 527, 536, 547}
+var _SymKind_index = [...]uint16{0, 4, 9, 19, 28, 33, 40, 49, 56, 63, 70, 78, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 220, 230, 238, 244, 253, 261, 268, 278, 286, 291, 300, 304, 313, 336, 343, 348, 360, 372, 389, 406, 415, 425, 433, 442, 452, 464, 475, 484, 496, 506, 515, 526, 535, 546}
 
 func (i SymKind) String() string {
        if i >= SymKind(len(_SymKind_index)-1) {
index e7b3cdc46a9ea8b4c9c908dcbdf3154eb9d4568c..920ac575f58c40d276932d0c17ffb7251d03c200 100644 (file)
@@ -6,8 +6,9 @@
 
 package runtime
 
-import _ "unsafe" // for go:linkname
+import "unsafe"
 
+func libfuzzerCallWithTwoByteBuffers(fn, start, end *byte)
 func libfuzzerCall(fn *byte, arg0, arg1 uintptr)
 
 func libfuzzerTraceCmp1(arg0, arg1 uint8) {
@@ -42,6 +43,22 @@ func libfuzzerTraceConstCmp8(arg0, arg1 uint64) {
        libfuzzerCall(&__sanitizer_cov_trace_const_cmp8, uintptr(arg0), uintptr(arg1))
 }
 
+var pcTables []byte
+
+func init() {
+       libfuzzerCallWithTwoByteBuffers(&__sanitizer_cov_8bit_counters_init, &__start___sancov_cntrs, &__stop___sancov_cntrs)
+       start := unsafe.Pointer(&__start___sancov_cntrs)
+       end := unsafe.Pointer(&__stop___sancov_cntrs)
+
+       // PC tables are arrays of ptr-sized integers representing pairs [PC,PCFlags] for every instrumented block.
+       // The number of PCs and PCFlags is the same as the number of 8-bit counters. Each PC table entry has
+       // the size of two ptr-sized integers. We allocate one more byte than what we actually need so that we can
+       // get a pointer representing the end of the PC table array.
+       size := (uintptr(end)-uintptr(start))*unsafe.Sizeof(uintptr(0))*2 + 1
+       pcTables = make([]byte, size)
+       libfuzzerCallWithTwoByteBuffers(&__sanitizer_cov_pcs_init, &pcTables[0], &pcTables[size-1])
+}
+
 //go:linkname __sanitizer_cov_trace_cmp1 __sanitizer_cov_trace_cmp1
 //go:cgo_import_static __sanitizer_cov_trace_cmp1
 var __sanitizer_cov_trace_cmp1 byte
@@ -73,3 +90,19 @@ var __sanitizer_cov_trace_const_cmp4 byte
 //go:linkname __sanitizer_cov_trace_const_cmp8 __sanitizer_cov_trace_const_cmp8
 //go:cgo_import_static __sanitizer_cov_trace_const_cmp8
 var __sanitizer_cov_trace_const_cmp8 byte
+
+//go:linkname __sanitizer_cov_8bit_counters_init __sanitizer_cov_8bit_counters_init
+//go:cgo_import_static __sanitizer_cov_8bit_counters_init
+var __sanitizer_cov_8bit_counters_init byte
+
+//go:linkname __start___sancov_cntrs __start___sancov_cntrs
+//go:cgo_import_static __start___sancov_cntrs
+var __start___sancov_cntrs byte
+
+//go:linkname __stop___sancov_cntrs __stop___sancov_cntrs
+//go:cgo_import_static __stop___sancov_cntrs
+var __stop___sancov_cntrs byte
+
+//go:linkname __sanitizer_cov_pcs_init __sanitizer_cov_pcs_init
+//go:cgo_import_static __sanitizer_cov_pcs_init
+var __sanitizer_cov_pcs_init byte
index 253fe15198120c86424a6a4e2bcc3a5f701cf6a1..5ea77f59de25037a1e426f91b983aa180508eb7e 100644 (file)
@@ -40,3 +40,26 @@ call:
        CALL    AX
        MOVQ    R12, SP
        RET
+
+// void runtime·libfuzzerCallWithTwoByteBuffers(fn, start, end *byte)
+// Calls C function fn from libFuzzer and passes 2 arguments of type *byte to it.
+TEXT   runtime·libfuzzerCallWithTwoByteBuffers(SB), NOSPLIT, $0-24
+       MOVQ    fn+0(FP), AX
+       MOVQ    start+8(FP), RARG0
+       MOVQ    end+16(FP), RARG1
+
+       get_tls(R12)
+       MOVQ    g(R12), R14
+       MOVQ    g_m(R14), R13
+
+       // Switch to g0 stack.
+       MOVQ    SP, R12         // callee-saved, preserved across the CALL
+       MOVQ    m_g0(R13), R10
+       CMPQ    R10, R14
+       JE      call    // already on g0
+       MOVQ    (g_sched+gobuf_sp)(R10), SP
+call:
+       ANDQ    $~15, SP        // alignment for gcc ABI
+       CALL    AX
+       MOVQ    R12, SP
+       RET
index ae0efd8c9bf2e8d672cbabd65847e56264ae3ea9..b0146682a2660ac6db4de5cbdf96aaa4eccff769 100644 (file)
@@ -29,3 +29,24 @@ call:
        BL      R9
        MOVD    R19, RSP
        RET
+
+// void runtime·libfuzzerCallWithTwoByteBuffers(fn, start, end *byte)
+// Calls C function fn from libFuzzer and passes 2 arguments of type *byte to it.
+TEXT   runtime·libfuzzerCallWithTwoByteBuffers(SB), NOSPLIT, $0-24
+       MOVD    fn+0(FP), R9
+       MOVD    start+8(FP), R0
+       MOVD    end+16(FP), R1
+
+       MOVD    g_m(g), R10
+
+       // Switch to g0 stack.
+       MOVD    RSP, R19        // callee-saved, preserved across the CALL
+       MOVD    m_g0(R10), R11
+       CMP     R11, g
+       BEQ     call    // already on g0
+       MOVD    (g_sched+gobuf_sp)(R11), R12
+       MOVD    R12, RSP
+call:
+       BL      R9
+       MOVD    R19, RSP
+       RET