mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-06-26 17:49:23 +00:00
Compare commits
21 Commits
v0.10.0
...
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 | |||
936bccccd2 | |||
c30ffeb81e |
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.0](https://github.com/42wim/matterbridge/releases/tag/v0.10.0)
|
||||
* 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 {
|
||||
|
@ -58,8 +58,9 @@ func (b *Bgitter) JoinChannel(channel string) error {
|
||||
}
|
||||
room, err := b.c.GetRoom(roomID)
|
||||
if err != nil {
|
||||
b.Rooms = append(b.Rooms, *room)
|
||||
return err
|
||||
}
|
||||
b.Rooms = append(b.Rooms, *room)
|
||||
user, err := b.c.GetUser()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -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"
|
||||
}
|
||||
|
25
changelog.md
25
changelog.md
@ -1,3 +1,28 @@
|
||||
# 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.
|
||||
|
||||
# v0.10.0
|
||||
## New features
|
||||
* matrix: New protocol support added (https://matrix.org)
|
||||
|
@ -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.0"
|
||||
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)
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user