mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
cmd/compile, cmd/link: use libFuzzer 8-bit instead of extra counters
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).
This commit is contained in:
parent
5f2fdbe7ed
commit
9057e4b21d
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.Linksym().Type = objabi.SLIBFUZZER_8BIT_COUNTER
|
||||
|
||||
// counter += 1
|
||||
incr := ir.NewAssignOpStmt(base.Pos, ir.OADD, counter, ir.NewInt(1))
|
||||
o.append(incr)
|
||||
// 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,
|
||||
|
|
|
@ -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.
|
||||
|
||||
)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue