mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-06-27 06:29:24 +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
|
# 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.
|
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
|
# Installing
|
||||||
## Binaries
|
## Binaries
|
||||||
Binaries can be found [here] (https://github.com/42wim/matterbridge/releases/)
|
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
|
## 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)
|
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)
|
### Bridge slack (#general) - discord (general)
|
||||||
```
|
```
|
||||||
|
[slack]
|
||||||
[slack.test]
|
[slack.test]
|
||||||
|
useAPI=true
|
||||||
Token="yourslacktoken"
|
Token="yourslacktoken"
|
||||||
PrefixMessagesWithNick=true
|
PrefixMessagesWithNick=true
|
||||||
|
|
||||||
|
[discord]
|
||||||
[discord.test]
|
[discord.test]
|
||||||
Token="yourdiscordtoken"
|
Token="yourdiscordtoken"
|
||||||
Server="yourdiscordservername"
|
Server="yourdiscordservername"
|
||||||
@ -118,9 +122,11 @@ RemoteNickFormat="[{PROTOCOL}/{BRIDGE}] <{NICK}> "
|
|||||||
```
|
```
|
||||||
|
|
||||||
# Running
|
# 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.
|
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:
|
Usage of ./matterbridge:
|
||||||
@ -128,6 +134,8 @@ Usage of ./matterbridge:
|
|||||||
config file (default "matterbridge.toml")
|
config file (default "matterbridge.toml")
|
||||||
-debug
|
-debug
|
||||||
enable debug
|
enable debug
|
||||||
|
-gops
|
||||||
|
enable gops agent
|
||||||
-version
|
-version
|
||||||
show version
|
show version
|
||||||
```
|
```
|
||||||
@ -161,6 +169,7 @@ Matterbridge wouldn't exist without these libraries:
|
|||||||
* discord - https://github.com/bwmarrin/discordgo
|
* discord - https://github.com/bwmarrin/discordgo
|
||||||
* echo - https://github.com/labstack/echo
|
* echo - https://github.com/labstack/echo
|
||||||
* gitter - https://github.com/sromku/go-gitter
|
* gitter - https://github.com/sromku/go-gitter
|
||||||
|
* gops - https://github.com/google/gops
|
||||||
* irc - https://github.com/thoj/go-ircevent
|
* irc - https://github.com/thoj/go-ircevent
|
||||||
* mattermost - https://github.com/mattermost/platform
|
* mattermost - https://github.com/mattermost/platform
|
||||||
* matrix - https://github.com/matrix-org/gomatrix
|
* matrix - https://github.com/matrix-org/gomatrix
|
||||||
|
@ -27,23 +27,23 @@ type Bridger interface {
|
|||||||
type Bridge struct {
|
type Bridge struct {
|
||||||
Config config.Protocol
|
Config config.Protocol
|
||||||
Bridger
|
Bridger
|
||||||
Name string
|
Name string
|
||||||
Account string
|
Account string
|
||||||
Protocol string
|
Protocol string
|
||||||
ChannelsIn map[string]config.ChannelOptions
|
Channels map[string]config.ChannelInfo
|
||||||
ChannelsOut map[string]config.ChannelOptions
|
Joined map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(cfg *config.Config, bridge *config.Bridge, c chan config.Message) *Bridge {
|
func New(cfg *config.Config, bridge *config.Bridge, c chan config.Message) *Bridge {
|
||||||
b := new(Bridge)
|
b := new(Bridge)
|
||||||
b.ChannelsIn = make(map[string]config.ChannelOptions)
|
b.Channels = make(map[string]config.ChannelInfo)
|
||||||
b.ChannelsOut = make(map[string]config.ChannelOptions)
|
|
||||||
accInfo := strings.Split(bridge.Account, ".")
|
accInfo := strings.Split(bridge.Account, ".")
|
||||||
protocol := accInfo[0]
|
protocol := accInfo[0]
|
||||||
name := accInfo[1]
|
name := accInfo[1]
|
||||||
b.Name = name
|
b.Name = name
|
||||||
b.Protocol = protocol
|
b.Protocol = protocol
|
||||||
b.Account = bridge.Account
|
b.Account = bridge.Account
|
||||||
|
b.Joined = make(map[string]bool)
|
||||||
|
|
||||||
// override config from environment
|
// override config from environment
|
||||||
config.OverrideCfgFromEnv(cfg, protocol, name)
|
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 {
|
func (b *Bridge) JoinChannels() error {
|
||||||
exists := make(map[string]bool)
|
err := b.joinChannels(b.Channels, b.Joined)
|
||||||
err := b.joinChannels(b.ChannelsIn, exists)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = b.joinChannels(b.ChannelsOut, exists)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
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 := ""
|
mychannel := ""
|
||||||
for channel, info := range cMap {
|
for ID, channel := range channels {
|
||||||
if !exists[channel] {
|
if !exists[ID] {
|
||||||
mychannel = channel
|
mychannel = channel.Name
|
||||||
log.Infof("%s: joining %s", b.Account, channel)
|
log.Infof("%s: joining %s (%s)", b.Account, channel.Name, ID)
|
||||||
if b.Protocol == "irc" && info.Key != "" {
|
if b.Protocol == "irc" && channel.Options.Key != "" {
|
||||||
log.Debugf("using key %s for channel %s", info.Key, channel)
|
log.Debugf("using key %s for channel %s", channel.Options.Key, channel.Name)
|
||||||
mychannel = mychannel + " " + info.Key
|
mychannel = mychannel + " " + channel.Options.Key
|
||||||
}
|
}
|
||||||
err := b.JoinChannel(mychannel)
|
err := b.JoinChannel(channel.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
exists[channel] = true
|
exists[ID] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -25,6 +25,16 @@ type Message struct {
|
|||||||
Timestamp time.Time
|
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 {
|
type Protocol struct {
|
||||||
BindAddress string // mattermost, slack
|
BindAddress string // mattermost, slack
|
||||||
Buffer int // api
|
Buffer int // api
|
||||||
@ -63,9 +73,10 @@ type ChannelOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Bridge struct {
|
type Bridge struct {
|
||||||
Account string
|
Account string
|
||||||
Channel string
|
Channel string
|
||||||
Options ChannelOptions
|
Options ChannelOptions
|
||||||
|
SameChannel bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Gateway struct {
|
type Gateway struct {
|
||||||
|
@ -58,8 +58,9 @@ func (b *Bgitter) JoinChannel(channel string) error {
|
|||||||
}
|
}
|
||||||
room, err := b.c.GetRoom(roomID)
|
room, err := b.c.GetRoom(roomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Rooms = append(b.Rooms, *room)
|
return err
|
||||||
}
|
}
|
||||||
|
b.Rooms = append(b.Rooms, *room)
|
||||||
user, err := b.c.GetUser()
|
user, err := b.c.GetUser()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -92,7 +92,7 @@ func (b *Birc) Connect() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *Birc) Disconnect() error {
|
func (b *Birc) Disconnect() error {
|
||||||
b.i.Disconnect()
|
//b.i.Disconnect()
|
||||||
close(b.Local)
|
close(b.Local)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -96,12 +96,7 @@ func (b *Bmattermost) Send(msg config.Message) error {
|
|||||||
channel := msg.Channel
|
channel := msg.Channel
|
||||||
|
|
||||||
if b.Config.PrefixMessagesWithNick {
|
if b.Config.PrefixMessagesWithNick {
|
||||||
/*if IsMarkup(message) {
|
message = nick + message
|
||||||
message = nick + "\n\n" + message
|
|
||||||
} else {
|
|
||||||
*/
|
|
||||||
message = nick + " " + message
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
if !b.Config.UseAPI {
|
if !b.Config.UseAPI {
|
||||||
matterMessage := matterhook.OMessage{IconURL: b.Config.IconURL}
|
matterMessage := matterhook.OMessage{IconURL: b.Config.IconURL}
|
||||||
|
@ -73,6 +73,10 @@ func (b *Bslack) Disconnect() error {
|
|||||||
func (b *Bslack) JoinChannel(channel string) error {
|
func (b *Bslack) JoinChannel(channel string) error {
|
||||||
// we can only join channels using the API
|
// we can only join channels using the API
|
||||||
if b.Config.UseAPI {
|
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)
|
_, err := b.sc.JoinChannel(channel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -80,28 +80,30 @@ func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) {
|
|||||||
text := ""
|
text := ""
|
||||||
channel := ""
|
channel := ""
|
||||||
for update := range updates {
|
for update := range updates {
|
||||||
|
var message *tgbotapi.Message
|
||||||
// handle channels
|
// handle channels
|
||||||
if update.ChannelPost != nil {
|
if update.ChannelPost != nil {
|
||||||
if update.ChannelPost.From != nil {
|
message = update.ChannelPost
|
||||||
username = update.ChannelPost.From.FirstName
|
}
|
||||||
if username == "" {
|
if update.EditedChannelPost != nil {
|
||||||
username = update.ChannelPost.From.UserName
|
message = update.EditedChannelPost
|
||||||
}
|
|
||||||
}
|
|
||||||
text = update.ChannelPost.Text
|
|
||||||
channel = strconv.FormatInt(update.ChannelPost.Chat.ID, 10)
|
|
||||||
}
|
}
|
||||||
// handle groups
|
// handle groups
|
||||||
if update.Message != nil {
|
if update.Message != nil {
|
||||||
if update.Message.From != nil {
|
message = update.Message
|
||||||
username = update.Message.From.FirstName
|
|
||||||
if username == "" {
|
|
||||||
username = update.Message.From.UserName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
text = update.Message.Text
|
|
||||||
channel = strconv.FormatInt(update.Message.Chat.ID, 10)
|
|
||||||
}
|
}
|
||||||
|
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 == "" {
|
if username == "" {
|
||||||
username = "unknown"
|
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
|
# v0.10.0
|
||||||
## New features
|
## New features
|
||||||
* matrix: New protocol support added (https://matrix.org)
|
* matrix: New protocol support added (https://matrix.org)
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"github.com/42wim/matterbridge/bridge"
|
"github.com/42wim/matterbridge/bridge"
|
||||||
"github.com/42wim/matterbridge/bridge/config"
|
"github.com/42wim/matterbridge/bridge/config"
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"reflect"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -14,21 +13,21 @@ type Gateway struct {
|
|||||||
*config.Config
|
*config.Config
|
||||||
MyConfig *config.Gateway
|
MyConfig *config.Gateway
|
||||||
Bridges map[string]*bridge.Bridge
|
Bridges map[string]*bridge.Bridge
|
||||||
ChannelsOut map[string][]string
|
Channels map[string]*config.ChannelInfo
|
||||||
ChannelsIn map[string][]string
|
|
||||||
ChannelOptions map[string]config.ChannelOptions
|
ChannelOptions map[string]config.ChannelOptions
|
||||||
|
Names map[string]bool
|
||||||
Name string
|
Name string
|
||||||
Message chan config.Message
|
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 := &Gateway{}
|
||||||
gw.Name = gateway.Name
|
|
||||||
gw.Config = cfg
|
gw.Config = cfg
|
||||||
gw.MyConfig = gateway
|
gw.Channels = make(map[string]*config.ChannelInfo)
|
||||||
gw.Message = make(chan config.Message)
|
gw.Message = make(chan config.Message)
|
||||||
gw.Bridges = make(map[string]*bridge.Bridge)
|
gw.Bridges = make(map[string]*bridge.Bridge)
|
||||||
|
gw.Names = make(map[string]bool)
|
||||||
gw.DestChannelFunc = gw.getDestChannel
|
gw.DestChannelFunc = gw.getDestChannel
|
||||||
return gw
|
return gw
|
||||||
}
|
}
|
||||||
@ -36,13 +35,17 @@ func New(cfg *config.Config, gateway *config.Gateway) *Gateway {
|
|||||||
func (gw *Gateway) AddBridge(cfg *config.Bridge) error {
|
func (gw *Gateway) AddBridge(cfg *config.Bridge) error {
|
||||||
for _, br := range gw.Bridges {
|
for _, br := range gw.Bridges {
|
||||||
if br.Account == cfg.Account {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Infof("Starting bridge: %s ", cfg.Account)
|
log.Infof("Starting bridge: %s ", cfg.Account)
|
||||||
br := bridge.New(gw.Config, cfg, gw.Message)
|
br := bridge.New(gw.Config, cfg, gw.Message)
|
||||||
gw.mapChannelsToBridge(br, gw.ChannelsOut)
|
gw.mapChannelsToBridge(br)
|
||||||
gw.mapChannelsToBridge(br, gw.ChannelsIn)
|
|
||||||
gw.Bridges[cfg.Account] = br
|
gw.Bridges[cfg.Account] = br
|
||||||
err := br.Connect()
|
err := br.Connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -55,17 +58,17 @@ func (gw *Gateway) AddBridge(cfg *config.Bridge) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gw *Gateway) mapChannelsToBridge(br *bridge.Bridge, cMap map[string][]string) {
|
func (gw *Gateway) AddConfig(cfg *config.Gateway) error {
|
||||||
for _, channel := range cMap[br.Account] {
|
if gw.Names[cfg.Name] {
|
||||||
if _, ok := gw.ChannelOptions[br.Account+channel]; ok {
|
return fmt.Errorf("Gateway with name %s already exists", cfg.Name)
|
||||||
br.ChannelsOut[channel] = gw.ChannelOptions[br.Account+channel]
|
|
||||||
} else {
|
|
||||||
br.ChannelsOut[channel] = config.ChannelOptions{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
if cfg.Name == "" {
|
||||||
|
return fmt.Errorf("%s", "Gateway without name found")
|
||||||
func (gw *Gateway) Start() error {
|
}
|
||||||
|
log.Infof("Starting gateway: %s", cfg.Name)
|
||||||
|
gw.Names[cfg.Name] = true
|
||||||
|
gw.Name = cfg.Name
|
||||||
|
gw.MyConfig = cfg
|
||||||
gw.mapChannels()
|
gw.mapChannels()
|
||||||
for _, br := range append(gw.MyConfig.In, append(gw.MyConfig.InOut, gw.MyConfig.Out...)...) {
|
for _, br := range append(gw.MyConfig.In, append(gw.MyConfig.InOut, gw.MyConfig.Out...)...) {
|
||||||
err := gw.AddBridge(&br)
|
err := gw.AddBridge(&br)
|
||||||
@ -73,6 +76,18 @@ func (gw *Gateway) Start() error {
|
|||||||
return err
|
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()
|
go gw.handleReceive()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -109,65 +124,68 @@ RECONNECT:
|
|||||||
time.Sleep(time.Second * 60)
|
time.Sleep(time.Second * 60)
|
||||||
goto RECONNECT
|
goto RECONNECT
|
||||||
}
|
}
|
||||||
|
br.Joined = make(map[string]bool)
|
||||||
br.JoinChannels()
|
br.JoinChannels()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gw *Gateway) mapChannels() error {
|
func (gw *Gateway) mapChannels() error {
|
||||||
options := make(map[string]config.ChannelOptions)
|
for _, br := range append(gw.MyConfig.Out, gw.MyConfig.InOut...) {
|
||||||
m := make(map[string][]string)
|
ID := br.Channel + br.Account
|
||||||
for _, br := range gw.MyConfig.Out {
|
_, ok := gw.Channels[ID]
|
||||||
m[br.Account] = append(m[br.Account], br.Channel)
|
if !ok {
|
||||||
options[br.Account+br.Channel] = br.Options
|
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
|
for _, br := range append(gw.MyConfig.In, gw.MyConfig.InOut...) {
|
||||||
m = make(map[string][]string)
|
ID := br.Channel + br.Account
|
||||||
for _, br := range gw.MyConfig.In {
|
_, ok := gw.Channels[ID]
|
||||||
m[br.Account] = append(m[br.Account], br.Channel)
|
if !ok {
|
||||||
options[br.Account+br.Channel] = br.Options
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gw *Gateway) getDestChannel(msg *config.Message, dest string) []string {
|
func (gw *Gateway) getDestChannel(msg *config.Message, dest bridge.Bridge) []config.ChannelInfo {
|
||||||
channels := gw.ChannelsIn[msg.Account]
|
var channels []config.ChannelInfo
|
||||||
// broadcast to every out channel (irc QUIT)
|
for _, channel := range gw.Channels {
|
||||||
if msg.Event == config.EVENT_JOIN_LEAVE && msg.Channel == "" {
|
if _, ok := gw.Channels[getChannelID(*msg)]; !ok {
|
||||||
return gw.ChannelsOut[dest]
|
continue
|
||||||
}
|
}
|
||||||
for _, channel := range channels {
|
if channel.Direction == "out" && channel.Account == dest.Account && gw.validGatewayDest(*msg, channel) {
|
||||||
if channel == msg.Channel {
|
channels = append(channels, *channel)
|
||||||
return gw.ChannelsOut[dest]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return []string{}
|
return channels
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gw *Gateway) handleMessage(msg config.Message, dest *bridge.Bridge) {
|
func (gw *Gateway) handleMessage(msg config.Message, dest *bridge.Bridge) {
|
||||||
// only relay join/part when configged
|
// broadcast to every out channel (irc QUIT)
|
||||||
if msg.Event == config.EVENT_JOIN_LEAVE && !gw.Bridges[dest.Account].Config.ShowJoinPart {
|
if msg.Channel == "" && msg.Event != config.EVENT_JOIN_LEAVE {
|
||||||
|
log.Debug("empty channel")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
originchannel := msg.Channel
|
originchannel := msg.Channel
|
||||||
channels := gw.DestChannelFunc(&msg, dest.Account)
|
for _, channel := range gw.DestChannelFunc(&msg, *dest) {
|
||||||
for _, channel := range channels {
|
// do not send to ourself
|
||||||
// do not send the message to the bridge we come from if also the channel is the same
|
if channel.ID == getChannelID(msg) {
|
||||||
if msg.Account == dest.Account && channel == originchannel {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
msg.Channel = channel
|
log.Debugf("Sending %#v from %s (%s) to %s (%s)", msg, msg.Account, originchannel, dest.Account, channel.Name)
|
||||||
if msg.Channel == "" {
|
msg.Channel = channel.Name
|
||||||
log.Debug("empty channel")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Debugf("Sending %#v from %s (%s) to %s (%s)", msg, msg.Account, originchannel, dest.Account, channel)
|
|
||||||
gw.modifyUsername(&msg, dest)
|
gw.modifyUsername(&msg, dest)
|
||||||
// for api we need originchannel as channel
|
// for api we need originchannel as channel
|
||||||
if dest.Protocol == "api" {
|
if dest.Protocol == "api" {
|
||||||
@ -194,21 +212,6 @@ func (gw *Gateway) ignoreMessage(msg *config.Message) bool {
|
|||||||
return false
|
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) {
|
func (gw *Gateway) modifyUsername(msg *config.Message, dest *bridge.Bridge) {
|
||||||
br := gw.Bridges[msg.Account]
|
br := gw.Bridges[msg.Account]
|
||||||
msg.Protocol = br.Protocol
|
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)
|
nick = strings.Replace(nick, "{PROTOCOL}", br.Protocol, -1)
|
||||||
msg.Username = nick
|
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 (
|
import (
|
||||||
"github.com/42wim/matterbridge/bridge/config"
|
"github.com/42wim/matterbridge/bridge/config"
|
||||||
"github.com/42wim/matterbridge/gateway"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SameChannelGateway struct {
|
type SameChannelGateway struct {
|
||||||
*config.Config
|
*config.Config
|
||||||
MyConfig *config.SameChannelGateway
|
|
||||||
Channels []string
|
|
||||||
Name string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(cfg *config.Config, gatewayCfg *config.SameChannelGateway) *SameChannelGateway {
|
func New(cfg *config.Config) *SameChannelGateway {
|
||||||
return &SameChannelGateway{
|
return &SameChannelGateway{Config: cfg}
|
||||||
MyConfig: gatewayCfg,
|
|
||||||
Channels: gatewayCfg.Channels,
|
|
||||||
Name: gatewayCfg.Name,
|
|
||||||
Config: cfg}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sgw *SameChannelGateway) Start() error {
|
func (sgw *SameChannelGateway) GetConfig() []config.Gateway {
|
||||||
gw := gateway.New(sgw.Config, &config.Gateway{Name: sgw.Name})
|
var gwconfigs []config.Gateway
|
||||||
gw.DestChannelFunc = sgw.getDestChannel
|
cfg := sgw.Config
|
||||||
for _, account := range sgw.MyConfig.Accounts {
|
for _, gw := range cfg.SameChannelGateway {
|
||||||
for _, channel := range sgw.Channels {
|
gwconfig := config.Gateway{Name: gw.Name, Enable: gw.Enable}
|
||||||
br := config.Bridge{Account: account, Channel: channel}
|
for _, account := range gw.Accounts {
|
||||||
gw.MyConfig.InOut = append(gw.MyConfig.InOut, br)
|
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()
|
return gwconfigs
|
||||||
}
|
|
||||||
|
|
||||||
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{}
|
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,12 @@ import (
|
|||||||
"github.com/42wim/matterbridge/gateway"
|
"github.com/42wim/matterbridge/gateway"
|
||||||
"github.com/42wim/matterbridge/gateway/samechannel"
|
"github.com/42wim/matterbridge/gateway/samechannel"
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"github.com/google/gops/agent"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
version = "0.10.0"
|
version = "0.11.0-dev"
|
||||||
githash string
|
githash string
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,7 +24,12 @@ func main() {
|
|||||||
flagConfig := flag.String("conf", "matterbridge.toml", "config file")
|
flagConfig := flag.String("conf", "matterbridge.toml", "config file")
|
||||||
flagDebug := flag.Bool("debug", false, "enable debug")
|
flagDebug := flag.Bool("debug", false, "enable debug")
|
||||||
flagVersion := flag.Bool("version", false, "show version")
|
flagVersion := flag.Bool("version", false, "show version")
|
||||||
|
flagGops := flag.Bool("gops", false, "enable gops agent")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
if *flagGops {
|
||||||
|
agent.Listen(&agent.Options{})
|
||||||
|
defer agent.Close()
|
||||||
|
}
|
||||||
if *flagVersion {
|
if *flagVersion {
|
||||||
fmt.Printf("version: %s %s\n", version, githash)
|
fmt.Printf("version: %s %s\n", version, githash)
|
||||||
return
|
return
|
||||||
@ -33,29 +40,27 @@ func main() {
|
|||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
}
|
}
|
||||||
log.Printf("Running version %s %s", version, githash)
|
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)
|
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 {
|
if !gw.Enable {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Printf("Starting gateway %#v", gw.Name)
|
err := g.AddConfig(&gw)
|
||||||
g := gateway.New(cfg, &gw)
|
|
||||||
err := g.Start()
|
|
||||||
if err != nil {
|
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 {}
|
select {}
|
||||||
}
|
}
|
||||||
|
@ -321,6 +321,7 @@ useAPI=false
|
|||||||
#Token to connect with the Slack API
|
#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.
|
#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.
|
#See https://github.com/42wim/matterbridge/issues/75 for more info.
|
||||||
|
#Use https://api.slack.com/custom-integrations/legacy-tokens
|
||||||
#REQUIRED (when useAPI=true)
|
#REQUIRED (when useAPI=true)
|
||||||
Token="yourslacktoken"
|
Token="yourslacktoken"
|
||||||
|
|
||||||
@ -586,7 +587,7 @@ RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
|
|||||||
#
|
#
|
||||||
|
|
||||||
[[gateway]]
|
[[gateway]]
|
||||||
#OPTIONAL (not used for now)
|
#REQUIRED and UNIQUE
|
||||||
name="gateway1"
|
name="gateway1"
|
||||||
#Enable enables this gateway
|
#Enable enables this gateway
|
||||||
##OPTIONAL (default false)
|
##OPTIONAL (default false)
|
||||||
@ -658,6 +659,7 @@ enable=true
|
|||||||
#channel testing on slack and vice versa. (and for the channel testing2 and testing3)
|
#channel testing on slack and vice versa. (and for the channel testing2 and testing3)
|
||||||
|
|
||||||
[[samechannelgateway]]
|
[[samechannelgateway]]
|
||||||
|
name="samechannel1"
|
||||||
enable = false
|
enable = false
|
||||||
accounts = [ "mattermost.work","slack.hobby" ]
|
accounts = [ "mattermost.work","slack.hobby" ]
|
||||||
channels = [ "testing","testing2","testing3"]
|
channels = [ "testing","testing2","testing3"]
|
||||||
|
@ -30,3 +30,12 @@ enable=true
|
|||||||
[[gateway.out]]
|
[[gateway.out]]
|
||||||
account="mattermost.work"
|
account="mattermost.work"
|
||||||
channel="off-topic"
|
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)
|
m.Client.SetTeamId(m.Team.Id)
|
||||||
|
|
||||||
// setup websocket connection
|
// 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 := http.Header{}
|
||||||
header.Set(model.HEADER_AUTH, "BEARER "+m.Client.AuthToken)
|
header.Set(model.HEADER_AUTH, "BEARER "+m.Client.AuthToken)
|
||||||
|
|
||||||
m.log.Debug("WsClient: making connection")
|
m.log.Debugf("WsClient: making connection: %s", wsurl)
|
||||||
for {
|
for {
|
||||||
wsDialer := &websocket.Dialer{Proxy: http.ProxyFromEnvironment, TLSClientConfig: &tls.Config{InsecureSkipVerify: m.SkipTLSVerify}}
|
wsDialer := &websocket.Dialer{Proxy: http.ProxyFromEnvironment, TLSClientConfig: &tls.Config{InsecureSkipVerify: m.SkipTLSVerify}}
|
||||||
m.WsClient, _, err = wsDialer.Dial(wsurl, header)
|
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
|
the Primitive type, and querying the set of keys in a TOML document with the
|
||||||
MetaData type.
|
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
|
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
|
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) {
|
func (enc *Encoder) eTable(key Key, rv reflect.Value) {
|
||||||
panicIfInvalidKey(key)
|
panicIfInvalidKey(key)
|
||||||
if len(key) == 1 {
|
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.)
|
// (The newline isn't written if nothing else has been written though.)
|
||||||
enc.newline()
|
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
|
itemArrayTableEnd
|
||||||
itemKeyStart
|
itemKeyStart
|
||||||
itemCommentStart
|
itemCommentStart
|
||||||
|
itemInlineTableStart
|
||||||
|
itemInlineTableEnd
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
eof = 0
|
eof = 0
|
||||||
tableStart = '['
|
comma = ','
|
||||||
tableEnd = ']'
|
tableStart = '['
|
||||||
arrayTableStart = '['
|
tableEnd = ']'
|
||||||
arrayTableEnd = ']'
|
arrayTableStart = '['
|
||||||
tableSep = '.'
|
arrayTableEnd = ']'
|
||||||
keySep = '='
|
tableSep = '.'
|
||||||
arrayStart = '['
|
keySep = '='
|
||||||
arrayEnd = ']'
|
arrayStart = '['
|
||||||
arrayValTerm = ','
|
arrayEnd = ']'
|
||||||
commentStart = '#'
|
commentStart = '#'
|
||||||
stringStart = '"'
|
stringStart = '"'
|
||||||
stringEnd = '"'
|
stringEnd = '"'
|
||||||
rawStringStart = '\''
|
rawStringStart = '\''
|
||||||
rawStringEnd = '\''
|
rawStringEnd = '\''
|
||||||
|
inlineTableStart = '{'
|
||||||
|
inlineTableEnd = '}'
|
||||||
)
|
)
|
||||||
|
|
||||||
type stateFn func(lx *lexer) stateFn
|
type stateFn func(lx *lexer) stateFn
|
||||||
@ -56,11 +60,18 @@ type lexer struct {
|
|||||||
input string
|
input string
|
||||||
start int
|
start int
|
||||||
pos int
|
pos int
|
||||||
width int
|
|
||||||
line int
|
line int
|
||||||
state stateFn
|
state stateFn
|
||||||
items chan item
|
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.
|
// A stack of state functions used to maintain context.
|
||||||
// The idea is to reuse parts of the state machine in various places.
|
// 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
|
// 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 {
|
func lex(input string) *lexer {
|
||||||
lx := &lexer{
|
lx := &lexer{
|
||||||
input: input + "\n",
|
input: input,
|
||||||
state: lexTop,
|
state: lexTop,
|
||||||
line: 1,
|
line: 1,
|
||||||
items: make(chan item, 10),
|
items: make(chan item, 10),
|
||||||
@ -103,7 +114,7 @@ func (lx *lexer) push(state stateFn) {
|
|||||||
|
|
||||||
func (lx *lexer) pop() stateFn {
|
func (lx *lexer) pop() stateFn {
|
||||||
if len(lx.stack) == 0 {
|
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]
|
last := lx.stack[len(lx.stack)-1]
|
||||||
lx.stack = lx.stack[0 : 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) {
|
func (lx *lexer) next() (r rune) {
|
||||||
|
if lx.atEOF {
|
||||||
|
panic("next called after EOF")
|
||||||
|
}
|
||||||
if lx.pos >= len(lx.input) {
|
if lx.pos >= len(lx.input) {
|
||||||
lx.width = 0
|
lx.atEOF = true
|
||||||
return eof
|
return eof
|
||||||
}
|
}
|
||||||
|
|
||||||
if lx.input[lx.pos] == '\n' {
|
if lx.input[lx.pos] == '\n' {
|
||||||
lx.line++
|
lx.line++
|
||||||
}
|
}
|
||||||
r, lx.width = utf8.DecodeRuneInString(lx.input[lx.pos:])
|
lx.prevWidths[2] = lx.prevWidths[1]
|
||||||
lx.pos += lx.width
|
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
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,9 +163,20 @@ func (lx *lexer) ignore() {
|
|||||||
lx.start = lx.pos
|
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() {
|
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' {
|
if lx.pos < len(lx.input) && lx.input[lx.pos] == '\n' {
|
||||||
lx.line--
|
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`.
|
// 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
|
// 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 {
|
func (lx *lexer) errorf(format string, values ...interface{}) stateFn {
|
||||||
lx.items <- item{
|
lx.items <- item{
|
||||||
itemError,
|
itemError,
|
||||||
@ -198,7 +229,6 @@ func lexTop(lx *lexer) stateFn {
|
|||||||
if isWhitespace(r) || isNL(r) {
|
if isWhitespace(r) || isNL(r) {
|
||||||
return lexSkip(lx, lexTop)
|
return lexSkip(lx, lexTop)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch r {
|
switch r {
|
||||||
case commentStart:
|
case commentStart:
|
||||||
lx.push(lexTop)
|
lx.push(lexTop)
|
||||||
@ -207,7 +237,7 @@ func lexTop(lx *lexer) stateFn {
|
|||||||
return lexTableStart
|
return lexTableStart
|
||||||
case eof:
|
case eof:
|
||||||
if lx.pos > lx.start {
|
if lx.pos > lx.start {
|
||||||
return lx.errorf("Unexpected EOF.")
|
return lx.errorf("unexpected EOF")
|
||||||
}
|
}
|
||||||
lx.emit(itemEOF)
|
lx.emit(itemEOF)
|
||||||
return nil
|
return nil
|
||||||
@ -222,12 +252,12 @@ func lexTop(lx *lexer) stateFn {
|
|||||||
|
|
||||||
// lexTopEnd is entered whenever a top-level item has been consumed. (A value
|
// 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
|
// 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 {
|
func lexTopEnd(lx *lexer) stateFn {
|
||||||
r := lx.next()
|
r := lx.next()
|
||||||
switch {
|
switch {
|
||||||
case r == commentStart:
|
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)
|
lx.push(lexTop)
|
||||||
return lexCommentStart
|
return lexCommentStart
|
||||||
case isWhitespace(r):
|
case isWhitespace(r):
|
||||||
@ -236,11 +266,11 @@ func lexTopEnd(lx *lexer) stateFn {
|
|||||||
lx.ignore()
|
lx.ignore()
|
||||||
return lexTop
|
return lexTop
|
||||||
case r == eof:
|
case r == eof:
|
||||||
lx.ignore()
|
lx.emit(itemEOF)
|
||||||
return lexTop
|
return nil
|
||||||
}
|
}
|
||||||
return lx.errorf("Expected a top-level item to end with a new line, "+
|
return lx.errorf("expected a top-level item to end with a newline, "+
|
||||||
"comment or EOF, but got %q instead.", r)
|
"comment, or EOF, but got %q instead", r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// lexTable lexes the beginning of a table. Namely, it makes sure that
|
// 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 {
|
func lexArrayTableEnd(lx *lexer) stateFn {
|
||||||
if r := lx.next(); r != arrayTableEnd {
|
if r := lx.next(); r != arrayTableEnd {
|
||||||
return lx.errorf("Expected end of table array name delimiter %q, "+
|
return lx.errorf("expected end of table array name delimiter %q, "+
|
||||||
"but got %q instead.", arrayTableEnd, r)
|
"but got %q instead", arrayTableEnd, r)
|
||||||
}
|
}
|
||||||
lx.emit(itemArrayTableEnd)
|
lx.emit(itemArrayTableEnd)
|
||||||
return lexTopEnd
|
return lexTopEnd
|
||||||
@ -278,11 +308,11 @@ func lexTableNameStart(lx *lexer) stateFn {
|
|||||||
lx.skip(isWhitespace)
|
lx.skip(isWhitespace)
|
||||||
switch r := lx.peek(); {
|
switch r := lx.peek(); {
|
||||||
case r == tableEnd || r == eof:
|
case r == tableEnd || r == eof:
|
||||||
return lx.errorf("Unexpected end of table name. (Table names cannot " +
|
return lx.errorf("unexpected end of table name " +
|
||||||
"be empty.)")
|
"(table names cannot be empty)")
|
||||||
case r == tableSep:
|
case r == tableSep:
|
||||||
return lx.errorf("Unexpected table separator. (Table names cannot " +
|
return lx.errorf("unexpected table separator " +
|
||||||
"be empty.)")
|
"(table names cannot be empty)")
|
||||||
case r == stringStart || r == rawStringStart:
|
case r == stringStart || r == rawStringStart:
|
||||||
lx.ignore()
|
lx.ignore()
|
||||||
lx.push(lexTableNameEnd)
|
lx.push(lexTableNameEnd)
|
||||||
@ -317,8 +347,8 @@ func lexTableNameEnd(lx *lexer) stateFn {
|
|||||||
case r == tableEnd:
|
case r == tableEnd:
|
||||||
return lx.pop()
|
return lx.pop()
|
||||||
default:
|
default:
|
||||||
return lx.errorf("Expected '.' or ']' to end table name, but got %q "+
|
return lx.errorf("expected '.' or ']' to end table name, "+
|
||||||
"instead.", r)
|
"but got %q instead", r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,7 +358,7 @@ func lexKeyStart(lx *lexer) stateFn {
|
|||||||
r := lx.peek()
|
r := lx.peek()
|
||||||
switch {
|
switch {
|
||||||
case r == keySep:
|
case r == keySep:
|
||||||
return lx.errorf("Unexpected key separator %q.", keySep)
|
return lx.errorf("unexpected key separator %q", keySep)
|
||||||
case isWhitespace(r) || isNL(r):
|
case isWhitespace(r) || isNL(r):
|
||||||
lx.next()
|
lx.next()
|
||||||
return lexSkip(lx, lexKeyStart)
|
return lexSkip(lx, lexKeyStart)
|
||||||
@ -359,7 +389,7 @@ func lexBareKey(lx *lexer) stateFn {
|
|||||||
lx.emit(itemText)
|
lx.emit(itemText)
|
||||||
return lexKeyEnd
|
return lexKeyEnd
|
||||||
default:
|
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):
|
case isWhitespace(r):
|
||||||
return lexSkip(lx, lexKeyEnd)
|
return lexSkip(lx, lexKeyEnd)
|
||||||
default:
|
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)
|
keySep, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -381,9 +411,8 @@ func lexKeyEnd(lx *lexer) stateFn {
|
|||||||
// lexValue will ignore whitespace.
|
// lexValue will ignore whitespace.
|
||||||
// After a value is lexed, the last state on the next is popped and returned.
|
// After a value is lexed, the last state on the next is popped and returned.
|
||||||
func lexValue(lx *lexer) stateFn {
|
func lexValue(lx *lexer) stateFn {
|
||||||
// We allow whitespace to precede a value, but NOT new lines.
|
// We allow whitespace to precede a value, but NOT newlines.
|
||||||
// In array syntax, the array states are responsible for ignoring new
|
// In array syntax, the array states are responsible for ignoring newlines.
|
||||||
// lines.
|
|
||||||
r := lx.next()
|
r := lx.next()
|
||||||
switch {
|
switch {
|
||||||
case isWhitespace(r):
|
case isWhitespace(r):
|
||||||
@ -397,6 +426,10 @@ func lexValue(lx *lexer) stateFn {
|
|||||||
lx.ignore()
|
lx.ignore()
|
||||||
lx.emit(itemArray)
|
lx.emit(itemArray)
|
||||||
return lexArrayValue
|
return lexArrayValue
|
||||||
|
case inlineTableStart:
|
||||||
|
lx.ignore()
|
||||||
|
lx.emit(itemInlineTableStart)
|
||||||
|
return lexInlineTableValue
|
||||||
case stringStart:
|
case stringStart:
|
||||||
if lx.accept(stringStart) {
|
if lx.accept(stringStart) {
|
||||||
if lx.accept(stringStart) {
|
if lx.accept(stringStart) {
|
||||||
@ -420,7 +453,7 @@ func lexValue(lx *lexer) stateFn {
|
|||||||
case '+', '-':
|
case '+', '-':
|
||||||
return lexNumberStart
|
return lexNumberStart
|
||||||
case '.': // special error case, be kind to users
|
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) {
|
if unicode.IsLetter(r) {
|
||||||
// Be permissive here; lexBool will give a nice error if the
|
// Be permissive here; lexBool will give a nice error if the
|
||||||
@ -430,11 +463,11 @@ func lexValue(lx *lexer) stateFn {
|
|||||||
lx.backup()
|
lx.backup()
|
||||||
return lexBool
|
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 ','
|
// 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 {
|
func lexArrayValue(lx *lexer) stateFn {
|
||||||
r := lx.next()
|
r := lx.next()
|
||||||
switch {
|
switch {
|
||||||
@ -443,10 +476,11 @@ func lexArrayValue(lx *lexer) stateFn {
|
|||||||
case r == commentStart:
|
case r == commentStart:
|
||||||
lx.push(lexArrayValue)
|
lx.push(lexArrayValue)
|
||||||
return lexCommentStart
|
return lexCommentStart
|
||||||
case r == arrayValTerm:
|
case r == comma:
|
||||||
return lx.errorf("Unexpected array value terminator %q.",
|
return lx.errorf("unexpected comma")
|
||||||
arrayValTerm)
|
|
||||||
case r == arrayEnd:
|
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
|
return lexArrayEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,8 +489,9 @@ func lexArrayValue(lx *lexer) stateFn {
|
|||||||
return lexValue
|
return lexValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// lexArrayValueEnd consumes the cruft between values of an array. Namely,
|
// lexArrayValueEnd consumes everything between the end of an array value and
|
||||||
// it ignores whitespace and expects either a ',' or a ']'.
|
// 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 {
|
func lexArrayValueEnd(lx *lexer) stateFn {
|
||||||
r := lx.next()
|
r := lx.next()
|
||||||
switch {
|
switch {
|
||||||
@ -465,31 +500,88 @@ func lexArrayValueEnd(lx *lexer) stateFn {
|
|||||||
case r == commentStart:
|
case r == commentStart:
|
||||||
lx.push(lexArrayValueEnd)
|
lx.push(lexArrayValueEnd)
|
||||||
return lexCommentStart
|
return lexCommentStart
|
||||||
case r == arrayValTerm:
|
case r == comma:
|
||||||
lx.ignore()
|
lx.ignore()
|
||||||
return lexArrayValue // move on to the next value
|
return lexArrayValue // move on to the next value
|
||||||
case r == arrayEnd:
|
case r == arrayEnd:
|
||||||
return lexArrayEnd
|
return lexArrayEnd
|
||||||
}
|
}
|
||||||
return lx.errorf("Expected an array value terminator %q or an array "+
|
return lx.errorf(
|
||||||
"terminator %q, but got %q instead.", arrayValTerm, arrayEnd, r)
|
"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
|
// lexArrayEnd finishes the lexing of an array.
|
||||||
// just been consumed.
|
// It assumes that a ']' has just been consumed.
|
||||||
func lexArrayEnd(lx *lexer) stateFn {
|
func lexArrayEnd(lx *lexer) stateFn {
|
||||||
lx.ignore()
|
lx.ignore()
|
||||||
lx.emit(itemArrayEnd)
|
lx.emit(itemArrayEnd)
|
||||||
return lx.pop()
|
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
|
// lexString consumes the inner contents of a string. It assumes that the
|
||||||
// beginning '"' has already been consumed and ignored.
|
// beginning '"' has already been consumed and ignored.
|
||||||
func lexString(lx *lexer) stateFn {
|
func lexString(lx *lexer) stateFn {
|
||||||
r := lx.next()
|
r := lx.next()
|
||||||
switch {
|
switch {
|
||||||
|
case r == eof:
|
||||||
|
return lx.errorf("unexpected EOF")
|
||||||
case isNL(r):
|
case isNL(r):
|
||||||
return lx.errorf("Strings cannot contain new lines.")
|
return lx.errorf("strings cannot contain newlines")
|
||||||
case r == '\\':
|
case r == '\\':
|
||||||
lx.push(lexString)
|
lx.push(lexString)
|
||||||
return lexStringEscape
|
return lexStringEscape
|
||||||
@ -506,11 +598,12 @@ func lexString(lx *lexer) stateFn {
|
|||||||
// lexMultilineString consumes the inner contents of a string. It assumes that
|
// lexMultilineString consumes the inner contents of a string. It assumes that
|
||||||
// the beginning '"""' has already been consumed and ignored.
|
// the beginning '"""' has already been consumed and ignored.
|
||||||
func lexMultilineString(lx *lexer) stateFn {
|
func lexMultilineString(lx *lexer) stateFn {
|
||||||
r := lx.next()
|
switch lx.next() {
|
||||||
switch {
|
case eof:
|
||||||
case r == '\\':
|
return lx.errorf("unexpected EOF")
|
||||||
|
case '\\':
|
||||||
return lexMultilineStringEscape
|
return lexMultilineStringEscape
|
||||||
case r == stringEnd:
|
case stringEnd:
|
||||||
if lx.accept(stringEnd) {
|
if lx.accept(stringEnd) {
|
||||||
if lx.accept(stringEnd) {
|
if lx.accept(stringEnd) {
|
||||||
lx.backup()
|
lx.backup()
|
||||||
@ -534,8 +627,10 @@ func lexMultilineString(lx *lexer) stateFn {
|
|||||||
func lexRawString(lx *lexer) stateFn {
|
func lexRawString(lx *lexer) stateFn {
|
||||||
r := lx.next()
|
r := lx.next()
|
||||||
switch {
|
switch {
|
||||||
|
case r == eof:
|
||||||
|
return lx.errorf("unexpected EOF")
|
||||||
case isNL(r):
|
case isNL(r):
|
||||||
return lx.errorf("Strings cannot contain new lines.")
|
return lx.errorf("strings cannot contain newlines")
|
||||||
case r == rawStringEnd:
|
case r == rawStringEnd:
|
||||||
lx.backup()
|
lx.backup()
|
||||||
lx.emit(itemRawString)
|
lx.emit(itemRawString)
|
||||||
@ -547,12 +642,13 @@ func lexRawString(lx *lexer) stateFn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lexMultilineRawString consumes a raw string. Nothing can be escaped in such
|
// 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.
|
// ignored.
|
||||||
func lexMultilineRawString(lx *lexer) stateFn {
|
func lexMultilineRawString(lx *lexer) stateFn {
|
||||||
r := lx.next()
|
switch lx.next() {
|
||||||
switch {
|
case eof:
|
||||||
case r == rawStringEnd:
|
return lx.errorf("unexpected EOF")
|
||||||
|
case rawStringEnd:
|
||||||
if lx.accept(rawStringEnd) {
|
if lx.accept(rawStringEnd) {
|
||||||
if lx.accept(rawStringEnd) {
|
if lx.accept(rawStringEnd) {
|
||||||
lx.backup()
|
lx.backup()
|
||||||
@ -605,10 +701,9 @@ func lexStringEscape(lx *lexer) stateFn {
|
|||||||
case 'U':
|
case 'U':
|
||||||
return lexLongUnicodeEscape
|
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: "+
|
"escape characters are allowed: "+
|
||||||
"\\b, \\t, \\n, \\f, \\r, \\\", \\/, \\\\, "+
|
`\b, \t, \n, \f, \r, \", \\, \uXXXX, and \UXXXXXXXX`, r)
|
||||||
"\\uXXXX and \\UXXXXXXXX.", r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lexShortUnicodeEscape(lx *lexer) stateFn {
|
func lexShortUnicodeEscape(lx *lexer) stateFn {
|
||||||
@ -616,8 +711,8 @@ func lexShortUnicodeEscape(lx *lexer) stateFn {
|
|||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
r = lx.next()
|
r = lx.next()
|
||||||
if !isHexadecimal(r) {
|
if !isHexadecimal(r) {
|
||||||
return lx.errorf("Expected four hexadecimal digits after '\\u', "+
|
return lx.errorf(`expected four hexadecimal digits after '\u', `+
|
||||||
"but got '%s' instead.", lx.current())
|
"but got %q instead", lx.current())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lx.pop()
|
return lx.pop()
|
||||||
@ -628,8 +723,8 @@ func lexLongUnicodeEscape(lx *lexer) stateFn {
|
|||||||
for i := 0; i < 8; i++ {
|
for i := 0; i < 8; i++ {
|
||||||
r = lx.next()
|
r = lx.next()
|
||||||
if !isHexadecimal(r) {
|
if !isHexadecimal(r) {
|
||||||
return lx.errorf("Expected eight hexadecimal digits after '\\U', "+
|
return lx.errorf(`expected eight hexadecimal digits after '\U', `+
|
||||||
"but got '%s' instead.", lx.current())
|
"but got %q instead", lx.current())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lx.pop()
|
return lx.pop()
|
||||||
@ -647,9 +742,9 @@ func lexNumberOrDateStart(lx *lexer) stateFn {
|
|||||||
case 'e', 'E':
|
case 'e', 'E':
|
||||||
return lexFloat
|
return lexFloat
|
||||||
case '.':
|
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.
|
// lexNumberOrDate consumes either an integer, float or datetime.
|
||||||
@ -697,9 +792,9 @@ func lexNumberStart(lx *lexer) stateFn {
|
|||||||
r := lx.next()
|
r := lx.next()
|
||||||
if !isDigit(r) {
|
if !isDigit(r) {
|
||||||
if 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
|
return lexNumber
|
||||||
}
|
}
|
||||||
@ -757,7 +852,7 @@ func lexBool(lx *lexer) stateFn {
|
|||||||
lx.emit(itemBool)
|
lx.emit(itemBool)
|
||||||
return lx.pop()
|
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
|
// 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.
|
// 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.
|
// back to the last state on the stack.
|
||||||
func lexComment(lx *lexer) stateFn {
|
func lexComment(lx *lexer) stateFn {
|
||||||
r := lx.peek()
|
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)
|
types = append(types, typ)
|
||||||
}
|
}
|
||||||
return array, p.typeOfArray(types)
|
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)
|
p.bug("Unexpected value type: %s", it.typ)
|
||||||
panic("unreachable")
|
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 (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
"time"
|
"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.
|
// Defines the key when adding errors using WithError.
|
||||||
var ErrorKey = "error"
|
var ErrorKey = "error"
|
||||||
|
|
||||||
@ -29,6 +39,9 @@ type Entry struct {
|
|||||||
|
|
||||||
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
||||||
Message string
|
Message string
|
||||||
|
|
||||||
|
// When formatter is called in entry.log(), an Buffer may be set to entry
|
||||||
|
Buffer *bytes.Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEntry(logger *Logger) *Entry {
|
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
|
// Returns the string representation from the reader and ultimately the
|
||||||
// formatter.
|
// formatter.
|
||||||
func (entry *Entry) String() (string, error) {
|
func (entry *Entry) String() (string, error) {
|
||||||
reader, err := entry.Reader()
|
serialized, err := entry.Logger.Formatter.Format(entry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
str := string(serialized)
|
||||||
return reader.String(), err
|
return str, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add an error as single field (using the key defined in ErrorKey) to the Entry.
|
// 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
|
// This function is not declared with a pointer value because otherwise
|
||||||
// race conditions will occur when using multiple goroutines
|
// race conditions will occur when using multiple goroutines
|
||||||
func (entry Entry) log(level Level, msg string) {
|
func (entry Entry) log(level Level, msg string) {
|
||||||
|
var buffer *bytes.Buffer
|
||||||
entry.Time = time.Now()
|
entry.Time = time.Now()
|
||||||
entry.Level = level
|
entry.Level = level
|
||||||
entry.Message = msg
|
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)
|
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
|
||||||
entry.Logger.mu.Unlock()
|
entry.Logger.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
buffer = bufferPool.Get().(*bytes.Buffer)
|
||||||
reader, err := entry.Reader()
|
buffer.Reset()
|
||||||
|
defer bufferPool.Put(buffer)
|
||||||
|
entry.Buffer = buffer
|
||||||
|
serialized, err := entry.Logger.Formatter.Format(&entry)
|
||||||
|
entry.Buffer = nil
|
||||||
if err != nil {
|
if err != nil {
|
||||||
entry.Logger.mu.Lock()
|
entry.Logger.mu.Lock()
|
||||||
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
||||||
entry.Logger.mu.Unlock()
|
entry.Logger.mu.Unlock()
|
||||||
}
|
} else {
|
||||||
|
entry.Logger.mu.Lock()
|
||||||
entry.Logger.mu.Lock()
|
_, err = entry.Logger.Out.Write(serialized)
|
||||||
defer entry.Logger.mu.Unlock()
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
||||||
_, err = io.Copy(entry.Logger.Out, reader)
|
}
|
||||||
if err != nil {
|
entry.Logger.mu.Unlock()
|
||||||
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// To avoid Entry#log() returning a value that only would make sense for
|
// 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 {
|
if entry.Logger.Level >= FatalLevel {
|
||||||
entry.log(FatalLevel, fmt.Sprint(args...))
|
entry.log(FatalLevel, fmt.Sprint(args...))
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Panic(args ...interface{}) {
|
func (entry *Entry) Panic(args ...interface{}) {
|
||||||
@ -198,7 +209,7 @@ func (entry *Entry) Fatalf(format string, args ...interface{}) {
|
|||||||
if entry.Logger.Level >= FatalLevel {
|
if entry.Logger.Level >= FatalLevel {
|
||||||
entry.Fatal(fmt.Sprintf(format, args...))
|
entry.Fatal(fmt.Sprintf(format, args...))
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Panicf(format string, args ...interface{}) {
|
func (entry *Entry) Panicf(format string, args ...interface{}) {
|
||||||
@ -245,7 +256,7 @@ func (entry *Entry) Fatalln(args ...interface{}) {
|
|||||||
if entry.Logger.Level >= FatalLevel {
|
if entry.Logger.Level >= FatalLevel {
|
||||||
entry.Fatal(entry.sprintlnn(args...))
|
entry.Fatal(entry.sprintlnn(args...))
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *Entry) Panicln(args ...interface{}) {
|
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 (
|
import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
// "os"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = logrus.New()
|
var log = logrus.New()
|
||||||
@ -9,6 +10,14 @@ var log = logrus.New()
|
|||||||
func init() {
|
func init() {
|
||||||
log.Formatter = new(logrus.JSONFormatter)
|
log.Formatter = new(logrus.JSONFormatter)
|
||||||
log.Formatter = new(logrus.TextFormatter) // default
|
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
|
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
|
// 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.
|
// avoid code duplication between the two default formatters.
|
||||||
func prefixFieldClashes(data Fields) {
|
func prefixFieldClashes(data Fields) {
|
||||||
_, ok := data["time"]
|
if t, ok := data["time"]; ok {
|
||||||
if ok {
|
data["fields.time"] = t
|
||||||
data["fields.time"] = data["time"]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, ok = data["msg"]
|
if m, ok := data["msg"]; ok {
|
||||||
if ok {
|
data["fields.msg"] = m
|
||||||
data["fields.msg"] = data["msg"]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, ok = data["level"]
|
if l, ok := data["level"]; ok {
|
||||||
if ok {
|
data["fields.level"] = l
|
||||||
data["fields.level"] = data["level"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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"
|
"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 {
|
type JSONFormatter struct {
|
||||||
// TimestampFormat sets the format used for marshaling timestamps.
|
// TimestampFormat sets the format used for marshaling timestamps.
|
||||||
TimestampFormat string
|
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) {
|
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
@ -29,9 +60,11 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
|||||||
timestampFormat = DefaultTimestampFormat
|
timestampFormat = DefaultTimestampFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
data["time"] = entry.Time.Format(timestampFormat)
|
if !f.DisableTimestamp {
|
||||||
data["msg"] = entry.Message
|
data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
|
||||||
data["level"] = entry.Level.String()
|
}
|
||||||
|
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
|
||||||
|
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
|
||||||
|
|
||||||
serialized, err := json.Marshal(data)
|
serialized, err := json.Marshal(data)
|
||||||
if err != nil {
|
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
|
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
||||||
// logged. `logrus.Debug` is useful in
|
// logged. `logrus.Debug` is useful in
|
||||||
Level Level
|
Level Level
|
||||||
// Used to sync writing to the log.
|
// Used to sync writing to the log. Locking is enabled by Default
|
||||||
mu sync.Mutex
|
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`,
|
// 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.
|
// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry.
|
||||||
// If you want multiple fields, use `WithFields`.
|
// If you want multiple fields, use `WithFields`.
|
||||||
func (logger *Logger) WithField(key string, value interface{}) *Entry {
|
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
|
// Adds a struct of fields to the log entry. All it does is call `WithField` for
|
||||||
// each `Field`.
|
// each `Field`.
|
||||||
func (logger *Logger) WithFields(fields Fields) *Entry {
|
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
|
// Add an error as single field to the log entry. All it does is call
|
||||||
// `WithError` for the given `error`.
|
// `WithError` for the given `error`.
|
||||||
func (logger *Logger) WithError(err error) *Entry {
|
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{}) {
|
func (logger *Logger) Debugf(format string, args ...interface{}) {
|
||||||
if logger.Level >= DebugLevel {
|
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{}) {
|
func (logger *Logger) Infof(format string, args ...interface{}) {
|
||||||
if logger.Level >= InfoLevel {
|
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{}) {
|
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{}) {
|
func (logger *Logger) Warnf(format string, args ...interface{}) {
|
||||||
if logger.Level >= WarnLevel {
|
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{}) {
|
func (logger *Logger) Warningf(format string, args ...interface{}) {
|
||||||
if logger.Level >= WarnLevel {
|
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{}) {
|
func (logger *Logger) Errorf(format string, args ...interface{}) {
|
||||||
if logger.Level >= ErrorLevel {
|
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{}) {
|
func (logger *Logger) Fatalf(format string, args ...interface{}) {
|
||||||
if logger.Level >= FatalLevel {
|
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{}) {
|
func (logger *Logger) Panicf(format string, args ...interface{}) {
|
||||||
if logger.Level >= PanicLevel {
|
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{}) {
|
func (logger *Logger) Debug(args ...interface{}) {
|
||||||
if logger.Level >= DebugLevel {
|
if logger.Level >= DebugLevel {
|
||||||
NewEntry(logger).Debug(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Debug(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Info(args ...interface{}) {
|
func (logger *Logger) Info(args ...interface{}) {
|
||||||
if logger.Level >= InfoLevel {
|
if logger.Level >= InfoLevel {
|
||||||
NewEntry(logger).Info(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Info(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Print(args ...interface{}) {
|
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{}) {
|
func (logger *Logger) Warn(args ...interface{}) {
|
||||||
if logger.Level >= WarnLevel {
|
if logger.Level >= WarnLevel {
|
||||||
NewEntry(logger).Warn(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Warn(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Warning(args ...interface{}) {
|
func (logger *Logger) Warning(args ...interface{}) {
|
||||||
if logger.Level >= WarnLevel {
|
if logger.Level >= WarnLevel {
|
||||||
NewEntry(logger).Warn(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Warn(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Error(args ...interface{}) {
|
func (logger *Logger) Error(args ...interface{}) {
|
||||||
if logger.Level >= ErrorLevel {
|
if logger.Level >= ErrorLevel {
|
||||||
NewEntry(logger).Error(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Error(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Fatal(args ...interface{}) {
|
func (logger *Logger) Fatal(args ...interface{}) {
|
||||||
if logger.Level >= FatalLevel {
|
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{}) {
|
func (logger *Logger) Panic(args ...interface{}) {
|
||||||
if logger.Level >= PanicLevel {
|
if logger.Level >= PanicLevel {
|
||||||
NewEntry(logger).Panic(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Panic(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Debugln(args ...interface{}) {
|
func (logger *Logger) Debugln(args ...interface{}) {
|
||||||
if logger.Level >= DebugLevel {
|
if logger.Level >= DebugLevel {
|
||||||
NewEntry(logger).Debugln(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Debugln(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Infoln(args ...interface{}) {
|
func (logger *Logger) Infoln(args ...interface{}) {
|
||||||
if logger.Level >= InfoLevel {
|
if logger.Level >= InfoLevel {
|
||||||
NewEntry(logger).Infoln(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Infoln(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Println(args ...interface{}) {
|
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{}) {
|
func (logger *Logger) Warnln(args ...interface{}) {
|
||||||
if logger.Level >= WarnLevel {
|
if logger.Level >= WarnLevel {
|
||||||
NewEntry(logger).Warnln(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Warnln(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Warningln(args ...interface{}) {
|
func (logger *Logger) Warningln(args ...interface{}) {
|
||||||
if logger.Level >= WarnLevel {
|
if logger.Level >= WarnLevel {
|
||||||
NewEntry(logger).Warnln(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Warnln(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Errorln(args ...interface{}) {
|
func (logger *Logger) Errorln(args ...interface{}) {
|
||||||
if logger.Level >= ErrorLevel {
|
if logger.Level >= ErrorLevel {
|
||||||
NewEntry(logger).Errorln(args...)
|
entry := logger.newEntry()
|
||||||
|
entry.Errorln(args...)
|
||||||
|
logger.releaseEntry(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) Fatalln(args ...interface{}) {
|
func (logger *Logger) Fatalln(args ...interface{}) {
|
||||||
if logger.Level >= FatalLevel {
|
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{}) {
|
func (logger *Logger) Panicln(args ...interface{}) {
|
||||||
if logger.Level >= PanicLevel {
|
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 darwin freebsd openbsd netbsd dragonfly
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
package logrus
|
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
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import "syscall"
|
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.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build linux darwin freebsd openbsd netbsd dragonfly
|
// +build linux darwin freebsd openbsd netbsd dragonfly
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
||||||
func IsTerminal() bool {
|
func IsTerminal(f io.Writer) bool {
|
||||||
fd := syscall.Stderr
|
|
||||||
var termios Termios
|
var termios Termios
|
||||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
|
switch v := f.(type) {
|
||||||
return err == 0
|
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
|
package logrus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||||
func IsTerminal() bool {
|
func IsTerminal(f io.Writer) bool {
|
||||||
_, err := unix.IoctlGetTermios(int(os.Stdout.Fd()), unix.TCGETA)
|
switch v := f.(type) {
|
||||||
return err == nil
|
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
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build windows
|
// +build windows,!appengine
|
||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@ -19,9 +21,13 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
||||||
func IsTerminal() bool {
|
func IsTerminal(f io.Writer) bool {
|
||||||
fd := syscall.Stderr
|
switch v := f.(type) {
|
||||||
var st uint32
|
case *os.File:
|
||||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
|
var st uint32
|
||||||
return r != 0 && e == 0
|
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 (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,16 +20,10 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
baseTimestamp time.Time
|
baseTimestamp time.Time
|
||||||
isTerminal bool
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
baseTimestamp = time.Now()
|
baseTimestamp = time.Now()
|
||||||
isTerminal = IsTerminal()
|
|
||||||
}
|
|
||||||
|
|
||||||
func miniTS() int {
|
|
||||||
return int(time.Since(baseTimestamp) / time.Second)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type TextFormatter struct {
|
type TextFormatter struct {
|
||||||
@ -54,10 +48,32 @@ type TextFormatter struct {
|
|||||||
// that log extremely frequently and don't use the JSON formatter this may not
|
// that log extremely frequently and don't use the JSON formatter this may not
|
||||||
// be desired.
|
// be desired.
|
||||||
DisableSorting bool
|
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) {
|
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 {
|
for k := range entry.Data {
|
||||||
keys = append(keys, k)
|
keys = append(keys, k)
|
||||||
}
|
}
|
||||||
@ -65,13 +81,17 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
|||||||
if !f.DisableSorting {
|
if !f.DisableSorting {
|
||||||
sort.Strings(keys)
|
sort.Strings(keys)
|
||||||
}
|
}
|
||||||
|
if entry.Buffer != nil {
|
||||||
b := &bytes.Buffer{}
|
b = entry.Buffer
|
||||||
|
} else {
|
||||||
|
b = &bytes.Buffer{}
|
||||||
|
}
|
||||||
|
|
||||||
prefixFieldClashes(entry.Data)
|
prefixFieldClashes(entry.Data)
|
||||||
|
|
||||||
isColorTerminal := isTerminal && (runtime.GOOS != "windows")
|
f.Do(func() { f.init(entry) })
|
||||||
isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors
|
|
||||||
|
isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors
|
||||||
|
|
||||||
timestampFormat := f.TimestampFormat
|
timestampFormat := f.TimestampFormat
|
||||||
if 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]
|
levelText := strings.ToUpper(entry.Level.String())[0:4]
|
||||||
|
|
||||||
if !f.FullTimestamp {
|
if f.DisableTimestamp {
|
||||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message)
|
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 {
|
} else {
|
||||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
|
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
|
||||||
}
|
}
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
v := entry.Data[k]
|
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 {
|
for _, ch := range text {
|
||||||
if !((ch >= 'a' && ch <= 'z') ||
|
if !((ch >= 'a' && ch <= 'z') ||
|
||||||
(ch >= 'A' && ch <= 'Z') ||
|
(ch >= 'A' && ch <= 'Z') ||
|
||||||
(ch >= '0' && ch <= '9') ||
|
(ch >= '0' && ch <= '9') ||
|
||||||
ch == '-' || ch == '.') {
|
ch == '-' || ch == '.') {
|
||||||
return false
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
||||||
|
|
||||||
b.WriteString(key)
|
b.WriteString(key)
|
||||||
b.WriteByte('=')
|
b.WriteByte('=')
|
||||||
|
f.appendValue(b, value)
|
||||||
|
b.WriteByte(' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
||||||
switch value := value.(type) {
|
switch value := value.(type) {
|
||||||
case string:
|
case string:
|
||||||
if needsQuoting(value) {
|
if !f.needsQuoting(value) {
|
||||||
b.WriteString(value)
|
b.WriteString(value)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(b, "%q", value)
|
fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, value, f.QuoteCharacter)
|
||||||
}
|
}
|
||||||
case error:
|
case error:
|
||||||
errmsg := value.Error()
|
errmsg := value.Error()
|
||||||
if needsQuoting(errmsg) {
|
if !f.needsQuoting(errmsg) {
|
||||||
b.WriteString(errmsg)
|
b.WriteString(errmsg)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(b, "%q", value)
|
fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, errmsg, f.QuoteCharacter)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
fmt.Fprint(b, value)
|
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 {
|
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()
|
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)
|
runtime.SetFinalizer(writer, writerFinalizer)
|
||||||
|
|
||||||
return writer
|
return writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) writerScanner(reader *io.PipeReader) {
|
func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) {
|
||||||
scanner := bufio.NewScanner(reader)
|
scanner := bufio.NewScanner(reader)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
logger.Print(scanner.Text())
|
printFunc(scanner.Text())
|
||||||
}
|
}
|
||||||
if err := scanner.Err(); err != nil {
|
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()
|
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.
|
// BotAPI allows you to interact with the Telegram Bot API.
|
||||||
type BotAPI struct {
|
type BotAPI struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
Debug bool `json:"debug"`
|
Debug bool `json:"debug"`
|
||||||
|
Buffer int `json:"buffer"`
|
||||||
|
|
||||||
Self User `json:"-"`
|
Self User `json:"-"`
|
||||||
Client *http.Client `json:"-"`
|
Client *http.Client `json:"-"`
|
||||||
}
|
}
|
||||||
@ -42,11 +44,12 @@ func NewBotAPIWithClient(token string, client *http.Client) (*BotAPI, error) {
|
|||||||
bot := &BotAPI{
|
bot := &BotAPI{
|
||||||
Token: token,
|
Token: token,
|
||||||
Client: client,
|
Client: client,
|
||||||
|
Buffer: 100,
|
||||||
}
|
}
|
||||||
|
|
||||||
self, err := bot.GetMe()
|
self, err := bot.GetMe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &BotAPI{}, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
bot.Self = self
|
bot.Self = self
|
||||||
@ -68,6 +71,10 @@ func (bot *BotAPI) MakeRequest(endpoint string, params url.Values) (APIResponse,
|
|||||||
return APIResponse{}, errors.New(ErrAPIForbidden)
|
return APIResponse{}, errors.New(ErrAPIForbidden)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return APIResponse{}, errors.New(http.StatusText(resp.StatusCode))
|
||||||
|
}
|
||||||
|
|
||||||
bytes, err := ioutil.ReadAll(resp.Body)
|
bytes, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return APIResponse{}, err
|
return APIResponse{}, err
|
||||||
@ -457,7 +464,7 @@ func (bot *BotAPI) GetWebhookInfo() (WebhookInfo, error) {
|
|||||||
|
|
||||||
// GetUpdatesChan starts and returns a channel for getting updates.
|
// GetUpdatesChan starts and returns a channel for getting updates.
|
||||||
func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (UpdatesChannel, error) {
|
func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (UpdatesChannel, error) {
|
||||||
ch := make(chan Update, 100)
|
ch := make(chan Update, bot.Buffer)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
@ -484,7 +491,7 @@ func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (UpdatesChannel, error) {
|
|||||||
|
|
||||||
// ListenForWebhook registers a http handler for a webhook.
|
// ListenForWebhook registers a http handler for a webhook.
|
||||||
func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel {
|
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) {
|
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
||||||
bytes, _ := ioutil.ReadAll(r.Body)
|
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.
|
// WebhookConfig contains information about a SetWebhook request.
|
||||||
type WebhookConfig struct {
|
type WebhookConfig struct {
|
||||||
URL *url.URL
|
URL *url.URL
|
||||||
Certificate interface{}
|
Certificate interface{}
|
||||||
MaxConnections int
|
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.
|
// NewInlineQueryResultArticle creates a new inline query article.
|
||||||
func NewInlineQueryResultArticle(id, title, messageText string) InlineQueryResultArticle {
|
func NewInlineQueryResultArticle(id, title, messageText string) InlineQueryResultArticle {
|
||||||
return 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 ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.SplitN(m.Text, " ", 2)[1]
|
return split[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessageEntity contains information about data in a Message.
|
// 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