mirror of
https://github.com/42wim/matterbridge.git
synced 2024-11-23 19:22: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/samechannel"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/google/gops/agent"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -22,7 +23,12 @@ func main() {
|
||||
flagConfig := flag.String("conf", "matterbridge.toml", "config file")
|
||||
flagDebug := flag.Bool("debug", false, "enable debug")
|
||||
flagVersion := flag.Bool("version", false, "show version")
|
||||
flagGops := flag.Bool("gops", false, "enable gops agent")
|
||||
flag.Parse()
|
||||
if *flagGops {
|
||||
agent.Listen(&agent.Options{})
|
||||
defer agent.Close()
|
||||
}
|
||||
if *flagVersion {
|
||||
fmt.Printf("version: %s %s\n", version, githash)
|
||||
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",
|
||||
"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",
|
||||
"repository": "https://github.com/gorilla/schema",
|
||||
@ -346,6 +373,33 @@
|
||||
"branch": "master",
|
||||
"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",
|
||||
"repository": "https://go.googlesource.com/crypto",
|
||||
|
Loading…
Reference in New Issue
Block a user