mirror of
https://github.com/42wim/matterbridge.git
synced 2024-11-24 11:42:03 -08:00
Add gops agent
This commit is contained in:
parent
efe641f202
commit
2f68519b3c
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/42wim/matterbridge/gateway"
|
"github.com/42wim/matterbridge/gateway"
|
||||||
"github.com/42wim/matterbridge/gateway/samechannel"
|
"github.com/42wim/matterbridge/gateway/samechannel"
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"github.com/google/gops/agent"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -22,7 +23,12 @@ func main() {
|
|||||||
flagConfig := flag.String("conf", "matterbridge.toml", "config file")
|
flagConfig := flag.String("conf", "matterbridge.toml", "config file")
|
||||||
flagDebug := flag.Bool("debug", false, "enable debug")
|
flagDebug := flag.Bool("debug", false, "enable debug")
|
||||||
flagVersion := flag.Bool("version", false, "show version")
|
flagVersion := flag.Bool("version", false, "show version")
|
||||||
|
flagGops := flag.Bool("gops", false, "enable gops agent")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
if *flagGops {
|
||||||
|
agent.Listen(&agent.Options{})
|
||||||
|
defer agent.Close()
|
||||||
|
}
|
||||||
if *flagVersion {
|
if *flagVersion {
|
||||||
fmt.Printf("version: %s %s\n", version, githash)
|
fmt.Printf("version: %s %s\n", version, githash)
|
||||||
return
|
return
|
||||||
|
27
vendor/github.com/google/gops/agent/LICENSE
generated
vendored
Normal file
27
vendor/github.com/google/gops/agent/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2016 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
237
vendor/github.com/google/gops/agent/agent.go
generated
vendored
Normal file
237
vendor/github.com/google/gops/agent/agent.go
generated
vendored
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package agent provides hooks programs can register to retrieve
|
||||||
|
// diagnostics data by using gops.
|
||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
gosignal "os/signal"
|
||||||
|
"runtime"
|
||||||
|
"runtime/pprof"
|
||||||
|
"runtime/trace"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"bufio"
|
||||||
|
|
||||||
|
"github.com/google/gops/internal"
|
||||||
|
"github.com/google/gops/signal"
|
||||||
|
"github.com/kardianos/osext"
|
||||||
|
)
|
||||||
|
|
||||||
|
const defaultAddr = "127.0.0.1:0"
|
||||||
|
|
||||||
|
var (
|
||||||
|
mu sync.Mutex
|
||||||
|
portfile string
|
||||||
|
listener net.Listener
|
||||||
|
|
||||||
|
units = []string{" bytes", "KB", "MB", "GB", "TB", "PB"}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Options allows configuring the started agent.
|
||||||
|
type Options struct {
|
||||||
|
// Addr is the host:port the agent will be listening at.
|
||||||
|
// Optional.
|
||||||
|
Addr string
|
||||||
|
|
||||||
|
// NoShutdownCleanup tells the agent not to automatically cleanup
|
||||||
|
// resources if the running process receives an interrupt.
|
||||||
|
// Optional.
|
||||||
|
NoShutdownCleanup bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen starts the gops agent on a host process. Once agent started, users
|
||||||
|
// can use the advanced gops features. The agent will listen to Interrupt
|
||||||
|
// signals and exit the process, if you need to perform further work on the
|
||||||
|
// Interrupt signal use the options parameter to configure the agent
|
||||||
|
// accordingly.
|
||||||
|
//
|
||||||
|
// Note: The agent exposes an endpoint via a TCP connection that can be used by
|
||||||
|
// any program on the system. Review your security requirements before starting
|
||||||
|
// the agent.
|
||||||
|
func Listen(opts *Options) error {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
|
||||||
|
if opts == nil {
|
||||||
|
opts = &Options{}
|
||||||
|
}
|
||||||
|
if portfile != "" {
|
||||||
|
return fmt.Errorf("gops: agent already listening at: %v", listener.Addr())
|
||||||
|
}
|
||||||
|
|
||||||
|
gopsdir, err := internal.ConfigDir()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = os.MkdirAll(gopsdir, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !opts.NoShutdownCleanup {
|
||||||
|
gracefulShutdown()
|
||||||
|
}
|
||||||
|
|
||||||
|
addr := opts.Addr
|
||||||
|
if addr == "" {
|
||||||
|
addr = defaultAddr
|
||||||
|
}
|
||||||
|
ln, err := net.Listen("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
listener = ln
|
||||||
|
port := listener.Addr().(*net.TCPAddr).Port
|
||||||
|
portfile = fmt.Sprintf("%s/%d", gopsdir, os.Getpid())
|
||||||
|
err = ioutil.WriteFile(portfile, []byte(strconv.Itoa(port)), os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
go listen()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func listen() {
|
||||||
|
buf := make([]byte, 1)
|
||||||
|
for {
|
||||||
|
fd, err := listener.Accept()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "gops: %v", err)
|
||||||
|
if netErr, ok := err.(net.Error); ok && !netErr.Temporary() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, err := fd.Read(buf); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "gops: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := handle(fd, buf); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "gops: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fd.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func gracefulShutdown() {
|
||||||
|
c := make(chan os.Signal, 1)
|
||||||
|
gosignal.Notify(c, os.Interrupt)
|
||||||
|
go func() {
|
||||||
|
// cleanup the socket on shutdown.
|
||||||
|
<-c
|
||||||
|
Close()
|
||||||
|
os.Exit(1)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes the agent, removing temporary files and closing the TCP listener.
|
||||||
|
// If no agent is listening, Close does nothing.
|
||||||
|
func Close() {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
|
||||||
|
if portfile != "" {
|
||||||
|
os.Remove(portfile)
|
||||||
|
portfile = ""
|
||||||
|
}
|
||||||
|
if listener != nil {
|
||||||
|
listener.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatBytes(val uint64) string {
|
||||||
|
var i int
|
||||||
|
var target uint64
|
||||||
|
for i = range units {
|
||||||
|
target = 1 << uint(10*(i+1))
|
||||||
|
if val < target {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if i > 0 {
|
||||||
|
return fmt.Sprintf("%0.2f%s (%d bytes)", float64(val)/(float64(target)/1024), units[i], val)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%d bytes", val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handle(conn io.Writer, msg []byte) error {
|
||||||
|
switch msg[0] {
|
||||||
|
case signal.StackTrace:
|
||||||
|
return pprof.Lookup("goroutine").WriteTo(conn, 2)
|
||||||
|
case signal.GC:
|
||||||
|
runtime.GC()
|
||||||
|
_, err := conn.Write([]byte("ok"))
|
||||||
|
return err
|
||||||
|
case signal.MemStats:
|
||||||
|
var s runtime.MemStats
|
||||||
|
runtime.ReadMemStats(&s)
|
||||||
|
fmt.Fprintf(conn, "alloc: %v\n", formatBytes(s.Alloc))
|
||||||
|
fmt.Fprintf(conn, "total-alloc: %v\n", formatBytes(s.TotalAlloc))
|
||||||
|
fmt.Fprintf(conn, "sys: %v\n", formatBytes(s.Sys))
|
||||||
|
fmt.Fprintf(conn, "lookups: %v\n", s.Lookups)
|
||||||
|
fmt.Fprintf(conn, "mallocs: %v\n", s.Mallocs)
|
||||||
|
fmt.Fprintf(conn, "frees: %v\n", s.Frees)
|
||||||
|
fmt.Fprintf(conn, "heap-alloc: %v\n", formatBytes(s.HeapAlloc))
|
||||||
|
fmt.Fprintf(conn, "heap-sys: %v\n", formatBytes(s.HeapSys))
|
||||||
|
fmt.Fprintf(conn, "heap-idle: %v\n", formatBytes(s.HeapIdle))
|
||||||
|
fmt.Fprintf(conn, "heap-in-use: %v\n", formatBytes(s.HeapInuse))
|
||||||
|
fmt.Fprintf(conn, "heap-released: %v\n", formatBytes(s.HeapReleased))
|
||||||
|
fmt.Fprintf(conn, "heap-objects: %v\n", s.HeapObjects)
|
||||||
|
fmt.Fprintf(conn, "stack-in-use: %v\n", formatBytes(s.StackInuse))
|
||||||
|
fmt.Fprintf(conn, "stack-sys: %v\n", formatBytes(s.StackSys))
|
||||||
|
fmt.Fprintf(conn, "next-gc: when heap-alloc >= %v\n", formatBytes(s.NextGC))
|
||||||
|
lastGC := "-"
|
||||||
|
if s.LastGC != 0 {
|
||||||
|
lastGC = fmt.Sprint(time.Unix(0, int64(s.LastGC)))
|
||||||
|
}
|
||||||
|
fmt.Fprintf(conn, "last-gc: %v\n", lastGC)
|
||||||
|
fmt.Fprintf(conn, "gc-pause: %v\n", time.Duration(s.PauseTotalNs))
|
||||||
|
fmt.Fprintf(conn, "num-gc: %v\n", s.NumGC)
|
||||||
|
fmt.Fprintf(conn, "enable-gc: %v\n", s.EnableGC)
|
||||||
|
fmt.Fprintf(conn, "debug-gc: %v\n", s.DebugGC)
|
||||||
|
case signal.Version:
|
||||||
|
fmt.Fprintf(conn, "%v\n", runtime.Version())
|
||||||
|
case signal.HeapProfile:
|
||||||
|
pprof.WriteHeapProfile(conn)
|
||||||
|
case signal.CPUProfile:
|
||||||
|
if err := pprof.StartCPUProfile(conn); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
time.Sleep(30 * time.Second)
|
||||||
|
pprof.StopCPUProfile()
|
||||||
|
case signal.Stats:
|
||||||
|
fmt.Fprintf(conn, "goroutines: %v\n", runtime.NumGoroutine())
|
||||||
|
fmt.Fprintf(conn, "OS threads: %v\n", pprof.Lookup("threadcreate").Count())
|
||||||
|
fmt.Fprintf(conn, "GOMAXPROCS: %v\n", runtime.GOMAXPROCS(0))
|
||||||
|
fmt.Fprintf(conn, "num CPU: %v\n", runtime.NumCPU())
|
||||||
|
case signal.BinaryDump:
|
||||||
|
path, err := osext.Executable()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
_, err = bufio.NewReader(f).WriteTo(conn)
|
||||||
|
return err
|
||||||
|
case signal.Trace:
|
||||||
|
trace.Start(conn)
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
trace.Stop()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
27
vendor/github.com/google/gops/internal/LICENSE
generated
vendored
Normal file
27
vendor/github.com/google/gops/internal/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2016 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
600
vendor/github.com/google/gops/internal/dwarf/dwarf.go
generated
vendored
Normal file
600
vendor/github.com/google/gops/internal/dwarf/dwarf.go
generated
vendored
Normal file
@ -0,0 +1,600 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package dwarf generates DWARF debugging information.
|
||||||
|
// DWARF generation is split between the compiler and the linker,
|
||||||
|
// this package contains the shared code.
|
||||||
|
package dwarf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InfoPrefix is the prefix for all the symbols containing DWARF info entries.
|
||||||
|
const InfoPrefix = "go.info."
|
||||||
|
|
||||||
|
// Sym represents a symbol.
|
||||||
|
type Sym interface {
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Var represents a local variable or a function parameter.
|
||||||
|
type Var struct {
|
||||||
|
Name string
|
||||||
|
Abbrev int // Either DW_ABRV_AUTO or DW_ABRV_PARAM
|
||||||
|
Offset int32
|
||||||
|
Type Sym
|
||||||
|
Link *Var
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Context specifies how to add data to a Sym.
|
||||||
|
type Context interface {
|
||||||
|
PtrSize() int
|
||||||
|
AddInt(s Sym, size int, i int64)
|
||||||
|
AddBytes(s Sym, b []byte)
|
||||||
|
AddAddress(s Sym, t interface{}, ofs int64)
|
||||||
|
AddSectionOffset(s Sym, size int, t interface{}, ofs int64)
|
||||||
|
AddString(s Sym, v string)
|
||||||
|
SymValue(s Sym) int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUleb128 appends v to b using DWARF's unsigned LEB128 encoding.
|
||||||
|
func AppendUleb128(b []byte, v uint64) []byte {
|
||||||
|
for {
|
||||||
|
c := uint8(v & 0x7f)
|
||||||
|
v >>= 7
|
||||||
|
if v != 0 {
|
||||||
|
c |= 0x80
|
||||||
|
}
|
||||||
|
b = append(b, c)
|
||||||
|
if c&0x80 == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendSleb128 appends v to b using DWARF's signed LEB128 encoding.
|
||||||
|
func AppendSleb128(b []byte, v int64) []byte {
|
||||||
|
for {
|
||||||
|
c := uint8(v & 0x7f)
|
||||||
|
s := uint8(v & 0x40)
|
||||||
|
v >>= 7
|
||||||
|
if (v != -1 || s == 0) && (v != 0 || s != 0) {
|
||||||
|
c |= 0x80
|
||||||
|
}
|
||||||
|
b = append(b, c)
|
||||||
|
if c&0x80 == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
var encbuf [20]byte
|
||||||
|
|
||||||
|
// AppendUleb128 appends v to s using DWARF's unsigned LEB128 encoding.
|
||||||
|
func Uleb128put(ctxt Context, s Sym, v int64) {
|
||||||
|
b := AppendUleb128(encbuf[:0], uint64(v))
|
||||||
|
ctxt.AddBytes(s, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendUleb128 appends v to s using DWARF's signed LEB128 encoding.
|
||||||
|
func Sleb128put(ctxt Context, s Sym, v int64) {
|
||||||
|
b := AppendSleb128(encbuf[:0], v)
|
||||||
|
ctxt.AddBytes(s, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defining Abbrevs. This is hardcoded, and there will be
|
||||||
|
* only a handful of them. The DWARF spec places no restriction on
|
||||||
|
* the ordering of attributes in the Abbrevs and DIEs, and we will
|
||||||
|
* always write them out in the order of declaration in the abbrev.
|
||||||
|
*/
|
||||||
|
type dwAttrForm struct {
|
||||||
|
attr uint16
|
||||||
|
form uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go-specific type attributes.
|
||||||
|
const (
|
||||||
|
DW_AT_go_kind = 0x2900
|
||||||
|
DW_AT_go_key = 0x2901
|
||||||
|
DW_AT_go_elem = 0x2902
|
||||||
|
|
||||||
|
DW_AT_internal_location = 253 // params and locals; not emitted
|
||||||
|
)
|
||||||
|
|
||||||
|
// Index into the abbrevs table below.
|
||||||
|
// Keep in sync with ispubname() and ispubtype() below.
|
||||||
|
// ispubtype considers >= NULLTYPE public
|
||||||
|
const (
|
||||||
|
DW_ABRV_NULL = iota
|
||||||
|
DW_ABRV_COMPUNIT
|
||||||
|
DW_ABRV_FUNCTION
|
||||||
|
DW_ABRV_VARIABLE
|
||||||
|
DW_ABRV_AUTO
|
||||||
|
DW_ABRV_PARAM
|
||||||
|
DW_ABRV_STRUCTFIELD
|
||||||
|
DW_ABRV_FUNCTYPEPARAM
|
||||||
|
DW_ABRV_DOTDOTDOT
|
||||||
|
DW_ABRV_ARRAYRANGE
|
||||||
|
DW_ABRV_NULLTYPE
|
||||||
|
DW_ABRV_BASETYPE
|
||||||
|
DW_ABRV_ARRAYTYPE
|
||||||
|
DW_ABRV_CHANTYPE
|
||||||
|
DW_ABRV_FUNCTYPE
|
||||||
|
DW_ABRV_IFACETYPE
|
||||||
|
DW_ABRV_MAPTYPE
|
||||||
|
DW_ABRV_PTRTYPE
|
||||||
|
DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6.
|
||||||
|
DW_ABRV_SLICETYPE
|
||||||
|
DW_ABRV_STRINGTYPE
|
||||||
|
DW_ABRV_STRUCTTYPE
|
||||||
|
DW_ABRV_TYPEDECL
|
||||||
|
DW_NABRV
|
||||||
|
)
|
||||||
|
|
||||||
|
type dwAbbrev struct {
|
||||||
|
tag uint8
|
||||||
|
children uint8
|
||||||
|
attr []dwAttrForm
|
||||||
|
}
|
||||||
|
|
||||||
|
var abbrevs = [DW_NABRV]dwAbbrev{
|
||||||
|
/* The mandatory DW_ABRV_NULL entry. */
|
||||||
|
{0, 0, []dwAttrForm{}},
|
||||||
|
|
||||||
|
/* COMPUNIT */
|
||||||
|
{
|
||||||
|
DW_TAG_compile_unit,
|
||||||
|
DW_CHILDREN_yes,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_language, DW_FORM_data1},
|
||||||
|
{DW_AT_low_pc, DW_FORM_addr},
|
||||||
|
{DW_AT_high_pc, DW_FORM_addr},
|
||||||
|
{DW_AT_stmt_list, DW_FORM_data4},
|
||||||
|
{DW_AT_comp_dir, DW_FORM_string},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* FUNCTION */
|
||||||
|
{
|
||||||
|
DW_TAG_subprogram,
|
||||||
|
DW_CHILDREN_yes,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_low_pc, DW_FORM_addr},
|
||||||
|
{DW_AT_high_pc, DW_FORM_addr},
|
||||||
|
{DW_AT_external, DW_FORM_flag},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* VARIABLE */
|
||||||
|
{
|
||||||
|
DW_TAG_variable,
|
||||||
|
DW_CHILDREN_no,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_location, DW_FORM_block1},
|
||||||
|
{DW_AT_type, DW_FORM_ref_addr},
|
||||||
|
{DW_AT_external, DW_FORM_flag},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* AUTO */
|
||||||
|
{
|
||||||
|
DW_TAG_variable,
|
||||||
|
DW_CHILDREN_no,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_location, DW_FORM_block1},
|
||||||
|
{DW_AT_type, DW_FORM_ref_addr},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* PARAM */
|
||||||
|
{
|
||||||
|
DW_TAG_formal_parameter,
|
||||||
|
DW_CHILDREN_no,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_location, DW_FORM_block1},
|
||||||
|
{DW_AT_type, DW_FORM_ref_addr},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* STRUCTFIELD */
|
||||||
|
{
|
||||||
|
DW_TAG_member,
|
||||||
|
DW_CHILDREN_no,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_data_member_location, DW_FORM_block1},
|
||||||
|
{DW_AT_type, DW_FORM_ref_addr},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* FUNCTYPEPARAM */
|
||||||
|
{
|
||||||
|
DW_TAG_formal_parameter,
|
||||||
|
DW_CHILDREN_no,
|
||||||
|
|
||||||
|
// No name!
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_type, DW_FORM_ref_addr},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* DOTDOTDOT */
|
||||||
|
{
|
||||||
|
DW_TAG_unspecified_parameters,
|
||||||
|
DW_CHILDREN_no,
|
||||||
|
[]dwAttrForm{},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ARRAYRANGE */
|
||||||
|
{
|
||||||
|
DW_TAG_subrange_type,
|
||||||
|
DW_CHILDREN_no,
|
||||||
|
|
||||||
|
// No name!
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_type, DW_FORM_ref_addr},
|
||||||
|
{DW_AT_count, DW_FORM_udata},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Below here are the types considered public by ispubtype
|
||||||
|
/* NULLTYPE */
|
||||||
|
{
|
||||||
|
DW_TAG_unspecified_type,
|
||||||
|
DW_CHILDREN_no,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* BASETYPE */
|
||||||
|
{
|
||||||
|
DW_TAG_base_type,
|
||||||
|
DW_CHILDREN_no,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_encoding, DW_FORM_data1},
|
||||||
|
{DW_AT_byte_size, DW_FORM_data1},
|
||||||
|
{DW_AT_go_kind, DW_FORM_data1},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ARRAYTYPE */
|
||||||
|
// child is subrange with upper bound
|
||||||
|
{
|
||||||
|
DW_TAG_array_type,
|
||||||
|
DW_CHILDREN_yes,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_type, DW_FORM_ref_addr},
|
||||||
|
{DW_AT_byte_size, DW_FORM_udata},
|
||||||
|
{DW_AT_go_kind, DW_FORM_data1},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* CHANTYPE */
|
||||||
|
{
|
||||||
|
DW_TAG_typedef,
|
||||||
|
DW_CHILDREN_no,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_type, DW_FORM_ref_addr},
|
||||||
|
{DW_AT_go_kind, DW_FORM_data1},
|
||||||
|
{DW_AT_go_elem, DW_FORM_ref_addr},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* FUNCTYPE */
|
||||||
|
{
|
||||||
|
DW_TAG_subroutine_type,
|
||||||
|
DW_CHILDREN_yes,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
// {DW_AT_type, DW_FORM_ref_addr},
|
||||||
|
{DW_AT_go_kind, DW_FORM_data1},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* IFACETYPE */
|
||||||
|
{
|
||||||
|
DW_TAG_typedef,
|
||||||
|
DW_CHILDREN_yes,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_type, DW_FORM_ref_addr},
|
||||||
|
{DW_AT_go_kind, DW_FORM_data1},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* MAPTYPE */
|
||||||
|
{
|
||||||
|
DW_TAG_typedef,
|
||||||
|
DW_CHILDREN_no,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_type, DW_FORM_ref_addr},
|
||||||
|
{DW_AT_go_kind, DW_FORM_data1},
|
||||||
|
{DW_AT_go_key, DW_FORM_ref_addr},
|
||||||
|
{DW_AT_go_elem, DW_FORM_ref_addr},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* PTRTYPE */
|
||||||
|
{
|
||||||
|
DW_TAG_pointer_type,
|
||||||
|
DW_CHILDREN_no,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_type, DW_FORM_ref_addr},
|
||||||
|
{DW_AT_go_kind, DW_FORM_data1},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* BARE_PTRTYPE */
|
||||||
|
{
|
||||||
|
DW_TAG_pointer_type,
|
||||||
|
DW_CHILDREN_no,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* SLICETYPE */
|
||||||
|
{
|
||||||
|
DW_TAG_structure_type,
|
||||||
|
DW_CHILDREN_yes,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_byte_size, DW_FORM_udata},
|
||||||
|
{DW_AT_go_kind, DW_FORM_data1},
|
||||||
|
{DW_AT_go_elem, DW_FORM_ref_addr},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* STRINGTYPE */
|
||||||
|
{
|
||||||
|
DW_TAG_structure_type,
|
||||||
|
DW_CHILDREN_yes,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_byte_size, DW_FORM_udata},
|
||||||
|
{DW_AT_go_kind, DW_FORM_data1},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* STRUCTTYPE */
|
||||||
|
{
|
||||||
|
DW_TAG_structure_type,
|
||||||
|
DW_CHILDREN_yes,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_byte_size, DW_FORM_udata},
|
||||||
|
{DW_AT_go_kind, DW_FORM_data1},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* TYPEDECL */
|
||||||
|
{
|
||||||
|
DW_TAG_typedef,
|
||||||
|
DW_CHILDREN_no,
|
||||||
|
[]dwAttrForm{
|
||||||
|
{DW_AT_name, DW_FORM_string},
|
||||||
|
{DW_AT_type, DW_FORM_ref_addr},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAbbrev returns the contents of the .debug_abbrev section.
|
||||||
|
func GetAbbrev() []byte {
|
||||||
|
var buf []byte
|
||||||
|
for i := 1; i < DW_NABRV; i++ {
|
||||||
|
// See section 7.5.3
|
||||||
|
buf = AppendUleb128(buf, uint64(i))
|
||||||
|
|
||||||
|
buf = AppendUleb128(buf, uint64(abbrevs[i].tag))
|
||||||
|
buf = append(buf, byte(abbrevs[i].children))
|
||||||
|
for _, f := range abbrevs[i].attr {
|
||||||
|
buf = AppendUleb128(buf, uint64(f.attr))
|
||||||
|
buf = AppendUleb128(buf, uint64(f.form))
|
||||||
|
}
|
||||||
|
buf = append(buf, 0, 0)
|
||||||
|
}
|
||||||
|
return append(buf, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debugging Information Entries and their attributes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DWAttr represents an attribute of a DWDie.
|
||||||
|
//
|
||||||
|
// For DW_CLS_string and _block, value should contain the length, and
|
||||||
|
// data the data, for _reference, value is 0 and data is a DWDie* to
|
||||||
|
// the referenced instance, for all others, value is the whole thing
|
||||||
|
// and data is null.
|
||||||
|
type DWAttr struct {
|
||||||
|
Link *DWAttr
|
||||||
|
Atr uint16 // DW_AT_
|
||||||
|
Cls uint8 // DW_CLS_
|
||||||
|
Value int64
|
||||||
|
Data interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DWDie represents a DWARF debug info entry.
|
||||||
|
type DWDie struct {
|
||||||
|
Abbrev int
|
||||||
|
Link *DWDie
|
||||||
|
Child *DWDie
|
||||||
|
Attr *DWAttr
|
||||||
|
Sym Sym
|
||||||
|
}
|
||||||
|
|
||||||
|
func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, data interface{}) error {
|
||||||
|
switch form {
|
||||||
|
case DW_FORM_addr: // address
|
||||||
|
ctxt.AddAddress(s, data, value)
|
||||||
|
|
||||||
|
case DW_FORM_block1: // block
|
||||||
|
if cls == DW_CLS_ADDRESS {
|
||||||
|
ctxt.AddInt(s, 1, int64(1+ctxt.PtrSize()))
|
||||||
|
ctxt.AddInt(s, 1, DW_OP_addr)
|
||||||
|
ctxt.AddAddress(s, data, 0)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
value &= 0xff
|
||||||
|
ctxt.AddInt(s, 1, value)
|
||||||
|
p := data.([]byte)[:value]
|
||||||
|
ctxt.AddBytes(s, p)
|
||||||
|
|
||||||
|
case DW_FORM_block2: // block
|
||||||
|
value &= 0xffff
|
||||||
|
|
||||||
|
ctxt.AddInt(s, 2, value)
|
||||||
|
p := data.([]byte)[:value]
|
||||||
|
ctxt.AddBytes(s, p)
|
||||||
|
|
||||||
|
case DW_FORM_block4: // block
|
||||||
|
value &= 0xffffffff
|
||||||
|
|
||||||
|
ctxt.AddInt(s, 4, value)
|
||||||
|
p := data.([]byte)[:value]
|
||||||
|
ctxt.AddBytes(s, p)
|
||||||
|
|
||||||
|
case DW_FORM_block: // block
|
||||||
|
Uleb128put(ctxt, s, value)
|
||||||
|
|
||||||
|
p := data.([]byte)[:value]
|
||||||
|
ctxt.AddBytes(s, p)
|
||||||
|
|
||||||
|
case DW_FORM_data1: // constant
|
||||||
|
ctxt.AddInt(s, 1, value)
|
||||||
|
|
||||||
|
case DW_FORM_data2: // constant
|
||||||
|
ctxt.AddInt(s, 2, value)
|
||||||
|
|
||||||
|
case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr
|
||||||
|
if cls == DW_CLS_PTR { // DW_AT_stmt_list
|
||||||
|
ctxt.AddSectionOffset(s, 4, data, 0)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
ctxt.AddInt(s, 4, value)
|
||||||
|
|
||||||
|
case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr
|
||||||
|
ctxt.AddInt(s, 8, value)
|
||||||
|
|
||||||
|
case DW_FORM_sdata: // constant
|
||||||
|
Sleb128put(ctxt, s, value)
|
||||||
|
|
||||||
|
case DW_FORM_udata: // constant
|
||||||
|
Uleb128put(ctxt, s, value)
|
||||||
|
|
||||||
|
case DW_FORM_string: // string
|
||||||
|
str := data.(string)
|
||||||
|
ctxt.AddString(s, str)
|
||||||
|
// TODO(ribrdb): verify padded strings are never used and remove this
|
||||||
|
for i := int64(len(str)); i < value; i++ {
|
||||||
|
ctxt.AddInt(s, 1, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
case DW_FORM_flag: // flag
|
||||||
|
if value != 0 {
|
||||||
|
ctxt.AddInt(s, 1, 1)
|
||||||
|
} else {
|
||||||
|
ctxt.AddInt(s, 1, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// In DWARF 2 (which is what we claim to generate),
|
||||||
|
// the ref_addr is the same size as a normal address.
|
||||||
|
// In DWARF 3 it is always 32 bits, unless emitting a large
|
||||||
|
// (> 4 GB of debug info aka "64-bit") unit, which we don't implement.
|
||||||
|
case DW_FORM_ref_addr: // reference to a DIE in the .info section
|
||||||
|
if data == nil {
|
||||||
|
return fmt.Errorf("dwarf: null reference in %d", abbrev)
|
||||||
|
} else {
|
||||||
|
ctxt.AddSectionOffset(s, ctxt.PtrSize(), data, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
case DW_FORM_ref1, // reference within the compilation unit
|
||||||
|
DW_FORM_ref2, // reference
|
||||||
|
DW_FORM_ref4, // reference
|
||||||
|
DW_FORM_ref8, // reference
|
||||||
|
DW_FORM_ref_udata, // reference
|
||||||
|
|
||||||
|
DW_FORM_strp, // string
|
||||||
|
DW_FORM_indirect: // (see Section 7.5.3)
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("dwarf: unsupported attribute form %d / class %d", form, cls)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutAttrs writes the attributes for a DIE to symbol 's'.
|
||||||
|
//
|
||||||
|
// Note that we can (and do) add arbitrary attributes to a DIE, but
|
||||||
|
// only the ones actually listed in the Abbrev will be written out.
|
||||||
|
func PutAttrs(ctxt Context, s Sym, abbrev int, attr *DWAttr) {
|
||||||
|
Outer:
|
||||||
|
for _, f := range abbrevs[abbrev].attr {
|
||||||
|
for ap := attr; ap != nil; ap = ap.Link {
|
||||||
|
if ap.Atr == f.attr {
|
||||||
|
putattr(ctxt, s, abbrev, int(f.form), int(ap.Cls), ap.Value, ap.Data)
|
||||||
|
continue Outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
putattr(ctxt, s, abbrev, int(f.form), 0, 0, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasChildren returns true if 'die' uses an abbrev that supports children.
|
||||||
|
func HasChildren(die *DWDie) bool {
|
||||||
|
return abbrevs[die.Abbrev].children != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutFunc writes a DIE for a function to s.
|
||||||
|
// It also writes child DIEs for each variable in vars.
|
||||||
|
func PutFunc(ctxt Context, s Sym, name string, external bool, startPC Sym, size int64, vars *Var) {
|
||||||
|
Uleb128put(ctxt, s, DW_ABRV_FUNCTION)
|
||||||
|
putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name)
|
||||||
|
putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_addr, DW_CLS_ADDRESS, 0, startPC)
|
||||||
|
putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_addr, DW_CLS_ADDRESS, size+ctxt.SymValue(startPC), startPC)
|
||||||
|
var ev int64
|
||||||
|
if external {
|
||||||
|
ev = 1
|
||||||
|
}
|
||||||
|
putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_flag, DW_CLS_FLAG, ev, 0)
|
||||||
|
names := make(map[string]bool)
|
||||||
|
for v := vars; v != nil; v = v.Link {
|
||||||
|
var n string
|
||||||
|
if names[v.Name] {
|
||||||
|
n = fmt.Sprintf("%s#%d", v.Name, len(names))
|
||||||
|
} else {
|
||||||
|
n = v.Name
|
||||||
|
}
|
||||||
|
names[n] = true
|
||||||
|
|
||||||
|
Uleb128put(ctxt, s, int64(v.Abbrev))
|
||||||
|
putattr(ctxt, s, v.Abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n)
|
||||||
|
loc := append(encbuf[:0], DW_OP_call_frame_cfa)
|
||||||
|
if v.Offset != 0 {
|
||||||
|
loc = append(loc, DW_OP_consts)
|
||||||
|
loc = AppendSleb128(loc, int64(v.Offset))
|
||||||
|
loc = append(loc, DW_OP_plus)
|
||||||
|
}
|
||||||
|
putattr(ctxt, s, v.Abbrev, DW_FORM_block1, DW_CLS_BLOCK, int64(len(loc)), loc)
|
||||||
|
putattr(ctxt, s, v.Abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type)
|
||||||
|
|
||||||
|
}
|
||||||
|
Uleb128put(ctxt, s, 0)
|
||||||
|
}
|
483
vendor/github.com/google/gops/internal/dwarf/dwarf_defs.go
generated
vendored
Normal file
483
vendor/github.com/google/gops/internal/dwarf/dwarf_defs.go
generated
vendored
Normal file
@ -0,0 +1,483 @@
|
|||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package dwarf
|
||||||
|
|
||||||
|
// Cut, pasted, tr-and-awk'ed from tables in
|
||||||
|
// http://dwarfstd.org/doc/Dwarf3.pdf
|
||||||
|
|
||||||
|
// Table 18
|
||||||
|
const (
|
||||||
|
DW_TAG_array_type = 0x01
|
||||||
|
DW_TAG_class_type = 0x02
|
||||||
|
DW_TAG_entry_point = 0x03
|
||||||
|
DW_TAG_enumeration_type = 0x04
|
||||||
|
DW_TAG_formal_parameter = 0x05
|
||||||
|
DW_TAG_imported_declaration = 0x08
|
||||||
|
DW_TAG_label = 0x0a
|
||||||
|
DW_TAG_lexical_block = 0x0b
|
||||||
|
DW_TAG_member = 0x0d
|
||||||
|
DW_TAG_pointer_type = 0x0f
|
||||||
|
DW_TAG_reference_type = 0x10
|
||||||
|
DW_TAG_compile_unit = 0x11
|
||||||
|
DW_TAG_string_type = 0x12
|
||||||
|
DW_TAG_structure_type = 0x13
|
||||||
|
DW_TAG_subroutine_type = 0x15
|
||||||
|
DW_TAG_typedef = 0x16
|
||||||
|
DW_TAG_union_type = 0x17
|
||||||
|
DW_TAG_unspecified_parameters = 0x18
|
||||||
|
DW_TAG_variant = 0x19
|
||||||
|
DW_TAG_common_block = 0x1a
|
||||||
|
DW_TAG_common_inclusion = 0x1b
|
||||||
|
DW_TAG_inheritance = 0x1c
|
||||||
|
DW_TAG_inlined_subroutine = 0x1d
|
||||||
|
DW_TAG_module = 0x1e
|
||||||
|
DW_TAG_ptr_to_member_type = 0x1f
|
||||||
|
DW_TAG_set_type = 0x20
|
||||||
|
DW_TAG_subrange_type = 0x21
|
||||||
|
DW_TAG_with_stmt = 0x22
|
||||||
|
DW_TAG_access_declaration = 0x23
|
||||||
|
DW_TAG_base_type = 0x24
|
||||||
|
DW_TAG_catch_block = 0x25
|
||||||
|
DW_TAG_const_type = 0x26
|
||||||
|
DW_TAG_constant = 0x27
|
||||||
|
DW_TAG_enumerator = 0x28
|
||||||
|
DW_TAG_file_type = 0x29
|
||||||
|
DW_TAG_friend = 0x2a
|
||||||
|
DW_TAG_namelist = 0x2b
|
||||||
|
DW_TAG_namelist_item = 0x2c
|
||||||
|
DW_TAG_packed_type = 0x2d
|
||||||
|
DW_TAG_subprogram = 0x2e
|
||||||
|
DW_TAG_template_type_parameter = 0x2f
|
||||||
|
DW_TAG_template_value_parameter = 0x30
|
||||||
|
DW_TAG_thrown_type = 0x31
|
||||||
|
DW_TAG_try_block = 0x32
|
||||||
|
DW_TAG_variant_part = 0x33
|
||||||
|
DW_TAG_variable = 0x34
|
||||||
|
DW_TAG_volatile_type = 0x35
|
||||||
|
// Dwarf3
|
||||||
|
DW_TAG_dwarf_procedure = 0x36
|
||||||
|
DW_TAG_restrict_type = 0x37
|
||||||
|
DW_TAG_interface_type = 0x38
|
||||||
|
DW_TAG_namespace = 0x39
|
||||||
|
DW_TAG_imported_module = 0x3a
|
||||||
|
DW_TAG_unspecified_type = 0x3b
|
||||||
|
DW_TAG_partial_unit = 0x3c
|
||||||
|
DW_TAG_imported_unit = 0x3d
|
||||||
|
DW_TAG_condition = 0x3f
|
||||||
|
DW_TAG_shared_type = 0x40
|
||||||
|
// Dwarf4
|
||||||
|
DW_TAG_type_unit = 0x41
|
||||||
|
DW_TAG_rvalue_reference_type = 0x42
|
||||||
|
DW_TAG_template_alias = 0x43
|
||||||
|
|
||||||
|
// User defined
|
||||||
|
DW_TAG_lo_user = 0x4080
|
||||||
|
DW_TAG_hi_user = 0xffff
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 19
|
||||||
|
const (
|
||||||
|
DW_CHILDREN_no = 0x00
|
||||||
|
DW_CHILDREN_yes = 0x01
|
||||||
|
)
|
||||||
|
|
||||||
|
// Not from the spec, but logically belongs here
|
||||||
|
const (
|
||||||
|
DW_CLS_ADDRESS = 0x01 + iota
|
||||||
|
DW_CLS_BLOCK
|
||||||
|
DW_CLS_CONSTANT
|
||||||
|
DW_CLS_FLAG
|
||||||
|
DW_CLS_PTR // lineptr, loclistptr, macptr, rangelistptr
|
||||||
|
DW_CLS_REFERENCE
|
||||||
|
DW_CLS_ADDRLOC
|
||||||
|
DW_CLS_STRING
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 20
|
||||||
|
const (
|
||||||
|
DW_AT_sibling = 0x01 // reference
|
||||||
|
DW_AT_location = 0x02 // block, loclistptr
|
||||||
|
DW_AT_name = 0x03 // string
|
||||||
|
DW_AT_ordering = 0x09 // constant
|
||||||
|
DW_AT_byte_size = 0x0b // block, constant, reference
|
||||||
|
DW_AT_bit_offset = 0x0c // block, constant, reference
|
||||||
|
DW_AT_bit_size = 0x0d // block, constant, reference
|
||||||
|
DW_AT_stmt_list = 0x10 // lineptr
|
||||||
|
DW_AT_low_pc = 0x11 // address
|
||||||
|
DW_AT_high_pc = 0x12 // address
|
||||||
|
DW_AT_language = 0x13 // constant
|
||||||
|
DW_AT_discr = 0x15 // reference
|
||||||
|
DW_AT_discr_value = 0x16 // constant
|
||||||
|
DW_AT_visibility = 0x17 // constant
|
||||||
|
DW_AT_import = 0x18 // reference
|
||||||
|
DW_AT_string_length = 0x19 // block, loclistptr
|
||||||
|
DW_AT_common_reference = 0x1a // reference
|
||||||
|
DW_AT_comp_dir = 0x1b // string
|
||||||
|
DW_AT_const_value = 0x1c // block, constant, string
|
||||||
|
DW_AT_containing_type = 0x1d // reference
|
||||||
|
DW_AT_default_value = 0x1e // reference
|
||||||
|
DW_AT_inline = 0x20 // constant
|
||||||
|
DW_AT_is_optional = 0x21 // flag
|
||||||
|
DW_AT_lower_bound = 0x22 // block, constant, reference
|
||||||
|
DW_AT_producer = 0x25 // string
|
||||||
|
DW_AT_prototyped = 0x27 // flag
|
||||||
|
DW_AT_return_addr = 0x2a // block, loclistptr
|
||||||
|
DW_AT_start_scope = 0x2c // constant
|
||||||
|
DW_AT_bit_stride = 0x2e // constant
|
||||||
|
DW_AT_upper_bound = 0x2f // block, constant, reference
|
||||||
|
DW_AT_abstract_origin = 0x31 // reference
|
||||||
|
DW_AT_accessibility = 0x32 // constant
|
||||||
|
DW_AT_address_class = 0x33 // constant
|
||||||
|
DW_AT_artificial = 0x34 // flag
|
||||||
|
DW_AT_base_types = 0x35 // reference
|
||||||
|
DW_AT_calling_convention = 0x36 // constant
|
||||||
|
DW_AT_count = 0x37 // block, constant, reference
|
||||||
|
DW_AT_data_member_location = 0x38 // block, constant, loclistptr
|
||||||
|
DW_AT_decl_column = 0x39 // constant
|
||||||
|
DW_AT_decl_file = 0x3a // constant
|
||||||
|
DW_AT_decl_line = 0x3b // constant
|
||||||
|
DW_AT_declaration = 0x3c // flag
|
||||||
|
DW_AT_discr_list = 0x3d // block
|
||||||
|
DW_AT_encoding = 0x3e // constant
|
||||||
|
DW_AT_external = 0x3f // flag
|
||||||
|
DW_AT_frame_base = 0x40 // block, loclistptr
|
||||||
|
DW_AT_friend = 0x41 // reference
|
||||||
|
DW_AT_identifier_case = 0x42 // constant
|
||||||
|
DW_AT_macro_info = 0x43 // macptr
|
||||||
|
DW_AT_namelist_item = 0x44 // block
|
||||||
|
DW_AT_priority = 0x45 // reference
|
||||||
|
DW_AT_segment = 0x46 // block, loclistptr
|
||||||
|
DW_AT_specification = 0x47 // reference
|
||||||
|
DW_AT_static_link = 0x48 // block, loclistptr
|
||||||
|
DW_AT_type = 0x49 // reference
|
||||||
|
DW_AT_use_location = 0x4a // block, loclistptr
|
||||||
|
DW_AT_variable_parameter = 0x4b // flag
|
||||||
|
DW_AT_virtuality = 0x4c // constant
|
||||||
|
DW_AT_vtable_elem_location = 0x4d // block, loclistptr
|
||||||
|
// Dwarf3
|
||||||
|
DW_AT_allocated = 0x4e // block, constant, reference
|
||||||
|
DW_AT_associated = 0x4f // block, constant, reference
|
||||||
|
DW_AT_data_location = 0x50 // block
|
||||||
|
DW_AT_byte_stride = 0x51 // block, constant, reference
|
||||||
|
DW_AT_entry_pc = 0x52 // address
|
||||||
|
DW_AT_use_UTF8 = 0x53 // flag
|
||||||
|
DW_AT_extension = 0x54 // reference
|
||||||
|
DW_AT_ranges = 0x55 // rangelistptr
|
||||||
|
DW_AT_trampoline = 0x56 // address, flag, reference, string
|
||||||
|
DW_AT_call_column = 0x57 // constant
|
||||||
|
DW_AT_call_file = 0x58 // constant
|
||||||
|
DW_AT_call_line = 0x59 // constant
|
||||||
|
DW_AT_description = 0x5a // string
|
||||||
|
DW_AT_binary_scale = 0x5b // constant
|
||||||
|
DW_AT_decimal_scale = 0x5c // constant
|
||||||
|
DW_AT_small = 0x5d // reference
|
||||||
|
DW_AT_decimal_sign = 0x5e // constant
|
||||||
|
DW_AT_digit_count = 0x5f // constant
|
||||||
|
DW_AT_picture_string = 0x60 // string
|
||||||
|
DW_AT_mutable = 0x61 // flag
|
||||||
|
DW_AT_threads_scaled = 0x62 // flag
|
||||||
|
DW_AT_explicit = 0x63 // flag
|
||||||
|
DW_AT_object_pointer = 0x64 // reference
|
||||||
|
DW_AT_endianity = 0x65 // constant
|
||||||
|
DW_AT_elemental = 0x66 // flag
|
||||||
|
DW_AT_pure = 0x67 // flag
|
||||||
|
DW_AT_recursive = 0x68 // flag
|
||||||
|
|
||||||
|
DW_AT_lo_user = 0x2000 // ---
|
||||||
|
DW_AT_hi_user = 0x3fff // ---
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 21
|
||||||
|
const (
|
||||||
|
DW_FORM_addr = 0x01 // address
|
||||||
|
DW_FORM_block2 = 0x03 // block
|
||||||
|
DW_FORM_block4 = 0x04 // block
|
||||||
|
DW_FORM_data2 = 0x05 // constant
|
||||||
|
DW_FORM_data4 = 0x06 // constant, lineptr, loclistptr, macptr, rangelistptr
|
||||||
|
DW_FORM_data8 = 0x07 // constant, lineptr, loclistptr, macptr, rangelistptr
|
||||||
|
DW_FORM_string = 0x08 // string
|
||||||
|
DW_FORM_block = 0x09 // block
|
||||||
|
DW_FORM_block1 = 0x0a // block
|
||||||
|
DW_FORM_data1 = 0x0b // constant
|
||||||
|
DW_FORM_flag = 0x0c // flag
|
||||||
|
DW_FORM_sdata = 0x0d // constant
|
||||||
|
DW_FORM_strp = 0x0e // string
|
||||||
|
DW_FORM_udata = 0x0f // constant
|
||||||
|
DW_FORM_ref_addr = 0x10 // reference
|
||||||
|
DW_FORM_ref1 = 0x11 // reference
|
||||||
|
DW_FORM_ref2 = 0x12 // reference
|
||||||
|
DW_FORM_ref4 = 0x13 // reference
|
||||||
|
DW_FORM_ref8 = 0x14 // reference
|
||||||
|
DW_FORM_ref_udata = 0x15 // reference
|
||||||
|
DW_FORM_indirect = 0x16 // (see Section 7.5.3)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 24 (#operands, notes)
|
||||||
|
const (
|
||||||
|
DW_OP_addr = 0x03 // 1 constant address (size target specific)
|
||||||
|
DW_OP_deref = 0x06 // 0
|
||||||
|
DW_OP_const1u = 0x08 // 1 1-byte constant
|
||||||
|
DW_OP_const1s = 0x09 // 1 1-byte constant
|
||||||
|
DW_OP_const2u = 0x0a // 1 2-byte constant
|
||||||
|
DW_OP_const2s = 0x0b // 1 2-byte constant
|
||||||
|
DW_OP_const4u = 0x0c // 1 4-byte constant
|
||||||
|
DW_OP_const4s = 0x0d // 1 4-byte constant
|
||||||
|
DW_OP_const8u = 0x0e // 1 8-byte constant
|
||||||
|
DW_OP_const8s = 0x0f // 1 8-byte constant
|
||||||
|
DW_OP_constu = 0x10 // 1 ULEB128 constant
|
||||||
|
DW_OP_consts = 0x11 // 1 SLEB128 constant
|
||||||
|
DW_OP_dup = 0x12 // 0
|
||||||
|
DW_OP_drop = 0x13 // 0
|
||||||
|
DW_OP_over = 0x14 // 0
|
||||||
|
DW_OP_pick = 0x15 // 1 1-byte stack index
|
||||||
|
DW_OP_swap = 0x16 // 0
|
||||||
|
DW_OP_rot = 0x17 // 0
|
||||||
|
DW_OP_xderef = 0x18 // 0
|
||||||
|
DW_OP_abs = 0x19 // 0
|
||||||
|
DW_OP_and = 0x1a // 0
|
||||||
|
DW_OP_div = 0x1b // 0
|
||||||
|
DW_OP_minus = 0x1c // 0
|
||||||
|
DW_OP_mod = 0x1d // 0
|
||||||
|
DW_OP_mul = 0x1e // 0
|
||||||
|
DW_OP_neg = 0x1f // 0
|
||||||
|
DW_OP_not = 0x20 // 0
|
||||||
|
DW_OP_or = 0x21 // 0
|
||||||
|
DW_OP_plus = 0x22 // 0
|
||||||
|
DW_OP_plus_uconst = 0x23 // 1 ULEB128 addend
|
||||||
|
DW_OP_shl = 0x24 // 0
|
||||||
|
DW_OP_shr = 0x25 // 0
|
||||||
|
DW_OP_shra = 0x26 // 0
|
||||||
|
DW_OP_xor = 0x27 // 0
|
||||||
|
DW_OP_skip = 0x2f // 1 signed 2-byte constant
|
||||||
|
DW_OP_bra = 0x28 // 1 signed 2-byte constant
|
||||||
|
DW_OP_eq = 0x29 // 0
|
||||||
|
DW_OP_ge = 0x2a // 0
|
||||||
|
DW_OP_gt = 0x2b // 0
|
||||||
|
DW_OP_le = 0x2c // 0
|
||||||
|
DW_OP_lt = 0x2d // 0
|
||||||
|
DW_OP_ne = 0x2e // 0
|
||||||
|
DW_OP_lit0 = 0x30 // 0 ...
|
||||||
|
DW_OP_lit31 = 0x4f // 0 literals 0..31 = (DW_OP_lit0 + literal)
|
||||||
|
DW_OP_reg0 = 0x50 // 0 ..
|
||||||
|
DW_OP_reg31 = 0x6f // 0 reg 0..31 = (DW_OP_reg0 + regnum)
|
||||||
|
DW_OP_breg0 = 0x70 // 1 ...
|
||||||
|
DW_OP_breg31 = 0x8f // 1 SLEB128 offset base register 0..31 = (DW_OP_breg0 + regnum)
|
||||||
|
DW_OP_regx = 0x90 // 1 ULEB128 register
|
||||||
|
DW_OP_fbreg = 0x91 // 1 SLEB128 offset
|
||||||
|
DW_OP_bregx = 0x92 // 2 ULEB128 register followed by SLEB128 offset
|
||||||
|
DW_OP_piece = 0x93 // 1 ULEB128 size of piece addressed
|
||||||
|
DW_OP_deref_size = 0x94 // 1 1-byte size of data retrieved
|
||||||
|
DW_OP_xderef_size = 0x95 // 1 1-byte size of data retrieved
|
||||||
|
DW_OP_nop = 0x96 // 0
|
||||||
|
DW_OP_push_object_address = 0x97 // 0
|
||||||
|
DW_OP_call2 = 0x98 // 1 2-byte offset of DIE
|
||||||
|
DW_OP_call4 = 0x99 // 1 4-byte offset of DIE
|
||||||
|
DW_OP_call_ref = 0x9a // 1 4- or 8-byte offset of DIE
|
||||||
|
DW_OP_form_tls_address = 0x9b // 0
|
||||||
|
DW_OP_call_frame_cfa = 0x9c // 0
|
||||||
|
DW_OP_bit_piece = 0x9d // 2
|
||||||
|
DW_OP_lo_user = 0xe0
|
||||||
|
DW_OP_hi_user = 0xff
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 25
|
||||||
|
const (
|
||||||
|
DW_ATE_address = 0x01
|
||||||
|
DW_ATE_boolean = 0x02
|
||||||
|
DW_ATE_complex_float = 0x03
|
||||||
|
DW_ATE_float = 0x04
|
||||||
|
DW_ATE_signed = 0x05
|
||||||
|
DW_ATE_signed_char = 0x06
|
||||||
|
DW_ATE_unsigned = 0x07
|
||||||
|
DW_ATE_unsigned_char = 0x08
|
||||||
|
DW_ATE_imaginary_float = 0x09
|
||||||
|
DW_ATE_packed_decimal = 0x0a
|
||||||
|
DW_ATE_numeric_string = 0x0b
|
||||||
|
DW_ATE_edited = 0x0c
|
||||||
|
DW_ATE_signed_fixed = 0x0d
|
||||||
|
DW_ATE_unsigned_fixed = 0x0e
|
||||||
|
DW_ATE_decimal_float = 0x0f
|
||||||
|
DW_ATE_lo_user = 0x80
|
||||||
|
DW_ATE_hi_user = 0xff
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 26
|
||||||
|
const (
|
||||||
|
DW_DS_unsigned = 0x01
|
||||||
|
DW_DS_leading_overpunch = 0x02
|
||||||
|
DW_DS_trailing_overpunch = 0x03
|
||||||
|
DW_DS_leading_separate = 0x04
|
||||||
|
DW_DS_trailing_separate = 0x05
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 27
|
||||||
|
const (
|
||||||
|
DW_END_default = 0x00
|
||||||
|
DW_END_big = 0x01
|
||||||
|
DW_END_little = 0x02
|
||||||
|
DW_END_lo_user = 0x40
|
||||||
|
DW_END_hi_user = 0xff
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 28
|
||||||
|
const (
|
||||||
|
DW_ACCESS_public = 0x01
|
||||||
|
DW_ACCESS_protected = 0x02
|
||||||
|
DW_ACCESS_private = 0x03
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 29
|
||||||
|
const (
|
||||||
|
DW_VIS_local = 0x01
|
||||||
|
DW_VIS_exported = 0x02
|
||||||
|
DW_VIS_qualified = 0x03
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 30
|
||||||
|
const (
|
||||||
|
DW_VIRTUALITY_none = 0x00
|
||||||
|
DW_VIRTUALITY_virtual = 0x01
|
||||||
|
DW_VIRTUALITY_pure_virtual = 0x02
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 31
|
||||||
|
const (
|
||||||
|
DW_LANG_C89 = 0x0001
|
||||||
|
DW_LANG_C = 0x0002
|
||||||
|
DW_LANG_Ada83 = 0x0003
|
||||||
|
DW_LANG_C_plus_plus = 0x0004
|
||||||
|
DW_LANG_Cobol74 = 0x0005
|
||||||
|
DW_LANG_Cobol85 = 0x0006
|
||||||
|
DW_LANG_Fortran77 = 0x0007
|
||||||
|
DW_LANG_Fortran90 = 0x0008
|
||||||
|
DW_LANG_Pascal83 = 0x0009
|
||||||
|
DW_LANG_Modula2 = 0x000a
|
||||||
|
// Dwarf3
|
||||||
|
DW_LANG_Java = 0x000b
|
||||||
|
DW_LANG_C99 = 0x000c
|
||||||
|
DW_LANG_Ada95 = 0x000d
|
||||||
|
DW_LANG_Fortran95 = 0x000e
|
||||||
|
DW_LANG_PLI = 0x000f
|
||||||
|
DW_LANG_ObjC = 0x0010
|
||||||
|
DW_LANG_ObjC_plus_plus = 0x0011
|
||||||
|
DW_LANG_UPC = 0x0012
|
||||||
|
DW_LANG_D = 0x0013
|
||||||
|
// Dwarf4
|
||||||
|
DW_LANG_Python = 0x0014
|
||||||
|
// Dwarf5
|
||||||
|
DW_LANG_Go = 0x0016
|
||||||
|
|
||||||
|
DW_LANG_lo_user = 0x8000
|
||||||
|
DW_LANG_hi_user = 0xffff
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 32
|
||||||
|
const (
|
||||||
|
DW_ID_case_sensitive = 0x00
|
||||||
|
DW_ID_up_case = 0x01
|
||||||
|
DW_ID_down_case = 0x02
|
||||||
|
DW_ID_case_insensitive = 0x03
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 33
|
||||||
|
const (
|
||||||
|
DW_CC_normal = 0x01
|
||||||
|
DW_CC_program = 0x02
|
||||||
|
DW_CC_nocall = 0x03
|
||||||
|
DW_CC_lo_user = 0x40
|
||||||
|
DW_CC_hi_user = 0xff
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 34
|
||||||
|
const (
|
||||||
|
DW_INL_not_inlined = 0x00
|
||||||
|
DW_INL_inlined = 0x01
|
||||||
|
DW_INL_declared_not_inlined = 0x02
|
||||||
|
DW_INL_declared_inlined = 0x03
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 35
|
||||||
|
const (
|
||||||
|
DW_ORD_row_major = 0x00
|
||||||
|
DW_ORD_col_major = 0x01
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 36
|
||||||
|
const (
|
||||||
|
DW_DSC_label = 0x00
|
||||||
|
DW_DSC_range = 0x01
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 37
|
||||||
|
const (
|
||||||
|
DW_LNS_copy = 0x01
|
||||||
|
DW_LNS_advance_pc = 0x02
|
||||||
|
DW_LNS_advance_line = 0x03
|
||||||
|
DW_LNS_set_file = 0x04
|
||||||
|
DW_LNS_set_column = 0x05
|
||||||
|
DW_LNS_negate_stmt = 0x06
|
||||||
|
DW_LNS_set_basic_block = 0x07
|
||||||
|
DW_LNS_const_add_pc = 0x08
|
||||||
|
DW_LNS_fixed_advance_pc = 0x09
|
||||||
|
// Dwarf3
|
||||||
|
DW_LNS_set_prologue_end = 0x0a
|
||||||
|
DW_LNS_set_epilogue_begin = 0x0b
|
||||||
|
DW_LNS_set_isa = 0x0c
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 38
|
||||||
|
const (
|
||||||
|
DW_LNE_end_sequence = 0x01
|
||||||
|
DW_LNE_set_address = 0x02
|
||||||
|
DW_LNE_define_file = 0x03
|
||||||
|
DW_LNE_lo_user = 0x80
|
||||||
|
DW_LNE_hi_user = 0xff
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 39
|
||||||
|
const (
|
||||||
|
DW_MACINFO_define = 0x01
|
||||||
|
DW_MACINFO_undef = 0x02
|
||||||
|
DW_MACINFO_start_file = 0x03
|
||||||
|
DW_MACINFO_end_file = 0x04
|
||||||
|
DW_MACINFO_vendor_ext = 0xff
|
||||||
|
)
|
||||||
|
|
||||||
|
// Table 40.
|
||||||
|
const (
|
||||||
|
// operand,...
|
||||||
|
DW_CFA_nop = 0x00
|
||||||
|
DW_CFA_set_loc = 0x01 // address
|
||||||
|
DW_CFA_advance_loc1 = 0x02 // 1-byte delta
|
||||||
|
DW_CFA_advance_loc2 = 0x03 // 2-byte delta
|
||||||
|
DW_CFA_advance_loc4 = 0x04 // 4-byte delta
|
||||||
|
DW_CFA_offset_extended = 0x05 // ULEB128 register, ULEB128 offset
|
||||||
|
DW_CFA_restore_extended = 0x06 // ULEB128 register
|
||||||
|
DW_CFA_undefined = 0x07 // ULEB128 register
|
||||||
|
DW_CFA_same_value = 0x08 // ULEB128 register
|
||||||
|
DW_CFA_register = 0x09 // ULEB128 register, ULEB128 register
|
||||||
|
DW_CFA_remember_state = 0x0a
|
||||||
|
DW_CFA_restore_state = 0x0b
|
||||||
|
|
||||||
|
DW_CFA_def_cfa = 0x0c // ULEB128 register, ULEB128 offset
|
||||||
|
DW_CFA_def_cfa_register = 0x0d // ULEB128 register
|
||||||
|
DW_CFA_def_cfa_offset = 0x0e // ULEB128 offset
|
||||||
|
DW_CFA_def_cfa_expression = 0x0f // BLOCK
|
||||||
|
DW_CFA_expression = 0x10 // ULEB128 register, BLOCK
|
||||||
|
DW_CFA_offset_extended_sf = 0x11 // ULEB128 register, SLEB128 offset
|
||||||
|
DW_CFA_def_cfa_sf = 0x12 // ULEB128 register, SLEB128 offset
|
||||||
|
DW_CFA_def_cfa_offset_sf = 0x13 // SLEB128 offset
|
||||||
|
DW_CFA_val_offset = 0x14 // ULEB128, ULEB128
|
||||||
|
DW_CFA_val_offset_sf = 0x15 // ULEB128, SLEB128
|
||||||
|
DW_CFA_val_expression = 0x16 // ULEB128, BLOCK
|
||||||
|
|
||||||
|
DW_CFA_lo_user = 0x1c
|
||||||
|
DW_CFA_hi_user = 0x3f
|
||||||
|
|
||||||
|
// Opcodes that take an addend operand.
|
||||||
|
DW_CFA_advance_loc = 0x1 << 6 // +delta
|
||||||
|
DW_CFA_offset = 0x2 << 6 // +register (ULEB128 offset)
|
||||||
|
DW_CFA_restore = 0x3 << 6 // +register
|
||||||
|
)
|
714
vendor/github.com/google/gops/internal/goobj/read.go
generated
vendored
Normal file
714
vendor/github.com/google/gops/internal/goobj/read.go
generated
vendored
Normal file
@ -0,0 +1,714 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package goobj implements reading of Go object files and archives.
|
||||||
|
//
|
||||||
|
// TODO(rsc): Decide where this package should live. (golang.org/issue/6932)
|
||||||
|
// TODO(rsc): Decide the appropriate integer types for various fields.
|
||||||
|
// TODO(rsc): Write tests. (File format still up in the air a little.)
|
||||||
|
package goobj
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/gops/internal/obj"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A SymKind describes the kind of memory represented by a symbol.
|
||||||
|
type SymKind int
|
||||||
|
|
||||||
|
// This list is taken from include/link.h.
|
||||||
|
|
||||||
|
// Defined SymKind values.
|
||||||
|
// TODO(rsc): Give idiomatic Go names.
|
||||||
|
// TODO(rsc): Reduce the number of symbol types in the object files.
|
||||||
|
const (
|
||||||
|
// readonly, executable
|
||||||
|
STEXT = SymKind(obj.STEXT)
|
||||||
|
SELFRXSECT = SymKind(obj.SELFRXSECT)
|
||||||
|
|
||||||
|
// readonly, non-executable
|
||||||
|
STYPE = SymKind(obj.STYPE)
|
||||||
|
SSTRING = SymKind(obj.SSTRING)
|
||||||
|
SGOSTRING = SymKind(obj.SGOSTRING)
|
||||||
|
SGOFUNC = SymKind(obj.SGOFUNC)
|
||||||
|
SRODATA = SymKind(obj.SRODATA)
|
||||||
|
SFUNCTAB = SymKind(obj.SFUNCTAB)
|
||||||
|
STYPELINK = SymKind(obj.STYPELINK)
|
||||||
|
SITABLINK = SymKind(obj.SITABLINK)
|
||||||
|
SSYMTAB = SymKind(obj.SSYMTAB) // TODO: move to unmapped section
|
||||||
|
SPCLNTAB = SymKind(obj.SPCLNTAB)
|
||||||
|
SELFROSECT = SymKind(obj.SELFROSECT)
|
||||||
|
|
||||||
|
// writable, non-executable
|
||||||
|
SMACHOPLT = SymKind(obj.SMACHOPLT)
|
||||||
|
SELFSECT = SymKind(obj.SELFSECT)
|
||||||
|
SMACHO = SymKind(obj.SMACHO) // Mach-O __nl_symbol_ptr
|
||||||
|
SMACHOGOT = SymKind(obj.SMACHOGOT)
|
||||||
|
SWINDOWS = SymKind(obj.SWINDOWS)
|
||||||
|
SELFGOT = SymKind(obj.SELFGOT)
|
||||||
|
SNOPTRDATA = SymKind(obj.SNOPTRDATA)
|
||||||
|
SINITARR = SymKind(obj.SINITARR)
|
||||||
|
SDATA = SymKind(obj.SDATA)
|
||||||
|
SBSS = SymKind(obj.SBSS)
|
||||||
|
SNOPTRBSS = SymKind(obj.SNOPTRBSS)
|
||||||
|
STLSBSS = SymKind(obj.STLSBSS)
|
||||||
|
|
||||||
|
// not mapped
|
||||||
|
SXREF = SymKind(obj.SXREF)
|
||||||
|
SMACHOSYMSTR = SymKind(obj.SMACHOSYMSTR)
|
||||||
|
SMACHOSYMTAB = SymKind(obj.SMACHOSYMTAB)
|
||||||
|
SMACHOINDIRECTPLT = SymKind(obj.SMACHOINDIRECTPLT)
|
||||||
|
SMACHOINDIRECTGOT = SymKind(obj.SMACHOINDIRECTGOT)
|
||||||
|
SFILE = SymKind(obj.SFILE)
|
||||||
|
SFILEPATH = SymKind(obj.SFILEPATH)
|
||||||
|
SCONST = SymKind(obj.SCONST)
|
||||||
|
SDYNIMPORT = SymKind(obj.SDYNIMPORT)
|
||||||
|
SHOSTOBJ = SymKind(obj.SHOSTOBJ)
|
||||||
|
)
|
||||||
|
|
||||||
|
var symKindStrings = []string{
|
||||||
|
SBSS: "SBSS",
|
||||||
|
SCONST: "SCONST",
|
||||||
|
SDATA: "SDATA",
|
||||||
|
SDYNIMPORT: "SDYNIMPORT",
|
||||||
|
SELFROSECT: "SELFROSECT",
|
||||||
|
SELFRXSECT: "SELFRXSECT",
|
||||||
|
SELFSECT: "SELFSECT",
|
||||||
|
SFILE: "SFILE",
|
||||||
|
SFILEPATH: "SFILEPATH",
|
||||||
|
SFUNCTAB: "SFUNCTAB",
|
||||||
|
SGOFUNC: "SGOFUNC",
|
||||||
|
SGOSTRING: "SGOSTRING",
|
||||||
|
SHOSTOBJ: "SHOSTOBJ",
|
||||||
|
SINITARR: "SINITARR",
|
||||||
|
SMACHO: "SMACHO",
|
||||||
|
SMACHOGOT: "SMACHOGOT",
|
||||||
|
SMACHOINDIRECTGOT: "SMACHOINDIRECTGOT",
|
||||||
|
SMACHOINDIRECTPLT: "SMACHOINDIRECTPLT",
|
||||||
|
SMACHOPLT: "SMACHOPLT",
|
||||||
|
SMACHOSYMSTR: "SMACHOSYMSTR",
|
||||||
|
SMACHOSYMTAB: "SMACHOSYMTAB",
|
||||||
|
SNOPTRBSS: "SNOPTRBSS",
|
||||||
|
SNOPTRDATA: "SNOPTRDATA",
|
||||||
|
SPCLNTAB: "SPCLNTAB",
|
||||||
|
SRODATA: "SRODATA",
|
||||||
|
SSTRING: "SSTRING",
|
||||||
|
SSYMTAB: "SSYMTAB",
|
||||||
|
STEXT: "STEXT",
|
||||||
|
STLSBSS: "STLSBSS",
|
||||||
|
STYPE: "STYPE",
|
||||||
|
STYPELINK: "STYPELINK",
|
||||||
|
SITABLINK: "SITABLINK",
|
||||||
|
SWINDOWS: "SWINDOWS",
|
||||||
|
SXREF: "SXREF",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k SymKind) String() string {
|
||||||
|
if k < 0 || int(k) >= len(symKindStrings) {
|
||||||
|
return fmt.Sprintf("SymKind(%d)", k)
|
||||||
|
}
|
||||||
|
return symKindStrings[k]
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Sym is a named symbol in an object file.
|
||||||
|
type Sym struct {
|
||||||
|
SymID // symbol identifier (name and version)
|
||||||
|
Kind SymKind // kind of symbol
|
||||||
|
DupOK bool // are duplicate definitions okay?
|
||||||
|
Size int // size of corresponding data
|
||||||
|
Type SymID // symbol for Go type information
|
||||||
|
Data Data // memory image of symbol
|
||||||
|
Reloc []Reloc // relocations to apply to Data
|
||||||
|
Func *Func // additional data for functions
|
||||||
|
}
|
||||||
|
|
||||||
|
// A SymID - the combination of Name and Version - uniquely identifies
|
||||||
|
// a symbol within a package.
|
||||||
|
type SymID struct {
|
||||||
|
// Name is the name of a symbol.
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// Version is zero for symbols with global visibility.
|
||||||
|
// Symbols with only file visibility (such as file-level static
|
||||||
|
// declarations in C) have a non-zero version distinguishing
|
||||||
|
// a symbol in one file from a symbol of the same name
|
||||||
|
// in another file
|
||||||
|
Version int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SymID) String() string {
|
||||||
|
if s.Version == 0 {
|
||||||
|
return s.Name
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s<%d>", s.Name, s.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Data is a reference to data stored in an object file.
|
||||||
|
// It records the offset and size of the data, so that a client can
|
||||||
|
// read the data only if necessary.
|
||||||
|
type Data struct {
|
||||||
|
Offset int64
|
||||||
|
Size int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Reloc describes a relocation applied to a memory image to refer
|
||||||
|
// to an address within a particular symbol.
|
||||||
|
type Reloc struct {
|
||||||
|
// The bytes at [Offset, Offset+Size) within the containing Sym
|
||||||
|
// should be updated to refer to the address Add bytes after the start
|
||||||
|
// of the symbol Sym.
|
||||||
|
Offset int
|
||||||
|
Size int
|
||||||
|
Sym SymID
|
||||||
|
Add int
|
||||||
|
|
||||||
|
// The Type records the form of address expected in the bytes
|
||||||
|
// described by the previous fields: absolute, PC-relative, and so on.
|
||||||
|
// TODO(rsc): The interpretation of Type is not exposed by this package.
|
||||||
|
Type obj.RelocType
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Var describes a variable in a function stack frame: a declared
|
||||||
|
// local variable, an input argument, or an output result.
|
||||||
|
type Var struct {
|
||||||
|
// The combination of Name, Kind, and Offset uniquely
|
||||||
|
// identifies a variable in a function stack frame.
|
||||||
|
// Using fewer of these - in particular, using only Name - does not.
|
||||||
|
Name string // Name of variable.
|
||||||
|
Kind int // TODO(rsc): Define meaning.
|
||||||
|
Offset int // Frame offset. TODO(rsc): Define meaning.
|
||||||
|
|
||||||
|
Type SymID // Go type for variable.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Func contains additional per-symbol information specific to functions.
|
||||||
|
type Func struct {
|
||||||
|
Args int // size in bytes of argument frame: inputs and outputs
|
||||||
|
Frame int // size in bytes of local variable frame
|
||||||
|
Leaf bool // function omits save of link register (ARM)
|
||||||
|
NoSplit bool // function omits stack split prologue
|
||||||
|
Var []Var // detail about local variables
|
||||||
|
PCSP Data // PC → SP offset map
|
||||||
|
PCFile Data // PC → file number map (index into File)
|
||||||
|
PCLine Data // PC → line number map
|
||||||
|
PCData []Data // PC → runtime support data map
|
||||||
|
FuncData []FuncData // non-PC-specific runtime support data
|
||||||
|
File []string // paths indexed by PCFile
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add PCData []byte and PCDataIter (similar to liblink).
|
||||||
|
|
||||||
|
// A FuncData is a single function-specific data value.
|
||||||
|
type FuncData struct {
|
||||||
|
Sym SymID // symbol holding data
|
||||||
|
Offset int64 // offset into symbol for funcdata pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Package is a parsed Go object file or archive defining a Go package.
|
||||||
|
type Package struct {
|
||||||
|
ImportPath string // import path denoting this package
|
||||||
|
Imports []string // packages imported by this package
|
||||||
|
SymRefs []SymID // list of symbol names and versions referred to by this pack
|
||||||
|
Syms []*Sym // symbols defined by this package
|
||||||
|
MaxVersion int // maximum Version in any SymID in Syms
|
||||||
|
Arch string // architecture
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
archiveHeader = []byte("!<arch>\n")
|
||||||
|
archiveMagic = []byte("`\n")
|
||||||
|
goobjHeader = []byte("go objec") // truncated to size of archiveHeader
|
||||||
|
|
||||||
|
errCorruptArchive = errors.New("corrupt archive")
|
||||||
|
errTruncatedArchive = errors.New("truncated archive")
|
||||||
|
errCorruptObject = errors.New("corrupt object file")
|
||||||
|
errNotObject = errors.New("unrecognized object file format")
|
||||||
|
)
|
||||||
|
|
||||||
|
// An objReader is an object file reader.
|
||||||
|
type objReader struct {
|
||||||
|
p *Package
|
||||||
|
b *bufio.Reader
|
||||||
|
f io.ReadSeeker
|
||||||
|
err error
|
||||||
|
offset int64
|
||||||
|
dataOffset int64
|
||||||
|
limit int64
|
||||||
|
tmp [256]byte
|
||||||
|
pkgprefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
// importPathToPrefix returns the prefix that will be used in the
|
||||||
|
// final symbol table for the given import path.
|
||||||
|
// We escape '%', '"', all control characters and non-ASCII bytes,
|
||||||
|
// and any '.' after the final slash.
|
||||||
|
//
|
||||||
|
// See ../../../cmd/ld/lib.c:/^pathtoprefix and
|
||||||
|
// ../../../cmd/gc/subr.c:/^pathtoprefix.
|
||||||
|
func importPathToPrefix(s string) string {
|
||||||
|
// find index of last slash, if any, or else -1.
|
||||||
|
// used for determining whether an index is after the last slash.
|
||||||
|
slash := strings.LastIndex(s, "/")
|
||||||
|
|
||||||
|
// check for chars that need escaping
|
||||||
|
n := 0
|
||||||
|
for r := 0; r < len(s); r++ {
|
||||||
|
if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// quick exit
|
||||||
|
if n == 0 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// escape
|
||||||
|
const hex = "0123456789abcdef"
|
||||||
|
p := make([]byte, 0, len(s)+2*n)
|
||||||
|
for r := 0; r < len(s); r++ {
|
||||||
|
if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
|
||||||
|
p = append(p, '%', hex[c>>4], hex[c&0xF])
|
||||||
|
} else {
|
||||||
|
p = append(p, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// init initializes r to read package p from f.
|
||||||
|
func (r *objReader) init(f io.ReadSeeker, p *Package) {
|
||||||
|
r.f = f
|
||||||
|
r.p = p
|
||||||
|
r.offset, _ = f.Seek(0, io.SeekCurrent)
|
||||||
|
r.limit, _ = f.Seek(0, io.SeekEnd)
|
||||||
|
f.Seek(r.offset, io.SeekStart)
|
||||||
|
r.b = bufio.NewReader(f)
|
||||||
|
r.pkgprefix = importPathToPrefix(p.ImportPath) + "."
|
||||||
|
}
|
||||||
|
|
||||||
|
// error records that an error occurred.
|
||||||
|
// It returns only the first error, so that an error
|
||||||
|
// caused by an earlier error does not discard information
|
||||||
|
// about the earlier error.
|
||||||
|
func (r *objReader) error(err error) error {
|
||||||
|
if r.err == nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
err = io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
r.err = err
|
||||||
|
}
|
||||||
|
// panic("corrupt") // useful for debugging
|
||||||
|
return r.err
|
||||||
|
}
|
||||||
|
|
||||||
|
// readByte reads and returns a byte from the input file.
|
||||||
|
// On I/O error or EOF, it records the error but returns byte 0.
|
||||||
|
// A sequence of 0 bytes will eventually terminate any
|
||||||
|
// parsing state in the object file. In particular, it ends the
|
||||||
|
// reading of a varint.
|
||||||
|
func (r *objReader) readByte() byte {
|
||||||
|
if r.err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if r.offset >= r.limit {
|
||||||
|
r.error(io.ErrUnexpectedEOF)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
b, err := r.b.ReadByte()
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
err = io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
r.error(err)
|
||||||
|
b = 0
|
||||||
|
} else {
|
||||||
|
r.offset++
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// read reads exactly len(b) bytes from the input file.
|
||||||
|
// If an error occurs, read returns the error but also
|
||||||
|
// records it, so it is safe for callers to ignore the result
|
||||||
|
// as long as delaying the report is not a problem.
|
||||||
|
func (r *objReader) readFull(b []byte) error {
|
||||||
|
if r.err != nil {
|
||||||
|
return r.err
|
||||||
|
}
|
||||||
|
if r.offset+int64(len(b)) > r.limit {
|
||||||
|
return r.error(io.ErrUnexpectedEOF)
|
||||||
|
}
|
||||||
|
n, err := io.ReadFull(r.b, b)
|
||||||
|
r.offset += int64(n)
|
||||||
|
if err != nil {
|
||||||
|
return r.error(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// readInt reads a zigzag varint from the input file.
|
||||||
|
func (r *objReader) readInt() int {
|
||||||
|
var u uint64
|
||||||
|
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
r.error(errCorruptObject)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
c := r.readByte()
|
||||||
|
u |= uint64(c&0x7F) << shift
|
||||||
|
if c&0x80 == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v := int64(u>>1) ^ (int64(u) << 63 >> 63)
|
||||||
|
if int64(int(v)) != v {
|
||||||
|
r.error(errCorruptObject) // TODO
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return int(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// readString reads a length-delimited string from the input file.
|
||||||
|
func (r *objReader) readString() string {
|
||||||
|
n := r.readInt()
|
||||||
|
buf := make([]byte, n)
|
||||||
|
r.readFull(buf)
|
||||||
|
return string(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// readSymID reads a SymID from the input file.
|
||||||
|
func (r *objReader) readSymID() SymID {
|
||||||
|
i := r.readInt()
|
||||||
|
return r.p.SymRefs[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *objReader) readRef() {
|
||||||
|
name, vers := r.readString(), r.readInt()
|
||||||
|
|
||||||
|
// In a symbol name in an object file, "". denotes the
|
||||||
|
// prefix for the package in which the object file has been found.
|
||||||
|
// Expand it.
|
||||||
|
name = strings.Replace(name, `"".`, r.pkgprefix, -1)
|
||||||
|
|
||||||
|
// An individual object file only records version 0 (extern) or 1 (static).
|
||||||
|
// To make static symbols unique across all files being read, we
|
||||||
|
// replace version 1 with the version corresponding to the current
|
||||||
|
// file number. The number is incremented on each call to parseObject.
|
||||||
|
if vers != 0 {
|
||||||
|
vers = r.p.MaxVersion
|
||||||
|
}
|
||||||
|
r.p.SymRefs = append(r.p.SymRefs, SymID{name, vers})
|
||||||
|
}
|
||||||
|
|
||||||
|
// readData reads a data reference from the input file.
|
||||||
|
func (r *objReader) readData() Data {
|
||||||
|
n := r.readInt()
|
||||||
|
d := Data{Offset: r.dataOffset, Size: int64(n)}
|
||||||
|
r.dataOffset += int64(n)
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip skips n bytes in the input.
|
||||||
|
func (r *objReader) skip(n int64) {
|
||||||
|
if n < 0 {
|
||||||
|
r.error(fmt.Errorf("debug/goobj: internal error: misuse of skip"))
|
||||||
|
}
|
||||||
|
if n < int64(len(r.tmp)) {
|
||||||
|
// Since the data is so small, a just reading from the buffered
|
||||||
|
// reader is better than flushing the buffer and seeking.
|
||||||
|
r.readFull(r.tmp[:n])
|
||||||
|
} else if n <= int64(r.b.Buffered()) {
|
||||||
|
// Even though the data is not small, it has already been read.
|
||||||
|
// Advance the buffer instead of seeking.
|
||||||
|
for n > int64(len(r.tmp)) {
|
||||||
|
r.readFull(r.tmp[:])
|
||||||
|
n -= int64(len(r.tmp))
|
||||||
|
}
|
||||||
|
r.readFull(r.tmp[:n])
|
||||||
|
} else {
|
||||||
|
// Seek, giving up buffered data.
|
||||||
|
_, err := r.f.Seek(r.offset+n, io.SeekStart)
|
||||||
|
if err != nil {
|
||||||
|
r.error(err)
|
||||||
|
}
|
||||||
|
r.offset += n
|
||||||
|
r.b.Reset(r.f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse parses an object file or archive from r,
|
||||||
|
// assuming that its import path is pkgpath.
|
||||||
|
func Parse(r io.ReadSeeker, pkgpath string) (*Package, error) {
|
||||||
|
if pkgpath == "" {
|
||||||
|
pkgpath = `""`
|
||||||
|
}
|
||||||
|
p := new(Package)
|
||||||
|
p.ImportPath = pkgpath
|
||||||
|
|
||||||
|
var rd objReader
|
||||||
|
rd.init(r, p)
|
||||||
|
err := rd.readFull(rd.tmp[:8])
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
err = io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
default:
|
||||||
|
return nil, errNotObject
|
||||||
|
|
||||||
|
case bytes.Equal(rd.tmp[:8], archiveHeader):
|
||||||
|
if err := rd.parseArchive(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
case bytes.Equal(rd.tmp[:8], goobjHeader):
|
||||||
|
if err := rd.parseObject(goobjHeader); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// trimSpace removes trailing spaces from b and returns the corresponding string.
|
||||||
|
// This effectively parses the form used in archive headers.
|
||||||
|
func trimSpace(b []byte) string {
|
||||||
|
return string(bytes.TrimRight(b, " "))
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseArchive parses a Unix archive of Go object files.
|
||||||
|
// TODO(rsc): Need to skip non-Go object files.
|
||||||
|
// TODO(rsc): Maybe record table of contents in r.p so that
|
||||||
|
// linker can avoid having code to parse archives too.
|
||||||
|
func (r *objReader) parseArchive() error {
|
||||||
|
for r.offset < r.limit {
|
||||||
|
if err := r.readFull(r.tmp[:60]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data := r.tmp[:60]
|
||||||
|
|
||||||
|
// Each file is preceded by this text header (slice indices in first column):
|
||||||
|
// 0:16 name
|
||||||
|
// 16:28 date
|
||||||
|
// 28:34 uid
|
||||||
|
// 34:40 gid
|
||||||
|
// 40:48 mode
|
||||||
|
// 48:58 size
|
||||||
|
// 58:60 magic - `\n
|
||||||
|
// We only care about name, size, and magic.
|
||||||
|
// The fields are space-padded on the right.
|
||||||
|
// The size is in decimal.
|
||||||
|
// The file data - size bytes - follows the header.
|
||||||
|
// Headers are 2-byte aligned, so if size is odd, an extra padding
|
||||||
|
// byte sits between the file data and the next header.
|
||||||
|
// The file data that follows is padded to an even number of bytes:
|
||||||
|
// if size is odd, an extra padding byte is inserted betw the next header.
|
||||||
|
if len(data) < 60 {
|
||||||
|
return errTruncatedArchive
|
||||||
|
}
|
||||||
|
if !bytes.Equal(data[58:60], archiveMagic) {
|
||||||
|
return errCorruptArchive
|
||||||
|
}
|
||||||
|
name := trimSpace(data[0:16])
|
||||||
|
size, err := strconv.ParseInt(trimSpace(data[48:58]), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return errCorruptArchive
|
||||||
|
}
|
||||||
|
data = data[60:]
|
||||||
|
fsize := size + size&1
|
||||||
|
if fsize < 0 || fsize < size {
|
||||||
|
return errCorruptArchive
|
||||||
|
}
|
||||||
|
switch name {
|
||||||
|
case "__.PKGDEF":
|
||||||
|
r.skip(size)
|
||||||
|
default:
|
||||||
|
oldLimit := r.limit
|
||||||
|
r.limit = r.offset + size
|
||||||
|
if err := r.parseObject(nil); err != nil {
|
||||||
|
return fmt.Errorf("parsing archive member %q: %v", name, err)
|
||||||
|
}
|
||||||
|
r.skip(r.limit - r.offset)
|
||||||
|
r.limit = oldLimit
|
||||||
|
}
|
||||||
|
if size&1 != 0 {
|
||||||
|
r.skip(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseObject parses a single Go object file.
|
||||||
|
// The prefix is the bytes already read from the file,
|
||||||
|
// typically in order to detect that this is an object file.
|
||||||
|
// The object file consists of a textual header ending in "\n!\n"
|
||||||
|
// and then the part we want to parse begins.
|
||||||
|
// The format of that part is defined in a comment at the top
|
||||||
|
// of src/liblink/objfile.c.
|
||||||
|
func (r *objReader) parseObject(prefix []byte) error {
|
||||||
|
r.p.MaxVersion++
|
||||||
|
h := make([]byte, 0, 256)
|
||||||
|
h = append(h, prefix...)
|
||||||
|
var c1, c2, c3 byte
|
||||||
|
for {
|
||||||
|
c1, c2, c3 = c2, c3, r.readByte()
|
||||||
|
h = append(h, c3)
|
||||||
|
// The new export format can contain 0 bytes.
|
||||||
|
// Don't consider them errors, only look for r.err != nil.
|
||||||
|
if r.err != nil {
|
||||||
|
return errCorruptObject
|
||||||
|
}
|
||||||
|
if c1 == '\n' && c2 == '!' && c3 == '\n' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hs := strings.Fields(string(h))
|
||||||
|
if len(hs) >= 4 {
|
||||||
|
r.p.Arch = hs[3]
|
||||||
|
}
|
||||||
|
// TODO: extract OS + build ID if/when we need it
|
||||||
|
|
||||||
|
r.readFull(r.tmp[:8])
|
||||||
|
if !bytes.Equal(r.tmp[:8], []byte("\x00\x00go17ld")) {
|
||||||
|
return r.error(errCorruptObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
b := r.readByte()
|
||||||
|
if b != 1 {
|
||||||
|
return r.error(errCorruptObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Direct package dependencies.
|
||||||
|
for {
|
||||||
|
s := r.readString()
|
||||||
|
if s == "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
r.p.Imports = append(r.p.Imports, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
r.p.SymRefs = []SymID{{"", 0}}
|
||||||
|
for {
|
||||||
|
if b := r.readByte(); b != 0xfe {
|
||||||
|
if b != 0xff {
|
||||||
|
return r.error(errCorruptObject)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
r.readRef()
|
||||||
|
}
|
||||||
|
|
||||||
|
dataLength := r.readInt()
|
||||||
|
r.readInt() // n relocations - ignore
|
||||||
|
r.readInt() // n pcdata - ignore
|
||||||
|
r.readInt() // n autom - ignore
|
||||||
|
r.readInt() // n funcdata - ignore
|
||||||
|
r.readInt() // n files - ignore
|
||||||
|
|
||||||
|
r.dataOffset = r.offset
|
||||||
|
r.skip(int64(dataLength))
|
||||||
|
|
||||||
|
// Symbols.
|
||||||
|
for {
|
||||||
|
if b := r.readByte(); b != 0xfe {
|
||||||
|
if b != 0xff {
|
||||||
|
return r.error(errCorruptObject)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
typ := r.readInt()
|
||||||
|
s := &Sym{SymID: r.readSymID()}
|
||||||
|
r.p.Syms = append(r.p.Syms, s)
|
||||||
|
s.Kind = SymKind(typ)
|
||||||
|
flags := r.readInt()
|
||||||
|
s.DupOK = flags&1 != 0
|
||||||
|
s.Size = r.readInt()
|
||||||
|
s.Type = r.readSymID()
|
||||||
|
s.Data = r.readData()
|
||||||
|
s.Reloc = make([]Reloc, r.readInt())
|
||||||
|
for i := range s.Reloc {
|
||||||
|
rel := &s.Reloc[i]
|
||||||
|
rel.Offset = r.readInt()
|
||||||
|
rel.Size = r.readInt()
|
||||||
|
rel.Type = obj.RelocType(r.readInt())
|
||||||
|
rel.Add = r.readInt()
|
||||||
|
rel.Sym = r.readSymID()
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Kind == STEXT {
|
||||||
|
f := new(Func)
|
||||||
|
s.Func = f
|
||||||
|
f.Args = r.readInt()
|
||||||
|
f.Frame = r.readInt()
|
||||||
|
flags := r.readInt()
|
||||||
|
f.Leaf = flags&1 != 0
|
||||||
|
f.NoSplit = r.readInt() != 0
|
||||||
|
f.Var = make([]Var, r.readInt())
|
||||||
|
for i := range f.Var {
|
||||||
|
v := &f.Var[i]
|
||||||
|
v.Name = r.readSymID().Name
|
||||||
|
v.Offset = r.readInt()
|
||||||
|
v.Kind = r.readInt()
|
||||||
|
v.Type = r.readSymID()
|
||||||
|
}
|
||||||
|
|
||||||
|
f.PCSP = r.readData()
|
||||||
|
f.PCFile = r.readData()
|
||||||
|
f.PCLine = r.readData()
|
||||||
|
f.PCData = make([]Data, r.readInt())
|
||||||
|
for i := range f.PCData {
|
||||||
|
f.PCData[i] = r.readData()
|
||||||
|
}
|
||||||
|
f.FuncData = make([]FuncData, r.readInt())
|
||||||
|
for i := range f.FuncData {
|
||||||
|
f.FuncData[i].Sym = r.readSymID()
|
||||||
|
}
|
||||||
|
for i := range f.FuncData {
|
||||||
|
f.FuncData[i].Offset = int64(r.readInt()) // TODO
|
||||||
|
}
|
||||||
|
f.File = make([]string, r.readInt())
|
||||||
|
for i := range f.File {
|
||||||
|
f.File[i] = r.readSymID().Name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r.readFull(r.tmp[:7])
|
||||||
|
if !bytes.Equal(r.tmp[:7], []byte("\xffgo17ld")) {
|
||||||
|
return r.error(errCorruptObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reloc) String(insnOffset uint64) string {
|
||||||
|
delta := r.Offset - int(insnOffset)
|
||||||
|
s := fmt.Sprintf("[%d:%d]%s", delta, delta+r.Size, r.Type)
|
||||||
|
if r.Sym.Name != "" {
|
||||||
|
if r.Add != 0 {
|
||||||
|
return fmt.Sprintf("%s:%s+%d", s, r.Sym.Name, r.Add)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s:%s", s, r.Sym.Name)
|
||||||
|
}
|
||||||
|
if r.Add != 0 {
|
||||||
|
return fmt.Sprintf("%s:%d", s, r.Add)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
52
vendor/github.com/google/gops/internal/internal.go
generated
vendored
Normal file
52
vendor/github.com/google/gops/internal/internal.go
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ConfigDir() (string, error) {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
return filepath.Join(os.Getenv("APPDATA"), "gops"), nil
|
||||||
|
}
|
||||||
|
homeDir := guessUnixHomeDir()
|
||||||
|
if homeDir == "" {
|
||||||
|
return "", errors.New("unable to get current user home directory: os/user lookup failed; $HOME is empty")
|
||||||
|
}
|
||||||
|
return filepath.Join(homeDir, ".config", "gops"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func guessUnixHomeDir() string {
|
||||||
|
usr, err := user.Current()
|
||||||
|
if err == nil {
|
||||||
|
return usr.HomeDir
|
||||||
|
}
|
||||||
|
return os.Getenv("HOME")
|
||||||
|
}
|
||||||
|
|
||||||
|
func PIDFile(pid int) (string, error) {
|
||||||
|
gopsdir, err := ConfigDir()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s/%d", gopsdir, pid), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPort(pid int) (string, error) {
|
||||||
|
portfile, err := PIDFile(pid)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
b, err := ioutil.ReadFile(portfile)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
port := strings.TrimSpace(string(b))
|
||||||
|
return port, nil
|
||||||
|
}
|
27
vendor/github.com/google/gops/internal/obj/addrtype_string.go
generated
vendored
Normal file
27
vendor/github.com/google/gops/internal/obj/addrtype_string.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Code generated by "stringer -type AddrType cmd/internal/obj"; DO NOT EDIT
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const (
|
||||||
|
_AddrType_name_0 = "TYPE_NONE"
|
||||||
|
_AddrType_name_1 = "TYPE_BRANCHTYPE_TEXTSIZETYPE_MEMTYPE_CONSTTYPE_FCONSTTYPE_SCONSTTYPE_REGTYPE_ADDRTYPE_SHIFTTYPE_REGREGTYPE_REGREG2TYPE_INDIRTYPE_REGLIST"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_AddrType_index_0 = [...]uint8{0, 9}
|
||||||
|
_AddrType_index_1 = [...]uint8{0, 11, 24, 32, 42, 53, 64, 72, 81, 91, 102, 114, 124, 136}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i AddrType) String() string {
|
||||||
|
switch {
|
||||||
|
case i == 0:
|
||||||
|
return _AddrType_name_0
|
||||||
|
case 6 <= i && i <= 18:
|
||||||
|
i -= 6
|
||||||
|
return _AddrType_name_1[_AddrType_index_1[i]:_AddrType_index_1[i+1]]
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("AddrType(%d)", i)
|
||||||
|
}
|
||||||
|
}
|
338
vendor/github.com/google/gops/internal/obj/arm/a.out.go
generated
vendored
Normal file
338
vendor/github.com/google/gops/internal/obj/arm/a.out.go
generated
vendored
Normal file
@ -0,0 +1,338 @@
|
|||||||
|
// Inferno utils/5c/5.out.h
|
||||||
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5c/5.out.h
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package arm
|
||||||
|
|
||||||
|
import "github.com/google/gops/internal/obj"
|
||||||
|
|
||||||
|
//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p arm
|
||||||
|
|
||||||
|
const (
|
||||||
|
NSNAME = 8
|
||||||
|
NSYM = 50
|
||||||
|
NREG = 16
|
||||||
|
)
|
||||||
|
|
||||||
|
/* -1 disables use of REGARG */
|
||||||
|
const (
|
||||||
|
REGARG = -1
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
REG_R0 = obj.RBaseARM + iota // must be 16-aligned
|
||||||
|
REG_R1
|
||||||
|
REG_R2
|
||||||
|
REG_R3
|
||||||
|
REG_R4
|
||||||
|
REG_R5
|
||||||
|
REG_R6
|
||||||
|
REG_R7
|
||||||
|
REG_R8
|
||||||
|
REG_R9
|
||||||
|
REG_R10
|
||||||
|
REG_R11
|
||||||
|
REG_R12
|
||||||
|
REG_R13
|
||||||
|
REG_R14
|
||||||
|
REG_R15
|
||||||
|
|
||||||
|
REG_F0 // must be 16-aligned
|
||||||
|
REG_F1
|
||||||
|
REG_F2
|
||||||
|
REG_F3
|
||||||
|
REG_F4
|
||||||
|
REG_F5
|
||||||
|
REG_F6
|
||||||
|
REG_F7
|
||||||
|
REG_F8
|
||||||
|
REG_F9
|
||||||
|
REG_F10
|
||||||
|
REG_F11
|
||||||
|
REG_F12
|
||||||
|
REG_F13
|
||||||
|
REG_F14
|
||||||
|
REG_F15
|
||||||
|
|
||||||
|
REG_FPSR // must be 2-aligned
|
||||||
|
REG_FPCR
|
||||||
|
|
||||||
|
REG_CPSR // must be 2-aligned
|
||||||
|
REG_SPSR
|
||||||
|
|
||||||
|
MAXREG
|
||||||
|
REGRET = REG_R0
|
||||||
|
/* compiler allocates R1 up as temps */
|
||||||
|
/* compiler allocates register variables R3 up */
|
||||||
|
/* compiler allocates external registers R10 down */
|
||||||
|
REGEXT = REG_R10
|
||||||
|
/* these two registers are declared in runtime.h */
|
||||||
|
REGG = REGEXT - 0
|
||||||
|
REGM = REGEXT - 1
|
||||||
|
|
||||||
|
REGCTXT = REG_R7
|
||||||
|
REGTMP = REG_R11
|
||||||
|
REGSP = REG_R13
|
||||||
|
REGLINK = REG_R14
|
||||||
|
REGPC = REG_R15
|
||||||
|
|
||||||
|
NFREG = 16
|
||||||
|
/* compiler allocates register variables F0 up */
|
||||||
|
/* compiler allocates external registers F7 down */
|
||||||
|
FREGRET = REG_F0
|
||||||
|
FREGEXT = REG_F7
|
||||||
|
FREGTMP = REG_F15
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
C_NONE = iota
|
||||||
|
C_REG
|
||||||
|
C_REGREG
|
||||||
|
C_REGREG2
|
||||||
|
C_REGLIST
|
||||||
|
C_SHIFT
|
||||||
|
C_FREG
|
||||||
|
C_PSR
|
||||||
|
C_FCR
|
||||||
|
|
||||||
|
C_RCON /* 0xff rotated */
|
||||||
|
C_NCON /* ~RCON */
|
||||||
|
C_SCON /* 0xffff */
|
||||||
|
C_LCON
|
||||||
|
C_LCONADDR
|
||||||
|
C_ZFCON
|
||||||
|
C_SFCON
|
||||||
|
C_LFCON
|
||||||
|
|
||||||
|
C_RACON
|
||||||
|
C_LACON
|
||||||
|
|
||||||
|
C_SBRA
|
||||||
|
C_LBRA
|
||||||
|
|
||||||
|
C_HAUTO /* halfword insn offset (-0xff to 0xff) */
|
||||||
|
C_FAUTO /* float insn offset (0 to 0x3fc, word aligned) */
|
||||||
|
C_HFAUTO /* both H and F */
|
||||||
|
C_SAUTO /* -0xfff to 0xfff */
|
||||||
|
C_LAUTO
|
||||||
|
|
||||||
|
C_HOREG
|
||||||
|
C_FOREG
|
||||||
|
C_HFOREG
|
||||||
|
C_SOREG
|
||||||
|
C_ROREG
|
||||||
|
C_SROREG /* both nil and R */
|
||||||
|
C_LOREG
|
||||||
|
|
||||||
|
C_PC
|
||||||
|
C_SP
|
||||||
|
C_HREG
|
||||||
|
|
||||||
|
C_ADDR /* reference to relocatable address */
|
||||||
|
|
||||||
|
// TLS "var" in local exec mode: will become a constant offset from
|
||||||
|
// thread local base that is ultimately chosen by the program linker.
|
||||||
|
C_TLS_LE
|
||||||
|
|
||||||
|
// TLS "var" in initial exec mode: will become a memory address (chosen
|
||||||
|
// by the program linker) that the dynamic linker will fill with the
|
||||||
|
// offset from the thread local base.
|
||||||
|
C_TLS_IE
|
||||||
|
|
||||||
|
C_TEXTSIZE
|
||||||
|
|
||||||
|
C_GOK
|
||||||
|
|
||||||
|
C_NCLASS /* must be the last */
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AAND = obj.ABaseARM + obj.A_ARCHSPECIFIC + iota
|
||||||
|
AEOR
|
||||||
|
ASUB
|
||||||
|
ARSB
|
||||||
|
AADD
|
||||||
|
AADC
|
||||||
|
ASBC
|
||||||
|
ARSC
|
||||||
|
ATST
|
||||||
|
ATEQ
|
||||||
|
ACMP
|
||||||
|
ACMN
|
||||||
|
AORR
|
||||||
|
ABIC
|
||||||
|
|
||||||
|
AMVN
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not reorder or fragment the conditional branch
|
||||||
|
* opcodes, or the predication code will break
|
||||||
|
*/
|
||||||
|
ABEQ
|
||||||
|
ABNE
|
||||||
|
ABCS
|
||||||
|
ABHS
|
||||||
|
ABCC
|
||||||
|
ABLO
|
||||||
|
ABMI
|
||||||
|
ABPL
|
||||||
|
ABVS
|
||||||
|
ABVC
|
||||||
|
ABHI
|
||||||
|
ABLS
|
||||||
|
ABGE
|
||||||
|
ABLT
|
||||||
|
ABGT
|
||||||
|
ABLE
|
||||||
|
|
||||||
|
AMOVWD
|
||||||
|
AMOVWF
|
||||||
|
AMOVDW
|
||||||
|
AMOVFW
|
||||||
|
AMOVFD
|
||||||
|
AMOVDF
|
||||||
|
AMOVF
|
||||||
|
AMOVD
|
||||||
|
|
||||||
|
ACMPF
|
||||||
|
ACMPD
|
||||||
|
AADDF
|
||||||
|
AADDD
|
||||||
|
ASUBF
|
||||||
|
ASUBD
|
||||||
|
AMULF
|
||||||
|
AMULD
|
||||||
|
ADIVF
|
||||||
|
ADIVD
|
||||||
|
ASQRTF
|
||||||
|
ASQRTD
|
||||||
|
AABSF
|
||||||
|
AABSD
|
||||||
|
ANEGF
|
||||||
|
ANEGD
|
||||||
|
|
||||||
|
ASRL
|
||||||
|
ASRA
|
||||||
|
ASLL
|
||||||
|
AMULU
|
||||||
|
ADIVU
|
||||||
|
AMUL
|
||||||
|
ADIV
|
||||||
|
AMOD
|
||||||
|
AMODU
|
||||||
|
|
||||||
|
AMOVB
|
||||||
|
AMOVBS
|
||||||
|
AMOVBU
|
||||||
|
AMOVH
|
||||||
|
AMOVHS
|
||||||
|
AMOVHU
|
||||||
|
AMOVW
|
||||||
|
AMOVM
|
||||||
|
ASWPBU
|
||||||
|
ASWPW
|
||||||
|
|
||||||
|
ARFE
|
||||||
|
ASWI
|
||||||
|
AMULA
|
||||||
|
|
||||||
|
AWORD
|
||||||
|
|
||||||
|
AMULL
|
||||||
|
AMULAL
|
||||||
|
AMULLU
|
||||||
|
AMULALU
|
||||||
|
|
||||||
|
ABX
|
||||||
|
ABXRET
|
||||||
|
ADWORD
|
||||||
|
|
||||||
|
ALDREX
|
||||||
|
ASTREX
|
||||||
|
ALDREXD
|
||||||
|
ASTREXD
|
||||||
|
|
||||||
|
APLD
|
||||||
|
|
||||||
|
ACLZ
|
||||||
|
|
||||||
|
AMULWT
|
||||||
|
AMULWB
|
||||||
|
AMULAWT
|
||||||
|
AMULAWB
|
||||||
|
|
||||||
|
ADATABUNDLE
|
||||||
|
ADATABUNDLEEND
|
||||||
|
|
||||||
|
AMRC // MRC/MCR
|
||||||
|
|
||||||
|
ALAST
|
||||||
|
|
||||||
|
// aliases
|
||||||
|
AB = obj.AJMP
|
||||||
|
ABL = obj.ACALL
|
||||||
|
)
|
||||||
|
|
||||||
|
/* scond byte */
|
||||||
|
const (
|
||||||
|
C_SCOND = (1 << 4) - 1
|
||||||
|
C_SBIT = 1 << 4
|
||||||
|
C_PBIT = 1 << 5
|
||||||
|
C_WBIT = 1 << 6
|
||||||
|
C_FBIT = 1 << 7 /* psr flags-only */
|
||||||
|
C_UBIT = 1 << 7 /* up bit, unsigned bit */
|
||||||
|
|
||||||
|
// These constants are the ARM condition codes encodings,
|
||||||
|
// XORed with 14 so that C_SCOND_NONE has value 0,
|
||||||
|
// so that a zeroed Prog.scond means "always execute".
|
||||||
|
C_SCOND_XOR = 14
|
||||||
|
|
||||||
|
C_SCOND_EQ = 0 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_NE = 1 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_HS = 2 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_LO = 3 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_MI = 4 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_PL = 5 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_VS = 6 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_VC = 7 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_HI = 8 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_LS = 9 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_GE = 10 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_LT = 11 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_GT = 12 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_LE = 13 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_NONE = 14 ^ C_SCOND_XOR
|
||||||
|
C_SCOND_NV = 15 ^ C_SCOND_XOR
|
||||||
|
|
||||||
|
/* D_SHIFT type */
|
||||||
|
SHIFT_LL = 0 << 5
|
||||||
|
SHIFT_LR = 1 << 5
|
||||||
|
SHIFT_AR = 2 << 5
|
||||||
|
SHIFT_RR = 3 << 5
|
||||||
|
)
|
108
vendor/github.com/google/gops/internal/obj/arm/anames.go
generated
vendored
Normal file
108
vendor/github.com/google/gops/internal/obj/arm/anames.go
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
// Generated by stringer -i a.out.go -o anames.go -p arm
|
||||||
|
// Do not edit.
|
||||||
|
|
||||||
|
package arm
|
||||||
|
|
||||||
|
import "github.com/google/gops/internal/obj"
|
||||||
|
|
||||||
|
var Anames = []string{
|
||||||
|
obj.A_ARCHSPECIFIC: "AND",
|
||||||
|
"EOR",
|
||||||
|
"SUB",
|
||||||
|
"RSB",
|
||||||
|
"ADD",
|
||||||
|
"ADC",
|
||||||
|
"SBC",
|
||||||
|
"RSC",
|
||||||
|
"TST",
|
||||||
|
"TEQ",
|
||||||
|
"CMP",
|
||||||
|
"CMN",
|
||||||
|
"ORR",
|
||||||
|
"BIC",
|
||||||
|
"MVN",
|
||||||
|
"BEQ",
|
||||||
|
"BNE",
|
||||||
|
"BCS",
|
||||||
|
"BHS",
|
||||||
|
"BCC",
|
||||||
|
"BLO",
|
||||||
|
"BMI",
|
||||||
|
"BPL",
|
||||||
|
"BVS",
|
||||||
|
"BVC",
|
||||||
|
"BHI",
|
||||||
|
"BLS",
|
||||||
|
"BGE",
|
||||||
|
"BLT",
|
||||||
|
"BGT",
|
||||||
|
"BLE",
|
||||||
|
"MOVWD",
|
||||||
|
"MOVWF",
|
||||||
|
"MOVDW",
|
||||||
|
"MOVFW",
|
||||||
|
"MOVFD",
|
||||||
|
"MOVDF",
|
||||||
|
"MOVF",
|
||||||
|
"MOVD",
|
||||||
|
"CMPF",
|
||||||
|
"CMPD",
|
||||||
|
"ADDF",
|
||||||
|
"ADDD",
|
||||||
|
"SUBF",
|
||||||
|
"SUBD",
|
||||||
|
"MULF",
|
||||||
|
"MULD",
|
||||||
|
"DIVF",
|
||||||
|
"DIVD",
|
||||||
|
"SQRTF",
|
||||||
|
"SQRTD",
|
||||||
|
"ABSF",
|
||||||
|
"ABSD",
|
||||||
|
"NEGF",
|
||||||
|
"NEGD",
|
||||||
|
"SRL",
|
||||||
|
"SRA",
|
||||||
|
"SLL",
|
||||||
|
"MULU",
|
||||||
|
"DIVU",
|
||||||
|
"MUL",
|
||||||
|
"DIV",
|
||||||
|
"MOD",
|
||||||
|
"MODU",
|
||||||
|
"MOVB",
|
||||||
|
"MOVBS",
|
||||||
|
"MOVBU",
|
||||||
|
"MOVH",
|
||||||
|
"MOVHS",
|
||||||
|
"MOVHU",
|
||||||
|
"MOVW",
|
||||||
|
"MOVM",
|
||||||
|
"SWPBU",
|
||||||
|
"SWPW",
|
||||||
|
"RFE",
|
||||||
|
"SWI",
|
||||||
|
"MULA",
|
||||||
|
"WORD",
|
||||||
|
"MULL",
|
||||||
|
"MULAL",
|
||||||
|
"MULLU",
|
||||||
|
"MULALU",
|
||||||
|
"BX",
|
||||||
|
"BXRET",
|
||||||
|
"DWORD",
|
||||||
|
"LDREX",
|
||||||
|
"STREX",
|
||||||
|
"LDREXD",
|
||||||
|
"STREXD",
|
||||||
|
"PLD",
|
||||||
|
"CLZ",
|
||||||
|
"MULWT",
|
||||||
|
"MULWB",
|
||||||
|
"MULAWT",
|
||||||
|
"MULAWB",
|
||||||
|
"DATABUNDLE",
|
||||||
|
"DATABUNDLEEND",
|
||||||
|
"MRC",
|
||||||
|
"LAST",
|
||||||
|
}
|
73
vendor/github.com/google/gops/internal/obj/arm/anames5.go
generated
vendored
Normal file
73
vendor/github.com/google/gops/internal/obj/arm/anames5.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package arm
|
||||||
|
|
||||||
|
var cnames5 = []string{
|
||||||
|
"NONE",
|
||||||
|
"REG",
|
||||||
|
"REGREG",
|
||||||
|
"REGREG2",
|
||||||
|
"REGLIST",
|
||||||
|
"SHIFT",
|
||||||
|
"FREG",
|
||||||
|
"PSR",
|
||||||
|
"FCR",
|
||||||
|
"RCON",
|
||||||
|
"NCON",
|
||||||
|
"SCON",
|
||||||
|
"LCON",
|
||||||
|
"LCONADDR",
|
||||||
|
"ZFCON",
|
||||||
|
"SFCON",
|
||||||
|
"LFCON",
|
||||||
|
"RACON",
|
||||||
|
"LACON",
|
||||||
|
"SBRA",
|
||||||
|
"LBRA",
|
||||||
|
"HAUTO",
|
||||||
|
"FAUTO",
|
||||||
|
"HFAUTO",
|
||||||
|
"SAUTO",
|
||||||
|
"LAUTO",
|
||||||
|
"HOREG",
|
||||||
|
"FOREG",
|
||||||
|
"HFOREG",
|
||||||
|
"SOREG",
|
||||||
|
"ROREG",
|
||||||
|
"SROREG",
|
||||||
|
"LOREG",
|
||||||
|
"PC",
|
||||||
|
"SP",
|
||||||
|
"HREG",
|
||||||
|
"ADDR",
|
||||||
|
"C_TLS_LE",
|
||||||
|
"C_TLS_IE",
|
||||||
|
"TEXTSIZE",
|
||||||
|
"GOK",
|
||||||
|
"NCLASS",
|
||||||
|
"SCOND = (1<<4)-1",
|
||||||
|
"SBIT = 1<<4",
|
||||||
|
"PBIT = 1<<5",
|
||||||
|
"WBIT = 1<<6",
|
||||||
|
"FBIT = 1<<7",
|
||||||
|
"UBIT = 1<<7",
|
||||||
|
"SCOND_XOR = 14",
|
||||||
|
"SCOND_EQ = 0 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_NE = 1 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_HS = 2 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_LO = 3 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_MI = 4 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_PL = 5 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_VS = 6 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_VC = 7 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_HI = 8 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_LS = 9 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_GE = 10 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_LT = 11 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_GT = 12 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_LE = 13 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_NONE = 14 ^ C_SCOND_XOR",
|
||||||
|
"SCOND_NV = 15 ^ C_SCOND_XOR",
|
||||||
|
}
|
2846
vendor/github.com/google/gops/internal/obj/arm/asm5.go
generated
vendored
Normal file
2846
vendor/github.com/google/gops/internal/obj/arm/asm5.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
84
vendor/github.com/google/gops/internal/obj/arm/list5.go
generated
vendored
Normal file
84
vendor/github.com/google/gops/internal/obj/arm/list5.go
generated
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// Inferno utils/5c/list.c
|
||||||
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5c/list.c
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package arm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gops/internal/obj"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
obj.RegisterRegister(obj.RBaseARM, MAXREG, Rconv)
|
||||||
|
obj.RegisterOpcode(obj.ABaseARM, Anames)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Rconv(r int) string {
|
||||||
|
if r == 0 {
|
||||||
|
return "NONE"
|
||||||
|
}
|
||||||
|
if r == REGG {
|
||||||
|
// Special case.
|
||||||
|
return "g"
|
||||||
|
}
|
||||||
|
if REG_R0 <= r && r <= REG_R15 {
|
||||||
|
return fmt.Sprintf("R%d", r-REG_R0)
|
||||||
|
}
|
||||||
|
if REG_F0 <= r && r <= REG_F15 {
|
||||||
|
return fmt.Sprintf("F%d", r-REG_F0)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch r {
|
||||||
|
case REG_FPSR:
|
||||||
|
return "FPSR"
|
||||||
|
|
||||||
|
case REG_FPCR:
|
||||||
|
return "FPCR"
|
||||||
|
|
||||||
|
case REG_CPSR:
|
||||||
|
return "CPSR"
|
||||||
|
|
||||||
|
case REG_SPSR:
|
||||||
|
return "SPSR"
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("Rgok(%d)", r-obj.RBaseARM)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DRconv(a int) string {
|
||||||
|
s := "C_??"
|
||||||
|
if a >= C_NONE && a <= C_NCLASS {
|
||||||
|
s = cnames5[a]
|
||||||
|
}
|
||||||
|
var fp string
|
||||||
|
fp += s
|
||||||
|
return fp
|
||||||
|
}
|
1055
vendor/github.com/google/gops/internal/obj/arm/obj5.go
generated
vendored
Normal file
1055
vendor/github.com/google/gops/internal/obj/arm/obj5.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
719
vendor/github.com/google/gops/internal/obj/arm64/a.out.go
generated
vendored
Normal file
719
vendor/github.com/google/gops/internal/obj/arm64/a.out.go
generated
vendored
Normal file
@ -0,0 +1,719 @@
|
|||||||
|
// cmd/7c/7.out.h from Vita Nuova.
|
||||||
|
// https://code.google.com/p/ken-cc/source/browse/src/cmd/7c/7.out.h
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package arm64
|
||||||
|
|
||||||
|
import "github.com/google/gops/internal/obj"
|
||||||
|
|
||||||
|
const (
|
||||||
|
NSNAME = 8
|
||||||
|
NSYM = 50
|
||||||
|
NREG = 32 /* number of general registers */
|
||||||
|
NFREG = 32 /* number of floating point registers */
|
||||||
|
)
|
||||||
|
|
||||||
|
// General purpose registers, kept in the low bits of Prog.Reg.
|
||||||
|
const (
|
||||||
|
// integer
|
||||||
|
REG_R0 = obj.RBaseARM64 + iota
|
||||||
|
REG_R1
|
||||||
|
REG_R2
|
||||||
|
REG_R3
|
||||||
|
REG_R4
|
||||||
|
REG_R5
|
||||||
|
REG_R6
|
||||||
|
REG_R7
|
||||||
|
REG_R8
|
||||||
|
REG_R9
|
||||||
|
REG_R10
|
||||||
|
REG_R11
|
||||||
|
REG_R12
|
||||||
|
REG_R13
|
||||||
|
REG_R14
|
||||||
|
REG_R15
|
||||||
|
REG_R16
|
||||||
|
REG_R17
|
||||||
|
REG_R18
|
||||||
|
REG_R19
|
||||||
|
REG_R20
|
||||||
|
REG_R21
|
||||||
|
REG_R22
|
||||||
|
REG_R23
|
||||||
|
REG_R24
|
||||||
|
REG_R25
|
||||||
|
REG_R26
|
||||||
|
REG_R27
|
||||||
|
REG_R28
|
||||||
|
REG_R29
|
||||||
|
REG_R30
|
||||||
|
REG_R31
|
||||||
|
|
||||||
|
// scalar floating point
|
||||||
|
REG_F0
|
||||||
|
REG_F1
|
||||||
|
REG_F2
|
||||||
|
REG_F3
|
||||||
|
REG_F4
|
||||||
|
REG_F5
|
||||||
|
REG_F6
|
||||||
|
REG_F7
|
||||||
|
REG_F8
|
||||||
|
REG_F9
|
||||||
|
REG_F10
|
||||||
|
REG_F11
|
||||||
|
REG_F12
|
||||||
|
REG_F13
|
||||||
|
REG_F14
|
||||||
|
REG_F15
|
||||||
|
REG_F16
|
||||||
|
REG_F17
|
||||||
|
REG_F18
|
||||||
|
REG_F19
|
||||||
|
REG_F20
|
||||||
|
REG_F21
|
||||||
|
REG_F22
|
||||||
|
REG_F23
|
||||||
|
REG_F24
|
||||||
|
REG_F25
|
||||||
|
REG_F26
|
||||||
|
REG_F27
|
||||||
|
REG_F28
|
||||||
|
REG_F29
|
||||||
|
REG_F30
|
||||||
|
REG_F31
|
||||||
|
|
||||||
|
// SIMD
|
||||||
|
REG_V0
|
||||||
|
REG_V1
|
||||||
|
REG_V2
|
||||||
|
REG_V3
|
||||||
|
REG_V4
|
||||||
|
REG_V5
|
||||||
|
REG_V6
|
||||||
|
REG_V7
|
||||||
|
REG_V8
|
||||||
|
REG_V9
|
||||||
|
REG_V10
|
||||||
|
REG_V11
|
||||||
|
REG_V12
|
||||||
|
REG_V13
|
||||||
|
REG_V14
|
||||||
|
REG_V15
|
||||||
|
REG_V16
|
||||||
|
REG_V17
|
||||||
|
REG_V18
|
||||||
|
REG_V19
|
||||||
|
REG_V20
|
||||||
|
REG_V21
|
||||||
|
REG_V22
|
||||||
|
REG_V23
|
||||||
|
REG_V24
|
||||||
|
REG_V25
|
||||||
|
REG_V26
|
||||||
|
REG_V27
|
||||||
|
REG_V28
|
||||||
|
REG_V29
|
||||||
|
REG_V30
|
||||||
|
REG_V31
|
||||||
|
|
||||||
|
// The EQ in
|
||||||
|
// CSET EQ, R0
|
||||||
|
// is encoded as TYPE_REG, even though it's not really a register.
|
||||||
|
COND_EQ
|
||||||
|
COND_NE
|
||||||
|
COND_HS
|
||||||
|
COND_LO
|
||||||
|
COND_MI
|
||||||
|
COND_PL
|
||||||
|
COND_VS
|
||||||
|
COND_VC
|
||||||
|
COND_HI
|
||||||
|
COND_LS
|
||||||
|
COND_GE
|
||||||
|
COND_LT
|
||||||
|
COND_GT
|
||||||
|
COND_LE
|
||||||
|
COND_AL
|
||||||
|
COND_NV
|
||||||
|
|
||||||
|
REG_RSP = REG_V31 + 32 // to differentiate ZR/SP, REG_RSP&0x1f = 31
|
||||||
|
)
|
||||||
|
|
||||||
|
// Not registers, but flags that can be combined with regular register
|
||||||
|
// constants to indicate extended register conversion. When checking,
|
||||||
|
// you should subtract obj.RBaseARM64 first. From this difference, bit 11
|
||||||
|
// indicates extended register, bits 8-10 select the conversion mode.
|
||||||
|
const REG_EXT = obj.RBaseARM64 + 1<<11
|
||||||
|
|
||||||
|
const (
|
||||||
|
REG_UXTB = REG_EXT + iota<<8
|
||||||
|
REG_UXTH
|
||||||
|
REG_UXTW
|
||||||
|
REG_UXTX
|
||||||
|
REG_SXTB
|
||||||
|
REG_SXTH
|
||||||
|
REG_SXTW
|
||||||
|
REG_SXTX
|
||||||
|
)
|
||||||
|
|
||||||
|
// Special registers, after subtracting obj.RBaseARM64, bit 12 indicates
|
||||||
|
// a special register and the low bits select the register.
|
||||||
|
const (
|
||||||
|
REG_SPECIAL = obj.RBaseARM64 + 1<<12 + iota
|
||||||
|
REG_DAIF
|
||||||
|
REG_NZCV
|
||||||
|
REG_FPSR
|
||||||
|
REG_FPCR
|
||||||
|
REG_SPSR_EL1
|
||||||
|
REG_ELR_EL1
|
||||||
|
REG_SPSR_EL2
|
||||||
|
REG_ELR_EL2
|
||||||
|
REG_CurrentEL
|
||||||
|
REG_SP_EL0
|
||||||
|
REG_SPSel
|
||||||
|
REG_DAIFSet
|
||||||
|
REG_DAIFClr
|
||||||
|
)
|
||||||
|
|
||||||
|
// Register assignments:
|
||||||
|
//
|
||||||
|
// compiler allocates R0 up as temps
|
||||||
|
// compiler allocates register variables R7-R25
|
||||||
|
// compiler allocates external registers R26 down
|
||||||
|
//
|
||||||
|
// compiler allocates register variables F7-F26
|
||||||
|
// compiler allocates external registers F26 down
|
||||||
|
const (
|
||||||
|
REGMIN = REG_R7 // register variables allocated from here to REGMAX
|
||||||
|
REGRT1 = REG_R16 // ARM64 IP0, for external linker, runtime, duffzero and duffcopy
|
||||||
|
REGRT2 = REG_R17 // ARM64 IP1, for external linker, runtime, duffcopy
|
||||||
|
REGPR = REG_R18 // ARM64 platform register, unused in the Go toolchain
|
||||||
|
REGMAX = REG_R25
|
||||||
|
|
||||||
|
REGCTXT = REG_R26 // environment for closures
|
||||||
|
REGTMP = REG_R27 // reserved for liblink
|
||||||
|
REGG = REG_R28 // G
|
||||||
|
REGFP = REG_R29 // frame pointer, unused in the Go toolchain
|
||||||
|
REGLINK = REG_R30
|
||||||
|
|
||||||
|
// ARM64 uses R31 as both stack pointer and zero register,
|
||||||
|
// depending on the instruction. To differentiate RSP from ZR,
|
||||||
|
// we use a different numeric value for REGZERO and REGSP.
|
||||||
|
REGZERO = REG_R31
|
||||||
|
REGSP = REG_RSP
|
||||||
|
|
||||||
|
FREGRET = REG_F0
|
||||||
|
FREGMIN = REG_F7 // first register variable
|
||||||
|
FREGMAX = REG_F26 // last register variable for 7g only
|
||||||
|
FREGEXT = REG_F26 // first external register
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
BIG = 2048 - 8
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
/* mark flags */
|
||||||
|
LABEL = 1 << iota
|
||||||
|
LEAF
|
||||||
|
FLOAT
|
||||||
|
BRANCH
|
||||||
|
LOAD
|
||||||
|
FCMP
|
||||||
|
SYNC
|
||||||
|
LIST
|
||||||
|
FOLL
|
||||||
|
NOSCHED
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
C_NONE = iota
|
||||||
|
C_REG // R0..R30
|
||||||
|
C_RSP // R0..R30, RSP
|
||||||
|
C_FREG // F0..F31
|
||||||
|
C_VREG // V0..V31
|
||||||
|
C_PAIR // (Rn, Rm)
|
||||||
|
C_SHIFT // Rn<<2
|
||||||
|
C_EXTREG // Rn.UXTB<<3
|
||||||
|
C_SPR // REG_NZCV
|
||||||
|
C_COND // EQ, NE, etc
|
||||||
|
|
||||||
|
C_ZCON // $0 or ZR
|
||||||
|
C_ADDCON0 // 12-bit unsigned, unshifted
|
||||||
|
C_ADDCON // 12-bit unsigned, shifted left by 0 or 12
|
||||||
|
C_MOVCON // generated by a 16-bit constant, optionally inverted and/or shifted by multiple of 16
|
||||||
|
C_BITCON // bitfield and logical immediate masks
|
||||||
|
C_ABCON0 // could be C_ADDCON0 or C_BITCON
|
||||||
|
C_ABCON // could be C_ADDCON or C_BITCON
|
||||||
|
C_MBCON // could be C_MOVCON or C_BITCON
|
||||||
|
C_LCON // 32-bit constant
|
||||||
|
C_VCON // 64-bit constant
|
||||||
|
C_FCON // floating-point constant
|
||||||
|
C_VCONADDR // 64-bit memory address
|
||||||
|
|
||||||
|
C_AACON // ADDCON offset in auto constant $a(FP)
|
||||||
|
C_LACON // 32-bit offset in auto constant $a(FP)
|
||||||
|
C_AECON // ADDCON offset in extern constant $e(SB)
|
||||||
|
|
||||||
|
// TODO(aram): only one branch class should be enough
|
||||||
|
C_SBRA // for TYPE_BRANCH
|
||||||
|
C_LBRA
|
||||||
|
|
||||||
|
C_NPAUTO // -512 <= x < 0, 0 mod 8
|
||||||
|
C_NSAUTO // -256 <= x < 0
|
||||||
|
C_PSAUTO // 0 to 255
|
||||||
|
C_PPAUTO // 0 to 504, 0 mod 8
|
||||||
|
C_UAUTO4K // 0 to 4095
|
||||||
|
C_UAUTO8K // 0 to 8190, 0 mod 2
|
||||||
|
C_UAUTO16K // 0 to 16380, 0 mod 4
|
||||||
|
C_UAUTO32K // 0 to 32760, 0 mod 8
|
||||||
|
C_UAUTO64K // 0 to 65520, 0 mod 16
|
||||||
|
C_LAUTO // any other 32-bit constant
|
||||||
|
|
||||||
|
C_SEXT1 // 0 to 4095, direct
|
||||||
|
C_SEXT2 // 0 to 8190
|
||||||
|
C_SEXT4 // 0 to 16380
|
||||||
|
C_SEXT8 // 0 to 32760
|
||||||
|
C_SEXT16 // 0 to 65520
|
||||||
|
C_LEXT
|
||||||
|
|
||||||
|
// TODO(aram): s/AUTO/INDIR/
|
||||||
|
C_ZOREG // 0(R)
|
||||||
|
C_NPOREG // mirror NPAUTO, etc
|
||||||
|
C_NSOREG
|
||||||
|
C_PSOREG
|
||||||
|
C_PPOREG
|
||||||
|
C_UOREG4K
|
||||||
|
C_UOREG8K
|
||||||
|
C_UOREG16K
|
||||||
|
C_UOREG32K
|
||||||
|
C_UOREG64K
|
||||||
|
C_LOREG
|
||||||
|
|
||||||
|
C_ADDR // TODO(aram): explain difference from C_VCONADDR
|
||||||
|
|
||||||
|
// The GOT slot for a symbol in -dynlink mode.
|
||||||
|
C_GOTADDR
|
||||||
|
|
||||||
|
// TLS "var" in local exec mode: will become a constant offset from
|
||||||
|
// thread local base that is ultimately chosen by the program linker.
|
||||||
|
C_TLS_LE
|
||||||
|
|
||||||
|
// TLS "var" in initial exec mode: will become a memory address (chosen
|
||||||
|
// by the program linker) that the dynamic linker will fill with the
|
||||||
|
// offset from the thread local base.
|
||||||
|
C_TLS_IE
|
||||||
|
|
||||||
|
C_ROFF // register offset (including register extended)
|
||||||
|
|
||||||
|
C_GOK
|
||||||
|
C_TEXTSIZE
|
||||||
|
C_NCLASS // must be last
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
C_XPRE = 1 << 6 // match arm.C_WBIT, so Prog.String know how to print it
|
||||||
|
C_XPOST = 1 << 5 // match arm.C_PBIT, so Prog.String know how to print it
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p arm64
|
||||||
|
|
||||||
|
const (
|
||||||
|
AADC = obj.ABaseARM64 + obj.A_ARCHSPECIFIC + iota
|
||||||
|
AADCS
|
||||||
|
AADCSW
|
||||||
|
AADCW
|
||||||
|
AADD
|
||||||
|
AADDS
|
||||||
|
AADDSW
|
||||||
|
AADDW
|
||||||
|
AADR
|
||||||
|
AADRP
|
||||||
|
AAND
|
||||||
|
AANDS
|
||||||
|
AANDSW
|
||||||
|
AANDW
|
||||||
|
AASR
|
||||||
|
AASRW
|
||||||
|
AAT
|
||||||
|
ABFI
|
||||||
|
ABFIW
|
||||||
|
ABFM
|
||||||
|
ABFMW
|
||||||
|
ABFXIL
|
||||||
|
ABFXILW
|
||||||
|
ABIC
|
||||||
|
ABICS
|
||||||
|
ABICSW
|
||||||
|
ABICW
|
||||||
|
ABRK
|
||||||
|
ACBNZ
|
||||||
|
ACBNZW
|
||||||
|
ACBZ
|
||||||
|
ACBZW
|
||||||
|
ACCMN
|
||||||
|
ACCMNW
|
||||||
|
ACCMP
|
||||||
|
ACCMPW
|
||||||
|
ACINC
|
||||||
|
ACINCW
|
||||||
|
ACINV
|
||||||
|
ACINVW
|
||||||
|
ACLREX
|
||||||
|
ACLS
|
||||||
|
ACLSW
|
||||||
|
ACLZ
|
||||||
|
ACLZW
|
||||||
|
ACMN
|
||||||
|
ACMNW
|
||||||
|
ACMP
|
||||||
|
ACMPW
|
||||||
|
ACNEG
|
||||||
|
ACNEGW
|
||||||
|
ACRC32B
|
||||||
|
ACRC32CB
|
||||||
|
ACRC32CH
|
||||||
|
ACRC32CW
|
||||||
|
ACRC32CX
|
||||||
|
ACRC32H
|
||||||
|
ACRC32W
|
||||||
|
ACRC32X
|
||||||
|
ACSEL
|
||||||
|
ACSELW
|
||||||
|
ACSET
|
||||||
|
ACSETM
|
||||||
|
ACSETMW
|
||||||
|
ACSETW
|
||||||
|
ACSINC
|
||||||
|
ACSINCW
|
||||||
|
ACSINV
|
||||||
|
ACSINVW
|
||||||
|
ACSNEG
|
||||||
|
ACSNEGW
|
||||||
|
ADC
|
||||||
|
ADCPS1
|
||||||
|
ADCPS2
|
||||||
|
ADCPS3
|
||||||
|
ADMB
|
||||||
|
ADRPS
|
||||||
|
ADSB
|
||||||
|
AEON
|
||||||
|
AEONW
|
||||||
|
AEOR
|
||||||
|
AEORW
|
||||||
|
AERET
|
||||||
|
AEXTR
|
||||||
|
AEXTRW
|
||||||
|
AHINT
|
||||||
|
AHLT
|
||||||
|
AHVC
|
||||||
|
AIC
|
||||||
|
AISB
|
||||||
|
ALDAR
|
||||||
|
ALDARB
|
||||||
|
ALDARH
|
||||||
|
ALDARW
|
||||||
|
ALDAXP
|
||||||
|
ALDAXPW
|
||||||
|
ALDAXR
|
||||||
|
ALDAXRB
|
||||||
|
ALDAXRH
|
||||||
|
ALDAXRW
|
||||||
|
ALDP
|
||||||
|
ALDXR
|
||||||
|
ALDXRB
|
||||||
|
ALDXRH
|
||||||
|
ALDXRW
|
||||||
|
ALDXP
|
||||||
|
ALDXPW
|
||||||
|
ALSL
|
||||||
|
ALSLW
|
||||||
|
ALSR
|
||||||
|
ALSRW
|
||||||
|
AMADD
|
||||||
|
AMADDW
|
||||||
|
AMNEG
|
||||||
|
AMNEGW
|
||||||
|
AMOVK
|
||||||
|
AMOVKW
|
||||||
|
AMOVN
|
||||||
|
AMOVNW
|
||||||
|
AMOVZ
|
||||||
|
AMOVZW
|
||||||
|
AMRS
|
||||||
|
AMSR
|
||||||
|
AMSUB
|
||||||
|
AMSUBW
|
||||||
|
AMUL
|
||||||
|
AMULW
|
||||||
|
AMVN
|
||||||
|
AMVNW
|
||||||
|
ANEG
|
||||||
|
ANEGS
|
||||||
|
ANEGSW
|
||||||
|
ANEGW
|
||||||
|
ANGC
|
||||||
|
ANGCS
|
||||||
|
ANGCSW
|
||||||
|
ANGCW
|
||||||
|
AORN
|
||||||
|
AORNW
|
||||||
|
AORR
|
||||||
|
AORRW
|
||||||
|
APRFM
|
||||||
|
APRFUM
|
||||||
|
ARBIT
|
||||||
|
ARBITW
|
||||||
|
AREM
|
||||||
|
AREMW
|
||||||
|
AREV
|
||||||
|
AREV16
|
||||||
|
AREV16W
|
||||||
|
AREV32
|
||||||
|
AREVW
|
||||||
|
AROR
|
||||||
|
ARORW
|
||||||
|
ASBC
|
||||||
|
ASBCS
|
||||||
|
ASBCSW
|
||||||
|
ASBCW
|
||||||
|
ASBFIZ
|
||||||
|
ASBFIZW
|
||||||
|
ASBFM
|
||||||
|
ASBFMW
|
||||||
|
ASBFX
|
||||||
|
ASBFXW
|
||||||
|
ASDIV
|
||||||
|
ASDIVW
|
||||||
|
ASEV
|
||||||
|
ASEVL
|
||||||
|
ASMADDL
|
||||||
|
ASMC
|
||||||
|
ASMNEGL
|
||||||
|
ASMSUBL
|
||||||
|
ASMULH
|
||||||
|
ASMULL
|
||||||
|
ASTXR
|
||||||
|
ASTXRB
|
||||||
|
ASTXRH
|
||||||
|
ASTXP
|
||||||
|
ASTXPW
|
||||||
|
ASTXRW
|
||||||
|
ASTLP
|
||||||
|
ASTLPW
|
||||||
|
ASTLR
|
||||||
|
ASTLRB
|
||||||
|
ASTLRH
|
||||||
|
ASTLRW
|
||||||
|
ASTLXP
|
||||||
|
ASTLXPW
|
||||||
|
ASTLXR
|
||||||
|
ASTLXRB
|
||||||
|
ASTLXRH
|
||||||
|
ASTLXRW
|
||||||
|
ASTP
|
||||||
|
ASUB
|
||||||
|
ASUBS
|
||||||
|
ASUBSW
|
||||||
|
ASUBW
|
||||||
|
ASVC
|
||||||
|
ASXTB
|
||||||
|
ASXTBW
|
||||||
|
ASXTH
|
||||||
|
ASXTHW
|
||||||
|
ASXTW
|
||||||
|
ASYS
|
||||||
|
ASYSL
|
||||||
|
ATBNZ
|
||||||
|
ATBZ
|
||||||
|
ATLBI
|
||||||
|
ATST
|
||||||
|
ATSTW
|
||||||
|
AUBFIZ
|
||||||
|
AUBFIZW
|
||||||
|
AUBFM
|
||||||
|
AUBFMW
|
||||||
|
AUBFX
|
||||||
|
AUBFXW
|
||||||
|
AUDIV
|
||||||
|
AUDIVW
|
||||||
|
AUMADDL
|
||||||
|
AUMNEGL
|
||||||
|
AUMSUBL
|
||||||
|
AUMULH
|
||||||
|
AUMULL
|
||||||
|
AUREM
|
||||||
|
AUREMW
|
||||||
|
AUXTB
|
||||||
|
AUXTH
|
||||||
|
AUXTW
|
||||||
|
AUXTBW
|
||||||
|
AUXTHW
|
||||||
|
AWFE
|
||||||
|
AWFI
|
||||||
|
AYIELD
|
||||||
|
AMOVB
|
||||||
|
AMOVBU
|
||||||
|
AMOVH
|
||||||
|
AMOVHU
|
||||||
|
AMOVW
|
||||||
|
AMOVWU
|
||||||
|
AMOVD
|
||||||
|
AMOVNP
|
||||||
|
AMOVNPW
|
||||||
|
AMOVP
|
||||||
|
AMOVPD
|
||||||
|
AMOVPQ
|
||||||
|
AMOVPS
|
||||||
|
AMOVPSW
|
||||||
|
AMOVPW
|
||||||
|
ABEQ
|
||||||
|
ABNE
|
||||||
|
ABCS
|
||||||
|
ABHS
|
||||||
|
ABCC
|
||||||
|
ABLO
|
||||||
|
ABMI
|
||||||
|
ABPL
|
||||||
|
ABVS
|
||||||
|
ABVC
|
||||||
|
ABHI
|
||||||
|
ABLS
|
||||||
|
ABGE
|
||||||
|
ABLT
|
||||||
|
ABGT
|
||||||
|
ABLE
|
||||||
|
AFABSD
|
||||||
|
AFABSS
|
||||||
|
AFADDD
|
||||||
|
AFADDS
|
||||||
|
AFCCMPD
|
||||||
|
AFCCMPED
|
||||||
|
AFCCMPS
|
||||||
|
AFCCMPES
|
||||||
|
AFCMPD
|
||||||
|
AFCMPED
|
||||||
|
AFCMPES
|
||||||
|
AFCMPS
|
||||||
|
AFCVTSD
|
||||||
|
AFCVTDS
|
||||||
|
AFCVTZSD
|
||||||
|
AFCVTZSDW
|
||||||
|
AFCVTZSS
|
||||||
|
AFCVTZSSW
|
||||||
|
AFCVTZUD
|
||||||
|
AFCVTZUDW
|
||||||
|
AFCVTZUS
|
||||||
|
AFCVTZUSW
|
||||||
|
AFDIVD
|
||||||
|
AFDIVS
|
||||||
|
AFMOVD
|
||||||
|
AFMOVS
|
||||||
|
AFMULD
|
||||||
|
AFMULS
|
||||||
|
AFNEGD
|
||||||
|
AFNEGS
|
||||||
|
AFSQRTD
|
||||||
|
AFSQRTS
|
||||||
|
AFSUBD
|
||||||
|
AFSUBS
|
||||||
|
ASCVTFD
|
||||||
|
ASCVTFS
|
||||||
|
ASCVTFWD
|
||||||
|
ASCVTFWS
|
||||||
|
AUCVTFD
|
||||||
|
AUCVTFS
|
||||||
|
AUCVTFWD
|
||||||
|
AUCVTFWS
|
||||||
|
AWORD
|
||||||
|
ADWORD
|
||||||
|
AFCSELS
|
||||||
|
AFCSELD
|
||||||
|
AFMAXS
|
||||||
|
AFMINS
|
||||||
|
AFMAXD
|
||||||
|
AFMIND
|
||||||
|
AFMAXNMS
|
||||||
|
AFMAXNMD
|
||||||
|
AFNMULS
|
||||||
|
AFNMULD
|
||||||
|
AFRINTNS
|
||||||
|
AFRINTND
|
||||||
|
AFRINTPS
|
||||||
|
AFRINTPD
|
||||||
|
AFRINTMS
|
||||||
|
AFRINTMD
|
||||||
|
AFRINTZS
|
||||||
|
AFRINTZD
|
||||||
|
AFRINTAS
|
||||||
|
AFRINTAD
|
||||||
|
AFRINTXS
|
||||||
|
AFRINTXD
|
||||||
|
AFRINTIS
|
||||||
|
AFRINTID
|
||||||
|
AFMADDS
|
||||||
|
AFMADDD
|
||||||
|
AFMSUBS
|
||||||
|
AFMSUBD
|
||||||
|
AFNMADDS
|
||||||
|
AFNMADDD
|
||||||
|
AFNMSUBS
|
||||||
|
AFNMSUBD
|
||||||
|
AFMINNMS
|
||||||
|
AFMINNMD
|
||||||
|
AFCVTDH
|
||||||
|
AFCVTHS
|
||||||
|
AFCVTHD
|
||||||
|
AFCVTSH
|
||||||
|
AAESD
|
||||||
|
AAESE
|
||||||
|
AAESIMC
|
||||||
|
AAESMC
|
||||||
|
ASHA1C
|
||||||
|
ASHA1H
|
||||||
|
ASHA1M
|
||||||
|
ASHA1P
|
||||||
|
ASHA1SU0
|
||||||
|
ASHA1SU1
|
||||||
|
ASHA256H
|
||||||
|
ASHA256H2
|
||||||
|
ASHA256SU0
|
||||||
|
ASHA256SU1
|
||||||
|
ALAST
|
||||||
|
AB = obj.AJMP
|
||||||
|
ABL = obj.ACALL
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// shift types
|
||||||
|
SHIFT_LL = 0 << 22
|
||||||
|
SHIFT_LR = 1 << 22
|
||||||
|
SHIFT_AR = 2 << 22
|
||||||
|
)
|
370
vendor/github.com/google/gops/internal/obj/arm64/anames.go
generated
vendored
Normal file
370
vendor/github.com/google/gops/internal/obj/arm64/anames.go
generated
vendored
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
// Generated by stringer -i a.out.go -o anames.go -p arm64
|
||||||
|
// Do not edit.
|
||||||
|
|
||||||
|
package arm64
|
||||||
|
|
||||||
|
import "github.com/google/gops/internal/obj"
|
||||||
|
|
||||||
|
var Anames = []string{
|
||||||
|
obj.A_ARCHSPECIFIC: "ADC",
|
||||||
|
"ADCS",
|
||||||
|
"ADCSW",
|
||||||
|
"ADCW",
|
||||||
|
"ADD",
|
||||||
|
"ADDS",
|
||||||
|
"ADDSW",
|
||||||
|
"ADDW",
|
||||||
|
"ADR",
|
||||||
|
"ADRP",
|
||||||
|
"AND",
|
||||||
|
"ANDS",
|
||||||
|
"ANDSW",
|
||||||
|
"ANDW",
|
||||||
|
"ASR",
|
||||||
|
"ASRW",
|
||||||
|
"AT",
|
||||||
|
"BFI",
|
||||||
|
"BFIW",
|
||||||
|
"BFM",
|
||||||
|
"BFMW",
|
||||||
|
"BFXIL",
|
||||||
|
"BFXILW",
|
||||||
|
"BIC",
|
||||||
|
"BICS",
|
||||||
|
"BICSW",
|
||||||
|
"BICW",
|
||||||
|
"BRK",
|
||||||
|
"CBNZ",
|
||||||
|
"CBNZW",
|
||||||
|
"CBZ",
|
||||||
|
"CBZW",
|
||||||
|
"CCMN",
|
||||||
|
"CCMNW",
|
||||||
|
"CCMP",
|
||||||
|
"CCMPW",
|
||||||
|
"CINC",
|
||||||
|
"CINCW",
|
||||||
|
"CINV",
|
||||||
|
"CINVW",
|
||||||
|
"CLREX",
|
||||||
|
"CLS",
|
||||||
|
"CLSW",
|
||||||
|
"CLZ",
|
||||||
|
"CLZW",
|
||||||
|
"CMN",
|
||||||
|
"CMNW",
|
||||||
|
"CMP",
|
||||||
|
"CMPW",
|
||||||
|
"CNEG",
|
||||||
|
"CNEGW",
|
||||||
|
"CRC32B",
|
||||||
|
"CRC32CB",
|
||||||
|
"CRC32CH",
|
||||||
|
"CRC32CW",
|
||||||
|
"CRC32CX",
|
||||||
|
"CRC32H",
|
||||||
|
"CRC32W",
|
||||||
|
"CRC32X",
|
||||||
|
"CSEL",
|
||||||
|
"CSELW",
|
||||||
|
"CSET",
|
||||||
|
"CSETM",
|
||||||
|
"CSETMW",
|
||||||
|
"CSETW",
|
||||||
|
"CSINC",
|
||||||
|
"CSINCW",
|
||||||
|
"CSINV",
|
||||||
|
"CSINVW",
|
||||||
|
"CSNEG",
|
||||||
|
"CSNEGW",
|
||||||
|
"DC",
|
||||||
|
"DCPS1",
|
||||||
|
"DCPS2",
|
||||||
|
"DCPS3",
|
||||||
|
"DMB",
|
||||||
|
"DRPS",
|
||||||
|
"DSB",
|
||||||
|
"EON",
|
||||||
|
"EONW",
|
||||||
|
"EOR",
|
||||||
|
"EORW",
|
||||||
|
"ERET",
|
||||||
|
"EXTR",
|
||||||
|
"EXTRW",
|
||||||
|
"HINT",
|
||||||
|
"HLT",
|
||||||
|
"HVC",
|
||||||
|
"IC",
|
||||||
|
"ISB",
|
||||||
|
"LDAR",
|
||||||
|
"LDARB",
|
||||||
|
"LDARH",
|
||||||
|
"LDARW",
|
||||||
|
"LDAXP",
|
||||||
|
"LDAXPW",
|
||||||
|
"LDAXR",
|
||||||
|
"LDAXRB",
|
||||||
|
"LDAXRH",
|
||||||
|
"LDAXRW",
|
||||||
|
"LDP",
|
||||||
|
"LDXR",
|
||||||
|
"LDXRB",
|
||||||
|
"LDXRH",
|
||||||
|
"LDXRW",
|
||||||
|
"LDXP",
|
||||||
|
"LDXPW",
|
||||||
|
"LSL",
|
||||||
|
"LSLW",
|
||||||
|
"LSR",
|
||||||
|
"LSRW",
|
||||||
|
"MADD",
|
||||||
|
"MADDW",
|
||||||
|
"MNEG",
|
||||||
|
"MNEGW",
|
||||||
|
"MOVK",
|
||||||
|
"MOVKW",
|
||||||
|
"MOVN",
|
||||||
|
"MOVNW",
|
||||||
|
"MOVZ",
|
||||||
|
"MOVZW",
|
||||||
|
"MRS",
|
||||||
|
"MSR",
|
||||||
|
"MSUB",
|
||||||
|
"MSUBW",
|
||||||
|
"MUL",
|
||||||
|
"MULW",
|
||||||
|
"MVN",
|
||||||
|
"MVNW",
|
||||||
|
"NEG",
|
||||||
|
"NEGS",
|
||||||
|
"NEGSW",
|
||||||
|
"NEGW",
|
||||||
|
"NGC",
|
||||||
|
"NGCS",
|
||||||
|
"NGCSW",
|
||||||
|
"NGCW",
|
||||||
|
"ORN",
|
||||||
|
"ORNW",
|
||||||
|
"ORR",
|
||||||
|
"ORRW",
|
||||||
|
"PRFM",
|
||||||
|
"PRFUM",
|
||||||
|
"RBIT",
|
||||||
|
"RBITW",
|
||||||
|
"REM",
|
||||||
|
"REMW",
|
||||||
|
"REV",
|
||||||
|
"REV16",
|
||||||
|
"REV16W",
|
||||||
|
"REV32",
|
||||||
|
"REVW",
|
||||||
|
"ROR",
|
||||||
|
"RORW",
|
||||||
|
"SBC",
|
||||||
|
"SBCS",
|
||||||
|
"SBCSW",
|
||||||
|
"SBCW",
|
||||||
|
"SBFIZ",
|
||||||
|
"SBFIZW",
|
||||||
|
"SBFM",
|
||||||
|
"SBFMW",
|
||||||
|
"SBFX",
|
||||||
|
"SBFXW",
|
||||||
|
"SDIV",
|
||||||
|
"SDIVW",
|
||||||
|
"SEV",
|
||||||
|
"SEVL",
|
||||||
|
"SMADDL",
|
||||||
|
"SMC",
|
||||||
|
"SMNEGL",
|
||||||
|
"SMSUBL",
|
||||||
|
"SMULH",
|
||||||
|
"SMULL",
|
||||||
|
"STXR",
|
||||||
|
"STXRB",
|
||||||
|
"STXRH",
|
||||||
|
"STXP",
|
||||||
|
"STXPW",
|
||||||
|
"STXRW",
|
||||||
|
"STLP",
|
||||||
|
"STLPW",
|
||||||
|
"STLR",
|
||||||
|
"STLRB",
|
||||||
|
"STLRH",
|
||||||
|
"STLRW",
|
||||||
|
"STLXP",
|
||||||
|
"STLXPW",
|
||||||
|
"STLXR",
|
||||||
|
"STLXRB",
|
||||||
|
"STLXRH",
|
||||||
|
"STLXRW",
|
||||||
|
"STP",
|
||||||
|
"SUB",
|
||||||
|
"SUBS",
|
||||||
|
"SUBSW",
|
||||||
|
"SUBW",
|
||||||
|
"SVC",
|
||||||
|
"SXTB",
|
||||||
|
"SXTBW",
|
||||||
|
"SXTH",
|
||||||
|
"SXTHW",
|
||||||
|
"SXTW",
|
||||||
|
"SYS",
|
||||||
|
"SYSL",
|
||||||
|
"TBNZ",
|
||||||
|
"TBZ",
|
||||||
|
"TLBI",
|
||||||
|
"TST",
|
||||||
|
"TSTW",
|
||||||
|
"UBFIZ",
|
||||||
|
"UBFIZW",
|
||||||
|
"UBFM",
|
||||||
|
"UBFMW",
|
||||||
|
"UBFX",
|
||||||
|
"UBFXW",
|
||||||
|
"UDIV",
|
||||||
|
"UDIVW",
|
||||||
|
"UMADDL",
|
||||||
|
"UMNEGL",
|
||||||
|
"UMSUBL",
|
||||||
|
"UMULH",
|
||||||
|
"UMULL",
|
||||||
|
"UREM",
|
||||||
|
"UREMW",
|
||||||
|
"UXTB",
|
||||||
|
"UXTH",
|
||||||
|
"UXTW",
|
||||||
|
"UXTBW",
|
||||||
|
"UXTHW",
|
||||||
|
"WFE",
|
||||||
|
"WFI",
|
||||||
|
"YIELD",
|
||||||
|
"MOVB",
|
||||||
|
"MOVBU",
|
||||||
|
"MOVH",
|
||||||
|
"MOVHU",
|
||||||
|
"MOVW",
|
||||||
|
"MOVWU",
|
||||||
|
"MOVD",
|
||||||
|
"MOVNP",
|
||||||
|
"MOVNPW",
|
||||||
|
"MOVP",
|
||||||
|
"MOVPD",
|
||||||
|
"MOVPQ",
|
||||||
|
"MOVPS",
|
||||||
|
"MOVPSW",
|
||||||
|
"MOVPW",
|
||||||
|
"BEQ",
|
||||||
|
"BNE",
|
||||||
|
"BCS",
|
||||||
|
"BHS",
|
||||||
|
"BCC",
|
||||||
|
"BLO",
|
||||||
|
"BMI",
|
||||||
|
"BPL",
|
||||||
|
"BVS",
|
||||||
|
"BVC",
|
||||||
|
"BHI",
|
||||||
|
"BLS",
|
||||||
|
"BGE",
|
||||||
|
"BLT",
|
||||||
|
"BGT",
|
||||||
|
"BLE",
|
||||||
|
"FABSD",
|
||||||
|
"FABSS",
|
||||||
|
"FADDD",
|
||||||
|
"FADDS",
|
||||||
|
"FCCMPD",
|
||||||
|
"FCCMPED",
|
||||||
|
"FCCMPS",
|
||||||
|
"FCCMPES",
|
||||||
|
"FCMPD",
|
||||||
|
"FCMPED",
|
||||||
|
"FCMPES",
|
||||||
|
"FCMPS",
|
||||||
|
"FCVTSD",
|
||||||
|
"FCVTDS",
|
||||||
|
"FCVTZSD",
|
||||||
|
"FCVTZSDW",
|
||||||
|
"FCVTZSS",
|
||||||
|
"FCVTZSSW",
|
||||||
|
"FCVTZUD",
|
||||||
|
"FCVTZUDW",
|
||||||
|
"FCVTZUS",
|
||||||
|
"FCVTZUSW",
|
||||||
|
"FDIVD",
|
||||||
|
"FDIVS",
|
||||||
|
"FMOVD",
|
||||||
|
"FMOVS",
|
||||||
|
"FMULD",
|
||||||
|
"FMULS",
|
||||||
|
"FNEGD",
|
||||||
|
"FNEGS",
|
||||||
|
"FSQRTD",
|
||||||
|
"FSQRTS",
|
||||||
|
"FSUBD",
|
||||||
|
"FSUBS",
|
||||||
|
"SCVTFD",
|
||||||
|
"SCVTFS",
|
||||||
|
"SCVTFWD",
|
||||||
|
"SCVTFWS",
|
||||||
|
"UCVTFD",
|
||||||
|
"UCVTFS",
|
||||||
|
"UCVTFWD",
|
||||||
|
"UCVTFWS",
|
||||||
|
"WORD",
|
||||||
|
"DWORD",
|
||||||
|
"FCSELS",
|
||||||
|
"FCSELD",
|
||||||
|
"FMAXS",
|
||||||
|
"FMINS",
|
||||||
|
"FMAXD",
|
||||||
|
"FMIND",
|
||||||
|
"FMAXNMS",
|
||||||
|
"FMAXNMD",
|
||||||
|
"FNMULS",
|
||||||
|
"FNMULD",
|
||||||
|
"FRINTNS",
|
||||||
|
"FRINTND",
|
||||||
|
"FRINTPS",
|
||||||
|
"FRINTPD",
|
||||||
|
"FRINTMS",
|
||||||
|
"FRINTMD",
|
||||||
|
"FRINTZS",
|
||||||
|
"FRINTZD",
|
||||||
|
"FRINTAS",
|
||||||
|
"FRINTAD",
|
||||||
|
"FRINTXS",
|
||||||
|
"FRINTXD",
|
||||||
|
"FRINTIS",
|
||||||
|
"FRINTID",
|
||||||
|
"FMADDS",
|
||||||
|
"FMADDD",
|
||||||
|
"FMSUBS",
|
||||||
|
"FMSUBD",
|
||||||
|
"FNMADDS",
|
||||||
|
"FNMADDD",
|
||||||
|
"FNMSUBS",
|
||||||
|
"FNMSUBD",
|
||||||
|
"FMINNMS",
|
||||||
|
"FMINNMD",
|
||||||
|
"FCVTDH",
|
||||||
|
"FCVTHS",
|
||||||
|
"FCVTHD",
|
||||||
|
"FCVTSH",
|
||||||
|
"AESD",
|
||||||
|
"AESE",
|
||||||
|
"AESIMC",
|
||||||
|
"AESMC",
|
||||||
|
"SHA1C",
|
||||||
|
"SHA1H",
|
||||||
|
"SHA1M",
|
||||||
|
"SHA1P",
|
||||||
|
"SHA1SU0",
|
||||||
|
"SHA1SU1",
|
||||||
|
"SHA256H",
|
||||||
|
"SHA256H2",
|
||||||
|
"SHA256SU0",
|
||||||
|
"SHA256SU1",
|
||||||
|
"LAST",
|
||||||
|
}
|
70
vendor/github.com/google/gops/internal/obj/arm64/anames7.go
generated
vendored
Normal file
70
vendor/github.com/google/gops/internal/obj/arm64/anames7.go
generated
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package arm64
|
||||||
|
|
||||||
|
var cnames7 = []string{
|
||||||
|
"NONE",
|
||||||
|
"REG",
|
||||||
|
"RSP",
|
||||||
|
"FREG",
|
||||||
|
"VREG",
|
||||||
|
"PAIR",
|
||||||
|
"SHIFT",
|
||||||
|
"EXTREG",
|
||||||
|
"SPR",
|
||||||
|
"COND",
|
||||||
|
"ZCON",
|
||||||
|
"ADDCON0",
|
||||||
|
"ADDCON",
|
||||||
|
"MOVCON",
|
||||||
|
"BITCON",
|
||||||
|
"ABCON0",
|
||||||
|
"ABCON",
|
||||||
|
"MBCON",
|
||||||
|
"LCON",
|
||||||
|
"VCON",
|
||||||
|
"FCON",
|
||||||
|
"VCONADDR",
|
||||||
|
"AACON",
|
||||||
|
"LACON",
|
||||||
|
"AECON",
|
||||||
|
"SBRA",
|
||||||
|
"LBRA",
|
||||||
|
"NPAUTO",
|
||||||
|
"NSAUTO",
|
||||||
|
"PSAUTO",
|
||||||
|
"PPAUTO",
|
||||||
|
"UAUTO4K",
|
||||||
|
"UAUTO8K",
|
||||||
|
"UAUTO16K",
|
||||||
|
"UAUTO32K",
|
||||||
|
"UAUTO64K",
|
||||||
|
"LAUTO",
|
||||||
|
"SEXT1",
|
||||||
|
"SEXT2",
|
||||||
|
"SEXT4",
|
||||||
|
"SEXT8",
|
||||||
|
"SEXT16",
|
||||||
|
"LEXT",
|
||||||
|
"ZOREG",
|
||||||
|
"NPOREG",
|
||||||
|
"NSOREG",
|
||||||
|
"PSOREG",
|
||||||
|
"PPOREG",
|
||||||
|
"UOREG4K",
|
||||||
|
"UOREG8K",
|
||||||
|
"UOREG16K",
|
||||||
|
"UOREG32K",
|
||||||
|
"UOREG64K",
|
||||||
|
"LOREG",
|
||||||
|
"ADDR",
|
||||||
|
"GOTADDR",
|
||||||
|
"TLS_LE",
|
||||||
|
"TLS_IE",
|
||||||
|
"ROFF",
|
||||||
|
"GOK",
|
||||||
|
"TEXTSIZE",
|
||||||
|
"NCLASS",
|
||||||
|
}
|
4374
vendor/github.com/google/gops/internal/obj/arm64/asm7.go
generated
vendored
Normal file
4374
vendor/github.com/google/gops/internal/obj/arm64/asm7.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
115
vendor/github.com/google/gops/internal/obj/arm64/list7.go
generated
vendored
Normal file
115
vendor/github.com/google/gops/internal/obj/arm64/list7.go
generated
vendored
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// cmd/7l/list.c and cmd/7l/sub.c from Vita Nuova.
|
||||||
|
// https://code.google.com/p/ken-cc/source/browse/
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package arm64
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gops/internal/obj"
|
||||||
|
)
|
||||||
|
|
||||||
|
var strcond = [16]string{
|
||||||
|
"EQ",
|
||||||
|
"NE",
|
||||||
|
"HS",
|
||||||
|
"LO",
|
||||||
|
"MI",
|
||||||
|
"PL",
|
||||||
|
"VS",
|
||||||
|
"VC",
|
||||||
|
"HI",
|
||||||
|
"LS",
|
||||||
|
"GE",
|
||||||
|
"LT",
|
||||||
|
"GT",
|
||||||
|
"LE",
|
||||||
|
"AL",
|
||||||
|
"NV",
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
obj.RegisterRegister(obj.RBaseARM64, REG_SPECIAL+1024, Rconv)
|
||||||
|
obj.RegisterOpcode(obj.ABaseARM64, Anames)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Rconv(r int) string {
|
||||||
|
if r == REGG {
|
||||||
|
return "g"
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case REG_R0 <= r && r <= REG_R30:
|
||||||
|
return fmt.Sprintf("R%d", r-REG_R0)
|
||||||
|
case r == REG_R31:
|
||||||
|
return "ZR"
|
||||||
|
case REG_F0 <= r && r <= REG_F31:
|
||||||
|
return fmt.Sprintf("F%d", r-REG_F0)
|
||||||
|
case REG_V0 <= r && r <= REG_V31:
|
||||||
|
return fmt.Sprintf("V%d", r-REG_V0)
|
||||||
|
case COND_EQ <= r && r <= COND_NV:
|
||||||
|
return strcond[r-COND_EQ]
|
||||||
|
case r == REGSP:
|
||||||
|
return "RSP"
|
||||||
|
case r == REG_DAIF:
|
||||||
|
return "DAIF"
|
||||||
|
case r == REG_NZCV:
|
||||||
|
return "NZCV"
|
||||||
|
case r == REG_FPSR:
|
||||||
|
return "FPSR"
|
||||||
|
case r == REG_FPCR:
|
||||||
|
return "FPCR"
|
||||||
|
case r == REG_SPSR_EL1:
|
||||||
|
return "SPSR_EL1"
|
||||||
|
case r == REG_ELR_EL1:
|
||||||
|
return "ELR_EL1"
|
||||||
|
case r == REG_SPSR_EL2:
|
||||||
|
return "SPSR_EL2"
|
||||||
|
case r == REG_ELR_EL2:
|
||||||
|
return "ELR_EL2"
|
||||||
|
case r == REG_CurrentEL:
|
||||||
|
return "CurrentEL"
|
||||||
|
case r == REG_SP_EL0:
|
||||||
|
return "SP_EL0"
|
||||||
|
case r == REG_SPSel:
|
||||||
|
return "SPSel"
|
||||||
|
case r == REG_DAIFSet:
|
||||||
|
return "DAIFSet"
|
||||||
|
case r == REG_DAIFClr:
|
||||||
|
return "DAIFClr"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("badreg(%d)", r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DRconv(a int) string {
|
||||||
|
if a >= C_NONE && a <= C_NCLASS {
|
||||||
|
return cnames7[a]
|
||||||
|
}
|
||||||
|
return "C_??"
|
||||||
|
}
|
1005
vendor/github.com/google/gops/internal/obj/arm64/obj7.go
generated
vendored
Normal file
1005
vendor/github.com/google/gops/internal/obj/arm64/obj7.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
190
vendor/github.com/google/gops/internal/obj/data.go
generated
vendored
Normal file
190
vendor/github.com/google/gops/internal/obj/data.go
generated
vendored
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
|
||||||
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c
|
||||||
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Grow increases the length of s.P to lsiz.
|
||||||
|
func (s *LSym) Grow(lsiz int64) {
|
||||||
|
siz := int(lsiz)
|
||||||
|
if int64(siz) != lsiz {
|
||||||
|
log.Fatalf("LSym.Grow size %d too long", lsiz)
|
||||||
|
}
|
||||||
|
if len(s.P) >= siz {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// TODO(dfc) append cap-len at once, rather than
|
||||||
|
// one byte at a time.
|
||||||
|
for cap(s.P) < siz {
|
||||||
|
s.P = append(s.P[:cap(s.P)], 0)
|
||||||
|
}
|
||||||
|
s.P = s.P[:siz]
|
||||||
|
}
|
||||||
|
|
||||||
|
// GrowCap increases the capacity of s.P to c.
|
||||||
|
func (s *LSym) GrowCap(c int64) {
|
||||||
|
if int64(cap(s.P)) >= c {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if s.P == nil {
|
||||||
|
s.P = make([]byte, 0, c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b := make([]byte, len(s.P), c)
|
||||||
|
copy(b, s.P)
|
||||||
|
s.P = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepwrite prepares to write data of size siz into s at offset off.
|
||||||
|
func (s *LSym) prepwrite(ctxt *Link, off int64, siz int) {
|
||||||
|
if off < 0 || siz < 0 || off >= 1<<30 {
|
||||||
|
log.Fatalf("prepwrite: bad off=%d siz=%d", off, siz)
|
||||||
|
}
|
||||||
|
if s.Type == SBSS || s.Type == STLSBSS {
|
||||||
|
ctxt.Diag("cannot supply data for BSS var")
|
||||||
|
}
|
||||||
|
l := off + int64(siz)
|
||||||
|
s.Grow(l)
|
||||||
|
if l > s.Size {
|
||||||
|
s.Size = l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteFloat32 writes f into s at offset off.
|
||||||
|
func (s *LSym) WriteFloat32(ctxt *Link, off int64, f float32) {
|
||||||
|
s.prepwrite(ctxt, off, 4)
|
||||||
|
ctxt.Arch.ByteOrder.PutUint32(s.P[off:], math.Float32bits(f))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteFloat64 writes f into s at offset off.
|
||||||
|
func (s *LSym) WriteFloat64(ctxt *Link, off int64, f float64) {
|
||||||
|
s.prepwrite(ctxt, off, 8)
|
||||||
|
ctxt.Arch.ByteOrder.PutUint64(s.P[off:], math.Float64bits(f))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteInt writes an integer i of size siz into s at offset off.
|
||||||
|
func (s *LSym) WriteInt(ctxt *Link, off int64, siz int, i int64) {
|
||||||
|
s.prepwrite(ctxt, off, siz)
|
||||||
|
switch siz {
|
||||||
|
default:
|
||||||
|
ctxt.Diag("WriteInt: bad integer size: %d", siz)
|
||||||
|
case 1:
|
||||||
|
s.P[off] = byte(i)
|
||||||
|
case 2:
|
||||||
|
ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(i))
|
||||||
|
case 4:
|
||||||
|
ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(i))
|
||||||
|
case 8:
|
||||||
|
ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteAddr writes an address of size siz into s at offset off.
|
||||||
|
// rsym and roff specify the relocation for the address.
|
||||||
|
func (s *LSym) WriteAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) {
|
||||||
|
if siz != ctxt.Arch.PtrSize {
|
||||||
|
ctxt.Diag("WriteAddr: bad address size %d in %s", siz, s.Name)
|
||||||
|
}
|
||||||
|
s.prepwrite(ctxt, off, siz)
|
||||||
|
r := Addrel(s)
|
||||||
|
r.Off = int32(off)
|
||||||
|
if int64(r.Off) != off {
|
||||||
|
ctxt.Diag("WriteAddr: off overflow %d in %s", off, s.Name)
|
||||||
|
}
|
||||||
|
r.Siz = uint8(siz)
|
||||||
|
r.Sym = rsym
|
||||||
|
r.Type = R_ADDR
|
||||||
|
r.Add = roff
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteOff writes a 4 byte offset to rsym+roff into s at offset off.
|
||||||
|
// After linking the 4 bytes stored at s+off will be
|
||||||
|
// rsym+roff-(start of section that s is in).
|
||||||
|
func (s *LSym) WriteOff(ctxt *Link, off int64, rsym *LSym, roff int64) {
|
||||||
|
s.prepwrite(ctxt, off, 4)
|
||||||
|
r := Addrel(s)
|
||||||
|
r.Off = int32(off)
|
||||||
|
if int64(r.Off) != off {
|
||||||
|
ctxt.Diag("WriteOff: off overflow %d in %s", off, s.Name)
|
||||||
|
}
|
||||||
|
r.Siz = 4
|
||||||
|
r.Sym = rsym
|
||||||
|
r.Type = R_ADDROFF
|
||||||
|
r.Add = roff
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteString writes a string of size siz into s at offset off.
|
||||||
|
func (s *LSym) WriteString(ctxt *Link, off int64, siz int, str string) {
|
||||||
|
if siz < len(str) {
|
||||||
|
ctxt.Diag("WriteString: bad string size: %d < %d", siz, len(str))
|
||||||
|
}
|
||||||
|
s.prepwrite(ctxt, off, siz)
|
||||||
|
copy(s.P[off:off+int64(siz)], str)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteBytes writes a slice of bytes into s at offset off.
|
||||||
|
func (s *LSym) WriteBytes(ctxt *Link, off int64, b []byte) int64 {
|
||||||
|
s.prepwrite(ctxt, off, len(b))
|
||||||
|
copy(s.P[off:], b)
|
||||||
|
return off + int64(len(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Addrel(s *LSym) *Reloc {
|
||||||
|
s.R = append(s.R, Reloc{})
|
||||||
|
return &s.R[len(s.R)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 {
|
||||||
|
if s.Type == 0 {
|
||||||
|
s.Type = SDATA
|
||||||
|
}
|
||||||
|
if s.Size < off+wid {
|
||||||
|
s.Size = off + wid
|
||||||
|
s.Grow(s.Size)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch wid {
|
||||||
|
case 1:
|
||||||
|
s.P[off] = uint8(v)
|
||||||
|
case 2:
|
||||||
|
ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(v))
|
||||||
|
case 4:
|
||||||
|
ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(v))
|
||||||
|
case 8:
|
||||||
|
ctxt.Arch.ByteOrder.PutUint64(s.P[off:], v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return off + wid
|
||||||
|
}
|
115
vendor/github.com/google/gops/internal/obj/flag.go
generated
vendored
Normal file
115
vendor/github.com/google/gops/internal/obj/flag.go
generated
vendored
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Flagfn2(string, string, func(string, string)) { panic("flag") }
|
||||||
|
|
||||||
|
func Flagcount(name, usage string, val *int) {
|
||||||
|
flag.Var((*count)(val), name, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Flagint32(name, usage string, val *int32) {
|
||||||
|
flag.Var((*int32Value)(val), name, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Flagint64(name, usage string, val *int64) {
|
||||||
|
flag.Int64Var(val, name, *val, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Flagstr(name, usage string, val *string) {
|
||||||
|
flag.StringVar(val, name, *val, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Flagfn0(name, usage string, f func()) {
|
||||||
|
flag.Var(fn0(f), name, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Flagfn1(name, usage string, f func(string)) {
|
||||||
|
flag.Var(fn1(f), name, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Flagprint(fd int) {
|
||||||
|
if fd == 1 {
|
||||||
|
flag.CommandLine.SetOutput(os.Stdout)
|
||||||
|
}
|
||||||
|
flag.PrintDefaults()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Flagparse(usage func()) {
|
||||||
|
flag.Usage = usage
|
||||||
|
flag.Parse()
|
||||||
|
}
|
||||||
|
|
||||||
|
// count is a flag.Value that is like a flag.Bool and a flag.Int.
|
||||||
|
// If used as -name, it increments the count, but -name=x sets the count.
|
||||||
|
// Used for verbose flag -v.
|
||||||
|
type count int
|
||||||
|
|
||||||
|
func (c *count) String() string {
|
||||||
|
return fmt.Sprint(int(*c))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *count) Set(s string) error {
|
||||||
|
switch s {
|
||||||
|
case "true":
|
||||||
|
*c++
|
||||||
|
case "false":
|
||||||
|
*c = 0
|
||||||
|
default:
|
||||||
|
n, err := strconv.Atoi(s)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid count %q", s)
|
||||||
|
}
|
||||||
|
*c = count(n)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *count) IsBoolFlag() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
type int32Value int32
|
||||||
|
|
||||||
|
func (i *int32Value) Set(s string) error {
|
||||||
|
v, err := strconv.ParseInt(s, 0, 64)
|
||||||
|
*i = int32Value(v)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *int32Value) Get() interface{} { return int32(*i) }
|
||||||
|
|
||||||
|
func (i *int32Value) String() string { return fmt.Sprint(*i) }
|
||||||
|
|
||||||
|
type fn0 func()
|
||||||
|
|
||||||
|
func (f fn0) Set(s string) error {
|
||||||
|
f()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f fn0) Get() interface{} { return nil }
|
||||||
|
|
||||||
|
func (f fn0) String() string { return "" }
|
||||||
|
|
||||||
|
func (f fn0) IsBoolFlag() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
type fn1 func(string)
|
||||||
|
|
||||||
|
func (f fn1) Set(s string) error {
|
||||||
|
f(s)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f fn1) String() string { return "" }
|
48
vendor/github.com/google/gops/internal/obj/funcdata.go
generated
vendored
Normal file
48
vendor/github.com/google/gops/internal/obj/funcdata.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
// This file defines the IDs for PCDATA and FUNCDATA instructions
|
||||||
|
// in Go binaries. It is included by assembly sources, so it must
|
||||||
|
// be written using #defines.
|
||||||
|
//
|
||||||
|
// The Go compiler also #includes this file, for now.
|
||||||
|
//
|
||||||
|
// symtab.go also contains a copy of these constants.
|
||||||
|
|
||||||
|
// Pseudo-assembly statements.
|
||||||
|
|
||||||
|
// GO_ARGS, GO_RESULTS_INITIALIZED, and NO_LOCAL_POINTERS are macros
|
||||||
|
// that communicate to the runtime information about the location and liveness
|
||||||
|
// of pointers in an assembly function's arguments, results, and stack frame.
|
||||||
|
// This communication is only required in assembly functions that make calls
|
||||||
|
// to other functions that might be preempted or grow the stack.
|
||||||
|
// NOSPLIT functions that make no calls do not need to use these macros.
|
||||||
|
|
||||||
|
// GO_ARGS indicates that the Go prototype for this assembly function
|
||||||
|
// defines the pointer map for the function's arguments.
|
||||||
|
// GO_ARGS should be the first instruction in a function that uses it.
|
||||||
|
// It can be omitted if there are no arguments at all.
|
||||||
|
// GO_ARGS is inserted implicitly by the linker for any function
|
||||||
|
// that also has a Go prototype and therefore is usually not necessary
|
||||||
|
// to write explicitly.
|
||||||
|
|
||||||
|
// GO_RESULTS_INITIALIZED indicates that the assembly function
|
||||||
|
// has initialized the stack space for its results and that those results
|
||||||
|
// should be considered live for the remainder of the function.
|
||||||
|
|
||||||
|
// NO_LOCAL_POINTERS indicates that the assembly function stores
|
||||||
|
// no pointers to heap objects in its local stack variables.
|
||||||
|
|
||||||
|
// ArgsSizeUnknown is set in Func.argsize to mark all functions
|
||||||
|
// whose argument size is unknown (C vararg functions, and
|
||||||
|
// assembly code without an explicit specification).
|
||||||
|
// This value is generated by the compiler, assembler, or linker.
|
||||||
|
const (
|
||||||
|
PCDATA_StackMapIndex = 0
|
||||||
|
FUNCDATA_ArgsPointerMaps = 0
|
||||||
|
FUNCDATA_LocalsPointerMaps = 1
|
||||||
|
ArgsSizeUnknown = -0x80000000
|
||||||
|
)
|
86
vendor/github.com/google/gops/internal/obj/go.go
generated
vendored
Normal file
86
vendor/github.com/google/gops/internal/obj/go.go
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// go-specific code shared across loaders (5l, 6l, 8l).
|
||||||
|
|
||||||
|
var (
|
||||||
|
framepointer_enabled int
|
||||||
|
Fieldtrack_enabled int
|
||||||
|
)
|
||||||
|
|
||||||
|
// Toolchain experiments.
|
||||||
|
// These are controlled by the GOEXPERIMENT environment
|
||||||
|
// variable recorded when the toolchain is built.
|
||||||
|
// This list is also known to cmd/gc.
|
||||||
|
var exper = []struct {
|
||||||
|
name string
|
||||||
|
val *int
|
||||||
|
}{
|
||||||
|
{"fieldtrack", &Fieldtrack_enabled},
|
||||||
|
{"framepointer", &framepointer_enabled},
|
||||||
|
}
|
||||||
|
|
||||||
|
func addexp(s string) {
|
||||||
|
// Could do general integer parsing here, but the runtime copy doesn't yet.
|
||||||
|
v := 1
|
||||||
|
name := s
|
||||||
|
if len(name) > 2 && name[:2] == "no" {
|
||||||
|
v = 0
|
||||||
|
name = name[2:]
|
||||||
|
}
|
||||||
|
for i := 0; i < len(exper); i++ {
|
||||||
|
if exper[i].name == name {
|
||||||
|
if exper[i].val != nil {
|
||||||
|
*exper[i].val = v
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("unknown experiment %s\n", s)
|
||||||
|
os.Exit(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
framepointer_enabled = 1 // default
|
||||||
|
for _, f := range strings.Split(goexperiment, ",") {
|
||||||
|
if f != "" {
|
||||||
|
addexp(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Framepointer_enabled(goos, goarch string) bool {
|
||||||
|
return framepointer_enabled != 0 && goarch == "amd64" && goos != "nacl"
|
||||||
|
}
|
||||||
|
|
||||||
|
func Nopout(p *Prog) {
|
||||||
|
p.As = ANOP
|
||||||
|
p.Scond = 0
|
||||||
|
p.From = Addr{}
|
||||||
|
p.From3 = nil
|
||||||
|
p.Reg = 0
|
||||||
|
p.To = Addr{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Expstring() string {
|
||||||
|
buf := "X"
|
||||||
|
for i := range exper {
|
||||||
|
if *exper[i].val != 0 {
|
||||||
|
buf += "," + exper[i].name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buf == "X" {
|
||||||
|
buf += ",none"
|
||||||
|
}
|
||||||
|
return "X:" + buf[2:]
|
||||||
|
}
|
92
vendor/github.com/google/gops/internal/obj/ld.go
generated
vendored
Normal file
92
vendor/github.com/google/gops/internal/obj/ld.go
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
|
||||||
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c
|
||||||
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add library to library list.
|
||||||
|
* srcref: src file referring to package
|
||||||
|
* objref: object file referring to package
|
||||||
|
* file: object file, e.g., /home/rsc/go/pkg/container/vector.a
|
||||||
|
* pkg: package import path, e.g. container/vector
|
||||||
|
*/
|
||||||
|
|
||||||
|
const (
|
||||||
|
LOG = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
func mkfwd(sym *LSym) {
|
||||||
|
var dwn [LOG]int32
|
||||||
|
var cnt [LOG]int32
|
||||||
|
var lst [LOG]*Prog
|
||||||
|
|
||||||
|
for i := 0; i < LOG; i++ {
|
||||||
|
if i == 0 {
|
||||||
|
cnt[i] = 1
|
||||||
|
} else {
|
||||||
|
cnt[i] = LOG * cnt[i-1]
|
||||||
|
}
|
||||||
|
dwn[i] = 1
|
||||||
|
lst[i] = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for p := sym.Text; p != nil && p.Link != nil; p = p.Link {
|
||||||
|
i--
|
||||||
|
if i < 0 {
|
||||||
|
i = LOG - 1
|
||||||
|
}
|
||||||
|
p.Forwd = nil
|
||||||
|
dwn[i]--
|
||||||
|
if dwn[i] <= 0 {
|
||||||
|
dwn[i] = cnt[i]
|
||||||
|
if lst[i] != nil {
|
||||||
|
lst[i].Forwd = p
|
||||||
|
}
|
||||||
|
lst[i] = p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Copyp(ctxt *Link, q *Prog) *Prog {
|
||||||
|
p := ctxt.NewProg()
|
||||||
|
*p = *q
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func Appendp(ctxt *Link, q *Prog) *Prog {
|
||||||
|
p := ctxt.NewProg()
|
||||||
|
p.Link = q.Link
|
||||||
|
q.Link = p
|
||||||
|
p.Lineno = q.Lineno
|
||||||
|
p.Mode = q.Mode
|
||||||
|
return p
|
||||||
|
}
|
974
vendor/github.com/google/gops/internal/obj/link.go
generated
vendored
Normal file
974
vendor/github.com/google/gops/internal/obj/link.go
generated
vendored
Normal file
@ -0,0 +1,974 @@
|
|||||||
|
// Derived from Inferno utils/6l/l.h and related files.
|
||||||
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gops/internal/sys"
|
||||||
|
)
|
||||||
|
|
||||||
|
// An Addr is an argument to an instruction.
|
||||||
|
// The general forms and their encodings are:
|
||||||
|
//
|
||||||
|
// sym±offset(symkind)(reg)(index*scale)
|
||||||
|
// Memory reference at address &sym(symkind) + offset + reg + index*scale.
|
||||||
|
// Any of sym(symkind), ±offset, (reg), (index*scale), and *scale can be omitted.
|
||||||
|
// If (reg) and *scale are both omitted, the resulting expression (index) is parsed as (reg).
|
||||||
|
// To force a parsing as index*scale, write (index*1).
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_MEM
|
||||||
|
// name = symkind (NAME_AUTO, ...) or 0 (NAME_NONE)
|
||||||
|
// sym = sym
|
||||||
|
// offset = ±offset
|
||||||
|
// reg = reg (REG_*)
|
||||||
|
// index = index (REG_*)
|
||||||
|
// scale = scale (1, 2, 4, 8)
|
||||||
|
//
|
||||||
|
// $<mem>
|
||||||
|
// Effective address of memory reference <mem>, defined above.
|
||||||
|
// Encoding: same as memory reference, but type = TYPE_ADDR.
|
||||||
|
//
|
||||||
|
// $<±integer value>
|
||||||
|
// This is a special case of $<mem>, in which only ±offset is present.
|
||||||
|
// It has a separate type for easy recognition.
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_CONST
|
||||||
|
// offset = ±integer value
|
||||||
|
//
|
||||||
|
// *<mem>
|
||||||
|
// Indirect reference through memory reference <mem>, defined above.
|
||||||
|
// Only used on x86 for CALL/JMP *sym(SB), which calls/jumps to a function
|
||||||
|
// pointer stored in the data word sym(SB), not a function named sym(SB).
|
||||||
|
// Encoding: same as above, but type = TYPE_INDIR.
|
||||||
|
//
|
||||||
|
// $*$<mem>
|
||||||
|
// No longer used.
|
||||||
|
// On machines with actual SB registers, $*$<mem> forced the
|
||||||
|
// instruction encoding to use a full 32-bit constant, never a
|
||||||
|
// reference relative to SB.
|
||||||
|
//
|
||||||
|
// $<floating point literal>
|
||||||
|
// Floating point constant value.
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_FCONST
|
||||||
|
// val = floating point value
|
||||||
|
//
|
||||||
|
// $<string literal, up to 8 chars>
|
||||||
|
// String literal value (raw bytes used for DATA instruction).
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_SCONST
|
||||||
|
// val = string
|
||||||
|
//
|
||||||
|
// <register name>
|
||||||
|
// Any register: integer, floating point, control, segment, and so on.
|
||||||
|
// If looking for specific register kind, must check type and reg value range.
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_REG
|
||||||
|
// reg = reg (REG_*)
|
||||||
|
//
|
||||||
|
// x(PC)
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_BRANCH
|
||||||
|
// val = Prog* reference OR ELSE offset = target pc (branch takes priority)
|
||||||
|
//
|
||||||
|
// $±x-±y
|
||||||
|
// Final argument to TEXT, specifying local frame size x and argument size y.
|
||||||
|
// In this form, x and y are integer literals only, not arbitrary expressions.
|
||||||
|
// This avoids parsing ambiguities due to the use of - as a separator.
|
||||||
|
// The ± are optional.
|
||||||
|
// If the final argument to TEXT omits the -±y, the encoding should still
|
||||||
|
// use TYPE_TEXTSIZE (not TYPE_CONST), with u.argsize = ArgsSizeUnknown.
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_TEXTSIZE
|
||||||
|
// offset = x
|
||||||
|
// val = int32(y)
|
||||||
|
//
|
||||||
|
// reg<<shift, reg>>shift, reg->shift, reg@>shift
|
||||||
|
// Shifted register value, for ARM and ARM64.
|
||||||
|
// In this form, reg must be a register and shift can be a register or an integer constant.
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_SHIFT
|
||||||
|
// On ARM:
|
||||||
|
// offset = (reg&15) | shifttype<<5 | count
|
||||||
|
// shifttype = 0, 1, 2, 3 for <<, >>, ->, @>
|
||||||
|
// count = (reg&15)<<8 | 1<<4 for a register shift count, (n&31)<<7 for an integer constant.
|
||||||
|
// On ARM64:
|
||||||
|
// offset = (reg&31)<<16 | shifttype<<22 | (count&63)<<10
|
||||||
|
// shifttype = 0, 1, 2 for <<, >>, ->
|
||||||
|
//
|
||||||
|
// (reg, reg)
|
||||||
|
// A destination register pair. When used as the last argument of an instruction,
|
||||||
|
// this form makes clear that both registers are destinations.
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_REGREG
|
||||||
|
// reg = first register
|
||||||
|
// offset = second register
|
||||||
|
//
|
||||||
|
// [reg, reg, reg-reg]
|
||||||
|
// Register list for ARM.
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_REGLIST
|
||||||
|
// offset = bit mask of registers in list; R0 is low bit.
|
||||||
|
//
|
||||||
|
// reg, reg
|
||||||
|
// Register pair for ARM.
|
||||||
|
// TYPE_REGREG2
|
||||||
|
//
|
||||||
|
// (reg+reg)
|
||||||
|
// Register pair for PPC64.
|
||||||
|
// Encoding:
|
||||||
|
// type = TYPE_MEM
|
||||||
|
// reg = first register
|
||||||
|
// index = second register
|
||||||
|
// scale = 1
|
||||||
|
//
|
||||||
|
type Addr struct {
|
||||||
|
Reg int16
|
||||||
|
Index int16
|
||||||
|
Scale int16 // Sometimes holds a register.
|
||||||
|
Type AddrType
|
||||||
|
Name int8
|
||||||
|
Class int8
|
||||||
|
Offset int64
|
||||||
|
Sym *LSym
|
||||||
|
|
||||||
|
// argument value:
|
||||||
|
// for TYPE_SCONST, a string
|
||||||
|
// for TYPE_FCONST, a float64
|
||||||
|
// for TYPE_BRANCH, a *Prog (optional)
|
||||||
|
// for TYPE_TEXTSIZE, an int32 (optional)
|
||||||
|
Val interface{}
|
||||||
|
|
||||||
|
Node interface{} // for use by compiler
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddrType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
NAME_NONE = 0 + iota
|
||||||
|
NAME_EXTERN
|
||||||
|
NAME_STATIC
|
||||||
|
NAME_AUTO
|
||||||
|
NAME_PARAM
|
||||||
|
// A reference to name@GOT(SB) is a reference to the entry in the global offset
|
||||||
|
// table for 'name'.
|
||||||
|
NAME_GOTREF
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
TYPE_NONE AddrType = 0
|
||||||
|
|
||||||
|
TYPE_BRANCH AddrType = 5 + iota
|
||||||
|
TYPE_TEXTSIZE
|
||||||
|
TYPE_MEM
|
||||||
|
TYPE_CONST
|
||||||
|
TYPE_FCONST
|
||||||
|
TYPE_SCONST
|
||||||
|
TYPE_REG
|
||||||
|
TYPE_ADDR
|
||||||
|
TYPE_SHIFT
|
||||||
|
TYPE_REGREG
|
||||||
|
TYPE_REGREG2
|
||||||
|
TYPE_INDIR
|
||||||
|
TYPE_REGLIST
|
||||||
|
)
|
||||||
|
|
||||||
|
// Prog describes a single machine instruction.
|
||||||
|
//
|
||||||
|
// The general instruction form is:
|
||||||
|
//
|
||||||
|
// As.Scond From, Reg, From3, To, RegTo2
|
||||||
|
//
|
||||||
|
// where As is an opcode and the others are arguments:
|
||||||
|
// From, Reg, From3 are sources, and To, RegTo2 are destinations.
|
||||||
|
// Usually, not all arguments are present.
|
||||||
|
// For example, MOVL R1, R2 encodes using only As=MOVL, From=R1, To=R2.
|
||||||
|
// The Scond field holds additional condition bits for systems (like arm)
|
||||||
|
// that have generalized conditional execution.
|
||||||
|
//
|
||||||
|
// Jump instructions use the Pcond field to point to the target instruction,
|
||||||
|
// which must be in the same linked list as the jump instruction.
|
||||||
|
//
|
||||||
|
// The Progs for a given function are arranged in a list linked through the Link field.
|
||||||
|
//
|
||||||
|
// Each Prog is charged to a specific source line in the debug information,
|
||||||
|
// specified by Lineno, an index into the line history (see LineHist).
|
||||||
|
// Every Prog has a Ctxt field that defines various context, including the current LineHist.
|
||||||
|
// Progs should be allocated using ctxt.NewProg(), not new(Prog).
|
||||||
|
//
|
||||||
|
// The other fields not yet mentioned are for use by the back ends and should
|
||||||
|
// be left zeroed by creators of Prog lists.
|
||||||
|
type Prog struct {
|
||||||
|
Ctxt *Link // linker context
|
||||||
|
Link *Prog // next Prog in linked list
|
||||||
|
From Addr // first source operand
|
||||||
|
From3 *Addr // third source operand (second is Reg below)
|
||||||
|
To Addr // destination operand (second is RegTo2 below)
|
||||||
|
Pcond *Prog // target of conditional jump
|
||||||
|
Opt interface{} // available to optimization passes to hold per-Prog state
|
||||||
|
Forwd *Prog // for x86 back end
|
||||||
|
Rel *Prog // for x86, arm back ends
|
||||||
|
Pc int64 // for back ends or assembler: virtual or actual program counter, depending on phase
|
||||||
|
Lineno int32 // line number of this instruction
|
||||||
|
Spadj int32 // effect of instruction on stack pointer (increment or decrement amount)
|
||||||
|
As As // assembler opcode
|
||||||
|
Reg int16 // 2nd source operand
|
||||||
|
RegTo2 int16 // 2nd destination operand
|
||||||
|
Mark uint16 // bitmask of arch-specific items
|
||||||
|
Optab uint16 // arch-specific opcode index
|
||||||
|
Scond uint8 // condition bits for conditional instruction (e.g., on ARM)
|
||||||
|
Back uint8 // for x86 back end: backwards branch state
|
||||||
|
Ft uint8 // for x86 back end: type index of Prog.From
|
||||||
|
Tt uint8 // for x86 back end: type index of Prog.To
|
||||||
|
Isize uint8 // for x86 back end: size of the instruction in bytes
|
||||||
|
Mode int8 // for x86 back end: 32- or 64-bit mode
|
||||||
|
}
|
||||||
|
|
||||||
|
// From3Type returns From3.Type, or TYPE_NONE when From3 is nil.
|
||||||
|
func (p *Prog) From3Type() AddrType {
|
||||||
|
if p.From3 == nil {
|
||||||
|
return TYPE_NONE
|
||||||
|
}
|
||||||
|
return p.From3.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
// From3Offset returns From3.Offset, or 0 when From3 is nil.
|
||||||
|
func (p *Prog) From3Offset() int64 {
|
||||||
|
if p.From3 == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return p.From3.Offset
|
||||||
|
}
|
||||||
|
|
||||||
|
// An As denotes an assembler opcode.
|
||||||
|
// There are some portable opcodes, declared here in package obj,
|
||||||
|
// that are common to all architectures.
|
||||||
|
// However, the majority of opcodes are arch-specific
|
||||||
|
// and are declared in their respective architecture's subpackage.
|
||||||
|
type As int16
|
||||||
|
|
||||||
|
// These are the portable opcodes.
|
||||||
|
const (
|
||||||
|
AXXX As = iota
|
||||||
|
ACALL
|
||||||
|
ADUFFCOPY
|
||||||
|
ADUFFZERO
|
||||||
|
AEND
|
||||||
|
AFUNCDATA
|
||||||
|
AJMP
|
||||||
|
ANOP
|
||||||
|
APCDATA
|
||||||
|
ARET
|
||||||
|
ATEXT
|
||||||
|
ATYPE
|
||||||
|
AUNDEF
|
||||||
|
AUSEFIELD
|
||||||
|
AVARDEF
|
||||||
|
AVARKILL
|
||||||
|
AVARLIVE
|
||||||
|
A_ARCHSPECIFIC
|
||||||
|
)
|
||||||
|
|
||||||
|
// Each architecture is allotted a distinct subspace of opcode values
|
||||||
|
// for declaring its arch-specific opcodes.
|
||||||
|
// Within this subspace, the first arch-specific opcode should be
|
||||||
|
// at offset A_ARCHSPECIFIC.
|
||||||
|
//
|
||||||
|
// Subspaces are aligned to a power of two so opcodes can be masked
|
||||||
|
// with AMask and used as compact array indices.
|
||||||
|
const (
|
||||||
|
ABase386 = (1 + iota) << 10
|
||||||
|
ABaseARM
|
||||||
|
ABaseAMD64
|
||||||
|
ABasePPC64
|
||||||
|
ABaseARM64
|
||||||
|
ABaseMIPS64
|
||||||
|
ABaseS390X
|
||||||
|
|
||||||
|
AllowedOpCodes = 1 << 10 // The number of opcodes available for any given architecture.
|
||||||
|
AMask = AllowedOpCodes - 1 // AND with this to use the opcode as an array index.
|
||||||
|
)
|
||||||
|
|
||||||
|
// An LSym is the sort of symbol that is written to an object file.
|
||||||
|
type LSym struct {
|
||||||
|
Name string
|
||||||
|
Type SymKind
|
||||||
|
Version int16
|
||||||
|
Attribute
|
||||||
|
|
||||||
|
RefIdx int // Index of this symbol in the symbol reference list.
|
||||||
|
Args int32
|
||||||
|
Locals int32
|
||||||
|
Size int64
|
||||||
|
Gotype *LSym
|
||||||
|
Autom *Auto
|
||||||
|
Text *Prog
|
||||||
|
Pcln *Pcln
|
||||||
|
P []byte
|
||||||
|
R []Reloc
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attribute is a set of symbol attributes.
|
||||||
|
type Attribute int16
|
||||||
|
|
||||||
|
const (
|
||||||
|
AttrDuplicateOK Attribute = 1 << iota
|
||||||
|
AttrCFunc
|
||||||
|
AttrNoSplit
|
||||||
|
AttrLeaf
|
||||||
|
AttrSeenGlobl
|
||||||
|
AttrOnList
|
||||||
|
|
||||||
|
// MakeTypelink means that the type should have an entry in the typelink table.
|
||||||
|
AttrMakeTypelink
|
||||||
|
|
||||||
|
// ReflectMethod means the function may call reflect.Type.Method or
|
||||||
|
// reflect.Type.MethodByName. Matching is imprecise (as reflect.Type
|
||||||
|
// can be used through a custom interface), so ReflectMethod may be
|
||||||
|
// set in some cases when the reflect package is not called.
|
||||||
|
//
|
||||||
|
// Used by the linker to determine what methods can be pruned.
|
||||||
|
AttrReflectMethod
|
||||||
|
|
||||||
|
// Local means make the symbol local even when compiling Go code to reference Go
|
||||||
|
// symbols in other shared libraries, as in this mode symbols are global by
|
||||||
|
// default. "local" here means in the sense of the dynamic linker, i.e. not
|
||||||
|
// visible outside of the module (shared library or executable) that contains its
|
||||||
|
// definition. (When not compiling to support Go shared libraries, all symbols are
|
||||||
|
// local in this sense unless there is a cgo_export_* directive).
|
||||||
|
AttrLocal
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 }
|
||||||
|
func (a Attribute) MakeTypelink() bool { return a&AttrMakeTypelink != 0 }
|
||||||
|
func (a Attribute) CFunc() bool { return a&AttrCFunc != 0 }
|
||||||
|
func (a Attribute) NoSplit() bool { return a&AttrNoSplit != 0 }
|
||||||
|
func (a Attribute) Leaf() bool { return a&AttrLeaf != 0 }
|
||||||
|
func (a Attribute) SeenGlobl() bool { return a&AttrSeenGlobl != 0 }
|
||||||
|
func (a Attribute) OnList() bool { return a&AttrOnList != 0 }
|
||||||
|
func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 }
|
||||||
|
func (a Attribute) Local() bool { return a&AttrLocal != 0 }
|
||||||
|
|
||||||
|
func (a *Attribute) Set(flag Attribute, value bool) {
|
||||||
|
if value {
|
||||||
|
*a |= flag
|
||||||
|
} else {
|
||||||
|
*a &^= flag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The compiler needs LSym to satisfy fmt.Stringer, because it stores
|
||||||
|
// an LSym in ssa.ExternSymbol.
|
||||||
|
func (s *LSym) String() string {
|
||||||
|
return s.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
type Pcln struct {
|
||||||
|
Pcsp Pcdata
|
||||||
|
Pcfile Pcdata
|
||||||
|
Pcline Pcdata
|
||||||
|
Pcdata []Pcdata
|
||||||
|
Funcdata []*LSym
|
||||||
|
Funcdataoff []int64
|
||||||
|
File []*LSym
|
||||||
|
Lastfile *LSym
|
||||||
|
Lastindex int
|
||||||
|
}
|
||||||
|
|
||||||
|
// A SymKind describes the kind of memory represented by a symbol.
|
||||||
|
type SymKind int16
|
||||||
|
|
||||||
|
// Defined SymKind values.
|
||||||
|
//
|
||||||
|
// TODO(rsc): Give idiomatic Go names.
|
||||||
|
// TODO(rsc): Reduce the number of symbol types in the object files.
|
||||||
|
//go:generate stringer -type=SymKind
|
||||||
|
const (
|
||||||
|
Sxxx SymKind = iota
|
||||||
|
STEXT
|
||||||
|
SELFRXSECT
|
||||||
|
|
||||||
|
// Read-only sections.
|
||||||
|
STYPE
|
||||||
|
SSTRING
|
||||||
|
SGOSTRING
|
||||||
|
SGOFUNC
|
||||||
|
SGCBITS
|
||||||
|
SRODATA
|
||||||
|
SFUNCTAB
|
||||||
|
|
||||||
|
SELFROSECT
|
||||||
|
SMACHOPLT
|
||||||
|
|
||||||
|
// Read-only sections with relocations.
|
||||||
|
//
|
||||||
|
// Types STYPE-SFUNCTAB above are written to the .rodata section by default.
|
||||||
|
// When linking a shared object, some conceptually "read only" types need to
|
||||||
|
// be written to by relocations and putting them in a section called
|
||||||
|
// ".rodata" interacts poorly with the system linkers. The GNU linkers
|
||||||
|
// support this situation by arranging for sections of the name
|
||||||
|
// ".data.rel.ro.XXX" to be mprotected read only by the dynamic linker after
|
||||||
|
// relocations have applied, so when the Go linker is creating a shared
|
||||||
|
// object it checks all objects of the above types and bumps any object that
|
||||||
|
// has a relocation to it to the corresponding type below, which are then
|
||||||
|
// written to sections with appropriate magic names.
|
||||||
|
STYPERELRO
|
||||||
|
SSTRINGRELRO
|
||||||
|
SGOSTRINGRELRO
|
||||||
|
SGOFUNCRELRO
|
||||||
|
SGCBITSRELRO
|
||||||
|
SRODATARELRO
|
||||||
|
SFUNCTABRELRO
|
||||||
|
|
||||||
|
// Part of .data.rel.ro if it exists, otherwise part of .rodata.
|
||||||
|
STYPELINK
|
||||||
|
SITABLINK
|
||||||
|
SSYMTAB
|
||||||
|
SPCLNTAB
|
||||||
|
|
||||||
|
// Writable sections.
|
||||||
|
SELFSECT
|
||||||
|
SMACHO
|
||||||
|
SMACHOGOT
|
||||||
|
SWINDOWS
|
||||||
|
SELFGOT
|
||||||
|
SNOPTRDATA
|
||||||
|
SINITARR
|
||||||
|
SDATA
|
||||||
|
SBSS
|
||||||
|
SNOPTRBSS
|
||||||
|
STLSBSS
|
||||||
|
SXREF
|
||||||
|
SMACHOSYMSTR
|
||||||
|
SMACHOSYMTAB
|
||||||
|
SMACHOINDIRECTPLT
|
||||||
|
SMACHOINDIRECTGOT
|
||||||
|
SFILE
|
||||||
|
SFILEPATH
|
||||||
|
SCONST
|
||||||
|
SDYNIMPORT
|
||||||
|
SHOSTOBJ
|
||||||
|
SDWARFSECT
|
||||||
|
SDWARFINFO
|
||||||
|
SSUB = SymKind(1 << 8)
|
||||||
|
SMASK = SymKind(SSUB - 1)
|
||||||
|
SHIDDEN = SymKind(1 << 9)
|
||||||
|
SCONTAINER = SymKind(1 << 10) // has a sub-symbol
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReadOnly are the symbol kinds that form read-only sections. In some
|
||||||
|
// cases, if they will require relocations, they are transformed into
|
||||||
|
// rel-ro sections using RelROMap.
|
||||||
|
var ReadOnly = []SymKind{
|
||||||
|
STYPE,
|
||||||
|
SSTRING,
|
||||||
|
SGOSTRING,
|
||||||
|
SGOFUNC,
|
||||||
|
SGCBITS,
|
||||||
|
SRODATA,
|
||||||
|
SFUNCTAB,
|
||||||
|
}
|
||||||
|
|
||||||
|
// RelROMap describes the transformation of read-only symbols to rel-ro
|
||||||
|
// symbols.
|
||||||
|
var RelROMap = map[SymKind]SymKind{
|
||||||
|
STYPE: STYPERELRO,
|
||||||
|
SSTRING: SSTRINGRELRO,
|
||||||
|
SGOSTRING: SGOSTRINGRELRO,
|
||||||
|
SGOFUNC: SGOFUNCRELRO,
|
||||||
|
SGCBITS: SGCBITSRELRO,
|
||||||
|
SRODATA: SRODATARELRO,
|
||||||
|
SFUNCTAB: SFUNCTABRELRO,
|
||||||
|
}
|
||||||
|
|
||||||
|
type Reloc struct {
|
||||||
|
Off int32
|
||||||
|
Siz uint8
|
||||||
|
Type RelocType
|
||||||
|
Add int64
|
||||||
|
Sym *LSym
|
||||||
|
}
|
||||||
|
|
||||||
|
type RelocType int32
|
||||||
|
|
||||||
|
//go:generate stringer -type=RelocType
|
||||||
|
const (
|
||||||
|
R_ADDR RelocType = 1 + iota
|
||||||
|
// R_ADDRPOWER relocates a pair of "D-form" instructions (instructions with 16-bit
|
||||||
|
// immediates in the low half of the instruction word), usually addis followed by
|
||||||
|
// another add or a load, inserting the "high adjusted" 16 bits of the address of
|
||||||
|
// the referenced symbol into the immediate field of the first instruction and the
|
||||||
|
// low 16 bits into that of the second instruction.
|
||||||
|
R_ADDRPOWER
|
||||||
|
// R_ADDRARM64 relocates an adrp, add pair to compute the address of the
|
||||||
|
// referenced symbol.
|
||||||
|
R_ADDRARM64
|
||||||
|
// R_ADDRMIPS (only used on mips64) resolves to the low 16 bits of an external
|
||||||
|
// address, by encoding it into the instruction.
|
||||||
|
R_ADDRMIPS
|
||||||
|
// R_ADDROFF resolves to a 32-bit offset from the beginning of the section
|
||||||
|
// holding the data being relocated to the referenced symbol.
|
||||||
|
R_ADDROFF
|
||||||
|
R_SIZE
|
||||||
|
R_CALL
|
||||||
|
R_CALLARM
|
||||||
|
R_CALLARM64
|
||||||
|
R_CALLIND
|
||||||
|
R_CALLPOWER
|
||||||
|
// R_CALLMIPS (only used on mips64) resolves to non-PC-relative target address
|
||||||
|
// of a CALL (JAL) instruction, by encoding the address into the instruction.
|
||||||
|
R_CALLMIPS
|
||||||
|
R_CONST
|
||||||
|
R_PCREL
|
||||||
|
// R_TLS_LE, used on 386, amd64, and ARM, resolves to the offset of the
|
||||||
|
// thread-local symbol from the thread local base and is used to implement the
|
||||||
|
// "local exec" model for tls access (r.Sym is not set on intel platforms but is
|
||||||
|
// set to a TLS symbol -- runtime.tlsg -- in the linker when externally linking).
|
||||||
|
R_TLS_LE
|
||||||
|
// R_TLS_IE, used 386, amd64, and ARM resolves to the PC-relative offset to a GOT
|
||||||
|
// slot containing the offset from the thread-local symbol from the thread local
|
||||||
|
// base and is used to implemented the "initial exec" model for tls access (r.Sym
|
||||||
|
// is not set on intel platforms but is set to a TLS symbol -- runtime.tlsg -- in
|
||||||
|
// the linker when externally linking).
|
||||||
|
R_TLS_IE
|
||||||
|
R_GOTOFF
|
||||||
|
R_PLT0
|
||||||
|
R_PLT1
|
||||||
|
R_PLT2
|
||||||
|
R_USEFIELD
|
||||||
|
// R_USETYPE resolves to an *rtype, but no relocation is created. The
|
||||||
|
// linker uses this as a signal that the pointed-to type information
|
||||||
|
// should be linked into the final binary, even if there are no other
|
||||||
|
// direct references. (This is used for types reachable by reflection.)
|
||||||
|
R_USETYPE
|
||||||
|
// R_METHODOFF resolves to a 32-bit offset from the beginning of the section
|
||||||
|
// holding the data being relocated to the referenced symbol.
|
||||||
|
// It is a variant of R_ADDROFF used when linking from the uncommonType of a
|
||||||
|
// *rtype, and may be set to zero by the linker if it determines the method
|
||||||
|
// text is unreachable by the linked program.
|
||||||
|
R_METHODOFF
|
||||||
|
R_POWER_TOC
|
||||||
|
R_GOTPCREL
|
||||||
|
// R_JMPMIPS (only used on mips64) resolves to non-PC-relative target address
|
||||||
|
// of a JMP instruction, by encoding the address into the instruction.
|
||||||
|
// The stack nosplit check ignores this since it is not a function call.
|
||||||
|
R_JMPMIPS
|
||||||
|
// R_DWARFREF resolves to the offset of the symbol from its section.
|
||||||
|
R_DWARFREF
|
||||||
|
|
||||||
|
// Platform dependent relocations. Architectures with fixed width instructions
|
||||||
|
// have the inherent issue that a 32-bit (or 64-bit!) displacement cannot be
|
||||||
|
// stuffed into a 32-bit instruction, so an address needs to be spread across
|
||||||
|
// several instructions, and in turn this requires a sequence of relocations, each
|
||||||
|
// updating a part of an instruction. This leads to relocation codes that are
|
||||||
|
// inherently processor specific.
|
||||||
|
|
||||||
|
// Arm64.
|
||||||
|
|
||||||
|
// Set a MOV[NZ] immediate field to bits [15:0] of the offset from the thread
|
||||||
|
// local base to the thread local variable defined by the referenced (thread
|
||||||
|
// local) symbol. Error if the offset does not fit into 16 bits.
|
||||||
|
R_ARM64_TLS_LE
|
||||||
|
|
||||||
|
// Relocates an ADRP; LD64 instruction sequence to load the offset between
|
||||||
|
// the thread local base and the thread local variable defined by the
|
||||||
|
// referenced (thread local) symbol from the GOT.
|
||||||
|
R_ARM64_TLS_IE
|
||||||
|
|
||||||
|
// R_ARM64_GOTPCREL relocates an adrp, ld64 pair to compute the address of the GOT
|
||||||
|
// slot of the referenced symbol.
|
||||||
|
R_ARM64_GOTPCREL
|
||||||
|
|
||||||
|
// PPC64.
|
||||||
|
|
||||||
|
// R_POWER_TLS_LE is used to implement the "local exec" model for tls
|
||||||
|
// access. It resolves to the offset of the thread-local symbol from the
|
||||||
|
// thread pointer (R13) and inserts this value into the low 16 bits of an
|
||||||
|
// instruction word.
|
||||||
|
R_POWER_TLS_LE
|
||||||
|
|
||||||
|
// R_POWER_TLS_IE is used to implement the "initial exec" model for tls access. It
|
||||||
|
// relocates a D-form, DS-form instruction sequence like R_ADDRPOWER_DS. It
|
||||||
|
// inserts to the offset of GOT slot for the thread-local symbol from the TOC (the
|
||||||
|
// GOT slot is filled by the dynamic linker with the offset of the thread-local
|
||||||
|
// symbol from the thread pointer (R13)).
|
||||||
|
R_POWER_TLS_IE
|
||||||
|
|
||||||
|
// R_POWER_TLS marks an X-form instruction such as "MOVD 0(R13)(R31*1), g" as
|
||||||
|
// accessing a particular thread-local symbol. It does not affect code generation
|
||||||
|
// but is used by the system linker when relaxing "initial exec" model code to
|
||||||
|
// "local exec" model code.
|
||||||
|
R_POWER_TLS
|
||||||
|
|
||||||
|
// R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second
|
||||||
|
// instruction is a "DS-form" instruction, which has an immediate field occupying
|
||||||
|
// bits [15:2] of the instruction word. Bits [15:2] of the address of the
|
||||||
|
// relocated symbol are inserted into this field; it is an error if the last two
|
||||||
|
// bits of the address are not 0.
|
||||||
|
R_ADDRPOWER_DS
|
||||||
|
|
||||||
|
// R_ADDRPOWER_PCREL relocates a D-form, DS-form instruction sequence like
|
||||||
|
// R_ADDRPOWER_DS but inserts the offset of the GOT slot for the referenced symbol
|
||||||
|
// from the TOC rather than the symbol's address.
|
||||||
|
R_ADDRPOWER_GOT
|
||||||
|
|
||||||
|
// R_ADDRPOWER_PCREL relocates two D-form instructions like R_ADDRPOWER, but
|
||||||
|
// inserts the displacement from the place being relocated to the address of the
|
||||||
|
// the relocated symbol instead of just its address.
|
||||||
|
R_ADDRPOWER_PCREL
|
||||||
|
|
||||||
|
// R_ADDRPOWER_TOCREL relocates two D-form instructions like R_ADDRPOWER, but
|
||||||
|
// inserts the offset from the TOC to the address of the the relocated symbol
|
||||||
|
// rather than the symbol's address.
|
||||||
|
R_ADDRPOWER_TOCREL
|
||||||
|
|
||||||
|
// R_ADDRPOWER_TOCREL relocates a D-form, DS-form instruction sequence like
|
||||||
|
// R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the the
|
||||||
|
// relocated symbol rather than the symbol's address.
|
||||||
|
R_ADDRPOWER_TOCREL_DS
|
||||||
|
|
||||||
|
// R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses.
|
||||||
|
// TODO(mundaym): remove once variants can be serialized - see issue 14218.
|
||||||
|
R_PCRELDBL
|
||||||
|
|
||||||
|
// R_ADDRMIPSU (only used on mips64) resolves to the sign-adjusted "upper" 16
|
||||||
|
// bits (bit 16-31) of an external address, by encoding it into the instruction.
|
||||||
|
R_ADDRMIPSU
|
||||||
|
// R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS
|
||||||
|
// address (offset from thread pointer), by encoding it into the instruction.
|
||||||
|
R_ADDRMIPSTLS
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsDirectJump returns whether r is a relocation for a direct jump.
|
||||||
|
// A direct jump is a CALL or JMP instruction that takes the target address
|
||||||
|
// as immediate. The address is embedded into the instruction, possibly
|
||||||
|
// with limited width.
|
||||||
|
// An indirect jump is a CALL or JMP instruction that takes the target address
|
||||||
|
// in register or memory.
|
||||||
|
func (r RelocType) IsDirectJump() bool {
|
||||||
|
switch r {
|
||||||
|
case R_CALL, R_CALLARM, R_CALLARM64, R_CALLPOWER, R_CALLMIPS, R_JMPMIPS:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
type Auto struct {
|
||||||
|
Asym *LSym
|
||||||
|
Link *Auto
|
||||||
|
Aoffset int32
|
||||||
|
Name int16
|
||||||
|
Gotype *LSym
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto.name
|
||||||
|
const (
|
||||||
|
A_AUTO = 1 + iota
|
||||||
|
A_PARAM
|
||||||
|
)
|
||||||
|
|
||||||
|
type Pcdata struct {
|
||||||
|
P []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// symbol version, incremented each time a file is loaded.
|
||||||
|
// version==1 is reserved for savehist.
|
||||||
|
const (
|
||||||
|
HistVersion = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// Link holds the context for writing object code from a compiler
|
||||||
|
// to be linker input or for reading that input into the linker.
|
||||||
|
type Link struct {
|
||||||
|
Headtype HeadType
|
||||||
|
Arch *LinkArch
|
||||||
|
Debugasm int32
|
||||||
|
Debugvlog int32
|
||||||
|
Debugdivmod int32
|
||||||
|
Debugpcln int32
|
||||||
|
Flag_shared bool
|
||||||
|
Flag_dynlink bool
|
||||||
|
Flag_optimize bool
|
||||||
|
Bso *bufio.Writer
|
||||||
|
Pathname string
|
||||||
|
Hash map[SymVer]*LSym
|
||||||
|
LineHist LineHist
|
||||||
|
Imports []string
|
||||||
|
Plists []*Plist
|
||||||
|
Sym_div *LSym
|
||||||
|
Sym_divu *LSym
|
||||||
|
Sym_mod *LSym
|
||||||
|
Sym_modu *LSym
|
||||||
|
Plan9privates *LSym
|
||||||
|
Curp *Prog
|
||||||
|
Printp *Prog
|
||||||
|
Blitrl *Prog
|
||||||
|
Elitrl *Prog
|
||||||
|
Rexflag int
|
||||||
|
Vexflag int
|
||||||
|
Rep int
|
||||||
|
Repn int
|
||||||
|
Lock int
|
||||||
|
Asmode int
|
||||||
|
AsmBuf AsmBuf // instruction buffer for x86
|
||||||
|
Instoffset int64
|
||||||
|
Autosize int32
|
||||||
|
Armsize int32
|
||||||
|
Pc int64
|
||||||
|
DiagFunc func(string, ...interface{})
|
||||||
|
Mode int
|
||||||
|
Cursym *LSym
|
||||||
|
Version int
|
||||||
|
Errors int
|
||||||
|
|
||||||
|
Framepointer_enabled bool
|
||||||
|
|
||||||
|
// state for writing objects
|
||||||
|
Text []*LSym
|
||||||
|
Data []*LSym
|
||||||
|
|
||||||
|
// Cache of Progs
|
||||||
|
allocIdx int
|
||||||
|
progs [10000]Prog
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctxt *Link) Diag(format string, args ...interface{}) {
|
||||||
|
ctxt.Errors++
|
||||||
|
ctxt.DiagFunc(format, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctxt *Link) Logf(format string, args ...interface{}) {
|
||||||
|
fmt.Fprintf(ctxt.Bso, format, args...)
|
||||||
|
ctxt.Bso.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
// The smallest possible offset from the hardware stack pointer to a local
|
||||||
|
// variable on the stack. Architectures that use a link register save its value
|
||||||
|
// on the stack in the function prologue and so always have a pointer between
|
||||||
|
// the hardware stack pointer and the local variable area.
|
||||||
|
func (ctxt *Link) FixedFrameSize() int64 {
|
||||||
|
switch ctxt.Arch.Family {
|
||||||
|
case sys.AMD64, sys.I386:
|
||||||
|
return 0
|
||||||
|
case sys.PPC64:
|
||||||
|
// PIC code on ppc64le requires 32 bytes of stack, and it's easier to
|
||||||
|
// just use that much stack always on ppc64x.
|
||||||
|
return int64(4 * ctxt.Arch.PtrSize)
|
||||||
|
default:
|
||||||
|
return int64(ctxt.Arch.PtrSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type SymVer struct {
|
||||||
|
Name string
|
||||||
|
Version int // TODO: make int16 to match LSym.Version?
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkArch is the definition of a single architecture.
|
||||||
|
type LinkArch struct {
|
||||||
|
*sys.Arch
|
||||||
|
Preprocess func(*Link, *LSym)
|
||||||
|
Assemble func(*Link, *LSym)
|
||||||
|
Follow func(*Link, *LSym)
|
||||||
|
Progedit func(*Link, *Prog)
|
||||||
|
UnaryDst map[As]bool // Instruction takes one operand, a destination.
|
||||||
|
}
|
||||||
|
|
||||||
|
// HeadType is the executable header type.
|
||||||
|
type HeadType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
Hunknown HeadType = iota
|
||||||
|
Hdarwin
|
||||||
|
Hdragonfly
|
||||||
|
Hfreebsd
|
||||||
|
Hlinux
|
||||||
|
Hnacl
|
||||||
|
Hnetbsd
|
||||||
|
Hopenbsd
|
||||||
|
Hplan9
|
||||||
|
Hsolaris
|
||||||
|
Hwindows
|
||||||
|
Hwindowsgui
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *HeadType) Set(s string) error {
|
||||||
|
switch s {
|
||||||
|
case "darwin":
|
||||||
|
*h = Hdarwin
|
||||||
|
case "dragonfly":
|
||||||
|
*h = Hdragonfly
|
||||||
|
case "freebsd":
|
||||||
|
*h = Hfreebsd
|
||||||
|
case "linux", "android":
|
||||||
|
*h = Hlinux
|
||||||
|
case "nacl":
|
||||||
|
*h = Hnacl
|
||||||
|
case "netbsd":
|
||||||
|
*h = Hnetbsd
|
||||||
|
case "openbsd":
|
||||||
|
*h = Hopenbsd
|
||||||
|
case "plan9":
|
||||||
|
*h = Hplan9
|
||||||
|
case "solaris":
|
||||||
|
*h = Hsolaris
|
||||||
|
case "windows":
|
||||||
|
*h = Hwindows
|
||||||
|
case "windowsgui":
|
||||||
|
*h = Hwindowsgui
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid headtype: %q", s)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HeadType) String() string {
|
||||||
|
switch *h {
|
||||||
|
case Hdarwin:
|
||||||
|
return "darwin"
|
||||||
|
case Hdragonfly:
|
||||||
|
return "dragonfly"
|
||||||
|
case Hfreebsd:
|
||||||
|
return "freebsd"
|
||||||
|
case Hlinux:
|
||||||
|
return "linux"
|
||||||
|
case Hnacl:
|
||||||
|
return "nacl"
|
||||||
|
case Hnetbsd:
|
||||||
|
return "netbsd"
|
||||||
|
case Hopenbsd:
|
||||||
|
return "openbsd"
|
||||||
|
case Hplan9:
|
||||||
|
return "plan9"
|
||||||
|
case Hsolaris:
|
||||||
|
return "solaris"
|
||||||
|
case Hwindows:
|
||||||
|
return "windows"
|
||||||
|
case Hwindowsgui:
|
||||||
|
return "windowsgui"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("HeadType(%d)", *h)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsmBuf is a simple buffer to assemble variable-length x86 instructions into.
|
||||||
|
type AsmBuf struct {
|
||||||
|
buf [100]byte
|
||||||
|
off int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put1 appends one byte to the end of the buffer.
|
||||||
|
func (a *AsmBuf) Put1(x byte) {
|
||||||
|
a.buf[a.off] = x
|
||||||
|
a.off++
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put2 appends two bytes to the end of the buffer.
|
||||||
|
func (a *AsmBuf) Put2(x, y byte) {
|
||||||
|
a.buf[a.off+0] = x
|
||||||
|
a.buf[a.off+1] = y
|
||||||
|
a.off += 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put3 appends three bytes to the end of the buffer.
|
||||||
|
func (a *AsmBuf) Put3(x, y, z byte) {
|
||||||
|
a.buf[a.off+0] = x
|
||||||
|
a.buf[a.off+1] = y
|
||||||
|
a.buf[a.off+2] = z
|
||||||
|
a.off += 3
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put4 appends four bytes to the end of the buffer.
|
||||||
|
func (a *AsmBuf) Put4(x, y, z, w byte) {
|
||||||
|
a.buf[a.off+0] = x
|
||||||
|
a.buf[a.off+1] = y
|
||||||
|
a.buf[a.off+2] = z
|
||||||
|
a.buf[a.off+3] = w
|
||||||
|
a.off += 4
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutInt16 writes v into the buffer using little-endian encoding.
|
||||||
|
func (a *AsmBuf) PutInt16(v int16) {
|
||||||
|
a.buf[a.off+0] = byte(v)
|
||||||
|
a.buf[a.off+1] = byte(v >> 8)
|
||||||
|
a.off += 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutInt32 writes v into the buffer using little-endian encoding.
|
||||||
|
func (a *AsmBuf) PutInt32(v int32) {
|
||||||
|
a.buf[a.off+0] = byte(v)
|
||||||
|
a.buf[a.off+1] = byte(v >> 8)
|
||||||
|
a.buf[a.off+2] = byte(v >> 16)
|
||||||
|
a.buf[a.off+3] = byte(v >> 24)
|
||||||
|
a.off += 4
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutInt64 writes v into the buffer using little-endian encoding.
|
||||||
|
func (a *AsmBuf) PutInt64(v int64) {
|
||||||
|
a.buf[a.off+0] = byte(v)
|
||||||
|
a.buf[a.off+1] = byte(v >> 8)
|
||||||
|
a.buf[a.off+2] = byte(v >> 16)
|
||||||
|
a.buf[a.off+3] = byte(v >> 24)
|
||||||
|
a.buf[a.off+4] = byte(v >> 32)
|
||||||
|
a.buf[a.off+5] = byte(v >> 40)
|
||||||
|
a.buf[a.off+6] = byte(v >> 48)
|
||||||
|
a.buf[a.off+7] = byte(v >> 56)
|
||||||
|
a.off += 8
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put copies b into the buffer.
|
||||||
|
func (a *AsmBuf) Put(b []byte) {
|
||||||
|
copy(a.buf[a.off:], b)
|
||||||
|
a.off += len(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert inserts b at offset i.
|
||||||
|
func (a *AsmBuf) Insert(i int, b byte) {
|
||||||
|
a.off++
|
||||||
|
copy(a.buf[i+1:a.off], a.buf[i:a.off-1])
|
||||||
|
a.buf[i] = b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last returns the byte at the end of the buffer.
|
||||||
|
func (a *AsmBuf) Last() byte { return a.buf[a.off-1] }
|
||||||
|
|
||||||
|
// Len returns the length of the buffer.
|
||||||
|
func (a *AsmBuf) Len() int { return a.off }
|
||||||
|
|
||||||
|
// Bytes returns the contents of the buffer.
|
||||||
|
func (a *AsmBuf) Bytes() []byte { return a.buf[:a.off] }
|
||||||
|
|
||||||
|
// Reset empties the buffer.
|
||||||
|
func (a *AsmBuf) Reset() { a.off = 0 }
|
||||||
|
|
||||||
|
// Peek returns the byte at offset i.
|
||||||
|
func (a *AsmBuf) Peek(i int) byte { return a.buf[i] }
|
375
vendor/github.com/google/gops/internal/obj/mips/a.out.go
generated
vendored
Normal file
375
vendor/github.com/google/gops/internal/obj/mips/a.out.go
generated
vendored
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
// cmd/9c/9.out.h from Vita Nuova.
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package mips
|
||||||
|
|
||||||
|
import "github.com/google/gops/internal/obj"
|
||||||
|
|
||||||
|
//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p mips
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mips 64
|
||||||
|
*/
|
||||||
|
const (
|
||||||
|
NSNAME = 8
|
||||||
|
NSYM = 50
|
||||||
|
NREG = 32 /* number of general registers */
|
||||||
|
NFREG = 32 /* number of floating point registers */
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
REG_R0 = obj.RBaseMIPS64 + iota
|
||||||
|
REG_R1
|
||||||
|
REG_R2
|
||||||
|
REG_R3
|
||||||
|
REG_R4
|
||||||
|
REG_R5
|
||||||
|
REG_R6
|
||||||
|
REG_R7
|
||||||
|
REG_R8
|
||||||
|
REG_R9
|
||||||
|
REG_R10
|
||||||
|
REG_R11
|
||||||
|
REG_R12
|
||||||
|
REG_R13
|
||||||
|
REG_R14
|
||||||
|
REG_R15
|
||||||
|
REG_R16
|
||||||
|
REG_R17
|
||||||
|
REG_R18
|
||||||
|
REG_R19
|
||||||
|
REG_R20
|
||||||
|
REG_R21
|
||||||
|
REG_R22
|
||||||
|
REG_R23
|
||||||
|
REG_R24
|
||||||
|
REG_R25
|
||||||
|
REG_R26
|
||||||
|
REG_R27
|
||||||
|
REG_R28
|
||||||
|
REG_R29
|
||||||
|
REG_R30
|
||||||
|
REG_R31
|
||||||
|
|
||||||
|
REG_F0
|
||||||
|
REG_F1
|
||||||
|
REG_F2
|
||||||
|
REG_F3
|
||||||
|
REG_F4
|
||||||
|
REG_F5
|
||||||
|
REG_F6
|
||||||
|
REG_F7
|
||||||
|
REG_F8
|
||||||
|
REG_F9
|
||||||
|
REG_F10
|
||||||
|
REG_F11
|
||||||
|
REG_F12
|
||||||
|
REG_F13
|
||||||
|
REG_F14
|
||||||
|
REG_F15
|
||||||
|
REG_F16
|
||||||
|
REG_F17
|
||||||
|
REG_F18
|
||||||
|
REG_F19
|
||||||
|
REG_F20
|
||||||
|
REG_F21
|
||||||
|
REG_F22
|
||||||
|
REG_F23
|
||||||
|
REG_F24
|
||||||
|
REG_F25
|
||||||
|
REG_F26
|
||||||
|
REG_F27
|
||||||
|
REG_F28
|
||||||
|
REG_F29
|
||||||
|
REG_F30
|
||||||
|
REG_F31
|
||||||
|
|
||||||
|
REG_HI
|
||||||
|
REG_LO
|
||||||
|
|
||||||
|
// co-processor 0 control registers
|
||||||
|
REG_M0
|
||||||
|
REG_M1
|
||||||
|
REG_M2
|
||||||
|
REG_M3
|
||||||
|
REG_M4
|
||||||
|
REG_M5
|
||||||
|
REG_M6
|
||||||
|
REG_M7
|
||||||
|
REG_M8
|
||||||
|
REG_M9
|
||||||
|
REG_M10
|
||||||
|
REG_M11
|
||||||
|
REG_M12
|
||||||
|
REG_M13
|
||||||
|
REG_M14
|
||||||
|
REG_M15
|
||||||
|
REG_M16
|
||||||
|
REG_M17
|
||||||
|
REG_M18
|
||||||
|
REG_M19
|
||||||
|
REG_M20
|
||||||
|
REG_M21
|
||||||
|
REG_M22
|
||||||
|
REG_M23
|
||||||
|
REG_M24
|
||||||
|
REG_M25
|
||||||
|
REG_M26
|
||||||
|
REG_M27
|
||||||
|
REG_M28
|
||||||
|
REG_M29
|
||||||
|
REG_M30
|
||||||
|
REG_M31
|
||||||
|
|
||||||
|
// FPU control registers
|
||||||
|
REG_FCR0
|
||||||
|
REG_FCR1
|
||||||
|
REG_FCR2
|
||||||
|
REG_FCR3
|
||||||
|
REG_FCR4
|
||||||
|
REG_FCR5
|
||||||
|
REG_FCR6
|
||||||
|
REG_FCR7
|
||||||
|
REG_FCR8
|
||||||
|
REG_FCR9
|
||||||
|
REG_FCR10
|
||||||
|
REG_FCR11
|
||||||
|
REG_FCR12
|
||||||
|
REG_FCR13
|
||||||
|
REG_FCR14
|
||||||
|
REG_FCR15
|
||||||
|
REG_FCR16
|
||||||
|
REG_FCR17
|
||||||
|
REG_FCR18
|
||||||
|
REG_FCR19
|
||||||
|
REG_FCR20
|
||||||
|
REG_FCR21
|
||||||
|
REG_FCR22
|
||||||
|
REG_FCR23
|
||||||
|
REG_FCR24
|
||||||
|
REG_FCR25
|
||||||
|
REG_FCR26
|
||||||
|
REG_FCR27
|
||||||
|
REG_FCR28
|
||||||
|
REG_FCR29
|
||||||
|
REG_FCR30
|
||||||
|
REG_FCR31
|
||||||
|
|
||||||
|
REG_LAST = REG_FCR31 // the last defined register
|
||||||
|
|
||||||
|
REG_SPECIAL = REG_M0
|
||||||
|
|
||||||
|
REGZERO = REG_R0 /* set to zero */
|
||||||
|
REGSP = REG_R29
|
||||||
|
REGSB = REG_R28
|
||||||
|
REGLINK = REG_R31
|
||||||
|
REGRET = REG_R1
|
||||||
|
REGARG = -1 /* -1 disables passing the first argument in register */
|
||||||
|
REGRT1 = REG_R1 /* reserved for runtime, duffzero and duffcopy */
|
||||||
|
REGRT2 = REG_R2 /* reserved for runtime, duffcopy */
|
||||||
|
REGCTXT = REG_R22 /* context for closures */
|
||||||
|
REGG = REG_R30 /* G */
|
||||||
|
REGTMP = REG_R23 /* used by the linker */
|
||||||
|
FREGRET = REG_F0
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
BIG = 32766
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
/* mark flags */
|
||||||
|
FOLL = 1 << 0
|
||||||
|
LABEL = 1 << 1
|
||||||
|
LEAF = 1 << 2
|
||||||
|
SYNC = 1 << 3
|
||||||
|
BRANCH = 1 << 4
|
||||||
|
LOAD = 1 << 5
|
||||||
|
FCMP = 1 << 6
|
||||||
|
NOSCHED = 1 << 7
|
||||||
|
|
||||||
|
NSCHED = 20
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
C_NONE = iota
|
||||||
|
C_REG
|
||||||
|
C_FREG
|
||||||
|
C_FCREG
|
||||||
|
C_MREG /* special processor register */
|
||||||
|
C_HI
|
||||||
|
C_LO
|
||||||
|
C_ZCON
|
||||||
|
C_SCON /* 16 bit signed */
|
||||||
|
C_UCON /* 32 bit signed, low 16 bits 0 */
|
||||||
|
C_ADD0CON
|
||||||
|
C_AND0CON
|
||||||
|
C_ADDCON /* -0x8000 <= v < 0 */
|
||||||
|
C_ANDCON /* 0 < v <= 0xFFFF */
|
||||||
|
C_LCON /* other 32 */
|
||||||
|
C_DCON /* other 64 (could subdivide further) */
|
||||||
|
C_SACON /* $n(REG) where n <= int16 */
|
||||||
|
C_SECON
|
||||||
|
C_LACON /* $n(REG) where int16 < n <= int32 */
|
||||||
|
C_LECON
|
||||||
|
C_DACON /* $n(REG) where int32 < n */
|
||||||
|
C_STCON /* $tlsvar */
|
||||||
|
C_SBRA
|
||||||
|
C_LBRA
|
||||||
|
C_SAUTO
|
||||||
|
C_LAUTO
|
||||||
|
C_SEXT
|
||||||
|
C_LEXT
|
||||||
|
C_ZOREG
|
||||||
|
C_SOREG
|
||||||
|
C_LOREG
|
||||||
|
C_GOK
|
||||||
|
C_ADDR
|
||||||
|
C_TLS
|
||||||
|
C_TEXTSIZE
|
||||||
|
|
||||||
|
C_NCLASS /* must be the last */
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AABSD = obj.ABaseMIPS64 + obj.A_ARCHSPECIFIC + iota
|
||||||
|
AABSF
|
||||||
|
AABSW
|
||||||
|
AADD
|
||||||
|
AADDD
|
||||||
|
AADDF
|
||||||
|
AADDU
|
||||||
|
AADDW
|
||||||
|
AAND
|
||||||
|
ABEQ
|
||||||
|
ABFPF
|
||||||
|
ABFPT
|
||||||
|
ABGEZ
|
||||||
|
ABGEZAL
|
||||||
|
ABGTZ
|
||||||
|
ABLEZ
|
||||||
|
ABLTZ
|
||||||
|
ABLTZAL
|
||||||
|
ABNE
|
||||||
|
ABREAK
|
||||||
|
ACMPEQD
|
||||||
|
ACMPEQF
|
||||||
|
ACMPGED
|
||||||
|
ACMPGEF
|
||||||
|
ACMPGTD
|
||||||
|
ACMPGTF
|
||||||
|
ADIV
|
||||||
|
ADIVD
|
||||||
|
ADIVF
|
||||||
|
ADIVU
|
||||||
|
ADIVW
|
||||||
|
AGOK
|
||||||
|
ALUI
|
||||||
|
AMOVB
|
||||||
|
AMOVBU
|
||||||
|
AMOVD
|
||||||
|
AMOVDF
|
||||||
|
AMOVDW
|
||||||
|
AMOVF
|
||||||
|
AMOVFD
|
||||||
|
AMOVFW
|
||||||
|
AMOVH
|
||||||
|
AMOVHU
|
||||||
|
AMOVW
|
||||||
|
AMOVWD
|
||||||
|
AMOVWF
|
||||||
|
AMOVWL
|
||||||
|
AMOVWR
|
||||||
|
AMUL
|
||||||
|
AMULD
|
||||||
|
AMULF
|
||||||
|
AMULU
|
||||||
|
AMULW
|
||||||
|
ANEGD
|
||||||
|
ANEGF
|
||||||
|
ANEGW
|
||||||
|
ANOR
|
||||||
|
AOR
|
||||||
|
AREM
|
||||||
|
AREMU
|
||||||
|
ARFE
|
||||||
|
ASGT
|
||||||
|
ASGTU
|
||||||
|
ASLL
|
||||||
|
ASRA
|
||||||
|
ASRL
|
||||||
|
ASUB
|
||||||
|
ASUBD
|
||||||
|
ASUBF
|
||||||
|
ASUBU
|
||||||
|
ASUBW
|
||||||
|
ASYSCALL
|
||||||
|
ATLBP
|
||||||
|
ATLBR
|
||||||
|
ATLBWI
|
||||||
|
ATLBWR
|
||||||
|
AWORD
|
||||||
|
AXOR
|
||||||
|
|
||||||
|
/* 64-bit */
|
||||||
|
AMOVV
|
||||||
|
AMOVVL
|
||||||
|
AMOVVR
|
||||||
|
ASLLV
|
||||||
|
ASRAV
|
||||||
|
ASRLV
|
||||||
|
ADIVV
|
||||||
|
ADIVVU
|
||||||
|
AREMV
|
||||||
|
AREMVU
|
||||||
|
AMULV
|
||||||
|
AMULVU
|
||||||
|
AADDV
|
||||||
|
AADDVU
|
||||||
|
ASUBV
|
||||||
|
ASUBVU
|
||||||
|
|
||||||
|
/* 64-bit FP */
|
||||||
|
ATRUNCFV
|
||||||
|
ATRUNCDV
|
||||||
|
ATRUNCFW
|
||||||
|
ATRUNCDW
|
||||||
|
AMOVWU
|
||||||
|
AMOVFV
|
||||||
|
AMOVDV
|
||||||
|
AMOVVF
|
||||||
|
AMOVVD
|
||||||
|
|
||||||
|
ALAST
|
||||||
|
|
||||||
|
// aliases
|
||||||
|
AJMP = obj.AJMP
|
||||||
|
AJAL = obj.ACALL
|
||||||
|
ARET = obj.ARET
|
||||||
|
)
|
113
vendor/github.com/google/gops/internal/obj/mips/anames.go
generated
vendored
Normal file
113
vendor/github.com/google/gops/internal/obj/mips/anames.go
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
// Generated by stringer -i a.out.go -o anames.go -p mips
|
||||||
|
// Do not edit.
|
||||||
|
|
||||||
|
package mips
|
||||||
|
|
||||||
|
import "github.com/google/gops/internal/obj"
|
||||||
|
|
||||||
|
var Anames = []string{
|
||||||
|
obj.A_ARCHSPECIFIC: "ABSD",
|
||||||
|
"ABSF",
|
||||||
|
"ABSW",
|
||||||
|
"ADD",
|
||||||
|
"ADDD",
|
||||||
|
"ADDF",
|
||||||
|
"ADDU",
|
||||||
|
"ADDW",
|
||||||
|
"AND",
|
||||||
|
"BEQ",
|
||||||
|
"BFPF",
|
||||||
|
"BFPT",
|
||||||
|
"BGEZ",
|
||||||
|
"BGEZAL",
|
||||||
|
"BGTZ",
|
||||||
|
"BLEZ",
|
||||||
|
"BLTZ",
|
||||||
|
"BLTZAL",
|
||||||
|
"BNE",
|
||||||
|
"BREAK",
|
||||||
|
"CMPEQD",
|
||||||
|
"CMPEQF",
|
||||||
|
"CMPGED",
|
||||||
|
"CMPGEF",
|
||||||
|
"CMPGTD",
|
||||||
|
"CMPGTF",
|
||||||
|
"DIV",
|
||||||
|
"DIVD",
|
||||||
|
"DIVF",
|
||||||
|
"DIVU",
|
||||||
|
"DIVW",
|
||||||
|
"GOK",
|
||||||
|
"LUI",
|
||||||
|
"MOVB",
|
||||||
|
"MOVBU",
|
||||||
|
"MOVD",
|
||||||
|
"MOVDF",
|
||||||
|
"MOVDW",
|
||||||
|
"MOVF",
|
||||||
|
"MOVFD",
|
||||||
|
"MOVFW",
|
||||||
|
"MOVH",
|
||||||
|
"MOVHU",
|
||||||
|
"MOVW",
|
||||||
|
"MOVWD",
|
||||||
|
"MOVWF",
|
||||||
|
"MOVWL",
|
||||||
|
"MOVWR",
|
||||||
|
"MUL",
|
||||||
|
"MULD",
|
||||||
|
"MULF",
|
||||||
|
"MULU",
|
||||||
|
"MULW",
|
||||||
|
"NEGD",
|
||||||
|
"NEGF",
|
||||||
|
"NEGW",
|
||||||
|
"NOR",
|
||||||
|
"OR",
|
||||||
|
"REM",
|
||||||
|
"REMU",
|
||||||
|
"RFE",
|
||||||
|
"SGT",
|
||||||
|
"SGTU",
|
||||||
|
"SLL",
|
||||||
|
"SRA",
|
||||||
|
"SRL",
|
||||||
|
"SUB",
|
||||||
|
"SUBD",
|
||||||
|
"SUBF",
|
||||||
|
"SUBU",
|
||||||
|
"SUBW",
|
||||||
|
"SYSCALL",
|
||||||
|
"TLBP",
|
||||||
|
"TLBR",
|
||||||
|
"TLBWI",
|
||||||
|
"TLBWR",
|
||||||
|
"WORD",
|
||||||
|
"XOR",
|
||||||
|
"MOVV",
|
||||||
|
"MOVVL",
|
||||||
|
"MOVVR",
|
||||||
|
"SLLV",
|
||||||
|
"SRAV",
|
||||||
|
"SRLV",
|
||||||
|
"DIVV",
|
||||||
|
"DIVVU",
|
||||||
|
"REMV",
|
||||||
|
"REMVU",
|
||||||
|
"MULV",
|
||||||
|
"MULVU",
|
||||||
|
"ADDV",
|
||||||
|
"ADDVU",
|
||||||
|
"SUBV",
|
||||||
|
"SUBVU",
|
||||||
|
"TRUNCFV",
|
||||||
|
"TRUNCDV",
|
||||||
|
"TRUNCFW",
|
||||||
|
"TRUNCDW",
|
||||||
|
"MOVWU",
|
||||||
|
"MOVFV",
|
||||||
|
"MOVDV",
|
||||||
|
"MOVVF",
|
||||||
|
"MOVVD",
|
||||||
|
"LAST",
|
||||||
|
}
|
44
vendor/github.com/google/gops/internal/obj/mips/anames0.go
generated
vendored
Normal file
44
vendor/github.com/google/gops/internal/obj/mips/anames0.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package mips
|
||||||
|
|
||||||
|
var cnames0 = []string{
|
||||||
|
"NONE",
|
||||||
|
"REG",
|
||||||
|
"FREG",
|
||||||
|
"FCREG",
|
||||||
|
"MREG",
|
||||||
|
"HI",
|
||||||
|
"LO",
|
||||||
|
"ZCON",
|
||||||
|
"SCON",
|
||||||
|
"UCON",
|
||||||
|
"ADD0CON",
|
||||||
|
"AND0CON",
|
||||||
|
"ADDCON",
|
||||||
|
"ANDCON",
|
||||||
|
"LCON",
|
||||||
|
"DCON",
|
||||||
|
"SACON",
|
||||||
|
"SECON",
|
||||||
|
"LACON",
|
||||||
|
"LECON",
|
||||||
|
"DACON",
|
||||||
|
"STCON",
|
||||||
|
"SBRA",
|
||||||
|
"LBRA",
|
||||||
|
"SAUTO",
|
||||||
|
"LAUTO",
|
||||||
|
"SEXT",
|
||||||
|
"LEXT",
|
||||||
|
"ZOREG",
|
||||||
|
"SOREG",
|
||||||
|
"LOREG",
|
||||||
|
"GOK",
|
||||||
|
"ADDR",
|
||||||
|
"TLS",
|
||||||
|
"TEXTSIZE",
|
||||||
|
"NCLASS",
|
||||||
|
}
|
1783
vendor/github.com/google/gops/internal/obj/mips/asm0.go
generated
vendored
Normal file
1783
vendor/github.com/google/gops/internal/obj/mips/asm0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
85
vendor/github.com/google/gops/internal/obj/mips/list0.go
generated
vendored
Normal file
85
vendor/github.com/google/gops/internal/obj/mips/list0.go
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// cmd/9l/list.c from Vita Nuova.
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package mips
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gops/internal/obj"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
obj.RegisterRegister(obj.RBaseMIPS64, REG_LAST&^1023+1024, Rconv)
|
||||||
|
obj.RegisterOpcode(obj.ABaseMIPS64, Anames)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Rconv(r int) string {
|
||||||
|
if r == 0 {
|
||||||
|
return "NONE"
|
||||||
|
}
|
||||||
|
if r == REGG {
|
||||||
|
// Special case.
|
||||||
|
return "g"
|
||||||
|
}
|
||||||
|
if r == REGSB {
|
||||||
|
// Special case.
|
||||||
|
return "RSB"
|
||||||
|
}
|
||||||
|
if REG_R0 <= r && r <= REG_R31 {
|
||||||
|
return fmt.Sprintf("R%d", r-REG_R0)
|
||||||
|
}
|
||||||
|
if REG_F0 <= r && r <= REG_F31 {
|
||||||
|
return fmt.Sprintf("F%d", r-REG_F0)
|
||||||
|
}
|
||||||
|
if REG_M0 <= r && r <= REG_M31 {
|
||||||
|
return fmt.Sprintf("M%d", r-REG_M0)
|
||||||
|
}
|
||||||
|
if REG_FCR0 <= r && r <= REG_FCR31 {
|
||||||
|
return fmt.Sprintf("FCR%d", r-REG_FCR0)
|
||||||
|
}
|
||||||
|
if r == REG_HI {
|
||||||
|
return "HI"
|
||||||
|
}
|
||||||
|
if r == REG_LO {
|
||||||
|
return "LO"
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("Rgok(%d)", r-obj.RBaseMIPS64)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DRconv(a int) string {
|
||||||
|
s := "C_??"
|
||||||
|
if a >= C_NONE && a <= C_NCLASS {
|
||||||
|
s = cnames0[a]
|
||||||
|
}
|
||||||
|
var fp string
|
||||||
|
fp += s
|
||||||
|
return fp
|
||||||
|
}
|
1497
vendor/github.com/google/gops/internal/obj/mips/obj0.go
generated
vendored
Normal file
1497
vendor/github.com/google/gops/internal/obj/mips/obj0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
306
vendor/github.com/google/gops/internal/obj/obj.go
generated
vendored
Normal file
306
vendor/github.com/google/gops/internal/obj/obj.go
generated
vendored
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A LineHist records the history of the file input stack, which maps the virtual line number,
|
||||||
|
// an incrementing count of lines processed in any input file and typically named lineno,
|
||||||
|
// to a stack of file:line pairs showing the path of inclusions that led to that position.
|
||||||
|
// The first line directive (//line in Go, #line in assembly) is treated as pushing
|
||||||
|
// a new entry on the stack, so that errors can report both the actual and translated
|
||||||
|
// line number.
|
||||||
|
//
|
||||||
|
// In typical use, the virtual lineno begins at 1, and file line numbers also begin at 1,
|
||||||
|
// but the only requirements placed upon the numbers by this code are:
|
||||||
|
// - calls to Push, Update, and Pop must be monotonically increasing in lineno
|
||||||
|
// - except as specified by those methods, virtual and file line number increase
|
||||||
|
// together, so that given (only) calls Push(10, "x.go", 1) and Pop(15),
|
||||||
|
// virtual line 12 corresponds to x.go line 3.
|
||||||
|
type LineHist struct {
|
||||||
|
Top *LineStack // current top of stack
|
||||||
|
Ranges []LineRange // ranges for lookup
|
||||||
|
Dir string // directory to qualify relative paths
|
||||||
|
TrimPathPrefix string // remove leading TrimPath from recorded file names
|
||||||
|
PrintFilenameOnly bool // ignore path when pretty-printing a line; internal use only
|
||||||
|
GOROOT string // current GOROOT
|
||||||
|
}
|
||||||
|
|
||||||
|
// A LineStack is an entry in the recorded line history.
|
||||||
|
// Although the history at any given line number is a stack,
|
||||||
|
// the record for all line processed forms a tree, with common
|
||||||
|
// stack prefixes acting as parents.
|
||||||
|
type LineStack struct {
|
||||||
|
Parent *LineStack // parent in inclusion stack
|
||||||
|
Lineno int // virtual line number where this entry takes effect
|
||||||
|
File string // file name used to open source file, for error messages
|
||||||
|
AbsFile string // absolute file name, for pcln tables
|
||||||
|
FileLine int // line number in file at Lineno
|
||||||
|
Directive bool
|
||||||
|
Sym *LSym // for linkgetline - TODO(rsc): remove
|
||||||
|
}
|
||||||
|
|
||||||
|
func (stk *LineStack) fileLineAt(lineno int) int {
|
||||||
|
return stk.FileLine + lineno - stk.Lineno
|
||||||
|
}
|
||||||
|
|
||||||
|
// The span of valid linenos in the recorded line history can be broken
|
||||||
|
// into a set of ranges, each with a particular stack.
|
||||||
|
// A LineRange records one such range.
|
||||||
|
type LineRange struct {
|
||||||
|
Start int // starting lineno
|
||||||
|
Stack *LineStack // top of stack for this range
|
||||||
|
}
|
||||||
|
|
||||||
|
// startRange starts a new range with the given top of stack.
|
||||||
|
func (h *LineHist) startRange(lineno int, top *LineStack) {
|
||||||
|
h.Top = top
|
||||||
|
h.Ranges = append(h.Ranges, LineRange{top.Lineno, top})
|
||||||
|
}
|
||||||
|
|
||||||
|
// setFile sets stk.File = file and also derives stk.AbsFile.
|
||||||
|
func (h *LineHist) setFile(stk *LineStack, file string) {
|
||||||
|
// Note: The exclusion of stk.Directive may be wrong but matches what we've done before.
|
||||||
|
// The check for < avoids putting a path prefix on "<autogenerated>".
|
||||||
|
abs := file
|
||||||
|
if h.Dir != "" && !filepath.IsAbs(file) && !strings.HasPrefix(file, "<") && !stk.Directive {
|
||||||
|
abs = filepath.Join(h.Dir, file)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove leading TrimPathPrefix, or else rewrite $GOROOT to literal $GOROOT.
|
||||||
|
if h.TrimPathPrefix != "" && hasPathPrefix(abs, h.TrimPathPrefix) {
|
||||||
|
if abs == h.TrimPathPrefix {
|
||||||
|
abs = ""
|
||||||
|
} else {
|
||||||
|
abs = abs[len(h.TrimPathPrefix)+1:]
|
||||||
|
}
|
||||||
|
} else if hasPathPrefix(abs, h.GOROOT) {
|
||||||
|
abs = "$GOROOT" + abs[len(h.GOROOT):]
|
||||||
|
}
|
||||||
|
if abs == "" {
|
||||||
|
abs = "??"
|
||||||
|
}
|
||||||
|
abs = filepath.Clean(abs)
|
||||||
|
stk.AbsFile = abs
|
||||||
|
|
||||||
|
if file == "" {
|
||||||
|
file = "??"
|
||||||
|
}
|
||||||
|
stk.File = file
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does s have t as a path prefix?
|
||||||
|
// That is, does s == t or does s begin with t followed by a slash?
|
||||||
|
// For portability, we allow ASCII case folding, so that hasPathPrefix("a/b/c", "A/B") is true.
|
||||||
|
// Similarly, we allow slash folding, so that hasPathPrefix("a/b/c", "a\\b") is true.
|
||||||
|
// We do not allow full Unicode case folding, for fear of causing more confusion
|
||||||
|
// or harm than good. (For an example of the kinds of things that can go wrong,
|
||||||
|
// see http://article.gmane.org/gmane.linux.kernel/1853266.)
|
||||||
|
func hasPathPrefix(s string, t string) bool {
|
||||||
|
if len(t) > len(s) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
var i int
|
||||||
|
for i = 0; i < len(t); i++ {
|
||||||
|
cs := int(s[i])
|
||||||
|
ct := int(t[i])
|
||||||
|
if 'A' <= cs && cs <= 'Z' {
|
||||||
|
cs += 'a' - 'A'
|
||||||
|
}
|
||||||
|
if 'A' <= ct && ct <= 'Z' {
|
||||||
|
ct += 'a' - 'A'
|
||||||
|
}
|
||||||
|
if cs == '\\' {
|
||||||
|
cs = '/'
|
||||||
|
}
|
||||||
|
if ct == '\\' {
|
||||||
|
ct = '/'
|
||||||
|
}
|
||||||
|
if cs != ct {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i >= len(s) || s[i] == '/' || s[i] == '\\'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push records that at that lineno a new file with the given name was pushed onto the input stack.
|
||||||
|
func (h *LineHist) Push(lineno int, file string) {
|
||||||
|
stk := &LineStack{
|
||||||
|
Parent: h.Top,
|
||||||
|
Lineno: lineno,
|
||||||
|
FileLine: 1,
|
||||||
|
}
|
||||||
|
h.setFile(stk, file)
|
||||||
|
h.startRange(lineno, stk)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pop records that at lineno the current file was popped from the input stack.
|
||||||
|
func (h *LineHist) Pop(lineno int) {
|
||||||
|
top := h.Top
|
||||||
|
if top == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if top.Directive && top.Parent != nil { // pop #line level too
|
||||||
|
top = top.Parent
|
||||||
|
}
|
||||||
|
next := top.Parent
|
||||||
|
if next == nil {
|
||||||
|
h.Top = nil
|
||||||
|
h.Ranges = append(h.Ranges, LineRange{lineno, nil})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Popping included file. Update parent offset to account for
|
||||||
|
// the virtual line number range taken by the included file.
|
||||||
|
// Cannot modify the LineStack directly, or else lookups
|
||||||
|
// for the earlier line numbers will get the wrong answers,
|
||||||
|
// so make a new one.
|
||||||
|
stk := new(LineStack)
|
||||||
|
*stk = *next
|
||||||
|
stk.Lineno = lineno
|
||||||
|
stk.FileLine = next.fileLineAt(top.Lineno)
|
||||||
|
h.startRange(lineno, stk)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update records that at lineno the file name and line number were changed using
|
||||||
|
// a line directive (//line in Go, #line in assembly).
|
||||||
|
func (h *LineHist) Update(lineno int, file string, line int) {
|
||||||
|
top := h.Top
|
||||||
|
if top == nil {
|
||||||
|
return // shouldn't happen
|
||||||
|
}
|
||||||
|
var stk *LineStack
|
||||||
|
if top.Directive {
|
||||||
|
// Update existing entry, except make copy to avoid changing earlier history.
|
||||||
|
stk = new(LineStack)
|
||||||
|
*stk = *top
|
||||||
|
} else {
|
||||||
|
// Push new entry.
|
||||||
|
stk = &LineStack{
|
||||||
|
Parent: top,
|
||||||
|
Directive: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stk.Lineno = lineno
|
||||||
|
if stk.File != file {
|
||||||
|
h.setFile(stk, file) // only retain string if needed
|
||||||
|
}
|
||||||
|
stk.FileLine = line
|
||||||
|
h.startRange(lineno, stk)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImport adds a package to the list of imported packages.
|
||||||
|
func (ctxt *Link) AddImport(pkg string) {
|
||||||
|
ctxt.Imports = append(ctxt.Imports, pkg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// At returns the input stack in effect at lineno.
|
||||||
|
func (h *LineHist) At(lineno int) *LineStack {
|
||||||
|
i := sort.Search(len(h.Ranges), func(i int) bool {
|
||||||
|
return h.Ranges[i].Start > lineno
|
||||||
|
})
|
||||||
|
// Found first entry beyond lineno.
|
||||||
|
if i == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return h.Ranges[i-1].Stack
|
||||||
|
}
|
||||||
|
|
||||||
|
// LineString returns a string giving the file and line number
|
||||||
|
// corresponding to lineno, for use in error messages.
|
||||||
|
func (h *LineHist) LineString(lineno int) string {
|
||||||
|
stk := h.At(lineno)
|
||||||
|
if stk == nil {
|
||||||
|
return "<unknown line number>"
|
||||||
|
}
|
||||||
|
|
||||||
|
filename := stk.File
|
||||||
|
if h.PrintFilenameOnly {
|
||||||
|
filename = filepath.Base(filename)
|
||||||
|
}
|
||||||
|
text := fmt.Sprintf("%s:%d", filename, stk.fileLineAt(lineno))
|
||||||
|
if stk.Directive && stk.Parent != nil {
|
||||||
|
stk = stk.Parent
|
||||||
|
filename = stk.File
|
||||||
|
if h.PrintFilenameOnly {
|
||||||
|
filename = filepath.Base(filename)
|
||||||
|
}
|
||||||
|
text += fmt.Sprintf("[%s:%d]", filename, stk.fileLineAt(lineno))
|
||||||
|
}
|
||||||
|
const showFullStack = false // was used by old C compilers
|
||||||
|
if showFullStack {
|
||||||
|
for stk.Parent != nil {
|
||||||
|
lineno = stk.Lineno - 1
|
||||||
|
stk = stk.Parent
|
||||||
|
text += fmt.Sprintf(" %s:%d", filename, stk.fileLineAt(lineno))
|
||||||
|
if stk.Directive && stk.Parent != nil {
|
||||||
|
stk = stk.Parent
|
||||||
|
text += fmt.Sprintf("[%s:%d]", filename, stk.fileLineAt(lineno))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileLine returns the file name and line number
|
||||||
|
// at the top of the stack for the given lineno.
|
||||||
|
func (h *LineHist) FileLine(lineno int) (file string, line int) {
|
||||||
|
stk := h.At(lineno)
|
||||||
|
if stk == nil {
|
||||||
|
return "??", 0
|
||||||
|
}
|
||||||
|
return stk.File, stk.fileLineAt(lineno)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AbsFileLine returns the absolute file name and line number
|
||||||
|
// at the top of the stack for the given lineno.
|
||||||
|
func (h *LineHist) AbsFileLine(lineno int) (file string, line int) {
|
||||||
|
stk := h.At(lineno)
|
||||||
|
if stk == nil {
|
||||||
|
return "??", 0
|
||||||
|
}
|
||||||
|
return stk.AbsFile, stk.fileLineAt(lineno)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a simplified copy of linklinefmt above.
|
||||||
|
// It doesn't allow printing the full stack, and it returns the file name and line number separately.
|
||||||
|
// TODO: Unify with linklinefmt somehow.
|
||||||
|
func linkgetline(ctxt *Link, lineno int32) (f *LSym, l int32) {
|
||||||
|
stk := ctxt.LineHist.At(int(lineno))
|
||||||
|
if stk == nil || stk.AbsFile == "" {
|
||||||
|
return Linklookup(ctxt, "??", HistVersion), 0
|
||||||
|
}
|
||||||
|
if stk.Sym == nil {
|
||||||
|
stk.Sym = Linklookup(ctxt, stk.AbsFile, HistVersion)
|
||||||
|
}
|
||||||
|
return stk.Sym, int32(stk.fileLineAt(int(lineno)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Linkprfile(ctxt *Link, line int) {
|
||||||
|
fmt.Printf("%s ", ctxt.LineHist.LineString(line))
|
||||||
|
}
|
||||||
|
|
||||||
|
func fieldtrack(ctxt *Link, cursym *LSym) {
|
||||||
|
p := cursym.Text
|
||||||
|
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctxt.Cursym = cursym
|
||||||
|
|
||||||
|
for ; p != nil; p = p.Link {
|
||||||
|
if p.As == AUSEFIELD {
|
||||||
|
r := Addrel(ctxt.Cursym)
|
||||||
|
r.Off = 0
|
||||||
|
r.Siz = 0
|
||||||
|
r.Sym = p.From.Sym
|
||||||
|
r.Type = R_USEFIELD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
606
vendor/github.com/google/gops/internal/obj/objfile.go
generated
vendored
Normal file
606
vendor/github.com/google/gops/internal/obj/objfile.go
generated
vendored
Normal file
@ -0,0 +1,606 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Writing of Go object files.
|
||||||
|
//
|
||||||
|
// Originally, Go object files were Plan 9 object files, but no longer.
|
||||||
|
// Now they are more like standard object files, in that each symbol is defined
|
||||||
|
// by an associated memory image (bytes) and a list of relocations to apply
|
||||||
|
// during linking. We do not (yet?) use a standard file format, however.
|
||||||
|
// For now, the format is chosen to be as simple as possible to read and write.
|
||||||
|
// It may change for reasons of efficiency, or we may even switch to a
|
||||||
|
// standard file format if there are compelling benefits to doing so.
|
||||||
|
// See golang.org/s/go13linker for more background.
|
||||||
|
//
|
||||||
|
// The file format is:
|
||||||
|
//
|
||||||
|
// - magic header: "\x00\x00go17ld"
|
||||||
|
// - byte 1 - version number
|
||||||
|
// - sequence of strings giving dependencies (imported packages)
|
||||||
|
// - empty string (marks end of sequence)
|
||||||
|
// - sequence of symbol references used by the defined symbols
|
||||||
|
// - byte 0xff (marks end of sequence)
|
||||||
|
// - sequence of integer lengths:
|
||||||
|
// - total data length
|
||||||
|
// - total number of relocations
|
||||||
|
// - total number of pcdata
|
||||||
|
// - total number of automatics
|
||||||
|
// - total number of funcdata
|
||||||
|
// - total number of files
|
||||||
|
// - data, the content of the defined symbols
|
||||||
|
// - sequence of defined symbols
|
||||||
|
// - byte 0xff (marks end of sequence)
|
||||||
|
// - magic footer: "\xff\xffgo17ld"
|
||||||
|
//
|
||||||
|
// All integers are stored in a zigzag varint format.
|
||||||
|
// See golang.org/s/go12symtab for a definition.
|
||||||
|
//
|
||||||
|
// Data blocks and strings are both stored as an integer
|
||||||
|
// followed by that many bytes.
|
||||||
|
//
|
||||||
|
// A symbol reference is a string name followed by a version.
|
||||||
|
//
|
||||||
|
// A symbol points to other symbols using an index into the symbol
|
||||||
|
// reference sequence. Index 0 corresponds to a nil LSym* pointer.
|
||||||
|
// In the symbol layout described below "symref index" stands for this
|
||||||
|
// index.
|
||||||
|
//
|
||||||
|
// Each symbol is laid out as the following fields (taken from LSym*):
|
||||||
|
//
|
||||||
|
// - byte 0xfe (sanity check for synchronization)
|
||||||
|
// - type [int]
|
||||||
|
// - name & version [symref index]
|
||||||
|
// - flags [int]
|
||||||
|
// 1<<0 dupok
|
||||||
|
// 1<<1 local
|
||||||
|
// 1<<2 add to typelink table
|
||||||
|
// - size [int]
|
||||||
|
// - gotype [symref index]
|
||||||
|
// - p [data block]
|
||||||
|
// - nr [int]
|
||||||
|
// - r [nr relocations, sorted by off]
|
||||||
|
//
|
||||||
|
// If type == STEXT, there are a few more fields:
|
||||||
|
//
|
||||||
|
// - args [int]
|
||||||
|
// - locals [int]
|
||||||
|
// - nosplit [int]
|
||||||
|
// - flags [int]
|
||||||
|
// 1<<0 leaf
|
||||||
|
// 1<<1 C function
|
||||||
|
// 1<<2 function may call reflect.Type.Method
|
||||||
|
// - nlocal [int]
|
||||||
|
// - local [nlocal automatics]
|
||||||
|
// - pcln [pcln table]
|
||||||
|
//
|
||||||
|
// Each relocation has the encoding:
|
||||||
|
//
|
||||||
|
// - off [int]
|
||||||
|
// - siz [int]
|
||||||
|
// - type [int]
|
||||||
|
// - add [int]
|
||||||
|
// - sym [symref index]
|
||||||
|
//
|
||||||
|
// Each local has the encoding:
|
||||||
|
//
|
||||||
|
// - asym [symref index]
|
||||||
|
// - offset [int]
|
||||||
|
// - type [int]
|
||||||
|
// - gotype [symref index]
|
||||||
|
//
|
||||||
|
// The pcln table has the encoding:
|
||||||
|
//
|
||||||
|
// - pcsp [data block]
|
||||||
|
// - pcfile [data block]
|
||||||
|
// - pcline [data block]
|
||||||
|
// - npcdata [int]
|
||||||
|
// - pcdata [npcdata data blocks]
|
||||||
|
// - nfuncdata [int]
|
||||||
|
// - funcdata [nfuncdata symref index]
|
||||||
|
// - funcdatasym [nfuncdata ints]
|
||||||
|
// - nfile [int]
|
||||||
|
// - file [nfile symref index]
|
||||||
|
//
|
||||||
|
// The file layout and meaning of type integers are architecture-independent.
|
||||||
|
//
|
||||||
|
// TODO(rsc): The file format is good for a first pass but needs work.
|
||||||
|
// - There are SymID in the object file that should really just be strings.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/google/gops/internal/dwarf"
|
||||||
|
"github.com/google/gops/internal/sys"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The Go and C compilers, and the assembler, call writeobj to write
|
||||||
|
// out a Go object file. The linker does not call this; the linker
|
||||||
|
// does not write out object files.
|
||||||
|
func Writeobjdirect(ctxt *Link, b *bufio.Writer) {
|
||||||
|
Flushplist(ctxt)
|
||||||
|
WriteObjFile(ctxt, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// objWriter writes Go object files.
|
||||||
|
type objWriter struct {
|
||||||
|
wr *bufio.Writer
|
||||||
|
ctxt *Link
|
||||||
|
// Temporary buffer for zigzag int writing.
|
||||||
|
varintbuf [10]uint8
|
||||||
|
|
||||||
|
// Provide the the index of a symbol reference by symbol name.
|
||||||
|
// One map for versioned symbols and one for unversioned symbols.
|
||||||
|
// Used for deduplicating the symbol reference list.
|
||||||
|
refIdx map[string]int
|
||||||
|
vrefIdx map[string]int
|
||||||
|
|
||||||
|
// Number of objects written of each type.
|
||||||
|
nRefs int
|
||||||
|
nData int
|
||||||
|
nReloc int
|
||||||
|
nPcdata int
|
||||||
|
nAutom int
|
||||||
|
nFuncdata int
|
||||||
|
nFile int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *objWriter) addLengths(s *LSym) {
|
||||||
|
w.nData += len(s.P)
|
||||||
|
w.nReloc += len(s.R)
|
||||||
|
|
||||||
|
if s.Type != STEXT {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pc := s.Pcln
|
||||||
|
|
||||||
|
data := 0
|
||||||
|
data += len(pc.Pcsp.P)
|
||||||
|
data += len(pc.Pcfile.P)
|
||||||
|
data += len(pc.Pcline.P)
|
||||||
|
for i := 0; i < len(pc.Pcdata); i++ {
|
||||||
|
data += len(pc.Pcdata[i].P)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.nData += data
|
||||||
|
w.nPcdata += len(pc.Pcdata)
|
||||||
|
|
||||||
|
autom := 0
|
||||||
|
for a := s.Autom; a != nil; a = a.Link {
|
||||||
|
autom++
|
||||||
|
}
|
||||||
|
w.nAutom += autom
|
||||||
|
w.nFuncdata += len(pc.Funcdataoff)
|
||||||
|
w.nFile += len(pc.File)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *objWriter) writeLengths() {
|
||||||
|
w.writeInt(int64(w.nData))
|
||||||
|
w.writeInt(int64(w.nReloc))
|
||||||
|
w.writeInt(int64(w.nPcdata))
|
||||||
|
w.writeInt(int64(w.nAutom))
|
||||||
|
w.writeInt(int64(w.nFuncdata))
|
||||||
|
w.writeInt(int64(w.nFile))
|
||||||
|
}
|
||||||
|
|
||||||
|
func newObjWriter(ctxt *Link, b *bufio.Writer) *objWriter {
|
||||||
|
return &objWriter{
|
||||||
|
ctxt: ctxt,
|
||||||
|
wr: b,
|
||||||
|
vrefIdx: make(map[string]int),
|
||||||
|
refIdx: make(map[string]int),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteObjFile(ctxt *Link, b *bufio.Writer) {
|
||||||
|
w := newObjWriter(ctxt, b)
|
||||||
|
|
||||||
|
// Magic header
|
||||||
|
w.wr.WriteString("\x00\x00go17ld")
|
||||||
|
|
||||||
|
// Version
|
||||||
|
w.wr.WriteByte(1)
|
||||||
|
|
||||||
|
// Autolib
|
||||||
|
for _, pkg := range ctxt.Imports {
|
||||||
|
w.writeString(pkg)
|
||||||
|
}
|
||||||
|
w.writeString("")
|
||||||
|
|
||||||
|
// Symbol references
|
||||||
|
for _, s := range ctxt.Text {
|
||||||
|
w.writeRefs(s)
|
||||||
|
w.addLengths(s)
|
||||||
|
}
|
||||||
|
for _, s := range ctxt.Data {
|
||||||
|
w.writeRefs(s)
|
||||||
|
w.addLengths(s)
|
||||||
|
}
|
||||||
|
// End symbol references
|
||||||
|
w.wr.WriteByte(0xff)
|
||||||
|
|
||||||
|
// Lengths
|
||||||
|
w.writeLengths()
|
||||||
|
|
||||||
|
// Data block
|
||||||
|
for _, s := range ctxt.Text {
|
||||||
|
w.wr.Write(s.P)
|
||||||
|
pc := s.Pcln
|
||||||
|
w.wr.Write(pc.Pcsp.P)
|
||||||
|
w.wr.Write(pc.Pcfile.P)
|
||||||
|
w.wr.Write(pc.Pcline.P)
|
||||||
|
for i := 0; i < len(pc.Pcdata); i++ {
|
||||||
|
w.wr.Write(pc.Pcdata[i].P)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, s := range ctxt.Data {
|
||||||
|
w.wr.Write(s.P)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Symbols
|
||||||
|
for _, s := range ctxt.Text {
|
||||||
|
w.writeSym(s)
|
||||||
|
}
|
||||||
|
for _, s := range ctxt.Data {
|
||||||
|
w.writeSym(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magic footer
|
||||||
|
w.wr.WriteString("\xff\xffgo17ld")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Symbols are prefixed so their content doesn't get confused with the magic footer.
|
||||||
|
const symPrefix = 0xfe
|
||||||
|
|
||||||
|
func (w *objWriter) writeRef(s *LSym, isPath bool) {
|
||||||
|
if s == nil || s.RefIdx != 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var m map[string]int
|
||||||
|
switch s.Version {
|
||||||
|
case 0:
|
||||||
|
m = w.refIdx
|
||||||
|
case 1:
|
||||||
|
m = w.vrefIdx
|
||||||
|
default:
|
||||||
|
log.Fatalf("%s: invalid version number %d", s.Name, s.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
idx := m[s.Name]
|
||||||
|
if idx != 0 {
|
||||||
|
s.RefIdx = idx
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.wr.WriteByte(symPrefix)
|
||||||
|
if isPath {
|
||||||
|
w.writeString(filepath.ToSlash(s.Name))
|
||||||
|
} else {
|
||||||
|
w.writeString(s.Name)
|
||||||
|
}
|
||||||
|
w.writeInt(int64(s.Version))
|
||||||
|
w.nRefs++
|
||||||
|
s.RefIdx = w.nRefs
|
||||||
|
m[s.Name] = w.nRefs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *objWriter) writeRefs(s *LSym) {
|
||||||
|
w.writeRef(s, false)
|
||||||
|
w.writeRef(s.Gotype, false)
|
||||||
|
for i := range s.R {
|
||||||
|
w.writeRef(s.R[i].Sym, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Type == STEXT {
|
||||||
|
for a := s.Autom; a != nil; a = a.Link {
|
||||||
|
w.writeRef(a.Asym, false)
|
||||||
|
w.writeRef(a.Gotype, false)
|
||||||
|
}
|
||||||
|
pc := s.Pcln
|
||||||
|
for _, d := range pc.Funcdata {
|
||||||
|
w.writeRef(d, false)
|
||||||
|
}
|
||||||
|
for _, f := range pc.File {
|
||||||
|
w.writeRef(f, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *objWriter) writeSymDebug(s *LSym) {
|
||||||
|
ctxt := w.ctxt
|
||||||
|
fmt.Fprintf(ctxt.Bso, "%s ", s.Name)
|
||||||
|
if s.Version != 0 {
|
||||||
|
fmt.Fprintf(ctxt.Bso, "v=%d ", s.Version)
|
||||||
|
}
|
||||||
|
if s.Type != 0 {
|
||||||
|
fmt.Fprintf(ctxt.Bso, "t=%d ", s.Type)
|
||||||
|
}
|
||||||
|
if s.DuplicateOK() {
|
||||||
|
fmt.Fprintf(ctxt.Bso, "dupok ")
|
||||||
|
}
|
||||||
|
if s.CFunc() {
|
||||||
|
fmt.Fprintf(ctxt.Bso, "cfunc ")
|
||||||
|
}
|
||||||
|
if s.NoSplit() {
|
||||||
|
fmt.Fprintf(ctxt.Bso, "nosplit ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(ctxt.Bso, "size=%d", s.Size)
|
||||||
|
if s.Type == STEXT {
|
||||||
|
fmt.Fprintf(ctxt.Bso, " args=%#x locals=%#x", uint64(s.Args), uint64(s.Locals))
|
||||||
|
if s.Leaf() {
|
||||||
|
fmt.Fprintf(ctxt.Bso, " leaf")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(ctxt.Bso, "\n")
|
||||||
|
for p := s.Text; p != nil; p = p.Link {
|
||||||
|
fmt.Fprintf(ctxt.Bso, "\t%#04x %v\n", uint(int(p.Pc)), p)
|
||||||
|
}
|
||||||
|
var c int
|
||||||
|
var j int
|
||||||
|
for i := 0; i < len(s.P); {
|
||||||
|
fmt.Fprintf(ctxt.Bso, "\t%#04x", uint(i))
|
||||||
|
for j = i; j < i+16 && j < len(s.P); j++ {
|
||||||
|
fmt.Fprintf(ctxt.Bso, " %02x", s.P[j])
|
||||||
|
}
|
||||||
|
for ; j < i+16; j++ {
|
||||||
|
fmt.Fprintf(ctxt.Bso, " ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(ctxt.Bso, " ")
|
||||||
|
for j = i; j < i+16 && j < len(s.P); j++ {
|
||||||
|
c = int(s.P[j])
|
||||||
|
if ' ' <= c && c <= 0x7e {
|
||||||
|
fmt.Fprintf(ctxt.Bso, "%c", c)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(ctxt.Bso, ".")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(ctxt.Bso, "\n")
|
||||||
|
i += 16
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(relocByOff(s.R)) // generate stable output
|
||||||
|
for _, r := range s.R {
|
||||||
|
name := ""
|
||||||
|
if r.Sym != nil {
|
||||||
|
name = r.Sym.Name
|
||||||
|
} else if r.Type == R_TLS_LE {
|
||||||
|
name = "TLS"
|
||||||
|
}
|
||||||
|
if ctxt.Arch.InFamily(sys.ARM, sys.PPC64) {
|
||||||
|
fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%x\n", int(r.Off), r.Siz, r.Type, name, uint64(r.Add))
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type, name, r.Add)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *objWriter) writeSym(s *LSym) {
|
||||||
|
ctxt := w.ctxt
|
||||||
|
if ctxt.Debugasm != 0 {
|
||||||
|
w.writeSymDebug(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.wr.WriteByte(symPrefix)
|
||||||
|
w.writeInt(int64(s.Type))
|
||||||
|
w.writeRefIndex(s)
|
||||||
|
flags := int64(0)
|
||||||
|
if s.DuplicateOK() {
|
||||||
|
flags |= 1
|
||||||
|
}
|
||||||
|
if s.Local() {
|
||||||
|
flags |= 1 << 1
|
||||||
|
}
|
||||||
|
if s.MakeTypelink() {
|
||||||
|
flags |= 1 << 2
|
||||||
|
}
|
||||||
|
w.writeInt(flags)
|
||||||
|
w.writeInt(s.Size)
|
||||||
|
w.writeRefIndex(s.Gotype)
|
||||||
|
w.writeInt(int64(len(s.P)))
|
||||||
|
|
||||||
|
w.writeInt(int64(len(s.R)))
|
||||||
|
var r *Reloc
|
||||||
|
for i := 0; i < len(s.R); i++ {
|
||||||
|
r = &s.R[i]
|
||||||
|
w.writeInt(int64(r.Off))
|
||||||
|
w.writeInt(int64(r.Siz))
|
||||||
|
w.writeInt(int64(r.Type))
|
||||||
|
w.writeInt(r.Add)
|
||||||
|
w.writeRefIndex(r.Sym)
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Type != STEXT {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.writeInt(int64(s.Args))
|
||||||
|
w.writeInt(int64(s.Locals))
|
||||||
|
if s.NoSplit() {
|
||||||
|
w.writeInt(1)
|
||||||
|
} else {
|
||||||
|
w.writeInt(0)
|
||||||
|
}
|
||||||
|
flags = int64(0)
|
||||||
|
if s.Leaf() {
|
||||||
|
flags |= 1
|
||||||
|
}
|
||||||
|
if s.CFunc() {
|
||||||
|
flags |= 1 << 1
|
||||||
|
}
|
||||||
|
if s.ReflectMethod() {
|
||||||
|
flags |= 1 << 2
|
||||||
|
}
|
||||||
|
w.writeInt(flags)
|
||||||
|
n := 0
|
||||||
|
for a := s.Autom; a != nil; a = a.Link {
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
w.writeInt(int64(n))
|
||||||
|
for a := s.Autom; a != nil; a = a.Link {
|
||||||
|
w.writeRefIndex(a.Asym)
|
||||||
|
w.writeInt(int64(a.Aoffset))
|
||||||
|
if a.Name == NAME_AUTO {
|
||||||
|
w.writeInt(A_AUTO)
|
||||||
|
} else if a.Name == NAME_PARAM {
|
||||||
|
w.writeInt(A_PARAM)
|
||||||
|
} else {
|
||||||
|
log.Fatalf("%s: invalid local variable type %d", s.Name, a.Name)
|
||||||
|
}
|
||||||
|
w.writeRefIndex(a.Gotype)
|
||||||
|
}
|
||||||
|
|
||||||
|
pc := s.Pcln
|
||||||
|
w.writeInt(int64(len(pc.Pcsp.P)))
|
||||||
|
w.writeInt(int64(len(pc.Pcfile.P)))
|
||||||
|
w.writeInt(int64(len(pc.Pcline.P)))
|
||||||
|
w.writeInt(int64(len(pc.Pcdata)))
|
||||||
|
for i := 0; i < len(pc.Pcdata); i++ {
|
||||||
|
w.writeInt(int64(len(pc.Pcdata[i].P)))
|
||||||
|
}
|
||||||
|
w.writeInt(int64(len(pc.Funcdataoff)))
|
||||||
|
for i := 0; i < len(pc.Funcdataoff); i++ {
|
||||||
|
w.writeRefIndex(pc.Funcdata[i])
|
||||||
|
}
|
||||||
|
for i := 0; i < len(pc.Funcdataoff); i++ {
|
||||||
|
w.writeInt(pc.Funcdataoff[i])
|
||||||
|
}
|
||||||
|
w.writeInt(int64(len(pc.File)))
|
||||||
|
for _, f := range pc.File {
|
||||||
|
w.writeRefIndex(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *objWriter) writeInt(sval int64) {
|
||||||
|
var v uint64
|
||||||
|
uv := (uint64(sval) << 1) ^ uint64(sval>>63)
|
||||||
|
p := w.varintbuf[:]
|
||||||
|
for v = uv; v >= 0x80; v >>= 7 {
|
||||||
|
p[0] = uint8(v | 0x80)
|
||||||
|
p = p[1:]
|
||||||
|
}
|
||||||
|
p[0] = uint8(v)
|
||||||
|
p = p[1:]
|
||||||
|
w.wr.Write(w.varintbuf[:len(w.varintbuf)-len(p)])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *objWriter) writeString(s string) {
|
||||||
|
w.writeInt(int64(len(s)))
|
||||||
|
w.wr.WriteString(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *objWriter) writeRefIndex(s *LSym) {
|
||||||
|
if s == nil {
|
||||||
|
w.writeInt(0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if s.RefIdx == 0 {
|
||||||
|
log.Fatalln("writing an unreferenced symbol", s.Name)
|
||||||
|
}
|
||||||
|
w.writeInt(int64(s.RefIdx))
|
||||||
|
}
|
||||||
|
|
||||||
|
// relocByOff sorts relocations by their offsets.
|
||||||
|
type relocByOff []Reloc
|
||||||
|
|
||||||
|
func (x relocByOff) Len() int { return len(x) }
|
||||||
|
func (x relocByOff) Less(i, j int) bool { return x[i].Off < x[j].Off }
|
||||||
|
func (x relocByOff) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||||
|
|
||||||
|
// implement dwarf.Context
|
||||||
|
type dwCtxt struct{ *Link }
|
||||||
|
|
||||||
|
func (c dwCtxt) PtrSize() int {
|
||||||
|
return c.Arch.PtrSize
|
||||||
|
}
|
||||||
|
func (c dwCtxt) AddInt(s dwarf.Sym, size int, i int64) {
|
||||||
|
ls := s.(*LSym)
|
||||||
|
ls.WriteInt(c.Link, ls.Size, size, i)
|
||||||
|
}
|
||||||
|
func (c dwCtxt) AddBytes(s dwarf.Sym, b []byte) {
|
||||||
|
ls := s.(*LSym)
|
||||||
|
ls.WriteBytes(c.Link, ls.Size, b)
|
||||||
|
}
|
||||||
|
func (c dwCtxt) AddString(s dwarf.Sym, v string) {
|
||||||
|
ls := s.(*LSym)
|
||||||
|
ls.WriteString(c.Link, ls.Size, len(v), v)
|
||||||
|
ls.WriteInt(c.Link, ls.Size, 1, 0)
|
||||||
|
}
|
||||||
|
func (c dwCtxt) SymValue(s dwarf.Sym) int64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
func (c dwCtxt) AddAddress(s dwarf.Sym, data interface{}, value int64) {
|
||||||
|
rsym := data.(*LSym)
|
||||||
|
ls := s.(*LSym)
|
||||||
|
size := c.PtrSize()
|
||||||
|
ls.WriteAddr(c.Link, ls.Size, size, rsym, value)
|
||||||
|
}
|
||||||
|
func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
|
||||||
|
ls := s.(*LSym)
|
||||||
|
rsym := t.(*LSym)
|
||||||
|
ls.WriteAddr(c.Link, ls.Size, size, rsym, ofs)
|
||||||
|
r := &ls.R[len(ls.R)-1]
|
||||||
|
r.Type = R_DWARFREF
|
||||||
|
}
|
||||||
|
|
||||||
|
func gendwarf(ctxt *Link, text []*LSym) []*LSym {
|
||||||
|
dctxt := dwCtxt{ctxt}
|
||||||
|
var dw []*LSym
|
||||||
|
|
||||||
|
for _, s := range text {
|
||||||
|
dsym := Linklookup(ctxt, dwarf.InfoPrefix+s.Name, int(s.Version))
|
||||||
|
if dsym.Size != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
dw = append(dw, dsym)
|
||||||
|
dsym.Type = SDWARFINFO
|
||||||
|
dsym.Set(AttrDuplicateOK, s.DuplicateOK())
|
||||||
|
var vars dwarf.Var
|
||||||
|
var abbrev int
|
||||||
|
var offs int32
|
||||||
|
for a := s.Autom; a != nil; a = a.Link {
|
||||||
|
switch a.Name {
|
||||||
|
case NAME_AUTO:
|
||||||
|
abbrev = dwarf.DW_ABRV_AUTO
|
||||||
|
offs = a.Aoffset
|
||||||
|
if ctxt.FixedFrameSize() == 0 {
|
||||||
|
offs -= int32(ctxt.Arch.PtrSize)
|
||||||
|
}
|
||||||
|
if Framepointer_enabled(GOOS, GOARCH) {
|
||||||
|
offs -= int32(ctxt.Arch.PtrSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
case NAME_PARAM:
|
||||||
|
abbrev = dwarf.DW_ABRV_PARAM
|
||||||
|
offs = a.Aoffset + int32(ctxt.FixedFrameSize())
|
||||||
|
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
typename := dwarf.InfoPrefix + a.Gotype.Name[len("type."):]
|
||||||
|
dwvar := &dwarf.Var{
|
||||||
|
Name: a.Asym.Name,
|
||||||
|
Abbrev: abbrev,
|
||||||
|
Offset: int32(offs),
|
||||||
|
Type: Linklookup(ctxt, typename, 0),
|
||||||
|
}
|
||||||
|
dws := &vars.Link
|
||||||
|
for ; *dws != nil; dws = &(*dws).Link {
|
||||||
|
if offs <= (*dws).Offset {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dwvar.Link = *dws
|
||||||
|
*dws = dwvar
|
||||||
|
}
|
||||||
|
dwarf.PutFunc(dctxt, dsym, s.Name, s.Version == 0, s, s.Size, vars.Link)
|
||||||
|
}
|
||||||
|
return dw
|
||||||
|
}
|
217
vendor/github.com/google/gops/internal/obj/pass.go
generated
vendored
Normal file
217
vendor/github.com/google/gops/internal/obj/pass.go
generated
vendored
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
// Inferno utils/6l/pass.c
|
||||||
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/pass.c
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
// Code and data passes.
|
||||||
|
|
||||||
|
func Brchain(ctxt *Link, p *Prog) *Prog {
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
if p == nil || p.As != AJMP || p.Pcond == nil {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
p = p.Pcond
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func brloop(ctxt *Link, p *Prog) *Prog {
|
||||||
|
var q *Prog
|
||||||
|
|
||||||
|
c := 0
|
||||||
|
for q = p; q != nil; q = q.Pcond {
|
||||||
|
if q.As != AJMP || q.Pcond == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c++
|
||||||
|
if c >= 5000 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return q
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkaddr(ctxt *Link, p *Prog, a *Addr) {
|
||||||
|
// Check expected encoding, especially TYPE_CONST vs TYPE_ADDR.
|
||||||
|
switch a.Type {
|
||||||
|
case TYPE_NONE:
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_BRANCH:
|
||||||
|
if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_TEXTSIZE:
|
||||||
|
if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
//if(a->u.bits != 0)
|
||||||
|
// break;
|
||||||
|
case TYPE_MEM:
|
||||||
|
return
|
||||||
|
|
||||||
|
// TODO(rsc): After fixing SHRQ, check a->index != 0 too.
|
||||||
|
case TYPE_CONST:
|
||||||
|
if a.Name != 0 || a.Sym != nil || a.Reg != 0 {
|
||||||
|
ctxt.Diag("argument is TYPE_CONST, should be TYPE_ADDR, in %v", p)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if a.Reg != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.Val != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_FCONST, TYPE_SCONST:
|
||||||
|
if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Offset != 0 || a.Sym != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
// TODO(rsc): After fixing PINSRQ, check a->offset != 0 too.
|
||||||
|
// TODO(rsc): After fixing SHRQ, check a->index != 0 too.
|
||||||
|
case TYPE_REG:
|
||||||
|
if a.Scale != 0 || a.Name != 0 || a.Sym != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_ADDR:
|
||||||
|
if a.Val != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if a.Reg == 0 && a.Index == 0 && a.Scale == 0 && a.Name == 0 && a.Sym == nil {
|
||||||
|
ctxt.Diag("argument is TYPE_ADDR, should be TYPE_CONST, in %v", p)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_SHIFT:
|
||||||
|
if a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.Val != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_REGREG:
|
||||||
|
if a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.Val != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_REGREG2:
|
||||||
|
return
|
||||||
|
|
||||||
|
case TYPE_REGLIST:
|
||||||
|
return
|
||||||
|
|
||||||
|
// Expect sym and name to be set, nothing else.
|
||||||
|
// Technically more is allowed, but this is only used for *name(SB).
|
||||||
|
case TYPE_INDIR:
|
||||||
|
if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name == 0 || a.Offset != 0 || a.Sym == nil || a.Val != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt.Diag("invalid encoding for argument %v", p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func linkpatch(ctxt *Link, sym *LSym) {
|
||||||
|
var c int32
|
||||||
|
var name string
|
||||||
|
var q *Prog
|
||||||
|
|
||||||
|
ctxt.Cursym = sym
|
||||||
|
|
||||||
|
for p := sym.Text; p != nil; p = p.Link {
|
||||||
|
checkaddr(ctxt, p, &p.From)
|
||||||
|
if p.From3 != nil {
|
||||||
|
checkaddr(ctxt, p, p.From3)
|
||||||
|
}
|
||||||
|
checkaddr(ctxt, p, &p.To)
|
||||||
|
|
||||||
|
if ctxt.Arch.Progedit != nil {
|
||||||
|
ctxt.Arch.Progedit(ctxt, p)
|
||||||
|
}
|
||||||
|
if p.To.Type != TYPE_BRANCH {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if p.To.Val != nil {
|
||||||
|
// TODO: Remove To.Val.(*Prog) in favor of p->pcond.
|
||||||
|
p.Pcond = p.To.Val.(*Prog)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.To.Sym != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
c = int32(p.To.Offset)
|
||||||
|
for q = sym.Text; q != nil; {
|
||||||
|
if int64(c) == q.Pc {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if q.Forwd != nil && int64(c) >= q.Forwd.Pc {
|
||||||
|
q = q.Forwd
|
||||||
|
} else {
|
||||||
|
q = q.Link
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if q == nil {
|
||||||
|
name = "<nil>"
|
||||||
|
if p.To.Sym != nil {
|
||||||
|
name = p.To.Sym.Name
|
||||||
|
}
|
||||||
|
ctxt.Diag("branch out of range (%#x)\n%v [%s]", uint32(c), p, name)
|
||||||
|
p.To.Type = TYPE_NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
p.To.Val = q
|
||||||
|
p.Pcond = q
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctxt.Flag_optimize {
|
||||||
|
for p := sym.Text; p != nil; p = p.Link {
|
||||||
|
if p.Pcond != nil {
|
||||||
|
p.Pcond = brloop(ctxt, p.Pcond)
|
||||||
|
if p.Pcond != nil {
|
||||||
|
if p.To.Type == TYPE_BRANCH {
|
||||||
|
p.To.Offset = p.Pcond.Pc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
281
vendor/github.com/google/gops/internal/obj/pcln.go
generated
vendored
Normal file
281
vendor/github.com/google/gops/internal/obj/pcln.go
generated
vendored
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
|
||||||
|
func addvarint(ctxt *Link, d *Pcdata, val uint32) {
|
||||||
|
var v uint32
|
||||||
|
for v = val; v >= 0x80; v >>= 7 {
|
||||||
|
d.P = append(d.P, uint8(v|0x80))
|
||||||
|
}
|
||||||
|
d.P = append(d.P, uint8(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// funcpctab writes to dst a pc-value table mapping the code in func to the values
|
||||||
|
// returned by valfunc parameterized by arg. The invocation of valfunc to update the
|
||||||
|
// current value is, for each p,
|
||||||
|
//
|
||||||
|
// val = valfunc(func, val, p, 0, arg);
|
||||||
|
// record val as value at p->pc;
|
||||||
|
// val = valfunc(func, val, p, 1, arg);
|
||||||
|
//
|
||||||
|
// where func is the function, val is the current value, p is the instruction being
|
||||||
|
// considered, and arg can be used to further parameterize valfunc.
|
||||||
|
func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*Link, *LSym, int32, *Prog, int32, interface{}) int32, arg interface{}) {
|
||||||
|
// To debug a specific function, uncomment lines and change name.
|
||||||
|
dbg := 0
|
||||||
|
|
||||||
|
//if func_.Name == "main.main" || desc == "pctospadj" {
|
||||||
|
// dbg = 1
|
||||||
|
//}
|
||||||
|
|
||||||
|
ctxt.Debugpcln += int32(dbg)
|
||||||
|
|
||||||
|
dst.P = dst.P[:0]
|
||||||
|
|
||||||
|
if ctxt.Debugpcln != 0 {
|
||||||
|
ctxt.Logf("funcpctab %s [valfunc=%s]\n", func_.Name, desc)
|
||||||
|
}
|
||||||
|
|
||||||
|
val := int32(-1)
|
||||||
|
oldval := val
|
||||||
|
if func_.Text == nil {
|
||||||
|
ctxt.Debugpcln -= int32(dbg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pc := func_.Text.Pc
|
||||||
|
|
||||||
|
if ctxt.Debugpcln != 0 {
|
||||||
|
ctxt.Logf("%6x %6d %v\n", uint64(pc), val, func_.Text)
|
||||||
|
}
|
||||||
|
|
||||||
|
started := int32(0)
|
||||||
|
var delta uint32
|
||||||
|
for p := func_.Text; p != nil; p = p.Link {
|
||||||
|
// Update val. If it's not changing, keep going.
|
||||||
|
val = valfunc(ctxt, func_, val, p, 0, arg)
|
||||||
|
|
||||||
|
if val == oldval && started != 0 {
|
||||||
|
val = valfunc(ctxt, func_, val, p, 1, arg)
|
||||||
|
if ctxt.Debugpcln != 0 {
|
||||||
|
ctxt.Logf("%6x %6s %v\n", uint64(p.Pc), "", p)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the pc of the next instruction is the same as the
|
||||||
|
// pc of this instruction, this instruction is not a real
|
||||||
|
// instruction. Keep going, so that we only emit a delta
|
||||||
|
// for a true instruction boundary in the program.
|
||||||
|
if p.Link != nil && p.Link.Pc == p.Pc {
|
||||||
|
val = valfunc(ctxt, func_, val, p, 1, arg)
|
||||||
|
if ctxt.Debugpcln != 0 {
|
||||||
|
ctxt.Logf("%6x %6s %v\n", uint64(p.Pc), "", p)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// The table is a sequence of (value, pc) pairs, where each
|
||||||
|
// pair states that the given value is in effect from the current position
|
||||||
|
// up to the given pc, which becomes the new current position.
|
||||||
|
// To generate the table as we scan over the program instructions,
|
||||||
|
// we emit a "(value" when pc == func->value, and then
|
||||||
|
// each time we observe a change in value we emit ", pc) (value".
|
||||||
|
// When the scan is over, we emit the closing ", pc)".
|
||||||
|
//
|
||||||
|
// The table is delta-encoded. The value deltas are signed and
|
||||||
|
// transmitted in zig-zag form, where a complement bit is placed in bit 0,
|
||||||
|
// and the pc deltas are unsigned. Both kinds of deltas are sent
|
||||||
|
// as variable-length little-endian base-128 integers,
|
||||||
|
// where the 0x80 bit indicates that the integer continues.
|
||||||
|
|
||||||
|
if ctxt.Debugpcln != 0 {
|
||||||
|
ctxt.Logf("%6x %6d %v\n", uint64(p.Pc), val, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
if started != 0 {
|
||||||
|
addvarint(ctxt, dst, uint32((p.Pc-pc)/int64(ctxt.Arch.MinLC)))
|
||||||
|
pc = p.Pc
|
||||||
|
}
|
||||||
|
|
||||||
|
delta = uint32(val) - uint32(oldval)
|
||||||
|
if delta>>31 != 0 {
|
||||||
|
delta = 1 | ^(delta << 1)
|
||||||
|
} else {
|
||||||
|
delta <<= 1
|
||||||
|
}
|
||||||
|
addvarint(ctxt, dst, delta)
|
||||||
|
oldval = val
|
||||||
|
started = 1
|
||||||
|
val = valfunc(ctxt, func_, val, p, 1, arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
if started != 0 {
|
||||||
|
if ctxt.Debugpcln != 0 {
|
||||||
|
ctxt.Logf("%6x done\n", uint64(func_.Text.Pc+func_.Size))
|
||||||
|
}
|
||||||
|
addvarint(ctxt, dst, uint32((func_.Size-pc)/int64(ctxt.Arch.MinLC)))
|
||||||
|
addvarint(ctxt, dst, 0) // terminator
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctxt.Debugpcln != 0 {
|
||||||
|
ctxt.Logf("wrote %d bytes to %p\n", len(dst.P), dst)
|
||||||
|
for i := 0; i < len(dst.P); i++ {
|
||||||
|
ctxt.Logf(" %02x", dst.P[i])
|
||||||
|
}
|
||||||
|
ctxt.Logf("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt.Debugpcln -= int32(dbg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// pctofileline computes either the file number (arg == 0)
|
||||||
|
// or the line number (arg == 1) to use at p.
|
||||||
|
// Because p->lineno applies to p, phase == 0 (before p)
|
||||||
|
// takes care of the update.
|
||||||
|
func pctofileline(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
|
||||||
|
if p.As == ATEXT || p.As == ANOP || p.As == AUSEFIELD || p.Lineno == 0 || phase == 1 {
|
||||||
|
return oldval
|
||||||
|
}
|
||||||
|
f, l := linkgetline(ctxt, p.Lineno)
|
||||||
|
if f == nil {
|
||||||
|
// print("getline failed for %s %v\n", ctxt->cursym->name, p);
|
||||||
|
return oldval
|
||||||
|
}
|
||||||
|
|
||||||
|
if arg == nil {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
pcln := arg.(*Pcln)
|
||||||
|
|
||||||
|
if f == pcln.Lastfile {
|
||||||
|
return int32(pcln.Lastindex)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, file := range pcln.File {
|
||||||
|
if file == f {
|
||||||
|
pcln.Lastfile = f
|
||||||
|
pcln.Lastindex = i
|
||||||
|
return int32(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i := len(pcln.File)
|
||||||
|
pcln.File = append(pcln.File, f)
|
||||||
|
pcln.Lastfile = f
|
||||||
|
pcln.Lastindex = i
|
||||||
|
return int32(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// pctospadj computes the sp adjustment in effect.
|
||||||
|
// It is oldval plus any adjustment made by p itself.
|
||||||
|
// The adjustment by p takes effect only after p, so we
|
||||||
|
// apply the change during phase == 1.
|
||||||
|
func pctospadj(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
|
||||||
|
if oldval == -1 { // starting
|
||||||
|
oldval = 0
|
||||||
|
}
|
||||||
|
if phase == 0 {
|
||||||
|
return oldval
|
||||||
|
}
|
||||||
|
if oldval+p.Spadj < -10000 || oldval+p.Spadj > 1100000000 {
|
||||||
|
ctxt.Diag("overflow in spadj: %d + %d = %d", oldval, p.Spadj, oldval+p.Spadj)
|
||||||
|
log.Fatalf("bad code")
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldval + p.Spadj
|
||||||
|
}
|
||||||
|
|
||||||
|
// pctopcdata computes the pcdata value in effect at p.
|
||||||
|
// A PCDATA instruction sets the value in effect at future
|
||||||
|
// non-PCDATA instructions.
|
||||||
|
// Since PCDATA instructions have no width in the final code,
|
||||||
|
// it does not matter which phase we use for the update.
|
||||||
|
func pctopcdata(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
|
||||||
|
if phase == 0 || p.As != APCDATA || p.From.Offset != int64(arg.(uint32)) {
|
||||||
|
return oldval
|
||||||
|
}
|
||||||
|
if int64(int32(p.To.Offset)) != p.To.Offset {
|
||||||
|
ctxt.Diag("overflow in PCDATA instruction: %v", p)
|
||||||
|
log.Fatalf("bad code")
|
||||||
|
}
|
||||||
|
|
||||||
|
return int32(p.To.Offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
func linkpcln(ctxt *Link, cursym *LSym) {
|
||||||
|
ctxt.Cursym = cursym
|
||||||
|
|
||||||
|
pcln := new(Pcln)
|
||||||
|
cursym.Pcln = pcln
|
||||||
|
|
||||||
|
npcdata := 0
|
||||||
|
nfuncdata := 0
|
||||||
|
for p := cursym.Text; p != nil; p = p.Link {
|
||||||
|
// Find the highest ID of any used PCDATA table. This ignores PCDATA table
|
||||||
|
// that consist entirely of "-1", since that's the assumed default value.
|
||||||
|
// From.Offset is table ID
|
||||||
|
// To.Offset is data
|
||||||
|
if p.As == APCDATA && p.From.Offset >= int64(npcdata) && p.To.Offset != -1 { // ignore -1 as we start at -1, if we only see -1, nothing changed
|
||||||
|
npcdata = int(p.From.Offset + 1)
|
||||||
|
}
|
||||||
|
// Find the highest ID of any FUNCDATA table.
|
||||||
|
// From.Offset is table ID
|
||||||
|
if p.As == AFUNCDATA && p.From.Offset >= int64(nfuncdata) {
|
||||||
|
nfuncdata = int(p.From.Offset + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pcln.Pcdata = make([]Pcdata, npcdata)
|
||||||
|
pcln.Pcdata = pcln.Pcdata[:npcdata]
|
||||||
|
pcln.Funcdata = make([]*LSym, nfuncdata)
|
||||||
|
pcln.Funcdataoff = make([]int64, nfuncdata)
|
||||||
|
pcln.Funcdataoff = pcln.Funcdataoff[:nfuncdata]
|
||||||
|
|
||||||
|
funcpctab(ctxt, &pcln.Pcsp, cursym, "pctospadj", pctospadj, nil)
|
||||||
|
funcpctab(ctxt, &pcln.Pcfile, cursym, "pctofile", pctofileline, pcln)
|
||||||
|
funcpctab(ctxt, &pcln.Pcline, cursym, "pctoline", pctofileline, nil)
|
||||||
|
|
||||||
|
// tabulate which pc and func data we have.
|
||||||
|
havepc := make([]uint32, (npcdata+31)/32)
|
||||||
|
havefunc := make([]uint32, (nfuncdata+31)/32)
|
||||||
|
for p := cursym.Text; p != nil; p = p.Link {
|
||||||
|
if p.As == AFUNCDATA {
|
||||||
|
if (havefunc[p.From.Offset/32]>>uint64(p.From.Offset%32))&1 != 0 {
|
||||||
|
ctxt.Diag("multiple definitions for FUNCDATA $%d", p.From.Offset)
|
||||||
|
}
|
||||||
|
havefunc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.As == APCDATA && p.To.Offset != -1 {
|
||||||
|
havepc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pcdata.
|
||||||
|
for i := 0; i < npcdata; i++ {
|
||||||
|
if (havepc[i/32]>>uint(i%32))&1 == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
funcpctab(ctxt, &pcln.Pcdata[i], cursym, "pctopcdata", pctopcdata, interface{}(uint32(i)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// funcdata
|
||||||
|
if nfuncdata > 0 {
|
||||||
|
var i int
|
||||||
|
for p := cursym.Text; p != nil; p = p.Link {
|
||||||
|
if p.As == AFUNCDATA {
|
||||||
|
i = int(p.From.Offset)
|
||||||
|
pcln.Funcdataoff[i] = p.To.Offset
|
||||||
|
if p.To.Type != TYPE_CONST {
|
||||||
|
// TODO: Dedup.
|
||||||
|
//funcdata_bytes += p->to.sym->size;
|
||||||
|
pcln.Funcdata[i] = p.To.Sym
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
208
vendor/github.com/google/gops/internal/obj/plist.go
generated
vendored
Normal file
208
vendor/github.com/google/gops/internal/obj/plist.go
generated
vendored
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Plist struct {
|
||||||
|
Firstpc *Prog
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* start a new Prog list.
|
||||||
|
*/
|
||||||
|
func Linknewplist(ctxt *Link) *Plist {
|
||||||
|
pl := new(Plist)
|
||||||
|
ctxt.Plists = append(ctxt.Plists, pl)
|
||||||
|
return pl
|
||||||
|
}
|
||||||
|
|
||||||
|
func Flushplist(ctxt *Link) {
|
||||||
|
flushplist(ctxt, ctxt.Debugasm == 0)
|
||||||
|
}
|
||||||
|
func FlushplistNoFree(ctxt *Link) {
|
||||||
|
flushplist(ctxt, false)
|
||||||
|
}
|
||||||
|
func flushplist(ctxt *Link, freeProgs bool) {
|
||||||
|
// Build list of symbols, and assign instructions to lists.
|
||||||
|
// Ignore ctxt->plist boundaries. There are no guarantees there,
|
||||||
|
// and the assemblers just use one big list.
|
||||||
|
var curtext *LSym
|
||||||
|
var etext *Prog
|
||||||
|
var text []*LSym
|
||||||
|
|
||||||
|
for _, pl := range ctxt.Plists {
|
||||||
|
var plink *Prog
|
||||||
|
for p := pl.Firstpc; p != nil; p = plink {
|
||||||
|
if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 {
|
||||||
|
fmt.Printf("obj: %v\n", p)
|
||||||
|
}
|
||||||
|
plink = p.Link
|
||||||
|
p.Link = nil
|
||||||
|
|
||||||
|
switch p.As {
|
||||||
|
case AEND:
|
||||||
|
continue
|
||||||
|
|
||||||
|
case ATYPE:
|
||||||
|
// Assume each TYPE instruction describes
|
||||||
|
// a different local variable or parameter,
|
||||||
|
// so no dedup.
|
||||||
|
// Using only the TYPE instructions means
|
||||||
|
// that we discard location information about local variables
|
||||||
|
// in C and assembly functions; that information is inferred
|
||||||
|
// from ordinary references, because there are no TYPE
|
||||||
|
// instructions there. Without the type information, gdb can't
|
||||||
|
// use the locations, so we don't bother to save them.
|
||||||
|
// If something else could use them, we could arrange to
|
||||||
|
// preserve them.
|
||||||
|
if curtext == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
a := new(Auto)
|
||||||
|
a.Asym = p.From.Sym
|
||||||
|
a.Aoffset = int32(p.From.Offset)
|
||||||
|
a.Name = int16(p.From.Name)
|
||||||
|
a.Gotype = p.To.Sym
|
||||||
|
a.Link = curtext.Autom
|
||||||
|
curtext.Autom = a
|
||||||
|
continue
|
||||||
|
|
||||||
|
case ATEXT:
|
||||||
|
s := p.From.Sym
|
||||||
|
if s == nil {
|
||||||
|
// func _() { }
|
||||||
|
curtext = nil
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Text != nil {
|
||||||
|
log.Fatalf("duplicate TEXT for %s", s.Name)
|
||||||
|
}
|
||||||
|
if s.OnList() {
|
||||||
|
log.Fatalf("symbol %s listed multiple times", s.Name)
|
||||||
|
}
|
||||||
|
s.Set(AttrOnList, true)
|
||||||
|
text = append(text, s)
|
||||||
|
flag := int(p.From3Offset())
|
||||||
|
if flag&DUPOK != 0 {
|
||||||
|
s.Set(AttrDuplicateOK, true)
|
||||||
|
}
|
||||||
|
if flag&NOSPLIT != 0 {
|
||||||
|
s.Set(AttrNoSplit, true)
|
||||||
|
}
|
||||||
|
if flag&REFLECTMETHOD != 0 {
|
||||||
|
s.Set(AttrReflectMethod, true)
|
||||||
|
}
|
||||||
|
s.Type = STEXT
|
||||||
|
s.Text = p
|
||||||
|
etext = p
|
||||||
|
curtext = s
|
||||||
|
continue
|
||||||
|
|
||||||
|
case AFUNCDATA:
|
||||||
|
// Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information.
|
||||||
|
if curtext == nil { // func _() {}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if p.To.Sym.Name == "go_args_stackmap" {
|
||||||
|
if p.From.Type != TYPE_CONST || p.From.Offset != FUNCDATA_ArgsPointerMaps {
|
||||||
|
ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps")
|
||||||
|
}
|
||||||
|
p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", curtext.Name), int(curtext.Version))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if curtext == nil {
|
||||||
|
etext = nil
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
etext.Link = p
|
||||||
|
etext = p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add reference to Go arguments for C or assembly functions without them.
|
||||||
|
for _, s := range text {
|
||||||
|
if !strings.HasPrefix(s.Name, "\"\".") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
found := false
|
||||||
|
var p *Prog
|
||||||
|
for p = s.Text; p != nil; p = p.Link {
|
||||||
|
if p.As == AFUNCDATA && p.From.Type == TYPE_CONST && p.From.Offset == FUNCDATA_ArgsPointerMaps {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
p = Appendp(ctxt, s.Text)
|
||||||
|
p.As = AFUNCDATA
|
||||||
|
p.From.Type = TYPE_CONST
|
||||||
|
p.From.Offset = FUNCDATA_ArgsPointerMaps
|
||||||
|
p.To.Type = TYPE_MEM
|
||||||
|
p.To.Name = NAME_EXTERN
|
||||||
|
p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", s.Name), int(s.Version))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn functions into machine code images.
|
||||||
|
for _, s := range text {
|
||||||
|
mkfwd(s)
|
||||||
|
linkpatch(ctxt, s)
|
||||||
|
if ctxt.Flag_optimize {
|
||||||
|
ctxt.Arch.Follow(ctxt, s)
|
||||||
|
}
|
||||||
|
ctxt.Arch.Preprocess(ctxt, s)
|
||||||
|
ctxt.Arch.Assemble(ctxt, s)
|
||||||
|
fieldtrack(ctxt, s)
|
||||||
|
linkpcln(ctxt, s)
|
||||||
|
if freeProgs {
|
||||||
|
s.Text = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to running list in ctxt.
|
||||||
|
ctxt.Text = append(ctxt.Text, text...)
|
||||||
|
ctxt.Data = append(ctxt.Data, gendwarf(ctxt, text)...)
|
||||||
|
ctxt.Plists = nil
|
||||||
|
ctxt.Curp = nil
|
||||||
|
if freeProgs {
|
||||||
|
ctxt.freeProgs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctxt *Link) Globl(s *LSym, size int64, flag int) {
|
||||||
|
if s.SeenGlobl() {
|
||||||
|
fmt.Printf("duplicate %v\n", s)
|
||||||
|
}
|
||||||
|
s.Set(AttrSeenGlobl, true)
|
||||||
|
if s.OnList() {
|
||||||
|
log.Fatalf("symbol %s listed multiple times", s.Name)
|
||||||
|
}
|
||||||
|
s.Set(AttrOnList, true)
|
||||||
|
ctxt.Data = append(ctxt.Data, s)
|
||||||
|
s.Size = size
|
||||||
|
if s.Type == 0 || s.Type == SXREF {
|
||||||
|
s.Type = SBSS
|
||||||
|
}
|
||||||
|
if flag&DUPOK != 0 {
|
||||||
|
s.Set(AttrDuplicateOK, true)
|
||||||
|
}
|
||||||
|
if flag&RODATA != 0 {
|
||||||
|
s.Type = SRODATA
|
||||||
|
} else if flag&NOPTR != 0 {
|
||||||
|
s.Type = SNOPTRBSS
|
||||||
|
} else if flag&TLSBSS != 0 {
|
||||||
|
s.Type = STLSBSS
|
||||||
|
}
|
||||||
|
}
|
941
vendor/github.com/google/gops/internal/obj/ppc64/a.out.go
generated
vendored
Normal file
941
vendor/github.com/google/gops/internal/obj/ppc64/a.out.go
generated
vendored
Normal file
@ -0,0 +1,941 @@
|
|||||||
|
// cmd/9c/9.out.h from Vita Nuova.
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package ppc64
|
||||||
|
|
||||||
|
import "github.com/google/gops/internal/obj"
|
||||||
|
|
||||||
|
//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p ppc64
|
||||||
|
|
||||||
|
/*
|
||||||
|
* powerpc 64
|
||||||
|
*/
|
||||||
|
const (
|
||||||
|
NSNAME = 8
|
||||||
|
NSYM = 50
|
||||||
|
NREG = 32 /* number of general registers */
|
||||||
|
NFREG = 32 /* number of floating point registers */
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
/* RBasePPC64 = 4096 */
|
||||||
|
/* R0=4096 ... R31=4127 */
|
||||||
|
REG_R0 = obj.RBasePPC64 + iota
|
||||||
|
REG_R1
|
||||||
|
REG_R2
|
||||||
|
REG_R3
|
||||||
|
REG_R4
|
||||||
|
REG_R5
|
||||||
|
REG_R6
|
||||||
|
REG_R7
|
||||||
|
REG_R8
|
||||||
|
REG_R9
|
||||||
|
REG_R10
|
||||||
|
REG_R11
|
||||||
|
REG_R12
|
||||||
|
REG_R13
|
||||||
|
REG_R14
|
||||||
|
REG_R15
|
||||||
|
REG_R16
|
||||||
|
REG_R17
|
||||||
|
REG_R18
|
||||||
|
REG_R19
|
||||||
|
REG_R20
|
||||||
|
REG_R21
|
||||||
|
REG_R22
|
||||||
|
REG_R23
|
||||||
|
REG_R24
|
||||||
|
REG_R25
|
||||||
|
REG_R26
|
||||||
|
REG_R27
|
||||||
|
REG_R28
|
||||||
|
REG_R29
|
||||||
|
REG_R30
|
||||||
|
REG_R31
|
||||||
|
|
||||||
|
/* F0=4128 ... F31=4159 */
|
||||||
|
REG_F0
|
||||||
|
REG_F1
|
||||||
|
REG_F2
|
||||||
|
REG_F3
|
||||||
|
REG_F4
|
||||||
|
REG_F5
|
||||||
|
REG_F6
|
||||||
|
REG_F7
|
||||||
|
REG_F8
|
||||||
|
REG_F9
|
||||||
|
REG_F10
|
||||||
|
REG_F11
|
||||||
|
REG_F12
|
||||||
|
REG_F13
|
||||||
|
REG_F14
|
||||||
|
REG_F15
|
||||||
|
REG_F16
|
||||||
|
REG_F17
|
||||||
|
REG_F18
|
||||||
|
REG_F19
|
||||||
|
REG_F20
|
||||||
|
REG_F21
|
||||||
|
REG_F22
|
||||||
|
REG_F23
|
||||||
|
REG_F24
|
||||||
|
REG_F25
|
||||||
|
REG_F26
|
||||||
|
REG_F27
|
||||||
|
REG_F28
|
||||||
|
REG_F29
|
||||||
|
REG_F30
|
||||||
|
REG_F31
|
||||||
|
|
||||||
|
/* V0=4160 ... V31=4191 */
|
||||||
|
REG_V0
|
||||||
|
REG_V1
|
||||||
|
REG_V2
|
||||||
|
REG_V3
|
||||||
|
REG_V4
|
||||||
|
REG_V5
|
||||||
|
REG_V6
|
||||||
|
REG_V7
|
||||||
|
REG_V8
|
||||||
|
REG_V9
|
||||||
|
REG_V10
|
||||||
|
REG_V11
|
||||||
|
REG_V12
|
||||||
|
REG_V13
|
||||||
|
REG_V14
|
||||||
|
REG_V15
|
||||||
|
REG_V16
|
||||||
|
REG_V17
|
||||||
|
REG_V18
|
||||||
|
REG_V19
|
||||||
|
REG_V20
|
||||||
|
REG_V21
|
||||||
|
REG_V22
|
||||||
|
REG_V23
|
||||||
|
REG_V24
|
||||||
|
REG_V25
|
||||||
|
REG_V26
|
||||||
|
REG_V27
|
||||||
|
REG_V28
|
||||||
|
REG_V29
|
||||||
|
REG_V30
|
||||||
|
REG_V31
|
||||||
|
|
||||||
|
/* VS0=4192 ... VS63=4255 */
|
||||||
|
REG_VS0
|
||||||
|
REG_VS1
|
||||||
|
REG_VS2
|
||||||
|
REG_VS3
|
||||||
|
REG_VS4
|
||||||
|
REG_VS5
|
||||||
|
REG_VS6
|
||||||
|
REG_VS7
|
||||||
|
REG_VS8
|
||||||
|
REG_VS9
|
||||||
|
REG_VS10
|
||||||
|
REG_VS11
|
||||||
|
REG_VS12
|
||||||
|
REG_VS13
|
||||||
|
REG_VS14
|
||||||
|
REG_VS15
|
||||||
|
REG_VS16
|
||||||
|
REG_VS17
|
||||||
|
REG_VS18
|
||||||
|
REG_VS19
|
||||||
|
REG_VS20
|
||||||
|
REG_VS21
|
||||||
|
REG_VS22
|
||||||
|
REG_VS23
|
||||||
|
REG_VS24
|
||||||
|
REG_VS25
|
||||||
|
REG_VS26
|
||||||
|
REG_VS27
|
||||||
|
REG_VS28
|
||||||
|
REG_VS29
|
||||||
|
REG_VS30
|
||||||
|
REG_VS31
|
||||||
|
REG_VS32
|
||||||
|
REG_VS33
|
||||||
|
REG_VS34
|
||||||
|
REG_VS35
|
||||||
|
REG_VS36
|
||||||
|
REG_VS37
|
||||||
|
REG_VS38
|
||||||
|
REG_VS39
|
||||||
|
REG_VS40
|
||||||
|
REG_VS41
|
||||||
|
REG_VS42
|
||||||
|
REG_VS43
|
||||||
|
REG_VS44
|
||||||
|
REG_VS45
|
||||||
|
REG_VS46
|
||||||
|
REG_VS47
|
||||||
|
REG_VS48
|
||||||
|
REG_VS49
|
||||||
|
REG_VS50
|
||||||
|
REG_VS51
|
||||||
|
REG_VS52
|
||||||
|
REG_VS53
|
||||||
|
REG_VS54
|
||||||
|
REG_VS55
|
||||||
|
REG_VS56
|
||||||
|
REG_VS57
|
||||||
|
REG_VS58
|
||||||
|
REG_VS59
|
||||||
|
REG_VS60
|
||||||
|
REG_VS61
|
||||||
|
REG_VS62
|
||||||
|
REG_VS63
|
||||||
|
|
||||||
|
REG_CR0
|
||||||
|
REG_CR1
|
||||||
|
REG_CR2
|
||||||
|
REG_CR3
|
||||||
|
REG_CR4
|
||||||
|
REG_CR5
|
||||||
|
REG_CR6
|
||||||
|
REG_CR7
|
||||||
|
|
||||||
|
REG_MSR
|
||||||
|
REG_FPSCR
|
||||||
|
REG_CR
|
||||||
|
|
||||||
|
REG_SPECIAL = REG_CR0
|
||||||
|
|
||||||
|
REG_SPR0 = obj.RBasePPC64 + 1024 // first of 1024 registers
|
||||||
|
REG_DCR0 = obj.RBasePPC64 + 2048 // first of 1024 registers
|
||||||
|
|
||||||
|
REG_XER = REG_SPR0 + 1
|
||||||
|
REG_LR = REG_SPR0 + 8
|
||||||
|
REG_CTR = REG_SPR0 + 9
|
||||||
|
|
||||||
|
REGZERO = REG_R0 /* set to zero */
|
||||||
|
REGSP = REG_R1
|
||||||
|
REGSB = REG_R2
|
||||||
|
REGRET = REG_R3
|
||||||
|
REGARG = -1 /* -1 disables passing the first argument in register */
|
||||||
|
REGRT1 = REG_R3 /* reserved for runtime, duffzero and duffcopy */
|
||||||
|
REGRT2 = REG_R4 /* reserved for runtime, duffcopy */
|
||||||
|
REGMIN = REG_R7 /* register variables allocated from here to REGMAX */
|
||||||
|
REGCTXT = REG_R11 /* context for closures */
|
||||||
|
REGTLS = REG_R13 /* C ABI TLS base pointer */
|
||||||
|
REGMAX = REG_R27
|
||||||
|
REGEXT = REG_R30 /* external registers allocated from here down */
|
||||||
|
REGG = REG_R30 /* G */
|
||||||
|
REGTMP = REG_R31 /* used by the linker */
|
||||||
|
FREGRET = REG_F0
|
||||||
|
FREGMIN = REG_F17 /* first register variable */
|
||||||
|
FREGMAX = REG_F26 /* last register variable for 9g only */
|
||||||
|
FREGEXT = REG_F26 /* first external register */
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GENERAL:
|
||||||
|
*
|
||||||
|
* compiler allocates R3 up as temps
|
||||||
|
* compiler allocates register variables R7-R27
|
||||||
|
* compiler allocates external registers R30 down
|
||||||
|
*
|
||||||
|
* compiler allocates register variables F17-F26
|
||||||
|
* compiler allocates external registers F26 down
|
||||||
|
*/
|
||||||
|
const (
|
||||||
|
BIG = 32768 - 8
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
/* mark flags */
|
||||||
|
LABEL = 1 << 0
|
||||||
|
LEAF = 1 << 1
|
||||||
|
FLOAT = 1 << 2
|
||||||
|
BRANCH = 1 << 3
|
||||||
|
LOAD = 1 << 4
|
||||||
|
FCMP = 1 << 5
|
||||||
|
SYNC = 1 << 6
|
||||||
|
LIST = 1 << 7
|
||||||
|
FOLL = 1 << 8
|
||||||
|
NOSCHED = 1 << 9
|
||||||
|
)
|
||||||
|
|
||||||
|
// Values for use in branch instruction BC
|
||||||
|
// BC B0,BI,label
|
||||||
|
// BO is type of branch + likely bits described below
|
||||||
|
// BI is CR value + branch type
|
||||||
|
// ex: BEQ CR2,label is BC 12,10,label
|
||||||
|
// 12 = BO_BCR
|
||||||
|
// 10 = BI_CR2 + BI_EQ
|
||||||
|
|
||||||
|
const (
|
||||||
|
BI_CR0 = 0
|
||||||
|
BI_CR1 = 4
|
||||||
|
BI_CR2 = 8
|
||||||
|
BI_CR3 = 12
|
||||||
|
BI_CR4 = 16
|
||||||
|
BI_CR5 = 20
|
||||||
|
BI_CR6 = 24
|
||||||
|
BI_CR7 = 28
|
||||||
|
BI_LT = 0
|
||||||
|
BI_GT = 1
|
||||||
|
BI_EQ = 2
|
||||||
|
BI_OVF = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
// Values for the BO field. Add the branch type to
|
||||||
|
// the likely bits, if a likely setting is known.
|
||||||
|
// If branch likely or unlikely is not known, don't set it.
|
||||||
|
// e.g. branch on cr+likely = 15
|
||||||
|
|
||||||
|
const (
|
||||||
|
BO_BCTR = 16 // branch on ctr value
|
||||||
|
BO_BCR = 12 // branch on cr value
|
||||||
|
BO_BCRBCTR = 8 // branch on ctr and cr value
|
||||||
|
BO_NOTBCR = 4 // branch on not cr value
|
||||||
|
BO_UNLIKELY = 2 // value for unlikely
|
||||||
|
BO_LIKELY = 3 // value for likely
|
||||||
|
)
|
||||||
|
|
||||||
|
// Bit settings from the CR
|
||||||
|
|
||||||
|
const (
|
||||||
|
C_COND_LT = iota // 0 result is negative
|
||||||
|
C_COND_GT // 1 result is positive
|
||||||
|
C_COND_EQ // 2 result is zero
|
||||||
|
C_COND_SO // 3 summary overflow or FP compare w/ NaN
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
C_NONE = iota
|
||||||
|
C_REG
|
||||||
|
C_FREG
|
||||||
|
C_VREG
|
||||||
|
C_VSREG
|
||||||
|
C_CREG
|
||||||
|
C_SPR /* special processor register */
|
||||||
|
C_ZCON
|
||||||
|
C_SCON /* 16 bit signed */
|
||||||
|
C_UCON /* 32 bit signed, low 16 bits 0 */
|
||||||
|
C_ADDCON /* -0x8000 <= v < 0 */
|
||||||
|
C_ANDCON /* 0 < v <= 0xFFFF */
|
||||||
|
C_LCON /* other 32 */
|
||||||
|
C_DCON /* other 64 (could subdivide further) */
|
||||||
|
C_SACON /* $n(REG) where n <= int16 */
|
||||||
|
C_SECON
|
||||||
|
C_LACON /* $n(REG) where int16 < n <= int32 */
|
||||||
|
C_LECON
|
||||||
|
C_DACON /* $n(REG) where int32 < n */
|
||||||
|
C_SBRA
|
||||||
|
C_LBRA
|
||||||
|
C_LBRAPIC
|
||||||
|
C_SAUTO
|
||||||
|
C_LAUTO
|
||||||
|
C_SEXT
|
||||||
|
C_LEXT
|
||||||
|
C_ZOREG // conjecture: either (1) register + zeroed offset, or (2) "R0" implies zero or C_REG
|
||||||
|
C_SOREG // register + signed offset
|
||||||
|
C_LOREG
|
||||||
|
C_FPSCR
|
||||||
|
C_MSR
|
||||||
|
C_XER
|
||||||
|
C_LR
|
||||||
|
C_CTR
|
||||||
|
C_ANY
|
||||||
|
C_GOK
|
||||||
|
C_ADDR
|
||||||
|
C_GOTADDR
|
||||||
|
C_TLS_LE
|
||||||
|
C_TLS_IE
|
||||||
|
C_TEXTSIZE
|
||||||
|
|
||||||
|
C_NCLASS /* must be the last */
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AADD = obj.ABasePPC64 + obj.A_ARCHSPECIFIC + iota
|
||||||
|
AADDCC
|
||||||
|
AADDV
|
||||||
|
AADDVCC
|
||||||
|
AADDC
|
||||||
|
AADDCCC
|
||||||
|
AADDCV
|
||||||
|
AADDCVCC
|
||||||
|
AADDME
|
||||||
|
AADDMECC
|
||||||
|
AADDMEVCC
|
||||||
|
AADDMEV
|
||||||
|
AADDE
|
||||||
|
AADDECC
|
||||||
|
AADDEVCC
|
||||||
|
AADDEV
|
||||||
|
AADDZE
|
||||||
|
AADDZECC
|
||||||
|
AADDZEVCC
|
||||||
|
AADDZEV
|
||||||
|
AAND
|
||||||
|
AANDCC
|
||||||
|
AANDN
|
||||||
|
AANDNCC
|
||||||
|
ABC
|
||||||
|
ABCL
|
||||||
|
ABEQ
|
||||||
|
ABGE // not LT = G/E/U
|
||||||
|
ABGT
|
||||||
|
ABLE // not GT = L/E/U
|
||||||
|
ABLT
|
||||||
|
ABNE // not EQ = L/G/U
|
||||||
|
ABVC // Unordered-clear
|
||||||
|
ABVS // Unordered-set
|
||||||
|
ACMP
|
||||||
|
ACMPU
|
||||||
|
ACNTLZW
|
||||||
|
ACNTLZWCC
|
||||||
|
ACRAND
|
||||||
|
ACRANDN
|
||||||
|
ACREQV
|
||||||
|
ACRNAND
|
||||||
|
ACRNOR
|
||||||
|
ACROR
|
||||||
|
ACRORN
|
||||||
|
ACRXOR
|
||||||
|
ADIVW
|
||||||
|
ADIVWCC
|
||||||
|
ADIVWVCC
|
||||||
|
ADIVWV
|
||||||
|
ADIVWU
|
||||||
|
ADIVWUCC
|
||||||
|
ADIVWUVCC
|
||||||
|
ADIVWUV
|
||||||
|
AEQV
|
||||||
|
AEQVCC
|
||||||
|
AEXTSB
|
||||||
|
AEXTSBCC
|
||||||
|
AEXTSH
|
||||||
|
AEXTSHCC
|
||||||
|
AFABS
|
||||||
|
AFABSCC
|
||||||
|
AFADD
|
||||||
|
AFADDCC
|
||||||
|
AFADDS
|
||||||
|
AFADDSCC
|
||||||
|
AFCMPO
|
||||||
|
AFCMPU
|
||||||
|
AFCTIW
|
||||||
|
AFCTIWCC
|
||||||
|
AFCTIWZ
|
||||||
|
AFCTIWZCC
|
||||||
|
AFDIV
|
||||||
|
AFDIVCC
|
||||||
|
AFDIVS
|
||||||
|
AFDIVSCC
|
||||||
|
AFMADD
|
||||||
|
AFMADDCC
|
||||||
|
AFMADDS
|
||||||
|
AFMADDSCC
|
||||||
|
AFMOVD
|
||||||
|
AFMOVDCC
|
||||||
|
AFMOVDU
|
||||||
|
AFMOVS
|
||||||
|
AFMOVSU
|
||||||
|
AFMOVSX
|
||||||
|
AFMOVSZ
|
||||||
|
AFMSUB
|
||||||
|
AFMSUBCC
|
||||||
|
AFMSUBS
|
||||||
|
AFMSUBSCC
|
||||||
|
AFMUL
|
||||||
|
AFMULCC
|
||||||
|
AFMULS
|
||||||
|
AFMULSCC
|
||||||
|
AFNABS
|
||||||
|
AFNABSCC
|
||||||
|
AFNEG
|
||||||
|
AFNEGCC
|
||||||
|
AFNMADD
|
||||||
|
AFNMADDCC
|
||||||
|
AFNMADDS
|
||||||
|
AFNMADDSCC
|
||||||
|
AFNMSUB
|
||||||
|
AFNMSUBCC
|
||||||
|
AFNMSUBS
|
||||||
|
AFNMSUBSCC
|
||||||
|
AFRSP
|
||||||
|
AFRSPCC
|
||||||
|
AFSUB
|
||||||
|
AFSUBCC
|
||||||
|
AFSUBS
|
||||||
|
AFSUBSCC
|
||||||
|
AISEL
|
||||||
|
AMOVMW
|
||||||
|
ALBAR
|
||||||
|
ALSW
|
||||||
|
ALWAR
|
||||||
|
ALWSYNC
|
||||||
|
AMOVDBR
|
||||||
|
AMOVWBR
|
||||||
|
AMOVB
|
||||||
|
AMOVBU
|
||||||
|
AMOVBZ
|
||||||
|
AMOVBZU
|
||||||
|
AMOVH
|
||||||
|
AMOVHBR
|
||||||
|
AMOVHU
|
||||||
|
AMOVHZ
|
||||||
|
AMOVHZU
|
||||||
|
AMOVW
|
||||||
|
AMOVWU
|
||||||
|
AMOVFL
|
||||||
|
AMOVCRFS
|
||||||
|
AMTFSB0
|
||||||
|
AMTFSB0CC
|
||||||
|
AMTFSB1
|
||||||
|
AMTFSB1CC
|
||||||
|
AMULHW
|
||||||
|
AMULHWCC
|
||||||
|
AMULHWU
|
||||||
|
AMULHWUCC
|
||||||
|
AMULLW
|
||||||
|
AMULLWCC
|
||||||
|
AMULLWVCC
|
||||||
|
AMULLWV
|
||||||
|
ANAND
|
||||||
|
ANANDCC
|
||||||
|
ANEG
|
||||||
|
ANEGCC
|
||||||
|
ANEGVCC
|
||||||
|
ANEGV
|
||||||
|
ANOR
|
||||||
|
ANORCC
|
||||||
|
AOR
|
||||||
|
AORCC
|
||||||
|
AORN
|
||||||
|
AORNCC
|
||||||
|
AREM
|
||||||
|
AREMCC
|
||||||
|
AREMV
|
||||||
|
AREMVCC
|
||||||
|
AREMU
|
||||||
|
AREMUCC
|
||||||
|
AREMUV
|
||||||
|
AREMUVCC
|
||||||
|
ARFI
|
||||||
|
ARLWMI
|
||||||
|
ARLWMICC
|
||||||
|
ARLWNM
|
||||||
|
ARLWNMCC
|
||||||
|
ASLW
|
||||||
|
ASLWCC
|
||||||
|
ASRW
|
||||||
|
ASRAW
|
||||||
|
ASRAWCC
|
||||||
|
ASRWCC
|
||||||
|
ASTBCCC
|
||||||
|
ASTSW
|
||||||
|
ASTWCCC
|
||||||
|
ASUB
|
||||||
|
ASUBCC
|
||||||
|
ASUBVCC
|
||||||
|
ASUBC
|
||||||
|
ASUBCCC
|
||||||
|
ASUBCV
|
||||||
|
ASUBCVCC
|
||||||
|
ASUBME
|
||||||
|
ASUBMECC
|
||||||
|
ASUBMEVCC
|
||||||
|
ASUBMEV
|
||||||
|
ASUBV
|
||||||
|
ASUBE
|
||||||
|
ASUBECC
|
||||||
|
ASUBEV
|
||||||
|
ASUBEVCC
|
||||||
|
ASUBZE
|
||||||
|
ASUBZECC
|
||||||
|
ASUBZEVCC
|
||||||
|
ASUBZEV
|
||||||
|
ASYNC
|
||||||
|
AXOR
|
||||||
|
AXORCC
|
||||||
|
|
||||||
|
ADCBF
|
||||||
|
ADCBI
|
||||||
|
ADCBST
|
||||||
|
ADCBT
|
||||||
|
ADCBTST
|
||||||
|
ADCBZ
|
||||||
|
AECIWX
|
||||||
|
AECOWX
|
||||||
|
AEIEIO
|
||||||
|
AICBI
|
||||||
|
AISYNC
|
||||||
|
APTESYNC
|
||||||
|
ATLBIE
|
||||||
|
ATLBIEL
|
||||||
|
ATLBSYNC
|
||||||
|
ATW
|
||||||
|
|
||||||
|
ASYSCALL
|
||||||
|
AWORD
|
||||||
|
|
||||||
|
ARFCI
|
||||||
|
|
||||||
|
/* optional on 32-bit */
|
||||||
|
AFRES
|
||||||
|
AFRESCC
|
||||||
|
AFRIM
|
||||||
|
AFRIMCC
|
||||||
|
AFRIP
|
||||||
|
AFRIPCC
|
||||||
|
AFRIZ
|
||||||
|
AFRIZCC
|
||||||
|
AFRSQRTE
|
||||||
|
AFRSQRTECC
|
||||||
|
AFSEL
|
||||||
|
AFSELCC
|
||||||
|
AFSQRT
|
||||||
|
AFSQRTCC
|
||||||
|
AFSQRTS
|
||||||
|
AFSQRTSCC
|
||||||
|
|
||||||
|
/* 64-bit */
|
||||||
|
|
||||||
|
ACNTLZD
|
||||||
|
ACNTLZDCC
|
||||||
|
ACMPW /* CMP with L=0 */
|
||||||
|
ACMPWU
|
||||||
|
ADIVD
|
||||||
|
ADIVDCC
|
||||||
|
ADIVDE
|
||||||
|
ADIVDECC
|
||||||
|
ADIVDEU
|
||||||
|
ADIVDEUCC
|
||||||
|
ADIVDVCC
|
||||||
|
ADIVDV
|
||||||
|
ADIVDU
|
||||||
|
ADIVDUCC
|
||||||
|
ADIVDUVCC
|
||||||
|
ADIVDUV
|
||||||
|
AEXTSW
|
||||||
|
AEXTSWCC
|
||||||
|
/* AFCFIW; AFCFIWCC */
|
||||||
|
AFCFID
|
||||||
|
AFCFIDCC
|
||||||
|
AFCFIDU
|
||||||
|
AFCFIDUCC
|
||||||
|
AFCTID
|
||||||
|
AFCTIDCC
|
||||||
|
AFCTIDZ
|
||||||
|
AFCTIDZCC
|
||||||
|
ALDAR
|
||||||
|
AMOVD
|
||||||
|
AMOVDU
|
||||||
|
AMOVWZ
|
||||||
|
AMOVWZU
|
||||||
|
AMULHD
|
||||||
|
AMULHDCC
|
||||||
|
AMULHDU
|
||||||
|
AMULHDUCC
|
||||||
|
AMULLD
|
||||||
|
AMULLDCC
|
||||||
|
AMULLDVCC
|
||||||
|
AMULLDV
|
||||||
|
ARFID
|
||||||
|
ARLDMI
|
||||||
|
ARLDMICC
|
||||||
|
ARLDIMI
|
||||||
|
ARLDIMICC
|
||||||
|
ARLDC
|
||||||
|
ARLDCCC
|
||||||
|
ARLDCR
|
||||||
|
ARLDCRCC
|
||||||
|
ARLDICR
|
||||||
|
ARLDICRCC
|
||||||
|
ARLDCL
|
||||||
|
ARLDCLCC
|
||||||
|
ARLDICL
|
||||||
|
ARLDICLCC
|
||||||
|
ASLBIA
|
||||||
|
ASLBIE
|
||||||
|
ASLBMFEE
|
||||||
|
ASLBMFEV
|
||||||
|
ASLBMTE
|
||||||
|
ASLD
|
||||||
|
ASLDCC
|
||||||
|
ASRD
|
||||||
|
ASRAD
|
||||||
|
ASRADCC
|
||||||
|
ASRDCC
|
||||||
|
ASTDCCC
|
||||||
|
ATD
|
||||||
|
|
||||||
|
/* 64-bit pseudo operation */
|
||||||
|
ADWORD
|
||||||
|
AREMD
|
||||||
|
AREMDCC
|
||||||
|
AREMDV
|
||||||
|
AREMDVCC
|
||||||
|
AREMDU
|
||||||
|
AREMDUCC
|
||||||
|
AREMDUV
|
||||||
|
AREMDUVCC
|
||||||
|
|
||||||
|
/* more 64-bit operations */
|
||||||
|
AHRFID
|
||||||
|
|
||||||
|
/* Vector */
|
||||||
|
ALV
|
||||||
|
ALVEBX
|
||||||
|
ALVEHX
|
||||||
|
ALVEWX
|
||||||
|
ALVX
|
||||||
|
ALVXL
|
||||||
|
ALVSL
|
||||||
|
ALVSR
|
||||||
|
ASTV
|
||||||
|
ASTVEBX
|
||||||
|
ASTVEHX
|
||||||
|
ASTVEWX
|
||||||
|
ASTVX
|
||||||
|
ASTVXL
|
||||||
|
AVAND
|
||||||
|
AVANDL
|
||||||
|
AVANDC
|
||||||
|
AVNAND
|
||||||
|
AVOR
|
||||||
|
AVORL
|
||||||
|
AVORC
|
||||||
|
AVNOR
|
||||||
|
AVXOR
|
||||||
|
AVEQV
|
||||||
|
AVADDUM
|
||||||
|
AVADDUBM
|
||||||
|
AVADDUHM
|
||||||
|
AVADDUWM
|
||||||
|
AVADDUDM
|
||||||
|
AVADDUQM
|
||||||
|
AVADDCU
|
||||||
|
AVADDCUQ
|
||||||
|
AVADDCUW
|
||||||
|
AVADDUS
|
||||||
|
AVADDUBS
|
||||||
|
AVADDUHS
|
||||||
|
AVADDUWS
|
||||||
|
AVADDSS
|
||||||
|
AVADDSBS
|
||||||
|
AVADDSHS
|
||||||
|
AVADDSWS
|
||||||
|
AVADDE
|
||||||
|
AVADDEUQM
|
||||||
|
AVADDECUQ
|
||||||
|
AVSUBUM
|
||||||
|
AVSUBUBM
|
||||||
|
AVSUBUHM
|
||||||
|
AVSUBUWM
|
||||||
|
AVSUBUDM
|
||||||
|
AVSUBUQM
|
||||||
|
AVSUBCU
|
||||||
|
AVSUBCUQ
|
||||||
|
AVSUBCUW
|
||||||
|
AVSUBUS
|
||||||
|
AVSUBUBS
|
||||||
|
AVSUBUHS
|
||||||
|
AVSUBUWS
|
||||||
|
AVSUBSS
|
||||||
|
AVSUBSBS
|
||||||
|
AVSUBSHS
|
||||||
|
AVSUBSWS
|
||||||
|
AVSUBE
|
||||||
|
AVSUBEUQM
|
||||||
|
AVSUBECUQ
|
||||||
|
AVR
|
||||||
|
AVRLB
|
||||||
|
AVRLH
|
||||||
|
AVRLW
|
||||||
|
AVRLD
|
||||||
|
AVS
|
||||||
|
AVSLB
|
||||||
|
AVSLH
|
||||||
|
AVSLW
|
||||||
|
AVSL
|
||||||
|
AVSLO
|
||||||
|
AVSRB
|
||||||
|
AVSRH
|
||||||
|
AVSRW
|
||||||
|
AVSR
|
||||||
|
AVSRO
|
||||||
|
AVSLD
|
||||||
|
AVSRD
|
||||||
|
AVSA
|
||||||
|
AVSRAB
|
||||||
|
AVSRAH
|
||||||
|
AVSRAW
|
||||||
|
AVSRAD
|
||||||
|
AVSOI
|
||||||
|
AVSLDOI
|
||||||
|
AVCLZ
|
||||||
|
AVCLZB
|
||||||
|
AVCLZH
|
||||||
|
AVCLZW
|
||||||
|
AVCLZD
|
||||||
|
AVPOPCNT
|
||||||
|
AVPOPCNTB
|
||||||
|
AVPOPCNTH
|
||||||
|
AVPOPCNTW
|
||||||
|
AVPOPCNTD
|
||||||
|
AVCMPEQ
|
||||||
|
AVCMPEQUB
|
||||||
|
AVCMPEQUBCC
|
||||||
|
AVCMPEQUH
|
||||||
|
AVCMPEQUHCC
|
||||||
|
AVCMPEQUW
|
||||||
|
AVCMPEQUWCC
|
||||||
|
AVCMPEQUD
|
||||||
|
AVCMPEQUDCC
|
||||||
|
AVCMPGT
|
||||||
|
AVCMPGTUB
|
||||||
|
AVCMPGTUBCC
|
||||||
|
AVCMPGTUH
|
||||||
|
AVCMPGTUHCC
|
||||||
|
AVCMPGTUW
|
||||||
|
AVCMPGTUWCC
|
||||||
|
AVCMPGTUD
|
||||||
|
AVCMPGTUDCC
|
||||||
|
AVCMPGTSB
|
||||||
|
AVCMPGTSBCC
|
||||||
|
AVCMPGTSH
|
||||||
|
AVCMPGTSHCC
|
||||||
|
AVCMPGTSW
|
||||||
|
AVCMPGTSWCC
|
||||||
|
AVCMPGTSD
|
||||||
|
AVCMPGTSDCC
|
||||||
|
AVPERM
|
||||||
|
AVSEL
|
||||||
|
AVSPLT
|
||||||
|
AVSPLTB
|
||||||
|
AVSPLTH
|
||||||
|
AVSPLTW
|
||||||
|
AVSPLTI
|
||||||
|
AVSPLTISB
|
||||||
|
AVSPLTISH
|
||||||
|
AVSPLTISW
|
||||||
|
AVCIPH
|
||||||
|
AVCIPHER
|
||||||
|
AVCIPHERLAST
|
||||||
|
AVNCIPH
|
||||||
|
AVNCIPHER
|
||||||
|
AVNCIPHERLAST
|
||||||
|
AVSBOX
|
||||||
|
AVSHASIGMA
|
||||||
|
AVSHASIGMAW
|
||||||
|
AVSHASIGMAD
|
||||||
|
|
||||||
|
/* VSX */
|
||||||
|
ALXV
|
||||||
|
ALXVD2X
|
||||||
|
ALXVDSX
|
||||||
|
ALXVW4X
|
||||||
|
ASTXV
|
||||||
|
ASTXVD2X
|
||||||
|
ASTXVW4X
|
||||||
|
ALXS
|
||||||
|
ALXSDX
|
||||||
|
ASTXS
|
||||||
|
ASTXSDX
|
||||||
|
ALXSI
|
||||||
|
ALXSIWAX
|
||||||
|
ALXSIWZX
|
||||||
|
ASTXSI
|
||||||
|
ASTXSIWX
|
||||||
|
AMFVSR
|
||||||
|
AMFVSRD
|
||||||
|
AMFVSRWZ
|
||||||
|
AMTVSR
|
||||||
|
AMTVSRD
|
||||||
|
AMTVSRWA
|
||||||
|
AMTVSRWZ
|
||||||
|
AXXLAND
|
||||||
|
AXXLANDQ
|
||||||
|
AXXLANDC
|
||||||
|
AXXLEQV
|
||||||
|
AXXLNAND
|
||||||
|
AXXLOR
|
||||||
|
AXXLORC
|
||||||
|
AXXLNOR
|
||||||
|
AXXLORQ
|
||||||
|
AXXLXOR
|
||||||
|
AXXSEL
|
||||||
|
AXXMRG
|
||||||
|
AXXMRGHW
|
||||||
|
AXXMRGLW
|
||||||
|
AXXSPLT
|
||||||
|
AXXSPLTW
|
||||||
|
AXXPERM
|
||||||
|
AXXPERMDI
|
||||||
|
AXXSI
|
||||||
|
AXXSLDWI
|
||||||
|
AXSCV
|
||||||
|
AXSCVDPSP
|
||||||
|
AXSCVSPDP
|
||||||
|
AXSCVDPSPN
|
||||||
|
AXSCVSPDPN
|
||||||
|
AXVCV
|
||||||
|
AXVCVDPSP
|
||||||
|
AXVCVSPDP
|
||||||
|
AXSCVX
|
||||||
|
AXSCVDPSXDS
|
||||||
|
AXSCVDPSXWS
|
||||||
|
AXSCVDPUXDS
|
||||||
|
AXSCVDPUXWS
|
||||||
|
AXSCVXP
|
||||||
|
AXSCVSXDDP
|
||||||
|
AXSCVUXDDP
|
||||||
|
AXSCVSXDSP
|
||||||
|
AXSCVUXDSP
|
||||||
|
AXVCVX
|
||||||
|
AXVCVDPSXDS
|
||||||
|
AXVCVDPSXWS
|
||||||
|
AXVCVDPUXDS
|
||||||
|
AXVCVDPUXWS
|
||||||
|
AXVCVSPSXDS
|
||||||
|
AXVCVSPSXWS
|
||||||
|
AXVCVSPUXDS
|
||||||
|
AXVCVSPUXWS
|
||||||
|
AXVCVXP
|
||||||
|
AXVCVSXDDP
|
||||||
|
AXVCVSXWDP
|
||||||
|
AXVCVUXDDP
|
||||||
|
AXVCVUXWDP
|
||||||
|
AXVCVSXDSP
|
||||||
|
AXVCVSXWSP
|
||||||
|
AXVCVUXDSP
|
||||||
|
AXVCVUXWSP
|
||||||
|
|
||||||
|
ALAST
|
||||||
|
|
||||||
|
// aliases
|
||||||
|
ABR = obj.AJMP
|
||||||
|
ABL = obj.ACALL
|
||||||
|
)
|
549
vendor/github.com/google/gops/internal/obj/ppc64/anames.go
generated
vendored
Normal file
549
vendor/github.com/google/gops/internal/obj/ppc64/anames.go
generated
vendored
Normal file
@ -0,0 +1,549 @@
|
|||||||
|
// Generated by stringer -i a.out.go -o anames.go -p ppc64
|
||||||
|
// Do not edit.
|
||||||
|
|
||||||
|
package ppc64
|
||||||
|
|
||||||
|
import "github.com/google/gops/internal/obj"
|
||||||
|
|
||||||
|
var Anames = []string{
|
||||||
|
obj.A_ARCHSPECIFIC: "ADD",
|
||||||
|
"ADDCC",
|
||||||
|
"ADDV",
|
||||||
|
"ADDVCC",
|
||||||
|
"ADDC",
|
||||||
|
"ADDCCC",
|
||||||
|
"ADDCV",
|
||||||
|
"ADDCVCC",
|
||||||
|
"ADDME",
|
||||||
|
"ADDMECC",
|
||||||
|
"ADDMEVCC",
|
||||||
|
"ADDMEV",
|
||||||
|
"ADDE",
|
||||||
|
"ADDECC",
|
||||||
|
"ADDEVCC",
|
||||||
|
"ADDEV",
|
||||||
|
"ADDZE",
|
||||||
|
"ADDZECC",
|
||||||
|
"ADDZEVCC",
|
||||||
|
"ADDZEV",
|
||||||
|
"AND",
|
||||||
|
"ANDCC",
|
||||||
|
"ANDN",
|
||||||
|
"ANDNCC",
|
||||||
|
"BC",
|
||||||
|
"BCL",
|
||||||
|
"BEQ",
|
||||||
|
"BGE",
|
||||||
|
"BGT",
|
||||||
|
"BLE",
|
||||||
|
"BLT",
|
||||||
|
"BNE",
|
||||||
|
"BVC",
|
||||||
|
"BVS",
|
||||||
|
"CMP",
|
||||||
|
"CMPU",
|
||||||
|
"CNTLZW",
|
||||||
|
"CNTLZWCC",
|
||||||
|
"CRAND",
|
||||||
|
"CRANDN",
|
||||||
|
"CREQV",
|
||||||
|
"CRNAND",
|
||||||
|
"CRNOR",
|
||||||
|
"CROR",
|
||||||
|
"CRORN",
|
||||||
|
"CRXOR",
|
||||||
|
"DIVW",
|
||||||
|
"DIVWCC",
|
||||||
|
"DIVWVCC",
|
||||||
|
"DIVWV",
|
||||||
|
"DIVWU",
|
||||||
|
"DIVWUCC",
|
||||||
|
"DIVWUVCC",
|
||||||
|
"DIVWUV",
|
||||||
|
"EQV",
|
||||||
|
"EQVCC",
|
||||||
|
"EXTSB",
|
||||||
|
"EXTSBCC",
|
||||||
|
"EXTSH",
|
||||||
|
"EXTSHCC",
|
||||||
|
"FABS",
|
||||||
|
"FABSCC",
|
||||||
|
"FADD",
|
||||||
|
"FADDCC",
|
||||||
|
"FADDS",
|
||||||
|
"FADDSCC",
|
||||||
|
"FCMPO",
|
||||||
|
"FCMPU",
|
||||||
|
"FCTIW",
|
||||||
|
"FCTIWCC",
|
||||||
|
"FCTIWZ",
|
||||||
|
"FCTIWZCC",
|
||||||
|
"FDIV",
|
||||||
|
"FDIVCC",
|
||||||
|
"FDIVS",
|
||||||
|
"FDIVSCC",
|
||||||
|
"FMADD",
|
||||||
|
"FMADDCC",
|
||||||
|
"FMADDS",
|
||||||
|
"FMADDSCC",
|
||||||
|
"FMOVD",
|
||||||
|
"FMOVDCC",
|
||||||
|
"FMOVDU",
|
||||||
|
"FMOVS",
|
||||||
|
"FMOVSU",
|
||||||
|
"FMOVSX",
|
||||||
|
"FMOVSZ",
|
||||||
|
"FMSUB",
|
||||||
|
"FMSUBCC",
|
||||||
|
"FMSUBS",
|
||||||
|
"FMSUBSCC",
|
||||||
|
"FMUL",
|
||||||
|
"FMULCC",
|
||||||
|
"FMULS",
|
||||||
|
"FMULSCC",
|
||||||
|
"FNABS",
|
||||||
|
"FNABSCC",
|
||||||
|
"FNEG",
|
||||||
|
"FNEGCC",
|
||||||
|
"FNMADD",
|
||||||
|
"FNMADDCC",
|
||||||
|
"FNMADDS",
|
||||||
|
"FNMADDSCC",
|
||||||
|
"FNMSUB",
|
||||||
|
"FNMSUBCC",
|
||||||
|
"FNMSUBS",
|
||||||
|
"FNMSUBSCC",
|
||||||
|
"FRSP",
|
||||||
|
"FRSPCC",
|
||||||
|
"FSUB",
|
||||||
|
"FSUBCC",
|
||||||
|
"FSUBS",
|
||||||
|
"FSUBSCC",
|
||||||
|
"ISEL",
|
||||||
|
"MOVMW",
|
||||||
|
"LBAR",
|
||||||
|
"LSW",
|
||||||
|
"LWAR",
|
||||||
|
"LWSYNC",
|
||||||
|
"MOVDBR",
|
||||||
|
"MOVWBR",
|
||||||
|
"MOVB",
|
||||||
|
"MOVBU",
|
||||||
|
"MOVBZ",
|
||||||
|
"MOVBZU",
|
||||||
|
"MOVH",
|
||||||
|
"MOVHBR",
|
||||||
|
"MOVHU",
|
||||||
|
"MOVHZ",
|
||||||
|
"MOVHZU",
|
||||||
|
"MOVW",
|
||||||
|
"MOVWU",
|
||||||
|
"MOVFL",
|
||||||
|
"MOVCRFS",
|
||||||
|
"MTFSB0",
|
||||||
|
"MTFSB0CC",
|
||||||
|
"MTFSB1",
|
||||||
|
"MTFSB1CC",
|
||||||
|
"MULHW",
|
||||||
|
"MULHWCC",
|
||||||
|
"MULHWU",
|
||||||
|
"MULHWUCC",
|
||||||
|
"MULLW",
|
||||||
|
"MULLWCC",
|
||||||
|
"MULLWVCC",
|
||||||
|
"MULLWV",
|
||||||
|
"NAND",
|
||||||
|
"NANDCC",
|
||||||
|
"NEG",
|
||||||
|
"NEGCC",
|
||||||
|
"NEGVCC",
|
||||||
|
"NEGV",
|
||||||
|
"NOR",
|
||||||
|
"NORCC",
|
||||||
|
"OR",
|
||||||
|
"ORCC",
|
||||||
|
"ORN",
|
||||||
|
"ORNCC",
|
||||||
|
"REM",
|
||||||
|
"REMCC",
|
||||||
|
"REMV",
|
||||||
|
"REMVCC",
|
||||||
|
"REMU",
|
||||||
|
"REMUCC",
|
||||||
|
"REMUV",
|
||||||
|
"REMUVCC",
|
||||||
|
"RFI",
|
||||||
|
"RLWMI",
|
||||||
|
"RLWMICC",
|
||||||
|
"RLWNM",
|
||||||
|
"RLWNMCC",
|
||||||
|
"SLW",
|
||||||
|
"SLWCC",
|
||||||
|
"SRW",
|
||||||
|
"SRAW",
|
||||||
|
"SRAWCC",
|
||||||
|
"SRWCC",
|
||||||
|
"STBCCC",
|
||||||
|
"STSW",
|
||||||
|
"STWCCC",
|
||||||
|
"SUB",
|
||||||
|
"SUBCC",
|
||||||
|
"SUBVCC",
|
||||||
|
"SUBC",
|
||||||
|
"SUBCCC",
|
||||||
|
"SUBCV",
|
||||||
|
"SUBCVCC",
|
||||||
|
"SUBME",
|
||||||
|
"SUBMECC",
|
||||||
|
"SUBMEVCC",
|
||||||
|
"SUBMEV",
|
||||||
|
"SUBV",
|
||||||
|
"SUBE",
|
||||||
|
"SUBECC",
|
||||||
|
"SUBEV",
|
||||||
|
"SUBEVCC",
|
||||||
|
"SUBZE",
|
||||||
|
"SUBZECC",
|
||||||
|
"SUBZEVCC",
|
||||||
|
"SUBZEV",
|
||||||
|
"SYNC",
|
||||||
|
"XOR",
|
||||||
|
"XORCC",
|
||||||
|
"DCBF",
|
||||||
|
"DCBI",
|
||||||
|
"DCBST",
|
||||||
|
"DCBT",
|
||||||
|
"DCBTST",
|
||||||
|
"DCBZ",
|
||||||
|
"ECIWX",
|
||||||
|
"ECOWX",
|
||||||
|
"EIEIO",
|
||||||
|
"ICBI",
|
||||||
|
"ISYNC",
|
||||||
|
"PTESYNC",
|
||||||
|
"TLBIE",
|
||||||
|
"TLBIEL",
|
||||||
|
"TLBSYNC",
|
||||||
|
"TW",
|
||||||
|
"SYSCALL",
|
||||||
|
"WORD",
|
||||||
|
"RFCI",
|
||||||
|
"FRES",
|
||||||
|
"FRESCC",
|
||||||
|
"FRIM",
|
||||||
|
"FRIMCC",
|
||||||
|
"FRIP",
|
||||||
|
"FRIPCC",
|
||||||
|
"FRIZ",
|
||||||
|
"FRIZCC",
|
||||||
|
"FRSQRTE",
|
||||||
|
"FRSQRTECC",
|
||||||
|
"FSEL",
|
||||||
|
"FSELCC",
|
||||||
|
"FSQRT",
|
||||||
|
"FSQRTCC",
|
||||||
|
"FSQRTS",
|
||||||
|
"FSQRTSCC",
|
||||||
|
"CNTLZD",
|
||||||
|
"CNTLZDCC",
|
||||||
|
"CMPW",
|
||||||
|
"CMPWU",
|
||||||
|
"DIVD",
|
||||||
|
"DIVDCC",
|
||||||
|
"DIVDE",
|
||||||
|
"DIVDECC",
|
||||||
|
"DIVDEU",
|
||||||
|
"DIVDEUCC",
|
||||||
|
"DIVDVCC",
|
||||||
|
"DIVDV",
|
||||||
|
"DIVDU",
|
||||||
|
"DIVDUCC",
|
||||||
|
"DIVDUVCC",
|
||||||
|
"DIVDUV",
|
||||||
|
"EXTSW",
|
||||||
|
"EXTSWCC",
|
||||||
|
"FCFID",
|
||||||
|
"FCFIDCC",
|
||||||
|
"FCFIDU",
|
||||||
|
"FCFIDUCC",
|
||||||
|
"FCTID",
|
||||||
|
"FCTIDCC",
|
||||||
|
"FCTIDZ",
|
||||||
|
"FCTIDZCC",
|
||||||
|
"LDAR",
|
||||||
|
"MOVD",
|
||||||
|
"MOVDU",
|
||||||
|
"MOVWZ",
|
||||||
|
"MOVWZU",
|
||||||
|
"MULHD",
|
||||||
|
"MULHDCC",
|
||||||
|
"MULHDU",
|
||||||
|
"MULHDUCC",
|
||||||
|
"MULLD",
|
||||||
|
"MULLDCC",
|
||||||
|
"MULLDVCC",
|
||||||
|
"MULLDV",
|
||||||
|
"RFID",
|
||||||
|
"RLDMI",
|
||||||
|
"RLDMICC",
|
||||||
|
"RLDIMI",
|
||||||
|
"RLDIMICC",
|
||||||
|
"RLDC",
|
||||||
|
"RLDCCC",
|
||||||
|
"RLDCR",
|
||||||
|
"RLDCRCC",
|
||||||
|
"RLDICR",
|
||||||
|
"RLDICRCC",
|
||||||
|
"RLDCL",
|
||||||
|
"RLDCLCC",
|
||||||
|
"RLDICL",
|
||||||
|
"RLDICLCC",
|
||||||
|
"SLBIA",
|
||||||
|
"SLBIE",
|
||||||
|
"SLBMFEE",
|
||||||
|
"SLBMFEV",
|
||||||
|
"SLBMTE",
|
||||||
|
"SLD",
|
||||||
|
"SLDCC",
|
||||||
|
"SRD",
|
||||||
|
"SRAD",
|
||||||
|
"SRADCC",
|
||||||
|
"SRDCC",
|
||||||
|
"STDCCC",
|
||||||
|
"TD",
|
||||||
|
"DWORD",
|
||||||
|
"REMD",
|
||||||
|
"REMDCC",
|
||||||
|
"REMDV",
|
||||||
|
"REMDVCC",
|
||||||
|
"REMDU",
|
||||||
|
"REMDUCC",
|
||||||
|
"REMDUV",
|
||||||
|
"REMDUVCC",
|
||||||
|
"HRFID",
|
||||||
|
"LV",
|
||||||
|
"LVEBX",
|
||||||
|
"LVEHX",
|
||||||
|
"LVEWX",
|
||||||
|
"LVX",
|
||||||
|
"LVXL",
|
||||||
|
"LVSL",
|
||||||
|
"LVSR",
|
||||||
|
"STV",
|
||||||
|
"STVEBX",
|
||||||
|
"STVEHX",
|
||||||
|
"STVEWX",
|
||||||
|
"STVX",
|
||||||
|
"STVXL",
|
||||||
|
"VAND",
|
||||||
|
"VANDL",
|
||||||
|
"VANDC",
|
||||||
|
"VNAND",
|
||||||
|
"VOR",
|
||||||
|
"VORL",
|
||||||
|
"VORC",
|
||||||
|
"VNOR",
|
||||||
|
"VXOR",
|
||||||
|
"VEQV",
|
||||||
|
"VADDUM",
|
||||||
|
"VADDUBM",
|
||||||
|
"VADDUHM",
|
||||||
|
"VADDUWM",
|
||||||
|
"VADDUDM",
|
||||||
|
"VADDUQM",
|
||||||
|
"VADDCU",
|
||||||
|
"VADDCUQ",
|
||||||
|
"VADDCUW",
|
||||||
|
"VADDUS",
|
||||||
|
"VADDUBS",
|
||||||
|
"VADDUHS",
|
||||||
|
"VADDUWS",
|
||||||
|
"VADDSS",
|
||||||
|
"VADDSBS",
|
||||||
|
"VADDSHS",
|
||||||
|
"VADDSWS",
|
||||||
|
"VADDE",
|
||||||
|
"VADDEUQM",
|
||||||
|
"VADDECUQ",
|
||||||
|
"VSUBUM",
|
||||||
|
"VSUBUBM",
|
||||||
|
"VSUBUHM",
|
||||||
|
"VSUBUWM",
|
||||||
|
"VSUBUDM",
|
||||||
|
"VSUBUQM",
|
||||||
|
"VSUBCU",
|
||||||
|
"VSUBCUQ",
|
||||||
|
"VSUBCUW",
|
||||||
|
"VSUBUS",
|
||||||
|
"VSUBUBS",
|
||||||
|
"VSUBUHS",
|
||||||
|
"VSUBUWS",
|
||||||
|
"VSUBSS",
|
||||||
|
"VSUBSBS",
|
||||||
|
"VSUBSHS",
|
||||||
|
"VSUBSWS",
|
||||||
|
"VSUBE",
|
||||||
|
"VSUBEUQM",
|
||||||
|
"VSUBECUQ",
|
||||||
|
"VR",
|
||||||
|
"VRLB",
|
||||||
|
"VRLH",
|
||||||
|
"VRLW",
|
||||||
|
"VRLD",
|
||||||
|
"VS",
|
||||||
|
"VSLB",
|
||||||
|
"VSLH",
|
||||||
|
"VSLW",
|
||||||
|
"VSL",
|
||||||
|
"VSLO",
|
||||||
|
"VSRB",
|
||||||
|
"VSRH",
|
||||||
|
"VSRW",
|
||||||
|
"VSR",
|
||||||
|
"VSRO",
|
||||||
|
"VSLD",
|
||||||
|
"VSRD",
|
||||||
|
"VSA",
|
||||||
|
"VSRAB",
|
||||||
|
"VSRAH",
|
||||||
|
"VSRAW",
|
||||||
|
"VSRAD",
|
||||||
|
"VSOI",
|
||||||
|
"VSLDOI",
|
||||||
|
"VCLZ",
|
||||||
|
"VCLZB",
|
||||||
|
"VCLZH",
|
||||||
|
"VCLZW",
|
||||||
|
"VCLZD",
|
||||||
|
"VPOPCNT",
|
||||||
|
"VPOPCNTB",
|
||||||
|
"VPOPCNTH",
|
||||||
|
"VPOPCNTW",
|
||||||
|
"VPOPCNTD",
|
||||||
|
"VCMPEQ",
|
||||||
|
"VCMPEQUB",
|
||||||
|
"VCMPEQUBCC",
|
||||||
|
"VCMPEQUH",
|
||||||
|
"VCMPEQUHCC",
|
||||||
|
"VCMPEQUW",
|
||||||
|
"VCMPEQUWCC",
|
||||||
|
"VCMPEQUD",
|
||||||
|
"VCMPEQUDCC",
|
||||||
|
"VCMPGT",
|
||||||
|
"VCMPGTUB",
|
||||||
|
"VCMPGTUBCC",
|
||||||
|
"VCMPGTUH",
|
||||||
|
"VCMPGTUHCC",
|
||||||
|
"VCMPGTUW",
|
||||||
|
"VCMPGTUWCC",
|
||||||
|
"VCMPGTUD",
|
||||||
|
"VCMPGTUDCC",
|
||||||
|
"VCMPGTSB",
|
||||||
|
"VCMPGTSBCC",
|
||||||
|
"VCMPGTSH",
|
||||||
|
"VCMPGTSHCC",
|
||||||
|
"VCMPGTSW",
|
||||||
|
"VCMPGTSWCC",
|
||||||
|
"VCMPGTSD",
|
||||||
|
"VCMPGTSDCC",
|
||||||
|
"VPERM",
|
||||||
|
"VSEL",
|
||||||
|
"VSPLT",
|
||||||
|
"VSPLTB",
|
||||||
|
"VSPLTH",
|
||||||
|
"VSPLTW",
|
||||||
|
"VSPLTI",
|
||||||
|
"VSPLTISB",
|
||||||
|
"VSPLTISH",
|
||||||
|
"VSPLTISW",
|
||||||
|
"VCIPH",
|
||||||
|
"VCIPHER",
|
||||||
|
"VCIPHERLAST",
|
||||||
|
"VNCIPH",
|
||||||
|
"VNCIPHER",
|
||||||
|
"VNCIPHERLAST",
|
||||||
|
"VSBOX",
|
||||||
|
"VSHASIGMA",
|
||||||
|
"VSHASIGMAW",
|
||||||
|
"VSHASIGMAD",
|
||||||
|
"LXV",
|
||||||
|
"LXVD2X",
|
||||||
|
"LXVDSX",
|
||||||
|
"LXVW4X",
|
||||||
|
"STXV",
|
||||||
|
"STXVD2X",
|
||||||
|
"STXVW4X",
|
||||||
|
"LXS",
|
||||||
|
"LXSDX",
|
||||||
|
"STXS",
|
||||||
|
"STXSDX",
|
||||||
|
"LXSI",
|
||||||
|
"LXSIWAX",
|
||||||
|
"LXSIWZX",
|
||||||
|
"STXSI",
|
||||||
|
"STXSIWX",
|
||||||
|
"MFVSR",
|
||||||
|
"MFVSRD",
|
||||||
|
"MFVSRWZ",
|
||||||
|
"MTVSR",
|
||||||
|
"MTVSRD",
|
||||||
|
"MTVSRWA",
|
||||||
|
"MTVSRWZ",
|
||||||
|
"XXLAND",
|
||||||
|
"XXLANDQ",
|
||||||
|
"XXLANDC",
|
||||||
|
"XXLEQV",
|
||||||
|
"XXLNAND",
|
||||||
|
"XXLOR",
|
||||||
|
"XXLORC",
|
||||||
|
"XXLNOR",
|
||||||
|
"XXLORQ",
|
||||||
|
"XXLXOR",
|
||||||
|
"XXSEL",
|
||||||
|
"XXMRG",
|
||||||
|
"XXMRGHW",
|
||||||
|
"XXMRGLW",
|
||||||
|
"XXSPLT",
|
||||||
|
"XXSPLTW",
|
||||||
|
"XXPERM",
|
||||||
|
"XXPERMDI",
|
||||||
|
"XXSI",
|
||||||
|
"XXSLDWI",
|
||||||
|
"XSCV",
|
||||||
|
"XSCVDPSP",
|
||||||
|
"XSCVSPDP",
|
||||||
|
"XSCVDPSPN",
|
||||||
|
"XSCVSPDPN",
|
||||||
|
"XVCV",
|
||||||
|
"XVCVDPSP",
|
||||||
|
"XVCVSPDP",
|
||||||
|
"XSCVX",
|
||||||
|
"XSCVDPSXDS",
|
||||||
|
"XSCVDPSXWS",
|
||||||
|
"XSCVDPUXDS",
|
||||||
|
"XSCVDPUXWS",
|
||||||
|
"XSCVXP",
|
||||||
|
"XSCVSXDDP",
|
||||||
|
"XSCVUXDDP",
|
||||||
|
"XSCVSXDSP",
|
||||||
|
"XSCVUXDSP",
|
||||||
|
"XVCVX",
|
||||||
|
"XVCVDPSXDS",
|
||||||
|
"XVCVDPSXWS",
|
||||||
|
"XVCVDPUXDS",
|
||||||
|
"XVCVDPUXWS",
|
||||||
|
"XVCVSPSXDS",
|
||||||
|
"XVCVSPSXWS",
|
||||||
|
"XVCVSPUXDS",
|
||||||
|
"XVCVSPUXWS",
|
||||||
|
"XVCVXP",
|
||||||
|
"XVCVSXDDP",
|
||||||
|
"XVCVSXWDP",
|
||||||
|
"XVCVUXDDP",
|
||||||
|
"XVCVUXWDP",
|
||||||
|
"XVCVSXDSP",
|
||||||
|
"XVCVSXWSP",
|
||||||
|
"XVCVUXDSP",
|
||||||
|
"XVCVUXWSP",
|
||||||
|
"LAST",
|
||||||
|
}
|
49
vendor/github.com/google/gops/internal/obj/ppc64/anames9.go
generated
vendored
Normal file
49
vendor/github.com/google/gops/internal/obj/ppc64/anames9.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package ppc64
|
||||||
|
|
||||||
|
var cnames9 = []string{
|
||||||
|
"NONE",
|
||||||
|
"REG",
|
||||||
|
"FREG",
|
||||||
|
"VREG",
|
||||||
|
"VSREG",
|
||||||
|
"CREG",
|
||||||
|
"SPR",
|
||||||
|
"ZCON",
|
||||||
|
"SCON",
|
||||||
|
"UCON",
|
||||||
|
"ADDCON",
|
||||||
|
"ANDCON",
|
||||||
|
"LCON",
|
||||||
|
"DCON",
|
||||||
|
"SACON",
|
||||||
|
"SECON",
|
||||||
|
"LACON",
|
||||||
|
"LECON",
|
||||||
|
"DACON",
|
||||||
|
"SBRA",
|
||||||
|
"LBRA",
|
||||||
|
"SAUTO",
|
||||||
|
"LAUTO",
|
||||||
|
"SEXT",
|
||||||
|
"LEXT",
|
||||||
|
"ZOREG",
|
||||||
|
"SOREG",
|
||||||
|
"LOREG",
|
||||||
|
"FPSCR",
|
||||||
|
"MSR",
|
||||||
|
"XER",
|
||||||
|
"LR",
|
||||||
|
"CTR",
|
||||||
|
"ANY",
|
||||||
|
"GOK",
|
||||||
|
"ADDR",
|
||||||
|
"GOTADDR",
|
||||||
|
"TLS_LE",
|
||||||
|
"TLS_IE",
|
||||||
|
"TEXTSIZE",
|
||||||
|
"NCLASS",
|
||||||
|
}
|
4552
vendor/github.com/google/gops/internal/obj/ppc64/asm9.go
generated
vendored
Normal file
4552
vendor/github.com/google/gops/internal/obj/ppc64/asm9.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
105
vendor/github.com/google/gops/internal/obj/ppc64/list9.go
generated
vendored
Normal file
105
vendor/github.com/google/gops/internal/obj/ppc64/list9.go
generated
vendored
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// cmd/9l/list.c from Vita Nuova.
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package ppc64
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gops/internal/obj"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
obj.RegisterRegister(obj.RBasePPC64, REG_DCR0+1024, Rconv)
|
||||||
|
obj.RegisterOpcode(obj.ABasePPC64, Anames)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Rconv(r int) string {
|
||||||
|
if r == 0 {
|
||||||
|
return "NONE"
|
||||||
|
}
|
||||||
|
if r == REGG {
|
||||||
|
// Special case.
|
||||||
|
return "g"
|
||||||
|
}
|
||||||
|
if REG_R0 <= r && r <= REG_R31 {
|
||||||
|
return fmt.Sprintf("R%d", r-REG_R0)
|
||||||
|
}
|
||||||
|
if REG_F0 <= r && r <= REG_F31 {
|
||||||
|
return fmt.Sprintf("F%d", r-REG_F0)
|
||||||
|
}
|
||||||
|
if REG_V0 <= r && r <= REG_V31 {
|
||||||
|
return fmt.Sprintf("V%d", r-REG_V0)
|
||||||
|
}
|
||||||
|
if REG_VS0 <= r && r <= REG_VS63 {
|
||||||
|
return fmt.Sprintf("VS%d", r-REG_VS0)
|
||||||
|
}
|
||||||
|
if REG_CR0 <= r && r <= REG_CR7 {
|
||||||
|
return fmt.Sprintf("CR%d", r-REG_CR0)
|
||||||
|
}
|
||||||
|
if r == REG_CR {
|
||||||
|
return "CR"
|
||||||
|
}
|
||||||
|
if REG_SPR0 <= r && r <= REG_SPR0+1023 {
|
||||||
|
switch r {
|
||||||
|
case REG_XER:
|
||||||
|
return "XER"
|
||||||
|
|
||||||
|
case REG_LR:
|
||||||
|
return "LR"
|
||||||
|
|
||||||
|
case REG_CTR:
|
||||||
|
return "CTR"
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("SPR(%d)", r-REG_SPR0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if REG_DCR0 <= r && r <= REG_DCR0+1023 {
|
||||||
|
return fmt.Sprintf("DCR(%d)", r-REG_DCR0)
|
||||||
|
}
|
||||||
|
if r == REG_FPSCR {
|
||||||
|
return "FPSCR"
|
||||||
|
}
|
||||||
|
if r == REG_MSR {
|
||||||
|
return "MSR"
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("Rgok(%d)", r-obj.RBasePPC64)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DRconv(a int) string {
|
||||||
|
s := "C_??"
|
||||||
|
if a >= C_NONE && a <= C_NCLASS {
|
||||||
|
s = cnames9[a]
|
||||||
|
}
|
||||||
|
var fp string
|
||||||
|
fp += s
|
||||||
|
return fp
|
||||||
|
}
|
1251
vendor/github.com/google/gops/internal/obj/ppc64/obj9.go
generated
vendored
Normal file
1251
vendor/github.com/google/gops/internal/obj/ppc64/obj9.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
17
vendor/github.com/google/gops/internal/obj/reloctype_string.go
generated
vendored
Normal file
17
vendor/github.com/google/gops/internal/obj/reloctype_string.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Code generated by "stringer -type=RelocType"; DO NOT EDIT
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLS"
|
||||||
|
|
||||||
|
var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 195, 206, 216, 225, 235, 249, 263, 279, 293, 307, 318, 332, 347, 364, 382, 403, 413, 424, 437}
|
||||||
|
|
||||||
|
func (i RelocType) String() string {
|
||||||
|
i -= 1
|
||||||
|
if i < 0 || i >= RelocType(len(_RelocType_index)-1) {
|
||||||
|
return fmt.Sprintf("RelocType(%d)", i+1)
|
||||||
|
}
|
||||||
|
return _RelocType_name[_RelocType_index[i]:_RelocType_index[i+1]]
|
||||||
|
}
|
926
vendor/github.com/google/gops/internal/obj/s390x/a.out.go
generated
vendored
Normal file
926
vendor/github.com/google/gops/internal/obj/s390x/a.out.go
generated
vendored
Normal file
@ -0,0 +1,926 @@
|
|||||||
|
// Based on cmd/internal/obj/ppc64/a.out.go.
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package s390x
|
||||||
|
|
||||||
|
import "github.com/google/gops/internal/obj"
|
||||||
|
|
||||||
|
//go:generate go run ../stringer.go -i $GOFILE -o anames.go -p s390x
|
||||||
|
|
||||||
|
const (
|
||||||
|
NSNAME = 8
|
||||||
|
NSYM = 50
|
||||||
|
NREG = 16 // number of general purpose registers
|
||||||
|
NFREG = 16 // number of floating point registers
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// General purpose registers (GPRs).
|
||||||
|
REG_R0 = obj.RBaseS390X + iota
|
||||||
|
REG_R1
|
||||||
|
REG_R2
|
||||||
|
REG_R3
|
||||||
|
REG_R4
|
||||||
|
REG_R5
|
||||||
|
REG_R6
|
||||||
|
REG_R7
|
||||||
|
REG_R8
|
||||||
|
REG_R9
|
||||||
|
REG_R10
|
||||||
|
REG_R11
|
||||||
|
REG_R12
|
||||||
|
REG_R13
|
||||||
|
REG_R14
|
||||||
|
REG_R15
|
||||||
|
|
||||||
|
// Floating point registers (FPRs).
|
||||||
|
REG_F0
|
||||||
|
REG_F1
|
||||||
|
REG_F2
|
||||||
|
REG_F3
|
||||||
|
REG_F4
|
||||||
|
REG_F5
|
||||||
|
REG_F6
|
||||||
|
REG_F7
|
||||||
|
REG_F8
|
||||||
|
REG_F9
|
||||||
|
REG_F10
|
||||||
|
REG_F11
|
||||||
|
REG_F12
|
||||||
|
REG_F13
|
||||||
|
REG_F14
|
||||||
|
REG_F15
|
||||||
|
|
||||||
|
// Vector registers (VRs) - only available when the vector
|
||||||
|
// facility is installed.
|
||||||
|
// V0-V15 are aliases for F0-F15.
|
||||||
|
// We keep them in a separate space to make printing etc. easier
|
||||||
|
// If the code generator ever emits vector instructions it will
|
||||||
|
// need to take into account the aliasing.
|
||||||
|
REG_V0
|
||||||
|
REG_V1
|
||||||
|
REG_V2
|
||||||
|
REG_V3
|
||||||
|
REG_V4
|
||||||
|
REG_V5
|
||||||
|
REG_V6
|
||||||
|
REG_V7
|
||||||
|
REG_V8
|
||||||
|
REG_V9
|
||||||
|
REG_V10
|
||||||
|
REG_V11
|
||||||
|
REG_V12
|
||||||
|
REG_V13
|
||||||
|
REG_V14
|
||||||
|
REG_V15
|
||||||
|
REG_V16
|
||||||
|
REG_V17
|
||||||
|
REG_V18
|
||||||
|
REG_V19
|
||||||
|
REG_V20
|
||||||
|
REG_V21
|
||||||
|
REG_V22
|
||||||
|
REG_V23
|
||||||
|
REG_V24
|
||||||
|
REG_V25
|
||||||
|
REG_V26
|
||||||
|
REG_V27
|
||||||
|
REG_V28
|
||||||
|
REG_V29
|
||||||
|
REG_V30
|
||||||
|
REG_V31
|
||||||
|
|
||||||
|
// Access registers (ARs).
|
||||||
|
// The thread pointer is typically stored in the register pair
|
||||||
|
// AR0 and AR1.
|
||||||
|
REG_AR0
|
||||||
|
REG_AR1
|
||||||
|
REG_AR2
|
||||||
|
REG_AR3
|
||||||
|
REG_AR4
|
||||||
|
REG_AR5
|
||||||
|
REG_AR6
|
||||||
|
REG_AR7
|
||||||
|
REG_AR8
|
||||||
|
REG_AR9
|
||||||
|
REG_AR10
|
||||||
|
REG_AR11
|
||||||
|
REG_AR12
|
||||||
|
REG_AR13
|
||||||
|
REG_AR14
|
||||||
|
REG_AR15
|
||||||
|
|
||||||
|
REG_RESERVED // end of allocated registers
|
||||||
|
|
||||||
|
REGZERO = REG_R0 // set to zero
|
||||||
|
REGARG = -1 // -1 disables passing the first argument in register
|
||||||
|
REGRT1 = REG_R3 // used during zeroing of the stack - not reserved
|
||||||
|
REGRT2 = REG_R4 // used during zeroing of the stack - not reserved
|
||||||
|
REGTMP = REG_R10 // scratch register used in the assembler and linker
|
||||||
|
REGTMP2 = REG_R11 // scratch register used in the assembler and linker
|
||||||
|
REGCTXT = REG_R12 // context for closures
|
||||||
|
REGG = REG_R13 // G
|
||||||
|
REG_LR = REG_R14 // link register
|
||||||
|
REGSP = REG_R15 // stack pointer
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
BIG = 32768 - 8
|
||||||
|
DISP12 = 4096
|
||||||
|
DISP16 = 65536
|
||||||
|
DISP20 = 1048576
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// mark flags
|
||||||
|
LABEL = 1 << 0
|
||||||
|
LEAF = 1 << 1
|
||||||
|
FLOAT = 1 << 2
|
||||||
|
BRANCH = 1 << 3
|
||||||
|
LOAD = 1 << 4
|
||||||
|
FCMP = 1 << 5
|
||||||
|
SYNC = 1 << 6
|
||||||
|
LIST = 1 << 7
|
||||||
|
FOLL = 1 << 8
|
||||||
|
NOSCHED = 1 << 9
|
||||||
|
)
|
||||||
|
|
||||||
|
const ( // comments from func aclass in asmz.go
|
||||||
|
C_NONE = iota
|
||||||
|
C_REG // general-purpose register (64-bit)
|
||||||
|
C_FREG // floating-point register (64-bit)
|
||||||
|
C_VREG // vector register (128-bit)
|
||||||
|
C_AREG // access register (32-bit)
|
||||||
|
C_ZCON // constant == 0
|
||||||
|
C_SCON // 0 <= constant <= 0x7fff (positive int16)
|
||||||
|
C_UCON // constant & 0xffff == 0 (int16 or uint16)
|
||||||
|
C_ADDCON // 0 > constant >= -0x8000 (negative int16)
|
||||||
|
C_ANDCON // constant <= 0xffff
|
||||||
|
C_LCON // constant (int32 or uint32)
|
||||||
|
C_DCON // constant (int64 or uint64)
|
||||||
|
C_SACON // computed address, 16-bit displacement, possibly SP-relative
|
||||||
|
C_LACON // computed address, 32-bit displacement, possibly SP-relative
|
||||||
|
C_DACON // computed address, 64-bit displacment?
|
||||||
|
C_SBRA // short branch
|
||||||
|
C_LBRA // long branch
|
||||||
|
C_SAUTO // short auto
|
||||||
|
C_LAUTO // long auto
|
||||||
|
C_ZOREG // heap address, register-based, displacement == 0
|
||||||
|
C_SOREG // heap address, register-based, int16 displacement
|
||||||
|
C_LOREG // heap address, register-based, int32 displacement
|
||||||
|
C_TLS_LE // TLS - local exec model (for executables)
|
||||||
|
C_TLS_IE // TLS - initial exec model (for shared libraries loaded at program startup)
|
||||||
|
C_GOK // general address
|
||||||
|
C_ADDR // relocation for extern or static symbols (loads and stores)
|
||||||
|
C_SYMADDR // relocation for extern or static symbols (address taking)
|
||||||
|
C_GOTADDR // GOT slot for a symbol in -dynlink mode
|
||||||
|
C_TEXTSIZE // text size
|
||||||
|
C_ANY
|
||||||
|
C_NCLASS // must be the last
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// integer arithmetic
|
||||||
|
AADD = obj.ABaseS390X + obj.A_ARCHSPECIFIC + iota
|
||||||
|
AADDC
|
||||||
|
AADDE
|
||||||
|
AADDW
|
||||||
|
ADIVW
|
||||||
|
ADIVWU
|
||||||
|
ADIVD
|
||||||
|
ADIVDU
|
||||||
|
AMODW
|
||||||
|
AMODWU
|
||||||
|
AMODD
|
||||||
|
AMODDU
|
||||||
|
AMULLW
|
||||||
|
AMULLD
|
||||||
|
AMULHD
|
||||||
|
AMULHDU
|
||||||
|
ASUB
|
||||||
|
ASUBC
|
||||||
|
ASUBV
|
||||||
|
ASUBE
|
||||||
|
ASUBW
|
||||||
|
ANEG
|
||||||
|
ANEGW
|
||||||
|
|
||||||
|
// integer moves
|
||||||
|
AMOVWBR
|
||||||
|
AMOVB
|
||||||
|
AMOVBZ
|
||||||
|
AMOVH
|
||||||
|
AMOVHBR
|
||||||
|
AMOVHZ
|
||||||
|
AMOVW
|
||||||
|
AMOVWZ
|
||||||
|
AMOVD
|
||||||
|
AMOVDBR
|
||||||
|
|
||||||
|
// conditional moves
|
||||||
|
AMOVDEQ
|
||||||
|
AMOVDGE
|
||||||
|
AMOVDGT
|
||||||
|
AMOVDLE
|
||||||
|
AMOVDLT
|
||||||
|
AMOVDNE
|
||||||
|
|
||||||
|
// find leftmost one
|
||||||
|
AFLOGR
|
||||||
|
|
||||||
|
// integer bitwise
|
||||||
|
AAND
|
||||||
|
AANDW
|
||||||
|
AOR
|
||||||
|
AORW
|
||||||
|
AXOR
|
||||||
|
AXORW
|
||||||
|
ASLW
|
||||||
|
ASLD
|
||||||
|
ASRW
|
||||||
|
ASRAW
|
||||||
|
ASRD
|
||||||
|
ASRAD
|
||||||
|
ARLL
|
||||||
|
ARLLG
|
||||||
|
|
||||||
|
// floating point
|
||||||
|
AFABS
|
||||||
|
AFADD
|
||||||
|
AFADDS
|
||||||
|
AFCMPO
|
||||||
|
AFCMPU
|
||||||
|
ACEBR
|
||||||
|
AFDIV
|
||||||
|
AFDIVS
|
||||||
|
AFMADD
|
||||||
|
AFMADDS
|
||||||
|
AFMOVD
|
||||||
|
AFMOVS
|
||||||
|
AFMSUB
|
||||||
|
AFMSUBS
|
||||||
|
AFMUL
|
||||||
|
AFMULS
|
||||||
|
AFNABS
|
||||||
|
AFNEG
|
||||||
|
AFNEGS
|
||||||
|
AFNMADD
|
||||||
|
AFNMADDS
|
||||||
|
AFNMSUB
|
||||||
|
AFNMSUBS
|
||||||
|
ALEDBR
|
||||||
|
ALDEBR
|
||||||
|
AFSUB
|
||||||
|
AFSUBS
|
||||||
|
AFSQRT
|
||||||
|
AFSQRTS
|
||||||
|
AFIEBR
|
||||||
|
AFIDBR
|
||||||
|
|
||||||
|
// convert from int32/int64 to float/float64
|
||||||
|
ACEFBRA
|
||||||
|
ACDFBRA
|
||||||
|
ACEGBRA
|
||||||
|
ACDGBRA
|
||||||
|
|
||||||
|
// convert from float/float64 to int32/int64
|
||||||
|
ACFEBRA
|
||||||
|
ACFDBRA
|
||||||
|
ACGEBRA
|
||||||
|
ACGDBRA
|
||||||
|
|
||||||
|
// convert from uint32/uint64 to float/float64
|
||||||
|
ACELFBR
|
||||||
|
ACDLFBR
|
||||||
|
ACELGBR
|
||||||
|
ACDLGBR
|
||||||
|
|
||||||
|
// convert from float/float64 to uint32/uint64
|
||||||
|
ACLFEBR
|
||||||
|
ACLFDBR
|
||||||
|
ACLGEBR
|
||||||
|
ACLGDBR
|
||||||
|
|
||||||
|
// compare
|
||||||
|
ACMP
|
||||||
|
ACMPU
|
||||||
|
ACMPW
|
||||||
|
ACMPWU
|
||||||
|
|
||||||
|
// compare and swap
|
||||||
|
ACS
|
||||||
|
ACSG
|
||||||
|
|
||||||
|
// serialize
|
||||||
|
ASYNC
|
||||||
|
|
||||||
|
// branch
|
||||||
|
ABC
|
||||||
|
ABCL
|
||||||
|
ABEQ
|
||||||
|
ABGE
|
||||||
|
ABGT
|
||||||
|
ABLE
|
||||||
|
ABLT
|
||||||
|
ABLEU
|
||||||
|
ABLTU
|
||||||
|
ABNE
|
||||||
|
ABVC
|
||||||
|
ABVS
|
||||||
|
ASYSCALL
|
||||||
|
|
||||||
|
// compare and branch
|
||||||
|
ACMPBEQ
|
||||||
|
ACMPBGE
|
||||||
|
ACMPBGT
|
||||||
|
ACMPBLE
|
||||||
|
ACMPBLT
|
||||||
|
ACMPBNE
|
||||||
|
ACMPUBEQ
|
||||||
|
ACMPUBGE
|
||||||
|
ACMPUBGT
|
||||||
|
ACMPUBLE
|
||||||
|
ACMPUBLT
|
||||||
|
ACMPUBNE
|
||||||
|
|
||||||
|
// storage-and-storage
|
||||||
|
AMVC
|
||||||
|
ACLC
|
||||||
|
AXC
|
||||||
|
AOC
|
||||||
|
ANC
|
||||||
|
|
||||||
|
// load
|
||||||
|
AEXRL
|
||||||
|
ALARL
|
||||||
|
ALA
|
||||||
|
ALAY
|
||||||
|
|
||||||
|
// interlocked load and op
|
||||||
|
ALAA
|
||||||
|
ALAAG
|
||||||
|
ALAAL
|
||||||
|
ALAALG
|
||||||
|
ALAN
|
||||||
|
ALANG
|
||||||
|
ALAX
|
||||||
|
ALAXG
|
||||||
|
ALAO
|
||||||
|
ALAOG
|
||||||
|
|
||||||
|
// load/store multiple
|
||||||
|
ALMY
|
||||||
|
ALMG
|
||||||
|
ASTMY
|
||||||
|
ASTMG
|
||||||
|
|
||||||
|
// store clock
|
||||||
|
ASTCK
|
||||||
|
ASTCKC
|
||||||
|
ASTCKE
|
||||||
|
ASTCKF
|
||||||
|
|
||||||
|
// macros
|
||||||
|
ACLEAR
|
||||||
|
|
||||||
|
// vector
|
||||||
|
AVA
|
||||||
|
AVAB
|
||||||
|
AVAH
|
||||||
|
AVAF
|
||||||
|
AVAG
|
||||||
|
AVAQ
|
||||||
|
AVACC
|
||||||
|
AVACCB
|
||||||
|
AVACCH
|
||||||
|
AVACCF
|
||||||
|
AVACCG
|
||||||
|
AVACCQ
|
||||||
|
AVAC
|
||||||
|
AVACQ
|
||||||
|
AVACCC
|
||||||
|
AVACCCQ
|
||||||
|
AVN
|
||||||
|
AVNC
|
||||||
|
AVAVG
|
||||||
|
AVAVGB
|
||||||
|
AVAVGH
|
||||||
|
AVAVGF
|
||||||
|
AVAVGG
|
||||||
|
AVAVGL
|
||||||
|
AVAVGLB
|
||||||
|
AVAVGLH
|
||||||
|
AVAVGLF
|
||||||
|
AVAVGLG
|
||||||
|
AVCKSM
|
||||||
|
AVCEQ
|
||||||
|
AVCEQB
|
||||||
|
AVCEQH
|
||||||
|
AVCEQF
|
||||||
|
AVCEQG
|
||||||
|
AVCEQBS
|
||||||
|
AVCEQHS
|
||||||
|
AVCEQFS
|
||||||
|
AVCEQGS
|
||||||
|
AVCH
|
||||||
|
AVCHB
|
||||||
|
AVCHH
|
||||||
|
AVCHF
|
||||||
|
AVCHG
|
||||||
|
AVCHBS
|
||||||
|
AVCHHS
|
||||||
|
AVCHFS
|
||||||
|
AVCHGS
|
||||||
|
AVCHL
|
||||||
|
AVCHLB
|
||||||
|
AVCHLH
|
||||||
|
AVCHLF
|
||||||
|
AVCHLG
|
||||||
|
AVCHLBS
|
||||||
|
AVCHLHS
|
||||||
|
AVCHLFS
|
||||||
|
AVCHLGS
|
||||||
|
AVCLZ
|
||||||
|
AVCLZB
|
||||||
|
AVCLZH
|
||||||
|
AVCLZF
|
||||||
|
AVCLZG
|
||||||
|
AVCTZ
|
||||||
|
AVCTZB
|
||||||
|
AVCTZH
|
||||||
|
AVCTZF
|
||||||
|
AVCTZG
|
||||||
|
AVEC
|
||||||
|
AVECB
|
||||||
|
AVECH
|
||||||
|
AVECF
|
||||||
|
AVECG
|
||||||
|
AVECL
|
||||||
|
AVECLB
|
||||||
|
AVECLH
|
||||||
|
AVECLF
|
||||||
|
AVECLG
|
||||||
|
AVERIM
|
||||||
|
AVERIMB
|
||||||
|
AVERIMH
|
||||||
|
AVERIMF
|
||||||
|
AVERIMG
|
||||||
|
AVERLL
|
||||||
|
AVERLLB
|
||||||
|
AVERLLH
|
||||||
|
AVERLLF
|
||||||
|
AVERLLG
|
||||||
|
AVERLLV
|
||||||
|
AVERLLVB
|
||||||
|
AVERLLVH
|
||||||
|
AVERLLVF
|
||||||
|
AVERLLVG
|
||||||
|
AVESLV
|
||||||
|
AVESLVB
|
||||||
|
AVESLVH
|
||||||
|
AVESLVF
|
||||||
|
AVESLVG
|
||||||
|
AVESL
|
||||||
|
AVESLB
|
||||||
|
AVESLH
|
||||||
|
AVESLF
|
||||||
|
AVESLG
|
||||||
|
AVESRA
|
||||||
|
AVESRAB
|
||||||
|
AVESRAH
|
||||||
|
AVESRAF
|
||||||
|
AVESRAG
|
||||||
|
AVESRAV
|
||||||
|
AVESRAVB
|
||||||
|
AVESRAVH
|
||||||
|
AVESRAVF
|
||||||
|
AVESRAVG
|
||||||
|
AVESRL
|
||||||
|
AVESRLB
|
||||||
|
AVESRLH
|
||||||
|
AVESRLF
|
||||||
|
AVESRLG
|
||||||
|
AVESRLV
|
||||||
|
AVESRLVB
|
||||||
|
AVESRLVH
|
||||||
|
AVESRLVF
|
||||||
|
AVESRLVG
|
||||||
|
AVX
|
||||||
|
AVFAE
|
||||||
|
AVFAEB
|
||||||
|
AVFAEH
|
||||||
|
AVFAEF
|
||||||
|
AVFAEBS
|
||||||
|
AVFAEHS
|
||||||
|
AVFAEFS
|
||||||
|
AVFAEZB
|
||||||
|
AVFAEZH
|
||||||
|
AVFAEZF
|
||||||
|
AVFAEZBS
|
||||||
|
AVFAEZHS
|
||||||
|
AVFAEZFS
|
||||||
|
AVFEE
|
||||||
|
AVFEEB
|
||||||
|
AVFEEH
|
||||||
|
AVFEEF
|
||||||
|
AVFEEBS
|
||||||
|
AVFEEHS
|
||||||
|
AVFEEFS
|
||||||
|
AVFEEZB
|
||||||
|
AVFEEZH
|
||||||
|
AVFEEZF
|
||||||
|
AVFEEZBS
|
||||||
|
AVFEEZHS
|
||||||
|
AVFEEZFS
|
||||||
|
AVFENE
|
||||||
|
AVFENEB
|
||||||
|
AVFENEH
|
||||||
|
AVFENEF
|
||||||
|
AVFENEBS
|
||||||
|
AVFENEHS
|
||||||
|
AVFENEFS
|
||||||
|
AVFENEZB
|
||||||
|
AVFENEZH
|
||||||
|
AVFENEZF
|
||||||
|
AVFENEZBS
|
||||||
|
AVFENEZHS
|
||||||
|
AVFENEZFS
|
||||||
|
AVFA
|
||||||
|
AVFADB
|
||||||
|
AWFADB
|
||||||
|
AWFK
|
||||||
|
AWFKDB
|
||||||
|
AVFCE
|
||||||
|
AVFCEDB
|
||||||
|
AVFCEDBS
|
||||||
|
AWFCEDB
|
||||||
|
AWFCEDBS
|
||||||
|
AVFCH
|
||||||
|
AVFCHDB
|
||||||
|
AVFCHDBS
|
||||||
|
AWFCHDB
|
||||||
|
AWFCHDBS
|
||||||
|
AVFCHE
|
||||||
|
AVFCHEDB
|
||||||
|
AVFCHEDBS
|
||||||
|
AWFCHEDB
|
||||||
|
AWFCHEDBS
|
||||||
|
AWFC
|
||||||
|
AWFCDB
|
||||||
|
AVCDG
|
||||||
|
AVCDGB
|
||||||
|
AWCDGB
|
||||||
|
AVCDLG
|
||||||
|
AVCDLGB
|
||||||
|
AWCDLGB
|
||||||
|
AVCGD
|
||||||
|
AVCGDB
|
||||||
|
AWCGDB
|
||||||
|
AVCLGD
|
||||||
|
AVCLGDB
|
||||||
|
AWCLGDB
|
||||||
|
AVFD
|
||||||
|
AVFDDB
|
||||||
|
AWFDDB
|
||||||
|
AVLDE
|
||||||
|
AVLDEB
|
||||||
|
AWLDEB
|
||||||
|
AVLED
|
||||||
|
AVLEDB
|
||||||
|
AWLEDB
|
||||||
|
AVFM
|
||||||
|
AVFMDB
|
||||||
|
AWFMDB
|
||||||
|
AVFMA
|
||||||
|
AVFMADB
|
||||||
|
AWFMADB
|
||||||
|
AVFMS
|
||||||
|
AVFMSDB
|
||||||
|
AWFMSDB
|
||||||
|
AVFPSO
|
||||||
|
AVFPSODB
|
||||||
|
AWFPSODB
|
||||||
|
AVFLCDB
|
||||||
|
AWFLCDB
|
||||||
|
AVFLNDB
|
||||||
|
AWFLNDB
|
||||||
|
AVFLPDB
|
||||||
|
AWFLPDB
|
||||||
|
AVFSQ
|
||||||
|
AVFSQDB
|
||||||
|
AWFSQDB
|
||||||
|
AVFS
|
||||||
|
AVFSDB
|
||||||
|
AWFSDB
|
||||||
|
AVFTCI
|
||||||
|
AVFTCIDB
|
||||||
|
AWFTCIDB
|
||||||
|
AVGFM
|
||||||
|
AVGFMB
|
||||||
|
AVGFMH
|
||||||
|
AVGFMF
|
||||||
|
AVGFMG
|
||||||
|
AVGFMA
|
||||||
|
AVGFMAB
|
||||||
|
AVGFMAH
|
||||||
|
AVGFMAF
|
||||||
|
AVGFMAG
|
||||||
|
AVGEF
|
||||||
|
AVGEG
|
||||||
|
AVGBM
|
||||||
|
AVZERO
|
||||||
|
AVONE
|
||||||
|
AVGM
|
||||||
|
AVGMB
|
||||||
|
AVGMH
|
||||||
|
AVGMF
|
||||||
|
AVGMG
|
||||||
|
AVISTR
|
||||||
|
AVISTRB
|
||||||
|
AVISTRH
|
||||||
|
AVISTRF
|
||||||
|
AVISTRBS
|
||||||
|
AVISTRHS
|
||||||
|
AVISTRFS
|
||||||
|
AVL
|
||||||
|
AVLR
|
||||||
|
AVLREP
|
||||||
|
AVLREPB
|
||||||
|
AVLREPH
|
||||||
|
AVLREPF
|
||||||
|
AVLREPG
|
||||||
|
AVLC
|
||||||
|
AVLCB
|
||||||
|
AVLCH
|
||||||
|
AVLCF
|
||||||
|
AVLCG
|
||||||
|
AVLEH
|
||||||
|
AVLEF
|
||||||
|
AVLEG
|
||||||
|
AVLEB
|
||||||
|
AVLEIH
|
||||||
|
AVLEIF
|
||||||
|
AVLEIG
|
||||||
|
AVLEIB
|
||||||
|
AVFI
|
||||||
|
AVFIDB
|
||||||
|
AWFIDB
|
||||||
|
AVLGV
|
||||||
|
AVLGVB
|
||||||
|
AVLGVH
|
||||||
|
AVLGVF
|
||||||
|
AVLGVG
|
||||||
|
AVLLEZ
|
||||||
|
AVLLEZB
|
||||||
|
AVLLEZH
|
||||||
|
AVLLEZF
|
||||||
|
AVLLEZG
|
||||||
|
AVLM
|
||||||
|
AVLP
|
||||||
|
AVLPB
|
||||||
|
AVLPH
|
||||||
|
AVLPF
|
||||||
|
AVLPG
|
||||||
|
AVLBB
|
||||||
|
AVLVG
|
||||||
|
AVLVGB
|
||||||
|
AVLVGH
|
||||||
|
AVLVGF
|
||||||
|
AVLVGG
|
||||||
|
AVLVGP
|
||||||
|
AVLL
|
||||||
|
AVMX
|
||||||
|
AVMXB
|
||||||
|
AVMXH
|
||||||
|
AVMXF
|
||||||
|
AVMXG
|
||||||
|
AVMXL
|
||||||
|
AVMXLB
|
||||||
|
AVMXLH
|
||||||
|
AVMXLF
|
||||||
|
AVMXLG
|
||||||
|
AVMRH
|
||||||
|
AVMRHB
|
||||||
|
AVMRHH
|
||||||
|
AVMRHF
|
||||||
|
AVMRHG
|
||||||
|
AVMRL
|
||||||
|
AVMRLB
|
||||||
|
AVMRLH
|
||||||
|
AVMRLF
|
||||||
|
AVMRLG
|
||||||
|
AVMN
|
||||||
|
AVMNB
|
||||||
|
AVMNH
|
||||||
|
AVMNF
|
||||||
|
AVMNG
|
||||||
|
AVMNL
|
||||||
|
AVMNLB
|
||||||
|
AVMNLH
|
||||||
|
AVMNLF
|
||||||
|
AVMNLG
|
||||||
|
AVMAE
|
||||||
|
AVMAEB
|
||||||
|
AVMAEH
|
||||||
|
AVMAEF
|
||||||
|
AVMAH
|
||||||
|
AVMAHB
|
||||||
|
AVMAHH
|
||||||
|
AVMAHF
|
||||||
|
AVMALE
|
||||||
|
AVMALEB
|
||||||
|
AVMALEH
|
||||||
|
AVMALEF
|
||||||
|
AVMALH
|
||||||
|
AVMALHB
|
||||||
|
AVMALHH
|
||||||
|
AVMALHF
|
||||||
|
AVMALO
|
||||||
|
AVMALOB
|
||||||
|
AVMALOH
|
||||||
|
AVMALOF
|
||||||
|
AVMAL
|
||||||
|
AVMALB
|
||||||
|
AVMALHW
|
||||||
|
AVMALF
|
||||||
|
AVMAO
|
||||||
|
AVMAOB
|
||||||
|
AVMAOH
|
||||||
|
AVMAOF
|
||||||
|
AVME
|
||||||
|
AVMEB
|
||||||
|
AVMEH
|
||||||
|
AVMEF
|
||||||
|
AVMH
|
||||||
|
AVMHB
|
||||||
|
AVMHH
|
||||||
|
AVMHF
|
||||||
|
AVMLE
|
||||||
|
AVMLEB
|
||||||
|
AVMLEH
|
||||||
|
AVMLEF
|
||||||
|
AVMLH
|
||||||
|
AVMLHB
|
||||||
|
AVMLHH
|
||||||
|
AVMLHF
|
||||||
|
AVMLO
|
||||||
|
AVMLOB
|
||||||
|
AVMLOH
|
||||||
|
AVMLOF
|
||||||
|
AVML
|
||||||
|
AVMLB
|
||||||
|
AVMLHW
|
||||||
|
AVMLF
|
||||||
|
AVMO
|
||||||
|
AVMOB
|
||||||
|
AVMOH
|
||||||
|
AVMOF
|
||||||
|
AVNO
|
||||||
|
AVNOT
|
||||||
|
AVO
|
||||||
|
AVPK
|
||||||
|
AVPKH
|
||||||
|
AVPKF
|
||||||
|
AVPKG
|
||||||
|
AVPKLS
|
||||||
|
AVPKLSH
|
||||||
|
AVPKLSF
|
||||||
|
AVPKLSG
|
||||||
|
AVPKLSHS
|
||||||
|
AVPKLSFS
|
||||||
|
AVPKLSGS
|
||||||
|
AVPKS
|
||||||
|
AVPKSH
|
||||||
|
AVPKSF
|
||||||
|
AVPKSG
|
||||||
|
AVPKSHS
|
||||||
|
AVPKSFS
|
||||||
|
AVPKSGS
|
||||||
|
AVPERM
|
||||||
|
AVPDI
|
||||||
|
AVPOPCT
|
||||||
|
AVREP
|
||||||
|
AVREPB
|
||||||
|
AVREPH
|
||||||
|
AVREPF
|
||||||
|
AVREPG
|
||||||
|
AVREPI
|
||||||
|
AVREPIB
|
||||||
|
AVREPIH
|
||||||
|
AVREPIF
|
||||||
|
AVREPIG
|
||||||
|
AVSCEF
|
||||||
|
AVSCEG
|
||||||
|
AVSEL
|
||||||
|
AVSL
|
||||||
|
AVSLB
|
||||||
|
AVSLDB
|
||||||
|
AVSRA
|
||||||
|
AVSRAB
|
||||||
|
AVSRL
|
||||||
|
AVSRLB
|
||||||
|
AVSEG
|
||||||
|
AVSEGB
|
||||||
|
AVSEGH
|
||||||
|
AVSEGF
|
||||||
|
AVST
|
||||||
|
AVSTEH
|
||||||
|
AVSTEF
|
||||||
|
AVSTEG
|
||||||
|
AVSTEB
|
||||||
|
AVSTM
|
||||||
|
AVSTL
|
||||||
|
AVSTRC
|
||||||
|
AVSTRCB
|
||||||
|
AVSTRCH
|
||||||
|
AVSTRCF
|
||||||
|
AVSTRCBS
|
||||||
|
AVSTRCHS
|
||||||
|
AVSTRCFS
|
||||||
|
AVSTRCZB
|
||||||
|
AVSTRCZH
|
||||||
|
AVSTRCZF
|
||||||
|
AVSTRCZBS
|
||||||
|
AVSTRCZHS
|
||||||
|
AVSTRCZFS
|
||||||
|
AVS
|
||||||
|
AVSB
|
||||||
|
AVSH
|
||||||
|
AVSF
|
||||||
|
AVSG
|
||||||
|
AVSQ
|
||||||
|
AVSCBI
|
||||||
|
AVSCBIB
|
||||||
|
AVSCBIH
|
||||||
|
AVSCBIF
|
||||||
|
AVSCBIG
|
||||||
|
AVSCBIQ
|
||||||
|
AVSBCBI
|
||||||
|
AVSBCBIQ
|
||||||
|
AVSBI
|
||||||
|
AVSBIQ
|
||||||
|
AVSUMG
|
||||||
|
AVSUMGH
|
||||||
|
AVSUMGF
|
||||||
|
AVSUMQ
|
||||||
|
AVSUMQF
|
||||||
|
AVSUMQG
|
||||||
|
AVSUM
|
||||||
|
AVSUMB
|
||||||
|
AVSUMH
|
||||||
|
AVTM
|
||||||
|
AVUPH
|
||||||
|
AVUPHB
|
||||||
|
AVUPHH
|
||||||
|
AVUPHF
|
||||||
|
AVUPLH
|
||||||
|
AVUPLHB
|
||||||
|
AVUPLHH
|
||||||
|
AVUPLHF
|
||||||
|
AVUPLL
|
||||||
|
AVUPLLB
|
||||||
|
AVUPLLH
|
||||||
|
AVUPLLF
|
||||||
|
AVUPL
|
||||||
|
AVUPLB
|
||||||
|
AVUPLHW
|
||||||
|
AVUPLF
|
||||||
|
|
||||||
|
// binary
|
||||||
|
ABYTE
|
||||||
|
AWORD
|
||||||
|
ADWORD
|
||||||
|
|
||||||
|
// end marker
|
||||||
|
ALAST
|
||||||
|
|
||||||
|
// aliases
|
||||||
|
ABR = obj.AJMP
|
||||||
|
ABL = obj.ACALL
|
||||||
|
)
|
675
vendor/github.com/google/gops/internal/obj/s390x/anames.go
generated
vendored
Normal file
675
vendor/github.com/google/gops/internal/obj/s390x/anames.go
generated
vendored
Normal file
@ -0,0 +1,675 @@
|
|||||||
|
// Generated by stringer -i a.out.go -o anames.go -p s390x
|
||||||
|
// Do not edit.
|
||||||
|
|
||||||
|
package s390x
|
||||||
|
|
||||||
|
import "github.com/google/gops/internal/obj"
|
||||||
|
|
||||||
|
var Anames = []string{
|
||||||
|
obj.A_ARCHSPECIFIC: "ADD",
|
||||||
|
"ADDC",
|
||||||
|
"ADDE",
|
||||||
|
"ADDW",
|
||||||
|
"DIVW",
|
||||||
|
"DIVWU",
|
||||||
|
"DIVD",
|
||||||
|
"DIVDU",
|
||||||
|
"MODW",
|
||||||
|
"MODWU",
|
||||||
|
"MODD",
|
||||||
|
"MODDU",
|
||||||
|
"MULLW",
|
||||||
|
"MULLD",
|
||||||
|
"MULHD",
|
||||||
|
"MULHDU",
|
||||||
|
"SUB",
|
||||||
|
"SUBC",
|
||||||
|
"SUBV",
|
||||||
|
"SUBE",
|
||||||
|
"SUBW",
|
||||||
|
"NEG",
|
||||||
|
"NEGW",
|
||||||
|
"MOVWBR",
|
||||||
|
"MOVB",
|
||||||
|
"MOVBZ",
|
||||||
|
"MOVH",
|
||||||
|
"MOVHBR",
|
||||||
|
"MOVHZ",
|
||||||
|
"MOVW",
|
||||||
|
"MOVWZ",
|
||||||
|
"MOVD",
|
||||||
|
"MOVDBR",
|
||||||
|
"MOVDEQ",
|
||||||
|
"MOVDGE",
|
||||||
|
"MOVDGT",
|
||||||
|
"MOVDLE",
|
||||||
|
"MOVDLT",
|
||||||
|
"MOVDNE",
|
||||||
|
"FLOGR",
|
||||||
|
"AND",
|
||||||
|
"ANDW",
|
||||||
|
"OR",
|
||||||
|
"ORW",
|
||||||
|
"XOR",
|
||||||
|
"XORW",
|
||||||
|
"SLW",
|
||||||
|
"SLD",
|
||||||
|
"SRW",
|
||||||
|
"SRAW",
|
||||||
|
"SRD",
|
||||||
|
"SRAD",
|
||||||
|
"RLL",
|
||||||
|
"RLLG",
|
||||||
|
"FABS",
|
||||||
|
"FADD",
|
||||||
|
"FADDS",
|
||||||
|
"FCMPO",
|
||||||
|
"FCMPU",
|
||||||
|
"CEBR",
|
||||||
|
"FDIV",
|
||||||
|
"FDIVS",
|
||||||
|
"FMADD",
|
||||||
|
"FMADDS",
|
||||||
|
"FMOVD",
|
||||||
|
"FMOVS",
|
||||||
|
"FMSUB",
|
||||||
|
"FMSUBS",
|
||||||
|
"FMUL",
|
||||||
|
"FMULS",
|
||||||
|
"FNABS",
|
||||||
|
"FNEG",
|
||||||
|
"FNEGS",
|
||||||
|
"FNMADD",
|
||||||
|
"FNMADDS",
|
||||||
|
"FNMSUB",
|
||||||
|
"FNMSUBS",
|
||||||
|
"LEDBR",
|
||||||
|
"LDEBR",
|
||||||
|
"FSUB",
|
||||||
|
"FSUBS",
|
||||||
|
"FSQRT",
|
||||||
|
"FSQRTS",
|
||||||
|
"FIEBR",
|
||||||
|
"FIDBR",
|
||||||
|
"CEFBRA",
|
||||||
|
"CDFBRA",
|
||||||
|
"CEGBRA",
|
||||||
|
"CDGBRA",
|
||||||
|
"CFEBRA",
|
||||||
|
"CFDBRA",
|
||||||
|
"CGEBRA",
|
||||||
|
"CGDBRA",
|
||||||
|
"CELFBR",
|
||||||
|
"CDLFBR",
|
||||||
|
"CELGBR",
|
||||||
|
"CDLGBR",
|
||||||
|
"CLFEBR",
|
||||||
|
"CLFDBR",
|
||||||
|
"CLGEBR",
|
||||||
|
"CLGDBR",
|
||||||
|
"CMP",
|
||||||
|
"CMPU",
|
||||||
|
"CMPW",
|
||||||
|
"CMPWU",
|
||||||
|
"CS",
|
||||||
|
"CSG",
|
||||||
|
"SYNC",
|
||||||
|
"BC",
|
||||||
|
"BCL",
|
||||||
|
"BEQ",
|
||||||
|
"BGE",
|
||||||
|
"BGT",
|
||||||
|
"BLE",
|
||||||
|
"BLT",
|
||||||
|
"BLEU",
|
||||||
|
"BLTU",
|
||||||
|
"BNE",
|
||||||
|
"BVC",
|
||||||
|
"BVS",
|
||||||
|
"SYSCALL",
|
||||||
|
"CMPBEQ",
|
||||||
|
"CMPBGE",
|
||||||
|
"CMPBGT",
|
||||||
|
"CMPBLE",
|
||||||
|
"CMPBLT",
|
||||||
|
"CMPBNE",
|
||||||
|
"CMPUBEQ",
|
||||||
|
"CMPUBGE",
|
||||||
|
"CMPUBGT",
|
||||||
|
"CMPUBLE",
|
||||||
|
"CMPUBLT",
|
||||||
|
"CMPUBNE",
|
||||||
|
"MVC",
|
||||||
|
"CLC",
|
||||||
|
"XC",
|
||||||
|
"OC",
|
||||||
|
"NC",
|
||||||
|
"EXRL",
|
||||||
|
"LARL",
|
||||||
|
"LA",
|
||||||
|
"LAY",
|
||||||
|
"LAA",
|
||||||
|
"LAAG",
|
||||||
|
"LAAL",
|
||||||
|
"LAALG",
|
||||||
|
"LAN",
|
||||||
|
"LANG",
|
||||||
|
"LAX",
|
||||||
|
"LAXG",
|
||||||
|
"LAO",
|
||||||
|
"LAOG",
|
||||||
|
"LMY",
|
||||||
|
"LMG",
|
||||||
|
"STMY",
|
||||||
|
"STMG",
|
||||||
|
"STCK",
|
||||||
|
"STCKC",
|
||||||
|
"STCKE",
|
||||||
|
"STCKF",
|
||||||
|
"CLEAR",
|
||||||
|
"VA",
|
||||||
|
"VAB",
|
||||||
|
"VAH",
|
||||||
|
"VAF",
|
||||||
|
"VAG",
|
||||||
|
"VAQ",
|
||||||
|
"VACC",
|
||||||
|
"VACCB",
|
||||||
|
"VACCH",
|
||||||
|
"VACCF",
|
||||||
|
"VACCG",
|
||||||
|
"VACCQ",
|
||||||
|
"VAC",
|
||||||
|
"VACQ",
|
||||||
|
"VACCC",
|
||||||
|
"VACCCQ",
|
||||||
|
"VN",
|
||||||
|
"VNC",
|
||||||
|
"VAVG",
|
||||||
|
"VAVGB",
|
||||||
|
"VAVGH",
|
||||||
|
"VAVGF",
|
||||||
|
"VAVGG",
|
||||||
|
"VAVGL",
|
||||||
|
"VAVGLB",
|
||||||
|
"VAVGLH",
|
||||||
|
"VAVGLF",
|
||||||
|
"VAVGLG",
|
||||||
|
"VCKSM",
|
||||||
|
"VCEQ",
|
||||||
|
"VCEQB",
|
||||||
|
"VCEQH",
|
||||||
|
"VCEQF",
|
||||||
|
"VCEQG",
|
||||||
|
"VCEQBS",
|
||||||
|
"VCEQHS",
|
||||||
|
"VCEQFS",
|
||||||
|
"VCEQGS",
|
||||||
|
"VCH",
|
||||||
|
"VCHB",
|
||||||
|
"VCHH",
|
||||||
|
"VCHF",
|
||||||
|
"VCHG",
|
||||||
|
"VCHBS",
|
||||||
|
"VCHHS",
|
||||||
|
"VCHFS",
|
||||||
|
"VCHGS",
|
||||||
|
"VCHL",
|
||||||
|
"VCHLB",
|
||||||
|
"VCHLH",
|
||||||
|
"VCHLF",
|
||||||
|
"VCHLG",
|
||||||
|
"VCHLBS",
|
||||||
|
"VCHLHS",
|
||||||
|
"VCHLFS",
|
||||||
|
"VCHLGS",
|
||||||
|
"VCLZ",
|
||||||
|
"VCLZB",
|
||||||
|
"VCLZH",
|
||||||
|
"VCLZF",
|
||||||
|
"VCLZG",
|
||||||
|
"VCTZ",
|
||||||
|
"VCTZB",
|
||||||
|
"VCTZH",
|
||||||
|
"VCTZF",
|
||||||
|
"VCTZG",
|
||||||
|
"VEC",
|
||||||
|
"VECB",
|
||||||
|
"VECH",
|
||||||
|
"VECF",
|
||||||
|
"VECG",
|
||||||
|
"VECL",
|
||||||
|
"VECLB",
|
||||||
|
"VECLH",
|
||||||
|
"VECLF",
|
||||||
|
"VECLG",
|
||||||
|
"VERIM",
|
||||||
|
"VERIMB",
|
||||||
|
"VERIMH",
|
||||||
|
"VERIMF",
|
||||||
|
"VERIMG",
|
||||||
|
"VERLL",
|
||||||
|
"VERLLB",
|
||||||
|
"VERLLH",
|
||||||
|
"VERLLF",
|
||||||
|
"VERLLG",
|
||||||
|
"VERLLV",
|
||||||
|
"VERLLVB",
|
||||||
|
"VERLLVH",
|
||||||
|
"VERLLVF",
|
||||||
|
"VERLLVG",
|
||||||
|
"VESLV",
|
||||||
|
"VESLVB",
|
||||||
|
"VESLVH",
|
||||||
|
"VESLVF",
|
||||||
|
"VESLVG",
|
||||||
|
"VESL",
|
||||||
|
"VESLB",
|
||||||
|
"VESLH",
|
||||||
|
"VESLF",
|
||||||
|
"VESLG",
|
||||||
|
"VESRA",
|
||||||
|
"VESRAB",
|
||||||
|
"VESRAH",
|
||||||
|
"VESRAF",
|
||||||
|
"VESRAG",
|
||||||
|
"VESRAV",
|
||||||
|
"VESRAVB",
|
||||||
|
"VESRAVH",
|
||||||
|
"VESRAVF",
|
||||||
|
"VESRAVG",
|
||||||
|
"VESRL",
|
||||||
|
"VESRLB",
|
||||||
|
"VESRLH",
|
||||||
|
"VESRLF",
|
||||||
|
"VESRLG",
|
||||||
|
"VESRLV",
|
||||||
|
"VESRLVB",
|
||||||
|
"VESRLVH",
|
||||||
|
"VESRLVF",
|
||||||
|
"VESRLVG",
|
||||||
|
"VX",
|
||||||
|
"VFAE",
|
||||||
|
"VFAEB",
|
||||||
|
"VFAEH",
|
||||||
|
"VFAEF",
|
||||||
|
"VFAEBS",
|
||||||
|
"VFAEHS",
|
||||||
|
"VFAEFS",
|
||||||
|
"VFAEZB",
|
||||||
|
"VFAEZH",
|
||||||
|
"VFAEZF",
|
||||||
|
"VFAEZBS",
|
||||||
|
"VFAEZHS",
|
||||||
|
"VFAEZFS",
|
||||||
|
"VFEE",
|
||||||
|
"VFEEB",
|
||||||
|
"VFEEH",
|
||||||
|
"VFEEF",
|
||||||
|
"VFEEBS",
|
||||||
|
"VFEEHS",
|
||||||
|
"VFEEFS",
|
||||||
|
"VFEEZB",
|
||||||
|
"VFEEZH",
|
||||||
|
"VFEEZF",
|
||||||
|
"VFEEZBS",
|
||||||
|
"VFEEZHS",
|
||||||
|
"VFEEZFS",
|
||||||
|
"VFENE",
|
||||||
|
"VFENEB",
|
||||||
|
"VFENEH",
|
||||||
|
"VFENEF",
|
||||||
|
"VFENEBS",
|
||||||
|
"VFENEHS",
|
||||||
|
"VFENEFS",
|
||||||
|
"VFENEZB",
|
||||||
|
"VFENEZH",
|
||||||
|
"VFENEZF",
|
||||||
|
"VFENEZBS",
|
||||||
|
"VFENEZHS",
|
||||||
|
"VFENEZFS",
|
||||||
|
"VFA",
|
||||||
|
"VFADB",
|
||||||
|
"WFADB",
|
||||||
|
"WFK",
|
||||||
|
"WFKDB",
|
||||||
|
"VFCE",
|
||||||
|
"VFCEDB",
|
||||||
|
"VFCEDBS",
|
||||||
|
"WFCEDB",
|
||||||
|
"WFCEDBS",
|
||||||
|
"VFCH",
|
||||||
|
"VFCHDB",
|
||||||
|
"VFCHDBS",
|
||||||
|
"WFCHDB",
|
||||||
|
"WFCHDBS",
|
||||||
|
"VFCHE",
|
||||||
|
"VFCHEDB",
|
||||||
|
"VFCHEDBS",
|
||||||
|
"WFCHEDB",
|
||||||
|
"WFCHEDBS",
|
||||||
|
"WFC",
|
||||||
|
"WFCDB",
|
||||||
|
"VCDG",
|
||||||
|
"VCDGB",
|
||||||
|
"WCDGB",
|
||||||
|
"VCDLG",
|
||||||
|
"VCDLGB",
|
||||||
|
"WCDLGB",
|
||||||
|
"VCGD",
|
||||||
|
"VCGDB",
|
||||||
|
"WCGDB",
|
||||||
|
"VCLGD",
|
||||||
|
"VCLGDB",
|
||||||
|
"WCLGDB",
|
||||||
|
"VFD",
|
||||||
|
"VFDDB",
|
||||||
|
"WFDDB",
|
||||||
|
"VLDE",
|
||||||
|
"VLDEB",
|
||||||
|
"WLDEB",
|
||||||
|
"VLED",
|
||||||
|
"VLEDB",
|
||||||
|
"WLEDB",
|
||||||
|
"VFM",
|
||||||
|
"VFMDB",
|
||||||
|
"WFMDB",
|
||||||
|
"VFMA",
|
||||||
|
"VFMADB",
|
||||||
|
"WFMADB",
|
||||||
|
"VFMS",
|
||||||
|
"VFMSDB",
|
||||||
|
"WFMSDB",
|
||||||
|
"VFPSO",
|
||||||
|
"VFPSODB",
|
||||||
|
"WFPSODB",
|
||||||
|
"VFLCDB",
|
||||||
|
"WFLCDB",
|
||||||
|
"VFLNDB",
|
||||||
|
"WFLNDB",
|
||||||
|
"VFLPDB",
|
||||||
|
"WFLPDB",
|
||||||
|
"VFSQ",
|
||||||
|
"VFSQDB",
|
||||||
|
"WFSQDB",
|
||||||
|
"VFS",
|
||||||
|
"VFSDB",
|
||||||
|
"WFSDB",
|
||||||
|
"VFTCI",
|
||||||
|
"VFTCIDB",
|
||||||
|
"WFTCIDB",
|
||||||
|
"VGFM",
|
||||||
|
"VGFMB",
|
||||||
|
"VGFMH",
|
||||||
|
"VGFMF",
|
||||||
|
"VGFMG",
|
||||||
|
"VGFMA",
|
||||||
|
"VGFMAB",
|
||||||
|
"VGFMAH",
|
||||||
|
"VGFMAF",
|
||||||
|
"VGFMAG",
|
||||||
|
"VGEF",
|
||||||
|
"VGEG",
|
||||||
|
"VGBM",
|
||||||
|
"VZERO",
|
||||||
|
"VONE",
|
||||||
|
"VGM",
|
||||||
|
"VGMB",
|
||||||
|
"VGMH",
|
||||||
|
"VGMF",
|
||||||
|
"VGMG",
|
||||||
|
"VISTR",
|
||||||
|
"VISTRB",
|
||||||
|
"VISTRH",
|
||||||
|
"VISTRF",
|
||||||
|
"VISTRBS",
|
||||||
|
"VISTRHS",
|
||||||
|
"VISTRFS",
|
||||||
|
"VL",
|
||||||
|
"VLR",
|
||||||
|
"VLREP",
|
||||||
|
"VLREPB",
|
||||||
|
"VLREPH",
|
||||||
|
"VLREPF",
|
||||||
|
"VLREPG",
|
||||||
|
"VLC",
|
||||||
|
"VLCB",
|
||||||
|
"VLCH",
|
||||||
|
"VLCF",
|
||||||
|
"VLCG",
|
||||||
|
"VLEH",
|
||||||
|
"VLEF",
|
||||||
|
"VLEG",
|
||||||
|
"VLEB",
|
||||||
|
"VLEIH",
|
||||||
|
"VLEIF",
|
||||||
|
"VLEIG",
|
||||||
|
"VLEIB",
|
||||||
|
"VFI",
|
||||||
|
"VFIDB",
|
||||||
|
"WFIDB",
|
||||||
|
"VLGV",
|
||||||
|
"VLGVB",
|
||||||
|
"VLGVH",
|
||||||
|
"VLGVF",
|
||||||
|
"VLGVG",
|
||||||
|
"VLLEZ",
|
||||||
|
"VLLEZB",
|
||||||
|
"VLLEZH",
|
||||||
|
"VLLEZF",
|
||||||
|
"VLLEZG",
|
||||||
|
"VLM",
|
||||||
|
"VLP",
|
||||||
|
"VLPB",
|
||||||
|
"VLPH",
|
||||||
|
"VLPF",
|
||||||
|
"VLPG",
|
||||||
|
"VLBB",
|
||||||
|
"VLVG",
|
||||||
|
"VLVGB",
|
||||||
|
"VLVGH",
|
||||||
|
"VLVGF",
|
||||||
|
"VLVGG",
|
||||||
|
"VLVGP",
|
||||||
|
"VLL",
|
||||||
|
"VMX",
|
||||||
|
"VMXB",
|
||||||
|
"VMXH",
|
||||||
|
"VMXF",
|
||||||
|
"VMXG",
|
||||||
|
"VMXL",
|
||||||
|
"VMXLB",
|
||||||
|
"VMXLH",
|
||||||
|
"VMXLF",
|
||||||
|
"VMXLG",
|
||||||
|
"VMRH",
|
||||||
|
"VMRHB",
|
||||||
|
"VMRHH",
|
||||||
|
"VMRHF",
|
||||||
|
"VMRHG",
|
||||||
|
"VMRL",
|
||||||
|
"VMRLB",
|
||||||
|
"VMRLH",
|
||||||
|
"VMRLF",
|
||||||
|
"VMRLG",
|
||||||
|
"VMN",
|
||||||
|
"VMNB",
|
||||||
|
"VMNH",
|
||||||
|
"VMNF",
|
||||||
|
"VMNG",
|
||||||
|
"VMNL",
|
||||||
|
"VMNLB",
|
||||||
|
"VMNLH",
|
||||||
|
"VMNLF",
|
||||||
|
"VMNLG",
|
||||||
|
"VMAE",
|
||||||
|
"VMAEB",
|
||||||
|
"VMAEH",
|
||||||
|
"VMAEF",
|
||||||
|
"VMAH",
|
||||||
|
"VMAHB",
|
||||||
|
"VMAHH",
|
||||||
|
"VMAHF",
|
||||||
|
"VMALE",
|
||||||
|
"VMALEB",
|
||||||
|
"VMALEH",
|
||||||
|
"VMALEF",
|
||||||
|
"VMALH",
|
||||||
|
"VMALHB",
|
||||||
|
"VMALHH",
|
||||||
|
"VMALHF",
|
||||||
|
"VMALO",
|
||||||
|
"VMALOB",
|
||||||
|
"VMALOH",
|
||||||
|
"VMALOF",
|
||||||
|
"VMAL",
|
||||||
|
"VMALB",
|
||||||
|
"VMALHW",
|
||||||
|
"VMALF",
|
||||||
|
"VMAO",
|
||||||
|
"VMAOB",
|
||||||
|
"VMAOH",
|
||||||
|
"VMAOF",
|
||||||
|
"VME",
|
||||||
|
"VMEB",
|
||||||
|
"VMEH",
|
||||||
|
"VMEF",
|
||||||
|
"VMH",
|
||||||
|
"VMHB",
|
||||||
|
"VMHH",
|
||||||
|
"VMHF",
|
||||||
|
"VMLE",
|
||||||
|
"VMLEB",
|
||||||
|
"VMLEH",
|
||||||
|
"VMLEF",
|
||||||
|
"VMLH",
|
||||||
|
"VMLHB",
|
||||||
|
"VMLHH",
|
||||||
|
"VMLHF",
|
||||||
|
"VMLO",
|
||||||
|
"VMLOB",
|
||||||
|
"VMLOH",
|
||||||
|
"VMLOF",
|
||||||
|
"VML",
|
||||||
|
"VMLB",
|
||||||
|
"VMLHW",
|
||||||
|
"VMLF",
|
||||||
|
"VMO",
|
||||||
|
"VMOB",
|
||||||
|
"VMOH",
|
||||||
|
"VMOF",
|
||||||
|
"VNO",
|
||||||
|
"VNOT",
|
||||||
|
"VO",
|
||||||
|
"VPK",
|
||||||
|
"VPKH",
|
||||||
|
"VPKF",
|
||||||
|
"VPKG",
|
||||||
|
"VPKLS",
|
||||||
|
"VPKLSH",
|
||||||
|
"VPKLSF",
|
||||||
|
"VPKLSG",
|
||||||
|
"VPKLSHS",
|
||||||
|
"VPKLSFS",
|
||||||
|
"VPKLSGS",
|
||||||
|
"VPKS",
|
||||||
|
"VPKSH",
|
||||||
|
"VPKSF",
|
||||||
|
"VPKSG",
|
||||||
|
"VPKSHS",
|
||||||
|
"VPKSFS",
|
||||||
|
"VPKSGS",
|
||||||
|
"VPERM",
|
||||||
|
"VPDI",
|
||||||
|
"VPOPCT",
|
||||||
|
"VREP",
|
||||||
|
"VREPB",
|
||||||
|
"VREPH",
|
||||||
|
"VREPF",
|
||||||
|
"VREPG",
|
||||||
|
"VREPI",
|
||||||
|
"VREPIB",
|
||||||
|
"VREPIH",
|
||||||
|
"VREPIF",
|
||||||
|
"VREPIG",
|
||||||
|
"VSCEF",
|
||||||
|
"VSCEG",
|
||||||
|
"VSEL",
|
||||||
|
"VSL",
|
||||||
|
"VSLB",
|
||||||
|
"VSLDB",
|
||||||
|
"VSRA",
|
||||||
|
"VSRAB",
|
||||||
|
"VSRL",
|
||||||
|
"VSRLB",
|
||||||
|
"VSEG",
|
||||||
|
"VSEGB",
|
||||||
|
"VSEGH",
|
||||||
|
"VSEGF",
|
||||||
|
"VST",
|
||||||
|
"VSTEH",
|
||||||
|
"VSTEF",
|
||||||
|
"VSTEG",
|
||||||
|
"VSTEB",
|
||||||
|
"VSTM",
|
||||||
|
"VSTL",
|
||||||
|
"VSTRC",
|
||||||
|
"VSTRCB",
|
||||||
|
"VSTRCH",
|
||||||
|
"VSTRCF",
|
||||||
|
"VSTRCBS",
|
||||||
|
"VSTRCHS",
|
||||||
|
"VSTRCFS",
|
||||||
|
"VSTRCZB",
|
||||||
|
"VSTRCZH",
|
||||||
|
"VSTRCZF",
|
||||||
|
"VSTRCZBS",
|
||||||
|
"VSTRCZHS",
|
||||||
|
"VSTRCZFS",
|
||||||
|
"VS",
|
||||||
|
"VSB",
|
||||||
|
"VSH",
|
||||||
|
"VSF",
|
||||||
|
"VSG",
|
||||||
|
"VSQ",
|
||||||
|
"VSCBI",
|
||||||
|
"VSCBIB",
|
||||||
|
"VSCBIH",
|
||||||
|
"VSCBIF",
|
||||||
|
"VSCBIG",
|
||||||
|
"VSCBIQ",
|
||||||
|
"VSBCBI",
|
||||||
|
"VSBCBIQ",
|
||||||
|
"VSBI",
|
||||||
|
"VSBIQ",
|
||||||
|
"VSUMG",
|
||||||
|
"VSUMGH",
|
||||||
|
"VSUMGF",
|
||||||
|
"VSUMQ",
|
||||||
|
"VSUMQF",
|
||||||
|
"VSUMQG",
|
||||||
|
"VSUM",
|
||||||
|
"VSUMB",
|
||||||
|
"VSUMH",
|
||||||
|
"VTM",
|
||||||
|
"VUPH",
|
||||||
|
"VUPHB",
|
||||||
|
"VUPHH",
|
||||||
|
"VUPHF",
|
||||||
|
"VUPLH",
|
||||||
|
"VUPLHB",
|
||||||
|
"VUPLHH",
|
||||||
|
"VUPLHF",
|
||||||
|
"VUPLL",
|
||||||
|
"VUPLLB",
|
||||||
|
"VUPLLH",
|
||||||
|
"VUPLLF",
|
||||||
|
"VUPL",
|
||||||
|
"VUPLB",
|
||||||
|
"VUPLHW",
|
||||||
|
"VUPLF",
|
||||||
|
"BYTE",
|
||||||
|
"WORD",
|
||||||
|
"DWORD",
|
||||||
|
"LAST",
|
||||||
|
}
|
39
vendor/github.com/google/gops/internal/obj/s390x/anamesz.go
generated
vendored
Normal file
39
vendor/github.com/google/gops/internal/obj/s390x/anamesz.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package s390x
|
||||||
|
|
||||||
|
var cnamesz = []string{
|
||||||
|
"NONE",
|
||||||
|
"REG",
|
||||||
|
"FREG",
|
||||||
|
"VREG",
|
||||||
|
"AREG",
|
||||||
|
"ZCON",
|
||||||
|
"SCON",
|
||||||
|
"UCON",
|
||||||
|
"ADDCON",
|
||||||
|
"ANDCON",
|
||||||
|
"LCON",
|
||||||
|
"DCON",
|
||||||
|
"SACON",
|
||||||
|
"LACON",
|
||||||
|
"DACON",
|
||||||
|
"SBRA",
|
||||||
|
"LBRA",
|
||||||
|
"SAUTO",
|
||||||
|
"LAUTO",
|
||||||
|
"ZOREG",
|
||||||
|
"SOREG",
|
||||||
|
"LOREG",
|
||||||
|
"TLS_LE",
|
||||||
|
"TLS_IE",
|
||||||
|
"GOK",
|
||||||
|
"ADDR",
|
||||||
|
"SYMADDR",
|
||||||
|
"GOTADDR",
|
||||||
|
"TEXTSIZE",
|
||||||
|
"ANY",
|
||||||
|
"NCLASS",
|
||||||
|
}
|
4766
vendor/github.com/google/gops/internal/obj/s390x/asmz.go
generated
vendored
Normal file
4766
vendor/github.com/google/gops/internal/obj/s390x/asmz.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
74
vendor/github.com/google/gops/internal/obj/s390x/listz.go
generated
vendored
Normal file
74
vendor/github.com/google/gops/internal/obj/s390x/listz.go
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// Based on cmd/internal/obj/ppc64/list9.go.
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package s390x
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gops/internal/obj"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
obj.RegisterRegister(obj.RBaseS390X, REG_R0+1024, Rconv)
|
||||||
|
obj.RegisterOpcode(obj.ABaseS390X, Anames)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Rconv(r int) string {
|
||||||
|
if r == 0 {
|
||||||
|
return "NONE"
|
||||||
|
}
|
||||||
|
if r == REGG {
|
||||||
|
// Special case.
|
||||||
|
return "g"
|
||||||
|
}
|
||||||
|
if REG_R0 <= r && r <= REG_R15 {
|
||||||
|
return fmt.Sprintf("R%d", r-REG_R0)
|
||||||
|
}
|
||||||
|
if REG_F0 <= r && r <= REG_F15 {
|
||||||
|
return fmt.Sprintf("F%d", r-REG_F0)
|
||||||
|
}
|
||||||
|
if REG_AR0 <= r && r <= REG_AR15 {
|
||||||
|
return fmt.Sprintf("AR%d", r-REG_AR0)
|
||||||
|
}
|
||||||
|
if REG_V0 <= r && r <= REG_V31 {
|
||||||
|
return fmt.Sprintf("V%d", r-REG_V0)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Rgok(%d)", r-obj.RBaseS390X)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DRconv(a int) string {
|
||||||
|
s := "C_??"
|
||||||
|
if a >= C_NONE && a <= C_NCLASS {
|
||||||
|
s = cnamesz[a]
|
||||||
|
}
|
||||||
|
var fp string
|
||||||
|
fp += s
|
||||||
|
return fp
|
||||||
|
}
|
1029
vendor/github.com/google/gops/internal/obj/s390x/objz.go
generated
vendored
Normal file
1029
vendor/github.com/google/gops/internal/obj/s390x/objz.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1061
vendor/github.com/google/gops/internal/obj/s390x/vector.go
generated
vendored
Normal file
1061
vendor/github.com/google/gops/internal/obj/s390x/vector.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
21
vendor/github.com/google/gops/internal/obj/stack.go
generated
vendored
Normal file
21
vendor/github.com/google/gops/internal/obj/stack.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
// For the linkers. Must match Go definitions.
|
||||||
|
// TODO(rsc): Share Go definitions with linkers directly.
|
||||||
|
|
||||||
|
const (
|
||||||
|
STACKSYSTEM = 0
|
||||||
|
StackSystem = STACKSYSTEM
|
||||||
|
StackBig = 4096
|
||||||
|
StackGuard = 880*stackGuardMultiplier + StackSystem
|
||||||
|
StackSmall = 128
|
||||||
|
StackLimit = StackGuard - StackSystem - StackSmall
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
StackPreempt = -1314 // 0xfff...fade
|
||||||
|
)
|
104
vendor/github.com/google/gops/internal/obj/stringer.go
generated
vendored
Normal file
104
vendor/github.com/google/gops/internal/obj/stringer.go
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
// This is a mini version of the stringer tool customized for the Anames table
|
||||||
|
// in the architecture support for obj.
|
||||||
|
// This version just generates the slice of strings, not the String method.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
input = flag.String("i", "", "input file name")
|
||||||
|
output = flag.String("o", "", "output file name")
|
||||||
|
pkg = flag.String("p", "", "package name")
|
||||||
|
)
|
||||||
|
|
||||||
|
var Are = regexp.MustCompile(`^\tA([A-Z0-9]+)`)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
if *input == "" || *output == "" || *pkg == "" {
|
||||||
|
flag.Usage()
|
||||||
|
os.Exit(2)
|
||||||
|
}
|
||||||
|
in, err := os.Open(*input)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fd, err := os.Create(*output)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
out := bufio.NewWriter(fd)
|
||||||
|
defer out.Flush()
|
||||||
|
var on = false
|
||||||
|
s := bufio.NewScanner(in)
|
||||||
|
first := true
|
||||||
|
for s.Scan() {
|
||||||
|
line := s.Text()
|
||||||
|
if !on {
|
||||||
|
// First relevant line contains "= obj.ABase".
|
||||||
|
// If we find it, delete the = so we don't stop immediately.
|
||||||
|
const prefix = "= obj.ABase"
|
||||||
|
index := strings.Index(line, prefix)
|
||||||
|
if index < 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// It's on. Start with the header.
|
||||||
|
fmt.Fprintf(out, header, *input, *output, *pkg, *pkg)
|
||||||
|
on = true
|
||||||
|
line = line[:index]
|
||||||
|
}
|
||||||
|
// Strip comments so their text won't defeat our heuristic.
|
||||||
|
index := strings.Index(line, "//")
|
||||||
|
if index > 0 {
|
||||||
|
line = line[:index]
|
||||||
|
}
|
||||||
|
index = strings.Index(line, "/*")
|
||||||
|
if index > 0 {
|
||||||
|
line = line[:index]
|
||||||
|
}
|
||||||
|
// Termination condition: Any line with an = changes the sequence,
|
||||||
|
// so stop there, and stop at a closing brace.
|
||||||
|
if strings.HasPrefix(line, "}") || strings.ContainsRune(line, '=') {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
sub := Are.FindStringSubmatch(line)
|
||||||
|
if len(sub) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if first {
|
||||||
|
fmt.Fprintf(out, "\tobj.A_ARCHSPECIFIC: %q,\n", sub[1])
|
||||||
|
first = false
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(out, "\t%q,\n", sub[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Fprintln(out, "}")
|
||||||
|
if s.Err() != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const header = `// Generated by stringer -i %s -o %s -p %s
|
||||||
|
// Do not edit.
|
||||||
|
|
||||||
|
package %s
|
||||||
|
|
||||||
|
import "github.com/google/gops/internal/obj"
|
||||||
|
|
||||||
|
var Anames = []string{
|
||||||
|
`
|
88
vendor/github.com/google/gops/internal/obj/sym.go
generated
vendored
Normal file
88
vendor/github.com/google/gops/internal/obj/sym.go
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
|
||||||
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c
|
||||||
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Linknew(arch *LinkArch) *Link {
|
||||||
|
ctxt := new(Link)
|
||||||
|
ctxt.Hash = make(map[SymVer]*LSym)
|
||||||
|
ctxt.Arch = arch
|
||||||
|
ctxt.Version = HistVersion
|
||||||
|
|
||||||
|
var buf string
|
||||||
|
buf, _ = os.Getwd()
|
||||||
|
if buf == "" {
|
||||||
|
buf = "/???"
|
||||||
|
}
|
||||||
|
buf = filepath.ToSlash(buf)
|
||||||
|
ctxt.Pathname = buf
|
||||||
|
|
||||||
|
ctxt.LineHist.GOROOT = GOROOT
|
||||||
|
ctxt.LineHist.Dir = ctxt.Pathname
|
||||||
|
|
||||||
|
ctxt.Headtype.Set(GOOS)
|
||||||
|
if ctxt.Headtype < 0 {
|
||||||
|
log.Fatalf("unknown goos %s", GOOS)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt.Flag_optimize = true
|
||||||
|
ctxt.Framepointer_enabled = Framepointer_enabled(GOOS, arch.Name)
|
||||||
|
return ctxt
|
||||||
|
}
|
||||||
|
|
||||||
|
func Linklookup(ctxt *Link, name string, v int) *LSym {
|
||||||
|
s := ctxt.Hash[SymVer{name, v}]
|
||||||
|
if s != nil {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
s = &LSym{
|
||||||
|
Name: name,
|
||||||
|
Type: 0,
|
||||||
|
Version: int16(v),
|
||||||
|
Size: 0,
|
||||||
|
}
|
||||||
|
ctxt.Hash[SymVer{name, v}] = s
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func Linksymfmt(s *LSym) string {
|
||||||
|
if s == nil {
|
||||||
|
return "<nil>"
|
||||||
|
}
|
||||||
|
return s.Name
|
||||||
|
}
|
16
vendor/github.com/google/gops/internal/obj/symkind_string.go
generated
vendored
Normal file
16
vendor/github.com/google/gops/internal/obj/symkind_string.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Code generated by "stringer -type=SymKind"; DO NOT EDIT
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const _SymKind_name = "SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASBSSSNOPTRBSSSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILESFILEPATHSCONSTSDYNIMPORTSHOSTOBJSDWARFSECTSDWARFINFO"
|
||||||
|
|
||||||
|
var _SymKind_index = [...]uint16{0, 4, 9, 19, 24, 31, 40, 47, 54, 61, 69, 79, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 214, 220, 229, 237, 244, 254, 262, 267, 271, 280, 287, 292, 304, 316, 333, 350, 355, 364, 370, 380, 388, 398, 408}
|
||||||
|
|
||||||
|
func (i SymKind) String() string {
|
||||||
|
if i < 0 || i >= SymKind(len(_SymKind_index)-1) {
|
||||||
|
return fmt.Sprintf("SymKind(%d)", i)
|
||||||
|
}
|
||||||
|
return _SymKind_name[_SymKind_index[i]:_SymKind_index[i+1]]
|
||||||
|
}
|
50
vendor/github.com/google/gops/internal/obj/textflag.go
generated
vendored
Normal file
50
vendor/github.com/google/gops/internal/obj/textflag.go
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// This file defines flags attached to various functions
|
||||||
|
// and data objects. The compilers, assemblers, and linker must
|
||||||
|
// all agree on these values.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Don't profile the marked routine.
|
||||||
|
//
|
||||||
|
// Deprecated: Not implemented, do not use.
|
||||||
|
NOPROF = 1
|
||||||
|
|
||||||
|
// It is ok for the linker to get multiple of these symbols. It will
|
||||||
|
// pick one of the duplicates to use.
|
||||||
|
DUPOK = 2
|
||||||
|
|
||||||
|
// Don't insert stack check preamble.
|
||||||
|
NOSPLIT = 4
|
||||||
|
|
||||||
|
// Put this data in a read-only section.
|
||||||
|
RODATA = 8
|
||||||
|
|
||||||
|
// This data contains no pointers.
|
||||||
|
NOPTR = 16
|
||||||
|
|
||||||
|
// This is a wrapper function and should not count as disabling 'recover'.
|
||||||
|
WRAPPER = 32
|
||||||
|
|
||||||
|
// This function uses its incoming context register.
|
||||||
|
NEEDCTXT = 64
|
||||||
|
|
||||||
|
// When passed to ggloblsym, causes Local to be set to true on the LSym it creates.
|
||||||
|
LOCAL = 128
|
||||||
|
|
||||||
|
// Allocate a word of thread local storage and store the offset from the
|
||||||
|
// thread local base to the thread local storage in this variable.
|
||||||
|
TLSBSS = 256
|
||||||
|
|
||||||
|
// Do not insert instructions to allocate a stack frame for this function.
|
||||||
|
// Only valid on functions that declare a frame size of 0.
|
||||||
|
// TODO(mwhudson): only implemented for ppc64x at present.
|
||||||
|
NOFRAME = 512
|
||||||
|
|
||||||
|
// Function can call reflect.Type.Method or reflect.Type.MethodByName.
|
||||||
|
REFLECTMETHOD = 1024
|
||||||
|
)
|
41
vendor/github.com/google/gops/internal/obj/typekind.go
generated
vendored
Normal file
41
vendor/github.com/google/gops/internal/obj/typekind.go
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
// Must match runtime and reflect.
|
||||||
|
// Included by cmd/gc.
|
||||||
|
|
||||||
|
const (
|
||||||
|
KindBool = 1 + iota
|
||||||
|
KindInt
|
||||||
|
KindInt8
|
||||||
|
KindInt16
|
||||||
|
KindInt32
|
||||||
|
KindInt64
|
||||||
|
KindUint
|
||||||
|
KindUint8
|
||||||
|
KindUint16
|
||||||
|
KindUint32
|
||||||
|
KindUint64
|
||||||
|
KindUintptr
|
||||||
|
KindFloat32
|
||||||
|
KindFloat64
|
||||||
|
KindComplex64
|
||||||
|
KindComplex128
|
||||||
|
KindArray
|
||||||
|
KindChan
|
||||||
|
KindFunc
|
||||||
|
KindInterface
|
||||||
|
KindMap
|
||||||
|
KindPtr
|
||||||
|
KindSlice
|
||||||
|
KindString
|
||||||
|
KindStruct
|
||||||
|
KindUnsafePointer
|
||||||
|
KindDirectIface = 1 << 5
|
||||||
|
KindGCProg = 1 << 6
|
||||||
|
KindNoPointers = 1 << 7
|
||||||
|
KindMask = (1 << 5) - 1
|
||||||
|
)
|
499
vendor/github.com/google/gops/internal/obj/util.go
generated
vendored
Normal file
499
vendor/github.com/google/gops/internal/obj/util.go
generated
vendored
Normal file
@ -0,0 +1,499 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const REG_NONE = 0
|
||||||
|
|
||||||
|
var start time.Time
|
||||||
|
|
||||||
|
func Cputime() float64 {
|
||||||
|
if start.IsZero() {
|
||||||
|
start = time.Now()
|
||||||
|
}
|
||||||
|
return time.Since(start).Seconds()
|
||||||
|
}
|
||||||
|
|
||||||
|
func envOr(key, value string) string {
|
||||||
|
if x := os.Getenv(key); x != "" {
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
GOROOT = envOr("GOROOT", defaultGOROOT)
|
||||||
|
GOARCH = envOr("GOARCH", defaultGOARCH)
|
||||||
|
GOOS = envOr("GOOS", defaultGOOS)
|
||||||
|
GO386 = envOr("GO386", defaultGO386)
|
||||||
|
GOARM = goarm()
|
||||||
|
Version = version
|
||||||
|
)
|
||||||
|
|
||||||
|
func goarm() int {
|
||||||
|
switch v := envOr("GOARM", defaultGOARM); v {
|
||||||
|
case "5":
|
||||||
|
return 5
|
||||||
|
case "6":
|
||||||
|
return 6
|
||||||
|
case "7":
|
||||||
|
return 7
|
||||||
|
}
|
||||||
|
// Fail here, rather than validate at multiple call sites.
|
||||||
|
log.Fatalf("Invalid GOARM value. Must be 5, 6, or 7.")
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func Getgoextlinkenabled() string {
|
||||||
|
return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Prog) Line() string {
|
||||||
|
return p.Ctxt.LineHist.LineString(int(p.Lineno))
|
||||||
|
}
|
||||||
|
|
||||||
|
var armCondCode = []string{
|
||||||
|
".EQ",
|
||||||
|
".NE",
|
||||||
|
".CS",
|
||||||
|
".CC",
|
||||||
|
".MI",
|
||||||
|
".PL",
|
||||||
|
".VS",
|
||||||
|
".VC",
|
||||||
|
".HI",
|
||||||
|
".LS",
|
||||||
|
".GE",
|
||||||
|
".LT",
|
||||||
|
".GT",
|
||||||
|
".LE",
|
||||||
|
"",
|
||||||
|
".NV",
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARM scond byte */
|
||||||
|
const (
|
||||||
|
C_SCOND = (1 << 4) - 1
|
||||||
|
C_SBIT = 1 << 4
|
||||||
|
C_PBIT = 1 << 5
|
||||||
|
C_WBIT = 1 << 6
|
||||||
|
C_FBIT = 1 << 7
|
||||||
|
C_UBIT = 1 << 7
|
||||||
|
C_SCOND_XOR = 14
|
||||||
|
)
|
||||||
|
|
||||||
|
// CConv formats ARM condition codes.
|
||||||
|
func CConv(s uint8) string {
|
||||||
|
if s == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
sc := armCondCode[(s&C_SCOND)^C_SCOND_XOR]
|
||||||
|
if s&C_SBIT != 0 {
|
||||||
|
sc += ".S"
|
||||||
|
}
|
||||||
|
if s&C_PBIT != 0 {
|
||||||
|
sc += ".P"
|
||||||
|
}
|
||||||
|
if s&C_WBIT != 0 {
|
||||||
|
sc += ".W"
|
||||||
|
}
|
||||||
|
if s&C_UBIT != 0 { /* ambiguous with FBIT */
|
||||||
|
sc += ".U"
|
||||||
|
}
|
||||||
|
return sc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Prog) String() string {
|
||||||
|
if p == nil {
|
||||||
|
return "<nil Prog>"
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Ctxt == nil {
|
||||||
|
return "<Prog without ctxt>"
|
||||||
|
}
|
||||||
|
|
||||||
|
sc := CConv(p.Scond)
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
fmt.Fprintf(&buf, "%.5d (%v)\t%v%s", p.Pc, p.Line(), p.As, sc)
|
||||||
|
sep := "\t"
|
||||||
|
quadOpAmd64 := p.RegTo2 == -1
|
||||||
|
if quadOpAmd64 {
|
||||||
|
fmt.Fprintf(&buf, "%s$%d", sep, p.From3.Offset)
|
||||||
|
sep = ", "
|
||||||
|
}
|
||||||
|
if p.From.Type != TYPE_NONE {
|
||||||
|
fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.From))
|
||||||
|
sep = ", "
|
||||||
|
}
|
||||||
|
if p.Reg != REG_NONE {
|
||||||
|
// Should not happen but might as well show it if it does.
|
||||||
|
fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.Reg)))
|
||||||
|
sep = ", "
|
||||||
|
}
|
||||||
|
if p.From3Type() != TYPE_NONE {
|
||||||
|
if p.From3.Type == TYPE_CONST && p.As == ATEXT {
|
||||||
|
// Special case - omit $.
|
||||||
|
fmt.Fprintf(&buf, "%s%d", sep, p.From3.Offset)
|
||||||
|
} else if quadOpAmd64 {
|
||||||
|
fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.From3.Reg)))
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, p.From3))
|
||||||
|
}
|
||||||
|
sep = ", "
|
||||||
|
}
|
||||||
|
if p.To.Type != TYPE_NONE {
|
||||||
|
fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.To))
|
||||||
|
}
|
||||||
|
if p.RegTo2 != REG_NONE && !quadOpAmd64 {
|
||||||
|
fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.RegTo2)))
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctxt *Link) NewProg() *Prog {
|
||||||
|
var p *Prog
|
||||||
|
if i := ctxt.allocIdx; i < len(ctxt.progs) {
|
||||||
|
p = &ctxt.progs[i]
|
||||||
|
ctxt.allocIdx = i + 1
|
||||||
|
} else {
|
||||||
|
p = new(Prog) // should be the only call to this; all others should use ctxt.NewProg
|
||||||
|
}
|
||||||
|
p.Ctxt = ctxt
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
func (ctxt *Link) freeProgs() {
|
||||||
|
s := ctxt.progs[:ctxt.allocIdx]
|
||||||
|
for i := range s {
|
||||||
|
s[i] = Prog{}
|
||||||
|
}
|
||||||
|
ctxt.allocIdx = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctxt *Link) Line(n int) string {
|
||||||
|
return ctxt.LineHist.LineString(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Getcallerpc(interface{}) uintptr {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctxt *Link) Dconv(a *Addr) string {
|
||||||
|
return Dconv(nil, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Dconv(p *Prog, a *Addr) string {
|
||||||
|
var str string
|
||||||
|
|
||||||
|
switch a.Type {
|
||||||
|
default:
|
||||||
|
str = fmt.Sprintf("type=%d", a.Type)
|
||||||
|
|
||||||
|
case TYPE_NONE:
|
||||||
|
str = ""
|
||||||
|
if a.Name != NAME_NONE || a.Reg != 0 || a.Sym != nil {
|
||||||
|
str = fmt.Sprintf("%v(%v)(NONE)", Mconv(a), Rconv(int(a.Reg)))
|
||||||
|
}
|
||||||
|
|
||||||
|
case TYPE_REG:
|
||||||
|
// TODO(rsc): This special case is for x86 instructions like
|
||||||
|
// PINSRQ CX,$1,X6
|
||||||
|
// where the $1 is included in the p->to Addr.
|
||||||
|
// Move into a new field.
|
||||||
|
if a.Offset != 0 {
|
||||||
|
str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(int(a.Reg)))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
str = Rconv(int(a.Reg))
|
||||||
|
if a.Name != NAME_NONE || a.Sym != nil {
|
||||||
|
str = fmt.Sprintf("%v(%v)(REG)", Mconv(a), Rconv(int(a.Reg)))
|
||||||
|
}
|
||||||
|
|
||||||
|
case TYPE_BRANCH:
|
||||||
|
if a.Sym != nil {
|
||||||
|
str = fmt.Sprintf("%s(SB)", a.Sym.Name)
|
||||||
|
} else if p != nil && p.Pcond != nil {
|
||||||
|
str = fmt.Sprint(p.Pcond.Pc)
|
||||||
|
} else if a.Val != nil {
|
||||||
|
str = fmt.Sprint(a.Val.(*Prog).Pc)
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("%d(PC)", a.Offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
case TYPE_INDIR:
|
||||||
|
str = fmt.Sprintf("*%s", Mconv(a))
|
||||||
|
|
||||||
|
case TYPE_MEM:
|
||||||
|
str = Mconv(a)
|
||||||
|
if a.Index != REG_NONE {
|
||||||
|
str += fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
|
||||||
|
}
|
||||||
|
|
||||||
|
case TYPE_CONST:
|
||||||
|
if a.Reg != 0 {
|
||||||
|
str = fmt.Sprintf("$%v(%v)", Mconv(a), Rconv(int(a.Reg)))
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("$%v", Mconv(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
case TYPE_TEXTSIZE:
|
||||||
|
if a.Val.(int32) == ArgsSizeUnknown {
|
||||||
|
str = fmt.Sprintf("$%d", a.Offset)
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("$%d-%d", a.Offset, a.Val.(int32))
|
||||||
|
}
|
||||||
|
|
||||||
|
case TYPE_FCONST:
|
||||||
|
str = fmt.Sprintf("%.17g", a.Val.(float64))
|
||||||
|
// Make sure 1 prints as 1.0
|
||||||
|
if !strings.ContainsAny(str, ".e") {
|
||||||
|
str += ".0"
|
||||||
|
}
|
||||||
|
str = fmt.Sprintf("$(%s)", str)
|
||||||
|
|
||||||
|
case TYPE_SCONST:
|
||||||
|
str = fmt.Sprintf("$%q", a.Val.(string))
|
||||||
|
|
||||||
|
case TYPE_ADDR:
|
||||||
|
str = fmt.Sprintf("$%s", Mconv(a))
|
||||||
|
|
||||||
|
case TYPE_SHIFT:
|
||||||
|
v := int(a.Offset)
|
||||||
|
ops := "<<>>->@>"
|
||||||
|
switch GOARCH {
|
||||||
|
case "arm":
|
||||||
|
op := ops[((v>>5)&3)<<1:]
|
||||||
|
if v&(1<<4) != 0 {
|
||||||
|
str = fmt.Sprintf("R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15)
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31)
|
||||||
|
}
|
||||||
|
if a.Reg != 0 {
|
||||||
|
str += fmt.Sprintf("(%v)", Rconv(int(a.Reg)))
|
||||||
|
}
|
||||||
|
case "arm64":
|
||||||
|
op := ops[((v>>22)&3)<<1:]
|
||||||
|
str = fmt.Sprintf("R%d%c%c%d", (v>>16)&31, op[0], op[1], (v>>10)&63)
|
||||||
|
default:
|
||||||
|
panic("TYPE_SHIFT is not supported on " + GOARCH)
|
||||||
|
}
|
||||||
|
|
||||||
|
case TYPE_REGREG:
|
||||||
|
str = fmt.Sprintf("(%v, %v)", Rconv(int(a.Reg)), Rconv(int(a.Offset)))
|
||||||
|
|
||||||
|
case TYPE_REGREG2:
|
||||||
|
str = fmt.Sprintf("%v, %v", Rconv(int(a.Reg)), Rconv(int(a.Offset)))
|
||||||
|
|
||||||
|
case TYPE_REGLIST:
|
||||||
|
str = regListConv(int(a.Offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
func Mconv(a *Addr) string {
|
||||||
|
var str string
|
||||||
|
|
||||||
|
switch a.Name {
|
||||||
|
default:
|
||||||
|
str = fmt.Sprintf("name=%d", a.Name)
|
||||||
|
|
||||||
|
case NAME_NONE:
|
||||||
|
switch {
|
||||||
|
case a.Reg == REG_NONE:
|
||||||
|
str = fmt.Sprint(a.Offset)
|
||||||
|
case a.Offset == 0:
|
||||||
|
str = fmt.Sprintf("(%v)", Rconv(int(a.Reg)))
|
||||||
|
case a.Offset != 0:
|
||||||
|
str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(int(a.Reg)))
|
||||||
|
}
|
||||||
|
|
||||||
|
case NAME_EXTERN:
|
||||||
|
if a.Sym != nil {
|
||||||
|
str = fmt.Sprintf("%s%s(SB)", a.Sym.Name, offConv(a.Offset))
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("%s(SB)", offConv(a.Offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
case NAME_GOTREF:
|
||||||
|
if a.Sym != nil {
|
||||||
|
str = fmt.Sprintf("%s%s@GOT(SB)", a.Sym.Name, offConv(a.Offset))
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("%s@GOT(SB)", offConv(a.Offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
case NAME_STATIC:
|
||||||
|
if a.Sym != nil {
|
||||||
|
str = fmt.Sprintf("%s<>%s(SB)", a.Sym.Name, offConv(a.Offset))
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("<>%s(SB)", offConv(a.Offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
case NAME_AUTO:
|
||||||
|
if a.Sym != nil {
|
||||||
|
str = fmt.Sprintf("%s%s(SP)", a.Sym.Name, offConv(a.Offset))
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("%s(SP)", offConv(a.Offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
case NAME_PARAM:
|
||||||
|
if a.Sym != nil {
|
||||||
|
str = fmt.Sprintf("%s%s(FP)", a.Sym.Name, offConv(a.Offset))
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("%s(FP)", offConv(a.Offset))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
func offConv(off int64) string {
|
||||||
|
if off == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%+d", off)
|
||||||
|
}
|
||||||
|
|
||||||
|
type regSet struct {
|
||||||
|
lo int
|
||||||
|
hi int
|
||||||
|
Rconv func(int) string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Few enough architectures that a linear scan is fastest.
|
||||||
|
// Not even worth sorting.
|
||||||
|
var regSpace []regSet
|
||||||
|
|
||||||
|
/*
|
||||||
|
Each architecture defines a register space as a unique
|
||||||
|
integer range.
|
||||||
|
Here is the list of architectures and the base of their register spaces.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Because of masking operations in the encodings, each register
|
||||||
|
// space should start at 0 modulo some power of 2.
|
||||||
|
RBase386 = 1 * 1024
|
||||||
|
RBaseAMD64 = 2 * 1024
|
||||||
|
RBaseARM = 3 * 1024
|
||||||
|
RBasePPC64 = 4 * 1024 // range [4k, 8k)
|
||||||
|
RBaseARM64 = 8 * 1024 // range [8k, 13k)
|
||||||
|
RBaseMIPS64 = 13 * 1024 // range [13k, 14k)
|
||||||
|
RBaseS390X = 14 * 1024 // range [14k, 15k)
|
||||||
|
)
|
||||||
|
|
||||||
|
// RegisterRegister binds a pretty-printer (Rconv) for register
|
||||||
|
// numbers to a given register number range. Lo is inclusive,
|
||||||
|
// hi exclusive (valid registers are lo through hi-1).
|
||||||
|
func RegisterRegister(lo, hi int, Rconv func(int) string) {
|
||||||
|
regSpace = append(regSpace, regSet{lo, hi, Rconv})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Rconv(reg int) string {
|
||||||
|
if reg == REG_NONE {
|
||||||
|
return "NONE"
|
||||||
|
}
|
||||||
|
for i := range regSpace {
|
||||||
|
rs := ®Space[i]
|
||||||
|
if rs.lo <= reg && reg < rs.hi {
|
||||||
|
return rs.Rconv(reg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("R???%d", reg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func regListConv(list int) string {
|
||||||
|
str := ""
|
||||||
|
|
||||||
|
for i := 0; i < 16; i++ { // TODO: 16 is ARM-specific.
|
||||||
|
if list&(1<<uint(i)) != 0 {
|
||||||
|
if str == "" {
|
||||||
|
str += "["
|
||||||
|
} else {
|
||||||
|
str += ","
|
||||||
|
}
|
||||||
|
// This is ARM-specific; R10 is g.
|
||||||
|
if i == 10 {
|
||||||
|
str += "g"
|
||||||
|
} else {
|
||||||
|
str += fmt.Sprintf("R%d", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
str += "]"
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
type opSet struct {
|
||||||
|
lo As
|
||||||
|
names []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not even worth sorting
|
||||||
|
var aSpace []opSet
|
||||||
|
|
||||||
|
// RegisterOpcode binds a list of instruction names
|
||||||
|
// to a given instruction number range.
|
||||||
|
func RegisterOpcode(lo As, Anames []string) {
|
||||||
|
if len(Anames) > AllowedOpCodes {
|
||||||
|
panic(fmt.Sprintf("too many instructions, have %d max %d", len(Anames), AllowedOpCodes))
|
||||||
|
}
|
||||||
|
aSpace = append(aSpace, opSet{lo, Anames})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a As) String() string {
|
||||||
|
if 0 <= a && int(a) < len(Anames) {
|
||||||
|
return Anames[a]
|
||||||
|
}
|
||||||
|
for i := range aSpace {
|
||||||
|
as := &aSpace[i]
|
||||||
|
if as.lo <= a && int(a-as.lo) < len(as.names) {
|
||||||
|
return as.names[a-as.lo]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("A???%d", a)
|
||||||
|
}
|
||||||
|
|
||||||
|
var Anames = []string{
|
||||||
|
"XXX",
|
||||||
|
"CALL",
|
||||||
|
"DUFFCOPY",
|
||||||
|
"DUFFZERO",
|
||||||
|
"END",
|
||||||
|
"FUNCDATA",
|
||||||
|
"JMP",
|
||||||
|
"NOP",
|
||||||
|
"PCDATA",
|
||||||
|
"RET",
|
||||||
|
"TEXT",
|
||||||
|
"TYPE",
|
||||||
|
"UNDEF",
|
||||||
|
"USEFIELD",
|
||||||
|
"VARDEF",
|
||||||
|
"VARKILL",
|
||||||
|
"VARLIVE",
|
||||||
|
}
|
||||||
|
|
||||||
|
func Bool2int(b bool) int {
|
||||||
|
// The compiler currently only optimizes this form.
|
||||||
|
// See issue 6011.
|
||||||
|
var i int
|
||||||
|
if b {
|
||||||
|
i = 1
|
||||||
|
} else {
|
||||||
|
i = 0
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
1009
vendor/github.com/google/gops/internal/obj/x86/a.out.go
generated
vendored
Normal file
1009
vendor/github.com/google/gops/internal/obj/x86/a.out.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
769
vendor/github.com/google/gops/internal/obj/x86/anames.go
generated
vendored
Normal file
769
vendor/github.com/google/gops/internal/obj/x86/anames.go
generated
vendored
Normal file
@ -0,0 +1,769 @@
|
|||||||
|
// Generated by stringer -i a.out.go -o anames.go -p x86
|
||||||
|
// Do not edit.
|
||||||
|
|
||||||
|
package x86
|
||||||
|
|
||||||
|
import "github.com/google/gops/internal/obj"
|
||||||
|
|
||||||
|
var Anames = []string{
|
||||||
|
obj.A_ARCHSPECIFIC: "AAA",
|
||||||
|
"AAD",
|
||||||
|
"AAM",
|
||||||
|
"AAS",
|
||||||
|
"ADCB",
|
||||||
|
"ADCL",
|
||||||
|
"ADCW",
|
||||||
|
"ADDB",
|
||||||
|
"ADDL",
|
||||||
|
"ADDW",
|
||||||
|
"ADJSP",
|
||||||
|
"ANDB",
|
||||||
|
"ANDL",
|
||||||
|
"ANDW",
|
||||||
|
"ARPL",
|
||||||
|
"BOUNDL",
|
||||||
|
"BOUNDW",
|
||||||
|
"BSFL",
|
||||||
|
"BSFW",
|
||||||
|
"BSRL",
|
||||||
|
"BSRW",
|
||||||
|
"BTL",
|
||||||
|
"BTW",
|
||||||
|
"BTCL",
|
||||||
|
"BTCW",
|
||||||
|
"BTRL",
|
||||||
|
"BTRW",
|
||||||
|
"BTSL",
|
||||||
|
"BTSW",
|
||||||
|
"BYTE",
|
||||||
|
"CLC",
|
||||||
|
"CLD",
|
||||||
|
"CLI",
|
||||||
|
"CLTS",
|
||||||
|
"CMC",
|
||||||
|
"CMPB",
|
||||||
|
"CMPL",
|
||||||
|
"CMPW",
|
||||||
|
"CMPSB",
|
||||||
|
"CMPSL",
|
||||||
|
"CMPSW",
|
||||||
|
"DAA",
|
||||||
|
"DAS",
|
||||||
|
"DECB",
|
||||||
|
"DECL",
|
||||||
|
"DECQ",
|
||||||
|
"DECW",
|
||||||
|
"DIVB",
|
||||||
|
"DIVL",
|
||||||
|
"DIVW",
|
||||||
|
"ENTER",
|
||||||
|
"HADDPD",
|
||||||
|
"HADDPS",
|
||||||
|
"HLT",
|
||||||
|
"HSUBPD",
|
||||||
|
"HSUBPS",
|
||||||
|
"IDIVB",
|
||||||
|
"IDIVL",
|
||||||
|
"IDIVW",
|
||||||
|
"IMULB",
|
||||||
|
"IMULL",
|
||||||
|
"IMULW",
|
||||||
|
"INB",
|
||||||
|
"INL",
|
||||||
|
"INW",
|
||||||
|
"INCB",
|
||||||
|
"INCL",
|
||||||
|
"INCQ",
|
||||||
|
"INCW",
|
||||||
|
"INSB",
|
||||||
|
"INSL",
|
||||||
|
"INSW",
|
||||||
|
"INT",
|
||||||
|
"INTO",
|
||||||
|
"IRETL",
|
||||||
|
"IRETW",
|
||||||
|
"JCC",
|
||||||
|
"JCS",
|
||||||
|
"JCXZL",
|
||||||
|
"JEQ",
|
||||||
|
"JGE",
|
||||||
|
"JGT",
|
||||||
|
"JHI",
|
||||||
|
"JLE",
|
||||||
|
"JLS",
|
||||||
|
"JLT",
|
||||||
|
"JMI",
|
||||||
|
"JNE",
|
||||||
|
"JOC",
|
||||||
|
"JOS",
|
||||||
|
"JPC",
|
||||||
|
"JPL",
|
||||||
|
"JPS",
|
||||||
|
"LAHF",
|
||||||
|
"LARL",
|
||||||
|
"LARW",
|
||||||
|
"LEAL",
|
||||||
|
"LEAW",
|
||||||
|
"LEAVEL",
|
||||||
|
"LEAVEW",
|
||||||
|
"LOCK",
|
||||||
|
"LODSB",
|
||||||
|
"LODSL",
|
||||||
|
"LODSW",
|
||||||
|
"LONG",
|
||||||
|
"LOOP",
|
||||||
|
"LOOPEQ",
|
||||||
|
"LOOPNE",
|
||||||
|
"LSLL",
|
||||||
|
"LSLW",
|
||||||
|
"MOVB",
|
||||||
|
"MOVL",
|
||||||
|
"MOVW",
|
||||||
|
"MOVBLSX",
|
||||||
|
"MOVBLZX",
|
||||||
|
"MOVBQSX",
|
||||||
|
"MOVBQZX",
|
||||||
|
"MOVBWSX",
|
||||||
|
"MOVBWZX",
|
||||||
|
"MOVWLSX",
|
||||||
|
"MOVWLZX",
|
||||||
|
"MOVWQSX",
|
||||||
|
"MOVWQZX",
|
||||||
|
"MOVSB",
|
||||||
|
"MOVSL",
|
||||||
|
"MOVSW",
|
||||||
|
"MULB",
|
||||||
|
"MULL",
|
||||||
|
"MULW",
|
||||||
|
"NEGB",
|
||||||
|
"NEGL",
|
||||||
|
"NEGW",
|
||||||
|
"NOTB",
|
||||||
|
"NOTL",
|
||||||
|
"NOTW",
|
||||||
|
"ORB",
|
||||||
|
"ORL",
|
||||||
|
"ORW",
|
||||||
|
"OUTB",
|
||||||
|
"OUTL",
|
||||||
|
"OUTW",
|
||||||
|
"OUTSB",
|
||||||
|
"OUTSL",
|
||||||
|
"OUTSW",
|
||||||
|
"PAUSE",
|
||||||
|
"POPAL",
|
||||||
|
"POPAW",
|
||||||
|
"POPCNTW",
|
||||||
|
"POPCNTL",
|
||||||
|
"POPCNTQ",
|
||||||
|
"POPFL",
|
||||||
|
"POPFW",
|
||||||
|
"POPL",
|
||||||
|
"POPW",
|
||||||
|
"PUSHAL",
|
||||||
|
"PUSHAW",
|
||||||
|
"PUSHFL",
|
||||||
|
"PUSHFW",
|
||||||
|
"PUSHL",
|
||||||
|
"PUSHW",
|
||||||
|
"RCLB",
|
||||||
|
"RCLL",
|
||||||
|
"RCLW",
|
||||||
|
"RCRB",
|
||||||
|
"RCRL",
|
||||||
|
"RCRW",
|
||||||
|
"REP",
|
||||||
|
"REPN",
|
||||||
|
"ROLB",
|
||||||
|
"ROLL",
|
||||||
|
"ROLW",
|
||||||
|
"RORB",
|
||||||
|
"RORL",
|
||||||
|
"RORW",
|
||||||
|
"SAHF",
|
||||||
|
"SALB",
|
||||||
|
"SALL",
|
||||||
|
"SALW",
|
||||||
|
"SARB",
|
||||||
|
"SARL",
|
||||||
|
"SARW",
|
||||||
|
"SBBB",
|
||||||
|
"SBBL",
|
||||||
|
"SBBW",
|
||||||
|
"SCASB",
|
||||||
|
"SCASL",
|
||||||
|
"SCASW",
|
||||||
|
"SETCC",
|
||||||
|
"SETCS",
|
||||||
|
"SETEQ",
|
||||||
|
"SETGE",
|
||||||
|
"SETGT",
|
||||||
|
"SETHI",
|
||||||
|
"SETLE",
|
||||||
|
"SETLS",
|
||||||
|
"SETLT",
|
||||||
|
"SETMI",
|
||||||
|
"SETNE",
|
||||||
|
"SETOC",
|
||||||
|
"SETOS",
|
||||||
|
"SETPC",
|
||||||
|
"SETPL",
|
||||||
|
"SETPS",
|
||||||
|
"CDQ",
|
||||||
|
"CWD",
|
||||||
|
"SHLB",
|
||||||
|
"SHLL",
|
||||||
|
"SHLW",
|
||||||
|
"SHRB",
|
||||||
|
"SHRL",
|
||||||
|
"SHRW",
|
||||||
|
"STC",
|
||||||
|
"STD",
|
||||||
|
"STI",
|
||||||
|
"STOSB",
|
||||||
|
"STOSL",
|
||||||
|
"STOSW",
|
||||||
|
"SUBB",
|
||||||
|
"SUBL",
|
||||||
|
"SUBW",
|
||||||
|
"SYSCALL",
|
||||||
|
"TESTB",
|
||||||
|
"TESTL",
|
||||||
|
"TESTW",
|
||||||
|
"VERR",
|
||||||
|
"VERW",
|
||||||
|
"WAIT",
|
||||||
|
"WORD",
|
||||||
|
"XCHGB",
|
||||||
|
"XCHGL",
|
||||||
|
"XCHGW",
|
||||||
|
"XLAT",
|
||||||
|
"XORB",
|
||||||
|
"XORL",
|
||||||
|
"XORW",
|
||||||
|
"FMOVB",
|
||||||
|
"FMOVBP",
|
||||||
|
"FMOVD",
|
||||||
|
"FMOVDP",
|
||||||
|
"FMOVF",
|
||||||
|
"FMOVFP",
|
||||||
|
"FMOVL",
|
||||||
|
"FMOVLP",
|
||||||
|
"FMOVV",
|
||||||
|
"FMOVVP",
|
||||||
|
"FMOVW",
|
||||||
|
"FMOVWP",
|
||||||
|
"FMOVX",
|
||||||
|
"FMOVXP",
|
||||||
|
"FCOMD",
|
||||||
|
"FCOMDP",
|
||||||
|
"FCOMDPP",
|
||||||
|
"FCOMF",
|
||||||
|
"FCOMFP",
|
||||||
|
"FCOML",
|
||||||
|
"FCOMLP",
|
||||||
|
"FCOMW",
|
||||||
|
"FCOMWP",
|
||||||
|
"FUCOM",
|
||||||
|
"FUCOMP",
|
||||||
|
"FUCOMPP",
|
||||||
|
"FADDDP",
|
||||||
|
"FADDW",
|
||||||
|
"FADDL",
|
||||||
|
"FADDF",
|
||||||
|
"FADDD",
|
||||||
|
"FMULDP",
|
||||||
|
"FMULW",
|
||||||
|
"FMULL",
|
||||||
|
"FMULF",
|
||||||
|
"FMULD",
|
||||||
|
"FSUBDP",
|
||||||
|
"FSUBW",
|
||||||
|
"FSUBL",
|
||||||
|
"FSUBF",
|
||||||
|
"FSUBD",
|
||||||
|
"FSUBRDP",
|
||||||
|
"FSUBRW",
|
||||||
|
"FSUBRL",
|
||||||
|
"FSUBRF",
|
||||||
|
"FSUBRD",
|
||||||
|
"FDIVDP",
|
||||||
|
"FDIVW",
|
||||||
|
"FDIVL",
|
||||||
|
"FDIVF",
|
||||||
|
"FDIVD",
|
||||||
|
"FDIVRDP",
|
||||||
|
"FDIVRW",
|
||||||
|
"FDIVRL",
|
||||||
|
"FDIVRF",
|
||||||
|
"FDIVRD",
|
||||||
|
"FXCHD",
|
||||||
|
"FFREE",
|
||||||
|
"FLDCW",
|
||||||
|
"FLDENV",
|
||||||
|
"FRSTOR",
|
||||||
|
"FSAVE",
|
||||||
|
"FSTCW",
|
||||||
|
"FSTENV",
|
||||||
|
"FSTSW",
|
||||||
|
"F2XM1",
|
||||||
|
"FABS",
|
||||||
|
"FCHS",
|
||||||
|
"FCLEX",
|
||||||
|
"FCOS",
|
||||||
|
"FDECSTP",
|
||||||
|
"FINCSTP",
|
||||||
|
"FINIT",
|
||||||
|
"FLD1",
|
||||||
|
"FLDL2E",
|
||||||
|
"FLDL2T",
|
||||||
|
"FLDLG2",
|
||||||
|
"FLDLN2",
|
||||||
|
"FLDPI",
|
||||||
|
"FLDZ",
|
||||||
|
"FNOP",
|
||||||
|
"FPATAN",
|
||||||
|
"FPREM",
|
||||||
|
"FPREM1",
|
||||||
|
"FPTAN",
|
||||||
|
"FRNDINT",
|
||||||
|
"FSCALE",
|
||||||
|
"FSIN",
|
||||||
|
"FSINCOS",
|
||||||
|
"FSQRT",
|
||||||
|
"FTST",
|
||||||
|
"FXAM",
|
||||||
|
"FXTRACT",
|
||||||
|
"FYL2X",
|
||||||
|
"FYL2XP1",
|
||||||
|
"CMPXCHGB",
|
||||||
|
"CMPXCHGL",
|
||||||
|
"CMPXCHGW",
|
||||||
|
"CMPXCHG8B",
|
||||||
|
"CPUID",
|
||||||
|
"INVD",
|
||||||
|
"INVLPG",
|
||||||
|
"LFENCE",
|
||||||
|
"MFENCE",
|
||||||
|
"MOVNTIL",
|
||||||
|
"RDMSR",
|
||||||
|
"RDPMC",
|
||||||
|
"RDTSC",
|
||||||
|
"RSM",
|
||||||
|
"SFENCE",
|
||||||
|
"SYSRET",
|
||||||
|
"WBINVD",
|
||||||
|
"WRMSR",
|
||||||
|
"XADDB",
|
||||||
|
"XADDL",
|
||||||
|
"XADDW",
|
||||||
|
"CMOVLCC",
|
||||||
|
"CMOVLCS",
|
||||||
|
"CMOVLEQ",
|
||||||
|
"CMOVLGE",
|
||||||
|
"CMOVLGT",
|
||||||
|
"CMOVLHI",
|
||||||
|
"CMOVLLE",
|
||||||
|
"CMOVLLS",
|
||||||
|
"CMOVLLT",
|
||||||
|
"CMOVLMI",
|
||||||
|
"CMOVLNE",
|
||||||
|
"CMOVLOC",
|
||||||
|
"CMOVLOS",
|
||||||
|
"CMOVLPC",
|
||||||
|
"CMOVLPL",
|
||||||
|
"CMOVLPS",
|
||||||
|
"CMOVQCC",
|
||||||
|
"CMOVQCS",
|
||||||
|
"CMOVQEQ",
|
||||||
|
"CMOVQGE",
|
||||||
|
"CMOVQGT",
|
||||||
|
"CMOVQHI",
|
||||||
|
"CMOVQLE",
|
||||||
|
"CMOVQLS",
|
||||||
|
"CMOVQLT",
|
||||||
|
"CMOVQMI",
|
||||||
|
"CMOVQNE",
|
||||||
|
"CMOVQOC",
|
||||||
|
"CMOVQOS",
|
||||||
|
"CMOVQPC",
|
||||||
|
"CMOVQPL",
|
||||||
|
"CMOVQPS",
|
||||||
|
"CMOVWCC",
|
||||||
|
"CMOVWCS",
|
||||||
|
"CMOVWEQ",
|
||||||
|
"CMOVWGE",
|
||||||
|
"CMOVWGT",
|
||||||
|
"CMOVWHI",
|
||||||
|
"CMOVWLE",
|
||||||
|
"CMOVWLS",
|
||||||
|
"CMOVWLT",
|
||||||
|
"CMOVWMI",
|
||||||
|
"CMOVWNE",
|
||||||
|
"CMOVWOC",
|
||||||
|
"CMOVWOS",
|
||||||
|
"CMOVWPC",
|
||||||
|
"CMOVWPL",
|
||||||
|
"CMOVWPS",
|
||||||
|
"ADCQ",
|
||||||
|
"ADDQ",
|
||||||
|
"ANDQ",
|
||||||
|
"BSFQ",
|
||||||
|
"BSRQ",
|
||||||
|
"BTCQ",
|
||||||
|
"BTQ",
|
||||||
|
"BTRQ",
|
||||||
|
"BTSQ",
|
||||||
|
"CMPQ",
|
||||||
|
"CMPSQ",
|
||||||
|
"CMPXCHGQ",
|
||||||
|
"CQO",
|
||||||
|
"DIVQ",
|
||||||
|
"IDIVQ",
|
||||||
|
"IMULQ",
|
||||||
|
"IRETQ",
|
||||||
|
"JCXZQ",
|
||||||
|
"LEAQ",
|
||||||
|
"LEAVEQ",
|
||||||
|
"LODSQ",
|
||||||
|
"MOVQ",
|
||||||
|
"MOVLQSX",
|
||||||
|
"MOVLQZX",
|
||||||
|
"MOVNTIQ",
|
||||||
|
"MOVSQ",
|
||||||
|
"MULQ",
|
||||||
|
"NEGQ",
|
||||||
|
"NOTQ",
|
||||||
|
"ORQ",
|
||||||
|
"POPFQ",
|
||||||
|
"POPQ",
|
||||||
|
"PUSHFQ",
|
||||||
|
"PUSHQ",
|
||||||
|
"RCLQ",
|
||||||
|
"RCRQ",
|
||||||
|
"ROLQ",
|
||||||
|
"RORQ",
|
||||||
|
"QUAD",
|
||||||
|
"SALQ",
|
||||||
|
"SARQ",
|
||||||
|
"SBBQ",
|
||||||
|
"SCASQ",
|
||||||
|
"SHLQ",
|
||||||
|
"SHRQ",
|
||||||
|
"STOSQ",
|
||||||
|
"SUBQ",
|
||||||
|
"TESTQ",
|
||||||
|
"XADDQ",
|
||||||
|
"XCHGQ",
|
||||||
|
"XORQ",
|
||||||
|
"XGETBV",
|
||||||
|
"ADDPD",
|
||||||
|
"ADDPS",
|
||||||
|
"ADDSD",
|
||||||
|
"ADDSS",
|
||||||
|
"ANDNL",
|
||||||
|
"ANDNQ",
|
||||||
|
"ANDNPD",
|
||||||
|
"ANDNPS",
|
||||||
|
"ANDPD",
|
||||||
|
"ANDPS",
|
||||||
|
"BEXTRL",
|
||||||
|
"BEXTRQ",
|
||||||
|
"BLSIL",
|
||||||
|
"BLSIQ",
|
||||||
|
"BLSMSKL",
|
||||||
|
"BLSMSKQ",
|
||||||
|
"BLSRL",
|
||||||
|
"BLSRQ",
|
||||||
|
"BZHIL",
|
||||||
|
"BZHIQ",
|
||||||
|
"CMPPD",
|
||||||
|
"CMPPS",
|
||||||
|
"CMPSD",
|
||||||
|
"CMPSS",
|
||||||
|
"COMISD",
|
||||||
|
"COMISS",
|
||||||
|
"CVTPD2PL",
|
||||||
|
"CVTPD2PS",
|
||||||
|
"CVTPL2PD",
|
||||||
|
"CVTPL2PS",
|
||||||
|
"CVTPS2PD",
|
||||||
|
"CVTPS2PL",
|
||||||
|
"CVTSD2SL",
|
||||||
|
"CVTSD2SQ",
|
||||||
|
"CVTSD2SS",
|
||||||
|
"CVTSL2SD",
|
||||||
|
"CVTSL2SS",
|
||||||
|
"CVTSQ2SD",
|
||||||
|
"CVTSQ2SS",
|
||||||
|
"CVTSS2SD",
|
||||||
|
"CVTSS2SL",
|
||||||
|
"CVTSS2SQ",
|
||||||
|
"CVTTPD2PL",
|
||||||
|
"CVTTPS2PL",
|
||||||
|
"CVTTSD2SL",
|
||||||
|
"CVTTSD2SQ",
|
||||||
|
"CVTTSS2SL",
|
||||||
|
"CVTTSS2SQ",
|
||||||
|
"DIVPD",
|
||||||
|
"DIVPS",
|
||||||
|
"DIVSD",
|
||||||
|
"DIVSS",
|
||||||
|
"EMMS",
|
||||||
|
"FXRSTOR",
|
||||||
|
"FXRSTOR64",
|
||||||
|
"FXSAVE",
|
||||||
|
"FXSAVE64",
|
||||||
|
"LDDQU",
|
||||||
|
"LDMXCSR",
|
||||||
|
"MASKMOVOU",
|
||||||
|
"MASKMOVQ",
|
||||||
|
"MAXPD",
|
||||||
|
"MAXPS",
|
||||||
|
"MAXSD",
|
||||||
|
"MAXSS",
|
||||||
|
"MINPD",
|
||||||
|
"MINPS",
|
||||||
|
"MINSD",
|
||||||
|
"MINSS",
|
||||||
|
"MOVAPD",
|
||||||
|
"MOVAPS",
|
||||||
|
"MOVOU",
|
||||||
|
"MOVHLPS",
|
||||||
|
"MOVHPD",
|
||||||
|
"MOVHPS",
|
||||||
|
"MOVLHPS",
|
||||||
|
"MOVLPD",
|
||||||
|
"MOVLPS",
|
||||||
|
"MOVMSKPD",
|
||||||
|
"MOVMSKPS",
|
||||||
|
"MOVNTO",
|
||||||
|
"MOVNTPD",
|
||||||
|
"MOVNTPS",
|
||||||
|
"MOVNTQ",
|
||||||
|
"MOVO",
|
||||||
|
"MOVQOZX",
|
||||||
|
"MOVSD",
|
||||||
|
"MOVSS",
|
||||||
|
"MOVUPD",
|
||||||
|
"MOVUPS",
|
||||||
|
"MULPD",
|
||||||
|
"MULPS",
|
||||||
|
"MULSD",
|
||||||
|
"MULSS",
|
||||||
|
"MULXL",
|
||||||
|
"MULXQ",
|
||||||
|
"ORPD",
|
||||||
|
"ORPS",
|
||||||
|
"PACKSSLW",
|
||||||
|
"PACKSSWB",
|
||||||
|
"PACKUSWB",
|
||||||
|
"PADDB",
|
||||||
|
"PADDL",
|
||||||
|
"PADDQ",
|
||||||
|
"PADDSB",
|
||||||
|
"PADDSW",
|
||||||
|
"PADDUSB",
|
||||||
|
"PADDUSW",
|
||||||
|
"PADDW",
|
||||||
|
"PAND",
|
||||||
|
"PANDN",
|
||||||
|
"PAVGB",
|
||||||
|
"PAVGW",
|
||||||
|
"PCMPEQB",
|
||||||
|
"PCMPEQL",
|
||||||
|
"PCMPEQW",
|
||||||
|
"PCMPGTB",
|
||||||
|
"PCMPGTL",
|
||||||
|
"PCMPGTW",
|
||||||
|
"PDEPL",
|
||||||
|
"PDEPQ",
|
||||||
|
"PEXTL",
|
||||||
|
"PEXTQ",
|
||||||
|
"PEXTRB",
|
||||||
|
"PEXTRD",
|
||||||
|
"PEXTRQ",
|
||||||
|
"PEXTRW",
|
||||||
|
"PHADDD",
|
||||||
|
"PHADDSW",
|
||||||
|
"PHADDW",
|
||||||
|
"PHMINPOSUW",
|
||||||
|
"PHSUBD",
|
||||||
|
"PHSUBSW",
|
||||||
|
"PHSUBW",
|
||||||
|
"PINSRB",
|
||||||
|
"PINSRD",
|
||||||
|
"PINSRQ",
|
||||||
|
"PINSRW",
|
||||||
|
"PMADDWL",
|
||||||
|
"PMAXSW",
|
||||||
|
"PMAXUB",
|
||||||
|
"PMINSW",
|
||||||
|
"PMINUB",
|
||||||
|
"PMOVMSKB",
|
||||||
|
"PMOVSXBD",
|
||||||
|
"PMOVSXBQ",
|
||||||
|
"PMOVSXBW",
|
||||||
|
"PMOVSXDQ",
|
||||||
|
"PMOVSXWD",
|
||||||
|
"PMOVSXWQ",
|
||||||
|
"PMOVZXBD",
|
||||||
|
"PMOVZXBQ",
|
||||||
|
"PMOVZXBW",
|
||||||
|
"PMOVZXDQ",
|
||||||
|
"PMOVZXWD",
|
||||||
|
"PMOVZXWQ",
|
||||||
|
"PMULDQ",
|
||||||
|
"PMULHUW",
|
||||||
|
"PMULHW",
|
||||||
|
"PMULLD",
|
||||||
|
"PMULLW",
|
||||||
|
"PMULULQ",
|
||||||
|
"POR",
|
||||||
|
"PSADBW",
|
||||||
|
"PSHUFB",
|
||||||
|
"PSHUFHW",
|
||||||
|
"PSHUFL",
|
||||||
|
"PSHUFLW",
|
||||||
|
"PSHUFW",
|
||||||
|
"PSLLL",
|
||||||
|
"PSLLO",
|
||||||
|
"PSLLQ",
|
||||||
|
"PSLLW",
|
||||||
|
"PSRAL",
|
||||||
|
"PSRAW",
|
||||||
|
"PSRLL",
|
||||||
|
"PSRLO",
|
||||||
|
"PSRLQ",
|
||||||
|
"PSRLW",
|
||||||
|
"PSUBB",
|
||||||
|
"PSUBL",
|
||||||
|
"PSUBQ",
|
||||||
|
"PSUBSB",
|
||||||
|
"PSUBSW",
|
||||||
|
"PSUBUSB",
|
||||||
|
"PSUBUSW",
|
||||||
|
"PSUBW",
|
||||||
|
"PUNPCKHBW",
|
||||||
|
"PUNPCKHLQ",
|
||||||
|
"PUNPCKHQDQ",
|
||||||
|
"PUNPCKHWL",
|
||||||
|
"PUNPCKLBW",
|
||||||
|
"PUNPCKLLQ",
|
||||||
|
"PUNPCKLQDQ",
|
||||||
|
"PUNPCKLWL",
|
||||||
|
"PXOR",
|
||||||
|
"RCPPS",
|
||||||
|
"RCPSS",
|
||||||
|
"RSQRTPS",
|
||||||
|
"RSQRTSS",
|
||||||
|
"SARXL",
|
||||||
|
"SARXQ",
|
||||||
|
"SHLXL",
|
||||||
|
"SHLXQ",
|
||||||
|
"SHRXL",
|
||||||
|
"SHRXQ",
|
||||||
|
"SHUFPD",
|
||||||
|
"SHUFPS",
|
||||||
|
"SQRTPD",
|
||||||
|
"SQRTPS",
|
||||||
|
"SQRTSD",
|
||||||
|
"SQRTSS",
|
||||||
|
"STMXCSR",
|
||||||
|
"SUBPD",
|
||||||
|
"SUBPS",
|
||||||
|
"SUBSD",
|
||||||
|
"SUBSS",
|
||||||
|
"UCOMISD",
|
||||||
|
"UCOMISS",
|
||||||
|
"UNPCKHPD",
|
||||||
|
"UNPCKHPS",
|
||||||
|
"UNPCKLPD",
|
||||||
|
"UNPCKLPS",
|
||||||
|
"XORPD",
|
||||||
|
"XORPS",
|
||||||
|
"PCMPESTRI",
|
||||||
|
"RETFW",
|
||||||
|
"RETFL",
|
||||||
|
"RETFQ",
|
||||||
|
"SWAPGS",
|
||||||
|
"MODE",
|
||||||
|
"CRC32B",
|
||||||
|
"CRC32Q",
|
||||||
|
"IMUL3Q",
|
||||||
|
"PREFETCHT0",
|
||||||
|
"PREFETCHT1",
|
||||||
|
"PREFETCHT2",
|
||||||
|
"PREFETCHNTA",
|
||||||
|
"MOVQL",
|
||||||
|
"BSWAPL",
|
||||||
|
"BSWAPQ",
|
||||||
|
"AESENC",
|
||||||
|
"AESENCLAST",
|
||||||
|
"AESDEC",
|
||||||
|
"AESDECLAST",
|
||||||
|
"AESIMC",
|
||||||
|
"AESKEYGENASSIST",
|
||||||
|
"ROUNDPS",
|
||||||
|
"ROUNDSS",
|
||||||
|
"ROUNDPD",
|
||||||
|
"ROUNDSD",
|
||||||
|
"MOVDDUP",
|
||||||
|
"MOVSHDUP",
|
||||||
|
"MOVSLDUP",
|
||||||
|
"PSHUFD",
|
||||||
|
"PCLMULQDQ",
|
||||||
|
"VZEROUPPER",
|
||||||
|
"VMOVDQU",
|
||||||
|
"VMOVNTDQ",
|
||||||
|
"VMOVDQA",
|
||||||
|
"VPCMPEQB",
|
||||||
|
"VPXOR",
|
||||||
|
"VPMOVMSKB",
|
||||||
|
"VPAND",
|
||||||
|
"VPTEST",
|
||||||
|
"VPBROADCASTB",
|
||||||
|
"VPSHUFB",
|
||||||
|
"VPSHUFD",
|
||||||
|
"VPERM2F128",
|
||||||
|
"VPALIGNR",
|
||||||
|
"VPADDQ",
|
||||||
|
"VPADDD",
|
||||||
|
"VPSRLDQ",
|
||||||
|
"VPSLLDQ",
|
||||||
|
"VPSRLQ",
|
||||||
|
"VPSLLQ",
|
||||||
|
"VPSRLD",
|
||||||
|
"VPSLLD",
|
||||||
|
"VPOR",
|
||||||
|
"VPBLENDD",
|
||||||
|
"VINSERTI128",
|
||||||
|
"VPERM2I128",
|
||||||
|
"RORXL",
|
||||||
|
"RORXQ",
|
||||||
|
"VBROADCASTSS",
|
||||||
|
"VBROADCASTSD",
|
||||||
|
"VMOVDDUP",
|
||||||
|
"VMOVSHDUP",
|
||||||
|
"VMOVSLDUP",
|
||||||
|
"JCXZW",
|
||||||
|
"FCMOVCC",
|
||||||
|
"FCMOVCS",
|
||||||
|
"FCMOVEQ",
|
||||||
|
"FCMOVHI",
|
||||||
|
"FCMOVLS",
|
||||||
|
"FCMOVNE",
|
||||||
|
"FCMOVNU",
|
||||||
|
"FCMOVUN",
|
||||||
|
"FCOMI",
|
||||||
|
"FCOMIP",
|
||||||
|
"FUCOMI",
|
||||||
|
"FUCOMIP",
|
||||||
|
"XACQUIRE",
|
||||||
|
"XRELEASE",
|
||||||
|
"XBEGIN",
|
||||||
|
"XEND",
|
||||||
|
"XABORT",
|
||||||
|
"XTEST",
|
||||||
|
"LAST",
|
||||||
|
}
|
4536
vendor/github.com/google/gops/internal/obj/x86/asm6.go
generated
vendored
Normal file
4536
vendor/github.com/google/gops/internal/obj/x86/asm6.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
181
vendor/github.com/google/gops/internal/obj/x86/list6.go
generated
vendored
Normal file
181
vendor/github.com/google/gops/internal/obj/x86/list6.go
generated
vendored
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
// Inferno utils/6c/list.c
|
||||||
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6c/list.c
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package x86
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gops/internal/obj"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Register = []string{
|
||||||
|
"AL", /* [D_AL] */
|
||||||
|
"CL",
|
||||||
|
"DL",
|
||||||
|
"BL",
|
||||||
|
"SPB",
|
||||||
|
"BPB",
|
||||||
|
"SIB",
|
||||||
|
"DIB",
|
||||||
|
"R8B",
|
||||||
|
"R9B",
|
||||||
|
"R10B",
|
||||||
|
"R11B",
|
||||||
|
"R12B",
|
||||||
|
"R13B",
|
||||||
|
"R14B",
|
||||||
|
"R15B",
|
||||||
|
"AX", /* [D_AX] */
|
||||||
|
"CX",
|
||||||
|
"DX",
|
||||||
|
"BX",
|
||||||
|
"SP",
|
||||||
|
"BP",
|
||||||
|
"SI",
|
||||||
|
"DI",
|
||||||
|
"R8",
|
||||||
|
"R9",
|
||||||
|
"R10",
|
||||||
|
"R11",
|
||||||
|
"R12",
|
||||||
|
"R13",
|
||||||
|
"R14",
|
||||||
|
"R15",
|
||||||
|
"AH",
|
||||||
|
"CH",
|
||||||
|
"DH",
|
||||||
|
"BH",
|
||||||
|
"F0", /* [D_F0] */
|
||||||
|
"F1",
|
||||||
|
"F2",
|
||||||
|
"F3",
|
||||||
|
"F4",
|
||||||
|
"F5",
|
||||||
|
"F6",
|
||||||
|
"F7",
|
||||||
|
"M0",
|
||||||
|
"M1",
|
||||||
|
"M2",
|
||||||
|
"M3",
|
||||||
|
"M4",
|
||||||
|
"M5",
|
||||||
|
"M6",
|
||||||
|
"M7",
|
||||||
|
"X0",
|
||||||
|
"X1",
|
||||||
|
"X2",
|
||||||
|
"X3",
|
||||||
|
"X4",
|
||||||
|
"X5",
|
||||||
|
"X6",
|
||||||
|
"X7",
|
||||||
|
"X8",
|
||||||
|
"X9",
|
||||||
|
"X10",
|
||||||
|
"X11",
|
||||||
|
"X12",
|
||||||
|
"X13",
|
||||||
|
"X14",
|
||||||
|
"X15",
|
||||||
|
"Y0",
|
||||||
|
"Y1",
|
||||||
|
"Y2",
|
||||||
|
"Y3",
|
||||||
|
"Y4",
|
||||||
|
"Y5",
|
||||||
|
"Y6",
|
||||||
|
"Y7",
|
||||||
|
"Y8",
|
||||||
|
"Y9",
|
||||||
|
"Y10",
|
||||||
|
"Y11",
|
||||||
|
"Y12",
|
||||||
|
"Y13",
|
||||||
|
"Y14",
|
||||||
|
"Y15",
|
||||||
|
"CS", /* [D_CS] */
|
||||||
|
"SS",
|
||||||
|
"DS",
|
||||||
|
"ES",
|
||||||
|
"FS",
|
||||||
|
"GS",
|
||||||
|
"GDTR", /* [D_GDTR] */
|
||||||
|
"IDTR", /* [D_IDTR] */
|
||||||
|
"LDTR", /* [D_LDTR] */
|
||||||
|
"MSW", /* [D_MSW] */
|
||||||
|
"TASK", /* [D_TASK] */
|
||||||
|
"CR0", /* [D_CR] */
|
||||||
|
"CR1",
|
||||||
|
"CR2",
|
||||||
|
"CR3",
|
||||||
|
"CR4",
|
||||||
|
"CR5",
|
||||||
|
"CR6",
|
||||||
|
"CR7",
|
||||||
|
"CR8",
|
||||||
|
"CR9",
|
||||||
|
"CR10",
|
||||||
|
"CR11",
|
||||||
|
"CR12",
|
||||||
|
"CR13",
|
||||||
|
"CR14",
|
||||||
|
"CR15",
|
||||||
|
"DR0", /* [D_DR] */
|
||||||
|
"DR1",
|
||||||
|
"DR2",
|
||||||
|
"DR3",
|
||||||
|
"DR4",
|
||||||
|
"DR5",
|
||||||
|
"DR6",
|
||||||
|
"DR7",
|
||||||
|
"TR0", /* [D_TR] */
|
||||||
|
"TR1",
|
||||||
|
"TR2",
|
||||||
|
"TR3",
|
||||||
|
"TR4",
|
||||||
|
"TR5",
|
||||||
|
"TR6",
|
||||||
|
"TR7",
|
||||||
|
"TLS", /* [D_TLS] */
|
||||||
|
"MAXREG", /* [MAXREG] */
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
obj.RegisterRegister(REG_AL, REG_AL+len(Register), Rconv)
|
||||||
|
obj.RegisterOpcode(obj.ABaseAMD64, Anames)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Rconv(r int) string {
|
||||||
|
if REG_AL <= r && r-REG_AL < len(Register) {
|
||||||
|
return Register[r-REG_AL]
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Rgok(%d)", r-obj.RBaseAMD64)
|
||||||
|
}
|
1481
vendor/github.com/google/gops/internal/obj/x86/obj6.go
generated
vendored
Normal file
1481
vendor/github.com/google/gops/internal/obj/x86/obj6.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
15
vendor/github.com/google/gops/internal/obj/zbootstrap.go
generated
vendored
Normal file
15
vendor/github.com/google/gops/internal/obj/zbootstrap.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// auto generated by go tool dist
|
||||||
|
|
||||||
|
package obj
|
||||||
|
|
||||||
|
import "runtime"
|
||||||
|
|
||||||
|
const defaultGOROOT = `/Users/jbd/go`
|
||||||
|
const defaultGO386 = `sse2`
|
||||||
|
const defaultGOARM = `7`
|
||||||
|
const defaultGOOS = runtime.GOOS
|
||||||
|
const defaultGOARCH = runtime.GOARCH
|
||||||
|
const defaultGO_EXTLINK_ENABLED = ``
|
||||||
|
const version = `devel +4141054 Thu Nov 3 17:42:01 2016 +0000`
|
||||||
|
const stackGuardMultiplier = 1
|
||||||
|
const goexperiment = ``
|
283
vendor/github.com/google/gops/internal/objfile/disasm.go
generated
vendored
Normal file
283
vendor/github.com/google/gops/internal/objfile/disasm.go
generated
vendored
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package objfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"debug/gosym"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"regexp"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"text/tabwriter"
|
||||||
|
|
||||||
|
"golang.org/x/arch/arm/armasm"
|
||||||
|
"golang.org/x/arch/ppc64/ppc64asm"
|
||||||
|
"golang.org/x/arch/x86/x86asm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Disasm is a disassembler for a given File.
|
||||||
|
type Disasm struct {
|
||||||
|
syms []Sym //symbols in file, sorted by address
|
||||||
|
pcln Liner // pcln table
|
||||||
|
text []byte // bytes of text segment (actual instructions)
|
||||||
|
textStart uint64 // start PC of text
|
||||||
|
textEnd uint64 // end PC of text
|
||||||
|
goarch string // GOARCH string
|
||||||
|
disasm disasmFunc // disassembler function for goarch
|
||||||
|
byteOrder binary.ByteOrder // byte order for goarch
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disasm returns a disassembler for the file f.
|
||||||
|
func (f *File) Disasm() (*Disasm, error) {
|
||||||
|
syms, err := f.Symbols()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pcln, err := f.PCLineTable()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
textStart, textBytes, err := f.Text()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
goarch := f.GOARCH()
|
||||||
|
disasm := disasms[goarch]
|
||||||
|
byteOrder := byteOrders[goarch]
|
||||||
|
if disasm == nil || byteOrder == nil {
|
||||||
|
return nil, fmt.Errorf("unsupported architecture")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter out section symbols, overwriting syms in place.
|
||||||
|
keep := syms[:0]
|
||||||
|
for _, sym := range syms {
|
||||||
|
switch sym.Name {
|
||||||
|
case "runtime.text", "text", "_text", "runtime.etext", "etext", "_etext":
|
||||||
|
// drop
|
||||||
|
default:
|
||||||
|
keep = append(keep, sym)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
syms = keep
|
||||||
|
d := &Disasm{
|
||||||
|
syms: syms,
|
||||||
|
pcln: pcln,
|
||||||
|
text: textBytes,
|
||||||
|
textStart: textStart,
|
||||||
|
textEnd: textStart + uint64(len(textBytes)),
|
||||||
|
goarch: goarch,
|
||||||
|
disasm: disasm,
|
||||||
|
byteOrder: byteOrder,
|
||||||
|
}
|
||||||
|
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// lookup finds the symbol name containing addr.
|
||||||
|
func (d *Disasm) lookup(addr uint64) (name string, base uint64) {
|
||||||
|
i := sort.Search(len(d.syms), func(i int) bool { return addr < d.syms[i].Addr })
|
||||||
|
if i > 0 {
|
||||||
|
s := d.syms[i-1]
|
||||||
|
if s.Addr != 0 && s.Addr <= addr && addr < s.Addr+uint64(s.Size) {
|
||||||
|
return s.Name, s.Addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// base returns the final element in the path.
|
||||||
|
// It works on both Windows and Unix paths,
|
||||||
|
// regardless of host operating system.
|
||||||
|
func base(path string) string {
|
||||||
|
path = path[strings.LastIndex(path, "/")+1:]
|
||||||
|
path = path[strings.LastIndex(path, `\`)+1:]
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print prints a disassembly of the file to w.
|
||||||
|
// If filter is non-nil, the disassembly only includes functions with names matching filter.
|
||||||
|
// The disassembly only includes functions that overlap the range [start, end).
|
||||||
|
func (d *Disasm) Print(w io.Writer, filter *regexp.Regexp, start, end uint64) {
|
||||||
|
if start < d.textStart {
|
||||||
|
start = d.textStart
|
||||||
|
}
|
||||||
|
if end > d.textEnd {
|
||||||
|
end = d.textEnd
|
||||||
|
}
|
||||||
|
printed := false
|
||||||
|
bw := bufio.NewWriter(w)
|
||||||
|
for _, sym := range d.syms {
|
||||||
|
symStart := sym.Addr
|
||||||
|
symEnd := sym.Addr + uint64(sym.Size)
|
||||||
|
relocs := sym.Relocs
|
||||||
|
if sym.Code != 'T' && sym.Code != 't' ||
|
||||||
|
symStart < d.textStart ||
|
||||||
|
symEnd <= start || end <= symStart ||
|
||||||
|
filter != nil && !filter.MatchString(sym.Name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if printed {
|
||||||
|
fmt.Fprintf(bw, "\n")
|
||||||
|
}
|
||||||
|
printed = true
|
||||||
|
|
||||||
|
file, _, _ := d.pcln.PCToLine(sym.Addr)
|
||||||
|
fmt.Fprintf(bw, "TEXT %s(SB) %s\n", sym.Name, file)
|
||||||
|
|
||||||
|
tw := tabwriter.NewWriter(bw, 1, 8, 1, '\t', 0)
|
||||||
|
if symEnd > end {
|
||||||
|
symEnd = end
|
||||||
|
}
|
||||||
|
code := d.text[:end-d.textStart]
|
||||||
|
d.Decode(symStart, symEnd, relocs, func(pc, size uint64, file string, line int, text string) {
|
||||||
|
i := pc - d.textStart
|
||||||
|
fmt.Fprintf(tw, "\t%s:%d\t%#x\t", base(file), line, pc)
|
||||||
|
if size%4 != 0 || d.goarch == "386" || d.goarch == "amd64" {
|
||||||
|
// Print instruction as bytes.
|
||||||
|
fmt.Fprintf(tw, "%x", code[i:i+size])
|
||||||
|
} else {
|
||||||
|
// Print instruction as 32-bit words.
|
||||||
|
for j := uint64(0); j < size; j += 4 {
|
||||||
|
if j > 0 {
|
||||||
|
fmt.Fprintf(tw, " ")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(tw, "%08x", d.byteOrder.Uint32(code[i+j:]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Fprintf(tw, "\t%s\n", text)
|
||||||
|
})
|
||||||
|
tw.Flush()
|
||||||
|
}
|
||||||
|
bw.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode disassembles the text segment range [start, end), calling f for each instruction.
|
||||||
|
func (d *Disasm) Decode(start, end uint64, relocs []Reloc, f func(pc, size uint64, file string, line int, text string)) {
|
||||||
|
if start < d.textStart {
|
||||||
|
start = d.textStart
|
||||||
|
}
|
||||||
|
if end > d.textEnd {
|
||||||
|
end = d.textEnd
|
||||||
|
}
|
||||||
|
code := d.text[:end-d.textStart]
|
||||||
|
lookup := d.lookup
|
||||||
|
for pc := start; pc < end; {
|
||||||
|
i := pc - d.textStart
|
||||||
|
text, size := d.disasm(code[i:], pc, lookup, d.byteOrder)
|
||||||
|
file, line, _ := d.pcln.PCToLine(pc)
|
||||||
|
text += "\t"
|
||||||
|
first := true
|
||||||
|
for len(relocs) > 0 && relocs[0].Addr < i+uint64(size) {
|
||||||
|
if first {
|
||||||
|
first = false
|
||||||
|
} else {
|
||||||
|
text += " "
|
||||||
|
}
|
||||||
|
text += relocs[0].Stringer.String(pc - start)
|
||||||
|
relocs = relocs[1:]
|
||||||
|
}
|
||||||
|
f(pc, uint64(size), file, line, text)
|
||||||
|
pc += uint64(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type lookupFunc func(addr uint64) (sym string, base uint64)
|
||||||
|
type disasmFunc func(code []byte, pc uint64, lookup lookupFunc, ord binary.ByteOrder) (text string, size int)
|
||||||
|
|
||||||
|
func disasm_386(code []byte, pc uint64, lookup lookupFunc, _ binary.ByteOrder) (string, int) {
|
||||||
|
return disasm_x86(code, pc, lookup, 32)
|
||||||
|
}
|
||||||
|
|
||||||
|
func disasm_amd64(code []byte, pc uint64, lookup lookupFunc, _ binary.ByteOrder) (string, int) {
|
||||||
|
return disasm_x86(code, pc, lookup, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
func disasm_x86(code []byte, pc uint64, lookup lookupFunc, arch int) (string, int) {
|
||||||
|
inst, err := x86asm.Decode(code, 64)
|
||||||
|
var text string
|
||||||
|
size := inst.Len
|
||||||
|
if err != nil || size == 0 || inst.Op == 0 {
|
||||||
|
size = 1
|
||||||
|
text = "?"
|
||||||
|
} else {
|
||||||
|
text = x86asm.GoSyntax(inst, pc, lookup)
|
||||||
|
}
|
||||||
|
return text, size
|
||||||
|
}
|
||||||
|
|
||||||
|
type textReader struct {
|
||||||
|
code []byte
|
||||||
|
pc uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r textReader) ReadAt(data []byte, off int64) (n int, err error) {
|
||||||
|
if off < 0 || uint64(off) < r.pc {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
d := uint64(off) - r.pc
|
||||||
|
if d >= uint64(len(r.code)) {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
n = copy(data, r.code[d:])
|
||||||
|
if n < len(data) {
|
||||||
|
err = io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func disasm_arm(code []byte, pc uint64, lookup lookupFunc, _ binary.ByteOrder) (string, int) {
|
||||||
|
inst, err := armasm.Decode(code, armasm.ModeARM)
|
||||||
|
var text string
|
||||||
|
size := inst.Len
|
||||||
|
if err != nil || size == 0 || inst.Op == 0 {
|
||||||
|
size = 4
|
||||||
|
text = "?"
|
||||||
|
} else {
|
||||||
|
text = armasm.GoSyntax(inst, pc, lookup, textReader{code, pc})
|
||||||
|
}
|
||||||
|
return text, size
|
||||||
|
}
|
||||||
|
|
||||||
|
func disasm_ppc64(code []byte, pc uint64, lookup lookupFunc, byteOrder binary.ByteOrder) (string, int) {
|
||||||
|
inst, err := ppc64asm.Decode(code, byteOrder)
|
||||||
|
var text string
|
||||||
|
size := inst.Len
|
||||||
|
if err != nil || size == 0 || inst.Op == 0 {
|
||||||
|
size = 4
|
||||||
|
text = "?"
|
||||||
|
} else {
|
||||||
|
text = ppc64asm.GoSyntax(inst, pc, lookup)
|
||||||
|
}
|
||||||
|
return text, size
|
||||||
|
}
|
||||||
|
|
||||||
|
var disasms = map[string]disasmFunc{
|
||||||
|
"386": disasm_386,
|
||||||
|
"amd64": disasm_amd64,
|
||||||
|
"arm": disasm_arm,
|
||||||
|
"ppc64": disasm_ppc64,
|
||||||
|
"ppc64le": disasm_ppc64,
|
||||||
|
}
|
||||||
|
|
||||||
|
var byteOrders = map[string]binary.ByteOrder{
|
||||||
|
"386": binary.LittleEndian,
|
||||||
|
"amd64": binary.LittleEndian,
|
||||||
|
"arm": binary.LittleEndian,
|
||||||
|
"ppc64": binary.BigEndian,
|
||||||
|
"ppc64le": binary.LittleEndian,
|
||||||
|
"s390x": binary.BigEndian,
|
||||||
|
}
|
||||||
|
|
||||||
|
type Liner interface {
|
||||||
|
// Given a pc, returns the corresponding file, line, and function data.
|
||||||
|
// If unknown, returns "",0,nil.
|
||||||
|
PCToLine(uint64) (string, int, *gosym.Func)
|
||||||
|
}
|
124
vendor/github.com/google/gops/internal/objfile/elf.go
generated
vendored
Normal file
124
vendor/github.com/google/gops/internal/objfile/elf.go
generated
vendored
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Parsing of ELF executables (Linux, FreeBSD, and so on).
|
||||||
|
|
||||||
|
package objfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"debug/dwarf"
|
||||||
|
"debug/elf"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type elfFile struct {
|
||||||
|
elf *elf.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func openElf(r *os.File) (rawFile, error) {
|
||||||
|
f, err := elf.NewFile(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &elfFile{f}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *elfFile) symbols() ([]Sym, error) {
|
||||||
|
elfSyms, err := f.elf.Symbols()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var syms []Sym
|
||||||
|
for _, s := range elfSyms {
|
||||||
|
sym := Sym{Addr: s.Value, Name: s.Name, Size: int64(s.Size), Code: '?'}
|
||||||
|
switch s.Section {
|
||||||
|
case elf.SHN_UNDEF:
|
||||||
|
sym.Code = 'U'
|
||||||
|
case elf.SHN_COMMON:
|
||||||
|
sym.Code = 'B'
|
||||||
|
default:
|
||||||
|
i := int(s.Section)
|
||||||
|
if i < 0 || i >= len(f.elf.Sections) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
sect := f.elf.Sections[i]
|
||||||
|
switch sect.Flags & (elf.SHF_WRITE | elf.SHF_ALLOC | elf.SHF_EXECINSTR) {
|
||||||
|
case elf.SHF_ALLOC | elf.SHF_EXECINSTR:
|
||||||
|
sym.Code = 'T'
|
||||||
|
case elf.SHF_ALLOC:
|
||||||
|
sym.Code = 'R'
|
||||||
|
case elf.SHF_ALLOC | elf.SHF_WRITE:
|
||||||
|
sym.Code = 'D'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if elf.ST_BIND(s.Info) == elf.STB_LOCAL {
|
||||||
|
sym.Code += 'a' - 'A'
|
||||||
|
}
|
||||||
|
syms = append(syms, sym)
|
||||||
|
}
|
||||||
|
|
||||||
|
return syms, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *elfFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) {
|
||||||
|
if sect := f.elf.Section(".text"); sect != nil {
|
||||||
|
textStart = sect.Addr
|
||||||
|
}
|
||||||
|
if sect := f.elf.Section(".gosymtab"); sect != nil {
|
||||||
|
if symtab, err = sect.Data(); err != nil {
|
||||||
|
return 0, nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sect := f.elf.Section(".gopclntab"); sect != nil {
|
||||||
|
if pclntab, err = sect.Data(); err != nil {
|
||||||
|
return 0, nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return textStart, symtab, pclntab, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *elfFile) text() (textStart uint64, text []byte, err error) {
|
||||||
|
sect := f.elf.Section(".text")
|
||||||
|
if sect == nil {
|
||||||
|
return 0, nil, fmt.Errorf("text section not found")
|
||||||
|
}
|
||||||
|
textStart = sect.Addr
|
||||||
|
text, err = sect.Data()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *elfFile) goarch() string {
|
||||||
|
switch f.elf.Machine {
|
||||||
|
case elf.EM_386:
|
||||||
|
return "386"
|
||||||
|
case elf.EM_X86_64:
|
||||||
|
return "amd64"
|
||||||
|
case elf.EM_ARM:
|
||||||
|
return "arm"
|
||||||
|
case elf.EM_PPC64:
|
||||||
|
if f.elf.ByteOrder == binary.LittleEndian {
|
||||||
|
return "ppc64le"
|
||||||
|
}
|
||||||
|
return "ppc64"
|
||||||
|
case elf.EM_S390:
|
||||||
|
return "s390x"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *elfFile) loadAddress() (uint64, error) {
|
||||||
|
for _, p := range f.elf.Progs {
|
||||||
|
if p.Type == elf.PT_LOAD {
|
||||||
|
return p.Vaddr, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, fmt.Errorf("unknown load address")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *elfFile) dwarf() (*dwarf.Data, error) {
|
||||||
|
return f.elf.DWARF()
|
||||||
|
}
|
160
vendor/github.com/google/gops/internal/objfile/goobj.go
generated
vendored
Normal file
160
vendor/github.com/google/gops/internal/objfile/goobj.go
generated
vendored
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Parsing of Go intermediate object files and archives.
|
||||||
|
|
||||||
|
package objfile
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
import (
|
||||||
|
"debug/dwarf"
|
||||||
|
"debug/gosym"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/google/gops/internal/sys"
|
||||||
|
|
||||||
|
"github.com/google/gops/internal/goobj"
|
||||||
|
)
|
||||||
|
|
||||||
|
type goobjFile struct {
|
||||||
|
goobj *goobj.Package
|
||||||
|
f *os.File // the underlying .o or .a file
|
||||||
|
}
|
||||||
|
|
||||||
|
func openGoobj(r *os.File) (rawFile, error) {
|
||||||
|
f, err := goobj.Parse(r, `""`)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &goobjFile{goobj: f, f: r}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func goobjName(id goobj.SymID) string {
|
||||||
|
if id.Version == 0 {
|
||||||
|
return id.Name
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s<%d>", id.Name, id.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *goobjFile) symbols() ([]Sym, error) {
|
||||||
|
seen := make(map[goobj.SymID]bool)
|
||||||
|
|
||||||
|
var syms []Sym
|
||||||
|
for _, s := range f.goobj.Syms {
|
||||||
|
seen[s.SymID] = true
|
||||||
|
sym := Sym{Addr: uint64(s.Data.Offset), Name: goobjName(s.SymID), Size: int64(s.Size), Type: s.Type.Name, Code: '?'}
|
||||||
|
switch s.Kind {
|
||||||
|
case goobj.STEXT, goobj.SELFRXSECT:
|
||||||
|
sym.Code = 'T'
|
||||||
|
case goobj.STYPE, goobj.SSTRING, goobj.SGOSTRING, goobj.SGOFUNC, goobj.SRODATA, goobj.SFUNCTAB, goobj.STYPELINK, goobj.SITABLINK, goobj.SSYMTAB, goobj.SPCLNTAB, goobj.SELFROSECT:
|
||||||
|
sym.Code = 'R'
|
||||||
|
case goobj.SMACHOPLT, goobj.SELFSECT, goobj.SMACHO, goobj.SMACHOGOT, goobj.SNOPTRDATA, goobj.SINITARR, goobj.SDATA, goobj.SWINDOWS:
|
||||||
|
sym.Code = 'D'
|
||||||
|
case goobj.SBSS, goobj.SNOPTRBSS, goobj.STLSBSS:
|
||||||
|
sym.Code = 'B'
|
||||||
|
case goobj.SXREF, goobj.SMACHOSYMSTR, goobj.SMACHOSYMTAB, goobj.SMACHOINDIRECTPLT, goobj.SMACHOINDIRECTGOT, goobj.SFILE, goobj.SFILEPATH, goobj.SCONST, goobj.SDYNIMPORT, goobj.SHOSTOBJ:
|
||||||
|
sym.Code = 'X' // should not see
|
||||||
|
}
|
||||||
|
if s.Version != 0 {
|
||||||
|
sym.Code += 'a' - 'A'
|
||||||
|
}
|
||||||
|
for i, r := range s.Reloc {
|
||||||
|
sym.Relocs = append(sym.Relocs, Reloc{Addr: uint64(s.Data.Offset) + uint64(r.Offset), Size: uint64(r.Size), Stringer: &s.Reloc[i]})
|
||||||
|
}
|
||||||
|
syms = append(syms, sym)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range f.goobj.Syms {
|
||||||
|
for _, r := range s.Reloc {
|
||||||
|
if !seen[r.Sym] {
|
||||||
|
seen[r.Sym] = true
|
||||||
|
sym := Sym{Name: goobjName(r.Sym), Code: 'U'}
|
||||||
|
if s.Version != 0 {
|
||||||
|
// should not happen but handle anyway
|
||||||
|
sym.Code = 'u'
|
||||||
|
}
|
||||||
|
syms = append(syms, sym)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return syms, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *goobjFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) {
|
||||||
|
// Should never be called. We implement Liner below, callers
|
||||||
|
// should use that instead.
|
||||||
|
return 0, nil, nil, fmt.Errorf("pcln not available in go object file")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find returns the file name, line, and function data for the given pc.
|
||||||
|
// Returns "",0,nil if unknown.
|
||||||
|
// This function implements the Liner interface in preference to pcln() above.
|
||||||
|
func (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) {
|
||||||
|
// TODO: this is really inefficient. Binary search? Memoize last result?
|
||||||
|
var arch *sys.Arch
|
||||||
|
for _, a := range sys.Archs {
|
||||||
|
if a.Name == f.goobj.Arch {
|
||||||
|
arch = a
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if arch == nil {
|
||||||
|
return "", 0, nil
|
||||||
|
}
|
||||||
|
for _, s := range f.goobj.Syms {
|
||||||
|
if pc < uint64(s.Data.Offset) || pc >= uint64(s.Data.Offset+s.Data.Size) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if s.Func == nil {
|
||||||
|
return "", 0, nil
|
||||||
|
}
|
||||||
|
pcfile := make([]byte, s.Func.PCFile.Size)
|
||||||
|
_, err := f.f.ReadAt(pcfile, s.Func.PCFile.Offset)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, nil
|
||||||
|
}
|
||||||
|
fileID := gosym.PCValue(pcfile, pc-uint64(s.Data.Offset), arch.MinLC)
|
||||||
|
fileName := s.Func.File[fileID]
|
||||||
|
pcline := make([]byte, s.Func.PCLine.Size)
|
||||||
|
_, err = f.f.ReadAt(pcline, s.Func.PCLine.Offset)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, nil
|
||||||
|
}
|
||||||
|
line := gosym.PCValue(pcline, pc-uint64(s.Data.Offset), arch.MinLC)
|
||||||
|
// Note: we provide only the name in the Func structure.
|
||||||
|
// We could provide more if needed.
|
||||||
|
return fileName, line, &gosym.Func{Sym: &gosym.Sym{Name: s.Name}}
|
||||||
|
}
|
||||||
|
return "", 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// We treat the whole object file as the text section.
|
||||||
|
func (f *goobjFile) text() (textStart uint64, text []byte, err error) {
|
||||||
|
var info os.FileInfo
|
||||||
|
info, err = f.f.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
text = make([]byte, info.Size())
|
||||||
|
_, err = f.f.ReadAt(text, 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *goobjFile) goarch() string {
|
||||||
|
return f.goobj.Arch
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *goobjFile) loadAddress() (uint64, error) {
|
||||||
|
return 0, fmt.Errorf("unknown load address")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *goobjFile) dwarf() (*dwarf.Data, error) {
|
||||||
|
return nil, errors.New("no DWARF data in go object file")
|
||||||
|
}
|
||||||
|
*/
|
134
vendor/github.com/google/gops/internal/objfile/macho.go
generated
vendored
Normal file
134
vendor/github.com/google/gops/internal/objfile/macho.go
generated
vendored
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Parsing of Mach-O executables (OS X).
|
||||||
|
|
||||||
|
package objfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"debug/dwarf"
|
||||||
|
"debug/macho"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
const stabTypeMask = 0xe0
|
||||||
|
|
||||||
|
type machoFile struct {
|
||||||
|
macho *macho.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func openMacho(r *os.File) (rawFile, error) {
|
||||||
|
f, err := macho.NewFile(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &machoFile{f}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *machoFile) symbols() ([]Sym, error) {
|
||||||
|
if f.macho.Symtab == nil {
|
||||||
|
return nil, fmt.Errorf("missing symbol table")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build sorted list of addresses of all symbols.
|
||||||
|
// We infer the size of a symbol by looking at where the next symbol begins.
|
||||||
|
var addrs []uint64
|
||||||
|
for _, s := range f.macho.Symtab.Syms {
|
||||||
|
// Skip stab debug info.
|
||||||
|
if s.Type&stabTypeMask == 0 {
|
||||||
|
addrs = append(addrs, s.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Sort(uint64s(addrs))
|
||||||
|
|
||||||
|
var syms []Sym
|
||||||
|
for _, s := range f.macho.Symtab.Syms {
|
||||||
|
if s.Type&stabTypeMask != 0 {
|
||||||
|
// Skip stab debug info.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sym := Sym{Name: s.Name, Addr: s.Value, Code: '?'}
|
||||||
|
i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value })
|
||||||
|
if i < len(addrs) {
|
||||||
|
sym.Size = int64(addrs[i] - s.Value)
|
||||||
|
}
|
||||||
|
if s.Sect == 0 {
|
||||||
|
sym.Code = 'U'
|
||||||
|
} else if int(s.Sect) <= len(f.macho.Sections) {
|
||||||
|
sect := f.macho.Sections[s.Sect-1]
|
||||||
|
switch sect.Seg {
|
||||||
|
case "__TEXT":
|
||||||
|
sym.Code = 'R'
|
||||||
|
case "__DATA":
|
||||||
|
sym.Code = 'D'
|
||||||
|
}
|
||||||
|
switch sect.Seg + " " + sect.Name {
|
||||||
|
case "__TEXT __text":
|
||||||
|
sym.Code = 'T'
|
||||||
|
case "__DATA __bss", "__DATA __noptrbss":
|
||||||
|
sym.Code = 'B'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
syms = append(syms, sym)
|
||||||
|
}
|
||||||
|
|
||||||
|
return syms, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *machoFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) {
|
||||||
|
if sect := f.macho.Section("__text"); sect != nil {
|
||||||
|
textStart = sect.Addr
|
||||||
|
}
|
||||||
|
if sect := f.macho.Section("__gosymtab"); sect != nil {
|
||||||
|
if symtab, err = sect.Data(); err != nil {
|
||||||
|
return 0, nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sect := f.macho.Section("__gopclntab"); sect != nil {
|
||||||
|
if pclntab, err = sect.Data(); err != nil {
|
||||||
|
return 0, nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return textStart, symtab, pclntab, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *machoFile) text() (textStart uint64, text []byte, err error) {
|
||||||
|
sect := f.macho.Section("__text")
|
||||||
|
if sect == nil {
|
||||||
|
return 0, nil, fmt.Errorf("text section not found")
|
||||||
|
}
|
||||||
|
textStart = sect.Addr
|
||||||
|
text, err = sect.Data()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *machoFile) goarch() string {
|
||||||
|
switch f.macho.Cpu {
|
||||||
|
case macho.Cpu386:
|
||||||
|
return "386"
|
||||||
|
case macho.CpuAmd64:
|
||||||
|
return "amd64"
|
||||||
|
case macho.CpuArm:
|
||||||
|
return "arm"
|
||||||
|
case macho.CpuPpc64:
|
||||||
|
return "ppc64"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
type uint64s []uint64
|
||||||
|
|
||||||
|
func (x uint64s) Len() int { return len(x) }
|
||||||
|
func (x uint64s) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||||
|
func (x uint64s) Less(i, j int) bool { return x[i] < x[j] }
|
||||||
|
|
||||||
|
func (f *machoFile) loadAddress() (uint64, error) {
|
||||||
|
return 0, fmt.Errorf("unknown load address")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *machoFile) dwarf() (*dwarf.Data, error) {
|
||||||
|
return f.macho.DWARF()
|
||||||
|
}
|
129
vendor/github.com/google/gops/internal/objfile/objfile.go
generated
vendored
Normal file
129
vendor/github.com/google/gops/internal/objfile/objfile.go
generated
vendored
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package objfile implements portable access to OS-specific executable files.
|
||||||
|
package objfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"debug/dwarf"
|
||||||
|
"debug/gosym"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
type rawFile interface {
|
||||||
|
symbols() (syms []Sym, err error)
|
||||||
|
pcln() (textStart uint64, symtab, pclntab []byte, err error)
|
||||||
|
text() (textStart uint64, text []byte, err error)
|
||||||
|
goarch() string
|
||||||
|
loadAddress() (uint64, error)
|
||||||
|
dwarf() (*dwarf.Data, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A File is an opened executable file.
|
||||||
|
type File struct {
|
||||||
|
r *os.File
|
||||||
|
raw rawFile
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Sym is a symbol defined in an executable file.
|
||||||
|
type Sym struct {
|
||||||
|
Name string // symbol name
|
||||||
|
Addr uint64 // virtual address of symbol
|
||||||
|
Size int64 // size in bytes
|
||||||
|
Code rune // nm code (T for text, D for data, and so on)
|
||||||
|
Type string // XXX?
|
||||||
|
Relocs []Reloc // in increasing Addr order
|
||||||
|
}
|
||||||
|
|
||||||
|
type Reloc struct {
|
||||||
|
Addr uint64 // Address of first byte that reloc applies to.
|
||||||
|
Size uint64 // Number of bytes
|
||||||
|
Stringer RelocStringer
|
||||||
|
}
|
||||||
|
|
||||||
|
type RelocStringer interface {
|
||||||
|
// insnOffset is the offset of the instruction containing the relocation
|
||||||
|
// from the start of the symbol containing the relocation.
|
||||||
|
String(insnOffset uint64) string
|
||||||
|
}
|
||||||
|
|
||||||
|
var openers = []func(*os.File) (rawFile, error){
|
||||||
|
openElf,
|
||||||
|
// openGoobj, // TODO(jbd): Bring it back when 1.8 is popular.
|
||||||
|
openMacho,
|
||||||
|
openPE,
|
||||||
|
openPlan9,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open opens the named file.
|
||||||
|
// The caller must call f.Close when the file is no longer needed.
|
||||||
|
func Open(name string) (*File, error) {
|
||||||
|
r, err := os.Open(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, try := range openers {
|
||||||
|
if raw, err := try(r); err == nil {
|
||||||
|
return &File{r, raw}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.Close()
|
||||||
|
return nil, fmt.Errorf("open %s: unrecognized object file", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) Close() error {
|
||||||
|
return f.r.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) Symbols() ([]Sym, error) {
|
||||||
|
syms, err := f.raw.symbols()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sort.Sort(byAddr(syms))
|
||||||
|
return syms, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type byAddr []Sym
|
||||||
|
|
||||||
|
func (x byAddr) Less(i, j int) bool { return x[i].Addr < x[j].Addr }
|
||||||
|
func (x byAddr) Len() int { return len(x) }
|
||||||
|
func (x byAddr) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||||
|
|
||||||
|
func (f *File) PCLineTable() (Liner, error) {
|
||||||
|
// If the raw file implements Liner directly, use that.
|
||||||
|
// Currently, only Go intermediate objects and archives (goobj) use this path.
|
||||||
|
if pcln, ok := f.raw.(Liner); ok {
|
||||||
|
return pcln, nil
|
||||||
|
}
|
||||||
|
// Otherwise, read the pcln tables and build a Liner out of that.
|
||||||
|
textStart, symtab, pclntab, err := f.raw.pcln()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return gosym.NewTable(symtab, gosym.NewLineTable(pclntab, textStart))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) Text() (uint64, []byte, error) {
|
||||||
|
return f.raw.text()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) GOARCH() string {
|
||||||
|
return f.raw.goarch()
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadAddress returns the expected load address of the file.
|
||||||
|
// This differs from the actual load address for a position-independent
|
||||||
|
// executable.
|
||||||
|
func (f *File) LoadAddress() (uint64, error) {
|
||||||
|
return f.raw.loadAddress()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DWARF returns DWARF debug data for the file, if any.
|
||||||
|
// This is for cmd/pprof to locate cgo functions.
|
||||||
|
func (f *File) DWARF() (*dwarf.Data, error) {
|
||||||
|
return f.raw.dwarf()
|
||||||
|
}
|
208
vendor/github.com/google/gops/internal/objfile/pe.go
generated
vendored
Normal file
208
vendor/github.com/google/gops/internal/objfile/pe.go
generated
vendored
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Parsing of PE executables (Microsoft Windows).
|
||||||
|
|
||||||
|
package objfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"debug/dwarf"
|
||||||
|
"debug/pe"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
type peFile struct {
|
||||||
|
pe *pe.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func openPE(r *os.File) (rawFile, error) {
|
||||||
|
f, err := pe.NewFile(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch f.OptionalHeader.(type) {
|
||||||
|
case *pe.OptionalHeader32, *pe.OptionalHeader64:
|
||||||
|
// ok
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unrecognized PE format")
|
||||||
|
}
|
||||||
|
return &peFile{f}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *peFile) symbols() ([]Sym, error) {
|
||||||
|
// Build sorted list of addresses of all symbols.
|
||||||
|
// We infer the size of a symbol by looking at where the next symbol begins.
|
||||||
|
var addrs []uint64
|
||||||
|
|
||||||
|
var imageBase uint64
|
||||||
|
switch oh := f.pe.OptionalHeader.(type) {
|
||||||
|
case *pe.OptionalHeader32:
|
||||||
|
imageBase = uint64(oh.ImageBase)
|
||||||
|
case *pe.OptionalHeader64:
|
||||||
|
imageBase = oh.ImageBase
|
||||||
|
}
|
||||||
|
|
||||||
|
var syms []Sym
|
||||||
|
for _, s := range f.pe.Symbols {
|
||||||
|
const (
|
||||||
|
N_UNDEF = 0 // An undefined (extern) symbol
|
||||||
|
N_ABS = -1 // An absolute symbol (e_value is a constant, not an address)
|
||||||
|
N_DEBUG = -2 // A debugging symbol
|
||||||
|
)
|
||||||
|
sym := Sym{Name: s.Name, Addr: uint64(s.Value), Code: '?'}
|
||||||
|
switch s.SectionNumber {
|
||||||
|
case N_UNDEF:
|
||||||
|
sym.Code = 'U'
|
||||||
|
case N_ABS:
|
||||||
|
sym.Code = 'C'
|
||||||
|
case N_DEBUG:
|
||||||
|
sym.Code = '?'
|
||||||
|
default:
|
||||||
|
if s.SectionNumber < 0 || len(f.pe.Sections) < int(s.SectionNumber) {
|
||||||
|
return nil, fmt.Errorf("invalid section number in symbol table")
|
||||||
|
}
|
||||||
|
sect := f.pe.Sections[s.SectionNumber-1]
|
||||||
|
const (
|
||||||
|
text = 0x20
|
||||||
|
data = 0x40
|
||||||
|
bss = 0x80
|
||||||
|
permW = 0x80000000
|
||||||
|
)
|
||||||
|
ch := sect.Characteristics
|
||||||
|
switch {
|
||||||
|
case ch&text != 0:
|
||||||
|
sym.Code = 'T'
|
||||||
|
case ch&data != 0:
|
||||||
|
if ch&permW == 0 {
|
||||||
|
sym.Code = 'R'
|
||||||
|
} else {
|
||||||
|
sym.Code = 'D'
|
||||||
|
}
|
||||||
|
case ch&bss != 0:
|
||||||
|
sym.Code = 'B'
|
||||||
|
}
|
||||||
|
sym.Addr += imageBase + uint64(sect.VirtualAddress)
|
||||||
|
}
|
||||||
|
syms = append(syms, sym)
|
||||||
|
addrs = append(addrs, sym.Addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(uint64s(addrs))
|
||||||
|
for i := range syms {
|
||||||
|
j := sort.Search(len(addrs), func(x int) bool { return addrs[x] > syms[i].Addr })
|
||||||
|
if j < len(addrs) {
|
||||||
|
syms[i].Size = int64(addrs[j] - syms[i].Addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return syms, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *peFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) {
|
||||||
|
var imageBase uint64
|
||||||
|
switch oh := f.pe.OptionalHeader.(type) {
|
||||||
|
case *pe.OptionalHeader32:
|
||||||
|
imageBase = uint64(oh.ImageBase)
|
||||||
|
case *pe.OptionalHeader64:
|
||||||
|
imageBase = oh.ImageBase
|
||||||
|
default:
|
||||||
|
return 0, nil, nil, fmt.Errorf("pe file format not recognized")
|
||||||
|
}
|
||||||
|
if sect := f.pe.Section(".text"); sect != nil {
|
||||||
|
textStart = imageBase + uint64(sect.VirtualAddress)
|
||||||
|
}
|
||||||
|
if pclntab, err = loadPETable(f.pe, "runtime.pclntab", "runtime.epclntab"); err != nil {
|
||||||
|
// We didn't find the symbols, so look for the names used in 1.3 and earlier.
|
||||||
|
// TODO: Remove code looking for the old symbols when we no longer care about 1.3.
|
||||||
|
var err2 error
|
||||||
|
if pclntab, err2 = loadPETable(f.pe, "pclntab", "epclntab"); err2 != nil {
|
||||||
|
return 0, nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if symtab, err = loadPETable(f.pe, "runtime.symtab", "runtime.esymtab"); err != nil {
|
||||||
|
// Same as above.
|
||||||
|
var err2 error
|
||||||
|
if symtab, err2 = loadPETable(f.pe, "symtab", "esymtab"); err2 != nil {
|
||||||
|
return 0, nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return textStart, symtab, pclntab, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *peFile) text() (textStart uint64, text []byte, err error) {
|
||||||
|
var imageBase uint64
|
||||||
|
switch oh := f.pe.OptionalHeader.(type) {
|
||||||
|
case *pe.OptionalHeader32:
|
||||||
|
imageBase = uint64(oh.ImageBase)
|
||||||
|
case *pe.OptionalHeader64:
|
||||||
|
imageBase = oh.ImageBase
|
||||||
|
default:
|
||||||
|
return 0, nil, fmt.Errorf("pe file format not recognized")
|
||||||
|
}
|
||||||
|
sect := f.pe.Section(".text")
|
||||||
|
if sect == nil {
|
||||||
|
return 0, nil, fmt.Errorf("text section not found")
|
||||||
|
}
|
||||||
|
textStart = imageBase + uint64(sect.VirtualAddress)
|
||||||
|
text, err = sect.Data()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func findPESymbol(f *pe.File, name string) (*pe.Symbol, error) {
|
||||||
|
for _, s := range f.Symbols {
|
||||||
|
if s.Name != name {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if s.SectionNumber <= 0 {
|
||||||
|
return nil, fmt.Errorf("symbol %s: invalid section number %d", name, s.SectionNumber)
|
||||||
|
}
|
||||||
|
if len(f.Sections) < int(s.SectionNumber) {
|
||||||
|
return nil, fmt.Errorf("symbol %s: section number %d is larger than max %d", name, s.SectionNumber, len(f.Sections))
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("no %s symbol found", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadPETable(f *pe.File, sname, ename string) ([]byte, error) {
|
||||||
|
ssym, err := findPESymbol(f, sname)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
esym, err := findPESymbol(f, ename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if ssym.SectionNumber != esym.SectionNumber {
|
||||||
|
return nil, fmt.Errorf("%s and %s symbols must be in the same section", sname, ename)
|
||||||
|
}
|
||||||
|
sect := f.Sections[ssym.SectionNumber-1]
|
||||||
|
data, err := sect.Data()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data[ssym.Value:esym.Value], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *peFile) goarch() string {
|
||||||
|
// Not sure how to get the info we want from PE header.
|
||||||
|
// Look in symbol table for telltale rt0 symbol.
|
||||||
|
if _, err := findPESymbol(f.pe, "_rt0_386_windows"); err == nil {
|
||||||
|
return "386"
|
||||||
|
}
|
||||||
|
if _, err := findPESymbol(f.pe, "_rt0_amd64_windows"); err == nil {
|
||||||
|
return "amd64"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *peFile) loadAddress() (uint64, error) {
|
||||||
|
return 0, fmt.Errorf("unknown load address")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *peFile) dwarf() (*dwarf.Data, error) {
|
||||||
|
return f.pe.DWARF()
|
||||||
|
}
|
156
vendor/github.com/google/gops/internal/objfile/plan9obj.go
generated
vendored
Normal file
156
vendor/github.com/google/gops/internal/objfile/plan9obj.go
generated
vendored
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Parsing of Plan 9 a.out executables.
|
||||||
|
|
||||||
|
package objfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"debug/dwarf"
|
||||||
|
"debug/plan9obj"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
var validSymType = map[rune]bool{
|
||||||
|
'T': true,
|
||||||
|
't': true,
|
||||||
|
'D': true,
|
||||||
|
'd': true,
|
||||||
|
'B': true,
|
||||||
|
'b': true,
|
||||||
|
}
|
||||||
|
|
||||||
|
type plan9File struct {
|
||||||
|
plan9 *plan9obj.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func openPlan9(r *os.File) (rawFile, error) {
|
||||||
|
f, err := plan9obj.NewFile(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &plan9File{f}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *plan9File) symbols() ([]Sym, error) {
|
||||||
|
plan9Syms, err := f.plan9.Symbols()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build sorted list of addresses of all symbols.
|
||||||
|
// We infer the size of a symbol by looking at where the next symbol begins.
|
||||||
|
var addrs []uint64
|
||||||
|
for _, s := range plan9Syms {
|
||||||
|
if !validSymType[s.Type] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
addrs = append(addrs, s.Value)
|
||||||
|
}
|
||||||
|
sort.Sort(uint64s(addrs))
|
||||||
|
|
||||||
|
var syms []Sym
|
||||||
|
|
||||||
|
for _, s := range plan9Syms {
|
||||||
|
if !validSymType[s.Type] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sym := Sym{Addr: s.Value, Name: s.Name, Code: s.Type}
|
||||||
|
i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value })
|
||||||
|
if i < len(addrs) {
|
||||||
|
sym.Size = int64(addrs[i] - s.Value)
|
||||||
|
}
|
||||||
|
syms = append(syms, sym)
|
||||||
|
}
|
||||||
|
|
||||||
|
return syms, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *plan9File) pcln() (textStart uint64, symtab, pclntab []byte, err error) {
|
||||||
|
textStart = f.plan9.LoadAddress + f.plan9.HdrSize
|
||||||
|
if pclntab, err = loadPlan9Table(f.plan9, "runtime.pclntab", "runtime.epclntab"); err != nil {
|
||||||
|
// We didn't find the symbols, so look for the names used in 1.3 and earlier.
|
||||||
|
// TODO: Remove code looking for the old symbols when we no longer care about 1.3.
|
||||||
|
var err2 error
|
||||||
|
if pclntab, err2 = loadPlan9Table(f.plan9, "pclntab", "epclntab"); err2 != nil {
|
||||||
|
return 0, nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if symtab, err = loadPlan9Table(f.plan9, "runtime.symtab", "runtime.esymtab"); err != nil {
|
||||||
|
// Same as above.
|
||||||
|
var err2 error
|
||||||
|
if symtab, err2 = loadPlan9Table(f.plan9, "symtab", "esymtab"); err2 != nil {
|
||||||
|
return 0, nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return textStart, symtab, pclntab, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *plan9File) text() (textStart uint64, text []byte, err error) {
|
||||||
|
sect := f.plan9.Section("text")
|
||||||
|
if sect == nil {
|
||||||
|
return 0, nil, fmt.Errorf("text section not found")
|
||||||
|
}
|
||||||
|
textStart = f.plan9.LoadAddress + f.plan9.HdrSize
|
||||||
|
text, err = sect.Data()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func findPlan9Symbol(f *plan9obj.File, name string) (*plan9obj.Sym, error) {
|
||||||
|
syms, err := f.Symbols()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, s := range syms {
|
||||||
|
if s.Name != name {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return &s, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("no %s symbol found", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadPlan9Table(f *plan9obj.File, sname, ename string) ([]byte, error) {
|
||||||
|
ssym, err := findPlan9Symbol(f, sname)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
esym, err := findPlan9Symbol(f, ename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sect := f.Section("text")
|
||||||
|
if sect == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
data, err := sect.Data()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
textStart := f.LoadAddress + f.HdrSize
|
||||||
|
return data[ssym.Value-textStart : esym.Value-textStart], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *plan9File) goarch() string {
|
||||||
|
switch f.plan9.Magic {
|
||||||
|
case plan9obj.Magic386:
|
||||||
|
return "386"
|
||||||
|
case plan9obj.MagicAMD64:
|
||||||
|
return "amd64"
|
||||||
|
case plan9obj.MagicARM:
|
||||||
|
return "arm"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *plan9File) loadAddress() (uint64, error) {
|
||||||
|
return 0, fmt.Errorf("unknown load address")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *plan9File) dwarf() (*dwarf.Data, error) {
|
||||||
|
return nil, errors.New("no DWARF data in Plan 9 file")
|
||||||
|
}
|
161
vendor/github.com/google/gops/internal/sys/arch.go
generated
vendored
Normal file
161
vendor/github.com/google/gops/internal/sys/arch.go
generated
vendored
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package sys
|
||||||
|
|
||||||
|
import "encoding/binary"
|
||||||
|
|
||||||
|
// ArchFamily represents a family of one or more related architectures.
|
||||||
|
// For example, amd64 and amd64p32 are both members of the AMD64 family,
|
||||||
|
// and ppc64 and ppc64le are both members of the PPC64 family.
|
||||||
|
type ArchFamily byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
AMD64 ArchFamily = iota
|
||||||
|
ARM
|
||||||
|
ARM64
|
||||||
|
I386
|
||||||
|
MIPS64
|
||||||
|
PPC64
|
||||||
|
S390X
|
||||||
|
)
|
||||||
|
|
||||||
|
// Arch represents an individual architecture.
|
||||||
|
type Arch struct {
|
||||||
|
Name string
|
||||||
|
Family ArchFamily
|
||||||
|
|
||||||
|
ByteOrder binary.ByteOrder
|
||||||
|
|
||||||
|
IntSize int
|
||||||
|
PtrSize int
|
||||||
|
RegSize int
|
||||||
|
|
||||||
|
// MinLC is the minimum length of an instruction code.
|
||||||
|
MinLC int
|
||||||
|
}
|
||||||
|
|
||||||
|
// InFamily reports whether a is a member of any of the specified
|
||||||
|
// architecture families.
|
||||||
|
func (a *Arch) InFamily(xs ...ArchFamily) bool {
|
||||||
|
for _, x := range xs {
|
||||||
|
if a.Family == x {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var Arch386 = &Arch{
|
||||||
|
Name: "386",
|
||||||
|
Family: I386,
|
||||||
|
ByteOrder: binary.LittleEndian,
|
||||||
|
IntSize: 4,
|
||||||
|
PtrSize: 4,
|
||||||
|
RegSize: 4,
|
||||||
|
MinLC: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
var ArchAMD64 = &Arch{
|
||||||
|
Name: "amd64",
|
||||||
|
Family: AMD64,
|
||||||
|
ByteOrder: binary.LittleEndian,
|
||||||
|
IntSize: 8,
|
||||||
|
PtrSize: 8,
|
||||||
|
RegSize: 8,
|
||||||
|
MinLC: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
var ArchAMD64P32 = &Arch{
|
||||||
|
Name: "amd64p32",
|
||||||
|
Family: AMD64,
|
||||||
|
ByteOrder: binary.LittleEndian,
|
||||||
|
IntSize: 4,
|
||||||
|
PtrSize: 4,
|
||||||
|
RegSize: 8,
|
||||||
|
MinLC: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
var ArchARM = &Arch{
|
||||||
|
Name: "arm",
|
||||||
|
Family: ARM,
|
||||||
|
ByteOrder: binary.LittleEndian,
|
||||||
|
IntSize: 4,
|
||||||
|
PtrSize: 4,
|
||||||
|
RegSize: 4,
|
||||||
|
MinLC: 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
var ArchARM64 = &Arch{
|
||||||
|
Name: "arm64",
|
||||||
|
Family: ARM64,
|
||||||
|
ByteOrder: binary.LittleEndian,
|
||||||
|
IntSize: 8,
|
||||||
|
PtrSize: 8,
|
||||||
|
RegSize: 8,
|
||||||
|
MinLC: 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
var ArchMIPS64 = &Arch{
|
||||||
|
Name: "mips64",
|
||||||
|
Family: MIPS64,
|
||||||
|
ByteOrder: binary.BigEndian,
|
||||||
|
IntSize: 8,
|
||||||
|
PtrSize: 8,
|
||||||
|
RegSize: 8,
|
||||||
|
MinLC: 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
var ArchMIPS64LE = &Arch{
|
||||||
|
Name: "mips64le",
|
||||||
|
Family: MIPS64,
|
||||||
|
ByteOrder: binary.LittleEndian,
|
||||||
|
IntSize: 8,
|
||||||
|
PtrSize: 8,
|
||||||
|
RegSize: 8,
|
||||||
|
MinLC: 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
var ArchPPC64 = &Arch{
|
||||||
|
Name: "ppc64",
|
||||||
|
Family: PPC64,
|
||||||
|
ByteOrder: binary.BigEndian,
|
||||||
|
IntSize: 8,
|
||||||
|
PtrSize: 8,
|
||||||
|
RegSize: 8,
|
||||||
|
MinLC: 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
var ArchPPC64LE = &Arch{
|
||||||
|
Name: "ppc64le",
|
||||||
|
Family: PPC64,
|
||||||
|
ByteOrder: binary.LittleEndian,
|
||||||
|
IntSize: 8,
|
||||||
|
PtrSize: 8,
|
||||||
|
RegSize: 8,
|
||||||
|
MinLC: 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
var ArchS390X = &Arch{
|
||||||
|
Name: "s390x",
|
||||||
|
Family: S390X,
|
||||||
|
ByteOrder: binary.BigEndian,
|
||||||
|
IntSize: 8,
|
||||||
|
PtrSize: 8,
|
||||||
|
RegSize: 8,
|
||||||
|
MinLC: 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
var Archs = [...]*Arch{
|
||||||
|
Arch386,
|
||||||
|
ArchAMD64,
|
||||||
|
ArchAMD64P32,
|
||||||
|
ArchARM,
|
||||||
|
ArchARM64,
|
||||||
|
ArchMIPS64,
|
||||||
|
ArchMIPS64LE,
|
||||||
|
ArchPPC64,
|
||||||
|
ArchPPC64LE,
|
||||||
|
ArchS390X,
|
||||||
|
}
|
27
vendor/github.com/google/gops/signal/LICENSE
generated
vendored
Normal file
27
vendor/github.com/google/gops/signal/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2016 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
35
vendor/github.com/google/gops/signal/signal.go
generated
vendored
Normal file
35
vendor/github.com/google/gops/signal/signal.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package signal contains signals used to communicate to the gops agents.
|
||||||
|
package signal
|
||||||
|
|
||||||
|
const (
|
||||||
|
// StackTrace represents a command to print stack trace.
|
||||||
|
StackTrace = byte(0x1)
|
||||||
|
|
||||||
|
// GC runs the garbage collector.
|
||||||
|
GC = byte(0x2)
|
||||||
|
|
||||||
|
// MemStats reports memory stats.
|
||||||
|
MemStats = byte(0x3)
|
||||||
|
|
||||||
|
// Version prints the Go version.
|
||||||
|
Version = byte(0x4)
|
||||||
|
|
||||||
|
// HeapProfile starts `go tool pprof` with the current memory profile.
|
||||||
|
HeapProfile = byte(0x5)
|
||||||
|
|
||||||
|
// CPUProfile starts `go tool pprof` with the current CPU profile
|
||||||
|
CPUProfile = byte(0x6)
|
||||||
|
|
||||||
|
// Stats returns Go runtime statistics such as number of goroutines, GOMAXPROCS, and NumCPU.
|
||||||
|
Stats = byte(0x7)
|
||||||
|
|
||||||
|
// Trace starts the Go execution tracer, waits 5 seconds and launches the trace tool.
|
||||||
|
Trace = byte(0x8)
|
||||||
|
|
||||||
|
// BinaryDump returns running binary file.
|
||||||
|
BinaryDump = byte(0x9)
|
||||||
|
)
|
27
vendor/golang.org/x/arch/arm/armasm/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/arch/arm/armasm/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2015 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
567
vendor/golang.org/x/arch/arm/armasm/decode.go
generated
vendored
Normal file
567
vendor/golang.org/x/arch/arm/armasm/decode.go
generated
vendored
Normal file
@ -0,0 +1,567 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package armasm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// An instFormat describes the format of an instruction encoding.
|
||||||
|
// An instruction with 32-bit value x matches the format if x&mask == value
|
||||||
|
// and the condition matches.
|
||||||
|
// The condition matches if x>>28 == 0xF && value>>28==0xF
|
||||||
|
// or if x>>28 != 0xF and value>>28 == 0.
|
||||||
|
// If x matches the format, then the rest of the fields describe how to interpret x.
|
||||||
|
// The opBits describe bits that should be extracted from x and added to the opcode.
|
||||||
|
// For example opBits = 0x1234 means that the value
|
||||||
|
// (2 bits at offset 1) followed by (4 bits at offset 3)
|
||||||
|
// should be added to op.
|
||||||
|
// Finally the args describe how to decode the instruction arguments.
|
||||||
|
// args is stored as a fixed-size array; if there are fewer than len(args) arguments,
|
||||||
|
// args[i] == 0 marks the end of the argument list.
|
||||||
|
type instFormat struct {
|
||||||
|
mask uint32
|
||||||
|
value uint32
|
||||||
|
priority int8
|
||||||
|
op Op
|
||||||
|
opBits uint64
|
||||||
|
args instArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
type instArgs [4]instArg
|
||||||
|
|
||||||
|
var (
|
||||||
|
errMode = fmt.Errorf("unsupported execution mode")
|
||||||
|
errShort = fmt.Errorf("truncated instruction")
|
||||||
|
errUnknown = fmt.Errorf("unknown instruction")
|
||||||
|
)
|
||||||
|
|
||||||
|
var decoderCover []bool
|
||||||
|
|
||||||
|
// Decode decodes the leading bytes in src as a single instruction.
|
||||||
|
func Decode(src []byte, mode Mode) (inst Inst, err error) {
|
||||||
|
if mode != ModeARM {
|
||||||
|
return Inst{}, errMode
|
||||||
|
}
|
||||||
|
if len(src) < 4 {
|
||||||
|
return Inst{}, errShort
|
||||||
|
}
|
||||||
|
|
||||||
|
if decoderCover == nil {
|
||||||
|
decoderCover = make([]bool, len(instFormats))
|
||||||
|
}
|
||||||
|
|
||||||
|
x := binary.LittleEndian.Uint32(src)
|
||||||
|
|
||||||
|
// The instFormat table contains both conditional and unconditional instructions.
|
||||||
|
// Considering only the top 4 bits, the conditional instructions use mask=0, value=0,
|
||||||
|
// while the unconditional instructions use mask=f, value=f.
|
||||||
|
// Prepare a version of x with the condition cleared to 0 in conditional instructions
|
||||||
|
// and then assume mask=f during matching.
|
||||||
|
const condMask = 0xf0000000
|
||||||
|
xNoCond := x
|
||||||
|
if x&condMask != condMask {
|
||||||
|
xNoCond &^= condMask
|
||||||
|
}
|
||||||
|
var priority int8
|
||||||
|
Search:
|
||||||
|
for i := range instFormats {
|
||||||
|
f := &instFormats[i]
|
||||||
|
if xNoCond&(f.mask|condMask) != f.value || f.priority <= priority {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
delta := uint32(0)
|
||||||
|
deltaShift := uint(0)
|
||||||
|
for opBits := f.opBits; opBits != 0; opBits >>= 16 {
|
||||||
|
n := uint(opBits & 0xFF)
|
||||||
|
off := uint((opBits >> 8) & 0xFF)
|
||||||
|
delta |= (x >> off) & (1<<n - 1) << deltaShift
|
||||||
|
deltaShift += n
|
||||||
|
}
|
||||||
|
op := f.op + Op(delta)
|
||||||
|
|
||||||
|
// Special case: BKPT encodes with condition but cannot have one.
|
||||||
|
if op&^15 == BKPT_EQ && op != BKPT {
|
||||||
|
continue Search
|
||||||
|
}
|
||||||
|
|
||||||
|
var args Args
|
||||||
|
for j, aop := range f.args {
|
||||||
|
if aop == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
arg := decodeArg(aop, x)
|
||||||
|
if arg == nil { // cannot decode argument
|
||||||
|
continue Search
|
||||||
|
}
|
||||||
|
args[j] = arg
|
||||||
|
}
|
||||||
|
|
||||||
|
decoderCover[i] = true
|
||||||
|
|
||||||
|
inst = Inst{
|
||||||
|
Op: op,
|
||||||
|
Args: args,
|
||||||
|
Enc: x,
|
||||||
|
Len: 4,
|
||||||
|
}
|
||||||
|
priority = f.priority
|
||||||
|
continue Search
|
||||||
|
}
|
||||||
|
if inst.Op != 0 {
|
||||||
|
return inst, nil
|
||||||
|
}
|
||||||
|
return Inst{}, errUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
// An instArg describes the encoding of a single argument.
|
||||||
|
// In the names used for arguments, _p_ means +, _m_ means -,
|
||||||
|
// _pm_ means ± (usually keyed by the U bit).
|
||||||
|
// The _W suffix indicates a general addressing mode based on the P and W bits.
|
||||||
|
// The _offset and _postindex suffixes force the given addressing mode.
|
||||||
|
// The rest should be somewhat self-explanatory, at least given
|
||||||
|
// the decodeArg function.
|
||||||
|
type instArg uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ instArg = iota
|
||||||
|
arg_APSR
|
||||||
|
arg_FPSCR
|
||||||
|
arg_Dn_half
|
||||||
|
arg_R1_0
|
||||||
|
arg_R1_12
|
||||||
|
arg_R2_0
|
||||||
|
arg_R2_12
|
||||||
|
arg_R_0
|
||||||
|
arg_R_12
|
||||||
|
arg_R_12_nzcv
|
||||||
|
arg_R_16
|
||||||
|
arg_R_16_WB
|
||||||
|
arg_R_8
|
||||||
|
arg_R_rotate
|
||||||
|
arg_R_shift_R
|
||||||
|
arg_R_shift_imm
|
||||||
|
arg_SP
|
||||||
|
arg_Sd
|
||||||
|
arg_Sd_Dd
|
||||||
|
arg_Dd_Sd
|
||||||
|
arg_Sm
|
||||||
|
arg_Sm_Dm
|
||||||
|
arg_Sn
|
||||||
|
arg_Sn_Dn
|
||||||
|
arg_const
|
||||||
|
arg_endian
|
||||||
|
arg_fbits
|
||||||
|
arg_fp_0
|
||||||
|
arg_imm24
|
||||||
|
arg_imm5
|
||||||
|
arg_imm5_32
|
||||||
|
arg_imm5_nz
|
||||||
|
arg_imm_12at8_4at0
|
||||||
|
arg_imm_4at16_12at0
|
||||||
|
arg_imm_vfp
|
||||||
|
arg_label24
|
||||||
|
arg_label24H
|
||||||
|
arg_label_m_12
|
||||||
|
arg_label_p_12
|
||||||
|
arg_label_pm_12
|
||||||
|
arg_label_pm_4_4
|
||||||
|
arg_lsb_width
|
||||||
|
arg_mem_R
|
||||||
|
arg_mem_R_pm_R_W
|
||||||
|
arg_mem_R_pm_R_postindex
|
||||||
|
arg_mem_R_pm_R_shift_imm_W
|
||||||
|
arg_mem_R_pm_R_shift_imm_offset
|
||||||
|
arg_mem_R_pm_R_shift_imm_postindex
|
||||||
|
arg_mem_R_pm_imm12_W
|
||||||
|
arg_mem_R_pm_imm12_offset
|
||||||
|
arg_mem_R_pm_imm12_postindex
|
||||||
|
arg_mem_R_pm_imm8_W
|
||||||
|
arg_mem_R_pm_imm8_postindex
|
||||||
|
arg_mem_R_pm_imm8at0_offset
|
||||||
|
arg_option
|
||||||
|
arg_registers
|
||||||
|
arg_registers1
|
||||||
|
arg_registers2
|
||||||
|
arg_satimm4
|
||||||
|
arg_satimm5
|
||||||
|
arg_satimm4m1
|
||||||
|
arg_satimm5m1
|
||||||
|
arg_widthm1
|
||||||
|
)
|
||||||
|
|
||||||
|
// decodeArg decodes the arg described by aop from the instruction bits x.
|
||||||
|
// It returns nil if x cannot be decoded according to aop.
|
||||||
|
func decodeArg(aop instArg, x uint32) Arg {
|
||||||
|
switch aop {
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
|
||||||
|
case arg_APSR:
|
||||||
|
return APSR
|
||||||
|
case arg_FPSCR:
|
||||||
|
return FPSCR
|
||||||
|
|
||||||
|
case arg_R_0:
|
||||||
|
return Reg(x & (1<<4 - 1))
|
||||||
|
case arg_R_8:
|
||||||
|
return Reg((x >> 8) & (1<<4 - 1))
|
||||||
|
case arg_R_12:
|
||||||
|
return Reg((x >> 12) & (1<<4 - 1))
|
||||||
|
case arg_R_16:
|
||||||
|
return Reg((x >> 16) & (1<<4 - 1))
|
||||||
|
|
||||||
|
case arg_R_12_nzcv:
|
||||||
|
r := Reg((x >> 12) & (1<<4 - 1))
|
||||||
|
if r == R15 {
|
||||||
|
return APSR_nzcv
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
|
||||||
|
case arg_R_16_WB:
|
||||||
|
mode := AddrLDM
|
||||||
|
if (x>>21)&1 != 0 {
|
||||||
|
mode = AddrLDM_WB
|
||||||
|
}
|
||||||
|
return Mem{Base: Reg((x >> 16) & (1<<4 - 1)), Mode: mode}
|
||||||
|
|
||||||
|
case arg_R_rotate:
|
||||||
|
Rm := Reg(x & (1<<4 - 1))
|
||||||
|
typ, count := decodeShift(x)
|
||||||
|
// ROR #0 here means ROR #0, but decodeShift rewrites to RRX #1.
|
||||||
|
if typ == RotateRightExt {
|
||||||
|
return Reg(Rm)
|
||||||
|
}
|
||||||
|
return RegShift{Rm, typ, uint8(count)}
|
||||||
|
|
||||||
|
case arg_R_shift_R:
|
||||||
|
Rm := Reg(x & (1<<4 - 1))
|
||||||
|
Rs := Reg((x >> 8) & (1<<4 - 1))
|
||||||
|
typ := Shift((x >> 5) & (1<<2 - 1))
|
||||||
|
return RegShiftReg{Rm, typ, Rs}
|
||||||
|
|
||||||
|
case arg_R_shift_imm:
|
||||||
|
Rm := Reg(x & (1<<4 - 1))
|
||||||
|
typ, count := decodeShift(x)
|
||||||
|
if typ == ShiftLeft && count == 0 {
|
||||||
|
return Reg(Rm)
|
||||||
|
}
|
||||||
|
return RegShift{Rm, typ, uint8(count)}
|
||||||
|
|
||||||
|
case arg_R1_0:
|
||||||
|
return Reg((x & (1<<4 - 1)))
|
||||||
|
case arg_R1_12:
|
||||||
|
return Reg(((x >> 12) & (1<<4 - 1)))
|
||||||
|
case arg_R2_0:
|
||||||
|
return Reg((x & (1<<4 - 1)) | 1)
|
||||||
|
case arg_R2_12:
|
||||||
|
return Reg(((x >> 12) & (1<<4 - 1)) | 1)
|
||||||
|
|
||||||
|
case arg_SP:
|
||||||
|
return SP
|
||||||
|
|
||||||
|
case arg_Sd_Dd:
|
||||||
|
v := (x >> 12) & (1<<4 - 1)
|
||||||
|
vx := (x >> 22) & 1
|
||||||
|
sz := (x >> 8) & 1
|
||||||
|
if sz != 0 {
|
||||||
|
return D0 + Reg(vx<<4+v)
|
||||||
|
} else {
|
||||||
|
return S0 + Reg(v<<1+vx)
|
||||||
|
}
|
||||||
|
|
||||||
|
case arg_Dd_Sd:
|
||||||
|
return decodeArg(arg_Sd_Dd, x^(1<<8))
|
||||||
|
|
||||||
|
case arg_Sd:
|
||||||
|
v := (x >> 12) & (1<<4 - 1)
|
||||||
|
vx := (x >> 22) & 1
|
||||||
|
return S0 + Reg(v<<1+vx)
|
||||||
|
|
||||||
|
case arg_Sm_Dm:
|
||||||
|
v := (x >> 0) & (1<<4 - 1)
|
||||||
|
vx := (x >> 5) & 1
|
||||||
|
sz := (x >> 8) & 1
|
||||||
|
if sz != 0 {
|
||||||
|
return D0 + Reg(vx<<4+v)
|
||||||
|
} else {
|
||||||
|
return S0 + Reg(v<<1+vx)
|
||||||
|
}
|
||||||
|
|
||||||
|
case arg_Sm:
|
||||||
|
v := (x >> 0) & (1<<4 - 1)
|
||||||
|
vx := (x >> 5) & 1
|
||||||
|
return S0 + Reg(v<<1+vx)
|
||||||
|
|
||||||
|
case arg_Dn_half:
|
||||||
|
v := (x >> 16) & (1<<4 - 1)
|
||||||
|
vx := (x >> 7) & 1
|
||||||
|
return RegX{D0 + Reg(vx<<4+v), int((x >> 21) & 1)}
|
||||||
|
|
||||||
|
case arg_Sn_Dn:
|
||||||
|
v := (x >> 16) & (1<<4 - 1)
|
||||||
|
vx := (x >> 7) & 1
|
||||||
|
sz := (x >> 8) & 1
|
||||||
|
if sz != 0 {
|
||||||
|
return D0 + Reg(vx<<4+v)
|
||||||
|
} else {
|
||||||
|
return S0 + Reg(v<<1+vx)
|
||||||
|
}
|
||||||
|
|
||||||
|
case arg_Sn:
|
||||||
|
v := (x >> 16) & (1<<4 - 1)
|
||||||
|
vx := (x >> 7) & 1
|
||||||
|
return S0 + Reg(v<<1+vx)
|
||||||
|
|
||||||
|
case arg_const:
|
||||||
|
v := x & (1<<8 - 1)
|
||||||
|
rot := (x >> 8) & (1<<4 - 1) * 2
|
||||||
|
if rot > 0 && v&3 == 0 {
|
||||||
|
// could rotate less
|
||||||
|
return ImmAlt{uint8(v), uint8(rot)}
|
||||||
|
}
|
||||||
|
if rot >= 24 && ((v<<(32-rot))&0xFF)>>(32-rot) == v {
|
||||||
|
// could wrap around to rot==0.
|
||||||
|
return ImmAlt{uint8(v), uint8(rot)}
|
||||||
|
}
|
||||||
|
return Imm(v>>rot | v<<(32-rot))
|
||||||
|
|
||||||
|
case arg_endian:
|
||||||
|
return Endian((x >> 9) & 1)
|
||||||
|
|
||||||
|
case arg_fbits:
|
||||||
|
return Imm((16 << ((x >> 7) & 1)) - ((x&(1<<4-1))<<1 | (x>>5)&1))
|
||||||
|
|
||||||
|
case arg_fp_0:
|
||||||
|
return Imm(0)
|
||||||
|
|
||||||
|
case arg_imm24:
|
||||||
|
return Imm(x & (1<<24 - 1))
|
||||||
|
|
||||||
|
case arg_imm5:
|
||||||
|
return Imm((x >> 7) & (1<<5 - 1))
|
||||||
|
|
||||||
|
case arg_imm5_32:
|
||||||
|
x = (x >> 7) & (1<<5 - 1)
|
||||||
|
if x == 0 {
|
||||||
|
x = 32
|
||||||
|
}
|
||||||
|
return Imm(x)
|
||||||
|
|
||||||
|
case arg_imm5_nz:
|
||||||
|
x = (x >> 7) & (1<<5 - 1)
|
||||||
|
if x == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return Imm(x)
|
||||||
|
|
||||||
|
case arg_imm_4at16_12at0:
|
||||||
|
return Imm((x>>16)&(1<<4-1)<<12 | x&(1<<12-1))
|
||||||
|
|
||||||
|
case arg_imm_12at8_4at0:
|
||||||
|
return Imm((x>>8)&(1<<12-1)<<4 | x&(1<<4-1))
|
||||||
|
|
||||||
|
case arg_imm_vfp:
|
||||||
|
x = (x>>16)&(1<<4-1)<<4 | x&(1<<4-1)
|
||||||
|
return Imm(x)
|
||||||
|
|
||||||
|
case arg_label24:
|
||||||
|
imm := (x & (1<<24 - 1)) << 2
|
||||||
|
return PCRel(int32(imm<<6) >> 6)
|
||||||
|
|
||||||
|
case arg_label24H:
|
||||||
|
h := (x >> 24) & 1
|
||||||
|
imm := (x&(1<<24-1))<<2 | h<<1
|
||||||
|
return PCRel(int32(imm<<6) >> 6)
|
||||||
|
|
||||||
|
case arg_label_m_12:
|
||||||
|
d := int32(x & (1<<12 - 1))
|
||||||
|
return Mem{Base: PC, Mode: AddrOffset, Offset: int16(-d)}
|
||||||
|
|
||||||
|
case arg_label_p_12:
|
||||||
|
d := int32(x & (1<<12 - 1))
|
||||||
|
return Mem{Base: PC, Mode: AddrOffset, Offset: int16(d)}
|
||||||
|
|
||||||
|
case arg_label_pm_12:
|
||||||
|
d := int32(x & (1<<12 - 1))
|
||||||
|
u := (x >> 23) & 1
|
||||||
|
if u == 0 {
|
||||||
|
d = -d
|
||||||
|
}
|
||||||
|
return Mem{Base: PC, Mode: AddrOffset, Offset: int16(d)}
|
||||||
|
|
||||||
|
case arg_label_pm_4_4:
|
||||||
|
d := int32((x>>8)&(1<<4-1)<<4 | x&(1<<4-1))
|
||||||
|
u := (x >> 23) & 1
|
||||||
|
if u == 0 {
|
||||||
|
d = -d
|
||||||
|
}
|
||||||
|
return PCRel(d)
|
||||||
|
|
||||||
|
case arg_lsb_width:
|
||||||
|
lsb := (x >> 7) & (1<<5 - 1)
|
||||||
|
msb := (x >> 16) & (1<<5 - 1)
|
||||||
|
if msb < lsb || msb >= 32 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return Imm(msb + 1 - lsb)
|
||||||
|
|
||||||
|
case arg_mem_R:
|
||||||
|
Rn := Reg((x >> 16) & (1<<4 - 1))
|
||||||
|
return Mem{Base: Rn, Mode: AddrOffset}
|
||||||
|
|
||||||
|
case arg_mem_R_pm_R_postindex:
|
||||||
|
// Treat [<Rn>],+/-<Rm> like [<Rn>,+/-<Rm>{,<shift>}]{!}
|
||||||
|
// by forcing shift bits to <<0 and P=0, W=0 (postindex=true).
|
||||||
|
return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5|1<<24|1<<21))
|
||||||
|
|
||||||
|
case arg_mem_R_pm_R_W:
|
||||||
|
// Treat [<Rn>,+/-<Rm>]{!} like [<Rn>,+/-<Rm>{,<shift>}]{!}
|
||||||
|
// by forcing shift bits to <<0.
|
||||||
|
return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5))
|
||||||
|
|
||||||
|
case arg_mem_R_pm_R_shift_imm_offset:
|
||||||
|
// Treat [<Rn>],+/-<Rm>{,<shift>} like [<Rn>,+/-<Rm>{,<shift>}]{!}
|
||||||
|
// by forcing P=1, W=0 (index=false, wback=false).
|
||||||
|
return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^(1<<21)|1<<24)
|
||||||
|
|
||||||
|
case arg_mem_R_pm_R_shift_imm_postindex:
|
||||||
|
// Treat [<Rn>],+/-<Rm>{,<shift>} like [<Rn>,+/-<Rm>{,<shift>}]{!}
|
||||||
|
// by forcing P=0, W=0 (postindex=true).
|
||||||
|
return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^(1<<24|1<<21))
|
||||||
|
|
||||||
|
case arg_mem_R_pm_R_shift_imm_W:
|
||||||
|
Rn := Reg((x >> 16) & (1<<4 - 1))
|
||||||
|
Rm := Reg(x & (1<<4 - 1))
|
||||||
|
typ, count := decodeShift(x)
|
||||||
|
u := (x >> 23) & 1
|
||||||
|
w := (x >> 21) & 1
|
||||||
|
p := (x >> 24) & 1
|
||||||
|
if p == 0 && w == 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
sign := int8(+1)
|
||||||
|
if u == 0 {
|
||||||
|
sign = -1
|
||||||
|
}
|
||||||
|
mode := AddrMode(uint8(p<<1) | uint8(w^1))
|
||||||
|
return Mem{Base: Rn, Mode: mode, Sign: sign, Index: Rm, Shift: typ, Count: count}
|
||||||
|
|
||||||
|
case arg_mem_R_pm_imm12_offset:
|
||||||
|
// Treat [<Rn>,#+/-<imm12>] like [<Rn>{,#+/-<imm12>}]{!}
|
||||||
|
// by forcing P=1, W=0 (index=false, wback=false).
|
||||||
|
return decodeArg(arg_mem_R_pm_imm12_W, x&^(1<<21)|1<<24)
|
||||||
|
|
||||||
|
case arg_mem_R_pm_imm12_postindex:
|
||||||
|
// Treat [<Rn>],#+/-<imm12> like [<Rn>{,#+/-<imm12>}]{!}
|
||||||
|
// by forcing P=0, W=0 (postindex=true).
|
||||||
|
return decodeArg(arg_mem_R_pm_imm12_W, x&^(1<<24|1<<21))
|
||||||
|
|
||||||
|
case arg_mem_R_pm_imm12_W:
|
||||||
|
Rn := Reg((x >> 16) & (1<<4 - 1))
|
||||||
|
u := (x >> 23) & 1
|
||||||
|
w := (x >> 21) & 1
|
||||||
|
p := (x >> 24) & 1
|
||||||
|
if p == 0 && w == 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
sign := int8(+1)
|
||||||
|
if u == 0 {
|
||||||
|
sign = -1
|
||||||
|
}
|
||||||
|
imm := int16(x & (1<<12 - 1))
|
||||||
|
mode := AddrMode(uint8(p<<1) | uint8(w^1))
|
||||||
|
return Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm}
|
||||||
|
|
||||||
|
case arg_mem_R_pm_imm8_postindex:
|
||||||
|
// Treat [<Rn>],#+/-<imm8> like [<Rn>{,#+/-<imm8>}]{!}
|
||||||
|
// by forcing P=0, W=0 (postindex=true).
|
||||||
|
return decodeArg(arg_mem_R_pm_imm8_W, x&^(1<<24|1<<21))
|
||||||
|
|
||||||
|
case arg_mem_R_pm_imm8_W:
|
||||||
|
Rn := Reg((x >> 16) & (1<<4 - 1))
|
||||||
|
u := (x >> 23) & 1
|
||||||
|
w := (x >> 21) & 1
|
||||||
|
p := (x >> 24) & 1
|
||||||
|
if p == 0 && w == 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
sign := int8(+1)
|
||||||
|
if u == 0 {
|
||||||
|
sign = -1
|
||||||
|
}
|
||||||
|
imm := int16((x>>8)&(1<<4-1)<<4 | x&(1<<4-1))
|
||||||
|
mode := AddrMode(uint8(p<<1) | uint8(w^1))
|
||||||
|
return Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm}
|
||||||
|
|
||||||
|
case arg_mem_R_pm_imm8at0_offset:
|
||||||
|
Rn := Reg((x >> 16) & (1<<4 - 1))
|
||||||
|
u := (x >> 23) & 1
|
||||||
|
sign := int8(+1)
|
||||||
|
if u == 0 {
|
||||||
|
sign = -1
|
||||||
|
}
|
||||||
|
imm := int16(x&(1<<8-1)) << 2
|
||||||
|
return Mem{Base: Rn, Mode: AddrOffset, Offset: int16(sign) * imm}
|
||||||
|
|
||||||
|
case arg_option:
|
||||||
|
return Imm(x & (1<<4 - 1))
|
||||||
|
|
||||||
|
case arg_registers:
|
||||||
|
return RegList(x & (1<<16 - 1))
|
||||||
|
|
||||||
|
case arg_registers2:
|
||||||
|
x &= 1<<16 - 1
|
||||||
|
n := 0
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
if x>>uint(i)&1 != 0 {
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if n < 2 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return RegList(x)
|
||||||
|
|
||||||
|
case arg_registers1:
|
||||||
|
Rt := (x >> 12) & (1<<4 - 1)
|
||||||
|
return RegList(1 << Rt)
|
||||||
|
|
||||||
|
case arg_satimm4:
|
||||||
|
return Imm((x >> 16) & (1<<4 - 1))
|
||||||
|
|
||||||
|
case arg_satimm5:
|
||||||
|
return Imm((x >> 16) & (1<<5 - 1))
|
||||||
|
|
||||||
|
case arg_satimm4m1:
|
||||||
|
return Imm((x>>16)&(1<<4-1) + 1)
|
||||||
|
|
||||||
|
case arg_satimm5m1:
|
||||||
|
return Imm((x>>16)&(1<<5-1) + 1)
|
||||||
|
|
||||||
|
case arg_widthm1:
|
||||||
|
return Imm((x>>16)&(1<<5-1) + 1)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodeShift decodes the shift-by-immediate encoded in x.
|
||||||
|
func decodeShift(x uint32) (Shift, uint8) {
|
||||||
|
count := (x >> 7) & (1<<5 - 1)
|
||||||
|
typ := Shift((x >> 5) & (1<<2 - 1))
|
||||||
|
switch typ {
|
||||||
|
case ShiftRight, ShiftRightSigned:
|
||||||
|
if count == 0 {
|
||||||
|
count = 32
|
||||||
|
}
|
||||||
|
case RotateRight:
|
||||||
|
if count == 0 {
|
||||||
|
typ = RotateRightExt
|
||||||
|
count = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typ, uint8(count)
|
||||||
|
}
|
164
vendor/golang.org/x/arch/arm/armasm/gnu.go
generated
vendored
Normal file
164
vendor/golang.org/x/arch/arm/armasm/gnu.go
generated
vendored
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package armasm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var saveDot = strings.NewReplacer(
|
||||||
|
".F16", "_dot_F16",
|
||||||
|
".F32", "_dot_F32",
|
||||||
|
".F64", "_dot_F64",
|
||||||
|
".S32", "_dot_S32",
|
||||||
|
".U32", "_dot_U32",
|
||||||
|
".FXS", "_dot_S",
|
||||||
|
".FXU", "_dot_U",
|
||||||
|
".32", "_dot_32",
|
||||||
|
)
|
||||||
|
|
||||||
|
// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils.
|
||||||
|
// This form typically matches the syntax defined in the ARM Reference Manual.
|
||||||
|
func GNUSyntax(inst Inst) string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
op := inst.Op.String()
|
||||||
|
op = saveDot.Replace(op)
|
||||||
|
op = strings.Replace(op, ".", "", -1)
|
||||||
|
op = strings.Replace(op, "_dot_", ".", -1)
|
||||||
|
op = strings.ToLower(op)
|
||||||
|
buf.WriteString(op)
|
||||||
|
sep := " "
|
||||||
|
for i, arg := range inst.Args {
|
||||||
|
if arg == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
text := gnuArg(&inst, i, arg)
|
||||||
|
if text == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
buf.WriteString(sep)
|
||||||
|
sep = ", "
|
||||||
|
buf.WriteString(text)
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func gnuArg(inst *Inst, argIndex int, arg Arg) string {
|
||||||
|
switch inst.Op &^ 15 {
|
||||||
|
case LDRD_EQ, LDREXD_EQ, STRD_EQ:
|
||||||
|
if argIndex == 1 {
|
||||||
|
// second argument in consecutive pair not printed
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
case STREXD_EQ:
|
||||||
|
if argIndex == 2 {
|
||||||
|
// second argument in consecutive pair not printed
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch arg := arg.(type) {
|
||||||
|
case Imm:
|
||||||
|
switch inst.Op &^ 15 {
|
||||||
|
case BKPT_EQ:
|
||||||
|
return fmt.Sprintf("%#04x", uint32(arg))
|
||||||
|
case SVC_EQ:
|
||||||
|
return fmt.Sprintf("%#08x", uint32(arg))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("#%d", int32(arg))
|
||||||
|
|
||||||
|
case ImmAlt:
|
||||||
|
return fmt.Sprintf("#%d, %d", arg.Val, arg.Rot)
|
||||||
|
|
||||||
|
case Mem:
|
||||||
|
R := gnuArg(inst, -1, arg.Base)
|
||||||
|
X := ""
|
||||||
|
if arg.Sign != 0 {
|
||||||
|
X = ""
|
||||||
|
if arg.Sign < 0 {
|
||||||
|
X = "-"
|
||||||
|
}
|
||||||
|
X += gnuArg(inst, -1, arg.Index)
|
||||||
|
if arg.Shift == ShiftLeft && arg.Count == 0 {
|
||||||
|
// nothing
|
||||||
|
} else if arg.Shift == RotateRightExt {
|
||||||
|
X += ", rrx"
|
||||||
|
} else {
|
||||||
|
X += fmt.Sprintf(", %s #%d", strings.ToLower(arg.Shift.String()), arg.Count)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
X = fmt.Sprintf("#%d", arg.Offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch arg.Mode {
|
||||||
|
case AddrOffset:
|
||||||
|
if X == "#0" {
|
||||||
|
return fmt.Sprintf("[%s]", R)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("[%s, %s]", R, X)
|
||||||
|
case AddrPreIndex:
|
||||||
|
return fmt.Sprintf("[%s, %s]!", R, X)
|
||||||
|
case AddrPostIndex:
|
||||||
|
return fmt.Sprintf("[%s], %s", R, X)
|
||||||
|
case AddrLDM:
|
||||||
|
if X == "#0" {
|
||||||
|
return R
|
||||||
|
}
|
||||||
|
case AddrLDM_WB:
|
||||||
|
if X == "#0" {
|
||||||
|
return R + "!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("[%s Mode(%d) %s]", R, int(arg.Mode), X)
|
||||||
|
|
||||||
|
case PCRel:
|
||||||
|
return fmt.Sprintf(".%+#x", int32(arg)+4)
|
||||||
|
|
||||||
|
case Reg:
|
||||||
|
switch inst.Op &^ 15 {
|
||||||
|
case LDREX_EQ:
|
||||||
|
if argIndex == 0 {
|
||||||
|
return fmt.Sprintf("r%d", int32(arg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch arg {
|
||||||
|
case R10:
|
||||||
|
return "sl"
|
||||||
|
case R11:
|
||||||
|
return "fp"
|
||||||
|
case R12:
|
||||||
|
return "ip"
|
||||||
|
}
|
||||||
|
|
||||||
|
case RegList:
|
||||||
|
var buf bytes.Buffer
|
||||||
|
fmt.Fprintf(&buf, "{")
|
||||||
|
sep := ""
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
if arg&(1<<uint(i)) != 0 {
|
||||||
|
fmt.Fprintf(&buf, "%s%s", sep, gnuArg(inst, -1, Reg(i)))
|
||||||
|
sep = ", "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Fprintf(&buf, "}")
|
||||||
|
return buf.String()
|
||||||
|
|
||||||
|
case RegShift:
|
||||||
|
if arg.Shift == ShiftLeft && arg.Count == 0 {
|
||||||
|
return gnuArg(inst, -1, arg.Reg)
|
||||||
|
}
|
||||||
|
if arg.Shift == RotateRightExt {
|
||||||
|
return gnuArg(inst, -1, arg.Reg) + ", rrx"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s, %s #%d", gnuArg(inst, -1, arg.Reg), strings.ToLower(arg.Shift.String()), arg.Count)
|
||||||
|
|
||||||
|
case RegShiftReg:
|
||||||
|
return fmt.Sprintf("%s, %s %s", gnuArg(inst, -1, arg.Reg), strings.ToLower(arg.Shift.String()), gnuArg(inst, -1, arg.RegCount))
|
||||||
|
|
||||||
|
}
|
||||||
|
return strings.ToLower(arg.String())
|
||||||
|
}
|
438
vendor/golang.org/x/arch/arm/armasm/inst.go
generated
vendored
Normal file
438
vendor/golang.org/x/arch/arm/armasm/inst.go
generated
vendored
Normal file
@ -0,0 +1,438 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package armasm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Mode is an instruction execution mode.
|
||||||
|
type Mode int
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ Mode = iota
|
||||||
|
ModeARM
|
||||||
|
ModeThumb
|
||||||
|
)
|
||||||
|
|
||||||
|
func (m Mode) String() string {
|
||||||
|
switch m {
|
||||||
|
case ModeARM:
|
||||||
|
return "ARM"
|
||||||
|
case ModeThumb:
|
||||||
|
return "Thumb"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Mode(%d)", int(m))
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Op is an ARM opcode.
|
||||||
|
type Op uint16
|
||||||
|
|
||||||
|
// NOTE: The actual Op values are defined in tables.go.
|
||||||
|
// They are chosen to simplify instruction decoding and
|
||||||
|
// are not a dense packing from 0 to N, although the
|
||||||
|
// density is high, probably at least 90%.
|
||||||
|
|
||||||
|
func (op Op) String() string {
|
||||||
|
if op >= Op(len(opstr)) || opstr[op] == "" {
|
||||||
|
return fmt.Sprintf("Op(%d)", int(op))
|
||||||
|
}
|
||||||
|
return opstr[op]
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Inst is a single instruction.
|
||||||
|
type Inst struct {
|
||||||
|
Op Op // Opcode mnemonic
|
||||||
|
Enc uint32 // Raw encoding bits.
|
||||||
|
Len int // Length of encoding in bytes.
|
||||||
|
Args Args // Instruction arguments, in ARM manual order.
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i Inst) String() string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
buf.WriteString(i.Op.String())
|
||||||
|
for j, arg := range i.Args {
|
||||||
|
if arg == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if j == 0 {
|
||||||
|
buf.WriteString(" ")
|
||||||
|
} else {
|
||||||
|
buf.WriteString(", ")
|
||||||
|
}
|
||||||
|
buf.WriteString(arg.String())
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Args holds the instruction arguments.
|
||||||
|
// If an instruction has fewer than 4 arguments,
|
||||||
|
// the final elements in the array are nil.
|
||||||
|
type Args [4]Arg
|
||||||
|
|
||||||
|
// An Arg is a single instruction argument, one of these types:
|
||||||
|
// Endian, Imm, Mem, PCRel, Reg, RegList, RegShift, RegShiftReg.
|
||||||
|
type Arg interface {
|
||||||
|
IsArg()
|
||||||
|
String() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Float32Imm float32
|
||||||
|
|
||||||
|
func (Float32Imm) IsArg() {}
|
||||||
|
|
||||||
|
func (f Float32Imm) String() string {
|
||||||
|
return fmt.Sprintf("#%v", float32(f))
|
||||||
|
}
|
||||||
|
|
||||||
|
type Float64Imm float32
|
||||||
|
|
||||||
|
func (Float64Imm) IsArg() {}
|
||||||
|
|
||||||
|
func (f Float64Imm) String() string {
|
||||||
|
return fmt.Sprintf("#%v", float64(f))
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Imm is an integer constant.
|
||||||
|
type Imm uint32
|
||||||
|
|
||||||
|
func (Imm) IsArg() {}
|
||||||
|
|
||||||
|
func (i Imm) String() string {
|
||||||
|
return fmt.Sprintf("#%#x", uint32(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
// A ImmAlt is an alternate encoding of an integer constant.
|
||||||
|
type ImmAlt struct {
|
||||||
|
Val uint8
|
||||||
|
Rot uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ImmAlt) IsArg() {}
|
||||||
|
|
||||||
|
func (i ImmAlt) Imm() Imm {
|
||||||
|
v := uint32(i.Val)
|
||||||
|
r := uint(i.Rot)
|
||||||
|
return Imm(v>>r | v<<(32-r))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i ImmAlt) String() string {
|
||||||
|
return fmt.Sprintf("#%#x, %d", i.Val, i.Rot)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Label is a text (code) address.
|
||||||
|
type Label uint32
|
||||||
|
|
||||||
|
func (Label) IsArg() {}
|
||||||
|
|
||||||
|
func (i Label) String() string {
|
||||||
|
return fmt.Sprintf("%#x", uint32(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Reg is a single register.
|
||||||
|
// The zero value denotes R0, not the absence of a register.
|
||||||
|
type Reg uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
R0 Reg = iota
|
||||||
|
R1
|
||||||
|
R2
|
||||||
|
R3
|
||||||
|
R4
|
||||||
|
R5
|
||||||
|
R6
|
||||||
|
R7
|
||||||
|
R8
|
||||||
|
R9
|
||||||
|
R10
|
||||||
|
R11
|
||||||
|
R12
|
||||||
|
R13
|
||||||
|
R14
|
||||||
|
R15
|
||||||
|
|
||||||
|
S0
|
||||||
|
S1
|
||||||
|
S2
|
||||||
|
S3
|
||||||
|
S4
|
||||||
|
S5
|
||||||
|
S6
|
||||||
|
S7
|
||||||
|
S8
|
||||||
|
S9
|
||||||
|
S10
|
||||||
|
S11
|
||||||
|
S12
|
||||||
|
S13
|
||||||
|
S14
|
||||||
|
S15
|
||||||
|
S16
|
||||||
|
S17
|
||||||
|
S18
|
||||||
|
S19
|
||||||
|
S20
|
||||||
|
S21
|
||||||
|
S22
|
||||||
|
S23
|
||||||
|
S24
|
||||||
|
S25
|
||||||
|
S26
|
||||||
|
S27
|
||||||
|
S28
|
||||||
|
S29
|
||||||
|
S30
|
||||||
|
S31
|
||||||
|
|
||||||
|
D0
|
||||||
|
D1
|
||||||
|
D2
|
||||||
|
D3
|
||||||
|
D4
|
||||||
|
D5
|
||||||
|
D6
|
||||||
|
D7
|
||||||
|
D8
|
||||||
|
D9
|
||||||
|
D10
|
||||||
|
D11
|
||||||
|
D12
|
||||||
|
D13
|
||||||
|
D14
|
||||||
|
D15
|
||||||
|
D16
|
||||||
|
D17
|
||||||
|
D18
|
||||||
|
D19
|
||||||
|
D20
|
||||||
|
D21
|
||||||
|
D22
|
||||||
|
D23
|
||||||
|
D24
|
||||||
|
D25
|
||||||
|
D26
|
||||||
|
D27
|
||||||
|
D28
|
||||||
|
D29
|
||||||
|
D30
|
||||||
|
D31
|
||||||
|
|
||||||
|
APSR
|
||||||
|
APSR_nzcv
|
||||||
|
FPSCR
|
||||||
|
|
||||||
|
SP = R13
|
||||||
|
LR = R14
|
||||||
|
PC = R15
|
||||||
|
)
|
||||||
|
|
||||||
|
func (Reg) IsArg() {}
|
||||||
|
|
||||||
|
func (r Reg) String() string {
|
||||||
|
switch r {
|
||||||
|
case APSR:
|
||||||
|
return "APSR"
|
||||||
|
case APSR_nzcv:
|
||||||
|
return "APSR_nzcv"
|
||||||
|
case FPSCR:
|
||||||
|
return "FPSCR"
|
||||||
|
case SP:
|
||||||
|
return "SP"
|
||||||
|
case PC:
|
||||||
|
return "PC"
|
||||||
|
case LR:
|
||||||
|
return "LR"
|
||||||
|
}
|
||||||
|
if R0 <= r && r <= R15 {
|
||||||
|
return fmt.Sprintf("R%d", int(r-R0))
|
||||||
|
}
|
||||||
|
if S0 <= r && r <= S31 {
|
||||||
|
return fmt.Sprintf("S%d", int(r-S0))
|
||||||
|
}
|
||||||
|
if D0 <= r && r <= D31 {
|
||||||
|
return fmt.Sprintf("D%d", int(r-D0))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Reg(%d)", int(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
// A RegX represents a fraction of a multi-value register.
|
||||||
|
// The Index field specifies the index number,
|
||||||
|
// but the size of the fraction is not specified.
|
||||||
|
// It must be inferred from the instruction and the register type.
|
||||||
|
// For example, in a VMOV instruction, RegX{D5, 1} represents
|
||||||
|
// the top 32 bits of the 64-bit D5 register.
|
||||||
|
type RegX struct {
|
||||||
|
Reg Reg
|
||||||
|
Index int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (RegX) IsArg() {}
|
||||||
|
|
||||||
|
func (r RegX) String() string {
|
||||||
|
return fmt.Sprintf("%s[%d]", r.Reg, r.Index)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A RegList is a register list.
|
||||||
|
// Bits at indexes x = 0 through 15 indicate whether the corresponding Rx register is in the list.
|
||||||
|
type RegList uint16
|
||||||
|
|
||||||
|
func (RegList) IsArg() {}
|
||||||
|
|
||||||
|
func (r RegList) String() string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
fmt.Fprintf(&buf, "{")
|
||||||
|
sep := ""
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
if r&(1<<uint(i)) != 0 {
|
||||||
|
fmt.Fprintf(&buf, "%s%s", sep, Reg(i).String())
|
||||||
|
sep = ","
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Fprintf(&buf, "}")
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Endian is the argument to the SETEND instruction.
|
||||||
|
type Endian uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
LittleEndian Endian = 0
|
||||||
|
BigEndian Endian = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
func (Endian) IsArg() {}
|
||||||
|
|
||||||
|
func (e Endian) String() string {
|
||||||
|
if e != 0 {
|
||||||
|
return "BE"
|
||||||
|
}
|
||||||
|
return "LE"
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Shift describes an ARM shift operation.
|
||||||
|
type Shift uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
ShiftLeft Shift = 0 // left shift
|
||||||
|
ShiftRight Shift = 1 // logical (unsigned) right shift
|
||||||
|
ShiftRightSigned Shift = 2 // arithmetic (signed) right shift
|
||||||
|
RotateRight Shift = 3 // right rotate
|
||||||
|
RotateRightExt Shift = 4 // right rotate through carry (Count will always be 1)
|
||||||
|
)
|
||||||
|
|
||||||
|
var shiftName = [...]string{
|
||||||
|
"LSL", "LSR", "ASR", "ROR", "RRX",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Shift) String() string {
|
||||||
|
if s < 5 {
|
||||||
|
return shiftName[s]
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Shift(%d)", int(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
// A RegShift is a register shifted by a constant.
|
||||||
|
type RegShift struct {
|
||||||
|
Reg Reg
|
||||||
|
Shift Shift
|
||||||
|
Count uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (RegShift) IsArg() {}
|
||||||
|
|
||||||
|
func (r RegShift) String() string {
|
||||||
|
return fmt.Sprintf("%s %s #%d", r.Reg, r.Shift, r.Count)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A RegShiftReg is a register shifted by a register.
|
||||||
|
type RegShiftReg struct {
|
||||||
|
Reg Reg
|
||||||
|
Shift Shift
|
||||||
|
RegCount Reg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (RegShiftReg) IsArg() {}
|
||||||
|
|
||||||
|
func (r RegShiftReg) String() string {
|
||||||
|
return fmt.Sprintf("%s %s %s", r.Reg, r.Shift, r.RegCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A PCRel describes a memory address (usually a code label)
|
||||||
|
// as a distance relative to the program counter.
|
||||||
|
// TODO(rsc): Define which program counter (PC+4? PC+8? PC?).
|
||||||
|
type PCRel int32
|
||||||
|
|
||||||
|
func (PCRel) IsArg() {}
|
||||||
|
|
||||||
|
func (r PCRel) String() string {
|
||||||
|
return fmt.Sprintf("PC%+#x", int32(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
// An AddrMode is an ARM addressing mode.
|
||||||
|
type AddrMode uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ AddrMode = iota
|
||||||
|
AddrPostIndex // [R], X – use address R, set R = R + X
|
||||||
|
AddrPreIndex // [R, X]! – use address R + X, set R = R + X
|
||||||
|
AddrOffset // [R, X] – use address R + X
|
||||||
|
AddrLDM // R – [R] but formats as R, for LDM/STM only
|
||||||
|
AddrLDM_WB // R! - [R], X where X is instruction-specific amount, for LDM/STM only
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Mem is a memory reference made up of a base R and index expression X.
|
||||||
|
// The effective memory address is R or R+X depending on AddrMode.
|
||||||
|
// The index expression is X = Sign*(Index Shift Count) + Offset,
|
||||||
|
// but in any instruction either Sign = 0 or Offset = 0.
|
||||||
|
type Mem struct {
|
||||||
|
Base Reg
|
||||||
|
Mode AddrMode
|
||||||
|
Sign int8
|
||||||
|
Index Reg
|
||||||
|
Shift Shift
|
||||||
|
Count uint8
|
||||||
|
Offset int16
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Mem) IsArg() {}
|
||||||
|
|
||||||
|
func (m Mem) String() string {
|
||||||
|
R := m.Base.String()
|
||||||
|
X := ""
|
||||||
|
if m.Sign != 0 {
|
||||||
|
X = "+"
|
||||||
|
if m.Sign < 0 {
|
||||||
|
X = "-"
|
||||||
|
}
|
||||||
|
X += m.Index.String()
|
||||||
|
if m.Shift != ShiftLeft || m.Count != 0 {
|
||||||
|
X += fmt.Sprintf(", %s #%d", m.Shift, m.Count)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
X = fmt.Sprintf("#%d", m.Offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch m.Mode {
|
||||||
|
case AddrOffset:
|
||||||
|
if X == "#0" {
|
||||||
|
return fmt.Sprintf("[%s]", R)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("[%s, %s]", R, X)
|
||||||
|
case AddrPreIndex:
|
||||||
|
return fmt.Sprintf("[%s, %s]!", R, X)
|
||||||
|
case AddrPostIndex:
|
||||||
|
return fmt.Sprintf("[%s], %s", R, X)
|
||||||
|
case AddrLDM:
|
||||||
|
if X == "#0" {
|
||||||
|
return R
|
||||||
|
}
|
||||||
|
case AddrLDM_WB:
|
||||||
|
if X == "#0" {
|
||||||
|
return R + "!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("[%s Mode(%d) %s]", R, int(m.Mode), X)
|
||||||
|
}
|
215
vendor/golang.org/x/arch/arm/armasm/plan9x.go
generated
vendored
Normal file
215
vendor/golang.org/x/arch/arm/armasm/plan9x.go
generated
vendored
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package armasm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GoSyntax returns the Go assembler syntax for the instruction.
|
||||||
|
// The syntax was originally defined by Plan 9.
|
||||||
|
// The pc is the program counter of the instruction, used for expanding
|
||||||
|
// PC-relative addresses into absolute ones.
|
||||||
|
// The symname function queries the symbol table for the program
|
||||||
|
// being disassembled. Given a target address it returns the name and base
|
||||||
|
// address of the symbol containing the target, if any; otherwise it returns "", 0.
|
||||||
|
// The reader r should read from the text segment using text addresses
|
||||||
|
// as offsets; it is used to display pc-relative loads as constant loads.
|
||||||
|
func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text io.ReaderAt) string {
|
||||||
|
if symname == nil {
|
||||||
|
symname = func(uint64) (string, uint64) { return "", 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
var args []string
|
||||||
|
for _, a := range inst.Args {
|
||||||
|
if a == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
args = append(args, plan9Arg(&inst, pc, symname, a))
|
||||||
|
}
|
||||||
|
|
||||||
|
op := inst.Op.String()
|
||||||
|
|
||||||
|
switch inst.Op &^ 15 {
|
||||||
|
case LDR_EQ, LDRB_EQ, LDRH_EQ:
|
||||||
|
// Check for RET
|
||||||
|
reg, _ := inst.Args[0].(Reg)
|
||||||
|
mem, _ := inst.Args[1].(Mem)
|
||||||
|
if inst.Op&^15 == LDR_EQ && reg == R15 && mem.Base == SP && mem.Sign == 0 && mem.Mode == AddrPostIndex {
|
||||||
|
return fmt.Sprintf("RET%s #%d", op[3:], mem.Offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for PC-relative load.
|
||||||
|
if mem.Base == PC && mem.Sign == 0 && mem.Mode == AddrOffset && text != nil {
|
||||||
|
addr := uint32(pc) + 8 + uint32(mem.Offset)
|
||||||
|
buf := make([]byte, 4)
|
||||||
|
switch inst.Op &^ 15 {
|
||||||
|
case LDRB_EQ:
|
||||||
|
if _, err := text.ReadAt(buf[:1], int64(addr)); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
args[1] = fmt.Sprintf("$%#x", buf[0])
|
||||||
|
|
||||||
|
case LDRH_EQ:
|
||||||
|
if _, err := text.ReadAt(buf[:2], int64(addr)); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
args[1] = fmt.Sprintf("$%#x", binary.LittleEndian.Uint16(buf))
|
||||||
|
|
||||||
|
case LDR_EQ:
|
||||||
|
if _, err := text.ReadAt(buf, int64(addr)); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
x := binary.LittleEndian.Uint32(buf)
|
||||||
|
if s, base := symname(uint64(x)); s != "" && uint64(x) == base {
|
||||||
|
args[1] = fmt.Sprintf("$%s(SB)", s)
|
||||||
|
} else {
|
||||||
|
args[1] = fmt.Sprintf("$%#x", x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move addressing mode into opcode suffix.
|
||||||
|
suffix := ""
|
||||||
|
switch inst.Op &^ 15 {
|
||||||
|
case LDR_EQ, LDRB_EQ, LDRH_EQ, STR_EQ, STRB_EQ, STRH_EQ:
|
||||||
|
mem, _ := inst.Args[1].(Mem)
|
||||||
|
switch mem.Mode {
|
||||||
|
case AddrOffset, AddrLDM:
|
||||||
|
// no suffix
|
||||||
|
case AddrPreIndex, AddrLDM_WB:
|
||||||
|
suffix = ".W"
|
||||||
|
case AddrPostIndex:
|
||||||
|
suffix = ".P"
|
||||||
|
}
|
||||||
|
off := ""
|
||||||
|
if mem.Offset != 0 {
|
||||||
|
off = fmt.Sprintf("%#x", mem.Offset)
|
||||||
|
}
|
||||||
|
base := fmt.Sprintf("(R%d)", int(mem.Base))
|
||||||
|
index := ""
|
||||||
|
if mem.Sign != 0 {
|
||||||
|
sign := ""
|
||||||
|
if mem.Sign < 0 {
|
||||||
|
sign = ""
|
||||||
|
}
|
||||||
|
shift := ""
|
||||||
|
if mem.Count != 0 {
|
||||||
|
shift = fmt.Sprintf("%s%d", plan9Shift[mem.Shift], mem.Count)
|
||||||
|
}
|
||||||
|
index = fmt.Sprintf("(%sR%d%s)", sign, int(mem.Index), shift)
|
||||||
|
}
|
||||||
|
args[1] = off + base + index
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse args, placing dest last.
|
||||||
|
for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
|
||||||
|
args[i], args[j] = args[j], args[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
switch inst.Op &^ 15 {
|
||||||
|
case MOV_EQ:
|
||||||
|
op = "MOVW" + op[3:]
|
||||||
|
|
||||||
|
case LDR_EQ:
|
||||||
|
op = "MOVW" + op[3:] + suffix
|
||||||
|
case LDRB_EQ:
|
||||||
|
op = "MOVB" + op[4:] + suffix
|
||||||
|
case LDRH_EQ:
|
||||||
|
op = "MOVH" + op[4:] + suffix
|
||||||
|
|
||||||
|
case STR_EQ:
|
||||||
|
op = "MOVW" + op[3:] + suffix
|
||||||
|
args[0], args[1] = args[1], args[0]
|
||||||
|
case STRB_EQ:
|
||||||
|
op = "MOVB" + op[4:] + suffix
|
||||||
|
args[0], args[1] = args[1], args[0]
|
||||||
|
case STRH_EQ:
|
||||||
|
op = "MOVH" + op[4:] + suffix
|
||||||
|
args[0], args[1] = args[1], args[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if args != nil {
|
||||||
|
op += " " + strings.Join(args, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
return op
|
||||||
|
}
|
||||||
|
|
||||||
|
// assembler syntax for the various shifts.
|
||||||
|
// @x> is a lie; the assembler uses @> 0
|
||||||
|
// instead of @x> 1, but i wanted to be clear that it
|
||||||
|
// was a different operation (rotate right extended, not rotate right).
|
||||||
|
var plan9Shift = []string{"<<", ">>", "->", "@>", "@x>"}
|
||||||
|
|
||||||
|
func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
|
||||||
|
switch a := arg.(type) {
|
||||||
|
case Endian:
|
||||||
|
|
||||||
|
case Imm:
|
||||||
|
return fmt.Sprintf("$%d", int(a))
|
||||||
|
|
||||||
|
case Mem:
|
||||||
|
|
||||||
|
case PCRel:
|
||||||
|
addr := uint32(pc) + 8 + uint32(a)
|
||||||
|
if s, base := symname(uint64(addr)); s != "" && uint64(addr) == base {
|
||||||
|
return fmt.Sprintf("%s(SB)", s)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%#x", addr)
|
||||||
|
|
||||||
|
case Reg:
|
||||||
|
if a < 16 {
|
||||||
|
return fmt.Sprintf("R%d", int(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
case RegList:
|
||||||
|
var buf bytes.Buffer
|
||||||
|
start := -2
|
||||||
|
end := -2
|
||||||
|
fmt.Fprintf(&buf, "[")
|
||||||
|
flush := func() {
|
||||||
|
if start >= 0 {
|
||||||
|
if buf.Len() > 1 {
|
||||||
|
fmt.Fprintf(&buf, ",")
|
||||||
|
}
|
||||||
|
if start == end {
|
||||||
|
fmt.Fprintf(&buf, "R%d", start)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(&buf, "R%d-R%d", start, end)
|
||||||
|
}
|
||||||
|
start = -2
|
||||||
|
end = -2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
if a&(1<<uint(i)) != 0 {
|
||||||
|
if i == end+1 {
|
||||||
|
end++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
start = i
|
||||||
|
end = i
|
||||||
|
} else {
|
||||||
|
flush()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flush()
|
||||||
|
fmt.Fprintf(&buf, "]")
|
||||||
|
return buf.String()
|
||||||
|
|
||||||
|
case RegShift:
|
||||||
|
return fmt.Sprintf("R%d%s$%d", int(a.Reg), plan9Shift[a.Shift], int(a.Count))
|
||||||
|
|
||||||
|
case RegShiftReg:
|
||||||
|
return fmt.Sprintf("R%d%sR%d", int(a.Reg), plan9Shift[a.Shift], int(a.RegCount))
|
||||||
|
}
|
||||||
|
return strings.ToUpper(arg.String())
|
||||||
|
}
|
9448
vendor/golang.org/x/arch/arm/armasm/tables.go
generated
vendored
Normal file
9448
vendor/golang.org/x/arch/arm/armasm/tables.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
27
vendor/golang.org/x/arch/ppc64/ppc64asm/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/arch/ppc64/ppc64asm/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2015 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
179
vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go
generated
vendored
Normal file
179
vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go
generated
vendored
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package ppc64asm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
const debugDecode = false
|
||||||
|
|
||||||
|
// instFormat is a decoding rule for one specific instruction form.
|
||||||
|
// a uint32 instruction ins matches the rule if ins&Mask == Value
|
||||||
|
// DontCare bits should be zero, but the machine might not reject
|
||||||
|
// ones in those bits, they are mainly reserved for future expansion
|
||||||
|
// of the instruction set.
|
||||||
|
// The Args are stored in the same order as the instruction manual.
|
||||||
|
type instFormat struct {
|
||||||
|
Op Op
|
||||||
|
Mask uint32
|
||||||
|
Value uint32
|
||||||
|
DontCare uint32
|
||||||
|
Args [5]*argField
|
||||||
|
}
|
||||||
|
|
||||||
|
// argField indicate how to decode an argument to an instruction.
|
||||||
|
// First parse the value from the BitFields, shift it left by Shift
|
||||||
|
// bits to get the actual numerical value.
|
||||||
|
type argField struct {
|
||||||
|
Type ArgType
|
||||||
|
Shift uint8
|
||||||
|
BitFields
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse parses the Arg out from the given binary instruction i.
|
||||||
|
func (a argField) Parse(i uint32) Arg {
|
||||||
|
switch a.Type {
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
case TypeUnknown:
|
||||||
|
return nil
|
||||||
|
case TypeReg:
|
||||||
|
return R0 + Reg(a.BitFields.Parse(i))
|
||||||
|
case TypeCondRegBit:
|
||||||
|
return Cond0LT + CondReg(a.BitFields.Parse(i))
|
||||||
|
case TypeCondRegField:
|
||||||
|
return CR0 + CondReg(a.BitFields.Parse(i))
|
||||||
|
case TypeFPReg:
|
||||||
|
return F0 + Reg(a.BitFields.Parse(i))
|
||||||
|
case TypeVecReg:
|
||||||
|
return V0 + Reg(a.BitFields.Parse(i))
|
||||||
|
case TypeVecSReg:
|
||||||
|
return VS0 + Reg(a.BitFields.Parse(i))
|
||||||
|
case TypeSpReg:
|
||||||
|
return SpReg(a.BitFields.Parse(i))
|
||||||
|
case TypeImmSigned:
|
||||||
|
return Imm(a.BitFields.ParseSigned(i) << a.Shift)
|
||||||
|
case TypeImmUnsigned:
|
||||||
|
return Imm(a.BitFields.Parse(i) << a.Shift)
|
||||||
|
case TypePCRel:
|
||||||
|
return PCRel(a.BitFields.ParseSigned(i) << a.Shift)
|
||||||
|
case TypeLabel:
|
||||||
|
return Label(a.BitFields.ParseSigned(i) << a.Shift)
|
||||||
|
case TypeOffset:
|
||||||
|
return Offset(a.BitFields.ParseSigned(i) << a.Shift)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ArgType int8
|
||||||
|
|
||||||
|
const (
|
||||||
|
TypeUnknown ArgType = iota
|
||||||
|
TypePCRel // PC-relative address
|
||||||
|
TypeLabel // absolute address
|
||||||
|
TypeReg // integer register
|
||||||
|
TypeCondRegBit // conditional register bit (0-31)
|
||||||
|
TypeCondRegField // conditional register field (0-7)
|
||||||
|
TypeFPReg // floating point register
|
||||||
|
TypeVecReg // vector register
|
||||||
|
TypeVecSReg // VSX register
|
||||||
|
TypeSpReg // special register (depends on Op)
|
||||||
|
TypeImmSigned // signed immediate
|
||||||
|
TypeImmUnsigned // unsigned immediate/flag/mask, this is the catch-all type
|
||||||
|
TypeOffset // signed offset in load/store
|
||||||
|
TypeLast // must be the last one
|
||||||
|
)
|
||||||
|
|
||||||
|
func (t ArgType) String() string {
|
||||||
|
switch t {
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("ArgType(%d)", int(t))
|
||||||
|
case TypeUnknown:
|
||||||
|
return "Unknown"
|
||||||
|
case TypeReg:
|
||||||
|
return "Reg"
|
||||||
|
case TypeCondRegBit:
|
||||||
|
return "CondRegBit"
|
||||||
|
case TypeCondRegField:
|
||||||
|
return "CondRegField"
|
||||||
|
case TypeFPReg:
|
||||||
|
return "FPReg"
|
||||||
|
case TypeVecReg:
|
||||||
|
return "VecReg"
|
||||||
|
case TypeVecSReg:
|
||||||
|
return "VecSReg"
|
||||||
|
case TypeSpReg:
|
||||||
|
return "SpReg"
|
||||||
|
case TypeImmSigned:
|
||||||
|
return "ImmSigned"
|
||||||
|
case TypeImmUnsigned:
|
||||||
|
return "ImmUnsigned"
|
||||||
|
case TypePCRel:
|
||||||
|
return "PCRel"
|
||||||
|
case TypeLabel:
|
||||||
|
return "Label"
|
||||||
|
case TypeOffset:
|
||||||
|
return "Offset"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t ArgType) GoString() string {
|
||||||
|
s := t.String()
|
||||||
|
if t > 0 && t < TypeLast {
|
||||||
|
return "Type" + s
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Errors
|
||||||
|
errShort = fmt.Errorf("truncated instruction")
|
||||||
|
errUnknown = fmt.Errorf("unknown instruction")
|
||||||
|
)
|
||||||
|
|
||||||
|
var decoderCover []bool
|
||||||
|
|
||||||
|
// Decode decodes the leading bytes in src as a single instruction using
|
||||||
|
// byte order ord.
|
||||||
|
func Decode(src []byte, ord binary.ByteOrder) (inst Inst, err error) {
|
||||||
|
if len(src) < 4 {
|
||||||
|
return inst, errShort
|
||||||
|
}
|
||||||
|
if decoderCover == nil {
|
||||||
|
decoderCover = make([]bool, len(instFormats))
|
||||||
|
}
|
||||||
|
inst.Len = 4 // only 4-byte instructions are supported
|
||||||
|
ui := ord.Uint32(src[:inst.Len])
|
||||||
|
inst.Enc = ui
|
||||||
|
for i, iform := range instFormats {
|
||||||
|
if ui&iform.Mask != iform.Value {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ui&iform.DontCare != 0 {
|
||||||
|
if debugDecode {
|
||||||
|
log.Printf("Decode(%#x): unused bit is 1 for Op %s", ui, iform.Op)
|
||||||
|
}
|
||||||
|
// to match GNU objdump (libopcodes), we ignore don't care bits
|
||||||
|
}
|
||||||
|
for i, argfield := range iform.Args {
|
||||||
|
if argfield == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
inst.Args[i] = argfield.Parse(ui)
|
||||||
|
}
|
||||||
|
inst.Op = iform.Op
|
||||||
|
if debugDecode {
|
||||||
|
log.Printf("%#x: search entry %d", ui, i)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if inst.Op == 0 {
|
||||||
|
return inst, errUnknown
|
||||||
|
}
|
||||||
|
return inst, nil
|
||||||
|
}
|
6
vendor/golang.org/x/arch/ppc64/ppc64asm/doc.go
generated
vendored
Normal file
6
vendor/golang.org/x/arch/ppc64/ppc64asm/doc.go
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package ppc64asm implements decoding of 64-bit PowerPC machine code.
|
||||||
|
package ppc64asm
|
84
vendor/golang.org/x/arch/ppc64/ppc64asm/field.go
generated
vendored
Normal file
84
vendor/golang.org/x/arch/ppc64/ppc64asm/field.go
generated
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package ppc64asm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A BitField is a bit-field in a 32-bit word.
|
||||||
|
// Bits are counted from 0 from the MSB to 31 as the LSB.
|
||||||
|
type BitField struct {
|
||||||
|
Offs uint8 // the offset of the left-most bit.
|
||||||
|
Bits uint8 // length in bits.
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BitField) String() string {
|
||||||
|
if b.Bits > 1 {
|
||||||
|
return fmt.Sprintf("[%d:%d]", b.Offs, int(b.Offs+b.Bits)-1)
|
||||||
|
} else if b.Bits == 1 {
|
||||||
|
return fmt.Sprintf("[%d]", b.Offs)
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("[%d, len=0]", b.Offs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse extracts the bitfield b from i, and return it as an unsigned integer.
|
||||||
|
// Parse will panic if b is invalid.
|
||||||
|
func (b BitField) Parse(i uint32) uint32 {
|
||||||
|
if b.Bits > 32 || b.Bits == 0 || b.Offs > 31 || b.Offs+b.Bits > 32 {
|
||||||
|
panic(fmt.Sprintf("invalid bitfiled %v", b))
|
||||||
|
}
|
||||||
|
return (i >> (32 - b.Offs - b.Bits)) & ((1 << b.Bits) - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseSigned extracts the bitfield b from i, and return it as a signed integer.
|
||||||
|
// ParseSigned will panic if b is invalid.
|
||||||
|
func (b BitField) ParseSigned(i uint32) int32 {
|
||||||
|
u := int32(b.Parse(i))
|
||||||
|
return u << (32 - b.Bits) >> (32 - b.Bits)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BitFields is a series of BitFields representing a single number.
|
||||||
|
type BitFields []BitField
|
||||||
|
|
||||||
|
func (bs BitFields) String() string {
|
||||||
|
ss := make([]string, len(bs))
|
||||||
|
for i, bf := range bs {
|
||||||
|
ss[i] = bf.String()
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("<%s>", strings.Join(ss, "|"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs *BitFields) Append(b BitField) {
|
||||||
|
*bs = append(*bs, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse extracts the bitfields from i, concatenate them and return the result
|
||||||
|
// as an unsigned integer and the total length of all the bitfields.
|
||||||
|
// parse will panic if any bitfield in b is invalid, but it doesn't check if
|
||||||
|
// the sequence of bitfields is reasonable.
|
||||||
|
func (bs BitFields) parse(i uint32) (u uint32, Bits uint8) {
|
||||||
|
for _, b := range bs {
|
||||||
|
u = (u << b.Bits) | b.Parse(i)
|
||||||
|
Bits += b.Bits
|
||||||
|
}
|
||||||
|
return u, Bits
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse extracts the bitfields from i, concatenate them and return the result
|
||||||
|
// as an unsigned integer. Parse will panic if any bitfield in b is invalid.
|
||||||
|
func (bs BitFields) Parse(i uint32) uint32 {
|
||||||
|
u, _ := bs.parse(i)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse extracts the bitfields from i, concatenate them and return the result
|
||||||
|
// as a signed integer. Parse will panic if any bitfield in b is invalid.
|
||||||
|
func (bs BitFields) ParseSigned(i uint32) int32 {
|
||||||
|
u, l := bs.parse(i)
|
||||||
|
return int32(u) << (32 - l) >> (32 - l)
|
||||||
|
}
|
125
vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go
generated
vendored
Normal file
125
vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go
generated
vendored
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package ppc64asm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils.
|
||||||
|
// This form typically matches the syntax defined in the Power ISA Reference Manual.
|
||||||
|
func GNUSyntax(inst Inst) string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if inst.Op == 0 {
|
||||||
|
return "error: unkown instruction"
|
||||||
|
}
|
||||||
|
buf.WriteString(inst.Op.String())
|
||||||
|
sep := " "
|
||||||
|
for i, arg := range inst.Args[:] {
|
||||||
|
if arg == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
text := gnuArg(&inst, i, arg)
|
||||||
|
if text == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
buf.WriteString(sep)
|
||||||
|
sep = ","
|
||||||
|
buf.WriteString(text)
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// gnuArg formats arg (which is the argIndex's arg in inst) according to GNU rules.
|
||||||
|
// NOTE: because GNUSyntax is the only caller of this func, and it receives a copy
|
||||||
|
// of inst, it's ok to modify inst.Args here.
|
||||||
|
func gnuArg(inst *Inst, argIndex int, arg Arg) string {
|
||||||
|
// special cases for load/store instructions
|
||||||
|
if _, ok := arg.(Offset); ok {
|
||||||
|
if argIndex+1 == len(inst.Args) || inst.Args[argIndex+1] == nil {
|
||||||
|
panic(fmt.Errorf("wrong table: offset not followed by register"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch arg := arg.(type) {
|
||||||
|
case Reg:
|
||||||
|
if isLoadStoreOp(inst.Op) && argIndex == 1 && arg == R0 {
|
||||||
|
return "0"
|
||||||
|
}
|
||||||
|
return arg.String()
|
||||||
|
case CondReg:
|
||||||
|
if arg == CR0 && strings.HasPrefix(inst.Op.String(), "cmp") {
|
||||||
|
return "" // don't show cr0 for cmp instructions
|
||||||
|
} else if arg >= CR0 {
|
||||||
|
return fmt.Sprintf("cr%d", int(arg-CR0))
|
||||||
|
}
|
||||||
|
bit := [4]string{"lt", "gt", "eq", "so"}[(arg-Cond0LT)%4]
|
||||||
|
if arg <= Cond0SO {
|
||||||
|
return bit
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("4*cr%d+%s", int(arg-Cond0LT)/4, bit)
|
||||||
|
case Imm:
|
||||||
|
return fmt.Sprintf("%d", arg)
|
||||||
|
case SpReg:
|
||||||
|
return fmt.Sprintf("%d", int(arg))
|
||||||
|
case PCRel:
|
||||||
|
return fmt.Sprintf(".%+#x", int(arg))
|
||||||
|
case Label:
|
||||||
|
return fmt.Sprintf("%#x", uint32(arg))
|
||||||
|
case Offset:
|
||||||
|
reg := inst.Args[argIndex+1].(Reg)
|
||||||
|
removeArg(inst, argIndex+1)
|
||||||
|
if reg == R0 {
|
||||||
|
return fmt.Sprintf("%d(0)", int(arg))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%d(r%d)", int(arg), reg-R0)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("???(%v)", arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// removeArg removes the arg in inst.Args[index].
|
||||||
|
func removeArg(inst *Inst, index int) {
|
||||||
|
for i := index; i < len(inst.Args); i++ {
|
||||||
|
if i+1 < len(inst.Args) {
|
||||||
|
inst.Args[i] = inst.Args[i+1]
|
||||||
|
} else {
|
||||||
|
inst.Args[i] = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// isLoadStoreOp returns true if op is a load or store instruction
|
||||||
|
func isLoadStoreOp(op Op) bool {
|
||||||
|
switch op {
|
||||||
|
case LBZ, LBZU, LBZX, LBZUX:
|
||||||
|
return true
|
||||||
|
case LHZ, LHZU, LHZX, LHZUX:
|
||||||
|
return true
|
||||||
|
case LHA, LHAU, LHAX, LHAUX:
|
||||||
|
return true
|
||||||
|
case LWZ, LWZU, LWZX, LWZUX:
|
||||||
|
return true
|
||||||
|
case LWA, LWAX, LWAUX:
|
||||||
|
return true
|
||||||
|
case LD, LDU, LDX, LDUX:
|
||||||
|
return true
|
||||||
|
case LQ:
|
||||||
|
return true
|
||||||
|
case STB, STBU, STBX, STBUX:
|
||||||
|
return true
|
||||||
|
case STH, STHU, STHX, STHUX:
|
||||||
|
return true
|
||||||
|
case STW, STWU, STWX, STWUX:
|
||||||
|
return true
|
||||||
|
case STD, STDU, STDX, STDUX:
|
||||||
|
return true
|
||||||
|
case STQ:
|
||||||
|
return true
|
||||||
|
case LHBRX, LWBRX, STHBRX, STWBRX:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
344
vendor/golang.org/x/arch/ppc64/ppc64asm/inst.go
generated
vendored
Normal file
344
vendor/golang.org/x/arch/ppc64/ppc64asm/inst.go
generated
vendored
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package ppc64asm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Inst struct {
|
||||||
|
Op Op // Opcode mnemonic
|
||||||
|
Enc uint32 // Raw encoding bits
|
||||||
|
Len int // Length of encoding in bytes.
|
||||||
|
Args Args // Instruction arguments, in Power ISA manual order.
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i Inst) String() string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
buf.WriteString(i.Op.String())
|
||||||
|
for j, arg := range i.Args {
|
||||||
|
if arg == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if j == 0 {
|
||||||
|
buf.WriteString(" ")
|
||||||
|
} else {
|
||||||
|
buf.WriteString(", ")
|
||||||
|
}
|
||||||
|
buf.WriteString(arg.String())
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Op is an instruction operation.
|
||||||
|
type Op uint16
|
||||||
|
|
||||||
|
func (o Op) String() string {
|
||||||
|
if int(o) >= len(opstr) || opstr[o] == "" {
|
||||||
|
return fmt.Sprintf("Op(%d)", int(o))
|
||||||
|
}
|
||||||
|
return opstr[o]
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Arg is a single instruction argument, one of these types: Reg, CondReg, SpReg, Imm, PCRel, Label, or Offset.
|
||||||
|
type Arg interface {
|
||||||
|
IsArg()
|
||||||
|
String() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Args holds the instruction arguments.
|
||||||
|
// If an instruction has fewer than 4 arguments,
|
||||||
|
// the final elements in the array are nil.
|
||||||
|
type Args [5]Arg
|
||||||
|
|
||||||
|
// A Reg is a single register. The zero value means R0, not the absence of a register.
|
||||||
|
// It also includes special registers.
|
||||||
|
type Reg uint16
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ Reg = iota
|
||||||
|
R0
|
||||||
|
R1
|
||||||
|
R2
|
||||||
|
R3
|
||||||
|
R4
|
||||||
|
R5
|
||||||
|
R6
|
||||||
|
R7
|
||||||
|
R8
|
||||||
|
R9
|
||||||
|
R10
|
||||||
|
R11
|
||||||
|
R12
|
||||||
|
R13
|
||||||
|
R14
|
||||||
|
R15
|
||||||
|
R16
|
||||||
|
R17
|
||||||
|
R18
|
||||||
|
R19
|
||||||
|
R20
|
||||||
|
R21
|
||||||
|
R22
|
||||||
|
R23
|
||||||
|
R24
|
||||||
|
R25
|
||||||
|
R26
|
||||||
|
R27
|
||||||
|
R28
|
||||||
|
R29
|
||||||
|
R30
|
||||||
|
R31
|
||||||
|
F0
|
||||||
|
F1
|
||||||
|
F2
|
||||||
|
F3
|
||||||
|
F4
|
||||||
|
F5
|
||||||
|
F6
|
||||||
|
F7
|
||||||
|
F8
|
||||||
|
F9
|
||||||
|
F10
|
||||||
|
F11
|
||||||
|
F12
|
||||||
|
F13
|
||||||
|
F14
|
||||||
|
F15
|
||||||
|
F16
|
||||||
|
F17
|
||||||
|
F18
|
||||||
|
F19
|
||||||
|
F20
|
||||||
|
F21
|
||||||
|
F22
|
||||||
|
F23
|
||||||
|
F24
|
||||||
|
F25
|
||||||
|
F26
|
||||||
|
F27
|
||||||
|
F28
|
||||||
|
F29
|
||||||
|
F30
|
||||||
|
F31
|
||||||
|
V0 // VSX extension, F0 is V0[0:63].
|
||||||
|
V1
|
||||||
|
V2
|
||||||
|
V3
|
||||||
|
V4
|
||||||
|
V5
|
||||||
|
V6
|
||||||
|
V7
|
||||||
|
V8
|
||||||
|
V9
|
||||||
|
V10
|
||||||
|
V11
|
||||||
|
V12
|
||||||
|
V13
|
||||||
|
V14
|
||||||
|
V15
|
||||||
|
V16
|
||||||
|
V17
|
||||||
|
V18
|
||||||
|
V19
|
||||||
|
V20
|
||||||
|
V21
|
||||||
|
V22
|
||||||
|
V23
|
||||||
|
V24
|
||||||
|
V25
|
||||||
|
V26
|
||||||
|
V27
|
||||||
|
V28
|
||||||
|
V29
|
||||||
|
V30
|
||||||
|
V31
|
||||||
|
VS0
|
||||||
|
VS1
|
||||||
|
VS2
|
||||||
|
VS3
|
||||||
|
VS4
|
||||||
|
VS5
|
||||||
|
VS6
|
||||||
|
VS7
|
||||||
|
VS8
|
||||||
|
VS9
|
||||||
|
VS10
|
||||||
|
VS11
|
||||||
|
VS12
|
||||||
|
VS13
|
||||||
|
VS14
|
||||||
|
VS15
|
||||||
|
VS16
|
||||||
|
VS17
|
||||||
|
VS18
|
||||||
|
VS19
|
||||||
|
VS20
|
||||||
|
VS21
|
||||||
|
VS22
|
||||||
|
VS23
|
||||||
|
VS24
|
||||||
|
VS25
|
||||||
|
VS26
|
||||||
|
VS27
|
||||||
|
VS28
|
||||||
|
VS29
|
||||||
|
VS30
|
||||||
|
VS31
|
||||||
|
VS32
|
||||||
|
VS33
|
||||||
|
VS34
|
||||||
|
VS35
|
||||||
|
VS36
|
||||||
|
VS37
|
||||||
|
VS38
|
||||||
|
VS39
|
||||||
|
VS40
|
||||||
|
VS41
|
||||||
|
VS42
|
||||||
|
VS43
|
||||||
|
VS44
|
||||||
|
VS45
|
||||||
|
VS46
|
||||||
|
VS47
|
||||||
|
VS48
|
||||||
|
VS49
|
||||||
|
VS50
|
||||||
|
VS51
|
||||||
|
VS52
|
||||||
|
VS53
|
||||||
|
VS54
|
||||||
|
VS55
|
||||||
|
VS56
|
||||||
|
VS57
|
||||||
|
VS58
|
||||||
|
VS59
|
||||||
|
VS60
|
||||||
|
VS61
|
||||||
|
VS62
|
||||||
|
VS63
|
||||||
|
)
|
||||||
|
|
||||||
|
func (Reg) IsArg() {}
|
||||||
|
func (r Reg) String() string {
|
||||||
|
switch {
|
||||||
|
case R0 <= r && r <= R31:
|
||||||
|
return fmt.Sprintf("r%d", int(r-R0))
|
||||||
|
case F0 <= r && r <= F31:
|
||||||
|
return fmt.Sprintf("f%d", int(r-F0))
|
||||||
|
case V0 <= r && r <= V31:
|
||||||
|
return fmt.Sprintf("v%d", int(r-V0))
|
||||||
|
case VS0 <= r && r <= VS63:
|
||||||
|
return fmt.Sprintf("vs%d", int(r-VS0))
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("Reg(%d)", int(r))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CondReg is a bit or field in the conditon register.
|
||||||
|
type CondReg int8
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ CondReg = iota
|
||||||
|
// Condition Regster bits
|
||||||
|
Cond0LT
|
||||||
|
Cond0GT
|
||||||
|
Cond0EQ
|
||||||
|
Cond0SO
|
||||||
|
Cond1LT
|
||||||
|
Cond1GT
|
||||||
|
Cond1EQ
|
||||||
|
Cond1SO
|
||||||
|
Cond2LT
|
||||||
|
Cond2GT
|
||||||
|
Cond2EQ
|
||||||
|
Cond2SO
|
||||||
|
Cond3LT
|
||||||
|
Cond3GT
|
||||||
|
Cond3EQ
|
||||||
|
Cond3SO
|
||||||
|
Cond4LT
|
||||||
|
Cond4GT
|
||||||
|
Cond4EQ
|
||||||
|
Cond4SO
|
||||||
|
Cond5LT
|
||||||
|
Cond5GT
|
||||||
|
Cond5EQ
|
||||||
|
Cond5SO
|
||||||
|
Cond6LT
|
||||||
|
Cond6GT
|
||||||
|
Cond6EQ
|
||||||
|
Cond6SO
|
||||||
|
Cond7LT
|
||||||
|
Cond7GT
|
||||||
|
Cond7EQ
|
||||||
|
Cond7SO
|
||||||
|
// Condition Register Fields
|
||||||
|
CR0
|
||||||
|
CR1
|
||||||
|
CR2
|
||||||
|
CR3
|
||||||
|
CR4
|
||||||
|
CR5
|
||||||
|
CR6
|
||||||
|
CR7
|
||||||
|
)
|
||||||
|
|
||||||
|
func (CondReg) IsArg() {}
|
||||||
|
func (c CondReg) String() string {
|
||||||
|
switch {
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("CondReg(%d)", int(c))
|
||||||
|
case c >= CR0:
|
||||||
|
return fmt.Sprintf("CR%d", int(c-CR0))
|
||||||
|
case c >= Cond0LT && c < CR0:
|
||||||
|
return fmt.Sprintf("Cond%d%s", int((c-Cond0LT)/4), [4]string{"LT", "GT", "EQ", "SO"}[(c-Cond0LT)%4])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SpReg is a special register, its meaning depends on Op.
|
||||||
|
type SpReg uint16
|
||||||
|
|
||||||
|
const (
|
||||||
|
SpRegZero SpReg = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
func (SpReg) IsArg() {}
|
||||||
|
func (s SpReg) String() string {
|
||||||
|
return fmt.Sprintf("SpReg(%d)", int(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PCRel is a PC-relative offset, used only in branch instructions.
|
||||||
|
type PCRel int32
|
||||||
|
|
||||||
|
func (PCRel) IsArg() {}
|
||||||
|
func (r PCRel) String() string {
|
||||||
|
return fmt.Sprintf("PC%+#x", int32(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Label is a code (text) address, used only in absolute branch instructions.
|
||||||
|
type Label uint32
|
||||||
|
|
||||||
|
func (Label) IsArg() {}
|
||||||
|
func (l Label) String() string {
|
||||||
|
return fmt.Sprintf("%#x", uint32(l))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Imm represents an immediate number.
|
||||||
|
type Imm int32
|
||||||
|
|
||||||
|
func (Imm) IsArg() {}
|
||||||
|
func (i Imm) String() string {
|
||||||
|
return fmt.Sprintf("%d", int32(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offset represents a memory offset immediate.
|
||||||
|
type Offset int32
|
||||||
|
|
||||||
|
func (Offset) IsArg() {}
|
||||||
|
func (o Offset) String() string {
|
||||||
|
return fmt.Sprintf("%+d", int32(o))
|
||||||
|
}
|
172
vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go
generated
vendored
Normal file
172
vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go
generated
vendored
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package ppc64asm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GoSyntax returns the Go assembler syntax for the instruction.
|
||||||
|
// The pc is the program counter of the first instruction, used for expanding
|
||||||
|
// PC-relative addresses into absolute ones.
|
||||||
|
// The symname function queries the symbol table for the program
|
||||||
|
// being disassembled. It returns the name and base address of the symbol
|
||||||
|
// containing the target, if any; otherwise it returns "", 0.
|
||||||
|
func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) string {
|
||||||
|
if symname == nil {
|
||||||
|
symname = func(uint64) (string, uint64) { return "", 0 }
|
||||||
|
}
|
||||||
|
if inst.Op == 0 {
|
||||||
|
return "?"
|
||||||
|
}
|
||||||
|
var args []string
|
||||||
|
for i, a := range inst.Args[:] {
|
||||||
|
if a == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if s := plan9Arg(&inst, i, pc, a, symname); s != "" {
|
||||||
|
args = append(args, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var op string
|
||||||
|
op = plan9OpMap[inst.Op]
|
||||||
|
if op == "" {
|
||||||
|
op = strings.ToUpper(inst.Op.String())
|
||||||
|
}
|
||||||
|
// laid out the instruction
|
||||||
|
switch inst.Op {
|
||||||
|
default: // dst, sA, sB, ...
|
||||||
|
if len(args) == 0 {
|
||||||
|
return op
|
||||||
|
} else if len(args) == 1 {
|
||||||
|
return fmt.Sprintf("%s %s", op, args[0])
|
||||||
|
}
|
||||||
|
args = append(args, args[0])
|
||||||
|
return op + " " + strings.Join(args[1:], ", ")
|
||||||
|
// store instructions always have the memory operand at the end, no need to reorder
|
||||||
|
case STB, STBU, STBX, STBUX,
|
||||||
|
STH, STHU, STHX, STHUX,
|
||||||
|
STW, STWU, STWX, STWUX,
|
||||||
|
STD, STDU, STDX, STDUX,
|
||||||
|
STQ,
|
||||||
|
STHBRX, STWBRX:
|
||||||
|
return op + " " + strings.Join(args, ", ")
|
||||||
|
// branch instructions needs additional handling
|
||||||
|
case BCLR:
|
||||||
|
if int(inst.Args[0].(Imm))&20 == 20 { // unconditional
|
||||||
|
return "RET"
|
||||||
|
}
|
||||||
|
return op + " " + strings.Join(args, ", ")
|
||||||
|
case BC:
|
||||||
|
if int(inst.Args[0].(Imm))&0x1c == 12 { // jump on cond bit set
|
||||||
|
return fmt.Sprintf("B%s %s", args[1], args[2])
|
||||||
|
} else if int(inst.Args[0].(Imm))&0x1c == 4 && revCondMap[args[1]] != "" { // jump on cond bit not set
|
||||||
|
return fmt.Sprintf("B%s %s", revCondMap[args[1]], args[2])
|
||||||
|
}
|
||||||
|
return op + " " + strings.Join(args, ", ")
|
||||||
|
case BCCTR:
|
||||||
|
if int(inst.Args[0].(Imm))&20 == 20 { // unconditional
|
||||||
|
return "BR (CTR)"
|
||||||
|
}
|
||||||
|
return op + " " + strings.Join(args, ", ")
|
||||||
|
case BCCTRL:
|
||||||
|
if int(inst.Args[0].(Imm))&20 == 20 { // unconditional
|
||||||
|
return "BL (CTR)"
|
||||||
|
}
|
||||||
|
return op + " " + strings.Join(args, ", ")
|
||||||
|
case BCA, BCL, BCLA, BCLRL, BCTAR, BCTARL:
|
||||||
|
return op + " " + strings.Join(args, ", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// plan9Arg formats arg (which is the argIndex's arg in inst) according to Plan 9 rules.
|
||||||
|
// NOTE: because Plan9Syntax is the only caller of this func, and it receives a copy
|
||||||
|
// of inst, it's ok to modify inst.Args here.
|
||||||
|
func plan9Arg(inst *Inst, argIndex int, pc uint64, arg Arg, symname func(uint64) (string, uint64)) string {
|
||||||
|
// special cases for load/store instructions
|
||||||
|
if _, ok := arg.(Offset); ok {
|
||||||
|
if argIndex+1 == len(inst.Args) || inst.Args[argIndex+1] == nil {
|
||||||
|
panic(fmt.Errorf("wrong table: offset not followed by register"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch arg := arg.(type) {
|
||||||
|
case Reg:
|
||||||
|
if isLoadStoreOp(inst.Op) && argIndex == 1 && arg == R0 {
|
||||||
|
return "0"
|
||||||
|
}
|
||||||
|
if arg == R30 {
|
||||||
|
return "g"
|
||||||
|
}
|
||||||
|
return strings.ToUpper(arg.String())
|
||||||
|
case CondReg:
|
||||||
|
if arg == CR0 && strings.HasPrefix(inst.Op.String(), "cmp") {
|
||||||
|
return "" // don't show cr0 for cmp instructions
|
||||||
|
} else if arg >= CR0 {
|
||||||
|
return fmt.Sprintf("CR%d", int(arg-CR0))
|
||||||
|
}
|
||||||
|
bit := [4]string{"LT", "GT", "EQ", "SO"}[(arg-Cond0LT)%4]
|
||||||
|
if arg <= Cond0SO {
|
||||||
|
return bit
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("4*CR%d+%s", int(arg-Cond0LT)/4, bit)
|
||||||
|
case Imm:
|
||||||
|
return fmt.Sprintf("$%d", arg)
|
||||||
|
case SpReg:
|
||||||
|
switch arg {
|
||||||
|
case 8:
|
||||||
|
return "LR"
|
||||||
|
case 9:
|
||||||
|
return "CTR"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("SPR(%d)", int(arg))
|
||||||
|
case PCRel:
|
||||||
|
addr := pc + uint64(int64(arg))
|
||||||
|
if s, base := symname(addr); s != "" && base == addr {
|
||||||
|
return fmt.Sprintf("%s(SB)", s)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%#x", addr)
|
||||||
|
case Label:
|
||||||
|
return fmt.Sprintf("%#x", int(arg))
|
||||||
|
case Offset:
|
||||||
|
reg := inst.Args[argIndex+1].(Reg)
|
||||||
|
removeArg(inst, argIndex+1)
|
||||||
|
if reg == R0 {
|
||||||
|
return fmt.Sprintf("%d(0)", int(arg))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%d(R%d)", int(arg), reg-R0)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("???(%v)", arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// revCondMap maps a conditional register bit to its inverse, if possible.
|
||||||
|
var revCondMap = map[string]string{
|
||||||
|
"LT": "GE", "GT": "LE", "EQ": "NE",
|
||||||
|
}
|
||||||
|
|
||||||
|
// plan9OpMap maps an Op to its Plan 9 mnemonics, if different than its GNU mnemonics.
|
||||||
|
var plan9OpMap = map[Op]string{
|
||||||
|
LWARX: "LWAR", STWCX_: "STWCCC",
|
||||||
|
LDARX: "LDAR", STDCX_: "STDCCC",
|
||||||
|
LHARX: "LHAR", STHCX_: "STHCCC",
|
||||||
|
LBARX: "LBAR", STBCX_: "STBCCC",
|
||||||
|
ADDI: "ADD",
|
||||||
|
ADD_: "ADDCC",
|
||||||
|
LBZ: "MOVBZ", STB: "MOVB",
|
||||||
|
LBZU: "MOVBZU", STBU: "MOVBU", // TODO(minux): indexed forms are not handled
|
||||||
|
LHZ: "MOVHZ", LHA: "MOVH", STH: "MOVH",
|
||||||
|
LHZU: "MOVHZU", STHU: "MOVHU",
|
||||||
|
LI: "MOVD",
|
||||||
|
LIS: "ADDIS",
|
||||||
|
LWZ: "MOVWZ", LWA: "MOVW", STW: "MOVW",
|
||||||
|
LWZU: "MOVWZU", STWU: "MOVWU",
|
||||||
|
LD: "MOVD", STD: "MOVD",
|
||||||
|
LDU: "MOVDU", STDU: "MOVDU",
|
||||||
|
MTSPR: "MOVD", MFSPR: "MOVD", // the width is ambiguous for SPRs
|
||||||
|
B: "BR",
|
||||||
|
BL: "CALL",
|
||||||
|
CMPLD: "CMPU", CMPLW: "CMPWU",
|
||||||
|
CMPD: "CMP", CMPW: "CMPW",
|
||||||
|
}
|
5421
vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go
generated
vendored
Normal file
5421
vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
27
vendor/golang.org/x/arch/x86/x86asm/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/arch/x86/x86asm/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2015 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
1724
vendor/golang.org/x/arch/x86/x86asm/decode.go
generated
vendored
Normal file
1724
vendor/golang.org/x/arch/x86/x86asm/decode.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
928
vendor/golang.org/x/arch/x86/x86asm/gnu.go
generated
vendored
Normal file
928
vendor/golang.org/x/arch/x86/x86asm/gnu.go
generated
vendored
Normal file
@ -0,0 +1,928 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package x86asm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils.
|
||||||
|
// This general form is often called ``AT&T syntax'' as a reference to AT&T System V Unix.
|
||||||
|
func GNUSyntax(inst Inst) string {
|
||||||
|
// Rewrite instruction to mimic GNU peculiarities.
|
||||||
|
// Note that inst has been passed by value and contains
|
||||||
|
// no pointers, so any changes we make here are local
|
||||||
|
// and will not propagate back out to the caller.
|
||||||
|
|
||||||
|
// Adjust opcode [sic].
|
||||||
|
switch inst.Op {
|
||||||
|
case FDIV, FDIVR, FSUB, FSUBR, FDIVP, FDIVRP, FSUBP, FSUBRP:
|
||||||
|
// DC E0, DC F0: libopcodes swaps FSUBR/FSUB and FDIVR/FDIV, at least
|
||||||
|
// if you believe the Intel manual is correct (the encoding is irregular as given;
|
||||||
|
// libopcodes uses the more regular expected encoding).
|
||||||
|
// TODO(rsc): Test to ensure Intel manuals are correct and report to libopcodes maintainers?
|
||||||
|
// NOTE: iant thinks this is deliberate, but we can't find the history.
|
||||||
|
_, reg1 := inst.Args[0].(Reg)
|
||||||
|
_, reg2 := inst.Args[1].(Reg)
|
||||||
|
if reg1 && reg2 && (inst.Opcode>>24 == 0xDC || inst.Opcode>>24 == 0xDE) {
|
||||||
|
switch inst.Op {
|
||||||
|
case FDIV:
|
||||||
|
inst.Op = FDIVR
|
||||||
|
case FDIVR:
|
||||||
|
inst.Op = FDIV
|
||||||
|
case FSUB:
|
||||||
|
inst.Op = FSUBR
|
||||||
|
case FSUBR:
|
||||||
|
inst.Op = FSUB
|
||||||
|
case FDIVP:
|
||||||
|
inst.Op = FDIVRP
|
||||||
|
case FDIVRP:
|
||||||
|
inst.Op = FDIVP
|
||||||
|
case FSUBP:
|
||||||
|
inst.Op = FSUBRP
|
||||||
|
case FSUBRP:
|
||||||
|
inst.Op = FSUBP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case MOVNTSD:
|
||||||
|
// MOVNTSD is F2 0F 2B /r.
|
||||||
|
// MOVNTSS is F3 0F 2B /r (supposedly; not in manuals).
|
||||||
|
// Usually inner prefixes win for display,
|
||||||
|
// so that F3 F2 0F 2B 11 is REP MOVNTSD
|
||||||
|
// and F2 F3 0F 2B 11 is REPN MOVNTSS.
|
||||||
|
// Libopcodes always prefers MOVNTSS regardless of prefix order.
|
||||||
|
if countPrefix(&inst, 0xF3) > 0 {
|
||||||
|
found := false
|
||||||
|
for i := len(inst.Prefix) - 1; i >= 0; i-- {
|
||||||
|
switch inst.Prefix[i] & 0xFF {
|
||||||
|
case 0xF3:
|
||||||
|
if !found {
|
||||||
|
found = true
|
||||||
|
inst.Prefix[i] |= PrefixImplicit
|
||||||
|
}
|
||||||
|
case 0xF2:
|
||||||
|
inst.Prefix[i] &^= PrefixImplicit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inst.Op = MOVNTSS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add implicit arguments.
|
||||||
|
switch inst.Op {
|
||||||
|
case MONITOR:
|
||||||
|
inst.Args[0] = EDX
|
||||||
|
inst.Args[1] = ECX
|
||||||
|
inst.Args[2] = EAX
|
||||||
|
if inst.AddrSize == 16 {
|
||||||
|
inst.Args[2] = AX
|
||||||
|
}
|
||||||
|
|
||||||
|
case MWAIT:
|
||||||
|
if inst.Mode == 64 {
|
||||||
|
inst.Args[0] = RCX
|
||||||
|
inst.Args[1] = RAX
|
||||||
|
} else {
|
||||||
|
inst.Args[0] = ECX
|
||||||
|
inst.Args[1] = EAX
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust which prefixes will be displayed.
|
||||||
|
// The rule is to display all the prefixes not implied by
|
||||||
|
// the usual instruction display, that is, all the prefixes
|
||||||
|
// except the ones with PrefixImplicit set.
|
||||||
|
// However, of course, there are exceptions to the rule.
|
||||||
|
switch inst.Op {
|
||||||
|
case CRC32:
|
||||||
|
// CRC32 has a mandatory F2 prefix.
|
||||||
|
// If there are multiple F2s and no F3s, the extra F2s do not print.
|
||||||
|
// (And Decode has already marked them implicit.)
|
||||||
|
// However, if there is an F3 anywhere, then the extra F2s do print.
|
||||||
|
// If there are multiple F2 prefixes *and* an (ignored) F3,
|
||||||
|
// then libopcodes prints the extra F2s as REPNs.
|
||||||
|
if countPrefix(&inst, 0xF2) > 1 {
|
||||||
|
unmarkImplicit(&inst, 0xF2)
|
||||||
|
markLastImplicit(&inst, 0xF2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// An unused data size override should probably be shown,
|
||||||
|
// to distinguish DATA16 CRC32B from plain CRC32B,
|
||||||
|
// but libopcodes always treats the final override as implicit
|
||||||
|
// and the others as explicit.
|
||||||
|
unmarkImplicit(&inst, PrefixDataSize)
|
||||||
|
markLastImplicit(&inst, PrefixDataSize)
|
||||||
|
|
||||||
|
case CVTSI2SD, CVTSI2SS:
|
||||||
|
if !isMem(inst.Args[1]) {
|
||||||
|
markLastImplicit(&inst, PrefixDataSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
case CVTSD2SI, CVTSS2SI, CVTTSD2SI, CVTTSS2SI,
|
||||||
|
ENTER, FLDENV, FNSAVE, FNSTENV, FRSTOR, LGDT, LIDT, LRET,
|
||||||
|
POP, PUSH, RET, SGDT, SIDT, SYSRET, XBEGIN:
|
||||||
|
markLastImplicit(&inst, PrefixDataSize)
|
||||||
|
|
||||||
|
case LOOP, LOOPE, LOOPNE, MONITOR:
|
||||||
|
markLastImplicit(&inst, PrefixAddrSize)
|
||||||
|
|
||||||
|
case MOV:
|
||||||
|
// The 16-bit and 32-bit forms of MOV Sreg, dst and MOV src, Sreg
|
||||||
|
// cannot be distinguished when src or dst refers to memory, because
|
||||||
|
// Sreg is always a 16-bit value, even when we're doing a 32-bit
|
||||||
|
// instruction. Because the instruction tables distinguished these two,
|
||||||
|
// any operand size prefix has been marked as used (to decide which
|
||||||
|
// branch to take). Unmark it, so that it will show up in disassembly,
|
||||||
|
// so that the reader can tell the size of memory operand.
|
||||||
|
// up with the same arguments
|
||||||
|
dst, _ := inst.Args[0].(Reg)
|
||||||
|
src, _ := inst.Args[1].(Reg)
|
||||||
|
if ES <= src && src <= GS && isMem(inst.Args[0]) || ES <= dst && dst <= GS && isMem(inst.Args[1]) {
|
||||||
|
unmarkImplicit(&inst, PrefixDataSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
case MOVDQU:
|
||||||
|
if countPrefix(&inst, 0xF3) > 1 {
|
||||||
|
unmarkImplicit(&inst, 0xF3)
|
||||||
|
markLastImplicit(&inst, 0xF3)
|
||||||
|
}
|
||||||
|
|
||||||
|
case MOVQ2DQ:
|
||||||
|
markLastImplicit(&inst, PrefixDataSize)
|
||||||
|
|
||||||
|
case SLDT, SMSW, STR, FXRSTOR, XRSTOR, XSAVE, XSAVEOPT, CMPXCHG8B:
|
||||||
|
if isMem(inst.Args[0]) {
|
||||||
|
unmarkImplicit(&inst, PrefixDataSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
case SYSEXIT:
|
||||||
|
unmarkImplicit(&inst, PrefixDataSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
if isCondJmp[inst.Op] || isLoop[inst.Op] || inst.Op == JCXZ || inst.Op == JECXZ || inst.Op == JRCXZ {
|
||||||
|
if countPrefix(&inst, PrefixCS) > 0 && countPrefix(&inst, PrefixDS) > 0 {
|
||||||
|
for i, p := range inst.Prefix {
|
||||||
|
switch p & 0xFFF {
|
||||||
|
case PrefixPN, PrefixPT:
|
||||||
|
inst.Prefix[i] &= 0xF0FF // cut interpretation bits, producing original segment prefix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// XACQUIRE/XRELEASE adjustment.
|
||||||
|
if inst.Op == MOV {
|
||||||
|
// MOV into memory is a candidate for turning REP into XRELEASE.
|
||||||
|
// However, if the REP is followed by a REPN, that REPN blocks the
|
||||||
|
// conversion.
|
||||||
|
haveREPN := false
|
||||||
|
for i := len(inst.Prefix) - 1; i >= 0; i-- {
|
||||||
|
switch inst.Prefix[i] &^ PrefixIgnored {
|
||||||
|
case PrefixREPN:
|
||||||
|
haveREPN = true
|
||||||
|
case PrefixXRELEASE:
|
||||||
|
if haveREPN {
|
||||||
|
inst.Prefix[i] = PrefixREP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We only format the final F2/F3 as XRELEASE/XACQUIRE.
|
||||||
|
haveXA := false
|
||||||
|
haveXR := false
|
||||||
|
for i := len(inst.Prefix) - 1; i >= 0; i-- {
|
||||||
|
switch inst.Prefix[i] &^ PrefixIgnored {
|
||||||
|
case PrefixXRELEASE:
|
||||||
|
if !haveXR {
|
||||||
|
haveXR = true
|
||||||
|
} else {
|
||||||
|
inst.Prefix[i] = PrefixREP
|
||||||
|
}
|
||||||
|
|
||||||
|
case PrefixXACQUIRE:
|
||||||
|
if !haveXA {
|
||||||
|
haveXA = true
|
||||||
|
} else {
|
||||||
|
inst.Prefix[i] = PrefixREPN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine opcode.
|
||||||
|
op := strings.ToLower(inst.Op.String())
|
||||||
|
if alt := gnuOp[inst.Op]; alt != "" {
|
||||||
|
op = alt
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine opcode suffix.
|
||||||
|
// Libopcodes omits the suffix if the width of the operation
|
||||||
|
// can be inferred from a register arguments. For example,
|
||||||
|
// add $1, %ebx has no suffix because you can tell from the
|
||||||
|
// 32-bit register destination that it is a 32-bit add,
|
||||||
|
// but in addl $1, (%ebx), the destination is memory, so the
|
||||||
|
// size is not evident without the l suffix.
|
||||||
|
needSuffix := true
|
||||||
|
SuffixLoop:
|
||||||
|
for i, a := range inst.Args {
|
||||||
|
if a == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
switch a := a.(type) {
|
||||||
|
case Reg:
|
||||||
|
switch inst.Op {
|
||||||
|
case MOVSX, MOVZX:
|
||||||
|
continue
|
||||||
|
|
||||||
|
case SHL, SHR, RCL, RCR, ROL, ROR, SAR:
|
||||||
|
if i == 1 {
|
||||||
|
// shift count does not tell us operand size
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
case CRC32:
|
||||||
|
// The source argument does tell us operand size,
|
||||||
|
// but libopcodes still always puts a suffix on crc32.
|
||||||
|
continue
|
||||||
|
|
||||||
|
case PUSH, POP:
|
||||||
|
// Even though segment registers are 16-bit, push and pop
|
||||||
|
// can save/restore them from 32-bit slots, so they
|
||||||
|
// do not imply operand size.
|
||||||
|
if ES <= a && a <= GS {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
case CVTSI2SD, CVTSI2SS:
|
||||||
|
// The integer register argument takes priority.
|
||||||
|
if X0 <= a && a <= X15 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if AL <= a && a <= R15 || ES <= a && a <= GS || X0 <= a && a <= X15 || M0 <= a && a <= M7 {
|
||||||
|
needSuffix = false
|
||||||
|
break SuffixLoop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if needSuffix {
|
||||||
|
switch inst.Op {
|
||||||
|
case CMPXCHG8B, FLDCW, FNSTCW, FNSTSW, LDMXCSR, LLDT, LMSW, LTR, PCLMULQDQ,
|
||||||
|
SETA, SETAE, SETB, SETBE, SETE, SETG, SETGE, SETL, SETLE, SETNE, SETNO, SETNP, SETNS, SETO, SETP, SETS,
|
||||||
|
SLDT, SMSW, STMXCSR, STR, VERR, VERW:
|
||||||
|
// For various reasons, libopcodes emits no suffix for these instructions.
|
||||||
|
|
||||||
|
case CRC32:
|
||||||
|
op += byteSizeSuffix(argBytes(&inst, inst.Args[1]))
|
||||||
|
|
||||||
|
case LGDT, LIDT, SGDT, SIDT:
|
||||||
|
op += byteSizeSuffix(inst.DataSize / 8)
|
||||||
|
|
||||||
|
case MOVZX, MOVSX:
|
||||||
|
// Integer size conversions get two suffixes.
|
||||||
|
op = op[:4] + byteSizeSuffix(argBytes(&inst, inst.Args[1])) + byteSizeSuffix(argBytes(&inst, inst.Args[0]))
|
||||||
|
|
||||||
|
case LOOP, LOOPE, LOOPNE:
|
||||||
|
// Add w suffix to indicate use of CX register instead of ECX.
|
||||||
|
if inst.AddrSize == 16 {
|
||||||
|
op += "w"
|
||||||
|
}
|
||||||
|
|
||||||
|
case CALL, ENTER, JMP, LCALL, LEAVE, LJMP, LRET, RET, SYSRET, XBEGIN:
|
||||||
|
// Add w suffix to indicate use of 16-bit target.
|
||||||
|
// Exclude JMP rel8.
|
||||||
|
if inst.Opcode>>24 == 0xEB {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if inst.DataSize == 16 && inst.Mode != 16 {
|
||||||
|
markLastImplicit(&inst, PrefixDataSize)
|
||||||
|
op += "w"
|
||||||
|
} else if inst.Mode == 64 {
|
||||||
|
op += "q"
|
||||||
|
}
|
||||||
|
|
||||||
|
case FRSTOR, FNSAVE, FNSTENV, FLDENV:
|
||||||
|
// Add s suffix to indicate shortened FPU state (I guess).
|
||||||
|
if inst.DataSize == 16 {
|
||||||
|
op += "s"
|
||||||
|
}
|
||||||
|
|
||||||
|
case PUSH, POP:
|
||||||
|
if markLastImplicit(&inst, PrefixDataSize) {
|
||||||
|
op += byteSizeSuffix(inst.DataSize / 8)
|
||||||
|
} else if inst.Mode == 64 {
|
||||||
|
op += "q"
|
||||||
|
} else {
|
||||||
|
op += byteSizeSuffix(inst.MemBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
if isFloat(inst.Op) {
|
||||||
|
// I can't explain any of this, but it's what libopcodes does.
|
||||||
|
switch inst.MemBytes {
|
||||||
|
default:
|
||||||
|
if (inst.Op == FLD || inst.Op == FSTP) && isMem(inst.Args[0]) {
|
||||||
|
op += "t"
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
if isFloatInt(inst.Op) {
|
||||||
|
op += "l"
|
||||||
|
} else {
|
||||||
|
op += "s"
|
||||||
|
}
|
||||||
|
case 8:
|
||||||
|
if isFloatInt(inst.Op) {
|
||||||
|
op += "ll"
|
||||||
|
} else {
|
||||||
|
op += "l"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
op += byteSizeSuffix(inst.MemBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust special case opcodes.
|
||||||
|
switch inst.Op {
|
||||||
|
case 0:
|
||||||
|
if inst.Prefix[0] != 0 {
|
||||||
|
return strings.ToLower(inst.Prefix[0].String())
|
||||||
|
}
|
||||||
|
|
||||||
|
case INT:
|
||||||
|
if inst.Opcode>>24 == 0xCC {
|
||||||
|
inst.Args[0] = nil
|
||||||
|
op = "int3"
|
||||||
|
}
|
||||||
|
|
||||||
|
case CMPPS, CMPPD, CMPSD_XMM, CMPSS:
|
||||||
|
imm, ok := inst.Args[2].(Imm)
|
||||||
|
if ok && 0 <= imm && imm < 8 {
|
||||||
|
inst.Args[2] = nil
|
||||||
|
op = cmppsOps[imm] + op[3:]
|
||||||
|
}
|
||||||
|
|
||||||
|
case PCLMULQDQ:
|
||||||
|
imm, ok := inst.Args[2].(Imm)
|
||||||
|
if ok && imm&^0x11 == 0 {
|
||||||
|
inst.Args[2] = nil
|
||||||
|
op = pclmulqOps[(imm&0x10)>>3|(imm&1)]
|
||||||
|
}
|
||||||
|
|
||||||
|
case XLATB:
|
||||||
|
if markLastImplicit(&inst, PrefixAddrSize) {
|
||||||
|
op = "xlat" // not xlatb
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build list of argument strings.
|
||||||
|
var (
|
||||||
|
usedPrefixes bool // segment prefixes consumed by Mem formatting
|
||||||
|
args []string // formatted arguments
|
||||||
|
)
|
||||||
|
for i, a := range inst.Args {
|
||||||
|
if a == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
switch inst.Op {
|
||||||
|
case MOVSB, MOVSW, MOVSD, MOVSQ, OUTSB, OUTSW, OUTSD:
|
||||||
|
if i == 0 {
|
||||||
|
usedPrefixes = true // disable use of prefixes for first argument
|
||||||
|
} else {
|
||||||
|
usedPrefixes = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if a == Imm(1) && (inst.Opcode>>24)&^1 == 0xD0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
args = append(args, gnuArg(&inst, a, &usedPrefixes))
|
||||||
|
}
|
||||||
|
|
||||||
|
// The default is to print the arguments in reverse Intel order.
|
||||||
|
// A few instructions inhibit this behavior.
|
||||||
|
switch inst.Op {
|
||||||
|
case BOUND, LCALL, ENTER, LJMP:
|
||||||
|
// no reverse
|
||||||
|
default:
|
||||||
|
// reverse args
|
||||||
|
for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
|
||||||
|
args[i], args[j] = args[j], args[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build prefix string.
|
||||||
|
// Must be after argument formatting, which can turn off segment prefixes.
|
||||||
|
var (
|
||||||
|
prefix = "" // output string
|
||||||
|
numAddr = 0
|
||||||
|
numData = 0
|
||||||
|
implicitData = false
|
||||||
|
)
|
||||||
|
for _, p := range inst.Prefix {
|
||||||
|
if p&0xFF == PrefixDataSize && p&PrefixImplicit != 0 {
|
||||||
|
implicitData = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, p := range inst.Prefix {
|
||||||
|
if p == 0 || p.IsVEX() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if p&PrefixImplicit != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch p &^ (PrefixIgnored | PrefixInvalid) {
|
||||||
|
default:
|
||||||
|
if p.IsREX() {
|
||||||
|
if p&0xFF == PrefixREX {
|
||||||
|
prefix += "rex "
|
||||||
|
} else {
|
||||||
|
prefix += "rex." + p.String()[4:] + " "
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
prefix += strings.ToLower(p.String()) + " "
|
||||||
|
|
||||||
|
case PrefixPN:
|
||||||
|
op += ",pn"
|
||||||
|
continue
|
||||||
|
|
||||||
|
case PrefixPT:
|
||||||
|
op += ",pt"
|
||||||
|
continue
|
||||||
|
|
||||||
|
case PrefixAddrSize, PrefixAddr16, PrefixAddr32:
|
||||||
|
// For unknown reasons, if the addr16 prefix is repeated,
|
||||||
|
// libopcodes displays all but the last as addr32, even though
|
||||||
|
// the addressing form used in a memory reference is clearly
|
||||||
|
// still 16-bit.
|
||||||
|
n := 32
|
||||||
|
if inst.Mode == 32 {
|
||||||
|
n = 16
|
||||||
|
}
|
||||||
|
numAddr++
|
||||||
|
if countPrefix(&inst, PrefixAddrSize) > numAddr {
|
||||||
|
n = inst.Mode
|
||||||
|
}
|
||||||
|
prefix += fmt.Sprintf("addr%d ", n)
|
||||||
|
continue
|
||||||
|
|
||||||
|
case PrefixData16, PrefixData32:
|
||||||
|
if implicitData && countPrefix(&inst, PrefixDataSize) > 1 {
|
||||||
|
// Similar to the addr32 logic above, but it only kicks in
|
||||||
|
// when something used the data size prefix (one is implicit).
|
||||||
|
n := 16
|
||||||
|
if inst.Mode == 16 {
|
||||||
|
n = 32
|
||||||
|
}
|
||||||
|
numData++
|
||||||
|
if countPrefix(&inst, PrefixDataSize) > numData {
|
||||||
|
if inst.Mode == 16 {
|
||||||
|
n = 16
|
||||||
|
} else {
|
||||||
|
n = 32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prefix += fmt.Sprintf("data%d ", n)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
prefix += strings.ToLower(p.String()) + " "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally! Put it all together.
|
||||||
|
text := prefix + op
|
||||||
|
if args != nil {
|
||||||
|
text += " "
|
||||||
|
// Indirect call/jmp gets a star to distinguish from direct jump address.
|
||||||
|
if (inst.Op == CALL || inst.Op == JMP || inst.Op == LJMP || inst.Op == LCALL) && (isMem(inst.Args[0]) || isReg(inst.Args[0])) {
|
||||||
|
text += "*"
|
||||||
|
}
|
||||||
|
text += strings.Join(args, ",")
|
||||||
|
}
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
|
// gnuArg returns the GNU syntax for the argument x from the instruction inst.
|
||||||
|
// If *usedPrefixes is false and x is a Mem, then the formatting
|
||||||
|
// includes any segment prefixes and sets *usedPrefixes to true.
|
||||||
|
func gnuArg(inst *Inst, x Arg, usedPrefixes *bool) string {
|
||||||
|
if x == nil {
|
||||||
|
return "<nil>"
|
||||||
|
}
|
||||||
|
switch x := x.(type) {
|
||||||
|
case Reg:
|
||||||
|
switch inst.Op {
|
||||||
|
case CVTSI2SS, CVTSI2SD, CVTSS2SI, CVTSD2SI, CVTTSD2SI, CVTTSS2SI:
|
||||||
|
if inst.DataSize == 16 && EAX <= x && x <= R15L {
|
||||||
|
x -= EAX - AX
|
||||||
|
}
|
||||||
|
|
||||||
|
case IN, INSB, INSW, INSD, OUT, OUTSB, OUTSW, OUTSD:
|
||||||
|
// DX is the port, but libopcodes prints it as if it were a memory reference.
|
||||||
|
if x == DX {
|
||||||
|
return "(%dx)"
|
||||||
|
}
|
||||||
|
case VMOVDQA, VMOVDQU, VMOVNTDQA, VMOVNTDQ:
|
||||||
|
return strings.Replace(gccRegName[x], "xmm", "ymm", -1)
|
||||||
|
}
|
||||||
|
return gccRegName[x]
|
||||||
|
case Mem:
|
||||||
|
seg := ""
|
||||||
|
var haveCS, haveDS, haveES, haveFS, haveGS, haveSS bool
|
||||||
|
switch x.Segment {
|
||||||
|
case CS:
|
||||||
|
haveCS = true
|
||||||
|
case DS:
|
||||||
|
haveDS = true
|
||||||
|
case ES:
|
||||||
|
haveES = true
|
||||||
|
case FS:
|
||||||
|
haveFS = true
|
||||||
|
case GS:
|
||||||
|
haveGS = true
|
||||||
|
case SS:
|
||||||
|
haveSS = true
|
||||||
|
}
|
||||||
|
switch inst.Op {
|
||||||
|
case INSB, INSW, INSD, STOSB, STOSW, STOSD, STOSQ, SCASB, SCASW, SCASD, SCASQ:
|
||||||
|
// These do not accept segment prefixes, at least in the GNU rendering.
|
||||||
|
default:
|
||||||
|
if *usedPrefixes {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for i := len(inst.Prefix) - 1; i >= 0; i-- {
|
||||||
|
p := inst.Prefix[i] &^ PrefixIgnored
|
||||||
|
if p == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch p {
|
||||||
|
case PrefixCS:
|
||||||
|
if !haveCS {
|
||||||
|
haveCS = true
|
||||||
|
inst.Prefix[i] |= PrefixImplicit
|
||||||
|
}
|
||||||
|
case PrefixDS:
|
||||||
|
if !haveDS {
|
||||||
|
haveDS = true
|
||||||
|
inst.Prefix[i] |= PrefixImplicit
|
||||||
|
}
|
||||||
|
case PrefixES:
|
||||||
|
if !haveES {
|
||||||
|
haveES = true
|
||||||
|
inst.Prefix[i] |= PrefixImplicit
|
||||||
|
}
|
||||||
|
case PrefixFS:
|
||||||
|
if !haveFS {
|
||||||
|
haveFS = true
|
||||||
|
inst.Prefix[i] |= PrefixImplicit
|
||||||
|
}
|
||||||
|
case PrefixGS:
|
||||||
|
if !haveGS {
|
||||||
|
haveGS = true
|
||||||
|
inst.Prefix[i] |= PrefixImplicit
|
||||||
|
}
|
||||||
|
case PrefixSS:
|
||||||
|
if !haveSS {
|
||||||
|
haveSS = true
|
||||||
|
inst.Prefix[i] |= PrefixImplicit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*usedPrefixes = true
|
||||||
|
}
|
||||||
|
if haveCS {
|
||||||
|
seg += "%cs:"
|
||||||
|
}
|
||||||
|
if haveDS {
|
||||||
|
seg += "%ds:"
|
||||||
|
}
|
||||||
|
if haveSS {
|
||||||
|
seg += "%ss:"
|
||||||
|
}
|
||||||
|
if haveES {
|
||||||
|
seg += "%es:"
|
||||||
|
}
|
||||||
|
if haveFS {
|
||||||
|
seg += "%fs:"
|
||||||
|
}
|
||||||
|
if haveGS {
|
||||||
|
seg += "%gs:"
|
||||||
|
}
|
||||||
|
disp := ""
|
||||||
|
if x.Disp != 0 {
|
||||||
|
disp = fmt.Sprintf("%#x", x.Disp)
|
||||||
|
}
|
||||||
|
if x.Scale == 0 || x.Index == 0 && x.Scale == 1 && (x.Base == ESP || x.Base == RSP || x.Base == 0 && inst.Mode == 64) {
|
||||||
|
if x.Base == 0 {
|
||||||
|
return seg + disp
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s%s(%s)", seg, disp, gccRegName[x.Base])
|
||||||
|
}
|
||||||
|
base := gccRegName[x.Base]
|
||||||
|
if x.Base == 0 {
|
||||||
|
base = ""
|
||||||
|
}
|
||||||
|
index := gccRegName[x.Index]
|
||||||
|
if x.Index == 0 {
|
||||||
|
if inst.AddrSize == 64 {
|
||||||
|
index = "%riz"
|
||||||
|
} else {
|
||||||
|
index = "%eiz"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if AX <= x.Base && x.Base <= DI {
|
||||||
|
// 16-bit addressing - no scale
|
||||||
|
return fmt.Sprintf("%s%s(%s,%s)", seg, disp, base, index)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s%s(%s,%s,%d)", seg, disp, base, index, x.Scale)
|
||||||
|
case Rel:
|
||||||
|
return fmt.Sprintf(".%+#x", int32(x))
|
||||||
|
case Imm:
|
||||||
|
if inst.Mode == 32 {
|
||||||
|
return fmt.Sprintf("$%#x", uint32(x))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("$%#x", int64(x))
|
||||||
|
}
|
||||||
|
return x.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
var gccRegName = [...]string{
|
||||||
|
0: "REG0",
|
||||||
|
AL: "%al",
|
||||||
|
CL: "%cl",
|
||||||
|
BL: "%bl",
|
||||||
|
DL: "%dl",
|
||||||
|
AH: "%ah",
|
||||||
|
CH: "%ch",
|
||||||
|
BH: "%bh",
|
||||||
|
DH: "%dh",
|
||||||
|
SPB: "%spl",
|
||||||
|
BPB: "%bpl",
|
||||||
|
SIB: "%sil",
|
||||||
|
DIB: "%dil",
|
||||||
|
R8B: "%r8b",
|
||||||
|
R9B: "%r9b",
|
||||||
|
R10B: "%r10b",
|
||||||
|
R11B: "%r11b",
|
||||||
|
R12B: "%r12b",
|
||||||
|
R13B: "%r13b",
|
||||||
|
R14B: "%r14b",
|
||||||
|
R15B: "%r15b",
|
||||||
|
AX: "%ax",
|
||||||
|
CX: "%cx",
|
||||||
|
BX: "%bx",
|
||||||
|
DX: "%dx",
|
||||||
|
SP: "%sp",
|
||||||
|
BP: "%bp",
|
||||||
|
SI: "%si",
|
||||||
|
DI: "%di",
|
||||||
|
R8W: "%r8w",
|
||||||
|
R9W: "%r9w",
|
||||||
|
R10W: "%r10w",
|
||||||
|
R11W: "%r11w",
|
||||||
|
R12W: "%r12w",
|
||||||
|
R13W: "%r13w",
|
||||||
|
R14W: "%r14w",
|
||||||
|
R15W: "%r15w",
|
||||||
|
EAX: "%eax",
|
||||||
|
ECX: "%ecx",
|
||||||
|
EDX: "%edx",
|
||||||
|
EBX: "%ebx",
|
||||||
|
ESP: "%esp",
|
||||||
|
EBP: "%ebp",
|
||||||
|
ESI: "%esi",
|
||||||
|
EDI: "%edi",
|
||||||
|
R8L: "%r8d",
|
||||||
|
R9L: "%r9d",
|
||||||
|
R10L: "%r10d",
|
||||||
|
R11L: "%r11d",
|
||||||
|
R12L: "%r12d",
|
||||||
|
R13L: "%r13d",
|
||||||
|
R14L: "%r14d",
|
||||||
|
R15L: "%r15d",
|
||||||
|
RAX: "%rax",
|
||||||
|
RCX: "%rcx",
|
||||||
|
RDX: "%rdx",
|
||||||
|
RBX: "%rbx",
|
||||||
|
RSP: "%rsp",
|
||||||
|
RBP: "%rbp",
|
||||||
|
RSI: "%rsi",
|
||||||
|
RDI: "%rdi",
|
||||||
|
R8: "%r8",
|
||||||
|
R9: "%r9",
|
||||||
|
R10: "%r10",
|
||||||
|
R11: "%r11",
|
||||||
|
R12: "%r12",
|
||||||
|
R13: "%r13",
|
||||||
|
R14: "%r14",
|
||||||
|
R15: "%r15",
|
||||||
|
IP: "%ip",
|
||||||
|
EIP: "%eip",
|
||||||
|
RIP: "%rip",
|
||||||
|
F0: "%st",
|
||||||
|
F1: "%st(1)",
|
||||||
|
F2: "%st(2)",
|
||||||
|
F3: "%st(3)",
|
||||||
|
F4: "%st(4)",
|
||||||
|
F5: "%st(5)",
|
||||||
|
F6: "%st(6)",
|
||||||
|
F7: "%st(7)",
|
||||||
|
M0: "%mm0",
|
||||||
|
M1: "%mm1",
|
||||||
|
M2: "%mm2",
|
||||||
|
M3: "%mm3",
|
||||||
|
M4: "%mm4",
|
||||||
|
M5: "%mm5",
|
||||||
|
M6: "%mm6",
|
||||||
|
M7: "%mm7",
|
||||||
|
X0: "%xmm0",
|
||||||
|
X1: "%xmm1",
|
||||||
|
X2: "%xmm2",
|
||||||
|
X3: "%xmm3",
|
||||||
|
X4: "%xmm4",
|
||||||
|
X5: "%xmm5",
|
||||||
|
X6: "%xmm6",
|
||||||
|
X7: "%xmm7",
|
||||||
|
X8: "%xmm8",
|
||||||
|
X9: "%xmm9",
|
||||||
|
X10: "%xmm10",
|
||||||
|
X11: "%xmm11",
|
||||||
|
X12: "%xmm12",
|
||||||
|
X13: "%xmm13",
|
||||||
|
X14: "%xmm14",
|
||||||
|
X15: "%xmm15",
|
||||||
|
CS: "%cs",
|
||||||
|
SS: "%ss",
|
||||||
|
DS: "%ds",
|
||||||
|
ES: "%es",
|
||||||
|
FS: "%fs",
|
||||||
|
GS: "%gs",
|
||||||
|
GDTR: "%gdtr",
|
||||||
|
IDTR: "%idtr",
|
||||||
|
LDTR: "%ldtr",
|
||||||
|
MSW: "%msw",
|
||||||
|
TASK: "%task",
|
||||||
|
CR0: "%cr0",
|
||||||
|
CR1: "%cr1",
|
||||||
|
CR2: "%cr2",
|
||||||
|
CR3: "%cr3",
|
||||||
|
CR4: "%cr4",
|
||||||
|
CR5: "%cr5",
|
||||||
|
CR6: "%cr6",
|
||||||
|
CR7: "%cr7",
|
||||||
|
CR8: "%cr8",
|
||||||
|
CR9: "%cr9",
|
||||||
|
CR10: "%cr10",
|
||||||
|
CR11: "%cr11",
|
||||||
|
CR12: "%cr12",
|
||||||
|
CR13: "%cr13",
|
||||||
|
CR14: "%cr14",
|
||||||
|
CR15: "%cr15",
|
||||||
|
DR0: "%db0",
|
||||||
|
DR1: "%db1",
|
||||||
|
DR2: "%db2",
|
||||||
|
DR3: "%db3",
|
||||||
|
DR4: "%db4",
|
||||||
|
DR5: "%db5",
|
||||||
|
DR6: "%db6",
|
||||||
|
DR7: "%db7",
|
||||||
|
TR0: "%tr0",
|
||||||
|
TR1: "%tr1",
|
||||||
|
TR2: "%tr2",
|
||||||
|
TR3: "%tr3",
|
||||||
|
TR4: "%tr4",
|
||||||
|
TR5: "%tr5",
|
||||||
|
TR6: "%tr6",
|
||||||
|
TR7: "%tr7",
|
||||||
|
}
|
||||||
|
|
||||||
|
var gnuOp = map[Op]string{
|
||||||
|
CBW: "cbtw",
|
||||||
|
CDQ: "cltd",
|
||||||
|
CMPSD: "cmpsl",
|
||||||
|
CMPSD_XMM: "cmpsd",
|
||||||
|
CWD: "cwtd",
|
||||||
|
CWDE: "cwtl",
|
||||||
|
CQO: "cqto",
|
||||||
|
INSD: "insl",
|
||||||
|
IRET: "iretw",
|
||||||
|
IRETD: "iret",
|
||||||
|
IRETQ: "iretq",
|
||||||
|
LODSB: "lods",
|
||||||
|
LODSD: "lods",
|
||||||
|
LODSQ: "lods",
|
||||||
|
LODSW: "lods",
|
||||||
|
MOVSD: "movsl",
|
||||||
|
MOVSD_XMM: "movsd",
|
||||||
|
OUTSD: "outsl",
|
||||||
|
POPA: "popaw",
|
||||||
|
POPAD: "popa",
|
||||||
|
POPF: "popfw",
|
||||||
|
POPFD: "popf",
|
||||||
|
PUSHA: "pushaw",
|
||||||
|
PUSHAD: "pusha",
|
||||||
|
PUSHF: "pushfw",
|
||||||
|
PUSHFD: "pushf",
|
||||||
|
SCASB: "scas",
|
||||||
|
SCASD: "scas",
|
||||||
|
SCASQ: "scas",
|
||||||
|
SCASW: "scas",
|
||||||
|
STOSB: "stos",
|
||||||
|
STOSD: "stos",
|
||||||
|
STOSQ: "stos",
|
||||||
|
STOSW: "stos",
|
||||||
|
XLATB: "xlat",
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmppsOps = []string{
|
||||||
|
"cmpeq",
|
||||||
|
"cmplt",
|
||||||
|
"cmple",
|
||||||
|
"cmpunord",
|
||||||
|
"cmpneq",
|
||||||
|
"cmpnlt",
|
||||||
|
"cmpnle",
|
||||||
|
"cmpord",
|
||||||
|
}
|
||||||
|
|
||||||
|
var pclmulqOps = []string{
|
||||||
|
"pclmullqlqdq",
|
||||||
|
"pclmulhqlqdq",
|
||||||
|
"pclmullqhqdq",
|
||||||
|
"pclmulhqhqdq",
|
||||||
|
}
|
||||||
|
|
||||||
|
func countPrefix(inst *Inst, target Prefix) int {
|
||||||
|
n := 0
|
||||||
|
for _, p := range inst.Prefix {
|
||||||
|
if p&0xFF == target&0xFF {
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func markLastImplicit(inst *Inst, prefix Prefix) bool {
|
||||||
|
for i := len(inst.Prefix) - 1; i >= 0; i-- {
|
||||||
|
p := inst.Prefix[i]
|
||||||
|
if p&0xFF == prefix {
|
||||||
|
inst.Prefix[i] |= PrefixImplicit
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func unmarkImplicit(inst *Inst, prefix Prefix) {
|
||||||
|
for i := len(inst.Prefix) - 1; i >= 0; i-- {
|
||||||
|
p := inst.Prefix[i]
|
||||||
|
if p&0xFF == prefix {
|
||||||
|
inst.Prefix[i] &^= PrefixImplicit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func byteSizeSuffix(b int) string {
|
||||||
|
switch b {
|
||||||
|
case 1:
|
||||||
|
return "b"
|
||||||
|
case 2:
|
||||||
|
return "w"
|
||||||
|
case 4:
|
||||||
|
return "l"
|
||||||
|
case 8:
|
||||||
|
return "q"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func argBytes(inst *Inst, arg Arg) int {
|
||||||
|
if isMem(arg) {
|
||||||
|
return inst.MemBytes
|
||||||
|
}
|
||||||
|
return regBytes(arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isFloat(op Op) bool {
|
||||||
|
switch op {
|
||||||
|
case FADD, FCOM, FCOMP, FDIV, FDIVR, FIADD, FICOM, FICOMP, FIDIV, FIDIVR, FILD, FIMUL, FIST, FISTP, FISTTP, FISUB, FISUBR, FLD, FMUL, FST, FSTP, FSUB, FSUBR:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isFloatInt(op Op) bool {
|
||||||
|
switch op {
|
||||||
|
case FIADD, FICOM, FICOMP, FIDIV, FIDIVR, FILD, FIMUL, FIST, FISTP, FISTTP, FISUB, FISUBR:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
649
vendor/golang.org/x/arch/x86/x86asm/inst.go
generated
vendored
Normal file
649
vendor/golang.org/x/arch/x86/x86asm/inst.go
generated
vendored
Normal file
@ -0,0 +1,649 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package x86asm implements decoding of x86 machine code.
|
||||||
|
package x86asm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// An Inst is a single instruction.
|
||||||
|
type Inst struct {
|
||||||
|
Prefix Prefixes // Prefixes applied to the instruction.
|
||||||
|
Op Op // Opcode mnemonic
|
||||||
|
Opcode uint32 // Encoded opcode bits, left aligned (first byte is Opcode>>24, etc)
|
||||||
|
Args Args // Instruction arguments, in Intel order
|
||||||
|
Mode int // processor mode in bits: 16, 32, or 64
|
||||||
|
AddrSize int // address size in bits: 16, 32, or 64
|
||||||
|
DataSize int // operand size in bits: 16, 32, or 64
|
||||||
|
MemBytes int // size of memory argument in bytes: 1, 2, 4, 8, 16, and so on.
|
||||||
|
Len int // length of encoded instruction in bytes
|
||||||
|
PCRel int // length of PC-relative address in instruction encoding
|
||||||
|
PCRelOff int // index of start of PC-relative address in instruction encoding
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prefixes is an array of prefixes associated with a single instruction.
|
||||||
|
// The prefixes are listed in the same order as found in the instruction:
|
||||||
|
// each prefix byte corresponds to one slot in the array. The first zero
|
||||||
|
// in the array marks the end of the prefixes.
|
||||||
|
type Prefixes [14]Prefix
|
||||||
|
|
||||||
|
// A Prefix represents an Intel instruction prefix.
|
||||||
|
// The low 8 bits are the actual prefix byte encoding,
|
||||||
|
// and the top 8 bits contain distinguishing bits and metadata.
|
||||||
|
type Prefix uint16
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Metadata about the role of a prefix in an instruction.
|
||||||
|
PrefixImplicit Prefix = 0x8000 // prefix is implied by instruction text
|
||||||
|
PrefixIgnored Prefix = 0x4000 // prefix is ignored: either irrelevant or overridden by a later prefix
|
||||||
|
PrefixInvalid Prefix = 0x2000 // prefix makes entire instruction invalid (bad LOCK)
|
||||||
|
|
||||||
|
// Memory segment overrides.
|
||||||
|
PrefixES Prefix = 0x26 // ES segment override
|
||||||
|
PrefixCS Prefix = 0x2E // CS segment override
|
||||||
|
PrefixSS Prefix = 0x36 // SS segment override
|
||||||
|
PrefixDS Prefix = 0x3E // DS segment override
|
||||||
|
PrefixFS Prefix = 0x64 // FS segment override
|
||||||
|
PrefixGS Prefix = 0x65 // GS segment override
|
||||||
|
|
||||||
|
// Branch prediction.
|
||||||
|
PrefixPN Prefix = 0x12E // predict not taken (conditional branch only)
|
||||||
|
PrefixPT Prefix = 0x13E // predict taken (conditional branch only)
|
||||||
|
|
||||||
|
// Size attributes.
|
||||||
|
PrefixDataSize Prefix = 0x66 // operand size override
|
||||||
|
PrefixData16 Prefix = 0x166
|
||||||
|
PrefixData32 Prefix = 0x266
|
||||||
|
PrefixAddrSize Prefix = 0x67 // address size override
|
||||||
|
PrefixAddr16 Prefix = 0x167
|
||||||
|
PrefixAddr32 Prefix = 0x267
|
||||||
|
|
||||||
|
// One of a kind.
|
||||||
|
PrefixLOCK Prefix = 0xF0 // lock
|
||||||
|
PrefixREPN Prefix = 0xF2 // repeat not zero
|
||||||
|
PrefixXACQUIRE Prefix = 0x1F2
|
||||||
|
PrefixBND Prefix = 0x2F2
|
||||||
|
PrefixREP Prefix = 0xF3 // repeat
|
||||||
|
PrefixXRELEASE Prefix = 0x1F3
|
||||||
|
|
||||||
|
// The REX prefixes must be in the range [PrefixREX, PrefixREX+0x10).
|
||||||
|
// the other bits are set or not according to the intended use.
|
||||||
|
PrefixREX Prefix = 0x40 // REX 64-bit extension prefix
|
||||||
|
PrefixREXW Prefix = 0x08 // extension bit W (64-bit instruction width)
|
||||||
|
PrefixREXR Prefix = 0x04 // extension bit R (r field in modrm)
|
||||||
|
PrefixREXX Prefix = 0x02 // extension bit X (index field in sib)
|
||||||
|
PrefixREXB Prefix = 0x01 // extension bit B (r/m field in modrm or base field in sib)
|
||||||
|
PrefixVEX2Bytes Prefix = 0xC5 // Short form of vex prefix
|
||||||
|
PrefixVEX3Bytes Prefix = 0xC4 // Long form of vex prefix
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsREX reports whether p is a REX prefix byte.
|
||||||
|
func (p Prefix) IsREX() bool {
|
||||||
|
return p&0xF0 == PrefixREX
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Prefix) IsVEX() bool {
|
||||||
|
return p&0xFF == PrefixVEX2Bytes || p&0xFF == PrefixVEX3Bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Prefix) String() string {
|
||||||
|
p &^= PrefixImplicit | PrefixIgnored | PrefixInvalid
|
||||||
|
if s := prefixNames[p]; s != "" {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.IsREX() {
|
||||||
|
s := "REX."
|
||||||
|
if p&PrefixREXW != 0 {
|
||||||
|
s += "W"
|
||||||
|
}
|
||||||
|
if p&PrefixREXR != 0 {
|
||||||
|
s += "R"
|
||||||
|
}
|
||||||
|
if p&PrefixREXX != 0 {
|
||||||
|
s += "X"
|
||||||
|
}
|
||||||
|
if p&PrefixREXB != 0 {
|
||||||
|
s += "B"
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("Prefix(%#x)", int(p))
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Op is an x86 opcode.
|
||||||
|
type Op uint32
|
||||||
|
|
||||||
|
func (op Op) String() string {
|
||||||
|
i := int(op)
|
||||||
|
if i < 0 || i >= len(opNames) || opNames[i] == "" {
|
||||||
|
return fmt.Sprintf("Op(%d)", i)
|
||||||
|
}
|
||||||
|
return opNames[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Args holds the instruction arguments.
|
||||||
|
// If an instruction has fewer than 4 arguments,
|
||||||
|
// the final elements in the array are nil.
|
||||||
|
type Args [4]Arg
|
||||||
|
|
||||||
|
// An Arg is a single instruction argument,
|
||||||
|
// one of these types: Reg, Mem, Imm, Rel.
|
||||||
|
type Arg interface {
|
||||||
|
String() string
|
||||||
|
isArg()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that the implements of Arg that follow are all sized
|
||||||
|
// so that on a 64-bit machine the data can be inlined in
|
||||||
|
// the interface value instead of requiring an allocation.
|
||||||
|
|
||||||
|
// A Reg is a single register.
|
||||||
|
// The zero Reg value has no name but indicates ``no register.''
|
||||||
|
type Reg uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ Reg = iota
|
||||||
|
|
||||||
|
// 8-bit
|
||||||
|
AL
|
||||||
|
CL
|
||||||
|
DL
|
||||||
|
BL
|
||||||
|
AH
|
||||||
|
CH
|
||||||
|
DH
|
||||||
|
BH
|
||||||
|
SPB
|
||||||
|
BPB
|
||||||
|
SIB
|
||||||
|
DIB
|
||||||
|
R8B
|
||||||
|
R9B
|
||||||
|
R10B
|
||||||
|
R11B
|
||||||
|
R12B
|
||||||
|
R13B
|
||||||
|
R14B
|
||||||
|
R15B
|
||||||
|
|
||||||
|
// 16-bit
|
||||||
|
AX
|
||||||
|
CX
|
||||||
|
DX
|
||||||
|
BX
|
||||||
|
SP
|
||||||
|
BP
|
||||||
|
SI
|
||||||
|
DI
|
||||||
|
R8W
|
||||||
|
R9W
|
||||||
|
R10W
|
||||||
|
R11W
|
||||||
|
R12W
|
||||||
|
R13W
|
||||||
|
R14W
|
||||||
|
R15W
|
||||||
|
|
||||||
|
// 32-bit
|
||||||
|
EAX
|
||||||
|
ECX
|
||||||
|
EDX
|
||||||
|
EBX
|
||||||
|
ESP
|
||||||
|
EBP
|
||||||
|
ESI
|
||||||
|
EDI
|
||||||
|
R8L
|
||||||
|
R9L
|
||||||
|
R10L
|
||||||
|
R11L
|
||||||
|
R12L
|
||||||
|
R13L
|
||||||
|
R14L
|
||||||
|
R15L
|
||||||
|
|
||||||
|
// 64-bit
|
||||||
|
RAX
|
||||||
|
RCX
|
||||||
|
RDX
|
||||||
|
RBX
|
||||||
|
RSP
|
||||||
|
RBP
|
||||||
|
RSI
|
||||||
|
RDI
|
||||||
|
R8
|
||||||
|
R9
|
||||||
|
R10
|
||||||
|
R11
|
||||||
|
R12
|
||||||
|
R13
|
||||||
|
R14
|
||||||
|
R15
|
||||||
|
|
||||||
|
// Instruction pointer.
|
||||||
|
IP // 16-bit
|
||||||
|
EIP // 32-bit
|
||||||
|
RIP // 64-bit
|
||||||
|
|
||||||
|
// 387 floating point registers.
|
||||||
|
F0
|
||||||
|
F1
|
||||||
|
F2
|
||||||
|
F3
|
||||||
|
F4
|
||||||
|
F5
|
||||||
|
F6
|
||||||
|
F7
|
||||||
|
|
||||||
|
// MMX registers.
|
||||||
|
M0
|
||||||
|
M1
|
||||||
|
M2
|
||||||
|
M3
|
||||||
|
M4
|
||||||
|
M5
|
||||||
|
M6
|
||||||
|
M7
|
||||||
|
|
||||||
|
// XMM registers.
|
||||||
|
X0
|
||||||
|
X1
|
||||||
|
X2
|
||||||
|
X3
|
||||||
|
X4
|
||||||
|
X5
|
||||||
|
X6
|
||||||
|
X7
|
||||||
|
X8
|
||||||
|
X9
|
||||||
|
X10
|
||||||
|
X11
|
||||||
|
X12
|
||||||
|
X13
|
||||||
|
X14
|
||||||
|
X15
|
||||||
|
|
||||||
|
// Segment registers.
|
||||||
|
ES
|
||||||
|
CS
|
||||||
|
SS
|
||||||
|
DS
|
||||||
|
FS
|
||||||
|
GS
|
||||||
|
|
||||||
|
// System registers.
|
||||||
|
GDTR
|
||||||
|
IDTR
|
||||||
|
LDTR
|
||||||
|
MSW
|
||||||
|
TASK
|
||||||
|
|
||||||
|
// Control registers.
|
||||||
|
CR0
|
||||||
|
CR1
|
||||||
|
CR2
|
||||||
|
CR3
|
||||||
|
CR4
|
||||||
|
CR5
|
||||||
|
CR6
|
||||||
|
CR7
|
||||||
|
CR8
|
||||||
|
CR9
|
||||||
|
CR10
|
||||||
|
CR11
|
||||||
|
CR12
|
||||||
|
CR13
|
||||||
|
CR14
|
||||||
|
CR15
|
||||||
|
|
||||||
|
// Debug registers.
|
||||||
|
DR0
|
||||||
|
DR1
|
||||||
|
DR2
|
||||||
|
DR3
|
||||||
|
DR4
|
||||||
|
DR5
|
||||||
|
DR6
|
||||||
|
DR7
|
||||||
|
DR8
|
||||||
|
DR9
|
||||||
|
DR10
|
||||||
|
DR11
|
||||||
|
DR12
|
||||||
|
DR13
|
||||||
|
DR14
|
||||||
|
DR15
|
||||||
|
|
||||||
|
// Task registers.
|
||||||
|
TR0
|
||||||
|
TR1
|
||||||
|
TR2
|
||||||
|
TR3
|
||||||
|
TR4
|
||||||
|
TR5
|
||||||
|
TR6
|
||||||
|
TR7
|
||||||
|
)
|
||||||
|
|
||||||
|
const regMax = TR7
|
||||||
|
|
||||||
|
func (Reg) isArg() {}
|
||||||
|
|
||||||
|
func (r Reg) String() string {
|
||||||
|
i := int(r)
|
||||||
|
if i < 0 || i >= len(regNames) || regNames[i] == "" {
|
||||||
|
return fmt.Sprintf("Reg(%d)", i)
|
||||||
|
}
|
||||||
|
return regNames[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Mem is a memory reference.
|
||||||
|
// The general form is Segment:[Base+Scale*Index+Disp].
|
||||||
|
type Mem struct {
|
||||||
|
Segment Reg
|
||||||
|
Base Reg
|
||||||
|
Scale uint8
|
||||||
|
Index Reg
|
||||||
|
Disp int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Mem) isArg() {}
|
||||||
|
|
||||||
|
func (m Mem) String() string {
|
||||||
|
var base, plus, scale, index, disp string
|
||||||
|
|
||||||
|
if m.Base != 0 {
|
||||||
|
base = m.Base.String()
|
||||||
|
}
|
||||||
|
if m.Scale != 0 {
|
||||||
|
if m.Base != 0 {
|
||||||
|
plus = "+"
|
||||||
|
}
|
||||||
|
if m.Scale > 1 {
|
||||||
|
scale = fmt.Sprintf("%d*", m.Scale)
|
||||||
|
}
|
||||||
|
index = m.Index.String()
|
||||||
|
}
|
||||||
|
if m.Disp != 0 || m.Base == 0 && m.Scale == 0 {
|
||||||
|
disp = fmt.Sprintf("%+#x", m.Disp)
|
||||||
|
}
|
||||||
|
return "[" + base + plus + scale + index + disp + "]"
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Rel is an offset relative to the current instruction pointer.
|
||||||
|
type Rel int32
|
||||||
|
|
||||||
|
func (Rel) isArg() {}
|
||||||
|
|
||||||
|
func (r Rel) String() string {
|
||||||
|
return fmt.Sprintf(".%+d", r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Imm is an integer constant.
|
||||||
|
type Imm int64
|
||||||
|
|
||||||
|
func (Imm) isArg() {}
|
||||||
|
|
||||||
|
func (i Imm) String() string {
|
||||||
|
return fmt.Sprintf("%#x", int64(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i Inst) String() string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
for _, p := range i.Prefix {
|
||||||
|
if p == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if p&PrefixImplicit != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Fprintf(&buf, "%v ", p)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(&buf, "%v", i.Op)
|
||||||
|
sep := " "
|
||||||
|
for _, v := range i.Args {
|
||||||
|
if v == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fmt.Fprintf(&buf, "%s%v", sep, v)
|
||||||
|
sep = ", "
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func isReg(a Arg) bool {
|
||||||
|
_, ok := a.(Reg)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSegReg(a Arg) bool {
|
||||||
|
r, ok := a.(Reg)
|
||||||
|
return ok && ES <= r && r <= GS
|
||||||
|
}
|
||||||
|
|
||||||
|
func isMem(a Arg) bool {
|
||||||
|
_, ok := a.(Mem)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func isImm(a Arg) bool {
|
||||||
|
_, ok := a.(Imm)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func regBytes(a Arg) int {
|
||||||
|
r, ok := a.(Reg)
|
||||||
|
if !ok {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if AL <= r && r <= R15B {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if AX <= r && r <= R15W {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
if EAX <= r && r <= R15L {
|
||||||
|
return 4
|
||||||
|
}
|
||||||
|
if RAX <= r && r <= R15 {
|
||||||
|
return 8
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSegment(p Prefix) bool {
|
||||||
|
switch p {
|
||||||
|
case PrefixCS, PrefixDS, PrefixES, PrefixFS, PrefixGS, PrefixSS:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Op definitions and string list are in tables.go.
|
||||||
|
|
||||||
|
var prefixNames = map[Prefix]string{
|
||||||
|
PrefixCS: "CS",
|
||||||
|
PrefixDS: "DS",
|
||||||
|
PrefixES: "ES",
|
||||||
|
PrefixFS: "FS",
|
||||||
|
PrefixGS: "GS",
|
||||||
|
PrefixSS: "SS",
|
||||||
|
PrefixLOCK: "LOCK",
|
||||||
|
PrefixREP: "REP",
|
||||||
|
PrefixREPN: "REPN",
|
||||||
|
PrefixAddrSize: "ADDRSIZE",
|
||||||
|
PrefixDataSize: "DATASIZE",
|
||||||
|
PrefixAddr16: "ADDR16",
|
||||||
|
PrefixData16: "DATA16",
|
||||||
|
PrefixAddr32: "ADDR32",
|
||||||
|
PrefixData32: "DATA32",
|
||||||
|
PrefixBND: "BND",
|
||||||
|
PrefixXACQUIRE: "XACQUIRE",
|
||||||
|
PrefixXRELEASE: "XRELEASE",
|
||||||
|
PrefixREX: "REX",
|
||||||
|
PrefixPT: "PT",
|
||||||
|
PrefixPN: "PN",
|
||||||
|
}
|
||||||
|
|
||||||
|
var regNames = [...]string{
|
||||||
|
AL: "AL",
|
||||||
|
CL: "CL",
|
||||||
|
BL: "BL",
|
||||||
|
DL: "DL",
|
||||||
|
AH: "AH",
|
||||||
|
CH: "CH",
|
||||||
|
BH: "BH",
|
||||||
|
DH: "DH",
|
||||||
|
SPB: "SPB",
|
||||||
|
BPB: "BPB",
|
||||||
|
SIB: "SIB",
|
||||||
|
DIB: "DIB",
|
||||||
|
R8B: "R8B",
|
||||||
|
R9B: "R9B",
|
||||||
|
R10B: "R10B",
|
||||||
|
R11B: "R11B",
|
||||||
|
R12B: "R12B",
|
||||||
|
R13B: "R13B",
|
||||||
|
R14B: "R14B",
|
||||||
|
R15B: "R15B",
|
||||||
|
AX: "AX",
|
||||||
|
CX: "CX",
|
||||||
|
BX: "BX",
|
||||||
|
DX: "DX",
|
||||||
|
SP: "SP",
|
||||||
|
BP: "BP",
|
||||||
|
SI: "SI",
|
||||||
|
DI: "DI",
|
||||||
|
R8W: "R8W",
|
||||||
|
R9W: "R9W",
|
||||||
|
R10W: "R10W",
|
||||||
|
R11W: "R11W",
|
||||||
|
R12W: "R12W",
|
||||||
|
R13W: "R13W",
|
||||||
|
R14W: "R14W",
|
||||||
|
R15W: "R15W",
|
||||||
|
EAX: "EAX",
|
||||||
|
ECX: "ECX",
|
||||||
|
EDX: "EDX",
|
||||||
|
EBX: "EBX",
|
||||||
|
ESP: "ESP",
|
||||||
|
EBP: "EBP",
|
||||||
|
ESI: "ESI",
|
||||||
|
EDI: "EDI",
|
||||||
|
R8L: "R8L",
|
||||||
|
R9L: "R9L",
|
||||||
|
R10L: "R10L",
|
||||||
|
R11L: "R11L",
|
||||||
|
R12L: "R12L",
|
||||||
|
R13L: "R13L",
|
||||||
|
R14L: "R14L",
|
||||||
|
R15L: "R15L",
|
||||||
|
RAX: "RAX",
|
||||||
|
RCX: "RCX",
|
||||||
|
RDX: "RDX",
|
||||||
|
RBX: "RBX",
|
||||||
|
RSP: "RSP",
|
||||||
|
RBP: "RBP",
|
||||||
|
RSI: "RSI",
|
||||||
|
RDI: "RDI",
|
||||||
|
R8: "R8",
|
||||||
|
R9: "R9",
|
||||||
|
R10: "R10",
|
||||||
|
R11: "R11",
|
||||||
|
R12: "R12",
|
||||||
|
R13: "R13",
|
||||||
|
R14: "R14",
|
||||||
|
R15: "R15",
|
||||||
|
IP: "IP",
|
||||||
|
EIP: "EIP",
|
||||||
|
RIP: "RIP",
|
||||||
|
F0: "F0",
|
||||||
|
F1: "F1",
|
||||||
|
F2: "F2",
|
||||||
|
F3: "F3",
|
||||||
|
F4: "F4",
|
||||||
|
F5: "F5",
|
||||||
|
F6: "F6",
|
||||||
|
F7: "F7",
|
||||||
|
M0: "M0",
|
||||||
|
M1: "M1",
|
||||||
|
M2: "M2",
|
||||||
|
M3: "M3",
|
||||||
|
M4: "M4",
|
||||||
|
M5: "M5",
|
||||||
|
M6: "M6",
|
||||||
|
M7: "M7",
|
||||||
|
X0: "X0",
|
||||||
|
X1: "X1",
|
||||||
|
X2: "X2",
|
||||||
|
X3: "X3",
|
||||||
|
X4: "X4",
|
||||||
|
X5: "X5",
|
||||||
|
X6: "X6",
|
||||||
|
X7: "X7",
|
||||||
|
X8: "X8",
|
||||||
|
X9: "X9",
|
||||||
|
X10: "X10",
|
||||||
|
X11: "X11",
|
||||||
|
X12: "X12",
|
||||||
|
X13: "X13",
|
||||||
|
X14: "X14",
|
||||||
|
X15: "X15",
|
||||||
|
CS: "CS",
|
||||||
|
SS: "SS",
|
||||||
|
DS: "DS",
|
||||||
|
ES: "ES",
|
||||||
|
FS: "FS",
|
||||||
|
GS: "GS",
|
||||||
|
GDTR: "GDTR",
|
||||||
|
IDTR: "IDTR",
|
||||||
|
LDTR: "LDTR",
|
||||||
|
MSW: "MSW",
|
||||||
|
TASK: "TASK",
|
||||||
|
CR0: "CR0",
|
||||||
|
CR1: "CR1",
|
||||||
|
CR2: "CR2",
|
||||||
|
CR3: "CR3",
|
||||||
|
CR4: "CR4",
|
||||||
|
CR5: "CR5",
|
||||||
|
CR6: "CR6",
|
||||||
|
CR7: "CR7",
|
||||||
|
CR8: "CR8",
|
||||||
|
CR9: "CR9",
|
||||||
|
CR10: "CR10",
|
||||||
|
CR11: "CR11",
|
||||||
|
CR12: "CR12",
|
||||||
|
CR13: "CR13",
|
||||||
|
CR14: "CR14",
|
||||||
|
CR15: "CR15",
|
||||||
|
DR0: "DR0",
|
||||||
|
DR1: "DR1",
|
||||||
|
DR2: "DR2",
|
||||||
|
DR3: "DR3",
|
||||||
|
DR4: "DR4",
|
||||||
|
DR5: "DR5",
|
||||||
|
DR6: "DR6",
|
||||||
|
DR7: "DR7",
|
||||||
|
DR8: "DR8",
|
||||||
|
DR9: "DR9",
|
||||||
|
DR10: "DR10",
|
||||||
|
DR11: "DR11",
|
||||||
|
DR12: "DR12",
|
||||||
|
DR13: "DR13",
|
||||||
|
DR14: "DR14",
|
||||||
|
DR15: "DR15",
|
||||||
|
TR0: "TR0",
|
||||||
|
TR1: "TR1",
|
||||||
|
TR2: "TR2",
|
||||||
|
TR3: "TR3",
|
||||||
|
TR4: "TR4",
|
||||||
|
TR5: "TR5",
|
||||||
|
TR6: "TR6",
|
||||||
|
TR7: "TR7",
|
||||||
|
}
|
532
vendor/golang.org/x/arch/x86/x86asm/intel.go
generated
vendored
Normal file
532
vendor/golang.org/x/arch/x86/x86asm/intel.go
generated
vendored
Normal file
@ -0,0 +1,532 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package x86asm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IntelSyntax returns the Intel assembler syntax for the instruction, as defined by Intel's XED tool.
|
||||||
|
func IntelSyntax(inst Inst) string {
|
||||||
|
var iargs []Arg
|
||||||
|
for _, a := range inst.Args {
|
||||||
|
if a == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
iargs = append(iargs, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch inst.Op {
|
||||||
|
case INSB, INSD, INSW, OUTSB, OUTSD, OUTSW, LOOPNE, JCXZ, JECXZ, JRCXZ, LOOP, LOOPE, MOV, XLATB:
|
||||||
|
if inst.Op == MOV && (inst.Opcode>>16)&0xFFFC != 0x0F20 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for i, p := range inst.Prefix {
|
||||||
|
if p&0xFF == PrefixAddrSize {
|
||||||
|
inst.Prefix[i] &^= PrefixImplicit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch inst.Op {
|
||||||
|
case MOV:
|
||||||
|
dst, _ := inst.Args[0].(Reg)
|
||||||
|
src, _ := inst.Args[1].(Reg)
|
||||||
|
if ES <= dst && dst <= GS && EAX <= src && src <= R15L {
|
||||||
|
src -= EAX - AX
|
||||||
|
iargs[1] = src
|
||||||
|
}
|
||||||
|
if ES <= dst && dst <= GS && RAX <= src && src <= R15 {
|
||||||
|
src -= RAX - AX
|
||||||
|
iargs[1] = src
|
||||||
|
}
|
||||||
|
|
||||||
|
if inst.Opcode>>24&^3 == 0xA0 {
|
||||||
|
for i, p := range inst.Prefix {
|
||||||
|
if p&0xFF == PrefixAddrSize {
|
||||||
|
inst.Prefix[i] |= PrefixImplicit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch inst.Op {
|
||||||
|
case AAM, AAD:
|
||||||
|
if imm, ok := iargs[0].(Imm); ok {
|
||||||
|
if inst.DataSize == 32 {
|
||||||
|
iargs[0] = Imm(uint32(int8(imm)))
|
||||||
|
} else if inst.DataSize == 16 {
|
||||||
|
iargs[0] = Imm(uint16(int8(imm)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case PUSH:
|
||||||
|
if imm, ok := iargs[0].(Imm); ok {
|
||||||
|
iargs[0] = Imm(uint32(imm))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range inst.Prefix {
|
||||||
|
if p&PrefixImplicit != 0 {
|
||||||
|
for j, pj := range inst.Prefix {
|
||||||
|
if pj&0xFF == p&0xFF {
|
||||||
|
inst.Prefix[j] |= PrefixImplicit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if inst.Op != 0 {
|
||||||
|
for i, p := range inst.Prefix {
|
||||||
|
switch p &^ PrefixIgnored {
|
||||||
|
case PrefixData16, PrefixData32, PrefixCS, PrefixDS, PrefixES, PrefixSS:
|
||||||
|
inst.Prefix[i] |= PrefixImplicit
|
||||||
|
}
|
||||||
|
if p.IsREX() {
|
||||||
|
inst.Prefix[i] |= PrefixImplicit
|
||||||
|
}
|
||||||
|
if p.IsVEX() {
|
||||||
|
if p == PrefixVEX3Bytes {
|
||||||
|
inst.Prefix[i+2] |= PrefixImplicit
|
||||||
|
}
|
||||||
|
inst.Prefix[i] |= PrefixImplicit
|
||||||
|
inst.Prefix[i+1] |= PrefixImplicit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isLoop[inst.Op] || inst.Op == JCXZ || inst.Op == JECXZ || inst.Op == JRCXZ {
|
||||||
|
for i, p := range inst.Prefix {
|
||||||
|
if p == PrefixPT || p == PrefixPN {
|
||||||
|
inst.Prefix[i] |= PrefixImplicit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch inst.Op {
|
||||||
|
case AAA, AAS, CBW, CDQE, CLC, CLD, CLI, CLTS, CMC, CPUID, CQO, CWD, DAA, DAS,
|
||||||
|
FDECSTP, FINCSTP, FNCLEX, FNINIT, FNOP, FWAIT, HLT,
|
||||||
|
ICEBP, INSB, INSD, INSW, INT, INTO, INVD, IRET, IRETQ,
|
||||||
|
LAHF, LEAVE, LRET, MONITOR, MWAIT, NOP, OUTSB, OUTSD, OUTSW,
|
||||||
|
PAUSE, POPA, POPF, POPFQ, PUSHA, PUSHF, PUSHFQ,
|
||||||
|
RDMSR, RDPMC, RDTSC, RDTSCP, RET, RSM,
|
||||||
|
SAHF, STC, STD, STI, SYSENTER, SYSEXIT, SYSRET,
|
||||||
|
UD2, WBINVD, WRMSR, XEND, XLATB, XTEST:
|
||||||
|
|
||||||
|
if inst.Op == NOP && inst.Opcode>>24 != 0x90 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if inst.Op == RET && inst.Opcode>>24 != 0xC3 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if inst.Op == INT && inst.Opcode>>24 != 0xCC {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if inst.Op == LRET && inst.Opcode>>24 != 0xcb {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for i, p := range inst.Prefix {
|
||||||
|
if p&0xFF == PrefixDataSize {
|
||||||
|
inst.Prefix[i] &^= PrefixImplicit | PrefixIgnored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
// ok
|
||||||
|
}
|
||||||
|
|
||||||
|
switch inst.Op {
|
||||||
|
case INSB, INSD, INSW, OUTSB, OUTSD, OUTSW, MONITOR, MWAIT, XLATB:
|
||||||
|
iargs = nil
|
||||||
|
|
||||||
|
case STOSB, STOSW, STOSD, STOSQ:
|
||||||
|
iargs = iargs[:1]
|
||||||
|
|
||||||
|
case LODSB, LODSW, LODSD, LODSQ, SCASB, SCASW, SCASD, SCASQ:
|
||||||
|
iargs = iargs[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
haveData16 = 1 << iota
|
||||||
|
haveData32
|
||||||
|
haveAddr16
|
||||||
|
haveAddr32
|
||||||
|
haveXacquire
|
||||||
|
haveXrelease
|
||||||
|
haveLock
|
||||||
|
haveHintTaken
|
||||||
|
haveHintNotTaken
|
||||||
|
haveBnd
|
||||||
|
)
|
||||||
|
var prefixBits uint32
|
||||||
|
prefix := ""
|
||||||
|
for _, p := range inst.Prefix {
|
||||||
|
if p == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if p&0xFF == 0xF3 {
|
||||||
|
prefixBits &^= haveBnd
|
||||||
|
}
|
||||||
|
if p&(PrefixImplicit|PrefixIgnored) != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch p {
|
||||||
|
default:
|
||||||
|
prefix += strings.ToLower(p.String()) + " "
|
||||||
|
case PrefixCS, PrefixDS, PrefixES, PrefixFS, PrefixGS, PrefixSS:
|
||||||
|
if inst.Op == 0 {
|
||||||
|
prefix += strings.ToLower(p.String()) + " "
|
||||||
|
}
|
||||||
|
case PrefixREPN:
|
||||||
|
prefix += "repne "
|
||||||
|
case PrefixLOCK:
|
||||||
|
prefixBits |= haveLock
|
||||||
|
case PrefixData16, PrefixDataSize:
|
||||||
|
prefixBits |= haveData16
|
||||||
|
case PrefixData32:
|
||||||
|
prefixBits |= haveData32
|
||||||
|
case PrefixAddrSize, PrefixAddr16:
|
||||||
|
prefixBits |= haveAddr16
|
||||||
|
case PrefixAddr32:
|
||||||
|
prefixBits |= haveAddr32
|
||||||
|
case PrefixXACQUIRE:
|
||||||
|
prefixBits |= haveXacquire
|
||||||
|
case PrefixXRELEASE:
|
||||||
|
prefixBits |= haveXrelease
|
||||||
|
case PrefixPT:
|
||||||
|
prefixBits |= haveHintTaken
|
||||||
|
case PrefixPN:
|
||||||
|
prefixBits |= haveHintNotTaken
|
||||||
|
case PrefixBND:
|
||||||
|
prefixBits |= haveBnd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch inst.Op {
|
||||||
|
case JMP:
|
||||||
|
if inst.Opcode>>24 == 0xEB {
|
||||||
|
prefixBits &^= haveBnd
|
||||||
|
}
|
||||||
|
case RET, LRET:
|
||||||
|
prefixBits &^= haveData16 | haveData32
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefixBits&haveXacquire != 0 {
|
||||||
|
prefix += "xacquire "
|
||||||
|
}
|
||||||
|
if prefixBits&haveXrelease != 0 {
|
||||||
|
prefix += "xrelease "
|
||||||
|
}
|
||||||
|
if prefixBits&haveLock != 0 {
|
||||||
|
prefix += "lock "
|
||||||
|
}
|
||||||
|
if prefixBits&haveBnd != 0 {
|
||||||
|
prefix += "bnd "
|
||||||
|
}
|
||||||
|
if prefixBits&haveHintTaken != 0 {
|
||||||
|
prefix += "hint-taken "
|
||||||
|
}
|
||||||
|
if prefixBits&haveHintNotTaken != 0 {
|
||||||
|
prefix += "hint-not-taken "
|
||||||
|
}
|
||||||
|
if prefixBits&haveAddr16 != 0 {
|
||||||
|
prefix += "addr16 "
|
||||||
|
}
|
||||||
|
if prefixBits&haveAddr32 != 0 {
|
||||||
|
prefix += "addr32 "
|
||||||
|
}
|
||||||
|
if prefixBits&haveData16 != 0 {
|
||||||
|
prefix += "data16 "
|
||||||
|
}
|
||||||
|
if prefixBits&haveData32 != 0 {
|
||||||
|
prefix += "data32 "
|
||||||
|
}
|
||||||
|
|
||||||
|
if inst.Op == 0 {
|
||||||
|
if prefix == "" {
|
||||||
|
return "<no instruction>"
|
||||||
|
}
|
||||||
|
return prefix[:len(prefix)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
var args []string
|
||||||
|
for _, a := range iargs {
|
||||||
|
if a == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
args = append(args, intelArg(&inst, a))
|
||||||
|
}
|
||||||
|
|
||||||
|
var op string
|
||||||
|
switch inst.Op {
|
||||||
|
case NOP:
|
||||||
|
if inst.Opcode>>24 == 0x0F {
|
||||||
|
if inst.DataSize == 16 {
|
||||||
|
args = append(args, "ax")
|
||||||
|
} else {
|
||||||
|
args = append(args, "eax")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case BLENDVPD, BLENDVPS, PBLENDVB:
|
||||||
|
args = args[:2]
|
||||||
|
|
||||||
|
case INT:
|
||||||
|
if inst.Opcode>>24 == 0xCC {
|
||||||
|
args = nil
|
||||||
|
op = "int3"
|
||||||
|
}
|
||||||
|
|
||||||
|
case LCALL, LJMP:
|
||||||
|
if len(args) == 2 {
|
||||||
|
args[0], args[1] = args[1], args[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
case FCHS, FABS, FTST, FLDPI, FLDL2E, FLDLG2, F2XM1, FXAM, FLD1, FLDL2T, FSQRT, FRNDINT, FCOS, FSIN:
|
||||||
|
if len(args) == 0 {
|
||||||
|
args = append(args, "st0")
|
||||||
|
}
|
||||||
|
|
||||||
|
case FPTAN, FSINCOS, FUCOMPP, FCOMPP, FYL2X, FPATAN, FXTRACT, FPREM1, FPREM, FYL2XP1, FSCALE:
|
||||||
|
if len(args) == 0 {
|
||||||
|
args = []string{"st0", "st1"}
|
||||||
|
}
|
||||||
|
|
||||||
|
case FST, FSTP, FISTTP, FIST, FISTP, FBSTP:
|
||||||
|
if len(args) == 1 {
|
||||||
|
args = append(args, "st0")
|
||||||
|
}
|
||||||
|
|
||||||
|
case FLD, FXCH, FCOM, FCOMP, FIADD, FIMUL, FICOM, FICOMP, FISUBR, FIDIV, FUCOM, FUCOMP, FILD, FBLD, FADD, FMUL, FSUB, FSUBR, FISUB, FDIV, FDIVR, FIDIVR:
|
||||||
|
if len(args) == 1 {
|
||||||
|
args = []string{"st0", args[0]}
|
||||||
|
}
|
||||||
|
|
||||||
|
case MASKMOVDQU, MASKMOVQ, XLATB, OUTSB, OUTSW, OUTSD:
|
||||||
|
FixSegment:
|
||||||
|
for i := len(inst.Prefix) - 1; i >= 0; i-- {
|
||||||
|
p := inst.Prefix[i] & 0xFF
|
||||||
|
switch p {
|
||||||
|
case PrefixCS, PrefixES, PrefixFS, PrefixGS, PrefixSS:
|
||||||
|
if inst.Mode != 64 || p == PrefixFS || p == PrefixGS {
|
||||||
|
args = append(args, strings.ToLower((inst.Prefix[i] & 0xFF).String()))
|
||||||
|
break FixSegment
|
||||||
|
}
|
||||||
|
case PrefixDS:
|
||||||
|
if inst.Mode != 64 {
|
||||||
|
break FixSegment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if op == "" {
|
||||||
|
op = intelOp[inst.Op]
|
||||||
|
}
|
||||||
|
if op == "" {
|
||||||
|
op = strings.ToLower(inst.Op.String())
|
||||||
|
}
|
||||||
|
if args != nil {
|
||||||
|
op += " " + strings.Join(args, ", ")
|
||||||
|
}
|
||||||
|
return prefix + op
|
||||||
|
}
|
||||||
|
|
||||||
|
func intelArg(inst *Inst, arg Arg) string {
|
||||||
|
switch a := arg.(type) {
|
||||||
|
case Imm:
|
||||||
|
if inst.Mode == 32 {
|
||||||
|
return fmt.Sprintf("%#x", uint32(a))
|
||||||
|
}
|
||||||
|
if Imm(int32(a)) == a {
|
||||||
|
return fmt.Sprintf("%#x", int64(a))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%#x", uint64(a))
|
||||||
|
case Mem:
|
||||||
|
if a.Base == EIP {
|
||||||
|
a.Base = RIP
|
||||||
|
}
|
||||||
|
prefix := ""
|
||||||
|
switch inst.MemBytes {
|
||||||
|
case 1:
|
||||||
|
prefix = "byte "
|
||||||
|
case 2:
|
||||||
|
prefix = "word "
|
||||||
|
case 4:
|
||||||
|
prefix = "dword "
|
||||||
|
case 8:
|
||||||
|
prefix = "qword "
|
||||||
|
case 16:
|
||||||
|
prefix = "xmmword "
|
||||||
|
case 32:
|
||||||
|
prefix = "ymmword "
|
||||||
|
}
|
||||||
|
switch inst.Op {
|
||||||
|
case INVLPG:
|
||||||
|
prefix = "byte "
|
||||||
|
case STOSB, MOVSB, CMPSB, LODSB, SCASB:
|
||||||
|
prefix = "byte "
|
||||||
|
case STOSW, MOVSW, CMPSW, LODSW, SCASW:
|
||||||
|
prefix = "word "
|
||||||
|
case STOSD, MOVSD, CMPSD, LODSD, SCASD:
|
||||||
|
prefix = "dword "
|
||||||
|
case STOSQ, MOVSQ, CMPSQ, LODSQ, SCASQ:
|
||||||
|
prefix = "qword "
|
||||||
|
case LAR:
|
||||||
|
prefix = "word "
|
||||||
|
case BOUND:
|
||||||
|
if inst.Mode == 32 {
|
||||||
|
prefix = "qword "
|
||||||
|
} else {
|
||||||
|
prefix = "dword "
|
||||||
|
}
|
||||||
|
case PREFETCHW, PREFETCHNTA, PREFETCHT0, PREFETCHT1, PREFETCHT2, CLFLUSH:
|
||||||
|
prefix = "zmmword "
|
||||||
|
}
|
||||||
|
switch inst.Op {
|
||||||
|
case MOVSB, MOVSW, MOVSD, MOVSQ, CMPSB, CMPSW, CMPSD, CMPSQ, STOSB, STOSW, STOSD, STOSQ, SCASB, SCASW, SCASD, SCASQ, LODSB, LODSW, LODSD, LODSQ:
|
||||||
|
switch a.Base {
|
||||||
|
case DI, EDI, RDI:
|
||||||
|
if a.Segment == ES {
|
||||||
|
a.Segment = 0
|
||||||
|
}
|
||||||
|
case SI, ESI, RSI:
|
||||||
|
if a.Segment == DS {
|
||||||
|
a.Segment = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case LEA:
|
||||||
|
a.Segment = 0
|
||||||
|
default:
|
||||||
|
switch a.Base {
|
||||||
|
case SP, ESP, RSP, BP, EBP, RBP:
|
||||||
|
if a.Segment == SS {
|
||||||
|
a.Segment = 0
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if a.Segment == DS {
|
||||||
|
a.Segment = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if inst.Mode == 64 && a.Segment != FS && a.Segment != GS {
|
||||||
|
a.Segment = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix += "ptr "
|
||||||
|
if a.Segment != 0 {
|
||||||
|
prefix += strings.ToLower(a.Segment.String()) + ":"
|
||||||
|
}
|
||||||
|
prefix += "["
|
||||||
|
if a.Base != 0 {
|
||||||
|
prefix += intelArg(inst, a.Base)
|
||||||
|
}
|
||||||
|
if a.Scale != 0 && a.Index != 0 {
|
||||||
|
if a.Base != 0 {
|
||||||
|
prefix += "+"
|
||||||
|
}
|
||||||
|
prefix += fmt.Sprintf("%s*%d", intelArg(inst, a.Index), a.Scale)
|
||||||
|
}
|
||||||
|
if a.Disp != 0 {
|
||||||
|
if prefix[len(prefix)-1] == '[' && (a.Disp >= 0 || int64(int32(a.Disp)) != a.Disp) {
|
||||||
|
prefix += fmt.Sprintf("%#x", uint64(a.Disp))
|
||||||
|
} else {
|
||||||
|
prefix += fmt.Sprintf("%+#x", a.Disp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prefix += "]"
|
||||||
|
return prefix
|
||||||
|
case Rel:
|
||||||
|
return fmt.Sprintf(".%+#x", int64(a))
|
||||||
|
case Reg:
|
||||||
|
if int(a) < len(intelReg) && intelReg[a] != "" {
|
||||||
|
switch inst.Op {
|
||||||
|
case VMOVDQA, VMOVDQU, VMOVNTDQA, VMOVNTDQ:
|
||||||
|
return strings.Replace(intelReg[a], "xmm", "ymm", -1)
|
||||||
|
default:
|
||||||
|
return intelReg[a]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.ToLower(arg.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
var intelOp = map[Op]string{
|
||||||
|
JAE: "jnb",
|
||||||
|
JA: "jnbe",
|
||||||
|
JGE: "jnl",
|
||||||
|
JNE: "jnz",
|
||||||
|
JG: "jnle",
|
||||||
|
JE: "jz",
|
||||||
|
SETAE: "setnb",
|
||||||
|
SETA: "setnbe",
|
||||||
|
SETGE: "setnl",
|
||||||
|
SETNE: "setnz",
|
||||||
|
SETG: "setnle",
|
||||||
|
SETE: "setz",
|
||||||
|
CMOVAE: "cmovnb",
|
||||||
|
CMOVA: "cmovnbe",
|
||||||
|
CMOVGE: "cmovnl",
|
||||||
|
CMOVNE: "cmovnz",
|
||||||
|
CMOVG: "cmovnle",
|
||||||
|
CMOVE: "cmovz",
|
||||||
|
LCALL: "call far",
|
||||||
|
LJMP: "jmp far",
|
||||||
|
LRET: "ret far",
|
||||||
|
ICEBP: "int1",
|
||||||
|
MOVSD_XMM: "movsd",
|
||||||
|
XLATB: "xlat",
|
||||||
|
}
|
||||||
|
|
||||||
|
var intelReg = [...]string{
|
||||||
|
F0: "st0",
|
||||||
|
F1: "st1",
|
||||||
|
F2: "st2",
|
||||||
|
F3: "st3",
|
||||||
|
F4: "st4",
|
||||||
|
F5: "st5",
|
||||||
|
F6: "st6",
|
||||||
|
F7: "st7",
|
||||||
|
M0: "mmx0",
|
||||||
|
M1: "mmx1",
|
||||||
|
M2: "mmx2",
|
||||||
|
M3: "mmx3",
|
||||||
|
M4: "mmx4",
|
||||||
|
M5: "mmx5",
|
||||||
|
M6: "mmx6",
|
||||||
|
M7: "mmx7",
|
||||||
|
X0: "xmm0",
|
||||||
|
X1: "xmm1",
|
||||||
|
X2: "xmm2",
|
||||||
|
X3: "xmm3",
|
||||||
|
X4: "xmm4",
|
||||||
|
X5: "xmm5",
|
||||||
|
X6: "xmm6",
|
||||||
|
X7: "xmm7",
|
||||||
|
X8: "xmm8",
|
||||||
|
X9: "xmm9",
|
||||||
|
X10: "xmm10",
|
||||||
|
X11: "xmm11",
|
||||||
|
X12: "xmm12",
|
||||||
|
X13: "xmm13",
|
||||||
|
X14: "xmm14",
|
||||||
|
X15: "xmm15",
|
||||||
|
|
||||||
|
// TODO: Maybe the constants are named wrong.
|
||||||
|
SPB: "spl",
|
||||||
|
BPB: "bpl",
|
||||||
|
SIB: "sil",
|
||||||
|
DIB: "dil",
|
||||||
|
|
||||||
|
R8L: "r8d",
|
||||||
|
R9L: "r9d",
|
||||||
|
R10L: "r10d",
|
||||||
|
R11L: "r11d",
|
||||||
|
R12L: "r12d",
|
||||||
|
R13L: "r13d",
|
||||||
|
R14L: "r14d",
|
||||||
|
R15L: "r15d",
|
||||||
|
}
|
362
vendor/golang.org/x/arch/x86/x86asm/plan9x.go
generated
vendored
Normal file
362
vendor/golang.org/x/arch/x86/x86asm/plan9x.go
generated
vendored
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package x86asm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GoSyntax returns the Go assembler syntax for the instruction.
|
||||||
|
// The syntax was originally defined by Plan 9.
|
||||||
|
// The pc is the program counter of the instruction, used for expanding
|
||||||
|
// PC-relative addresses into absolute ones.
|
||||||
|
// The symname function queries the symbol table for the program
|
||||||
|
// being disassembled. Given a target address it returns the name and base
|
||||||
|
// address of the symbol containing the target, if any; otherwise it returns "", 0.
|
||||||
|
func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) string {
|
||||||
|
if symname == nil {
|
||||||
|
symname = func(uint64) (string, uint64) { return "", 0 }
|
||||||
|
}
|
||||||
|
var args []string
|
||||||
|
for i := len(inst.Args) - 1; i >= 0; i-- {
|
||||||
|
a := inst.Args[i]
|
||||||
|
if a == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
args = append(args, plan9Arg(&inst, pc, symname, a))
|
||||||
|
}
|
||||||
|
|
||||||
|
var rep string
|
||||||
|
var last Prefix
|
||||||
|
for _, p := range inst.Prefix {
|
||||||
|
if p == 0 || p.IsREX() || p.IsVEX() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
// Don't show prefixes implied by the instruction text.
|
||||||
|
case p&0xFF00 == PrefixImplicit:
|
||||||
|
continue
|
||||||
|
// Only REP and REPN are recognized repeaters. Plan 9 syntax
|
||||||
|
// treats them as separate opcodes.
|
||||||
|
case p&0xFF == PrefixREP:
|
||||||
|
rep = "REP; "
|
||||||
|
case p&0xFF == PrefixREPN:
|
||||||
|
rep = "REPNE; "
|
||||||
|
default:
|
||||||
|
last = p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix := ""
|
||||||
|
switch last & 0xFF {
|
||||||
|
case 0, 0x66, 0x67:
|
||||||
|
// ignore
|
||||||
|
default:
|
||||||
|
prefix += last.String() + " "
|
||||||
|
}
|
||||||
|
|
||||||
|
op := inst.Op.String()
|
||||||
|
if plan9Suffix[inst.Op] {
|
||||||
|
s := inst.DataSize
|
||||||
|
if inst.MemBytes != 0 {
|
||||||
|
s = inst.MemBytes * 8
|
||||||
|
}
|
||||||
|
switch s {
|
||||||
|
case 8:
|
||||||
|
op += "B"
|
||||||
|
case 16:
|
||||||
|
op += "W"
|
||||||
|
case 32:
|
||||||
|
op += "L"
|
||||||
|
case 64:
|
||||||
|
op += "Q"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if args != nil {
|
||||||
|
op += " " + strings.Join(args, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
return rep + prefix + op
|
||||||
|
}
|
||||||
|
|
||||||
|
func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
|
||||||
|
switch a := arg.(type) {
|
||||||
|
case Reg:
|
||||||
|
return plan9Reg[a]
|
||||||
|
case Rel:
|
||||||
|
if pc == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// If the absolute address is the start of a symbol, use the name.
|
||||||
|
// Otherwise use the raw address, so that things like relative
|
||||||
|
// jumps show up as JMP 0x123 instead of JMP f+10(SB).
|
||||||
|
// It is usually easier to search for 0x123 than to do the mental
|
||||||
|
// arithmetic to find f+10.
|
||||||
|
addr := pc + uint64(inst.Len) + uint64(a)
|
||||||
|
if s, base := symname(addr); s != "" && addr == base {
|
||||||
|
return fmt.Sprintf("%s(SB)", s)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%#x", addr)
|
||||||
|
|
||||||
|
case Imm:
|
||||||
|
if s, base := symname(uint64(a)); s != "" {
|
||||||
|
suffix := ""
|
||||||
|
if uint64(a) != base {
|
||||||
|
suffix = fmt.Sprintf("%+d", uint64(a)-base)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("$%s%s(SB)", s, suffix)
|
||||||
|
}
|
||||||
|
if inst.Mode == 32 {
|
||||||
|
return fmt.Sprintf("$%#x", uint32(a))
|
||||||
|
}
|
||||||
|
if Imm(int32(a)) == a {
|
||||||
|
return fmt.Sprintf("$%#x", int64(a))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("$%#x", uint64(a))
|
||||||
|
case Mem:
|
||||||
|
if a.Segment == 0 && a.Disp != 0 && a.Base == 0 && (a.Index == 0 || a.Scale == 0) {
|
||||||
|
if s, base := symname(uint64(a.Disp)); s != "" {
|
||||||
|
suffix := ""
|
||||||
|
if uint64(a.Disp) != base {
|
||||||
|
suffix = fmt.Sprintf("%+d", uint64(a.Disp)-base)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s%s(SB)", s, suffix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s := ""
|
||||||
|
if a.Segment != 0 {
|
||||||
|
s += fmt.Sprintf("%s:", plan9Reg[a.Segment])
|
||||||
|
}
|
||||||
|
if a.Disp != 0 {
|
||||||
|
s += fmt.Sprintf("%#x", a.Disp)
|
||||||
|
} else {
|
||||||
|
s += "0"
|
||||||
|
}
|
||||||
|
if a.Base != 0 {
|
||||||
|
s += fmt.Sprintf("(%s)", plan9Reg[a.Base])
|
||||||
|
}
|
||||||
|
if a.Index != 0 && a.Scale != 0 {
|
||||||
|
s += fmt.Sprintf("(%s*%d)", plan9Reg[a.Index], a.Scale)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return arg.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
var plan9Suffix = [maxOp + 1]bool{
|
||||||
|
ADC: true,
|
||||||
|
ADD: true,
|
||||||
|
AND: true,
|
||||||
|
BSF: true,
|
||||||
|
BSR: true,
|
||||||
|
BT: true,
|
||||||
|
BTC: true,
|
||||||
|
BTR: true,
|
||||||
|
BTS: true,
|
||||||
|
CMP: true,
|
||||||
|
CMPXCHG: true,
|
||||||
|
CVTSI2SD: true,
|
||||||
|
CVTSI2SS: true,
|
||||||
|
CVTSD2SI: true,
|
||||||
|
CVTSS2SI: true,
|
||||||
|
CVTTSD2SI: true,
|
||||||
|
CVTTSS2SI: true,
|
||||||
|
DEC: true,
|
||||||
|
DIV: true,
|
||||||
|
FLDENV: true,
|
||||||
|
FRSTOR: true,
|
||||||
|
IDIV: true,
|
||||||
|
IMUL: true,
|
||||||
|
IN: true,
|
||||||
|
INC: true,
|
||||||
|
LEA: true,
|
||||||
|
MOV: true,
|
||||||
|
MOVNTI: true,
|
||||||
|
MUL: true,
|
||||||
|
NEG: true,
|
||||||
|
NOP: true,
|
||||||
|
NOT: true,
|
||||||
|
OR: true,
|
||||||
|
OUT: true,
|
||||||
|
POP: true,
|
||||||
|
POPA: true,
|
||||||
|
PUSH: true,
|
||||||
|
PUSHA: true,
|
||||||
|
RCL: true,
|
||||||
|
RCR: true,
|
||||||
|
ROL: true,
|
||||||
|
ROR: true,
|
||||||
|
SAR: true,
|
||||||
|
SBB: true,
|
||||||
|
SHL: true,
|
||||||
|
SHLD: true,
|
||||||
|
SHR: true,
|
||||||
|
SHRD: true,
|
||||||
|
SUB: true,
|
||||||
|
TEST: true,
|
||||||
|
XADD: true,
|
||||||
|
XCHG: true,
|
||||||
|
XOR: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
var plan9Reg = [...]string{
|
||||||
|
AL: "AL",
|
||||||
|
CL: "CL",
|
||||||
|
BL: "BL",
|
||||||
|
DL: "DL",
|
||||||
|
AH: "AH",
|
||||||
|
CH: "CH",
|
||||||
|
BH: "BH",
|
||||||
|
DH: "DH",
|
||||||
|
SPB: "SP",
|
||||||
|
BPB: "BP",
|
||||||
|
SIB: "SI",
|
||||||
|
DIB: "DI",
|
||||||
|
R8B: "R8",
|
||||||
|
R9B: "R9",
|
||||||
|
R10B: "R10",
|
||||||
|
R11B: "R11",
|
||||||
|
R12B: "R12",
|
||||||
|
R13B: "R13",
|
||||||
|
R14B: "R14",
|
||||||
|
R15B: "R15",
|
||||||
|
AX: "AX",
|
||||||
|
CX: "CX",
|
||||||
|
BX: "BX",
|
||||||
|
DX: "DX",
|
||||||
|
SP: "SP",
|
||||||
|
BP: "BP",
|
||||||
|
SI: "SI",
|
||||||
|
DI: "DI",
|
||||||
|
R8W: "R8",
|
||||||
|
R9W: "R9",
|
||||||
|
R10W: "R10",
|
||||||
|
R11W: "R11",
|
||||||
|
R12W: "R12",
|
||||||
|
R13W: "R13",
|
||||||
|
R14W: "R14",
|
||||||
|
R15W: "R15",
|
||||||
|
EAX: "AX",
|
||||||
|
ECX: "CX",
|
||||||
|
EDX: "DX",
|
||||||
|
EBX: "BX",
|
||||||
|
ESP: "SP",
|
||||||
|
EBP: "BP",
|
||||||
|
ESI: "SI",
|
||||||
|
EDI: "DI",
|
||||||
|
R8L: "R8",
|
||||||
|
R9L: "R9",
|
||||||
|
R10L: "R10",
|
||||||
|
R11L: "R11",
|
||||||
|
R12L: "R12",
|
||||||
|
R13L: "R13",
|
||||||
|
R14L: "R14",
|
||||||
|
R15L: "R15",
|
||||||
|
RAX: "AX",
|
||||||
|
RCX: "CX",
|
||||||
|
RDX: "DX",
|
||||||
|
RBX: "BX",
|
||||||
|
RSP: "SP",
|
||||||
|
RBP: "BP",
|
||||||
|
RSI: "SI",
|
||||||
|
RDI: "DI",
|
||||||
|
R8: "R8",
|
||||||
|
R9: "R9",
|
||||||
|
R10: "R10",
|
||||||
|
R11: "R11",
|
||||||
|
R12: "R12",
|
||||||
|
R13: "R13",
|
||||||
|
R14: "R14",
|
||||||
|
R15: "R15",
|
||||||
|
IP: "IP",
|
||||||
|
EIP: "IP",
|
||||||
|
RIP: "IP",
|
||||||
|
F0: "F0",
|
||||||
|
F1: "F1",
|
||||||
|
F2: "F2",
|
||||||
|
F3: "F3",
|
||||||
|
F4: "F4",
|
||||||
|
F5: "F5",
|
||||||
|
F6: "F6",
|
||||||
|
F7: "F7",
|
||||||
|
M0: "M0",
|
||||||
|
M1: "M1",
|
||||||
|
M2: "M2",
|
||||||
|
M3: "M3",
|
||||||
|
M4: "M4",
|
||||||
|
M5: "M5",
|
||||||
|
M6: "M6",
|
||||||
|
M7: "M7",
|
||||||
|
X0: "X0",
|
||||||
|
X1: "X1",
|
||||||
|
X2: "X2",
|
||||||
|
X3: "X3",
|
||||||
|
X4: "X4",
|
||||||
|
X5: "X5",
|
||||||
|
X6: "X6",
|
||||||
|
X7: "X7",
|
||||||
|
X8: "X8",
|
||||||
|
X9: "X9",
|
||||||
|
X10: "X10",
|
||||||
|
X11: "X11",
|
||||||
|
X12: "X12",
|
||||||
|
X13: "X13",
|
||||||
|
X14: "X14",
|
||||||
|
X15: "X15",
|
||||||
|
CS: "CS",
|
||||||
|
SS: "SS",
|
||||||
|
DS: "DS",
|
||||||
|
ES: "ES",
|
||||||
|
FS: "FS",
|
||||||
|
GS: "GS",
|
||||||
|
GDTR: "GDTR",
|
||||||
|
IDTR: "IDTR",
|
||||||
|
LDTR: "LDTR",
|
||||||
|
MSW: "MSW",
|
||||||
|
TASK: "TASK",
|
||||||
|
CR0: "CR0",
|
||||||
|
CR1: "CR1",
|
||||||
|
CR2: "CR2",
|
||||||
|
CR3: "CR3",
|
||||||
|
CR4: "CR4",
|
||||||
|
CR5: "CR5",
|
||||||
|
CR6: "CR6",
|
||||||
|
CR7: "CR7",
|
||||||
|
CR8: "CR8",
|
||||||
|
CR9: "CR9",
|
||||||
|
CR10: "CR10",
|
||||||
|
CR11: "CR11",
|
||||||
|
CR12: "CR12",
|
||||||
|
CR13: "CR13",
|
||||||
|
CR14: "CR14",
|
||||||
|
CR15: "CR15",
|
||||||
|
DR0: "DR0",
|
||||||
|
DR1: "DR1",
|
||||||
|
DR2: "DR2",
|
||||||
|
DR3: "DR3",
|
||||||
|
DR4: "DR4",
|
||||||
|
DR5: "DR5",
|
||||||
|
DR6: "DR6",
|
||||||
|
DR7: "DR7",
|
||||||
|
DR8: "DR8",
|
||||||
|
DR9: "DR9",
|
||||||
|
DR10: "DR10",
|
||||||
|
DR11: "DR11",
|
||||||
|
DR12: "DR12",
|
||||||
|
DR13: "DR13",
|
||||||
|
DR14: "DR14",
|
||||||
|
DR15: "DR15",
|
||||||
|
TR0: "TR0",
|
||||||
|
TR1: "TR1",
|
||||||
|
TR2: "TR2",
|
||||||
|
TR3: "TR3",
|
||||||
|
TR4: "TR4",
|
||||||
|
TR5: "TR5",
|
||||||
|
TR6: "TR6",
|
||||||
|
TR7: "TR7",
|
||||||
|
}
|
9902
vendor/golang.org/x/arch/x86/x86asm/tables.go
generated
vendored
Normal file
9902
vendor/golang.org/x/arch/x86/x86asm/tables.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
54
vendor/manifest
vendored
54
vendor/manifest
vendored
@ -107,6 +107,33 @@
|
|||||||
"branch": "master",
|
"branch": "master",
|
||||||
"notests": true
|
"notests": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"importpath": "github.com/google/gops/agent",
|
||||||
|
"repository": "https://github.com/google/gops",
|
||||||
|
"vcs": "git",
|
||||||
|
"revision": "62f833fc9f6c4d3223bdb37bd0c2f8951bed8596",
|
||||||
|
"branch": "master",
|
||||||
|
"path": "/agent",
|
||||||
|
"notests": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"importpath": "github.com/google/gops/internal",
|
||||||
|
"repository": "https://github.com/google/gops",
|
||||||
|
"vcs": "git",
|
||||||
|
"revision": "62f833fc9f6c4d3223bdb37bd0c2f8951bed8596",
|
||||||
|
"branch": "master",
|
||||||
|
"path": "internal",
|
||||||
|
"notests": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"importpath": "github.com/google/gops/signal",
|
||||||
|
"repository": "https://github.com/google/gops",
|
||||||
|
"vcs": "git",
|
||||||
|
"revision": "62f833fc9f6c4d3223bdb37bd0c2f8951bed8596",
|
||||||
|
"branch": "master",
|
||||||
|
"path": "signal",
|
||||||
|
"notests": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"importpath": "github.com/gorilla/schema",
|
"importpath": "github.com/gorilla/schema",
|
||||||
"repository": "https://github.com/gorilla/schema",
|
"repository": "https://github.com/gorilla/schema",
|
||||||
@ -346,6 +373,33 @@
|
|||||||
"branch": "master",
|
"branch": "master",
|
||||||
"notests": true
|
"notests": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"importpath": "golang.org/x/arch/arm/armasm",
|
||||||
|
"repository": "https://go.googlesource.com/arch",
|
||||||
|
"vcs": "git",
|
||||||
|
"revision": "58ea1a195b1a354bcd572b7ef6bbbd264dc63732",
|
||||||
|
"branch": "master",
|
||||||
|
"path": "/arm/armasm",
|
||||||
|
"notests": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"importpath": "golang.org/x/arch/ppc64/ppc64asm",
|
||||||
|
"repository": "https://go.googlesource.com/arch",
|
||||||
|
"vcs": "git",
|
||||||
|
"revision": "58ea1a195b1a354bcd572b7ef6bbbd264dc63732",
|
||||||
|
"branch": "master",
|
||||||
|
"path": "ppc64/ppc64asm",
|
||||||
|
"notests": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"importpath": "golang.org/x/arch/x86/x86asm",
|
||||||
|
"repository": "https://go.googlesource.com/arch",
|
||||||
|
"vcs": "git",
|
||||||
|
"revision": "58ea1a195b1a354bcd572b7ef6bbbd264dc63732",
|
||||||
|
"branch": "master",
|
||||||
|
"path": "x86/x86asm",
|
||||||
|
"notests": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"importpath": "golang.org/x/crypto/acme",
|
"importpath": "golang.org/x/crypto/acme",
|
||||||
"repository": "https://go.googlesource.com/crypto",
|
"repository": "https://go.googlesource.com/crypto",
|
||||||
|
Loading…
Reference in New Issue
Block a user