Best Syzkaller code snippet using x86.addr32
ldpe.go
Source:ldpe.go
1// Copyright 2010 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4// Package loadpe implements a PE/COFF file reader.5package loadpe6import (7 "cmd/internal/bio"8 "cmd/internal/objabi"9 "cmd/internal/sys"10 "cmd/oldlink/internal/loader"11 "cmd/oldlink/internal/sym"12 "debug/pe"13 "encoding/binary"14 "errors"15 "fmt"16 "io"17 "sort"18 "strings"19)20const (21 // TODO: the Microsoft doco says IMAGE_SYM_DTYPE_ARRAY is 3 (same with IMAGE_SYM_DTYPE_POINTER and IMAGE_SYM_DTYPE_FUNCTION)22 IMAGE_SYM_UNDEFINED = 023 IMAGE_SYM_ABSOLUTE = -124 IMAGE_SYM_DEBUG = -225 IMAGE_SYM_TYPE_NULL = 026 IMAGE_SYM_TYPE_VOID = 127 IMAGE_SYM_TYPE_CHAR = 228 IMAGE_SYM_TYPE_SHORT = 329 IMAGE_SYM_TYPE_INT = 430 IMAGE_SYM_TYPE_LONG = 531 IMAGE_SYM_TYPE_FLOAT = 632 IMAGE_SYM_TYPE_DOUBLE = 733 IMAGE_SYM_TYPE_STRUCT = 834 IMAGE_SYM_TYPE_UNION = 935 IMAGE_SYM_TYPE_ENUM = 1036 IMAGE_SYM_TYPE_MOE = 1137 IMAGE_SYM_TYPE_BYTE = 1238 IMAGE_SYM_TYPE_WORD = 1339 IMAGE_SYM_TYPE_UINT = 1440 IMAGE_SYM_TYPE_DWORD = 1541 IMAGE_SYM_TYPE_PCODE = 3276842 IMAGE_SYM_DTYPE_NULL = 043 IMAGE_SYM_DTYPE_POINTER = 0x1044 IMAGE_SYM_DTYPE_FUNCTION = 0x2045 IMAGE_SYM_DTYPE_ARRAY = 0x3046 IMAGE_SYM_CLASS_END_OF_FUNCTION = -147 IMAGE_SYM_CLASS_NULL = 048 IMAGE_SYM_CLASS_AUTOMATIC = 149 IMAGE_SYM_CLASS_EXTERNAL = 250 IMAGE_SYM_CLASS_STATIC = 351 IMAGE_SYM_CLASS_REGISTER = 452 IMAGE_SYM_CLASS_EXTERNAL_DEF = 553 IMAGE_SYM_CLASS_LABEL = 654 IMAGE_SYM_CLASS_UNDEFINED_LABEL = 755 IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 856 IMAGE_SYM_CLASS_ARGUMENT = 957 IMAGE_SYM_CLASS_STRUCT_TAG = 1058 IMAGE_SYM_CLASS_MEMBER_OF_UNION = 1159 IMAGE_SYM_CLASS_UNION_TAG = 1260 IMAGE_SYM_CLASS_TYPE_DEFINITION = 1361 IMAGE_SYM_CLASS_UNDEFINED_STATIC = 1462 IMAGE_SYM_CLASS_ENUM_TAG = 1563 IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 1664 IMAGE_SYM_CLASS_REGISTER_PARAM = 1765 IMAGE_SYM_CLASS_BIT_FIELD = 1866 IMAGE_SYM_CLASS_FAR_EXTERNAL = 68 /* Not in PECOFF v8 spec */67 IMAGE_SYM_CLASS_BLOCK = 10068 IMAGE_SYM_CLASS_FUNCTION = 10169 IMAGE_SYM_CLASS_END_OF_STRUCT = 10270 IMAGE_SYM_CLASS_FILE = 10371 IMAGE_SYM_CLASS_SECTION = 10472 IMAGE_SYM_CLASS_WEAK_EXTERNAL = 10573 IMAGE_SYM_CLASS_CLR_TOKEN = 10774 IMAGE_REL_I386_ABSOLUTE = 0x000075 IMAGE_REL_I386_DIR16 = 0x000176 IMAGE_REL_I386_REL16 = 0x000277 IMAGE_REL_I386_DIR32 = 0x000678 IMAGE_REL_I386_DIR32NB = 0x000779 IMAGE_REL_I386_SEG12 = 0x000980 IMAGE_REL_I386_SECTION = 0x000A81 IMAGE_REL_I386_SECREL = 0x000B82 IMAGE_REL_I386_TOKEN = 0x000C83 IMAGE_REL_I386_SECREL7 = 0x000D84 IMAGE_REL_I386_REL32 = 0x001485 IMAGE_REL_AMD64_ABSOLUTE = 0x000086 IMAGE_REL_AMD64_ADDR64 = 0x000187 IMAGE_REL_AMD64_ADDR32 = 0x000288 IMAGE_REL_AMD64_ADDR32NB = 0x000389 IMAGE_REL_AMD64_REL32 = 0x000490 IMAGE_REL_AMD64_REL32_1 = 0x000591 IMAGE_REL_AMD64_REL32_2 = 0x000692 IMAGE_REL_AMD64_REL32_3 = 0x000793 IMAGE_REL_AMD64_REL32_4 = 0x000894 IMAGE_REL_AMD64_REL32_5 = 0x000995 IMAGE_REL_AMD64_SECTION = 0x000A96 IMAGE_REL_AMD64_SECREL = 0x000B97 IMAGE_REL_AMD64_SECREL7 = 0x000C98 IMAGE_REL_AMD64_TOKEN = 0x000D99 IMAGE_REL_AMD64_SREL32 = 0x000E100 IMAGE_REL_AMD64_PAIR = 0x000F101 IMAGE_REL_AMD64_SSPAN32 = 0x0010102 IMAGE_REL_ARM_ABSOLUTE = 0x0000103 IMAGE_REL_ARM_ADDR32 = 0x0001104 IMAGE_REL_ARM_ADDR32NB = 0x0002105 IMAGE_REL_ARM_BRANCH24 = 0x0003106 IMAGE_REL_ARM_BRANCH11 = 0x0004107 IMAGE_REL_ARM_SECTION = 0x000E108 IMAGE_REL_ARM_SECREL = 0x000F109 IMAGE_REL_ARM_MOV32 = 0x0010110 IMAGE_REL_THUMB_MOV32 = 0x0011111 IMAGE_REL_THUMB_BRANCH20 = 0x0012112 IMAGE_REL_THUMB_BRANCH24 = 0x0014113 IMAGE_REL_THUMB_BLX23 = 0x0015114 IMAGE_REL_ARM_PAIR = 0x0016115)116// TODO(crawshaw): de-duplicate these symbols with cmd/internal/ld, ideally in debug/pe.117const (118 IMAGE_SCN_CNT_CODE = 0x00000020119 IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040120 IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080121 IMAGE_SCN_MEM_DISCARDABLE = 0x02000000122 IMAGE_SCN_MEM_EXECUTE = 0x20000000123 IMAGE_SCN_MEM_READ = 0x40000000124 IMAGE_SCN_MEM_WRITE = 0x80000000125)126// TODO(brainman): maybe just add ReadAt method to bio.Reader instead of creating peBiobuf127// peBiobuf makes bio.Reader look like io.ReaderAt.128type peBiobuf bio.Reader129func (f *peBiobuf) ReadAt(p []byte, off int64) (int, error) {130 ret := ((*bio.Reader)(f)).MustSeek(off, 0)131 if ret < 0 {132 return 0, errors.New("fail to seek")133 }134 n, err := f.Read(p)135 if err != nil {136 return 0, err137 }138 return n, nil139}140func Load(l *loader.Loader, arch *sys.Arch, syms *sym.Symbols, input *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, rsrc *sym.Symbol, err error) {141 lookup := func(name string, version int) *sym.Symbol {142 return l.LookupOrCreate(name, version, syms)143 }144 return load(arch, lookup, syms.IncVersion(), input, pkg, length, pn)145}146func LoadOld(arch *sys.Arch, syms *sym.Symbols, input *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, rsrc *sym.Symbol, err error) {147 return load(arch, syms.Lookup, syms.IncVersion(), input, pkg, length, pn)148}149// load loads the PE file pn from input.150// Symbols are written into syms, and a slice of the text symbols is returned.151// If an .rsrc section is found, its symbol is returned as rsrc.152func load(arch *sys.Arch, lookup func(string, int) *sym.Symbol, localSymVersion int, input *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, rsrc *sym.Symbol, err error) {153 sectsyms := make(map[*pe.Section]*sym.Symbol)154 sectdata := make(map[*pe.Section][]byte)155 // Some input files are archives containing multiple of156 // object files, and pe.NewFile seeks to the start of157 // input file and get confused. Create section reader158 // to stop pe.NewFile looking before current position.159 sr := io.NewSectionReader((*peBiobuf)(input), input.Offset(), 1<<63-1)160 // TODO: replace pe.NewFile with pe.Load (grep for "add Load function" in debug/pe for details)161 f, err := pe.NewFile(sr)162 if err != nil {163 return nil, nil, err164 }165 defer f.Close()166 // TODO return error if found .cormeta167 // create symbols for mapped sections168 for _, sect := range f.Sections {169 if sect.Characteristics&IMAGE_SCN_MEM_DISCARDABLE != 0 {170 continue171 }172 if sect.Characteristics&(IMAGE_SCN_CNT_CODE|IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 {173 // This has been seen for .idata sections, which we174 // want to ignore. See issues 5106 and 5273.175 continue176 }177 name := fmt.Sprintf("%s(%s)", pkg, sect.Name)178 s := lookup(name, localSymVersion)179 switch sect.Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE) {180 case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ: //.rdata181 s.Type = sym.SRODATA182 case IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.bss183 s.Type = sym.SNOPTRBSS184 case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.data185 s.Type = sym.SNOPTRDATA186 case IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ: //.text187 s.Type = sym.STEXT188 default:189 return nil, nil, fmt.Errorf("unexpected flags %#06x for PE section %s", sect.Characteristics, sect.Name)190 }191 if s.Type != sym.SNOPTRBSS {192 data, err := sect.Data()193 if err != nil {194 return nil, nil, err195 }196 sectdata[sect] = data197 s.P = data198 }199 s.Size = int64(sect.Size)200 sectsyms[sect] = s201 if sect.Name == ".rsrc" {202 rsrc = s203 }204 }205 // load relocations206 for _, rsect := range f.Sections {207 if _, found := sectsyms[rsect]; !found {208 continue209 }210 if rsect.NumberOfRelocations == 0 {211 continue212 }213 if rsect.Characteristics&IMAGE_SCN_MEM_DISCARDABLE != 0 {214 continue215 }216 if rsect.Characteristics&(IMAGE_SCN_CNT_CODE|IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 {217 // This has been seen for .idata sections, which we218 // want to ignore. See issues 5106 and 5273.219 continue220 }221 rs := make([]sym.Reloc, rsect.NumberOfRelocations)222 for j, r := range rsect.Relocs {223 rp := &rs[j]224 if int(r.SymbolTableIndex) >= len(f.COFFSymbols) {225 return nil, nil, fmt.Errorf("relocation number %d symbol index idx=%d cannot be large then number of symbols %d", j, r.SymbolTableIndex, len(f.COFFSymbols))226 }227 pesym := &f.COFFSymbols[r.SymbolTableIndex]228 gosym, err := readpesym(arch, lookup, f, pesym, sectsyms, localSymVersion)229 if err != nil {230 return nil, nil, err231 }232 if gosym == nil {233 name, err := pesym.FullName(f.StringTable)234 if err != nil {235 name = string(pesym.Name[:])236 }237 return nil, nil, fmt.Errorf("reloc of invalid sym %s idx=%d type=%d", name, r.SymbolTableIndex, pesym.Type)238 }239 rp.Sym = gosym240 rp.Siz = 4241 rp.Off = int32(r.VirtualAddress)242 switch arch.Family {243 default:244 return nil, nil, fmt.Errorf("%s: unsupported arch %v", pn, arch.Family)245 case sys.I386, sys.AMD64:246 switch r.Type {247 default:248 return nil, nil, fmt.Errorf("%s: %v: unknown relocation type %v", pn, sectsyms[rsect], r.Type)249 case IMAGE_REL_I386_REL32, IMAGE_REL_AMD64_REL32,250 IMAGE_REL_AMD64_ADDR32, // R_X86_64_PC32251 IMAGE_REL_AMD64_ADDR32NB:252 rp.Type = objabi.R_PCREL253 rp.Add = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rp.Off:])))254 case IMAGE_REL_I386_DIR32NB, IMAGE_REL_I386_DIR32:255 rp.Type = objabi.R_ADDR256 // load addend from image257 rp.Add = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rp.Off:])))258 case IMAGE_REL_AMD64_ADDR64: // R_X86_64_64259 rp.Siz = 8260 rp.Type = objabi.R_ADDR261 // load addend from image262 rp.Add = int64(binary.LittleEndian.Uint64(sectdata[rsect][rp.Off:]))263 }264 case sys.ARM:265 switch r.Type {266 default:267 return nil, nil, fmt.Errorf("%s: %v: unknown ARM relocation type %v", pn, sectsyms[rsect], r.Type)268 case IMAGE_REL_ARM_SECREL:269 rp.Type = objabi.R_PCREL270 rp.Add = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rp.Off:])))271 case IMAGE_REL_ARM_ADDR32:272 rp.Type = objabi.R_ADDR273 rp.Add = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rp.Off:])))274 case IMAGE_REL_ARM_BRANCH24:275 rp.Type = objabi.R_CALLARM276 rp.Add = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rp.Off:])))277 }278 }279 // ld -r could generate multiple section symbols for the280 // same section but with different values, we have to take281 // that into account282 if issect(pesym) {283 rp.Add += int64(pesym.Value)284 }285 }286 sort.Sort(sym.RelocByOff(rs[:rsect.NumberOfRelocations]))287 s := sectsyms[rsect]288 s.R = rs289 s.R = s.R[:rsect.NumberOfRelocations]290 }291 // enter sub-symbols into symbol table.292 for i, numaux := 0, 0; i < len(f.COFFSymbols); i += numaux + 1 {293 pesym := &f.COFFSymbols[i]294 numaux = int(pesym.NumberOfAuxSymbols)295 name, err := pesym.FullName(f.StringTable)296 if err != nil {297 return nil, nil, err298 }299 if name == "" {300 continue301 }302 if issect(pesym) {303 continue304 }305 if int(pesym.SectionNumber) > len(f.Sections) {306 continue307 }308 if pesym.SectionNumber == IMAGE_SYM_DEBUG {309 continue310 }311 var sect *pe.Section312 if pesym.SectionNumber > 0 {313 sect = f.Sections[pesym.SectionNumber-1]314 if _, found := sectsyms[sect]; !found {315 continue316 }317 }318 s, err := readpesym(arch, lookup, f, pesym, sectsyms, localSymVersion)319 if err != nil {320 return nil, nil, err321 }322 if pesym.SectionNumber == 0 { // extern323 if s.Type == sym.SDYNIMPORT {324 s.SetPlt(-2) // flag for dynimport in PE object files.325 }326 if s.Type == sym.SXREF && pesym.Value > 0 { // global data327 s.Type = sym.SNOPTRDATA328 s.Size = int64(pesym.Value)329 }330 continue331 } else if pesym.SectionNumber > 0 && int(pesym.SectionNumber) <= len(f.Sections) {332 sect = f.Sections[pesym.SectionNumber-1]333 if _, found := sectsyms[sect]; !found {334 return nil, nil, fmt.Errorf("%s: %v: missing sect.sym", pn, s)335 }336 } else {337 return nil, nil, fmt.Errorf("%s: %v: sectnum < 0!", pn, s)338 }339 if sect == nil {340 return nil, rsrc, nil341 }342 if s.Outer != nil {343 if s.Attr.DuplicateOK() {344 continue345 }346 return nil, nil, fmt.Errorf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sectsyms[sect].Name)347 }348 sectsym := sectsyms[sect]349 s.Sub = sectsym.Sub350 sectsym.Sub = s351 s.Type = sectsym.Type352 s.Attr |= sym.AttrSubSymbol353 s.Value = int64(pesym.Value)354 s.Size = 4355 s.Outer = sectsym356 if sectsym.Type == sym.STEXT {357 if s.Attr.External() && !s.Attr.DuplicateOK() {358 return nil, nil, fmt.Errorf("%s: duplicate symbol definition", s.Name)359 }360 s.Attr |= sym.AttrExternal361 }362 }363 // Sort outer lists by address, adding to textp.364 // This keeps textp in increasing address order.365 for _, sect := range f.Sections {366 s := sectsyms[sect]367 if s == nil {368 continue369 }370 if s.Sub != nil {371 s.Sub = sym.SortSub(s.Sub)372 }373 if s.Type == sym.STEXT {374 if s.Attr.OnList() {375 return nil, nil, fmt.Errorf("symbol %s listed multiple times", s.Name)376 }377 s.Attr |= sym.AttrOnList378 textp = append(textp, s)379 for s = s.Sub; s != nil; s = s.Sub {380 if s.Attr.OnList() {381 return nil, nil, fmt.Errorf("symbol %s listed multiple times", s.Name)382 }383 s.Attr |= sym.AttrOnList384 textp = append(textp, s)385 }386 }387 }388 return textp, rsrc, nil389}390func issect(s *pe.COFFSymbol) bool {391 return s.StorageClass == IMAGE_SYM_CLASS_STATIC && s.Type == 0 && s.Name[0] == '.'392}393func readpesym(arch *sys.Arch, lookup func(string, int) *sym.Symbol, f *pe.File, pesym *pe.COFFSymbol, sectsyms map[*pe.Section]*sym.Symbol, localSymVersion int) (*sym.Symbol, error) {394 symname, err := pesym.FullName(f.StringTable)395 if err != nil {396 return nil, err397 }398 var name string399 if issect(pesym) {400 name = sectsyms[f.Sections[pesym.SectionNumber-1]].Name401 } else {402 name = symname403 switch arch.Family {404 case sys.AMD64:405 if name == "__imp___acrt_iob_func" {406 // Do not rename __imp___acrt_iob_func into __acrt_iob_func,407 // because __imp___acrt_iob_func symbol is real408 // (see commit b295099 from git://git.code.sf.net/p/mingw-w64/mingw-w64 for details).409 } else {410 name = strings.TrimPrefix(name, "__imp_") // __imp_Name => Name411 }412 case sys.I386:413 if name == "__imp____acrt_iob_func" {414 // Do not rename __imp____acrt_iob_func into ___acrt_iob_func,415 // because __imp____acrt_iob_func symbol is real416 // (see commit b295099 from git://git.code.sf.net/p/mingw-w64/mingw-w64 for details).417 } else {418 name = strings.TrimPrefix(name, "__imp_") // __imp_Name => Name419 }420 if name[0] == '_' {421 name = name[1:] // _Name => Name422 }423 }424 }425 // remove last @XXX426 if i := strings.LastIndex(name, "@"); i >= 0 {427 name = name[:i]428 }429 var s *sym.Symbol430 switch pesym.Type {431 default:432 return nil, fmt.Errorf("%s: invalid symbol type %d", symname, pesym.Type)433 case IMAGE_SYM_DTYPE_FUNCTION, IMAGE_SYM_DTYPE_NULL:434 switch pesym.StorageClass {435 case IMAGE_SYM_CLASS_EXTERNAL: //global436 s = lookup(name, 0)437 case IMAGE_SYM_CLASS_NULL, IMAGE_SYM_CLASS_STATIC, IMAGE_SYM_CLASS_LABEL:438 s = lookup(name, localSymVersion)439 s.Attr |= sym.AttrDuplicateOK440 default:441 return nil, fmt.Errorf("%s: invalid symbol binding %d", symname, pesym.StorageClass)442 }443 }444 if s != nil && s.Type == 0 && (pesym.StorageClass != IMAGE_SYM_CLASS_STATIC || pesym.Value != 0) {445 s.Type = sym.SXREF446 }447 if strings.HasPrefix(symname, "__imp_") {448 s.SetGot(-2) // flag for __imp_449 }450 return s, nil451}...
inst.go
Source:inst.go
1// Copyright 2014 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4// Package x86asm implements decoding of x86 machine code.5package x86asm6import (7 "bytes"8 "fmt"9)10// An Inst is a single instruction.11type Inst struct {12 Prefix Prefixes // Prefixes applied to the instruction.13 Op Op // Opcode mnemonic14 Opcode uint32 // Encoded opcode bits, left aligned (first byte is Opcode>>24, etc)15 Args Args // Instruction arguments, in Intel order16 Mode int // processor mode in bits: 16, 32, or 6417 AddrSize int // address size in bits: 16, 32, or 6418 DataSize int // operand size in bits: 16, 32, or 6419 MemBytes int // size of memory argument in bytes: 1, 2, 4, 8, 16, and so on.20 Len int // length of encoded instruction in bytes21}22// Prefixes is an array of prefixes associated with a single instruction.23// The prefixes are listed in the same order as found in the instruction:24// each prefix byte corresponds to one slot in the array. The first zero25// in the array marks the end of the prefixes.26type Prefixes [14]Prefix27// A Prefix represents an Intel instruction prefix.28// The low 8 bits are the actual prefix byte encoding,29// and the top 8 bits contain distinguishing bits and metadata.30type Prefix uint1631const (32 // Metadata about the role of a prefix in an instruction.33 PrefixImplicit Prefix = 0x8000 // prefix is implied by instruction text34 PrefixIgnored Prefix = 0x4000 // prefix is ignored: either irrelevant or overridden by a later prefix35 PrefixInvalid Prefix = 0x2000 // prefix makes entire instruction invalid (bad LOCK)36 // Memory segment overrides.37 PrefixES Prefix = 0x26 // ES segment override38 PrefixCS Prefix = 0x2E // CS segment override39 PrefixSS Prefix = 0x36 // SS segment override40 PrefixDS Prefix = 0x3E // DS segment override41 PrefixFS Prefix = 0x64 // FS segment override42 PrefixGS Prefix = 0x65 // GS segment override43 // Branch prediction.44 PrefixPN Prefix = 0x12E // predict not taken (conditional branch only)45 PrefixPT Prefix = 0x13E // predict taken (conditional branch only)46 // Size attributes.47 PrefixDataSize Prefix = 0x66 // operand size override48 PrefixData16 Prefix = 0x16649 PrefixData32 Prefix = 0x26650 PrefixAddrSize Prefix = 0x67 // address size override51 PrefixAddr16 Prefix = 0x16752 PrefixAddr32 Prefix = 0x26753 // One of a kind.54 PrefixLOCK Prefix = 0xF0 // lock55 PrefixREPN Prefix = 0xF2 // repeat not zero56 PrefixXACQUIRE Prefix = 0x1F257 PrefixBND Prefix = 0x2F258 PrefixREP Prefix = 0xF3 // repeat59 PrefixXRELEASE Prefix = 0x1F360 // The REX prefixes must be in the range [PrefixREX, PrefixREX+0x10).61 // the other bits are set or not according to the intended use.62 PrefixREX Prefix = 0x40 // REX 64-bit extension prefix63 PrefixREXW Prefix = 0x08 // extension bit W (64-bit instruction width)64 PrefixREXR Prefix = 0x04 // extension bit R (r field in modrm)65 PrefixREXX Prefix = 0x02 // extension bit X (index field in sib)66 PrefixREXB Prefix = 0x01 // extension bit B (r/m field in modrm or base field in sib)67)68// IsREX reports whether p is a REX prefix byte.69func (p Prefix) IsREX() bool {70 return p&0xF0 == PrefixREX71}72func (p Prefix) String() string {73 p &^= PrefixImplicit | PrefixIgnored | PrefixInvalid74 if s := prefixNames[p]; s != "" {75 return s76 }77 if p.IsREX() {78 s := "REX."79 if p&PrefixREXW != 0 {80 s += "W"81 }82 if p&PrefixREXR != 0 {83 s += "R"84 }85 if p&PrefixREXX != 0 {86 s += "X"87 }88 if p&PrefixREXB != 0 {89 s += "B"90 }91 return s92 }93 return fmt.Sprintf("Prefix(%#x)", int(p))94}95// An Op is an x86 opcode.96type Op uint3297func (op Op) String() string {98 i := int(op)99 if i < 0 || i >= len(opNames) || opNames[i] == "" {100 return fmt.Sprintf("Op(%d)", i)101 }102 return opNames[i]103}104// An Args holds the instruction arguments.105// If an instruction has fewer than 4 arguments,106// the final elements in the array are nil.107type Args [4]Arg108// An Arg is a single instruction argument,109// one of these types: Reg, Mem, Imm, Rel.110type Arg interface {111 String() string112 isArg()113}114// Note that the implements of Arg that follow are all sized115// so that on a 64-bit machine the data can be inlined in116// the interface value instead of requiring an allocation.117// A Reg is a single register.118// The zero Reg value has no name but indicates ``no register.''119type Reg uint8120const (121 _ Reg = iota122 // 8-bit123 AL124 CL125 DL126 BL127 AH128 CH129 DH130 BH131 SPB132 BPB133 SIB134 DIB135 R8B136 R9B137 R10B138 R11B139 R12B140 R13B141 R14B142 R15B143 // 16-bit144 AX145 CX146 DX147 BX148 SP149 BP150 SI151 DI152 R8W153 R9W154 R10W155 R11W156 R12W157 R13W158 R14W159 R15W160 // 32-bit161 EAX162 ECX163 EDX164 EBX165 ESP166 EBP167 ESI168 EDI169 R8L170 R9L171 R10L172 R11L173 R12L174 R13L175 R14L176 R15L177 // 64-bit178 RAX179 RCX180 RDX181 RBX182 RSP183 RBP184 RSI185 RDI186 R8187 R9188 R10189 R11190 R12191 R13192 R14193 R15194 // Instruction pointer.195 IP // 16-bit196 EIP // 32-bit197 RIP // 64-bit198 // 387 floating point registers.199 F0200 F1201 F2202 F3203 F4204 F5205 F6206 F7207 // MMX registers.208 M0209 M1210 M2211 M3212 M4213 M5214 M6215 M7216 // XMM registers.217 X0218 X1219 X2220 X3221 X4222 X5223 X6224 X7225 X8226 X9227 X10228 X11229 X12230 X13231 X14232 X15233 // Segment registers.234 ES235 CS236 SS237 DS238 FS239 GS240 // System registers.241 GDTR242 IDTR243 LDTR244 MSW245 TASK246 // Control registers.247 CR0248 CR1249 CR2250 CR3251 CR4252 CR5253 CR6254 CR7255 CR8256 CR9257 CR10258 CR11259 CR12260 CR13261 CR14262 CR15263 // Debug registers.264 DR0265 DR1266 DR2267 DR3268 DR4269 DR5270 DR6271 DR7272 DR8273 DR9274 DR10275 DR11276 DR12277 DR13278 DR14279 DR15280 // Task registers.281 TR0282 TR1283 TR2284 TR3285 TR4286 TR5287 TR6288 TR7289)290const regMax = TR7291func (Reg) isArg() {}292func (r Reg) String() string {293 i := int(r)294 if i < 0 || i >= len(regNames) || regNames[i] == "" {295 return fmt.Sprintf("Reg(%d)", i)296 }297 return regNames[i]298}299// A Mem is a memory reference.300// The general form is Segment:[Base+Scale*Index+Disp].301type Mem struct {302 Segment Reg303 Base Reg304 Scale uint8305 Index Reg306 Disp int64307}308func (Mem) isArg() {}309func (m Mem) String() string {310 var base, plus, scale, index, disp string311 if m.Base != 0 {312 base = m.Base.String()313 }314 if m.Scale != 0 {315 if m.Base != 0 {316 plus = "+"317 }318 if m.Scale > 1 {319 scale = fmt.Sprintf("%d*", m.Scale)320 }321 index = m.Index.String()322 }323 if m.Disp != 0 || m.Base == 0 && m.Scale == 0 {324 disp = fmt.Sprintf("%+#x", m.Disp)325 }326 return "[" + base + plus + scale + index + disp + "]"327}328// A Rel is an offset relative to the current instruction pointer.329type Rel int32330func (Rel) isArg() {}331func (r Rel) String() string {332 return fmt.Sprintf(".%+d", r)333}334// An Imm is an integer constant.335type Imm int64336func (Imm) isArg() {}337func (i Imm) String() string {338 return fmt.Sprintf("%#x", int64(i))339}340func (i Inst) String() string {341 var buf bytes.Buffer342 for _, p := range i.Prefix {343 if p == 0 {344 break345 }346 if p&PrefixImplicit != 0 {347 continue348 }349 fmt.Fprintf(&buf, "%v ", p)350 }351 fmt.Fprintf(&buf, "%v", i.Op)352 sep := " "353 for _, v := range i.Args {354 if v == nil {355 break356 }357 fmt.Fprintf(&buf, "%s%v", sep, v)358 sep = ", "359 }360 return buf.String()361}362func isReg(a Arg) bool {363 _, ok := a.(Reg)364 return ok365}366func isSegReg(a Arg) bool {367 r, ok := a.(Reg)368 return ok && ES <= r && r <= GS369}370func isMem(a Arg) bool {371 _, ok := a.(Mem)372 return ok373}374func isImm(a Arg) bool {375 _, ok := a.(Imm)376 return ok377}378func regBytes(a Arg) int {379 r, ok := a.(Reg)380 if !ok {381 return 0382 }383 if AL <= r && r <= R15B {384 return 1385 }386 if AX <= r && r <= R15W {387 return 2388 }389 if EAX <= r && r <= R15L {390 return 4391 }392 if RAX <= r && r <= R15 {393 return 8394 }395 return 0396}397func isSegment(p Prefix) bool {398 switch p {399 case PrefixCS, PrefixDS, PrefixES, PrefixFS, PrefixGS, PrefixSS:400 return true401 }402 return false403}404// The Op definitions and string list are in tables.go.405var prefixNames = map[Prefix]string{406 PrefixCS: "CS",407 PrefixDS: "DS",408 PrefixES: "ES",409 PrefixFS: "FS",410 PrefixGS: "GS",411 PrefixSS: "SS",412 PrefixLOCK: "LOCK",413 PrefixREP: "REP",414 PrefixREPN: "REPN",415 PrefixAddrSize: "ADDRSIZE",416 PrefixDataSize: "DATASIZE",417 PrefixAddr16: "ADDR16",418 PrefixData16: "DATA16",419 PrefixAddr32: "ADDR32",420 PrefixData32: "DATA32",421 PrefixBND: "BND",422 PrefixXACQUIRE: "XACQUIRE",423 PrefixXRELEASE: "XRELEASE",424 PrefixREX: "REX",425 PrefixPT: "PT",426 PrefixPN: "PN",427}428var regNames = [...]string{429 AL: "AL",430 CL: "CL",431 BL: "BL",432 DL: "DL",433 AH: "AH",434 CH: "CH",435 BH: "BH",436 DH: "DH",437 SPB: "SPB",438 BPB: "BPB",439 SIB: "SIB",440 DIB: "DIB",441 R8B: "R8B",442 R9B: "R9B",443 R10B: "R10B",444 R11B: "R11B",445 R12B: "R12B",446 R13B: "R13B",447 R14B: "R14B",448 R15B: "R15B",449 AX: "AX",450 CX: "CX",451 BX: "BX",452 DX: "DX",453 SP: "SP",454 BP: "BP",455 SI: "SI",456 DI: "DI",457 R8W: "R8W",458 R9W: "R9W",459 R10W: "R10W",460 R11W: "R11W",461 R12W: "R12W",462 R13W: "R13W",463 R14W: "R14W",464 R15W: "R15W",465 EAX: "EAX",466 ECX: "ECX",467 EDX: "EDX",468 EBX: "EBX",469 ESP: "ESP",470 EBP: "EBP",471 ESI: "ESI",472 EDI: "EDI",473 R8L: "R8L",474 R9L: "R9L",475 R10L: "R10L",476 R11L: "R11L",477 R12L: "R12L",478 R13L: "R13L",479 R14L: "R14L",480 R15L: "R15L",481 RAX: "RAX",482 RCX: "RCX",483 RDX: "RDX",484 RBX: "RBX",485 RSP: "RSP",486 RBP: "RBP",487 RSI: "RSI",488 RDI: "RDI",489 R8: "R8",490 R9: "R9",491 R10: "R10",492 R11: "R11",493 R12: "R12",494 R13: "R13",495 R14: "R14",496 R15: "R15",497 IP: "IP",498 EIP: "EIP",499 RIP: "RIP",500 F0: "F0",501 F1: "F1",502 F2: "F2",503 F3: "F3",504 F4: "F4",505 F5: "F5",506 F6: "F6",507 F7: "F7",508 M0: "M0",509 M1: "M1",510 M2: "M2",511 M3: "M3",512 M4: "M4",513 M5: "M5",514 M6: "M6",515 M7: "M7",516 X0: "X0",517 X1: "X1",518 X2: "X2",519 X3: "X3",520 X4: "X4",521 X5: "X5",522 X6: "X6",523 X7: "X7",524 X8: "X8",525 X9: "X9",526 X10: "X10",527 X11: "X11",528 X12: "X12",529 X13: "X13",530 X14: "X14",531 X15: "X15",532 CS: "CS",533 SS: "SS",534 DS: "DS",535 ES: "ES",536 FS: "FS",537 GS: "GS",538 GDTR: "GDTR",539 IDTR: "IDTR",540 LDTR: "LDTR",541 MSW: "MSW",542 TASK: "TASK",543 CR0: "CR0",544 CR1: "CR1",545 CR2: "CR2",546 CR3: "CR3",547 CR4: "CR4",548 CR5: "CR5",549 CR6: "CR6",550 CR7: "CR7",551 CR8: "CR8",552 CR9: "CR9",553 CR10: "CR10",554 CR11: "CR11",555 CR12: "CR12",556 CR13: "CR13",557 CR14: "CR14",558 CR15: "CR15",559 DR0: "DR0",560 DR1: "DR1",561 DR2: "DR2",562 DR3: "DR3",563 DR4: "DR4",564 DR5: "DR5",565 DR6: "DR6",566 DR7: "DR7",567 DR8: "DR8",568 DR9: "DR9",569 DR10: "DR10",570 DR11: "DR11",571 DR12: "DR12",572 DR13: "DR13",573 DR14: "DR14",574 DR15: "DR15",575 TR0: "TR0",576 TR1: "TR1",577 TR2: "TR2",578 TR3: "TR3",579 TR4: "TR4",580 TR5: "TR5",581 TR6: "TR6",582 TR7: "TR7",583}...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!