package pkgbits
import (
)
type PkgDecoder struct {
version uint32
sync bool
pkgPath string
elemData string
elemEnds []uint32
elemEndsEnds [numRelocs]uint32
scratchRelocEnt []RelocEnt
}
func ( *PkgDecoder) () string { return .pkgPath }
func ( *PkgDecoder) () bool { return .sync }
func (, string) PkgDecoder {
:= PkgDecoder{
pkgPath: ,
}
:= strings.NewReader()
assert(binary.Read(, binary.LittleEndian, &.version) == nil)
switch .version {
default:
panic(fmt.Errorf("unsupported version: %v", .version))
case 0:
case 1:
var uint32
assert(binary.Read(, binary.LittleEndian, &) == nil)
.sync = &flagSyncMarkers != 0
}
assert(binary.Read(, binary.LittleEndian, .elemEndsEnds[:]) == nil)
.elemEnds = make([]uint32, .elemEndsEnds[len(.elemEndsEnds)-1])
assert(binary.Read(, binary.LittleEndian, .elemEnds[:]) == nil)
, := .Seek(0, io.SeekCurrent)
assert( == nil)
.elemData = [:]
assert(len(.elemData)-8 == int(.elemEnds[len(.elemEnds)-1]))
return
}
func ( *PkgDecoder) ( RelocKind) int {
:= int(.elemEndsEnds[])
if > 0 {
-= int(.elemEndsEnds[-1])
}
return
}
func ( *PkgDecoder) () int {
return len(.elemEnds)
}
func ( *PkgDecoder) () [8]byte {
var [8]byte
copy([:], .elemData[len(.elemData)-8:])
return
}
func ( *PkgDecoder) ( RelocKind, Index) int {
:= int()
if > 0 {
+= int(.elemEndsEnds[-1])
}
if >= int(.elemEndsEnds[]) {
errorf("%v:%v is out of bounds; %v", , , .elemEndsEnds)
}
return
}
func ( *PkgDecoder) ( RelocKind, Index) string {
:= .AbsIdx(, )
var uint32
if > 0 {
= .elemEnds[-1]
}
:= .elemEnds[]
return .elemData[:]
}
func ( *PkgDecoder) ( Index) string {
return .DataIdx(RelocString, )
}
func ( *PkgDecoder) ( RelocKind, Index, SyncMarker) Decoder {
:= .NewDecoderRaw(, )
.Sync()
return
}
func ( *PkgDecoder) ( RelocKind, Index, SyncMarker) Decoder {
:= .TempDecoderRaw(, )
.Sync()
return
}
func ( *PkgDecoder) ( *Decoder) {
.scratchRelocEnt = .Relocs
.Relocs = nil
}
func ( *PkgDecoder) ( RelocKind, Index) Decoder {
:= Decoder{
common: ,
k: ,
Idx: ,
}
.Data = *strings.NewReader(.DataIdx(, ))
.Sync(SyncRelocs)
.Relocs = make([]RelocEnt, .Len())
for := range .Relocs {
.Sync(SyncReloc)
.Relocs[] = RelocEnt{RelocKind(.Len()), Index(.Len())}
}
return
}
func ( *PkgDecoder) ( RelocKind, Index) Decoder {
:= Decoder{
common: ,
k: ,
Idx: ,
}
.Data.Reset(.DataIdx(, ))
.Sync(SyncRelocs)
:= .Len()
if cap(.scratchRelocEnt) >= {
.Relocs = .scratchRelocEnt[:]
.scratchRelocEnt = nil
} else {
.Relocs = make([]RelocEnt, )
}
for := range .Relocs {
.Sync(SyncReloc)
.Relocs[] = RelocEnt{RelocKind(.Len()), Index(.Len())}
}
return
}
type Decoder struct {
common *PkgDecoder
Relocs []RelocEnt
Data strings.Reader
k RelocKind
Idx Index
}
func ( *Decoder) ( error) {
if != nil {
errorf("unexpected decoding error: %w", )
}
}
func ( *Decoder) () uint64 {
, := readUvarint(&.Data)
.checkErr()
return
}
func ( *strings.Reader) (uint64, error) {
var uint64
var uint
for := 0; < binary.MaxVarintLen64; ++ {
, := .ReadByte()
if != nil {
if > 0 && == io.EOF {
= io.ErrUnexpectedEOF
}
return ,
}
if < 0x80 {
if == binary.MaxVarintLen64-1 && > 1 {
return , overflow
}
return | uint64()<<, nil
}
|= uint64(&0x7f) <<
+= 7
}
return , overflow
}
var overflow = errors.New("pkgbits: readUvarint overflows a 64-bit integer")
func ( *Decoder) () int64 {
:= .rawUvarint()
:= int64( >> 1)
if &1 != 0 {
= ^
}
return
}
func ( *Decoder) ( RelocKind, int) Index {
:= .Relocs[]
assert(.Kind == )
return .Idx
}
func ( *Decoder) ( SyncMarker) {
if !.common.sync {
return
}
, := .Data.Seek(0, io.SeekCurrent)
:= SyncMarker(.rawUvarint())
:= make([]int, .rawUvarint())
for := range {
[] = int(.rawUvarint())
}
if == {
return
}
fmt.Printf("export data desync: package %q, section %v, index %v, offset %v\n", .common.pkgPath, .k, .Idx, )
fmt.Printf("\nfound %v, written at:\n", )
if len() == 0 {
fmt.Printf("\t[stack trace unavailable; recompile package %q with -d=syncframes]\n", .common.pkgPath)
}
for , := range {
fmt.Printf("\t%s\n", .common.StringIdx(.rawReloc(RelocString, )))
}
fmt.Printf("\nexpected %v, reading at:\n", )
var [32]uintptr
:= runtime.Callers(2, [:])
for , := range fmtFrames([:]...) {
fmt.Printf("\t%s\n", )
}
os.Exit(1)
}
func ( *Decoder) () bool {
.Sync(SyncBool)
, := .Data.ReadByte()
.checkErr()
assert( < 2)
return != 0
}
func ( *Decoder) () int64 {
.Sync(SyncInt64)
return .rawVarint()
}
func ( *Decoder) () uint64 {
.Sync(SyncUint64)
return .rawUvarint()
}
func ( *Decoder) () int { := .Uint64(); := int(); assert(uint64() == ); return }
func ( *Decoder) () int { := .Int64(); := int(); assert(int64() == ); return }
func ( *Decoder) () uint { := .Uint64(); := uint(); assert(uint64() == ); return }
func ( *Decoder) ( SyncMarker) int {
.Sync()
return .Len()
}
func ( *Decoder) ( RelocKind) Index {
.Sync(SyncUseReloc)
return .rawReloc(, .Len())
}
func ( *Decoder) () string {
.Sync(SyncString)
return .common.StringIdx(.Reloc(RelocString))
}
func ( *Decoder) () []string {
:= make([]string, .Len())
for := range {
[] = .String()
}
return
}
func ( *Decoder) () constant.Value {
.Sync(SyncValue)
:= .Bool()
:= .scalar()
if {
= constant.BinaryOp(, token.ADD, constant.MakeImag(.scalar()))
}
return
}
func ( *Decoder) () constant.Value {
switch := CodeVal(.Code(SyncVal)); {
default:
panic(fmt.Errorf("unexpected scalar tag: %v", ))
case ValBool:
return constant.MakeBool(.Bool())
case ValString:
return constant.MakeString(.String())
case ValInt64:
return constant.MakeInt64(.Int64())
case ValBigInt:
return constant.Make(.bigInt())
case ValBigRat:
:= .bigInt()
:= .bigInt()
return constant.Make(new(big.Rat).SetFrac(, ))
case ValBigFloat:
return constant.Make(.bigFloat())
}
}
func ( *Decoder) () *big.Int {
:= new(big.Int).SetBytes([]byte(.String()))
if .Bool() {
.Neg()
}
return
}
func ( *Decoder) () *big.Float {
:= new(big.Float).SetPrec(512)
assert(.UnmarshalText([]byte(.String())) == nil)
return
}
func ( *PkgDecoder) ( Index) string {
var string
{
:= .TempDecoder(RelocPkg, , SyncPkgDef)
= .String()
.RetireDecoder(&)
}
if == "" {
= .pkgPath
}
return
}
func ( *PkgDecoder) ( Index) (string, string, CodeObj) {
var Index
var string
var int
{
:= .TempDecoder(RelocName, , SyncObject1)
.Sync(SyncSym)
.Sync(SyncPkg)
= .Reloc(RelocPkg)
= .String()
= .Code(SyncCodeObj)
.RetireDecoder(&)
}
:= .PeekPkgPath()
assert( != "")
:= CodeObj()
return , ,
}