mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-06-27 19:19:24 +00:00
Compare commits
19 Commits
v0.10.1
...
v0.11.0-be
Author | SHA1 | Date | |
---|---|---|---|
57176dadd4 | |||
dd449a8705 | |||
587ad9f41d | |||
a16ad8bf3b | |||
1e0490bd36 | |||
8afc641f0c | |||
2e4d58cb92 | |||
02d7e2db65 | |||
f935c573e9 | |||
4a25e66c00 | |||
95f4e3448e | |||
eacb1c1771 | |||
07fd825349 | |||
be15cc8a36 | |||
2f68519b3c | |||
efe641f202 | |||
9bd663046a | |||
11b07f01ba | |||
6c2f370e6b |
17
README.md
17
README.md
@ -1,5 +1,6 @@
|
||||
# matterbridge
|
||||
[](https://gitter.im/42wim/matterbridge) [](https://webchat.freenode.net/?channels=matterbridgechat)
|
||||
[](https://gitter.im/42wim/matterbridge) [](https://webchat.freenode.net/?channels=matterbridgechat) [](https://discord.gg/AkKPtrQ) [](https://riot.im/app/#/room/#matterbridge:matrix.org)
|
||||
|
||||

|
||||
|
||||
Simple bridge between Mattermost, IRC, XMPP, Gitter, Slack, Discord, Telegram, Rocket.Chat, Hipchat(via xmpp) and Matrix with REST API.
|
||||
@ -41,7 +42,7 @@ Accounts to one of the supported bridges
|
||||
# Installing
|
||||
## Binaries
|
||||
Binaries can be found [here] (https://github.com/42wim/matterbridge/releases/)
|
||||
* Latest release [v0.10.1](https://github.com/42wim/matterbridge/releases/latest)
|
||||
* Latest release [v0.10.3](https://github.com/42wim/matterbridge/releases/latest)
|
||||
|
||||
## Building
|
||||
Go 1.6+ is required. Make sure you have [Go](https://golang.org/doc/install) properly installed, including setting up your [GOPATH] (https://golang.org/doc/code.html#GOPATH)
|
||||
@ -93,10 +94,13 @@ enable=true
|
||||
|
||||
### Bridge slack (#general) - discord (general)
|
||||
```
|
||||
[slack]
|
||||
[slack.test]
|
||||
useAPI=true
|
||||
Token="yourslacktoken"
|
||||
PrefixMessagesWithNick=true
|
||||
|
||||
[discord]
|
||||
[discord.test]
|
||||
Token="yourdiscordtoken"
|
||||
Server="yourdiscordservername"
|
||||
@ -118,9 +122,11 @@ RemoteNickFormat="[{PROTOCOL}/{BRIDGE}] <{NICK}> "
|
||||
```
|
||||
|
||||
# Running
|
||||
1) Copy the matterbridge.toml.sample to matterbridge.toml in the same directory as the matterbridge binary.
|
||||
1) Copy the matterbridge.toml.sample to matterbridge.toml
|
||||
2) Edit matterbridge.toml with the settings for your environment.
|
||||
3) Now you can run matterbridge. (```./matterbridge```)
|
||||
3) Now you can run matterbridge. (```./matterbridge```)
|
||||
|
||||
(Matterbridge will only look for the config file in your current directory, if it isn't there specify -conf "/path/toyour/matterbridge.toml")
|
||||
|
||||
```
|
||||
Usage of ./matterbridge:
|
||||
@ -128,6 +134,8 @@ Usage of ./matterbridge:
|
||||
config file (default "matterbridge.toml")
|
||||
-debug
|
||||
enable debug
|
||||
-gops
|
||||
enable gops agent
|
||||
-version
|
||||
show version
|
||||
```
|
||||
@ -161,6 +169,7 @@ Matterbridge wouldn't exist without these libraries:
|
||||
* discord - https://github.com/bwmarrin/discordgo
|
||||
* echo - https://github.com/labstack/echo
|
||||
* gitter - https://github.com/sromku/go-gitter
|
||||
* gops - https://github.com/google/gops
|
||||
* irc - https://github.com/thoj/go-ircevent
|
||||
* mattermost - https://github.com/mattermost/platform
|
||||
* matrix - https://github.com/matrix-org/gomatrix
|
||||
|
@ -27,23 +27,23 @@ type Bridger interface {
|
||||
type Bridge struct {
|
||||
Config config.Protocol
|
||||
Bridger
|
||||
Name string
|
||||
Account string
|
||||
Protocol string
|
||||
ChannelsIn map[string]config.ChannelOptions
|
||||
ChannelsOut map[string]config.ChannelOptions
|
||||
Name string
|
||||
Account string
|
||||
Protocol string
|
||||
Channels map[string]config.ChannelInfo
|
||||
Joined map[string]bool
|
||||
}
|
||||
|
||||
func New(cfg *config.Config, bridge *config.Bridge, c chan config.Message) *Bridge {
|
||||
b := new(Bridge)
|
||||
b.ChannelsIn = make(map[string]config.ChannelOptions)
|
||||
b.ChannelsOut = make(map[string]config.ChannelOptions)
|
||||
b.Channels = make(map[string]config.ChannelInfo)
|
||||
accInfo := strings.Split(bridge.Account, ".")
|
||||
protocol := accInfo[0]
|
||||
name := accInfo[1]
|
||||
b.Name = name
|
||||
b.Protocol = protocol
|
||||
b.Account = bridge.Account
|
||||
b.Joined = make(map[string]bool)
|
||||
|
||||
// override config from environment
|
||||
config.OverrideCfgFromEnv(cfg, protocol, name)
|
||||
@ -83,33 +83,28 @@ func New(cfg *config.Config, bridge *config.Bridge, c chan config.Message) *Brid
|
||||
}
|
||||
|
||||
func (b *Bridge) JoinChannels() error {
|
||||
exists := make(map[string]bool)
|
||||
err := b.joinChannels(b.ChannelsIn, exists)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = b.joinChannels(b.ChannelsOut, exists)
|
||||
err := b.joinChannels(b.Channels, b.Joined)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bridge) joinChannels(cMap map[string]config.ChannelOptions, exists map[string]bool) error {
|
||||
func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map[string]bool) error {
|
||||
mychannel := ""
|
||||
for channel, info := range cMap {
|
||||
if !exists[channel] {
|
||||
mychannel = channel
|
||||
log.Infof("%s: joining %s", b.Account, channel)
|
||||
if b.Protocol == "irc" && info.Key != "" {
|
||||
log.Debugf("using key %s for channel %s", info.Key, channel)
|
||||
mychannel = mychannel + " " + info.Key
|
||||
for ID, channel := range channels {
|
||||
if !exists[ID] {
|
||||
mychannel = channel.Name
|
||||
log.Infof("%s: joining %s (%s)", b.Account, channel.Name, ID)
|
||||
if b.Protocol == "irc" && channel.Options.Key != "" {
|
||||
log.Debugf("using key %s for channel %s", channel.Options.Key, channel.Name)
|
||||
mychannel = mychannel + " " + channel.Options.Key
|
||||
}
|
||||
err := b.JoinChannel(mychannel)
|
||||
err := b.JoinChannel(channel.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
exists[channel] = true
|
||||
exists[ID] = true
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -25,6 +25,16 @@ type Message struct {
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
||||
type ChannelInfo struct {
|
||||
Name string
|
||||
Account string
|
||||
Direction string
|
||||
ID string
|
||||
GID map[string]bool
|
||||
SameChannel map[string]bool
|
||||
Options ChannelOptions
|
||||
}
|
||||
|
||||
type Protocol struct {
|
||||
BindAddress string // mattermost, slack
|
||||
Buffer int // api
|
||||
@ -63,9 +73,10 @@ type ChannelOptions struct {
|
||||
}
|
||||
|
||||
type Bridge struct {
|
||||
Account string
|
||||
Channel string
|
||||
Options ChannelOptions
|
||||
Account string
|
||||
Channel string
|
||||
Options ChannelOptions
|
||||
SameChannel bool
|
||||
}
|
||||
|
||||
type Gateway struct {
|
||||
|
@ -92,7 +92,7 @@ func (b *Birc) Connect() error {
|
||||
}
|
||||
|
||||
func (b *Birc) Disconnect() error {
|
||||
b.i.Disconnect()
|
||||
//b.i.Disconnect()
|
||||
close(b.Local)
|
||||
return nil
|
||||
}
|
||||
|
@ -96,12 +96,7 @@ func (b *Bmattermost) Send(msg config.Message) error {
|
||||
channel := msg.Channel
|
||||
|
||||
if b.Config.PrefixMessagesWithNick {
|
||||
/*if IsMarkup(message) {
|
||||
message = nick + "\n\n" + message
|
||||
} else {
|
||||
*/
|
||||
message = nick + " " + message
|
||||
//}
|
||||
message = nick + message
|
||||
}
|
||||
if !b.Config.UseAPI {
|
||||
matterMessage := matterhook.OMessage{IconURL: b.Config.IconURL}
|
||||
|
@ -73,6 +73,10 @@ func (b *Bslack) Disconnect() error {
|
||||
func (b *Bslack) JoinChannel(channel string) error {
|
||||
// we can only join channels using the API
|
||||
if b.Config.UseAPI {
|
||||
if strings.HasPrefix(b.Config.Token, "xoxb") {
|
||||
// TODO check if bot has already joined channel
|
||||
return nil
|
||||
}
|
||||
_, err := b.sc.JoinChannel(channel)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -80,28 +80,30 @@ func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) {
|
||||
text := ""
|
||||
channel := ""
|
||||
for update := range updates {
|
||||
var message *tgbotapi.Message
|
||||
// handle channels
|
||||
if update.ChannelPost != nil {
|
||||
if update.ChannelPost.From != nil {
|
||||
username = update.ChannelPost.From.FirstName
|
||||
if username == "" {
|
||||
username = update.ChannelPost.From.UserName
|
||||
}
|
||||
}
|
||||
text = update.ChannelPost.Text
|
||||
channel = strconv.FormatInt(update.ChannelPost.Chat.ID, 10)
|
||||
message = update.ChannelPost
|
||||
}
|
||||
if update.EditedChannelPost != nil {
|
||||
message = update.EditedChannelPost
|
||||
}
|
||||
// handle groups
|
||||
if update.Message != nil {
|
||||
if update.Message.From != nil {
|
||||
username = update.Message.From.FirstName
|
||||
if username == "" {
|
||||
username = update.Message.From.UserName
|
||||
}
|
||||
}
|
||||
text = update.Message.Text
|
||||
channel = strconv.FormatInt(update.Message.Chat.ID, 10)
|
||||
message = update.Message
|
||||
}
|
||||
if update.EditedMessage != nil {
|
||||
message = update.EditedMessage
|
||||
}
|
||||
if message.From != nil {
|
||||
username = message.From.FirstName
|
||||
if username == "" {
|
||||
username = message.From.UserName
|
||||
}
|
||||
text = message.Text
|
||||
channel = strconv.FormatInt(message.Chat.ID, 10)
|
||||
}
|
||||
|
||||
if username == "" {
|
||||
username = "unknown"
|
||||
}
|
||||
|
21
changelog.md
21
changelog.md
@ -1,3 +1,24 @@
|
||||
# v0.11.0-dev
|
||||
## New features
|
||||
* general: reusing the same account on multiple gateways now also reuses the connection.
|
||||
This is particuarly useful for irc. See #87
|
||||
* general: the Name is now REQUIRED and needs to be UNIQUE for each gateway configuration
|
||||
|
||||
# v0.10.3
|
||||
## Bugfix
|
||||
* slack: Allow bot tokens for now without warning (slack). Closes #140 (fixes user_is_bot message on channel join)
|
||||
|
||||
# v0.10.2
|
||||
## New features
|
||||
* general: gops agent added. Allows for more debugging. See #134
|
||||
* general: toml inline table support added for config file
|
||||
|
||||
## Bugfix
|
||||
* all: vendored libs updated
|
||||
|
||||
## Changes
|
||||
* general: add more informative messages on startup
|
||||
|
||||
# v0.10.1
|
||||
## Bugfix
|
||||
* gitter: Fix sending messages on new channel join.
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"github.com/42wim/matterbridge/bridge"
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@ -14,21 +13,21 @@ type Gateway struct {
|
||||
*config.Config
|
||||
MyConfig *config.Gateway
|
||||
Bridges map[string]*bridge.Bridge
|
||||
ChannelsOut map[string][]string
|
||||
ChannelsIn map[string][]string
|
||||
Channels map[string]*config.ChannelInfo
|
||||
ChannelOptions map[string]config.ChannelOptions
|
||||
Names map[string]bool
|
||||
Name string
|
||||
Message chan config.Message
|
||||
DestChannelFunc func(msg *config.Message, dest string) []string
|
||||
DestChannelFunc func(msg *config.Message, dest bridge.Bridge) []config.ChannelInfo
|
||||
}
|
||||
|
||||
func New(cfg *config.Config, gateway *config.Gateway) *Gateway {
|
||||
func New(cfg *config.Config) *Gateway {
|
||||
gw := &Gateway{}
|
||||
gw.Name = gateway.Name
|
||||
gw.Config = cfg
|
||||
gw.MyConfig = gateway
|
||||
gw.Channels = make(map[string]*config.ChannelInfo)
|
||||
gw.Message = make(chan config.Message)
|
||||
gw.Bridges = make(map[string]*bridge.Bridge)
|
||||
gw.Names = make(map[string]bool)
|
||||
gw.DestChannelFunc = gw.getDestChannel
|
||||
return gw
|
||||
}
|
||||
@ -36,13 +35,17 @@ func New(cfg *config.Config, gateway *config.Gateway) *Gateway {
|
||||
func (gw *Gateway) AddBridge(cfg *config.Bridge) error {
|
||||
for _, br := range gw.Bridges {
|
||||
if br.Account == cfg.Account {
|
||||
gw.mapChannelsToBridge(br)
|
||||
err := br.JoinChannels()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Bridge %s failed to join channel: %v", br.Account, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
log.Infof("Starting bridge: %s ", cfg.Account)
|
||||
br := bridge.New(gw.Config, cfg, gw.Message)
|
||||
gw.mapChannelsToBridge(br, gw.ChannelsOut)
|
||||
gw.mapChannelsToBridge(br, gw.ChannelsIn)
|
||||
gw.mapChannelsToBridge(br)
|
||||
gw.Bridges[cfg.Account] = br
|
||||
err := br.Connect()
|
||||
if err != nil {
|
||||
@ -55,17 +58,17 @@ func (gw *Gateway) AddBridge(cfg *config.Bridge) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gw *Gateway) mapChannelsToBridge(br *bridge.Bridge, cMap map[string][]string) {
|
||||
for _, channel := range cMap[br.Account] {
|
||||
if _, ok := gw.ChannelOptions[br.Account+channel]; ok {
|
||||
br.ChannelsOut[channel] = gw.ChannelOptions[br.Account+channel]
|
||||
} else {
|
||||
br.ChannelsOut[channel] = config.ChannelOptions{}
|
||||
}
|
||||
func (gw *Gateway) AddConfig(cfg *config.Gateway) error {
|
||||
if gw.Names[cfg.Name] {
|
||||
return fmt.Errorf("Gateway with name %s already exists", cfg.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func (gw *Gateway) Start() error {
|
||||
if cfg.Name == "" {
|
||||
return fmt.Errorf("%s", "Gateway without name found")
|
||||
}
|
||||
log.Infof("Starting gateway: %s", cfg.Name)
|
||||
gw.Names[cfg.Name] = true
|
||||
gw.Name = cfg.Name
|
||||
gw.MyConfig = cfg
|
||||
gw.mapChannels()
|
||||
for _, br := range append(gw.MyConfig.In, append(gw.MyConfig.InOut, gw.MyConfig.Out...)...) {
|
||||
err := gw.AddBridge(&br)
|
||||
@ -73,6 +76,18 @@ func (gw *Gateway) Start() error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gw *Gateway) mapChannelsToBridge(br *bridge.Bridge) {
|
||||
for ID, channel := range gw.Channels {
|
||||
if br.Account == channel.Account {
|
||||
br.Channels[ID] = *channel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (gw *Gateway) Start() error {
|
||||
go gw.handleReceive()
|
||||
return nil
|
||||
}
|
||||
@ -109,65 +124,68 @@ RECONNECT:
|
||||
time.Sleep(time.Second * 60)
|
||||
goto RECONNECT
|
||||
}
|
||||
br.Joined = make(map[string]bool)
|
||||
br.JoinChannels()
|
||||
}
|
||||
|
||||
func (gw *Gateway) mapChannels() error {
|
||||
options := make(map[string]config.ChannelOptions)
|
||||
m := make(map[string][]string)
|
||||
for _, br := range gw.MyConfig.Out {
|
||||
m[br.Account] = append(m[br.Account], br.Channel)
|
||||
options[br.Account+br.Channel] = br.Options
|
||||
for _, br := range append(gw.MyConfig.Out, gw.MyConfig.InOut...) {
|
||||
ID := br.Channel + br.Account
|
||||
_, ok := gw.Channels[ID]
|
||||
if !ok {
|
||||
channel := &config.ChannelInfo{Name: br.Channel, Direction: "out", ID: ID, Options: br.Options, Account: br.Account,
|
||||
GID: make(map[string]bool), SameChannel: make(map[string]bool)}
|
||||
channel.GID[gw.Name] = true
|
||||
channel.SameChannel[gw.Name] = br.SameChannel
|
||||
gw.Channels[channel.ID] = channel
|
||||
}
|
||||
gw.Channels[ID].GID[gw.Name] = true
|
||||
gw.Channels[ID].SameChannel[gw.Name] = br.SameChannel
|
||||
}
|
||||
gw.ChannelsOut = m
|
||||
m = nil
|
||||
m = make(map[string][]string)
|
||||
for _, br := range gw.MyConfig.In {
|
||||
m[br.Account] = append(m[br.Account], br.Channel)
|
||||
options[br.Account+br.Channel] = br.Options
|
||||
|
||||
for _, br := range append(gw.MyConfig.In, gw.MyConfig.InOut...) {
|
||||
ID := br.Channel + br.Account
|
||||
_, ok := gw.Channels[ID]
|
||||
if !ok {
|
||||
channel := &config.ChannelInfo{Name: br.Channel, Direction: "in", ID: ID, Options: br.Options, Account: br.Account,
|
||||
GID: make(map[string]bool), SameChannel: make(map[string]bool)}
|
||||
channel.GID[gw.Name] = true
|
||||
channel.SameChannel[gw.Name] = br.SameChannel
|
||||
gw.Channels[channel.ID] = channel
|
||||
}
|
||||
gw.Channels[ID].GID[gw.Name] = true
|
||||
gw.Channels[ID].SameChannel[gw.Name] = br.SameChannel
|
||||
}
|
||||
gw.ChannelsIn = m
|
||||
for _, br := range gw.MyConfig.InOut {
|
||||
gw.ChannelsIn[br.Account] = append(gw.ChannelsIn[br.Account], br.Channel)
|
||||
gw.ChannelsOut[br.Account] = append(gw.ChannelsOut[br.Account], br.Channel)
|
||||
options[br.Account+br.Channel] = br.Options
|
||||
}
|
||||
gw.ChannelOptions = options
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gw *Gateway) getDestChannel(msg *config.Message, dest string) []string {
|
||||
channels := gw.ChannelsIn[msg.Account]
|
||||
// broadcast to every out channel (irc QUIT)
|
||||
if msg.Event == config.EVENT_JOIN_LEAVE && msg.Channel == "" {
|
||||
return gw.ChannelsOut[dest]
|
||||
}
|
||||
for _, channel := range channels {
|
||||
if channel == msg.Channel {
|
||||
return gw.ChannelsOut[dest]
|
||||
func (gw *Gateway) getDestChannel(msg *config.Message, dest bridge.Bridge) []config.ChannelInfo {
|
||||
var channels []config.ChannelInfo
|
||||
for _, channel := range gw.Channels {
|
||||
if _, ok := gw.Channels[getChannelID(*msg)]; !ok {
|
||||
continue
|
||||
}
|
||||
if channel.Direction == "out" && channel.Account == dest.Account && gw.validGatewayDest(*msg, channel) {
|
||||
channels = append(channels, *channel)
|
||||
}
|
||||
}
|
||||
return []string{}
|
||||
return channels
|
||||
}
|
||||
|
||||
func (gw *Gateway) handleMessage(msg config.Message, dest *bridge.Bridge) {
|
||||
// only relay join/part when configged
|
||||
if msg.Event == config.EVENT_JOIN_LEAVE && !gw.Bridges[dest.Account].Config.ShowJoinPart {
|
||||
// broadcast to every out channel (irc QUIT)
|
||||
if msg.Channel == "" && msg.Event != config.EVENT_JOIN_LEAVE {
|
||||
log.Debug("empty channel")
|
||||
return
|
||||
}
|
||||
originchannel := msg.Channel
|
||||
channels := gw.DestChannelFunc(&msg, dest.Account)
|
||||
for _, channel := range channels {
|
||||
// do not send the message to the bridge we come from if also the channel is the same
|
||||
if msg.Account == dest.Account && channel == originchannel {
|
||||
for _, channel := range gw.DestChannelFunc(&msg, *dest) {
|
||||
// do not send to ourself
|
||||
if channel.ID == getChannelID(msg) {
|
||||
continue
|
||||
}
|
||||
msg.Channel = channel
|
||||
if msg.Channel == "" {
|
||||
log.Debug("empty channel")
|
||||
return
|
||||
}
|
||||
log.Debugf("Sending %#v from %s (%s) to %s (%s)", msg, msg.Account, originchannel, dest.Account, channel)
|
||||
log.Debugf("Sending %#v from %s (%s) to %s (%s)", msg, msg.Account, originchannel, dest.Account, channel.Name)
|
||||
msg.Channel = channel.Name
|
||||
gw.modifyUsername(&msg, dest)
|
||||
// for api we need originchannel as channel
|
||||
if dest.Protocol == "api" {
|
||||
@ -194,21 +212,6 @@ func (gw *Gateway) ignoreMessage(msg *config.Message) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (gw *Gateway) modifyMessage(msg *config.Message, dest *bridge.Bridge) {
|
||||
val := reflect.ValueOf(gw.Config).Elem()
|
||||
for i := 0; i < val.NumField(); i++ {
|
||||
typeField := val.Type().Field(i)
|
||||
// look for the protocol map (both lowercase)
|
||||
if strings.ToLower(typeField.Name) == dest.Protocol {
|
||||
// get the Protocol struct from the map
|
||||
protoCfg := val.Field(i).MapIndex(reflect.ValueOf(dest.Name))
|
||||
//config.SetNickFormat(msg, protoCfg.Interface().(config.Protocol))
|
||||
val.Field(i).SetMapIndex(reflect.ValueOf(dest.Name), protoCfg)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (gw *Gateway) modifyUsername(msg *config.Message, dest *bridge.Bridge) {
|
||||
br := gw.Bridges[msg.Account]
|
||||
msg.Protocol = br.Protocol
|
||||
@ -221,3 +224,29 @@ func (gw *Gateway) modifyUsername(msg *config.Message, dest *bridge.Bridge) {
|
||||
nick = strings.Replace(nick, "{PROTOCOL}", br.Protocol, -1)
|
||||
msg.Username = nick
|
||||
}
|
||||
|
||||
func getChannelID(msg config.Message) string {
|
||||
return msg.Channel + msg.Account
|
||||
}
|
||||
|
||||
func (gw *Gateway) validGatewayDest(msg config.Message, channel *config.ChannelInfo) bool {
|
||||
GIDmap := gw.Channels[getChannelID(msg)].GID
|
||||
// check if we are running a samechannelgateway.
|
||||
// if it is and the channel name matches it's ok, otherwise we shouldn't use this channel.
|
||||
for k, _ := range GIDmap {
|
||||
if channel.SameChannel[k] == true {
|
||||
if msg.Channel == channel.Name {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
// check if we are in the correct gateway
|
||||
for k, _ := range GIDmap {
|
||||
if channel.GID[k] == true {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -2,48 +2,27 @@ package samechannelgateway
|
||||
|
||||
import (
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/gateway"
|
||||
)
|
||||
|
||||
type SameChannelGateway struct {
|
||||
*config.Config
|
||||
MyConfig *config.SameChannelGateway
|
||||
Channels []string
|
||||
Name string
|
||||
}
|
||||
|
||||
func New(cfg *config.Config, gatewayCfg *config.SameChannelGateway) *SameChannelGateway {
|
||||
return &SameChannelGateway{
|
||||
MyConfig: gatewayCfg,
|
||||
Channels: gatewayCfg.Channels,
|
||||
Name: gatewayCfg.Name,
|
||||
Config: cfg}
|
||||
func New(cfg *config.Config) *SameChannelGateway {
|
||||
return &SameChannelGateway{Config: cfg}
|
||||
}
|
||||
|
||||
func (sgw *SameChannelGateway) Start() error {
|
||||
gw := gateway.New(sgw.Config, &config.Gateway{Name: sgw.Name})
|
||||
gw.DestChannelFunc = sgw.getDestChannel
|
||||
for _, account := range sgw.MyConfig.Accounts {
|
||||
for _, channel := range sgw.Channels {
|
||||
br := config.Bridge{Account: account, Channel: channel}
|
||||
gw.MyConfig.InOut = append(gw.MyConfig.InOut, br)
|
||||
func (sgw *SameChannelGateway) GetConfig() []config.Gateway {
|
||||
var gwconfigs []config.Gateway
|
||||
cfg := sgw.Config
|
||||
for _, gw := range cfg.SameChannelGateway {
|
||||
gwconfig := config.Gateway{Name: gw.Name, Enable: gw.Enable}
|
||||
for _, account := range gw.Accounts {
|
||||
for _, channel := range gw.Channels {
|
||||
gwconfig.InOut = append(gwconfig.InOut, config.Bridge{Account: account, Channel: channel, SameChannel: true})
|
||||
}
|
||||
}
|
||||
gwconfigs = append(gwconfigs, gwconfig)
|
||||
}
|
||||
return gw.Start()
|
||||
}
|
||||
|
||||
func (sgw *SameChannelGateway) validChannel(channel string) bool {
|
||||
for _, c := range sgw.Channels {
|
||||
if c == channel {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (sgw *SameChannelGateway) getDestChannel(msg *config.Message, dest string) []string {
|
||||
if sgw.validChannel(msg.Channel) {
|
||||
return []string{msg.Channel}
|
||||
}
|
||||
return []string{}
|
||||
return gwconfigs
|
||||
}
|
||||
|
@ -7,10 +7,12 @@ import (
|
||||
"github.com/42wim/matterbridge/gateway"
|
||||
"github.com/42wim/matterbridge/gateway/samechannel"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/google/gops/agent"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
version = "0.10.1"
|
||||
version = "0.11.0-dev"
|
||||
githash string
|
||||
)
|
||||
|
||||
@ -22,7 +24,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
|
||||
@ -33,29 +40,27 @@ func main() {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
}
|
||||
log.Printf("Running version %s %s", version, githash)
|
||||
if strings.Contains(version, "-dev") {
|
||||
log.Println("WARNING: THIS IS A DEVELOPMENT VERSION. Things may break.")
|
||||
}
|
||||
cfg := config.NewConfig(*flagConfig)
|
||||
for _, gw := range cfg.SameChannelGateway {
|
||||
if !gw.Enable {
|
||||
continue
|
||||
}
|
||||
log.Printf("Starting samechannel gateway %#v", gw.Name)
|
||||
g := samechannelgateway.New(cfg, &gw)
|
||||
err := g.Start()
|
||||
if err != nil {
|
||||
log.Fatalf("Starting gateway failed %#v", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, gw := range cfg.Gateway {
|
||||
g := gateway.New(cfg)
|
||||
sgw := samechannelgateway.New(cfg)
|
||||
gwconfigs := sgw.GetConfig()
|
||||
for _, gw := range append(gwconfigs, cfg.Gateway...) {
|
||||
if !gw.Enable {
|
||||
continue
|
||||
}
|
||||
log.Printf("Starting gateway %#v", gw.Name)
|
||||
g := gateway.New(cfg, &gw)
|
||||
err := g.Start()
|
||||
err := g.AddConfig(&gw)
|
||||
if err != nil {
|
||||
log.Fatalf("Starting gateway failed %#v", err)
|
||||
log.Fatalf("Starting gateway failed: %s", err)
|
||||
}
|
||||
}
|
||||
err := g.Start()
|
||||
if err != nil {
|
||||
log.Fatalf("Starting gateway failed: %s", err)
|
||||
}
|
||||
log.Printf("Gateway(s) started succesfully. Now relaying messages")
|
||||
select {}
|
||||
}
|
||||
|
@ -321,6 +321,7 @@ useAPI=false
|
||||
#Token to connect with the Slack API
|
||||
#You'll have to use a test/api-token using a dedicated user and not a bot token.
|
||||
#See https://github.com/42wim/matterbridge/issues/75 for more info.
|
||||
#Use https://api.slack.com/custom-integrations/legacy-tokens
|
||||
#REQUIRED (when useAPI=true)
|
||||
Token="yourslacktoken"
|
||||
|
||||
@ -586,7 +587,7 @@ RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
|
||||
#
|
||||
|
||||
[[gateway]]
|
||||
#OPTIONAL (not used for now)
|
||||
#REQUIRED and UNIQUE
|
||||
name="gateway1"
|
||||
#Enable enables this gateway
|
||||
##OPTIONAL (default false)
|
||||
@ -658,6 +659,7 @@ enable=true
|
||||
#channel testing on slack and vice versa. (and for the channel testing2 and testing3)
|
||||
|
||||
[[samechannelgateway]]
|
||||
name="samechannel1"
|
||||
enable = false
|
||||
accounts = [ "mattermost.work","slack.hobby" ]
|
||||
channels = [ "testing","testing2","testing3"]
|
||||
|
@ -30,3 +30,12 @@ enable=true
|
||||
[[gateway.out]]
|
||||
account="mattermost.work"
|
||||
channel="off-topic"
|
||||
|
||||
#simpler config possible since v0.10.2
|
||||
#[[gateway]]
|
||||
#name="gateway2"
|
||||
#enable=true
|
||||
#inout = [
|
||||
# { account="irc.freenode", channel="#testing", options={key="channelkey"}},
|
||||
# { account="mattermost.work", channel="off-topic" },
|
||||
#]
|
||||
|
@ -159,11 +159,11 @@ func (m *MMClient) Login() error {
|
||||
m.Client.SetTeamId(m.Team.Id)
|
||||
|
||||
// setup websocket connection
|
||||
wsurl := wsScheme + m.Credentials.Server + model.API_URL_SUFFIX + "/users/websocket"
|
||||
wsurl := wsScheme + m.Credentials.Server + model.API_URL_SUFFIX_V3 + "/users/websocket"
|
||||
header := http.Header{}
|
||||
header.Set(model.HEADER_AUTH, "BEARER "+m.Client.AuthToken)
|
||||
|
||||
m.log.Debug("WsClient: making connection")
|
||||
m.log.Debugf("WsClient: making connection: %s", wsurl)
|
||||
for {
|
||||
wsDialer := &websocket.Dialer{Proxy: http.ProxyFromEnvironment, TLSClientConfig: &tls.Config{InsecureSkipVerify: m.SkipTLSVerify}}
|
||||
m.WsClient, _, err = wsDialer.Dial(wsurl, header)
|
||||
|
2
vendor/github.com/BurntSushi/toml/doc.go
generated
vendored
2
vendor/github.com/BurntSushi/toml/doc.go
generated
vendored
@ -4,7 +4,7 @@ files via reflection. There is also support for delaying decoding with
|
||||
the Primitive type, and querying the set of keys in a TOML document with the
|
||||
MetaData type.
|
||||
|
||||
The specification implemented: https://github.com/mojombo/toml
|
||||
The specification implemented: https://github.com/toml-lang/toml
|
||||
|
||||
The sub-command github.com/BurntSushi/toml/cmd/tomlv can be used to verify
|
||||
whether a file is a valid TOML document. It can also be used to print the
|
||||
|
2
vendor/github.com/BurntSushi/toml/encode.go
generated
vendored
2
vendor/github.com/BurntSushi/toml/encode.go
generated
vendored
@ -241,7 +241,7 @@ func (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) {
|
||||
func (enc *Encoder) eTable(key Key, rv reflect.Value) {
|
||||
panicIfInvalidKey(key)
|
||||
if len(key) == 1 {
|
||||
// Output an extra new line between top-level tables.
|
||||
// Output an extra newline between top-level tables.
|
||||
// (The newline isn't written if nothing else has been written though.)
|
||||
enc.newline()
|
||||
}
|
||||
|
259
vendor/github.com/BurntSushi/toml/lex.go
generated
vendored
259
vendor/github.com/BurntSushi/toml/lex.go
generated
vendored
@ -30,24 +30,28 @@ const (
|
||||
itemArrayTableEnd
|
||||
itemKeyStart
|
||||
itemCommentStart
|
||||
itemInlineTableStart
|
||||
itemInlineTableEnd
|
||||
)
|
||||
|
||||
const (
|
||||
eof = 0
|
||||
tableStart = '['
|
||||
tableEnd = ']'
|
||||
arrayTableStart = '['
|
||||
arrayTableEnd = ']'
|
||||
tableSep = '.'
|
||||
keySep = '='
|
||||
arrayStart = '['
|
||||
arrayEnd = ']'
|
||||
arrayValTerm = ','
|
||||
commentStart = '#'
|
||||
stringStart = '"'
|
||||
stringEnd = '"'
|
||||
rawStringStart = '\''
|
||||
rawStringEnd = '\''
|
||||
eof = 0
|
||||
comma = ','
|
||||
tableStart = '['
|
||||
tableEnd = ']'
|
||||
arrayTableStart = '['
|
||||
arrayTableEnd = ']'
|
||||
tableSep = '.'
|
||||
keySep = '='
|
||||
arrayStart = '['
|
||||
arrayEnd = ']'
|
||||
commentStart = '#'
|
||||
stringStart = '"'
|
||||
stringEnd = '"'
|
||||
rawStringStart = '\''
|
||||
rawStringEnd = '\''
|
||||
inlineTableStart = '{'
|
||||
inlineTableEnd = '}'
|
||||
)
|
||||
|
||||
type stateFn func(lx *lexer) stateFn
|
||||
@ -56,11 +60,18 @@ type lexer struct {
|
||||
input string
|
||||
start int
|
||||
pos int
|
||||
width int
|
||||
line int
|
||||
state stateFn
|
||||
items chan item
|
||||
|
||||
// Allow for backing up up to three runes.
|
||||
// This is necessary because TOML contains 3-rune tokens (""" and ''').
|
||||
prevWidths [3]int
|
||||
nprev int // how many of prevWidths are in use
|
||||
// If we emit an eof, we can still back up, but it is not OK to call
|
||||
// next again.
|
||||
atEOF bool
|
||||
|
||||
// A stack of state functions used to maintain context.
|
||||
// The idea is to reuse parts of the state machine in various places.
|
||||
// For example, values can appear at the top level or within arbitrarily
|
||||
@ -88,7 +99,7 @@ func (lx *lexer) nextItem() item {
|
||||
|
||||
func lex(input string) *lexer {
|
||||
lx := &lexer{
|
||||
input: input + "\n",
|
||||
input: input,
|
||||
state: lexTop,
|
||||
line: 1,
|
||||
items: make(chan item, 10),
|
||||
@ -103,7 +114,7 @@ func (lx *lexer) push(state stateFn) {
|
||||
|
||||
func (lx *lexer) pop() stateFn {
|
||||
if len(lx.stack) == 0 {
|
||||
return lx.errorf("BUG in lexer: no states to pop.")
|
||||
return lx.errorf("BUG in lexer: no states to pop")
|
||||
}
|
||||
last := lx.stack[len(lx.stack)-1]
|
||||
lx.stack = lx.stack[0 : len(lx.stack)-1]
|
||||
@ -125,16 +136,25 @@ func (lx *lexer) emitTrim(typ itemType) {
|
||||
}
|
||||
|
||||
func (lx *lexer) next() (r rune) {
|
||||
if lx.atEOF {
|
||||
panic("next called after EOF")
|
||||
}
|
||||
if lx.pos >= len(lx.input) {
|
||||
lx.width = 0
|
||||
lx.atEOF = true
|
||||
return eof
|
||||
}
|
||||
|
||||
if lx.input[lx.pos] == '\n' {
|
||||
lx.line++
|
||||
}
|
||||
r, lx.width = utf8.DecodeRuneInString(lx.input[lx.pos:])
|
||||
lx.pos += lx.width
|
||||
lx.prevWidths[2] = lx.prevWidths[1]
|
||||
lx.prevWidths[1] = lx.prevWidths[0]
|
||||
if lx.nprev < 3 {
|
||||
lx.nprev++
|
||||
}
|
||||
r, w := utf8.DecodeRuneInString(lx.input[lx.pos:])
|
||||
lx.prevWidths[0] = w
|
||||
lx.pos += w
|
||||
return r
|
||||
}
|
||||
|
||||
@ -143,9 +163,20 @@ func (lx *lexer) ignore() {
|
||||
lx.start = lx.pos
|
||||
}
|
||||
|
||||
// backup steps back one rune. Can be called only once per call of next.
|
||||
// backup steps back one rune. Can be called only twice between calls to next.
|
||||
func (lx *lexer) backup() {
|
||||
lx.pos -= lx.width
|
||||
if lx.atEOF {
|
||||
lx.atEOF = false
|
||||
return
|
||||
}
|
||||
if lx.nprev < 1 {
|
||||
panic("backed up too far")
|
||||
}
|
||||
w := lx.prevWidths[0]
|
||||
lx.prevWidths[0] = lx.prevWidths[1]
|
||||
lx.prevWidths[1] = lx.prevWidths[2]
|
||||
lx.nprev--
|
||||
lx.pos -= w
|
||||
if lx.pos < len(lx.input) && lx.input[lx.pos] == '\n' {
|
||||
lx.line--
|
||||
}
|
||||
@ -182,7 +213,7 @@ func (lx *lexer) skip(pred func(rune) bool) {
|
||||
|
||||
// errorf stops all lexing by emitting an error and returning `nil`.
|
||||
// Note that any value that is a character is escaped if it's a special
|
||||
// character (new lines, tabs, etc.).
|
||||
// character (newlines, tabs, etc.).
|
||||
func (lx *lexer) errorf(format string, values ...interface{}) stateFn {
|
||||
lx.items <- item{
|
||||
itemError,
|
||||
@ -198,7 +229,6 @@ func lexTop(lx *lexer) stateFn {
|
||||
if isWhitespace(r) || isNL(r) {
|
||||
return lexSkip(lx, lexTop)
|
||||
}
|
||||
|
||||
switch r {
|
||||
case commentStart:
|
||||
lx.push(lexTop)
|
||||
@ -207,7 +237,7 @@ func lexTop(lx *lexer) stateFn {
|
||||
return lexTableStart
|
||||
case eof:
|
||||
if lx.pos > lx.start {
|
||||
return lx.errorf("Unexpected EOF.")
|
||||
return lx.errorf("unexpected EOF")
|
||||
}
|
||||
lx.emit(itemEOF)
|
||||
return nil
|
||||
@ -222,12 +252,12 @@ func lexTop(lx *lexer) stateFn {
|
||||
|
||||
// lexTopEnd is entered whenever a top-level item has been consumed. (A value
|
||||
// or a table.) It must see only whitespace, and will turn back to lexTop
|
||||
// upon a new line. If it sees EOF, it will quit the lexer successfully.
|
||||
// upon a newline. If it sees EOF, it will quit the lexer successfully.
|
||||
func lexTopEnd(lx *lexer) stateFn {
|
||||
r := lx.next()
|
||||
switch {
|
||||
case r == commentStart:
|
||||
// a comment will read to a new line for us.
|
||||
// a comment will read to a newline for us.
|
||||
lx.push(lexTop)
|
||||
return lexCommentStart
|
||||
case isWhitespace(r):
|
||||
@ -236,11 +266,11 @@ func lexTopEnd(lx *lexer) stateFn {
|
||||
lx.ignore()
|
||||
return lexTop
|
||||
case r == eof:
|
||||
lx.ignore()
|
||||
return lexTop
|
||||
lx.emit(itemEOF)
|
||||
return nil
|
||||
}
|
||||
return lx.errorf("Expected a top-level item to end with a new line, "+
|
||||
"comment or EOF, but got %q instead.", r)
|
||||
return lx.errorf("expected a top-level item to end with a newline, "+
|
||||
"comment, or EOF, but got %q instead", r)
|
||||
}
|
||||
|
||||
// lexTable lexes the beginning of a table. Namely, it makes sure that
|
||||
@ -267,8 +297,8 @@ func lexTableEnd(lx *lexer) stateFn {
|
||||
|
||||
func lexArrayTableEnd(lx *lexer) stateFn {
|
||||
if r := lx.next(); r != arrayTableEnd {
|
||||
return lx.errorf("Expected end of table array name delimiter %q, "+
|
||||
"but got %q instead.", arrayTableEnd, r)
|
||||
return lx.errorf("expected end of table array name delimiter %q, "+
|
||||
"but got %q instead", arrayTableEnd, r)
|
||||
}
|
||||
lx.emit(itemArrayTableEnd)
|
||||
return lexTopEnd
|
||||
@ -278,11 +308,11 @@ func lexTableNameStart(lx *lexer) stateFn {
|
||||
lx.skip(isWhitespace)
|
||||
switch r := lx.peek(); {
|
||||
case r == tableEnd || r == eof:
|
||||
return lx.errorf("Unexpected end of table name. (Table names cannot " +
|
||||
"be empty.)")
|
||||
return lx.errorf("unexpected end of table name " +
|
||||
"(table names cannot be empty)")
|
||||
case r == tableSep:
|
||||
return lx.errorf("Unexpected table separator. (Table names cannot " +
|
||||
"be empty.)")
|
||||
return lx.errorf("unexpected table separator " +
|
||||
"(table names cannot be empty)")
|
||||
case r == stringStart || r == rawStringStart:
|
||||
lx.ignore()
|
||||
lx.push(lexTableNameEnd)
|
||||
@ -317,8 +347,8 @@ func lexTableNameEnd(lx *lexer) stateFn {
|
||||
case r == tableEnd:
|
||||
return lx.pop()
|
||||
default:
|
||||
return lx.errorf("Expected '.' or ']' to end table name, but got %q "+
|
||||
"instead.", r)
|
||||
return lx.errorf("expected '.' or ']' to end table name, "+
|
||||
"but got %q instead", r)
|
||||
}
|
||||
}
|
||||
|
||||
@ -328,7 +358,7 @@ func lexKeyStart(lx *lexer) stateFn {
|
||||
r := lx.peek()
|
||||
switch {
|
||||
case r == keySep:
|
||||
return lx.errorf("Unexpected key separator %q.", keySep)
|
||||
return lx.errorf("unexpected key separator %q", keySep)
|
||||
case isWhitespace(r) || isNL(r):
|
||||
lx.next()
|
||||
return lexSkip(lx, lexKeyStart)
|
||||
@ -359,7 +389,7 @@ func lexBareKey(lx *lexer) stateFn {
|
||||
lx.emit(itemText)
|
||||
return lexKeyEnd
|
||||
default:
|
||||
return lx.errorf("Bare keys cannot contain %q.", r)
|
||||
return lx.errorf("bare keys cannot contain %q", r)
|
||||
}
|
||||
}
|
||||
|
||||
@ -372,7 +402,7 @@ func lexKeyEnd(lx *lexer) stateFn {
|
||||
case isWhitespace(r):
|
||||
return lexSkip(lx, lexKeyEnd)
|
||||
default:
|
||||
return lx.errorf("Expected key separator %q, but got %q instead.",
|
||||
return lx.errorf("expected key separator %q, but got %q instead",
|
||||
keySep, r)
|
||||
}
|
||||
}
|
||||
@ -381,9 +411,8 @@ func lexKeyEnd(lx *lexer) stateFn {
|
||||
// lexValue will ignore whitespace.
|
||||
// After a value is lexed, the last state on the next is popped and returned.
|
||||
func lexValue(lx *lexer) stateFn {
|
||||
// We allow whitespace to precede a value, but NOT new lines.
|
||||
// In array syntax, the array states are responsible for ignoring new
|
||||
// lines.
|
||||
// We allow whitespace to precede a value, but NOT newlines.
|
||||
// In array syntax, the array states are responsible for ignoring newlines.
|
||||
r := lx.next()
|
||||
switch {
|
||||
case isWhitespace(r):
|
||||
@ -397,6 +426,10 @@ func lexValue(lx *lexer) stateFn {
|
||||
lx.ignore()
|
||||
lx.emit(itemArray)
|
||||
return lexArrayValue
|
||||
case inlineTableStart:
|
||||
lx.ignore()
|
||||
lx.emit(itemInlineTableStart)
|
||||
return lexInlineTableValue
|
||||
case stringStart:
|
||||
if lx.accept(stringStart) {
|
||||
if lx.accept(stringStart) {
|
||||
@ -420,7 +453,7 @@ func lexValue(lx *lexer) stateFn {
|
||||
case '+', '-':
|
||||
return lexNumberStart
|
||||
case '.': // special error case, be kind to users
|
||||
return lx.errorf("Floats must start with a digit, not '.'.")
|
||||
return lx.errorf("floats must start with a digit, not '.'")
|
||||
}
|
||||
if unicode.IsLetter(r) {
|
||||
// Be permissive here; lexBool will give a nice error if the
|
||||
@ -430,11 +463,11 @@ func lexValue(lx *lexer) stateFn {
|
||||
lx.backup()
|
||||
return lexBool
|
||||
}
|
||||
return lx.errorf("Expected value but found %q instead.", r)
|
||||
return lx.errorf("expected value but found %q instead", r)
|
||||
}
|
||||
|
||||
// lexArrayValue consumes one value in an array. It assumes that '[' or ','
|
||||
// have already been consumed. All whitespace and new lines are ignored.
|
||||
// have already been consumed. All whitespace and newlines are ignored.
|
||||
func lexArrayValue(lx *lexer) stateFn {
|
||||
r := lx.next()
|
||||
switch {
|
||||
@ -443,10 +476,11 @@ func lexArrayValue(lx *lexer) stateFn {
|
||||
case r == commentStart:
|
||||
lx.push(lexArrayValue)
|
||||
return lexCommentStart
|
||||
case r == arrayValTerm:
|
||||
return lx.errorf("Unexpected array value terminator %q.",
|
||||
arrayValTerm)
|
||||
case r == comma:
|
||||
return lx.errorf("unexpected comma")
|
||||
case r == arrayEnd:
|
||||
// NOTE(caleb): The spec isn't clear about whether you can have
|
||||
// a trailing comma or not, so we'll allow it.
|
||||
return lexArrayEnd
|
||||
}
|
||||
|
||||
@ -455,8 +489,9 @@ func lexArrayValue(lx *lexer) stateFn {
|
||||
return lexValue
|
||||
}
|
||||
|
||||
// lexArrayValueEnd consumes the cruft between values of an array. Namely,
|
||||
// it ignores whitespace and expects either a ',' or a ']'.
|
||||
// lexArrayValueEnd consumes everything between the end of an array value and
|
||||
// the next value (or the end of the array): it ignores whitespace and newlines
|
||||
// and expects either a ',' or a ']'.
|
||||
func lexArrayValueEnd(lx *lexer) stateFn {
|
||||
r := lx.next()
|
||||
switch {
|
||||
@ -465,31 +500,88 @@ func lexArrayValueEnd(lx *lexer) stateFn {
|
||||
case r == commentStart:
|
||||
lx.push(lexArrayValueEnd)
|
||||
return lexCommentStart
|
||||
case r == arrayValTerm:
|
||||
case r == comma:
|
||||
lx.ignore()
|
||||
return lexArrayValue // move on to the next value
|
||||
case r == arrayEnd:
|
||||
return lexArrayEnd
|
||||
}
|
||||
return lx.errorf("Expected an array value terminator %q or an array "+
|
||||
"terminator %q, but got %q instead.", arrayValTerm, arrayEnd, r)
|
||||
return lx.errorf(
|
||||
"expected a comma or array terminator %q, but got %q instead",
|
||||
arrayEnd, r,
|
||||
)
|
||||
}
|
||||
|
||||
// lexArrayEnd finishes the lexing of an array. It assumes that a ']' has
|
||||
// just been consumed.
|
||||
// lexArrayEnd finishes the lexing of an array.
|
||||
// It assumes that a ']' has just been consumed.
|
||||
func lexArrayEnd(lx *lexer) stateFn {
|
||||
lx.ignore()
|
||||
lx.emit(itemArrayEnd)
|
||||
return lx.pop()
|
||||
}
|
||||
|
||||
// lexInlineTableValue consumes one key/value pair in an inline table.
|
||||
// It assumes that '{' or ',' have already been consumed. Whitespace is ignored.
|
||||
func lexInlineTableValue(lx *lexer) stateFn {
|
||||
r := lx.next()
|
||||
switch {
|
||||
case isWhitespace(r):
|
||||
return lexSkip(lx, lexInlineTableValue)
|
||||
case isNL(r):
|
||||
return lx.errorf("newlines not allowed within inline tables")
|
||||
case r == commentStart:
|
||||
lx.push(lexInlineTableValue)
|
||||
return lexCommentStart
|
||||
case r == comma:
|
||||
return lx.errorf("unexpected comma")
|
||||
case r == inlineTableEnd:
|
||||
return lexInlineTableEnd
|
||||
}
|
||||
lx.backup()
|
||||
lx.push(lexInlineTableValueEnd)
|
||||
return lexKeyStart
|
||||
}
|
||||
|
||||
// lexInlineTableValueEnd consumes everything between the end of an inline table
|
||||
// key/value pair and the next pair (or the end of the table):
|
||||
// it ignores whitespace and expects either a ',' or a '}'.
|
||||
func lexInlineTableValueEnd(lx *lexer) stateFn {
|
||||
r := lx.next()
|
||||
switch {
|
||||
case isWhitespace(r):
|
||||
return lexSkip(lx, lexInlineTableValueEnd)
|
||||
case isNL(r):
|
||||
return lx.errorf("newlines not allowed within inline tables")
|
||||
case r == commentStart:
|
||||
lx.push(lexInlineTableValueEnd)
|
||||
return lexCommentStart
|
||||
case r == comma:
|
||||
lx.ignore()
|
||||
return lexInlineTableValue
|
||||
case r == inlineTableEnd:
|
||||
return lexInlineTableEnd
|
||||
}
|
||||
return lx.errorf("expected a comma or an inline table terminator %q, "+
|
||||
"but got %q instead", inlineTableEnd, r)
|
||||
}
|
||||
|
||||
// lexInlineTableEnd finishes the lexing of an inline table.
|
||||
// It assumes that a '}' has just been consumed.
|
||||
func lexInlineTableEnd(lx *lexer) stateFn {
|
||||
lx.ignore()
|
||||
lx.emit(itemInlineTableEnd)
|
||||
return lx.pop()
|
||||
}
|
||||
|
||||
// lexString consumes the inner contents of a string. It assumes that the
|
||||
// beginning '"' has already been consumed and ignored.
|
||||
func lexString(lx *lexer) stateFn {
|
||||
r := lx.next()
|
||||
switch {
|
||||
case r == eof:
|
||||
return lx.errorf("unexpected EOF")
|
||||
case isNL(r):
|
||||
return lx.errorf("Strings cannot contain new lines.")
|
||||
return lx.errorf("strings cannot contain newlines")
|
||||
case r == '\\':
|
||||
lx.push(lexString)
|
||||
return lexStringEscape
|
||||
@ -506,11 +598,12 @@ func lexString(lx *lexer) stateFn {
|
||||
// lexMultilineString consumes the inner contents of a string. It assumes that
|
||||
// the beginning '"""' has already been consumed and ignored.
|
||||
func lexMultilineString(lx *lexer) stateFn {
|
||||
r := lx.next()
|
||||
switch {
|
||||
case r == '\\':
|
||||
switch lx.next() {
|
||||
case eof:
|
||||
return lx.errorf("unexpected EOF")
|
||||
case '\\':
|
||||
return lexMultilineStringEscape
|
||||
case r == stringEnd:
|
||||
case stringEnd:
|
||||
if lx.accept(stringEnd) {
|
||||
if lx.accept(stringEnd) {
|
||||
lx.backup()
|
||||
@ -534,8 +627,10 @@ func lexMultilineString(lx *lexer) stateFn {
|
||||
func lexRawString(lx *lexer) stateFn {
|
||||
r := lx.next()
|
||||
switch {
|
||||
case r == eof:
|
||||
return lx.errorf("unexpected EOF")
|
||||
case isNL(r):
|
||||
return lx.errorf("Strings cannot contain new lines.")
|
||||
return lx.errorf("strings cannot contain newlines")
|
||||
case r == rawStringEnd:
|
||||
lx.backup()
|
||||
lx.emit(itemRawString)
|
||||
@ -547,12 +642,13 @@ func lexRawString(lx *lexer) stateFn {
|
||||
}
|
||||
|
||||
// lexMultilineRawString consumes a raw string. Nothing can be escaped in such
|
||||
// a string. It assumes that the beginning "'" has already been consumed and
|
||||
// a string. It assumes that the beginning "'''" has already been consumed and
|
||||
// ignored.
|
||||
func lexMultilineRawString(lx *lexer) stateFn {
|
||||
r := lx.next()
|
||||
switch {
|
||||
case r == rawStringEnd:
|
||||
switch lx.next() {
|
||||
case eof:
|
||||
return lx.errorf("unexpected EOF")
|
||||
case rawStringEnd:
|
||||
if lx.accept(rawStringEnd) {
|
||||
if lx.accept(rawStringEnd) {
|
||||
lx.backup()
|
||||
@ -605,10 +701,9 @@ func lexStringEscape(lx *lexer) stateFn {
|
||||
case 'U':
|
||||
return lexLongUnicodeEscape
|
||||
}
|
||||
return lx.errorf("Invalid escape character %q. Only the following "+
|
||||
return lx.errorf("invalid escape character %q; only the following "+
|
||||
"escape characters are allowed: "+
|
||||
"\\b, \\t, \\n, \\f, \\r, \\\", \\/, \\\\, "+
|
||||
"\\uXXXX and \\UXXXXXXXX.", r)
|
||||
`\b, \t, \n, \f, \r, \", \\, \uXXXX, and \UXXXXXXXX`, r)
|
||||
}
|
||||
|
||||
func lexShortUnicodeEscape(lx *lexer) stateFn {
|
||||
@ -616,8 +711,8 @@ func lexShortUnicodeEscape(lx *lexer) stateFn {
|
||||
for i := 0; i < 4; i++ {
|
||||
r = lx.next()
|
||||
if !isHexadecimal(r) {
|
||||
return lx.errorf("Expected four hexadecimal digits after '\\u', "+
|
||||
"but got '%s' instead.", lx.current())
|
||||
return lx.errorf(`expected four hexadecimal digits after '\u', `+
|
||||
"but got %q instead", lx.current())
|
||||
}
|
||||
}
|
||||
return lx.pop()
|
||||
@ -628,8 +723,8 @@ func lexLongUnicodeEscape(lx *lexer) stateFn {
|
||||
for i := 0; i < 8; i++ {
|
||||
r = lx.next()
|
||||
if !isHexadecimal(r) {
|
||||
return lx.errorf("Expected eight hexadecimal digits after '\\U', "+
|
||||
"but got '%s' instead.", lx.current())
|
||||
return lx.errorf(`expected eight hexadecimal digits after '\U', `+
|
||||
"but got %q instead", lx.current())
|
||||
}
|
||||
}
|
||||
return lx.pop()
|
||||
@ -647,9 +742,9 @@ func lexNumberOrDateStart(lx *lexer) stateFn {
|
||||
case 'e', 'E':
|
||||
return lexFloat
|
||||
case '.':
|
||||
return lx.errorf("Floats must start with a digit, not '.'.")
|
||||
return lx.errorf("floats must start with a digit, not '.'")
|
||||
}
|
||||
return lx.errorf("Expected a digit but got %q.", r)
|
||||
return lx.errorf("expected a digit but got %q", r)
|
||||
}
|
||||
|
||||
// lexNumberOrDate consumes either an integer, float or datetime.
|
||||
@ -697,9 +792,9 @@ func lexNumberStart(lx *lexer) stateFn {
|
||||
r := lx.next()
|
||||
if !isDigit(r) {
|
||||
if r == '.' {
|
||||
return lx.errorf("Floats must start with a digit, not '.'.")
|
||||
return lx.errorf("floats must start with a digit, not '.'")
|
||||
}
|
||||
return lx.errorf("Expected a digit but got %q.", r)
|
||||
return lx.errorf("expected a digit but got %q", r)
|
||||
}
|
||||
return lexNumber
|
||||
}
|
||||
@ -757,7 +852,7 @@ func lexBool(lx *lexer) stateFn {
|
||||
lx.emit(itemBool)
|
||||
return lx.pop()
|
||||
}
|
||||
return lx.errorf("Expected value but found %q instead.", s)
|
||||
return lx.errorf("expected value but found %q instead", s)
|
||||
}
|
||||
|
||||
// lexCommentStart begins the lexing of a comment. It will emit
|
||||
@ -769,7 +864,7 @@ func lexCommentStart(lx *lexer) stateFn {
|
||||
}
|
||||
|
||||
// lexComment lexes an entire comment. It assumes that '#' has been consumed.
|
||||
// It will consume *up to* the first new line character, and pass control
|
||||
// It will consume *up to* the first newline character, and pass control
|
||||
// back to the last state on the stack.
|
||||
func lexComment(lx *lexer) stateFn {
|
||||
r := lx.peek()
|
||||
|
35
vendor/github.com/BurntSushi/toml/parse.go
generated
vendored
35
vendor/github.com/BurntSushi/toml/parse.go
generated
vendored
@ -269,6 +269,41 @@ func (p *parser) value(it item) (interface{}, tomlType) {
|
||||
types = append(types, typ)
|
||||
}
|
||||
return array, p.typeOfArray(types)
|
||||
case itemInlineTableStart:
|
||||
var (
|
||||
hash = make(map[string]interface{})
|
||||
outerContext = p.context
|
||||
outerKey = p.currentKey
|
||||
)
|
||||
|
||||
p.context = append(p.context, p.currentKey)
|
||||
p.currentKey = ""
|
||||
for it := p.next(); it.typ != itemInlineTableEnd; it = p.next() {
|
||||
if it.typ != itemKeyStart {
|
||||
p.bug("Expected key start but instead found %q, around line %d",
|
||||
it.val, p.approxLine)
|
||||
}
|
||||
if it.typ == itemCommentStart {
|
||||
p.expect(itemText)
|
||||
continue
|
||||
}
|
||||
|
||||
// retrieve key
|
||||
k := p.next()
|
||||
p.approxLine = k.line
|
||||
kname := p.keyString(k)
|
||||
|
||||
// retrieve value
|
||||
p.currentKey = kname
|
||||
val, typ := p.value(p.next())
|
||||
// make sure we keep metadata up to date
|
||||
p.setType(kname, typ)
|
||||
p.ordered = append(p.ordered, p.context.add(p.currentKey))
|
||||
hash[kname] = val
|
||||
}
|
||||
p.context = outerContext
|
||||
p.currentKey = outerKey
|
||||
return hash, tomlHash
|
||||
}
|
||||
p.bug("Unexpected value type: %s", it.typ)
|
||||
panic("unreachable")
|
||||
|
64
vendor/github.com/Sirupsen/logrus/alt_exit.go
generated
vendored
Normal file
64
vendor/github.com/Sirupsen/logrus/alt_exit.go
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
package logrus
|
||||
|
||||
// The following code was sourced and modified from the
|
||||
// https://github.com/tebeka/atexit package governed by the following license:
|
||||
//
|
||||
// Copyright (c) 2012 Miki Tebeka <miki.tebeka@gmail.com>.
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
var handlers = []func(){}
|
||||
|
||||
func runHandler(handler func()) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err)
|
||||
}
|
||||
}()
|
||||
|
||||
handler()
|
||||
}
|
||||
|
||||
func runHandlers() {
|
||||
for _, handler := range handlers {
|
||||
runHandler(handler)
|
||||
}
|
||||
}
|
||||
|
||||
// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code)
|
||||
func Exit(code int) {
|
||||
runHandlers()
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke
|
||||
// all handlers. The handlers will also be invoked when any Fatal log entry is
|
||||
// made.
|
||||
//
|
||||
// This method is useful when a caller wishes to use logrus to log a fatal
|
||||
// message but also needs to gracefully shutdown. An example usecase could be
|
||||
// closing database connections, or sending a alert that the application is
|
||||
// closing.
|
||||
func RegisterExitHandler(handler func()) {
|
||||
handlers = append(handlers, handler)
|
||||
}
|
57
vendor/github.com/Sirupsen/logrus/entry.go
generated
vendored
57
vendor/github.com/Sirupsen/logrus/entry.go
generated
vendored
@ -3,11 +3,21 @@ package logrus
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var bufferPool *sync.Pool
|
||||
|
||||
func init() {
|
||||
bufferPool = &sync.Pool{
|
||||
New: func() interface{} {
|
||||
return new(bytes.Buffer)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Defines the key when adding errors using WithError.
|
||||
var ErrorKey = "error"
|
||||
|
||||
@ -29,6 +39,9 @@ type Entry struct {
|
||||
|
||||
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
||||
Message string
|
||||
|
||||
// When formatter is called in entry.log(), an Buffer may be set to entry
|
||||
Buffer *bytes.Buffer
|
||||
}
|
||||
|
||||
func NewEntry(logger *Logger) *Entry {
|
||||
@ -39,21 +52,15 @@ func NewEntry(logger *Logger) *Entry {
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a reader for the entry, which is a proxy to the formatter.
|
||||
func (entry *Entry) Reader() (*bytes.Buffer, error) {
|
||||
serialized, err := entry.Logger.Formatter.Format(entry)
|
||||
return bytes.NewBuffer(serialized), err
|
||||
}
|
||||
|
||||
// Returns the string representation from the reader and ultimately the
|
||||
// formatter.
|
||||
func (entry *Entry) String() (string, error) {
|
||||
reader, err := entry.Reader()
|
||||
serialized, err := entry.Logger.Formatter.Format(entry)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return reader.String(), err
|
||||
str := string(serialized)
|
||||
return str, nil
|
||||
}
|
||||
|
||||
// Add an error as single field (using the key defined in ErrorKey) to the Entry.
|
||||
@ -81,6 +88,7 @@ func (entry *Entry) WithFields(fields Fields) *Entry {
|
||||
// This function is not declared with a pointer value because otherwise
|
||||
// race conditions will occur when using multiple goroutines
|
||||
func (entry Entry) log(level Level, msg string) {
|
||||
var buffer *bytes.Buffer
|
||||
entry.Time = time.Now()
|
||||
entry.Level = level
|
||||
entry.Message = msg
|
||||
@ -90,20 +98,23 @@ func (entry Entry) log(level Level, msg string) {
|
||||
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
|
||||
entry.Logger.mu.Unlock()
|
||||
}
|
||||
|
||||
reader, err := entry.Reader()
|
||||
buffer = bufferPool.Get().(*bytes.Buffer)
|
||||
buffer.Reset()
|
||||
defer bufferPool.Put(buffer)
|
||||
entry.Buffer = buffer
|
||||
serialized, err := entry.Logger.Formatter.Format(&entry)
|
||||
entry.Buffer = nil
|
||||
if err != nil {
|
||||
entry.Logger.mu.Lock()
|
||||
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
||||
entry.Logger.mu.Unlock()
|
||||
}
|
||||
|
||||
entry.Logger.mu.Lock()
|
||||
defer entry.Logger.mu.Unlock()
|
||||
|
||||
_, err = io.Copy(entry.Logger.Out, reader)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
||||
} else {
|
||||
entry.Logger.mu.Lock()
|
||||
_, err = entry.Logger.Out.Write(serialized)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
||||
}
|
||||
entry.Logger.mu.Unlock()
|
||||
}
|
||||
|
||||
// To avoid Entry#log() returning a value that only would make sense for
|
||||
@ -150,7 +161,7 @@ func (entry *Entry) Fatal(args ...interface{}) {
|
||||
if entry.Logger.Level >= FatalLevel {
|
||||
entry.log(FatalLevel, fmt.Sprint(args...))
|
||||
}
|
||||
os.Exit(1)
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panic(args ...interface{}) {
|
||||
@ -198,7 +209,7 @@ func (entry *Entry) Fatalf(format string, args ...interface{}) {
|
||||
if entry.Logger.Level >= FatalLevel {
|
||||
entry.Fatal(fmt.Sprintf(format, args...))
|
||||
}
|
||||
os.Exit(1)
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panicf(format string, args ...interface{}) {
|
||||
@ -245,7 +256,7 @@ func (entry *Entry) Fatalln(args ...interface{}) {
|
||||
if entry.Logger.Level >= FatalLevel {
|
||||
entry.Fatal(entry.sprintlnn(args...))
|
||||
}
|
||||
os.Exit(1)
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panicln(args ...interface{}) {
|
||||
|
9
vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
generated
vendored
9
vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
generated
vendored
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
// "os"
|
||||
)
|
||||
|
||||
var log = logrus.New()
|
||||
@ -9,6 +10,14 @@ var log = logrus.New()
|
||||
func init() {
|
||||
log.Formatter = new(logrus.JSONFormatter)
|
||||
log.Formatter = new(logrus.TextFormatter) // default
|
||||
|
||||
// file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
|
||||
// if err == nil {
|
||||
// log.Out = file
|
||||
// } else {
|
||||
// log.Info("Failed to log to file, using default stderr")
|
||||
// }
|
||||
|
||||
log.Level = logrus.DebugLevel
|
||||
}
|
||||
|
||||
|
15
vendor/github.com/Sirupsen/logrus/formatter.go
generated
vendored
15
vendor/github.com/Sirupsen/logrus/formatter.go
generated
vendored
@ -31,18 +31,15 @@ type Formatter interface {
|
||||
// It's not exported because it's still using Data in an opinionated way. It's to
|
||||
// avoid code duplication between the two default formatters.
|
||||
func prefixFieldClashes(data Fields) {
|
||||
_, ok := data["time"]
|
||||
if ok {
|
||||
data["fields.time"] = data["time"]
|
||||
if t, ok := data["time"]; ok {
|
||||
data["fields.time"] = t
|
||||
}
|
||||
|
||||
_, ok = data["msg"]
|
||||
if ok {
|
||||
data["fields.msg"] = data["msg"]
|
||||
if m, ok := data["msg"]; ok {
|
||||
data["fields.msg"] = m
|
||||
}
|
||||
|
||||
_, ok = data["level"]
|
||||
if ok {
|
||||
data["fields.level"] = data["level"]
|
||||
if l, ok := data["level"]; ok {
|
||||
data["fields.level"] = l
|
||||
}
|
||||
}
|
||||
|
61
vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go
generated
vendored
61
vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go
generated
vendored
@ -1,61 +0,0 @@
|
||||
package logstash
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Formatter generates json in logstash format.
|
||||
// Logstash site: http://logstash.net/
|
||||
type LogstashFormatter struct {
|
||||
Type string // if not empty use for logstash type field.
|
||||
|
||||
// TimestampFormat sets the format used for timestamps.
|
||||
TimestampFormat string
|
||||
}
|
||||
|
||||
func (f *LogstashFormatter) Format(entry *logrus.Entry) ([]byte, error) {
|
||||
fields := make(logrus.Fields)
|
||||
for k, v := range entry.Data {
|
||||
fields[k] = v
|
||||
}
|
||||
|
||||
fields["@version"] = 1
|
||||
|
||||
if f.TimestampFormat == "" {
|
||||
f.TimestampFormat = logrus.DefaultTimestampFormat
|
||||
}
|
||||
|
||||
fields["@timestamp"] = entry.Time.Format(f.TimestampFormat)
|
||||
|
||||
// set message field
|
||||
v, ok := entry.Data["message"]
|
||||
if ok {
|
||||
fields["fields.message"] = v
|
||||
}
|
||||
fields["message"] = entry.Message
|
||||
|
||||
// set level field
|
||||
v, ok = entry.Data["level"]
|
||||
if ok {
|
||||
fields["fields.level"] = v
|
||||
}
|
||||
fields["level"] = entry.Level.String()
|
||||
|
||||
// set type field
|
||||
if f.Type != "" {
|
||||
v, ok = entry.Data["type"]
|
||||
if ok {
|
||||
fields["fields.type"] = v
|
||||
}
|
||||
fields["type"] = f.Type
|
||||
}
|
||||
|
||||
serialized, err := json.Marshal(fields)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
|
||||
}
|
||||
return append(serialized, '\n'), nil
|
||||
}
|
39
vendor/github.com/Sirupsen/logrus/json_formatter.go
generated
vendored
39
vendor/github.com/Sirupsen/logrus/json_formatter.go
generated
vendored
@ -5,9 +5,40 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type fieldKey string
|
||||
type FieldMap map[fieldKey]string
|
||||
|
||||
const (
|
||||
FieldKeyMsg = "msg"
|
||||
FieldKeyLevel = "level"
|
||||
FieldKeyTime = "time"
|
||||
)
|
||||
|
||||
func (f FieldMap) resolve(key fieldKey) string {
|
||||
if k, ok := f[key]; ok {
|
||||
return k
|
||||
}
|
||||
|
||||
return string(key)
|
||||
}
|
||||
|
||||
type JSONFormatter struct {
|
||||
// TimestampFormat sets the format used for marshaling timestamps.
|
||||
TimestampFormat string
|
||||
|
||||
// DisableTimestamp allows disabling automatic timestamps in output
|
||||
DisableTimestamp bool
|
||||
|
||||
// FieldMap allows users to customize the names of keys for various fields.
|
||||
// As an example:
|
||||
// formatter := &JSONFormatter{
|
||||
// FieldMap: FieldMap{
|
||||
// FieldKeyTime: "@timestamp",
|
||||
// FieldKeyLevel: "@level",
|
||||
// FieldKeyLevel: "@message",
|
||||
// },
|
||||
// }
|
||||
FieldMap FieldMap
|
||||
}
|
||||
|
||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
@ -29,9 +60,11 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
timestampFormat = DefaultTimestampFormat
|
||||
}
|
||||
|
||||
data["time"] = entry.Time.Format(timestampFormat)
|
||||
data["msg"] = entry.Message
|
||||
data["level"] = entry.Level.String()
|
||||
if !f.DisableTimestamp {
|
||||
data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
|
||||
}
|
||||
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
|
||||
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
|
||||
|
||||
serialized, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
|
162
vendor/github.com/Sirupsen/logrus/logger.go
generated
vendored
162
vendor/github.com/Sirupsen/logrus/logger.go
generated
vendored
@ -26,8 +26,31 @@ type Logger struct {
|
||||
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
||||
// logged. `logrus.Debug` is useful in
|
||||
Level Level
|
||||
// Used to sync writing to the log.
|
||||
mu sync.Mutex
|
||||
// Used to sync writing to the log. Locking is enabled by Default
|
||||
mu MutexWrap
|
||||
// Reusable empty entry
|
||||
entryPool sync.Pool
|
||||
}
|
||||
|
||||
type MutexWrap struct {
|
||||
lock sync.Mutex
|
||||
disabled bool
|
||||
}
|
||||
|
||||
func (mw *MutexWrap) Lock() {
|
||||
if !mw.disabled {
|
||||
mw.lock.Lock()
|
||||
}
|
||||
}
|
||||
|
||||
func (mw *MutexWrap) Unlock() {
|
||||
if !mw.disabled {
|
||||
mw.lock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (mw *MutexWrap) Disable() {
|
||||
mw.disabled = true
|
||||
}
|
||||
|
||||
// Creates a new logger. Configuration should be set by changing `Formatter`,
|
||||
@ -51,162 +74,235 @@ func New() *Logger {
|
||||
}
|
||||
}
|
||||
|
||||
// Adds a field to the log entry, note that you it doesn't log until you call
|
||||
func (logger *Logger) newEntry() *Entry {
|
||||
entry, ok := logger.entryPool.Get().(*Entry)
|
||||
if ok {
|
||||
return entry
|
||||
}
|
||||
return NewEntry(logger)
|
||||
}
|
||||
|
||||
func (logger *Logger) releaseEntry(entry *Entry) {
|
||||
logger.entryPool.Put(entry)
|
||||
}
|
||||
|
||||
// Adds a field to the log entry, note that it doesn't log until you call
|
||||
// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry.
|
||||
// If you want multiple fields, use `WithFields`.
|
||||
func (logger *Logger) WithField(key string, value interface{}) *Entry {
|
||||
return NewEntry(logger).WithField(key, value)
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithField(key, value)
|
||||
}
|
||||
|
||||
// Adds a struct of fields to the log entry. All it does is call `WithField` for
|
||||
// each `Field`.
|
||||
func (logger *Logger) WithFields(fields Fields) *Entry {
|
||||
return NewEntry(logger).WithFields(fields)
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithFields(fields)
|
||||
}
|
||||
|
||||
// Add an error as single field to the log entry. All it does is call
|
||||
// `WithError` for the given `error`.
|
||||
func (logger *Logger) WithError(err error) *Entry {
|
||||
return NewEntry(logger).WithError(err)
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithError(err)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugf(format string, args ...interface{}) {
|
||||
if logger.Level >= DebugLevel {
|
||||
NewEntry(logger).Debugf(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Debugf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Infof(format string, args ...interface{}) {
|
||||
if logger.Level >= InfoLevel {
|
||||
NewEntry(logger).Infof(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Infof(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Printf(format string, args ...interface{}) {
|
||||
NewEntry(logger).Printf(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Printf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warnf(format string, args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warnf(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Warnf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Warningf(format string, args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warnf(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Warnf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Errorf(format string, args ...interface{}) {
|
||||
if logger.Level >= ErrorLevel {
|
||||
NewEntry(logger).Errorf(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Errorf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatalf(format string, args ...interface{}) {
|
||||
if logger.Level >= FatalLevel {
|
||||
NewEntry(logger).Fatalf(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Fatalf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
os.Exit(1)
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panicf(format string, args ...interface{}) {
|
||||
if logger.Level >= PanicLevel {
|
||||
NewEntry(logger).Panicf(format, args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Panicf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Debug(args ...interface{}) {
|
||||
if logger.Level >= DebugLevel {
|
||||
NewEntry(logger).Debug(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Debug(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Info(args ...interface{}) {
|
||||
if logger.Level >= InfoLevel {
|
||||
NewEntry(logger).Info(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Info(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Print(args ...interface{}) {
|
||||
NewEntry(logger).Info(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Info(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warn(args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warn(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Warn(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Warning(args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warn(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Warn(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Error(args ...interface{}) {
|
||||
if logger.Level >= ErrorLevel {
|
||||
NewEntry(logger).Error(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Error(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatal(args ...interface{}) {
|
||||
if logger.Level >= FatalLevel {
|
||||
NewEntry(logger).Fatal(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Fatal(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
os.Exit(1)
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panic(args ...interface{}) {
|
||||
if logger.Level >= PanicLevel {
|
||||
NewEntry(logger).Panic(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Panic(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugln(args ...interface{}) {
|
||||
if logger.Level >= DebugLevel {
|
||||
NewEntry(logger).Debugln(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Debugln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Infoln(args ...interface{}) {
|
||||
if logger.Level >= InfoLevel {
|
||||
NewEntry(logger).Infoln(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Infoln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Println(args ...interface{}) {
|
||||
NewEntry(logger).Println(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Println(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warnln(args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warnln(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Warnln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Warningln(args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warnln(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Warnln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Errorln(args ...interface{}) {
|
||||
if logger.Level >= ErrorLevel {
|
||||
NewEntry(logger).Errorln(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Errorln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatalln(args ...interface{}) {
|
||||
if logger.Level >= FatalLevel {
|
||||
NewEntry(logger).Fatalln(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Fatalln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
os.Exit(1)
|
||||
Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panicln(args ...interface{}) {
|
||||
if logger.Level >= PanicLevel {
|
||||
NewEntry(logger).Panicln(args...)
|
||||
entry := logger.newEntry()
|
||||
entry.Panicln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
//When file is opened with appending mode, it's safe to
|
||||
//write concurrently to a file (within 4k message on Linux).
|
||||
//In these cases user can choose to disable the lock.
|
||||
func (logger *Logger) SetNoLock() {
|
||||
logger.mu.Disable()
|
||||
}
|
||||
|
10
vendor/github.com/Sirupsen/logrus/terminal_appengine.go
generated
vendored
Normal file
10
vendor/github.com/Sirupsen/logrus/terminal_appengine.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
// +build appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import "io"
|
||||
|
||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
||||
func IsTerminal(f io.Writer) bool {
|
||||
return true
|
||||
}
|
1
vendor/github.com/Sirupsen/logrus/terminal_bsd.go
generated
vendored
1
vendor/github.com/Sirupsen/logrus/terminal_bsd.go
generated
vendored
@ -1,4 +1,5 @@
|
||||
// +build darwin freebsd openbsd netbsd dragonfly
|
||||
// +build !appengine
|
||||
|
||||
package logrus
|
||||
|
||||
|
2
vendor/github.com/Sirupsen/logrus/terminal_linux.go
generated
vendored
2
vendor/github.com/Sirupsen/logrus/terminal_linux.go
generated
vendored
@ -3,6 +3,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import "syscall"
|
||||
|
15
vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
generated
vendored
15
vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
generated
vendored
@ -4,18 +4,25 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux darwin freebsd openbsd netbsd dragonfly
|
||||
// +build !appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
||||
func IsTerminal() bool {
|
||||
fd := syscall.Stderr
|
||||
func IsTerminal(f io.Writer) bool {
|
||||
var termios Termios
|
||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
|
||||
return err == 0
|
||||
switch v := f.(type) {
|
||||
case *os.File:
|
||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(v.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
|
||||
return err == 0
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
14
vendor/github.com/Sirupsen/logrus/terminal_solaris.go
generated
vendored
14
vendor/github.com/Sirupsen/logrus/terminal_solaris.go
generated
vendored
@ -1,15 +1,21 @@
|
||||
// +build solaris
|
||||
// +build solaris,!appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||
func IsTerminal() bool {
|
||||
_, err := unix.IoctlGetTermios(int(os.Stdout.Fd()), unix.TCGETA)
|
||||
return err == nil
|
||||
func IsTerminal(f io.Writer) bool {
|
||||
switch v := f.(type) {
|
||||
case *os.File:
|
||||
_, err := unix.IoctlGetTermios(int(v.Fd()), unix.TCGETA)
|
||||
return err == nil
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
18
vendor/github.com/Sirupsen/logrus/terminal_windows.go
generated
vendored
18
vendor/github.com/Sirupsen/logrus/terminal_windows.go
generated
vendored
@ -3,11 +3,13 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
// +build windows,!appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
@ -19,9 +21,13 @@ var (
|
||||
)
|
||||
|
||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
||||
func IsTerminal() bool {
|
||||
fd := syscall.Stderr
|
||||
var st uint32
|
||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
|
||||
return r != 0 && e == 0
|
||||
func IsTerminal(f io.Writer) bool {
|
||||
switch v := f.(type) {
|
||||
case *os.File:
|
||||
var st uint32
|
||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0)
|
||||
return r != 0 && e == 0
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
76
vendor/github.com/Sirupsen/logrus/text_formatter.go
generated
vendored
76
vendor/github.com/Sirupsen/logrus/text_formatter.go
generated
vendored
@ -3,9 +3,9 @@ package logrus
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -20,16 +20,10 @@ const (
|
||||
|
||||
var (
|
||||
baseTimestamp time.Time
|
||||
isTerminal bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
baseTimestamp = time.Now()
|
||||
isTerminal = IsTerminal()
|
||||
}
|
||||
|
||||
func miniTS() int {
|
||||
return int(time.Since(baseTimestamp) / time.Second)
|
||||
}
|
||||
|
||||
type TextFormatter struct {
|
||||
@ -54,10 +48,32 @@ type TextFormatter struct {
|
||||
// that log extremely frequently and don't use the JSON formatter this may not
|
||||
// be desired.
|
||||
DisableSorting bool
|
||||
|
||||
// QuoteEmptyFields will wrap empty fields in quotes if true
|
||||
QuoteEmptyFields bool
|
||||
|
||||
// QuoteCharacter can be set to the override the default quoting character "
|
||||
// with something else. For example: ', or `.
|
||||
QuoteCharacter string
|
||||
|
||||
// Whether the logger's out is to a terminal
|
||||
isTerminal bool
|
||||
|
||||
sync.Once
|
||||
}
|
||||
|
||||
func (f *TextFormatter) init(entry *Entry) {
|
||||
if len(f.QuoteCharacter) == 0 {
|
||||
f.QuoteCharacter = "\""
|
||||
}
|
||||
if entry.Logger != nil {
|
||||
f.isTerminal = IsTerminal(entry.Logger.Out)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
var keys []string = make([]string, 0, len(entry.Data))
|
||||
var b *bytes.Buffer
|
||||
keys := make([]string, 0, len(entry.Data))
|
||||
for k := range entry.Data {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
@ -65,13 +81,17 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
if !f.DisableSorting {
|
||||
sort.Strings(keys)
|
||||
}
|
||||
|
||||
b := &bytes.Buffer{}
|
||||
if entry.Buffer != nil {
|
||||
b = entry.Buffer
|
||||
} else {
|
||||
b = &bytes.Buffer{}
|
||||
}
|
||||
|
||||
prefixFieldClashes(entry.Data)
|
||||
|
||||
isColorTerminal := isTerminal && (runtime.GOOS != "windows")
|
||||
isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors
|
||||
f.Do(func() { f.init(entry) })
|
||||
|
||||
isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors
|
||||
|
||||
timestampFormat := f.TimestampFormat
|
||||
if timestampFormat == "" {
|
||||
@ -111,51 +131,59 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
|
||||
|
||||
levelText := strings.ToUpper(entry.Level.String())[0:4]
|
||||
|
||||
if !f.FullTimestamp {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message)
|
||||
if f.DisableTimestamp {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message)
|
||||
} else if !f.FullTimestamp {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message)
|
||||
} else {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
|
||||
}
|
||||
for _, k := range keys {
|
||||
v := entry.Data[k]
|
||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%+v", levelColor, k, v)
|
||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
|
||||
f.appendValue(b, v)
|
||||
}
|
||||
}
|
||||
|
||||
func needsQuoting(text string) bool {
|
||||
func (f *TextFormatter) needsQuoting(text string) bool {
|
||||
if f.QuoteEmptyFields && len(text) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, ch := range text {
|
||||
if !((ch >= 'a' && ch <= 'z') ||
|
||||
(ch >= 'A' && ch <= 'Z') ||
|
||||
(ch >= '0' && ch <= '9') ||
|
||||
ch == '-' || ch == '.') {
|
||||
return false
|
||||
return true
|
||||
}
|
||||
}
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
||||
|
||||
b.WriteString(key)
|
||||
b.WriteByte('=')
|
||||
f.appendValue(b, value)
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
|
||||
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
if needsQuoting(value) {
|
||||
if !f.needsQuoting(value) {
|
||||
b.WriteString(value)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%q", value)
|
||||
fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, value, f.QuoteCharacter)
|
||||
}
|
||||
case error:
|
||||
errmsg := value.Error()
|
||||
if needsQuoting(errmsg) {
|
||||
if !f.needsQuoting(errmsg) {
|
||||
b.WriteString(errmsg)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%q", value)
|
||||
fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, errmsg, f.QuoteCharacter)
|
||||
}
|
||||
default:
|
||||
fmt.Fprint(b, value)
|
||||
}
|
||||
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
|
39
vendor/github.com/Sirupsen/logrus/writer.go
generated
vendored
39
vendor/github.com/Sirupsen/logrus/writer.go
generated
vendored
@ -7,21 +7,52 @@ import (
|
||||
)
|
||||
|
||||
func (logger *Logger) Writer() *io.PipeWriter {
|
||||
return logger.WriterLevel(InfoLevel)
|
||||
}
|
||||
|
||||
func (logger *Logger) WriterLevel(level Level) *io.PipeWriter {
|
||||
return NewEntry(logger).WriterLevel(level)
|
||||
}
|
||||
|
||||
func (entry *Entry) Writer() *io.PipeWriter {
|
||||
return entry.WriterLevel(InfoLevel)
|
||||
}
|
||||
|
||||
func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
|
||||
reader, writer := io.Pipe()
|
||||
|
||||
go logger.writerScanner(reader)
|
||||
var printFunc func(args ...interface{})
|
||||
|
||||
switch level {
|
||||
case DebugLevel:
|
||||
printFunc = entry.Debug
|
||||
case InfoLevel:
|
||||
printFunc = entry.Info
|
||||
case WarnLevel:
|
||||
printFunc = entry.Warn
|
||||
case ErrorLevel:
|
||||
printFunc = entry.Error
|
||||
case FatalLevel:
|
||||
printFunc = entry.Fatal
|
||||
case PanicLevel:
|
||||
printFunc = entry.Panic
|
||||
default:
|
||||
printFunc = entry.Print
|
||||
}
|
||||
|
||||
go entry.writerScanner(reader, printFunc)
|
||||
runtime.SetFinalizer(writer, writerFinalizer)
|
||||
|
||||
return writer
|
||||
}
|
||||
|
||||
func (logger *Logger) writerScanner(reader *io.PipeReader) {
|
||||
func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) {
|
||||
scanner := bufio.NewScanner(reader)
|
||||
for scanner.Scan() {
|
||||
logger.Print(scanner.Text())
|
||||
printFunc(scanner.Text())
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
logger.Errorf("Error while reading from Writer: %s", err)
|
||||
entry.Errorf("Error while reading from Writer: %s", err)
|
||||
}
|
||||
reader.Close()
|
||||
}
|
||||
|
17
vendor/github.com/go-telegram-bot-api/telegram-bot-api/bot.go
generated
vendored
17
vendor/github.com/go-telegram-bot-api/telegram-bot-api/bot.go
generated
vendored
@ -21,8 +21,10 @@ import (
|
||||
|
||||
// BotAPI allows you to interact with the Telegram Bot API.
|
||||
type BotAPI struct {
|
||||
Token string `json:"token"`
|
||||
Debug bool `json:"debug"`
|
||||
Token string `json:"token"`
|
||||
Debug bool `json:"debug"`
|
||||
Buffer int `json:"buffer"`
|
||||
|
||||
Self User `json:"-"`
|
||||
Client *http.Client `json:"-"`
|
||||
}
|
||||
@ -42,11 +44,12 @@ func NewBotAPIWithClient(token string, client *http.Client) (*BotAPI, error) {
|
||||
bot := &BotAPI{
|
||||
Token: token,
|
||||
Client: client,
|
||||
Buffer: 100,
|
||||
}
|
||||
|
||||
self, err := bot.GetMe()
|
||||
if err != nil {
|
||||
return &BotAPI{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bot.Self = self
|
||||
@ -68,6 +71,10 @@ func (bot *BotAPI) MakeRequest(endpoint string, params url.Values) (APIResponse,
|
||||
return APIResponse{}, errors.New(ErrAPIForbidden)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return APIResponse{}, errors.New(http.StatusText(resp.StatusCode))
|
||||
}
|
||||
|
||||
bytes, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return APIResponse{}, err
|
||||
@ -457,7 +464,7 @@ func (bot *BotAPI) GetWebhookInfo() (WebhookInfo, error) {
|
||||
|
||||
// GetUpdatesChan starts and returns a channel for getting updates.
|
||||
func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (UpdatesChannel, error) {
|
||||
ch := make(chan Update, 100)
|
||||
ch := make(chan Update, bot.Buffer)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
@ -484,7 +491,7 @@ func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (UpdatesChannel, error) {
|
||||
|
||||
// ListenForWebhook registers a http handler for a webhook.
|
||||
func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel {
|
||||
ch := make(chan Update, 100)
|
||||
ch := make(chan Update, bot.Buffer)
|
||||
|
||||
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
||||
bytes, _ := ioutil.ReadAll(r.Body)
|
||||
|
4
vendor/github.com/go-telegram-bot-api/telegram-bot-api/configs.go
generated
vendored
4
vendor/github.com/go-telegram-bot-api/telegram-bot-api/configs.go
generated
vendored
@ -768,8 +768,8 @@ type UpdateConfig struct {
|
||||
|
||||
// WebhookConfig contains information about a SetWebhook request.
|
||||
type WebhookConfig struct {
|
||||
URL *url.URL
|
||||
Certificate interface{}
|
||||
URL *url.URL
|
||||
Certificate interface{}
|
||||
MaxConnections int
|
||||
}
|
||||
|
||||
|
15
vendor/github.com/go-telegram-bot-api/telegram-bot-api/helpers.go
generated
vendored
15
vendor/github.com/go-telegram-bot-api/telegram-bot-api/helpers.go
generated
vendored
@ -318,21 +318,6 @@ func NewWebhookWithCert(link string, file interface{}) WebhookConfig {
|
||||
}
|
||||
}
|
||||
|
||||
// NewWebhookWithCert creates a new webhook with a certificate and max_connections.
|
||||
//
|
||||
// link is the url you wish to get webhooks,
|
||||
// file contains a string to a file, FileReader, or FileBytes.
|
||||
// maxConnections defines maximum number of connections from telegram to your server
|
||||
func NewWebhookWithCertAndMaxConnections(link string, file interface{}, maxConnections int) WebhookConfig {
|
||||
u, _ := url.Parse(link)
|
||||
|
||||
return WebhookConfig{
|
||||
URL: u,
|
||||
Certificate: file,
|
||||
MaxConnections: maxConnections,
|
||||
}
|
||||
}
|
||||
|
||||
// NewInlineQueryResultArticle creates a new inline query article.
|
||||
func NewInlineQueryResultArticle(id, title, messageText string) InlineQueryResultArticle {
|
||||
return InlineQueryResultArticle{
|
||||
|
2
vendor/github.com/go-telegram-bot-api/telegram-bot-api/types.go
generated
vendored
2
vendor/github.com/go-telegram-bot-api/telegram-bot-api/types.go
generated
vendored
@ -194,7 +194,7 @@ func (m *Message) CommandArguments() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
return strings.SplitN(m.Text, " ", 2)[1]
|
||||
return split[1]
|
||||
}
|
||||
|
||||
// MessageEntity contains information about data in a Message.
|
||||
|
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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user