Compare commits
	
		
			45 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 7a16146304 | ||
|   | 3d3809a21b | ||
|   | 29465397dd | ||
|   | d300bb1735 | ||
|   | 2e703472f1 | ||
|   | 8fede90b9e | ||
|   | d128f157c4 | ||
|   | 4fcedabfd0 | ||
|   | 246c8e4f74 | ||
|   | 4d2207aba7 | ||
|   | 17b8b86d68 | ||
|   | fdb57230a3 | ||
|   | 7469732bbc | ||
|   | d1dd6c3440 | ||
|   | 02612c0061 | ||
|   | a4db63a773 | ||
|   | 035c2b906a | ||
|   | 6ea8be5749 | ||
|   | 36024d5439 | ||
|   | 8d52c98373 | ||
|   | b4a4eb0057 | ||
|   | b469c8ddbd | ||
|   | eee0036c7f | ||
|   | 89c66b9430 | ||
|   | bd38319d83 | ||
|   | 33dffd5ea8 | ||
|   | 57176dadd4 | ||
|   | dd449a8705 | ||
|   | 587ad9f41d | ||
|   | a16ad8bf3b | ||
|   | 1e0490bd36 | ||
|   | 8afc641f0c | ||
|   | 2e4d58cb92 | ||
|   | 02d7e2db65 | ||
|   | f935c573e9 | ||
|   | 4a25e66c00 | ||
|   | 95f4e3448e | ||
|   | eacb1c1771 | ||
|   | 07fd825349 | ||
|   | be15cc8a36 | ||
|   | 2f68519b3c | ||
|   | efe641f202 | ||
|   | 9bd663046a | ||
|   | 11b07f01ba | ||
|   | 6c2f370e6b | 
							
								
								
									
										17
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,5 +1,6 @@ | ||||
| # matterbridge | ||||
| [](https://gitter.im/42wim/matterbridge) [](https://webchat.freenode.net/?channels=matterbridgechat)    | ||||
| [](https://gitter.im/42wim/matterbridge) [](https://webchat.freenode.net/?channels=matterbridgechat) [](https://discord.gg/AkKPtrQ) [](https://riot.im/app/#/room/#matterbridge:matrix.org) | ||||
|  | ||||
|  | ||||
|  | ||||
| Simple bridge between Mattermost, IRC, XMPP, Gitter, Slack, Discord, Telegram, Rocket.Chat, Hipchat(via xmpp) and Matrix with REST API. | ||||
| @@ -27,7 +28,7 @@ Simple bridge between Mattermost, IRC, XMPP, Gitter, Slack, Discord, Telegram, R | ||||
|  | ||||
| # Requirements | ||||
| Accounts to one of the supported bridges | ||||
| * [Mattermost](https://github.com/mattermost/platform/) 3.5.x - 3.7.x | ||||
| * [Mattermost](https://github.com/mattermost/platform/) 3.5.x - 3.9.x | ||||
| * [IRC](http://www.mirc.com/servers.html) | ||||
| * [XMPP](https://jabber.org) | ||||
| * [Gitter](https://gitter.im) | ||||
| @@ -41,7 +42,7 @@ Accounts to one of the supported bridges | ||||
| # Installing | ||||
| ## Binaries | ||||
| Binaries can be found [here] (https://github.com/42wim/matterbridge/releases/) | ||||
| * Latest release [v0.10.1](https://github.com/42wim/matterbridge/releases/latest) | ||||
| * Latest stable release [v0.12.0](https://github.com/42wim/matterbridge/releases/latest) | ||||
|  | ||||
| ## Building | ||||
| Go 1.6+ is required. Make sure you have [Go](https://golang.org/doc/install) properly installed, including setting up your [GOPATH] (https://golang.org/doc/code.html#GOPATH) | ||||
| @@ -93,10 +94,13 @@ enable=true | ||||
|  | ||||
| ### Bridge slack (#general) - discord (general) | ||||
| ``` | ||||
| [slack] | ||||
| [slack.test] | ||||
| useAPI=true | ||||
| Token="yourslacktoken" | ||||
| PrefixMessagesWithNick=true | ||||
|  | ||||
| [discord] | ||||
| [discord.test] | ||||
| Token="yourdiscordtoken" | ||||
| Server="yourdiscordservername" | ||||
| @@ -118,16 +122,20 @@ RemoteNickFormat="[{PROTOCOL}/{BRIDGE}] <{NICK}> " | ||||
| ``` | ||||
|  | ||||
| # Running | ||||
| 1) Copy the matterbridge.toml.sample to matterbridge.toml in the same directory as the matterbridge binary.   | ||||
| 1) Copy the matterbridge.toml.sample to matterbridge.toml  | ||||
| 2) Edit matterbridge.toml with the settings for your environment.  | ||||
| 3) Now you can run matterbridge.  (```./matterbridge```)    | ||||
|  | ||||
| (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: | ||||
|   -conf string | ||||
|         config file (default "matterbridge.toml") | ||||
|   -debug | ||||
|         enable debug | ||||
|   -gops | ||||
|         enable gops agent | ||||
|   -version | ||||
|         show version | ||||
| ``` | ||||
| @@ -161,6 +169,7 @@ Matterbridge wouldn't exist without these libraries: | ||||
| * discord - https://github.com/bwmarrin/discordgo | ||||
| * echo - https://github.com/labstack/echo | ||||
| * gitter - https://github.com/sromku/go-gitter | ||||
| * gops - https://github.com/google/gops | ||||
| * irc - https://github.com/thoj/go-ircevent | ||||
| * mattermost - https://github.com/mattermost/platform | ||||
| * matrix - https://github.com/matrix-org/gomatrix | ||||
|   | ||||
| @@ -27,23 +27,23 @@ type Bridger interface { | ||||
| type Bridge struct { | ||||
| 	Config config.Protocol | ||||
| 	Bridger | ||||
| 	Name        string | ||||
| 	Account     string | ||||
| 	Protocol    string | ||||
| 	ChannelsIn  map[string]config.ChannelOptions | ||||
| 	ChannelsOut map[string]config.ChannelOptions | ||||
| 	Name     string | ||||
| 	Account  string | ||||
| 	Protocol string | ||||
| 	Channels map[string]config.ChannelInfo | ||||
| 	Joined   map[string]bool | ||||
| } | ||||
|  | ||||
| func New(cfg *config.Config, bridge *config.Bridge, c chan config.Message) *Bridge { | ||||
| 	b := new(Bridge) | ||||
| 	b.ChannelsIn = make(map[string]config.ChannelOptions) | ||||
| 	b.ChannelsOut = make(map[string]config.ChannelOptions) | ||||
| 	b.Channels = make(map[string]config.ChannelInfo) | ||||
| 	accInfo := strings.Split(bridge.Account, ".") | ||||
| 	protocol := accInfo[0] | ||||
| 	name := accInfo[1] | ||||
| 	b.Name = name | ||||
| 	b.Protocol = protocol | ||||
| 	b.Account = bridge.Account | ||||
| 	b.Joined = make(map[string]bool) | ||||
|  | ||||
| 	// override config from environment | ||||
| 	config.OverrideCfgFromEnv(cfg, protocol, name) | ||||
| @@ -83,33 +83,28 @@ func New(cfg *config.Config, bridge *config.Bridge, c chan config.Message) *Brid | ||||
| } | ||||
|  | ||||
| func (b *Bridge) JoinChannels() error { | ||||
| 	exists := make(map[string]bool) | ||||
| 	err := b.joinChannels(b.ChannelsIn, exists) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	err = b.joinChannels(b.ChannelsOut, exists) | ||||
| 	err := b.joinChannels(b.Channels, b.Joined) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (b *Bridge) joinChannels(cMap map[string]config.ChannelOptions, exists map[string]bool) error { | ||||
| func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map[string]bool) error { | ||||
| 	mychannel := "" | ||||
| 	for channel, info := range cMap { | ||||
| 		if !exists[channel] { | ||||
| 			mychannel = channel | ||||
| 			log.Infof("%s: joining %s", b.Account, channel) | ||||
| 			if b.Protocol == "irc" && info.Key != "" { | ||||
| 				log.Debugf("using key %s for channel %s", info.Key, channel) | ||||
| 				mychannel = mychannel + " " + info.Key | ||||
| 	for ID, channel := range channels { | ||||
| 		if !exists[ID] { | ||||
| 			mychannel = channel.Name | ||||
| 			log.Infof("%s: joining %s (%s)", b.Account, channel.Name, ID) | ||||
| 			if b.Protocol == "irc" && channel.Options.Key != "" { | ||||
| 				log.Debugf("using key %s for channel %s", channel.Options.Key, channel.Name) | ||||
| 				mychannel = mychannel + " " + channel.Options.Key | ||||
| 			} | ||||
| 			err := b.JoinChannel(mychannel) | ||||
| 			err := b.JoinChannel(channel.Name) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			exists[channel] = true | ||||
| 			exists[ID] = true | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
|   | ||||
| @@ -10,8 +10,9 @@ import ( | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	EVENT_JOIN_LEAVE = "join_leave" | ||||
| 	EVENT_FAILURE    = "failure" | ||||
| 	EVENT_JOIN_LEAVE      = "join_leave" | ||||
| 	EVENT_FAILURE         = "failure" | ||||
| 	EVENT_REJOIN_CHANNELS = "rejoin_channels" | ||||
| ) | ||||
|  | ||||
| type Message struct { | ||||
| @@ -25,9 +26,21 @@ type Message struct { | ||||
| 	Timestamp time.Time | ||||
| } | ||||
|  | ||||
| type ChannelInfo struct { | ||||
| 	Name        string | ||||
| 	Account     string | ||||
| 	Direction   string | ||||
| 	ID          string | ||||
| 	GID         map[string]bool | ||||
| 	SameChannel map[string]bool | ||||
| 	Options     ChannelOptions | ||||
| } | ||||
|  | ||||
| type Protocol struct { | ||||
| 	BindAddress            string // mattermost, slack | ||||
| 	Buffer                 int    // api | ||||
| 	EditSuffix             string // mattermost, slack, discord, telegram, gitter | ||||
| 	EditDisable            bool   // mattermost, slack, discord, telegram, gitter | ||||
| 	IconURL                string // mattermost, slack | ||||
| 	IgnoreNicks            string // all protocols | ||||
| 	Jid                    string // xmpp | ||||
| @@ -63,9 +76,10 @@ type ChannelOptions struct { | ||||
| } | ||||
|  | ||||
| type Bridge struct { | ||||
| 	Account string | ||||
| 	Channel string | ||||
| 	Options ChannelOptions | ||||
| 	Account     string | ||||
| 	Channel     string | ||||
| 	Options     ChannelOptions | ||||
| 	SameChannel bool | ||||
| } | ||||
|  | ||||
| type Gateway struct { | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import ( | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	log "github.com/Sirupsen/logrus" | ||||
| 	"github.com/bwmarrin/discordgo" | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| ) | ||||
| @@ -51,6 +52,7 @@ func (b *bdiscord) Connect() error { | ||||
| 	flog.Info("Connection succeeded") | ||||
| 	b.c.AddHandler(b.messageCreate) | ||||
| 	b.c.AddHandler(b.memberUpdate) | ||||
| 	b.c.AddHandler(b.messageUpdate) | ||||
| 	err = b.c.Open() | ||||
| 	if err != nil { | ||||
| 		flog.Debugf("%#v", err) | ||||
| @@ -103,6 +105,18 @@ func (b *bdiscord) Send(msg config.Message) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (b *bdiscord) messageUpdate(s *discordgo.Session, m *discordgo.MessageUpdate) { | ||||
| 	if b.Config.EditDisable { | ||||
| 		return | ||||
| 	} | ||||
| 	// only when message is actually edited | ||||
| 	if m.Message.EditedTimestamp != "" { | ||||
| 		flog.Debugf("Sending edit message") | ||||
| 		m.Content = m.Content + b.Config.EditSuffix | ||||
| 		b.messageCreate(s, (*discordgo.MessageCreate)(m)) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (b *bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { | ||||
| 	// not relay our own messages | ||||
| 	if m.Author.Username == b.Nick { | ||||
| @@ -125,6 +139,7 @@ func (b *bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat | ||||
| 	if len(m.MentionRoles) > 0 { | ||||
| 		m.Message.Content = b.replaceRoleMentions(m.Message.Content) | ||||
| 	} | ||||
| 	m.Message.Content = b.stripCustomoji(m.Message.Content) | ||||
| 	b.Remote <- config.Message{Username: username, Text: m.ContentWithMentionsReplaced(), Channel: channelName, | ||||
| 		Account: b.Account, Avatar: "https://cdn.discordapp.com/avatars/" + m.Author.ID + "/" + m.Author.Avatar + ".jpg"} | ||||
| } | ||||
| @@ -195,3 +210,9 @@ func (b *bdiscord) replaceRoleMentions(text string) string { | ||||
| 	} | ||||
| 	return text | ||||
| } | ||||
|  | ||||
| func (b *bdiscord) stripCustomoji(text string) string { | ||||
| 	// <:doge:302803592035958784> | ||||
| 	re := regexp.MustCompile("<(:.*?:)[0-9]+>") | ||||
| 	return re.ReplaceAllString(text, `$1`) | ||||
| } | ||||
|   | ||||
| @@ -92,7 +92,7 @@ func (b *Birc) Connect() error { | ||||
| } | ||||
|  | ||||
| func (b *Birc) Disconnect() error { | ||||
| 	b.i.Disconnect() | ||||
| 	//b.i.Disconnect() | ||||
| 	close(b.Local) | ||||
| 	return nil | ||||
| } | ||||
| @@ -109,7 +109,6 @@ func (b *Birc) Send(msg config.Message) error { | ||||
| 	} | ||||
| 	if strings.HasPrefix(msg.Text, "!") { | ||||
| 		b.Command(&msg) | ||||
| 		return nil | ||||
| 	} | ||||
| 	for _, text := range strings.Split(msg.Text, "\n") { | ||||
| 		if len(b.Local) < b.Config.MessageQueue { | ||||
| @@ -167,14 +166,19 @@ func (b *Birc) handleNewConnection(event *irc.Event) { | ||||
| 	i.AddCallback("JOIN", b.handleJoinPart) | ||||
| 	i.AddCallback("PART", b.handleJoinPart) | ||||
| 	i.AddCallback("QUIT", b.handleJoinPart) | ||||
| 	i.AddCallback("KICK", b.handleJoinPart) | ||||
| 	i.AddCallback("*", b.handleOther) | ||||
| 	// we are now fully connected | ||||
| 	b.connected <- struct{}{} | ||||
| } | ||||
|  | ||||
| func (b *Birc) handleJoinPart(event *irc.Event) { | ||||
| 	flog.Debugf("Sending JOIN_LEAVE event from %s to gateway", b.Account) | ||||
| 	channel := event.Arguments[0] | ||||
| 	if event.Code == "KICK" { | ||||
| 		flog.Infof("Got kicked from %s by %s", channel, event.Nick) | ||||
| 		b.Remote <- config.Message{Username: "system", Text: "rejoin", Channel: channel, Account: b.Account, Event: config.EVENT_REJOIN_CHANNELS} | ||||
| 		return | ||||
| 	} | ||||
| 	if event.Code == "QUIT" { | ||||
| 		if event.Nick == b.Nick && strings.Contains(event.Raw, "Ping timeout") { | ||||
| 			flog.Infof("%s reconnecting ..", b.Account) | ||||
| @@ -182,6 +186,7 @@ func (b *Birc) handleJoinPart(event *irc.Event) { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 	flog.Debugf("Sending JOIN_LEAVE event from %s to gateway", b.Account) | ||||
| 	b.Remote <- config.Message{Username: "system", Text: event.Nick + " " + strings.ToLower(event.Code) + "s", Channel: channel, Account: b.Account, Event: config.EVENT_JOIN_LEAVE} | ||||
| 	flog.Debugf("handle %#v", event) | ||||
| } | ||||
|   | ||||
| @@ -72,6 +72,7 @@ func (b *Bmattermost) Connect() error { | ||||
| 		flog.Info("Connection succeeded") | ||||
| 		b.TeamId = b.mc.GetTeamId() | ||||
| 		go b.mc.WsReceiver() | ||||
| 		go b.mc.StatusLoop() | ||||
| 	} | ||||
| 	go b.handleMatter() | ||||
| 	return nil | ||||
| @@ -96,15 +97,11 @@ func (b *Bmattermost) Send(msg config.Message) error { | ||||
| 	channel := msg.Channel | ||||
|  | ||||
| 	if b.Config.PrefixMessagesWithNick { | ||||
| 		/*if IsMarkup(message) { | ||||
| 			message = nick + "\n\n" + message | ||||
| 		} else { | ||||
| 		*/ | ||||
| 		message = nick + " " + message | ||||
| 		//} | ||||
| 		message = nick + message | ||||
| 	} | ||||
| 	if !b.Config.UseAPI { | ||||
| 		matterMessage := matterhook.OMessage{IconURL: b.Config.IconURL} | ||||
| 		matterMessage.IconURL = msg.Avatar | ||||
| 		matterMessage.Channel = channel | ||||
| 		matterMessage.UserName = nick | ||||
| 		matterMessage.Type = "" | ||||
| @@ -136,14 +133,26 @@ func (b *Bmattermost) handleMatter() { | ||||
|  | ||||
| func (b *Bmattermost) handleMatterClient(mchan chan *MMMessage) { | ||||
| 	for message := range b.mc.MessageChan { | ||||
| 		flog.Debugf("%#v", message.Raw.Data) | ||||
| 		if message.Type == "system_join_leave" || | ||||
| 			message.Type == "system_join_channel" || | ||||
| 			message.Type == "system_leave_channel" { | ||||
| 			flog.Debugf("Sending JOIN_LEAVE event from %s to gateway", b.Account) | ||||
| 			b.Remote <- config.Message{Username: "system", Text: message.Text, Channel: message.Channel, Account: b.Account, Event: config.EVENT_JOIN_LEAVE} | ||||
| 			continue | ||||
| 		} | ||||
| 		// do not post our own messages back to irc | ||||
| 		// only listen to message from our team | ||||
| 		if message.Raw.Event == "posted" && b.mc.User.Username != message.Username && message.Raw.Data["team_id"].(string) == b.TeamId { | ||||
| 		if (message.Raw.Event == "posted" || message.Raw.Event == "post_edited") && | ||||
| 			b.mc.User.Username != message.Username && message.Raw.Data["team_id"].(string) == b.TeamId { | ||||
| 			flog.Debugf("Receiving from matterclient %#v", message) | ||||
| 			m := &MMMessage{} | ||||
| 			m.Username = message.Username | ||||
| 			m.Channel = message.Channel | ||||
| 			m.Text = message.Text | ||||
| 			if message.Raw.Event == "post_edited" && !b.Config.EditDisable { | ||||
| 				m.Text = message.Text + b.Config.EditSuffix | ||||
| 			} | ||||
| 			if len(message.Post.FileIds) > 0 { | ||||
| 				for _, link := range b.mc.GetPublicLinks(message.Post.FileIds) { | ||||
| 					m.Text = m.Text + "\n" + link | ||||
|   | ||||
| @@ -73,9 +73,15 @@ func (b *Bslack) Disconnect() error { | ||||
| func (b *Bslack) JoinChannel(channel string) error { | ||||
| 	// we can only join channels using the API | ||||
| 	if b.Config.UseAPI { | ||||
| 		if strings.HasPrefix(b.Config.Token, "xoxb") { | ||||
| 			// TODO check if bot has already joined channel | ||||
| 			return nil | ||||
| 		} | ||||
| 		_, err := b.sc.JoinChannel(channel) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 			if err.Error() != "name_taken" { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| @@ -195,6 +201,11 @@ func (b *Bslack) handleSlackClient(mchan chan *MMMessage) { | ||||
| 			// ignore first message | ||||
| 			if count > 0 { | ||||
| 				flog.Debugf("Receiving from slackclient %#v", ev) | ||||
| 				if !b.Config.EditDisable && ev.SubMessage != nil { | ||||
| 					flog.Debugf("SubMessage %#v", ev.SubMessage) | ||||
| 					ev.User = ev.SubMessage.User | ||||
| 					ev.Text = ev.SubMessage.Text + b.Config.EditSuffix | ||||
| 				} | ||||
| 				// use our own func because rtm.GetChannelInfo doesn't work for private channels | ||||
| 				channel, err := b.getChannelByID(ev.Channel) | ||||
| 				if err != nil { | ||||
|   | ||||
| @@ -80,28 +80,32 @@ func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) { | ||||
| 	text := "" | ||||
| 	channel := "" | ||||
| 	for update := range updates { | ||||
| 		var message *tgbotapi.Message | ||||
| 		// handle channels | ||||
| 		if update.ChannelPost != nil { | ||||
| 			if update.ChannelPost.From != nil { | ||||
| 				username = update.ChannelPost.From.FirstName | ||||
| 				if username == "" { | ||||
| 					username = update.ChannelPost.From.UserName | ||||
| 				} | ||||
| 			} | ||||
| 			text = update.ChannelPost.Text | ||||
| 			channel = strconv.FormatInt(update.ChannelPost.Chat.ID, 10) | ||||
| 			message = update.ChannelPost | ||||
| 		} | ||||
| 		if update.EditedChannelPost != nil && !b.Config.EditDisable { | ||||
| 			message = update.EditedChannelPost | ||||
| 			message.Text = message.Text + b.Config.EditSuffix | ||||
| 		} | ||||
| 		// handle groups | ||||
| 		if update.Message != nil { | ||||
| 			if update.Message.From != nil { | ||||
| 				username = update.Message.From.FirstName | ||||
| 				if username == "" { | ||||
| 					username = update.Message.From.UserName | ||||
| 				} | ||||
| 			} | ||||
| 			text = update.Message.Text | ||||
| 			channel = strconv.FormatInt(update.Message.Chat.ID, 10) | ||||
| 			message = update.Message | ||||
| 		} | ||||
| 		if update.EditedMessage != nil && !b.Config.EditDisable { | ||||
| 			message = update.EditedMessage | ||||
| 			message.Text = message.Text + b.Config.EditSuffix | ||||
| 		} | ||||
| 		if message.From != nil { | ||||
| 			username = message.From.FirstName | ||||
| 			if username == "" { | ||||
| 				username = message.From.UserName | ||||
| 			} | ||||
| 			text = message.Text | ||||
| 			channel = strconv.FormatInt(message.Chat.ID, 10) | ||||
| 		} | ||||
|  | ||||
| 		if username == "" { | ||||
| 			username = "unknown" | ||||
| 		} | ||||
|   | ||||
							
								
								
									
										42
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								changelog.md
									
									
									
									
									
								
							| @@ -1,3 +1,45 @@ | ||||
| # v0.12.0 | ||||
| ## Changes | ||||
| * general: edited messages are now being sent by default on discord/mattermost/telegram/slack. See "New Features" | ||||
|  | ||||
| ## New features | ||||
| * general: add support for edited messages.  | ||||
|   Add new keyword EditDisable (false/true), default false. Which means by default edited messages will be sent to other bridges. | ||||
|   Add new keyword EditSuffix , default "". You can change this eg to "(edited)", this will be appended to every edit message. | ||||
|  | ||||
| ## Enhancements | ||||
| * discord: Strip custom emoji metadata (discord). Closes #148 | ||||
|  | ||||
| # v0.11.0 | ||||
| ## 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 | ||||
| * telegram:  Support edited messages (telegram). See #141 | ||||
| * mattermost: Add support for showing/hiding join/leave messages from mattermost. Closes #147 | ||||
| * mattermost: Reconnect on session removal/timeout (mattermost) | ||||
| * irc:  Rejoin channel when kicked (irc). | ||||
|  | ||||
| ## Bugfix | ||||
| * mattermost: Remove space after nick (mattermost). Closes #142 | ||||
| * mattermost: Modify iconurl correctly (mattermost). | ||||
| * irc: Fix join/leave regression (irc) | ||||
|  | ||||
| # v0.10.3 | ||||
| ## Bugfix | ||||
| * slack: Allow bot tokens for now without warning (slack). Closes #140 (fixes user_is_bot message on channel join) | ||||
|  | ||||
| # v0.10.2 | ||||
| ## New features | ||||
| * general: gops agent added. Allows for more debugging. See #134 | ||||
| * general: toml inline table support added for config file | ||||
|  | ||||
| ## Bugfix | ||||
| * all: vendored libs updated | ||||
|  | ||||
| ## Changes | ||||
| * general: add more informative messages on startup | ||||
|  | ||||
| # v0.10.1 | ||||
| ## Bugfix | ||||
| * gitter: Fix sending messages on new channel join. | ||||
|   | ||||
| @@ -5,7 +5,6 @@ import ( | ||||
| 	"github.com/42wim/matterbridge/bridge" | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	log "github.com/Sirupsen/logrus" | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
| @@ -14,21 +13,21 @@ type Gateway struct { | ||||
| 	*config.Config | ||||
| 	MyConfig        *config.Gateway | ||||
| 	Bridges         map[string]*bridge.Bridge | ||||
| 	ChannelsOut     map[string][]string | ||||
| 	ChannelsIn      map[string][]string | ||||
| 	Channels        map[string]*config.ChannelInfo | ||||
| 	ChannelOptions  map[string]config.ChannelOptions | ||||
| 	Names           map[string]bool | ||||
| 	Name            string | ||||
| 	Message         chan config.Message | ||||
| 	DestChannelFunc func(msg *config.Message, dest string) []string | ||||
| 	DestChannelFunc func(msg *config.Message, dest bridge.Bridge) []config.ChannelInfo | ||||
| } | ||||
|  | ||||
| func New(cfg *config.Config, gateway *config.Gateway) *Gateway { | ||||
| func New(cfg *config.Config) *Gateway { | ||||
| 	gw := &Gateway{} | ||||
| 	gw.Name = gateway.Name | ||||
| 	gw.Config = cfg | ||||
| 	gw.MyConfig = gateway | ||||
| 	gw.Channels = make(map[string]*config.ChannelInfo) | ||||
| 	gw.Message = make(chan config.Message) | ||||
| 	gw.Bridges = make(map[string]*bridge.Bridge) | ||||
| 	gw.Names = make(map[string]bool) | ||||
| 	gw.DestChannelFunc = gw.getDestChannel | ||||
| 	return gw | ||||
| } | ||||
| @@ -36,13 +35,17 @@ func New(cfg *config.Config, gateway *config.Gateway) *Gateway { | ||||
| func (gw *Gateway) AddBridge(cfg *config.Bridge) error { | ||||
| 	for _, br := range gw.Bridges { | ||||
| 		if br.Account == cfg.Account { | ||||
| 			gw.mapChannelsToBridge(br) | ||||
| 			err := br.JoinChannels() | ||||
| 			if err != nil { | ||||
| 				return fmt.Errorf("Bridge %s failed to join channel: %v", br.Account, err) | ||||
| 			} | ||||
| 			return nil | ||||
| 		} | ||||
| 	} | ||||
| 	log.Infof("Starting bridge: %s ", cfg.Account) | ||||
| 	br := bridge.New(gw.Config, cfg, gw.Message) | ||||
| 	gw.mapChannelsToBridge(br, gw.ChannelsOut) | ||||
| 	gw.mapChannelsToBridge(br, gw.ChannelsIn) | ||||
| 	gw.mapChannelsToBridge(br) | ||||
| 	gw.Bridges[cfg.Account] = br | ||||
| 	err := br.Connect() | ||||
| 	if err != nil { | ||||
| @@ -55,17 +58,17 @@ func (gw *Gateway) AddBridge(cfg *config.Bridge) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (gw *Gateway) mapChannelsToBridge(br *bridge.Bridge, cMap map[string][]string) { | ||||
| 	for _, channel := range cMap[br.Account] { | ||||
| 		if _, ok := gw.ChannelOptions[br.Account+channel]; ok { | ||||
| 			br.ChannelsOut[channel] = gw.ChannelOptions[br.Account+channel] | ||||
| 		} else { | ||||
| 			br.ChannelsOut[channel] = config.ChannelOptions{} | ||||
| 		} | ||||
| func (gw *Gateway) AddConfig(cfg *config.Gateway) error { | ||||
| 	if gw.Names[cfg.Name] { | ||||
| 		return fmt.Errorf("Gateway with name %s already exists", cfg.Name) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (gw *Gateway) Start() error { | ||||
| 	if cfg.Name == "" { | ||||
| 		return fmt.Errorf("%s", "Gateway without name found") | ||||
| 	} | ||||
| 	log.Infof("Starting gateway: %s", cfg.Name) | ||||
| 	gw.Names[cfg.Name] = true | ||||
| 	gw.Name = cfg.Name | ||||
| 	gw.MyConfig = cfg | ||||
| 	gw.mapChannels() | ||||
| 	for _, br := range append(gw.MyConfig.In, append(gw.MyConfig.InOut, gw.MyConfig.Out...)...) { | ||||
| 		err := gw.AddBridge(&br) | ||||
| @@ -73,6 +76,18 @@ func (gw *Gateway) Start() error { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (gw *Gateway) mapChannelsToBridge(br *bridge.Bridge) { | ||||
| 	for ID, channel := range gw.Channels { | ||||
| 		if br.Account == channel.Account { | ||||
| 			br.Channels[ID] = *channel | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (gw *Gateway) Start() error { | ||||
| 	go gw.handleReceive() | ||||
| 	return nil | ||||
| } | ||||
| @@ -88,6 +103,15 @@ func (gw *Gateway) handleReceive() { | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			if msg.Event == config.EVENT_REJOIN_CHANNELS { | ||||
| 				for _, br := range gw.Bridges { | ||||
| 					if msg.Account == br.Account { | ||||
| 						br.Joined = make(map[string]bool) | ||||
| 						br.JoinChannels() | ||||
| 					} | ||||
| 				} | ||||
| 				continue | ||||
| 			} | ||||
| 			if !gw.ignoreMessage(&msg) { | ||||
| 				msg.Timestamp = time.Now() | ||||
| 				for _, br := range gw.Bridges { | ||||
| @@ -109,45 +133,52 @@ RECONNECT: | ||||
| 		time.Sleep(time.Second * 60) | ||||
| 		goto RECONNECT | ||||
| 	} | ||||
| 	br.Joined = make(map[string]bool) | ||||
| 	br.JoinChannels() | ||||
| } | ||||
|  | ||||
| func (gw *Gateway) mapChannels() error { | ||||
| 	options := make(map[string]config.ChannelOptions) | ||||
| 	m := make(map[string][]string) | ||||
| 	for _, br := range gw.MyConfig.Out { | ||||
| 		m[br.Account] = append(m[br.Account], br.Channel) | ||||
| 		options[br.Account+br.Channel] = br.Options | ||||
| 	for _, br := range append(gw.MyConfig.Out, gw.MyConfig.InOut...) { | ||||
| 		ID := br.Channel + br.Account | ||||
| 		_, ok := gw.Channels[ID] | ||||
| 		if !ok { | ||||
| 			channel := &config.ChannelInfo{Name: br.Channel, Direction: "out", ID: ID, Options: br.Options, Account: br.Account, | ||||
| 				GID: make(map[string]bool), SameChannel: make(map[string]bool)} | ||||
| 			channel.GID[gw.Name] = true | ||||
| 			channel.SameChannel[gw.Name] = br.SameChannel | ||||
| 			gw.Channels[channel.ID] = channel | ||||
| 		} | ||||
| 		gw.Channels[ID].GID[gw.Name] = true | ||||
| 		gw.Channels[ID].SameChannel[gw.Name] = br.SameChannel | ||||
| 	} | ||||
| 	gw.ChannelsOut = m | ||||
| 	m = nil | ||||
| 	m = make(map[string][]string) | ||||
| 	for _, br := range gw.MyConfig.In { | ||||
| 		m[br.Account] = append(m[br.Account], br.Channel) | ||||
| 		options[br.Account+br.Channel] = br.Options | ||||
|  | ||||
| 	for _, br := range append(gw.MyConfig.In, gw.MyConfig.InOut...) { | ||||
| 		ID := br.Channel + br.Account | ||||
| 		_, ok := gw.Channels[ID] | ||||
| 		if !ok { | ||||
| 			channel := &config.ChannelInfo{Name: br.Channel, Direction: "in", ID: ID, Options: br.Options, Account: br.Account, | ||||
| 				GID: make(map[string]bool), SameChannel: make(map[string]bool)} | ||||
| 			channel.GID[gw.Name] = true | ||||
| 			channel.SameChannel[gw.Name] = br.SameChannel | ||||
| 			gw.Channels[channel.ID] = channel | ||||
| 		} | ||||
| 		gw.Channels[ID].GID[gw.Name] = true | ||||
| 		gw.Channels[ID].SameChannel[gw.Name] = br.SameChannel | ||||
| 	} | ||||
| 	gw.ChannelsIn = m | ||||
| 	for _, br := range gw.MyConfig.InOut { | ||||
| 		gw.ChannelsIn[br.Account] = append(gw.ChannelsIn[br.Account], br.Channel) | ||||
| 		gw.ChannelsOut[br.Account] = append(gw.ChannelsOut[br.Account], br.Channel) | ||||
| 		options[br.Account+br.Channel] = br.Options | ||||
| 	} | ||||
| 	gw.ChannelOptions = options | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (gw *Gateway) getDestChannel(msg *config.Message, dest string) []string { | ||||
| 	channels := gw.ChannelsIn[msg.Account] | ||||
| 	// broadcast to every out channel (irc QUIT) | ||||
| 	if msg.Event == config.EVENT_JOIN_LEAVE && msg.Channel == "" { | ||||
| 		return gw.ChannelsOut[dest] | ||||
| 	} | ||||
| 	for _, channel := range channels { | ||||
| 		if channel == msg.Channel { | ||||
| 			return gw.ChannelsOut[dest] | ||||
| func (gw *Gateway) getDestChannel(msg *config.Message, dest bridge.Bridge) []config.ChannelInfo { | ||||
| 	var channels []config.ChannelInfo | ||||
| 	for _, channel := range gw.Channels { | ||||
| 		if _, ok := gw.Channels[getChannelID(*msg)]; !ok { | ||||
| 			continue | ||||
| 		} | ||||
| 		if channel.Direction == "out" && channel.Account == dest.Account && gw.validGatewayDest(*msg, channel) { | ||||
| 			channels = append(channels, *channel) | ||||
| 		} | ||||
| 	} | ||||
| 	return []string{} | ||||
| 	return channels | ||||
| } | ||||
|  | ||||
| func (gw *Gateway) handleMessage(msg config.Message, dest *bridge.Bridge) { | ||||
| @@ -155,19 +186,20 @@ func (gw *Gateway) handleMessage(msg config.Message, dest *bridge.Bridge) { | ||||
| 	if msg.Event == config.EVENT_JOIN_LEAVE && !gw.Bridges[dest.Account].Config.ShowJoinPart { | ||||
| 		return | ||||
| 	} | ||||
| 	// broadcast to every out channel (irc QUIT) | ||||
| 	if msg.Channel == "" && msg.Event != config.EVENT_JOIN_LEAVE { | ||||
| 		log.Debug("empty channel") | ||||
| 		return | ||||
| 	} | ||||
| 	originchannel := msg.Channel | ||||
| 	channels := gw.DestChannelFunc(&msg, dest.Account) | ||||
| 	for _, channel := range channels { | ||||
| 		// do not send the message to the bridge we come from if also the channel is the same | ||||
| 		if msg.Account == dest.Account && channel == originchannel { | ||||
| 	for _, channel := range gw.DestChannelFunc(&msg, *dest) { | ||||
| 		// do not send to ourself | ||||
| 		if channel.ID == getChannelID(msg) { | ||||
| 			continue | ||||
| 		} | ||||
| 		msg.Channel = channel | ||||
| 		if msg.Channel == "" { | ||||
| 			log.Debug("empty channel") | ||||
| 			return | ||||
| 		} | ||||
| 		log.Debugf("Sending %#v from %s (%s) to %s (%s)", msg, msg.Account, originchannel, dest.Account, channel) | ||||
| 		log.Debugf("Sending %#v from %s (%s) to %s (%s)", msg, msg.Account, originchannel, dest.Account, channel.Name) | ||||
| 		msg.Channel = channel.Name | ||||
| 		gw.modifyAvatar(&msg, dest) | ||||
| 		gw.modifyUsername(&msg, dest) | ||||
| 		// for api we need originchannel as channel | ||||
| 		if dest.Protocol == "api" { | ||||
| @@ -194,21 +226,6 @@ func (gw *Gateway) ignoreMessage(msg *config.Message) bool { | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (gw *Gateway) modifyMessage(msg *config.Message, dest *bridge.Bridge) { | ||||
| 	val := reflect.ValueOf(gw.Config).Elem() | ||||
| 	for i := 0; i < val.NumField(); i++ { | ||||
| 		typeField := val.Type().Field(i) | ||||
| 		// look for the protocol map (both lowercase) | ||||
| 		if strings.ToLower(typeField.Name) == dest.Protocol { | ||||
| 			// get the Protocol struct from the map | ||||
| 			protoCfg := val.Field(i).MapIndex(reflect.ValueOf(dest.Name)) | ||||
| 			//config.SetNickFormat(msg, protoCfg.Interface().(config.Protocol)) | ||||
| 			val.Field(i).SetMapIndex(reflect.ValueOf(dest.Name), protoCfg) | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (gw *Gateway) modifyUsername(msg *config.Message, dest *bridge.Bridge) { | ||||
| 	br := gw.Bridges[msg.Account] | ||||
| 	msg.Protocol = br.Protocol | ||||
| @@ -221,3 +238,40 @@ func (gw *Gateway) modifyUsername(msg *config.Message, dest *bridge.Bridge) { | ||||
| 	nick = strings.Replace(nick, "{PROTOCOL}", br.Protocol, -1) | ||||
| 	msg.Username = nick | ||||
| } | ||||
|  | ||||
| func (gw *Gateway) modifyAvatar(msg *config.Message, dest *bridge.Bridge) { | ||||
| 	iconurl := gw.Config.General.IconURL | ||||
| 	if iconurl == "" { | ||||
| 		iconurl = dest.Config.IconURL | ||||
| 	} | ||||
| 	iconurl = strings.Replace(iconurl, "{NICK}", msg.Username, -1) | ||||
| 	if msg.Avatar == "" { | ||||
| 		msg.Avatar = iconurl | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func getChannelID(msg config.Message) string { | ||||
| 	return msg.Channel + msg.Account | ||||
| } | ||||
|  | ||||
| func (gw *Gateway) validGatewayDest(msg config.Message, channel *config.ChannelInfo) bool { | ||||
| 	GIDmap := gw.Channels[getChannelID(msg)].GID | ||||
| 	// check if we are running a samechannelgateway. | ||||
| 	// if it is and the channel name matches it's ok, otherwise we shouldn't use this channel. | ||||
| 	for k, _ := range GIDmap { | ||||
| 		if channel.SameChannel[k] == true { | ||||
| 			if msg.Channel == channel.Name { | ||||
| 				return true | ||||
| 			} else { | ||||
| 				return false | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	// check if we are in the correct gateway | ||||
| 	for k, _ := range GIDmap { | ||||
| 		if channel.GID[k] == true { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|   | ||||
| @@ -2,48 +2,27 @@ package samechannelgateway | ||||
|  | ||||
| import ( | ||||
| 	"github.com/42wim/matterbridge/bridge/config" | ||||
| 	"github.com/42wim/matterbridge/gateway" | ||||
| ) | ||||
|  | ||||
| type SameChannelGateway struct { | ||||
| 	*config.Config | ||||
| 	MyConfig *config.SameChannelGateway | ||||
| 	Channels []string | ||||
| 	Name     string | ||||
| } | ||||
|  | ||||
| func New(cfg *config.Config, gatewayCfg *config.SameChannelGateway) *SameChannelGateway { | ||||
| 	return &SameChannelGateway{ | ||||
| 		MyConfig: gatewayCfg, | ||||
| 		Channels: gatewayCfg.Channels, | ||||
| 		Name:     gatewayCfg.Name, | ||||
| 		Config:   cfg} | ||||
| func New(cfg *config.Config) *SameChannelGateway { | ||||
| 	return &SameChannelGateway{Config: cfg} | ||||
| } | ||||
|  | ||||
| func (sgw *SameChannelGateway) Start() error { | ||||
| 	gw := gateway.New(sgw.Config, &config.Gateway{Name: sgw.Name}) | ||||
| 	gw.DestChannelFunc = sgw.getDestChannel | ||||
| 	for _, account := range sgw.MyConfig.Accounts { | ||||
| 		for _, channel := range sgw.Channels { | ||||
| 			br := config.Bridge{Account: account, Channel: channel} | ||||
| 			gw.MyConfig.InOut = append(gw.MyConfig.InOut, br) | ||||
| func (sgw *SameChannelGateway) GetConfig() []config.Gateway { | ||||
| 	var gwconfigs []config.Gateway | ||||
| 	cfg := sgw.Config | ||||
| 	for _, gw := range cfg.SameChannelGateway { | ||||
| 		gwconfig := config.Gateway{Name: gw.Name, Enable: gw.Enable} | ||||
| 		for _, account := range gw.Accounts { | ||||
| 			for _, channel := range gw.Channels { | ||||
| 				gwconfig.InOut = append(gwconfig.InOut, config.Bridge{Account: account, Channel: channel, SameChannel: true}) | ||||
| 			} | ||||
| 		} | ||||
| 		gwconfigs = append(gwconfigs, gwconfig) | ||||
| 	} | ||||
| 	return gw.Start() | ||||
| } | ||||
|  | ||||
| func (sgw *SameChannelGateway) validChannel(channel string) bool { | ||||
| 	for _, c := range sgw.Channels { | ||||
| 		if c == channel { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (sgw *SameChannelGateway) getDestChannel(msg *config.Message, dest string) []string { | ||||
| 	if sgw.validChannel(msg.Channel) { | ||||
| 		return []string{msg.Channel} | ||||
| 	} | ||||
| 	return []string{} | ||||
| 	return gwconfigs | ||||
| } | ||||
|   | ||||
| @@ -7,10 +7,12 @@ import ( | ||||
| 	"github.com/42wim/matterbridge/gateway" | ||||
| 	"github.com/42wim/matterbridge/gateway/samechannel" | ||||
| 	log "github.com/Sirupsen/logrus" | ||||
| 	"github.com/google/gops/agent" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	version = "0.10.1" | ||||
| 	version = "0.12.0" | ||||
| 	githash string | ||||
| ) | ||||
|  | ||||
| @@ -22,7 +24,12 @@ func main() { | ||||
| 	flagConfig := flag.String("conf", "matterbridge.toml", "config file") | ||||
| 	flagDebug := flag.Bool("debug", false, "enable debug") | ||||
| 	flagVersion := flag.Bool("version", false, "show version") | ||||
| 	flagGops := flag.Bool("gops", false, "enable gops agent") | ||||
| 	flag.Parse() | ||||
| 	if *flagGops { | ||||
| 		agent.Listen(&agent.Options{}) | ||||
| 		defer agent.Close() | ||||
| 	} | ||||
| 	if *flagVersion { | ||||
| 		fmt.Printf("version: %s %s\n", version, githash) | ||||
| 		return | ||||
| @@ -33,29 +40,27 @@ func main() { | ||||
| 		log.SetLevel(log.DebugLevel) | ||||
| 	} | ||||
| 	log.Printf("Running version %s %s", version, githash) | ||||
| 	if strings.Contains(version, "-dev") { | ||||
| 		log.Println("WARNING: THIS IS A DEVELOPMENT VERSION. Things may break.") | ||||
| 	} | ||||
| 	cfg := config.NewConfig(*flagConfig) | ||||
| 	for _, gw := range cfg.SameChannelGateway { | ||||
| 		if !gw.Enable { | ||||
| 			continue | ||||
| 		} | ||||
| 		log.Printf("Starting samechannel gateway %#v", gw.Name) | ||||
| 		g := samechannelgateway.New(cfg, &gw) | ||||
| 		err := g.Start() | ||||
| 		if err != nil { | ||||
| 			log.Fatalf("Starting gateway failed %#v", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	for _, gw := range cfg.Gateway { | ||||
| 	g := gateway.New(cfg) | ||||
| 	sgw := samechannelgateway.New(cfg) | ||||
| 	gwconfigs := sgw.GetConfig() | ||||
| 	for _, gw := range append(gwconfigs, cfg.Gateway...) { | ||||
| 		if !gw.Enable { | ||||
| 			continue | ||||
| 		} | ||||
| 		log.Printf("Starting gateway %#v", gw.Name) | ||||
| 		g := gateway.New(cfg, &gw) | ||||
| 		err := g.Start() | ||||
| 		err := g.AddConfig(&gw) | ||||
| 		if err != nil { | ||||
| 			log.Fatalf("Starting gateway failed %#v", err) | ||||
| 			log.Fatalf("Starting gateway failed: %s", err) | ||||
| 		} | ||||
| 	} | ||||
| 	err := g.Start() | ||||
| 	if err != nil { | ||||
| 		log.Fatalf("Starting gateway failed: %s", err) | ||||
| 	} | ||||
| 	log.Printf("Gateway(s) started succesfully. Now relaying messages") | ||||
| 	select {} | ||||
| } | ||||
|   | ||||
| @@ -64,7 +64,8 @@ IgnoreNicks="ircspammer1 ircspammer2" | ||||
| #OPTIONAL (default empty) | ||||
| RemoteNickFormat="[{PROTOCOL}] <{NICK}> " | ||||
|  | ||||
| #Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) | ||||
| #Enable to show users joins/parts from other bridges  | ||||
| #Only works hiding/show messages from irc and mattermost bridge for now | ||||
| #OPTIONAL (default false) | ||||
| ShowJoinPart=false | ||||
|  | ||||
| @@ -114,7 +115,8 @@ IgnoreNicks="ircspammer1 ircspammer2" | ||||
| #OPTIONAL (default empty) | ||||
| RemoteNickFormat="[{PROTOCOL}] <{NICK}> " | ||||
|  | ||||
| #Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) | ||||
| #Enable to show users joins/parts from other bridges  | ||||
| #Only works hiding/show messages from irc and mattermost bridge for now | ||||
| #OPTIONAL (default false) | ||||
| ShowJoinPart=false | ||||
|  | ||||
| @@ -157,7 +159,8 @@ IgnoreNicks="spammer1 spammer2" | ||||
| #OPTIONAL (default empty) | ||||
| RemoteNickFormat="[{PROTOCOL}/{BRIDGE}] <{NICK}> " | ||||
|  | ||||
| #Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) | ||||
| #Enable to show users joins/parts from other bridges  | ||||
| #Only works hiding/show messages from irc and mattermost bridge for now | ||||
| #OPTIONAL (default false) | ||||
| ShowJoinPart=false | ||||
|  | ||||
| @@ -197,7 +200,7 @@ IconURL="http://youricon.png" | ||||
| #OPTIONAL | ||||
| useAPI=false | ||||
|  | ||||
| #The mattermost hostname.  | ||||
| #The mattermost hostname. (do not prefix it with http or https) | ||||
| #REQUIRED (when useAPI=true) | ||||
| Server="yourmattermostserver.domain"  | ||||
|  | ||||
| @@ -238,6 +241,14 @@ NicksPerRow=4 | ||||
| #OPTIONAL (default false) | ||||
| PrefixMessagesWithNick=false | ||||
|  | ||||
| #Disable sending of edits to other bridges | ||||
| #OPTIONAL (default false) | ||||
| EditDisable=false | ||||
|  | ||||
| #Message to be appended to every edited message | ||||
| #OPTIONAL (default empty) | ||||
| EditSuffix=" (edited)" | ||||
|  | ||||
| #Nicks you want to ignore.  | ||||
| #Messages from those users will not be sent to other bridges. | ||||
| #OPTIONAL | ||||
| @@ -250,7 +261,8 @@ IgnoreNicks="ircspammer1 ircspammer2" | ||||
| #OPTIONAL (default empty) | ||||
| RemoteNickFormat="[{PROTOCOL}] <{NICK}> " | ||||
|  | ||||
| #Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) | ||||
| #Enable to show users joins/parts from other bridges  | ||||
| #Only works hiding/show messages from irc and mattermost bridge for now | ||||
| #OPTIONAL (default false) | ||||
| ShowJoinPart=false | ||||
|  | ||||
| @@ -282,7 +294,8 @@ IgnoreNicks="ircspammer1 ircspammer2" | ||||
| #OPTIONAL (default empty) | ||||
| RemoteNickFormat="[{PROTOCOL}] <{NICK}> " | ||||
|  | ||||
| #Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) | ||||
| #Enable to show users joins/parts from other bridges  | ||||
| #Only works hiding/show messages from irc and mattermost bridge for now | ||||
| #OPTIONAL (default false) | ||||
| ShowJoinPart=false | ||||
|  | ||||
| @@ -321,6 +334,7 @@ useAPI=false | ||||
| #Token to connect with the Slack API | ||||
| #You'll have to use a test/api-token using a dedicated user and not a bot token. | ||||
| #See https://github.com/42wim/matterbridge/issues/75 for more info. | ||||
| #Use https://api.slack.com/custom-integrations/legacy-tokens | ||||
| #REQUIRED (when useAPI=true) | ||||
| Token="yourslacktoken" | ||||
|  | ||||
| @@ -341,6 +355,14 @@ NickFormatter="plain" | ||||
| #OPTIONAL (default 4) | ||||
| NicksPerRow=4 | ||||
|  | ||||
| #Disable sending of edits to other bridges | ||||
| #OPTIONAL (default false) | ||||
| EditDisable=true | ||||
|  | ||||
| #Message to be appended to every edited message | ||||
| #OPTIONAL (default empty) | ||||
| EditSuffix=" (edited)" | ||||
|  | ||||
| #Whether to prefix messages from other bridges to mattermost with RemoteNickFormat | ||||
| #Useful if username overrides for incoming webhooks isn't enabled on the  | ||||
| #slack server. If you set PrefixMessagesWithNick to true, each message  | ||||
| @@ -361,7 +383,8 @@ IgnoreNicks="ircspammer1 ircspammer2" | ||||
| #OPTIONAL (default empty) | ||||
| RemoteNickFormat="[{PROTOCOL}] <{NICK}> " | ||||
|  | ||||
| #Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) | ||||
| #Enable to show users joins/parts from other bridges  | ||||
| #Only works hiding/show messages from irc and mattermost bridge for now | ||||
| #OPTIONAL (default false) | ||||
| ShowJoinPart=false | ||||
|  | ||||
| @@ -384,6 +407,14 @@ Token="Yourtokenhere" | ||||
| #REQUIRED | ||||
| Server="yourservername" | ||||
|  | ||||
| #Disable sending of edits to other bridges | ||||
| #OPTIONAL (default false) | ||||
| EditDisable=false | ||||
|  | ||||
| #Message to be appended to every edited message | ||||
| #OPTIONAL (default empty) | ||||
| EditSuffix=" (edited)" | ||||
|  | ||||
| #Nicks you want to ignore.  | ||||
| #Messages from those users will not be sent to other bridges. | ||||
| #OPTIONAL | ||||
| @@ -396,7 +427,8 @@ IgnoreNicks="ircspammer1 ircspammer2" | ||||
| #OPTIONAL (default empty) | ||||
| RemoteNickFormat="[{PROTOCOL}] <{NICK}> " | ||||
|  | ||||
| #Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) | ||||
| #Enable to show users joins/parts from other bridges  | ||||
| #Only works hiding/show messages from irc and mattermost bridge for now | ||||
| #OPTIONAL (default false) | ||||
| ShowJoinPart=false | ||||
|  | ||||
| @@ -419,6 +451,14 @@ Token="Yourtokenhere" | ||||
| #See https://core.telegram.org/bots/api#html-style | ||||
| MessageFormat="" | ||||
|  | ||||
| #Disable sending of edits to other bridges | ||||
| #OPTIONAL (default false) | ||||
| EditDisable=false | ||||
|  | ||||
| #Message to be appended to every edited message | ||||
| #OPTIONAL (default empty) | ||||
| EditSuffix=" (edited)" | ||||
|  | ||||
| #Nicks you want to ignore.  | ||||
| #Messages from those users will not be sent to other bridges. | ||||
| #OPTIONAL | ||||
| @@ -431,7 +471,8 @@ IgnoreNicks="spammer1 spammer2" | ||||
| #OPTIONAL (default empty) | ||||
| RemoteNickFormat="[{PROTOCOL}] <{NICK}> " | ||||
|  | ||||
| #Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) | ||||
| #Enable to show users joins/parts from other bridges  | ||||
| #Only works hiding/show messages from irc and mattermost bridge for now | ||||
| #OPTIONAL (default false) | ||||
| ShowJoinPart=false | ||||
|  | ||||
| @@ -488,7 +529,8 @@ IgnoreNicks="ircspammer1 ircspammer2" | ||||
| #OPTIONAL (default empty) | ||||
| RemoteNickFormat="[{PROTOCOL}] <{NICK}> " | ||||
|  | ||||
| #Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) | ||||
| #Enable to show users joins/parts from other bridges  | ||||
| #Only works hiding/show messages from irc and mattermost bridge for now | ||||
| #OPTIONAL (default false) | ||||
| ShowJoinPart=false | ||||
|  | ||||
| @@ -531,7 +573,8 @@ IgnoreNicks="spammer1 spammer2" | ||||
| #OPTIONAL (default empty) | ||||
| RemoteNickFormat="[{PROTOCOL}] <{NICK}> " | ||||
|  | ||||
| #Enable to show users joins/parts from other bridges (only from irc-bridge at the moment) | ||||
| #Enable to show users joins/parts from other bridges  | ||||
| #Only works hiding/show messages from irc and mattermost bridge for now | ||||
| #OPTIONAL (default false) | ||||
| ShowJoinPart=false | ||||
|  | ||||
| @@ -586,7 +629,7 @@ RemoteNickFormat="[{PROTOCOL}] <{NICK}> " | ||||
| # | ||||
|  | ||||
| [[gateway]] | ||||
| #OPTIONAL (not used for now) | ||||
| #REQUIRED and UNIQUE | ||||
| name="gateway1" | ||||
| #Enable enables this gateway | ||||
| ##OPTIONAL (default false) | ||||
| @@ -658,6 +701,7 @@ enable=true | ||||
| #channel testing on slack and vice versa. (and for the channel testing2 and testing3) | ||||
|  | ||||
| [[samechannelgateway]] | ||||
|    name="samechannel1" | ||||
|    enable = false | ||||
|    accounts = [ "mattermost.work","slack.hobby" ] | ||||
|    channels = [ "testing","testing2","testing3"] | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
| [mattermost] | ||||
|     [mattermost.work] | ||||
|     useAPI=true | ||||
|     #do not prefix it wit http:// or https:// | ||||
|     Server="yourmattermostserver.domain"  | ||||
|     Team="yourteam" | ||||
|     Login="yourlogin" | ||||
| @@ -30,3 +31,12 @@ enable=true | ||||
|     [[gateway.out]] | ||||
|     account="mattermost.work" | ||||
|     channel="off-topic" | ||||
|  | ||||
| #simpler config possible since v0.10.2 | ||||
| #[[gateway]] | ||||
| #name="gateway2" | ||||
| #enable=true | ||||
| #inout = [ | ||||
| #    { account="irc.freenode", channel="#testing", options={key="channelkey"}}, | ||||
| #    { account="mattermost.work", channel="off-topic" }, | ||||
| #] | ||||
|   | ||||
| @@ -4,9 +4,11 @@ import ( | ||||
| 	"crypto/tls" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"net/http/cookiejar" | ||||
| 	"net/url" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"time" | ||||
| @@ -34,6 +36,7 @@ type Message struct { | ||||
| 	Channel  string | ||||
| 	Username string | ||||
| 	Text     string | ||||
| 	Type     string | ||||
| } | ||||
|  | ||||
| type Team struct { | ||||
| @@ -47,19 +50,20 @@ type Team struct { | ||||
| type MMClient struct { | ||||
| 	sync.RWMutex | ||||
| 	*Credentials | ||||
| 	Team        *Team | ||||
| 	OtherTeams  []*Team | ||||
| 	Client      *model.Client | ||||
| 	User        *model.User | ||||
| 	Users       map[string]*model.User | ||||
| 	MessageChan chan *Message | ||||
| 	log         *log.Entry | ||||
| 	WsClient    *websocket.Conn | ||||
| 	WsQuit      bool | ||||
| 	WsAway      bool | ||||
| 	WsConnected bool | ||||
| 	WsSequence  int64 | ||||
| 	WsPingChan  chan *model.WebSocketResponse | ||||
| 	Team          *Team | ||||
| 	OtherTeams    []*Team | ||||
| 	Client        *model.Client | ||||
| 	User          *model.User | ||||
| 	Users         map[string]*model.User | ||||
| 	MessageChan   chan *Message | ||||
| 	log           *log.Entry | ||||
| 	WsClient      *websocket.Conn | ||||
| 	WsQuit        bool | ||||
| 	WsAway        bool | ||||
| 	WsConnected   bool | ||||
| 	WsSequence    int64 | ||||
| 	WsPingChan    chan *model.WebSocketResponse | ||||
| 	ServerVersion string | ||||
| } | ||||
|  | ||||
| func New(login, pass, team, server string) *MMClient { | ||||
| @@ -102,8 +106,27 @@ func (m *MMClient) Login() error { | ||||
| 	} | ||||
| 	// login to mattermost | ||||
| 	m.Client = model.NewClient(uriScheme + m.Credentials.Server) | ||||
| 	m.Client.HttpClient.Transport = &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: m.SkipTLSVerify}} | ||||
| 	m.Client.HttpClient.Transport = &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: m.SkipTLSVerify}, Proxy: http.ProxyFromEnvironment} | ||||
| 	m.Client.HttpClient.Timeout = time.Second * 10 | ||||
|  | ||||
| 	for { | ||||
| 		d := b.Duration() | ||||
| 		// bogus call to get the serverversion | ||||
| 		m.Client.GetClientProperties() | ||||
| 		if firstConnection && !supportedVersion(m.Client.ServerVersion) { | ||||
| 			return fmt.Errorf("unsupported mattermost version: %s", m.Client.ServerVersion) | ||||
| 		} | ||||
| 		m.ServerVersion = m.Client.ServerVersion | ||||
| 		if m.ServerVersion == "" { | ||||
| 			m.log.Debugf("Server not up yet, reconnecting in %s", d) | ||||
| 			time.Sleep(d) | ||||
| 		} else { | ||||
| 			m.log.Infof("Found version %s", m.ServerVersion) | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	b.Reset() | ||||
|  | ||||
| 	var myinfo *model.Result | ||||
| 	var appErr *model.AppError | ||||
| 	var logmsg = "trying login" | ||||
| @@ -159,11 +182,11 @@ func (m *MMClient) Login() error { | ||||
| 	m.Client.SetTeamId(m.Team.Id) | ||||
|  | ||||
| 	// setup websocket connection | ||||
| 	wsurl := wsScheme + m.Credentials.Server + model.API_URL_SUFFIX + "/users/websocket" | ||||
| 	wsurl := wsScheme + m.Credentials.Server + model.API_URL_SUFFIX_V3 + "/users/websocket" | ||||
| 	header := http.Header{} | ||||
| 	header.Set(model.HEADER_AUTH, "BEARER "+m.Client.AuthToken) | ||||
|  | ||||
| 	m.log.Debug("WsClient: making connection") | ||||
| 	m.log.Debugf("WsClient: making connection: %s", wsurl) | ||||
| 	for { | ||||
| 		wsDialer := &websocket.Dialer{Proxy: http.ProxyFromEnvironment, TLSClientConfig: &tls.Config{InsecureSkipVerify: m.SkipTLSVerify}} | ||||
| 		m.WsClient, _, err = wsDialer.Dial(wsurl, header) | ||||
| @@ -177,6 +200,7 @@ func (m *MMClient) Login() error { | ||||
| 	} | ||||
| 	b.Reset() | ||||
|  | ||||
| 	m.log.Debug("WsClient: connected") | ||||
| 	m.WsSequence = 1 | ||||
| 	m.WsPingChan = make(chan *model.WebSocketResponse) | ||||
| 	// only start to parse WS messages when login is completely done | ||||
| @@ -238,7 +262,7 @@ func (m *MMClient) WsReceiver() { | ||||
|  | ||||
| func (m *MMClient) parseMessage(rmsg *Message) { | ||||
| 	switch rmsg.Raw.Event { | ||||
| 	case model.WEBSOCKET_EVENT_POSTED: | ||||
| 	case model.WEBSOCKET_EVENT_POSTED, model.WEBSOCKET_EVENT_POST_EDITED: | ||||
| 		m.parseActionPost(rmsg) | ||||
| 		/* | ||||
| 			case model.ACTION_USER_REMOVED: | ||||
| @@ -266,7 +290,18 @@ func (m *MMClient) parseActionPost(rmsg *Message) { | ||||
| 	} | ||||
| 	rmsg.Username = m.GetUser(data.UserId).Username | ||||
| 	rmsg.Channel = m.GetChannelName(data.ChannelId) | ||||
| 	rmsg.Team = m.GetTeamName(rmsg.Raw.Data["team_id"].(string)) | ||||
| 	rmsg.Type = data.Type | ||||
| 	teamid, _ := rmsg.Raw.Data["team_id"].(string) | ||||
| 	// edit messsages have no team_id for some reason | ||||
| 	if teamid == "" { | ||||
| 		// we can find the team_id from the channelid | ||||
| 		result, _ := m.Client.GetChannel(data.ChannelId, "") | ||||
| 		teamid = result.Data.(*model.ChannelData).Channel.TeamId | ||||
| 		rmsg.Raw.Data["team_id"] = teamid | ||||
| 	} | ||||
| 	if teamid != "" { | ||||
| 		rmsg.Team = m.GetTeamName(teamid) | ||||
| 	} | ||||
| 	// direct message | ||||
| 	if rmsg.Raw.Data["channel_type"] == "D" { | ||||
| 		rmsg.Channel = m.GetUser(data.UserId).Username | ||||
| @@ -292,7 +327,12 @@ func (m *MMClient) UpdateChannels() error { | ||||
| 	if err != nil { | ||||
| 		return errors.New(err.DetailedError) | ||||
| 	} | ||||
| 	mmchannels2, err := m.Client.GetMoreChannels("") | ||||
| 	var mmchannels2 *model.Result | ||||
| 	if m.mmVersion() >= 3.8 { | ||||
| 		mmchannels2, err = m.Client.GetMoreChannelsPage(0, 5000) | ||||
| 	} else { | ||||
| 		mmchannels2, err = m.Client.GetMoreChannels("") | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return errors.New(err.DetailedError) | ||||
| 	} | ||||
| @@ -427,6 +467,14 @@ func (m *MMClient) UpdateChannelHeader(channelId string, header string) { | ||||
|  | ||||
| func (m *MMClient) UpdateLastViewed(channelId string) { | ||||
| 	m.log.Debugf("posting lastview %#v", channelId) | ||||
| 	if m.mmVersion() >= 3.8 { | ||||
| 		view := model.ChannelView{ChannelId: channelId} | ||||
| 		res, _ := m.Client.ViewChannel(view) | ||||
| 		if res == false { | ||||
| 			m.log.Errorf("ChannelView update for %s failed", channelId) | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
| 	_, err := m.Client.UpdateLastViewedAt(channelId, true) | ||||
| 	if err != nil { | ||||
| 		m.log.Error(err) | ||||
| @@ -628,6 +676,7 @@ func (m *MMClient) StatusLoop() { | ||||
| 				m.Logout() | ||||
| 				m.WsQuit = false | ||||
| 				m.Login() | ||||
| 				go m.WsReceiver() | ||||
| 			} | ||||
| 		} | ||||
| 		time.Sleep(time.Second * 60) | ||||
| @@ -659,7 +708,11 @@ func (m *MMClient) initUser() error { | ||||
| 			return errors.New(err.DetailedError) | ||||
| 		} | ||||
| 		t.Channels = mmchannels.Data.(*model.ChannelList) | ||||
| 		mmchannels, err = m.Client.GetMoreChannels("") | ||||
| 		if m.mmVersion() >= 3.8 { | ||||
| 			mmchannels, err = m.Client.GetMoreChannelsPage(0, 5000) | ||||
| 		} else { | ||||
| 			mmchannels, err = m.Client.GetMoreChannels("") | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			return errors.New(err.DetailedError) | ||||
| 		} | ||||
| @@ -687,3 +740,19 @@ func (m *MMClient) sendWSRequest(action string, data map[string]interface{}) err | ||||
| 	m.WsClient.WriteJSON(req) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (m *MMClient) mmVersion() float64 { | ||||
| 	v, _ := strconv.ParseFloat(m.ServerVersion[0:3], 64) | ||||
| 	return v | ||||
| } | ||||
|  | ||||
| func supportedVersion(version string) bool { | ||||
| 	if strings.HasPrefix(version, "3.5.0") || | ||||
| 		strings.HasPrefix(version, "3.6.0") || | ||||
| 		strings.HasPrefix(version, "3.7.0") || | ||||
| 		strings.HasPrefix(version, "3.8.0") || | ||||
| 		strings.HasPrefix(version, "3.9.0") { | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/BurntSushi/toml/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/BurntSushi/toml/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -4,7 +4,7 @@ files via reflection. There is also support for delaying decoding with | ||||
| the Primitive type, and querying the set of keys in a TOML document with the | ||||
| MetaData type. | ||||
|  | ||||
| The specification implemented: https://github.com/mojombo/toml | ||||
| The specification implemented: https://github.com/toml-lang/toml | ||||
|  | ||||
| The sub-command github.com/BurntSushi/toml/cmd/tomlv can be used to verify | ||||
| whether a file is a valid TOML document. It can also be used to print the | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/BurntSushi/toml/encode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/BurntSushi/toml/encode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -241,7 +241,7 @@ func (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) { | ||||
| func (enc *Encoder) eTable(key Key, rv reflect.Value) { | ||||
| 	panicIfInvalidKey(key) | ||||
| 	if len(key) == 1 { | ||||
| 		// Output an extra new line between top-level tables. | ||||
| 		// Output an extra newline between top-level tables. | ||||
| 		// (The newline isn't written if nothing else has been written though.) | ||||
| 		enc.newline() | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										259
									
								
								vendor/github.com/BurntSushi/toml/lex.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										259
									
								
								vendor/github.com/BurntSushi/toml/lex.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -30,24 +30,28 @@ const ( | ||||
| 	itemArrayTableEnd | ||||
| 	itemKeyStart | ||||
| 	itemCommentStart | ||||
| 	itemInlineTableStart | ||||
| 	itemInlineTableEnd | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	eof             = 0 | ||||
| 	tableStart      = '[' | ||||
| 	tableEnd        = ']' | ||||
| 	arrayTableStart = '[' | ||||
| 	arrayTableEnd   = ']' | ||||
| 	tableSep        = '.' | ||||
| 	keySep          = '=' | ||||
| 	arrayStart      = '[' | ||||
| 	arrayEnd        = ']' | ||||
| 	arrayValTerm    = ',' | ||||
| 	commentStart    = '#' | ||||
| 	stringStart     = '"' | ||||
| 	stringEnd       = '"' | ||||
| 	rawStringStart  = '\'' | ||||
| 	rawStringEnd    = '\'' | ||||
| 	eof              = 0 | ||||
| 	comma            = ',' | ||||
| 	tableStart       = '[' | ||||
| 	tableEnd         = ']' | ||||
| 	arrayTableStart  = '[' | ||||
| 	arrayTableEnd    = ']' | ||||
| 	tableSep         = '.' | ||||
| 	keySep           = '=' | ||||
| 	arrayStart       = '[' | ||||
| 	arrayEnd         = ']' | ||||
| 	commentStart     = '#' | ||||
| 	stringStart      = '"' | ||||
| 	stringEnd        = '"' | ||||
| 	rawStringStart   = '\'' | ||||
| 	rawStringEnd     = '\'' | ||||
| 	inlineTableStart = '{' | ||||
| 	inlineTableEnd   = '}' | ||||
| ) | ||||
|  | ||||
| type stateFn func(lx *lexer) stateFn | ||||
| @@ -56,11 +60,18 @@ type lexer struct { | ||||
| 	input string | ||||
| 	start int | ||||
| 	pos   int | ||||
| 	width int | ||||
| 	line  int | ||||
| 	state stateFn | ||||
| 	items chan item | ||||
|  | ||||
| 	// Allow for backing up up to three runes. | ||||
| 	// This is necessary because TOML contains 3-rune tokens (""" and '''). | ||||
| 	prevWidths [3]int | ||||
| 	nprev      int // how many of prevWidths are in use | ||||
| 	// If we emit an eof, we can still back up, but it is not OK to call | ||||
| 	// next again. | ||||
| 	atEOF bool | ||||
|  | ||||
| 	// A stack of state functions used to maintain context. | ||||
| 	// The idea is to reuse parts of the state machine in various places. | ||||
| 	// For example, values can appear at the top level or within arbitrarily | ||||
| @@ -88,7 +99,7 @@ func (lx *lexer) nextItem() item { | ||||
|  | ||||
| func lex(input string) *lexer { | ||||
| 	lx := &lexer{ | ||||
| 		input: input + "\n", | ||||
| 		input: input, | ||||
| 		state: lexTop, | ||||
| 		line:  1, | ||||
| 		items: make(chan item, 10), | ||||
| @@ -103,7 +114,7 @@ func (lx *lexer) push(state stateFn) { | ||||
|  | ||||
| func (lx *lexer) pop() stateFn { | ||||
| 	if len(lx.stack) == 0 { | ||||
| 		return lx.errorf("BUG in lexer: no states to pop.") | ||||
| 		return lx.errorf("BUG in lexer: no states to pop") | ||||
| 	} | ||||
| 	last := lx.stack[len(lx.stack)-1] | ||||
| 	lx.stack = lx.stack[0 : len(lx.stack)-1] | ||||
| @@ -125,16 +136,25 @@ func (lx *lexer) emitTrim(typ itemType) { | ||||
| } | ||||
|  | ||||
| func (lx *lexer) next() (r rune) { | ||||
| 	if lx.atEOF { | ||||
| 		panic("next called after EOF") | ||||
| 	} | ||||
| 	if lx.pos >= len(lx.input) { | ||||
| 		lx.width = 0 | ||||
| 		lx.atEOF = true | ||||
| 		return eof | ||||
| 	} | ||||
|  | ||||
| 	if lx.input[lx.pos] == '\n' { | ||||
| 		lx.line++ | ||||
| 	} | ||||
| 	r, lx.width = utf8.DecodeRuneInString(lx.input[lx.pos:]) | ||||
| 	lx.pos += lx.width | ||||
| 	lx.prevWidths[2] = lx.prevWidths[1] | ||||
| 	lx.prevWidths[1] = lx.prevWidths[0] | ||||
| 	if lx.nprev < 3 { | ||||
| 		lx.nprev++ | ||||
| 	} | ||||
| 	r, w := utf8.DecodeRuneInString(lx.input[lx.pos:]) | ||||
| 	lx.prevWidths[0] = w | ||||
| 	lx.pos += w | ||||
| 	return r | ||||
| } | ||||
|  | ||||
| @@ -143,9 +163,20 @@ func (lx *lexer) ignore() { | ||||
| 	lx.start = lx.pos | ||||
| } | ||||
|  | ||||
| // backup steps back one rune. Can be called only once per call of next. | ||||
| // backup steps back one rune. Can be called only twice between calls to next. | ||||
| func (lx *lexer) backup() { | ||||
| 	lx.pos -= lx.width | ||||
| 	if lx.atEOF { | ||||
| 		lx.atEOF = false | ||||
| 		return | ||||
| 	} | ||||
| 	if lx.nprev < 1 { | ||||
| 		panic("backed up too far") | ||||
| 	} | ||||
| 	w := lx.prevWidths[0] | ||||
| 	lx.prevWidths[0] = lx.prevWidths[1] | ||||
| 	lx.prevWidths[1] = lx.prevWidths[2] | ||||
| 	lx.nprev-- | ||||
| 	lx.pos -= w | ||||
| 	if lx.pos < len(lx.input) && lx.input[lx.pos] == '\n' { | ||||
| 		lx.line-- | ||||
| 	} | ||||
| @@ -182,7 +213,7 @@ func (lx *lexer) skip(pred func(rune) bool) { | ||||
|  | ||||
| // errorf stops all lexing by emitting an error and returning `nil`. | ||||
| // Note that any value that is a character is escaped if it's a special | ||||
| // character (new lines, tabs, etc.). | ||||
| // character (newlines, tabs, etc.). | ||||
| func (lx *lexer) errorf(format string, values ...interface{}) stateFn { | ||||
| 	lx.items <- item{ | ||||
| 		itemError, | ||||
| @@ -198,7 +229,6 @@ func lexTop(lx *lexer) stateFn { | ||||
| 	if isWhitespace(r) || isNL(r) { | ||||
| 		return lexSkip(lx, lexTop) | ||||
| 	} | ||||
|  | ||||
| 	switch r { | ||||
| 	case commentStart: | ||||
| 		lx.push(lexTop) | ||||
| @@ -207,7 +237,7 @@ func lexTop(lx *lexer) stateFn { | ||||
| 		return lexTableStart | ||||
| 	case eof: | ||||
| 		if lx.pos > lx.start { | ||||
| 			return lx.errorf("Unexpected EOF.") | ||||
| 			return lx.errorf("unexpected EOF") | ||||
| 		} | ||||
| 		lx.emit(itemEOF) | ||||
| 		return nil | ||||
| @@ -222,12 +252,12 @@ func lexTop(lx *lexer) stateFn { | ||||
|  | ||||
| // lexTopEnd is entered whenever a top-level item has been consumed. (A value | ||||
| // or a table.) It must see only whitespace, and will turn back to lexTop | ||||
| // upon a new line. If it sees EOF, it will quit the lexer successfully. | ||||
| // upon a newline. If it sees EOF, it will quit the lexer successfully. | ||||
| func lexTopEnd(lx *lexer) stateFn { | ||||
| 	r := lx.next() | ||||
| 	switch { | ||||
| 	case r == commentStart: | ||||
| 		// a comment will read to a new line for us. | ||||
| 		// a comment will read to a newline for us. | ||||
| 		lx.push(lexTop) | ||||
| 		return lexCommentStart | ||||
| 	case isWhitespace(r): | ||||
| @@ -236,11 +266,11 @@ func lexTopEnd(lx *lexer) stateFn { | ||||
| 		lx.ignore() | ||||
| 		return lexTop | ||||
| 	case r == eof: | ||||
| 		lx.ignore() | ||||
| 		return lexTop | ||||
| 		lx.emit(itemEOF) | ||||
| 		return nil | ||||
| 	} | ||||
| 	return lx.errorf("Expected a top-level item to end with a new line, "+ | ||||
| 		"comment or EOF, but got %q instead.", r) | ||||
| 	return lx.errorf("expected a top-level item to end with a newline, "+ | ||||
| 		"comment, or EOF, but got %q instead", r) | ||||
| } | ||||
|  | ||||
| // lexTable lexes the beginning of a table. Namely, it makes sure that | ||||
| @@ -267,8 +297,8 @@ func lexTableEnd(lx *lexer) stateFn { | ||||
|  | ||||
| func lexArrayTableEnd(lx *lexer) stateFn { | ||||
| 	if r := lx.next(); r != arrayTableEnd { | ||||
| 		return lx.errorf("Expected end of table array name delimiter %q, "+ | ||||
| 			"but got %q instead.", arrayTableEnd, r) | ||||
| 		return lx.errorf("expected end of table array name delimiter %q, "+ | ||||
| 			"but got %q instead", arrayTableEnd, r) | ||||
| 	} | ||||
| 	lx.emit(itemArrayTableEnd) | ||||
| 	return lexTopEnd | ||||
| @@ -278,11 +308,11 @@ func lexTableNameStart(lx *lexer) stateFn { | ||||
| 	lx.skip(isWhitespace) | ||||
| 	switch r := lx.peek(); { | ||||
| 	case r == tableEnd || r == eof: | ||||
| 		return lx.errorf("Unexpected end of table name. (Table names cannot " + | ||||
| 			"be empty.)") | ||||
| 		return lx.errorf("unexpected end of table name " + | ||||
| 			"(table names cannot be empty)") | ||||
| 	case r == tableSep: | ||||
| 		return lx.errorf("Unexpected table separator. (Table names cannot " + | ||||
| 			"be empty.)") | ||||
| 		return lx.errorf("unexpected table separator " + | ||||
| 			"(table names cannot be empty)") | ||||
| 	case r == stringStart || r == rawStringStart: | ||||
| 		lx.ignore() | ||||
| 		lx.push(lexTableNameEnd) | ||||
| @@ -317,8 +347,8 @@ func lexTableNameEnd(lx *lexer) stateFn { | ||||
| 	case r == tableEnd: | ||||
| 		return lx.pop() | ||||
| 	default: | ||||
| 		return lx.errorf("Expected '.' or ']' to end table name, but got %q "+ | ||||
| 			"instead.", r) | ||||
| 		return lx.errorf("expected '.' or ']' to end table name, "+ | ||||
| 			"but got %q instead", r) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -328,7 +358,7 @@ func lexKeyStart(lx *lexer) stateFn { | ||||
| 	r := lx.peek() | ||||
| 	switch { | ||||
| 	case r == keySep: | ||||
| 		return lx.errorf("Unexpected key separator %q.", keySep) | ||||
| 		return lx.errorf("unexpected key separator %q", keySep) | ||||
| 	case isWhitespace(r) || isNL(r): | ||||
| 		lx.next() | ||||
| 		return lexSkip(lx, lexKeyStart) | ||||
| @@ -359,7 +389,7 @@ func lexBareKey(lx *lexer) stateFn { | ||||
| 		lx.emit(itemText) | ||||
| 		return lexKeyEnd | ||||
| 	default: | ||||
| 		return lx.errorf("Bare keys cannot contain %q.", r) | ||||
| 		return lx.errorf("bare keys cannot contain %q", r) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -372,7 +402,7 @@ func lexKeyEnd(lx *lexer) stateFn { | ||||
| 	case isWhitespace(r): | ||||
| 		return lexSkip(lx, lexKeyEnd) | ||||
| 	default: | ||||
| 		return lx.errorf("Expected key separator %q, but got %q instead.", | ||||
| 		return lx.errorf("expected key separator %q, but got %q instead", | ||||
| 			keySep, r) | ||||
| 	} | ||||
| } | ||||
| @@ -381,9 +411,8 @@ func lexKeyEnd(lx *lexer) stateFn { | ||||
| // lexValue will ignore whitespace. | ||||
| // After a value is lexed, the last state on the next is popped and returned. | ||||
| func lexValue(lx *lexer) stateFn { | ||||
| 	// We allow whitespace to precede a value, but NOT new lines. | ||||
| 	// In array syntax, the array states are responsible for ignoring new | ||||
| 	// lines. | ||||
| 	// We allow whitespace to precede a value, but NOT newlines. | ||||
| 	// In array syntax, the array states are responsible for ignoring newlines. | ||||
| 	r := lx.next() | ||||
| 	switch { | ||||
| 	case isWhitespace(r): | ||||
| @@ -397,6 +426,10 @@ func lexValue(lx *lexer) stateFn { | ||||
| 		lx.ignore() | ||||
| 		lx.emit(itemArray) | ||||
| 		return lexArrayValue | ||||
| 	case inlineTableStart: | ||||
| 		lx.ignore() | ||||
| 		lx.emit(itemInlineTableStart) | ||||
| 		return lexInlineTableValue | ||||
| 	case stringStart: | ||||
| 		if lx.accept(stringStart) { | ||||
| 			if lx.accept(stringStart) { | ||||
| @@ -420,7 +453,7 @@ func lexValue(lx *lexer) stateFn { | ||||
| 	case '+', '-': | ||||
| 		return lexNumberStart | ||||
| 	case '.': // special error case, be kind to users | ||||
| 		return lx.errorf("Floats must start with a digit, not '.'.") | ||||
| 		return lx.errorf("floats must start with a digit, not '.'") | ||||
| 	} | ||||
| 	if unicode.IsLetter(r) { | ||||
| 		// Be permissive here; lexBool will give a nice error if the | ||||
| @@ -430,11 +463,11 @@ func lexValue(lx *lexer) stateFn { | ||||
| 		lx.backup() | ||||
| 		return lexBool | ||||
| 	} | ||||
| 	return lx.errorf("Expected value but found %q instead.", r) | ||||
| 	return lx.errorf("expected value but found %q instead", r) | ||||
| } | ||||
|  | ||||
| // lexArrayValue consumes one value in an array. It assumes that '[' or ',' | ||||
| // have already been consumed. All whitespace and new lines are ignored. | ||||
| // have already been consumed. All whitespace and newlines are ignored. | ||||
| func lexArrayValue(lx *lexer) stateFn { | ||||
| 	r := lx.next() | ||||
| 	switch { | ||||
| @@ -443,10 +476,11 @@ func lexArrayValue(lx *lexer) stateFn { | ||||
| 	case r == commentStart: | ||||
| 		lx.push(lexArrayValue) | ||||
| 		return lexCommentStart | ||||
| 	case r == arrayValTerm: | ||||
| 		return lx.errorf("Unexpected array value terminator %q.", | ||||
| 			arrayValTerm) | ||||
| 	case r == comma: | ||||
| 		return lx.errorf("unexpected comma") | ||||
| 	case r == arrayEnd: | ||||
| 		// NOTE(caleb): The spec isn't clear about whether you can have | ||||
| 		// a trailing comma or not, so we'll allow it. | ||||
| 		return lexArrayEnd | ||||
| 	} | ||||
|  | ||||
| @@ -455,8 +489,9 @@ func lexArrayValue(lx *lexer) stateFn { | ||||
| 	return lexValue | ||||
| } | ||||
|  | ||||
| // lexArrayValueEnd consumes the cruft between values of an array. Namely, | ||||
| // it ignores whitespace and expects either a ',' or a ']'. | ||||
| // lexArrayValueEnd consumes everything between the end of an array value and | ||||
| // the next value (or the end of the array): it ignores whitespace and newlines | ||||
| // and expects either a ',' or a ']'. | ||||
| func lexArrayValueEnd(lx *lexer) stateFn { | ||||
| 	r := lx.next() | ||||
| 	switch { | ||||
| @@ -465,31 +500,88 @@ func lexArrayValueEnd(lx *lexer) stateFn { | ||||
| 	case r == commentStart: | ||||
| 		lx.push(lexArrayValueEnd) | ||||
| 		return lexCommentStart | ||||
| 	case r == arrayValTerm: | ||||
| 	case r == comma: | ||||
| 		lx.ignore() | ||||
| 		return lexArrayValue // move on to the next value | ||||
| 	case r == arrayEnd: | ||||
| 		return lexArrayEnd | ||||
| 	} | ||||
| 	return lx.errorf("Expected an array value terminator %q or an array "+ | ||||
| 		"terminator %q, but got %q instead.", arrayValTerm, arrayEnd, r) | ||||
| 	return lx.errorf( | ||||
| 		"expected a comma or array terminator %q, but got %q instead", | ||||
| 		arrayEnd, r, | ||||
| 	) | ||||
| } | ||||
|  | ||||
| // lexArrayEnd finishes the lexing of an array. It assumes that a ']' has | ||||
| // just been consumed. | ||||
| // lexArrayEnd finishes the lexing of an array. | ||||
| // It assumes that a ']' has just been consumed. | ||||
| func lexArrayEnd(lx *lexer) stateFn { | ||||
| 	lx.ignore() | ||||
| 	lx.emit(itemArrayEnd) | ||||
| 	return lx.pop() | ||||
| } | ||||
|  | ||||
| // lexInlineTableValue consumes one key/value pair in an inline table. | ||||
| // It assumes that '{' or ',' have already been consumed. Whitespace is ignored. | ||||
| func lexInlineTableValue(lx *lexer) stateFn { | ||||
| 	r := lx.next() | ||||
| 	switch { | ||||
| 	case isWhitespace(r): | ||||
| 		return lexSkip(lx, lexInlineTableValue) | ||||
| 	case isNL(r): | ||||
| 		return lx.errorf("newlines not allowed within inline tables") | ||||
| 	case r == commentStart: | ||||
| 		lx.push(lexInlineTableValue) | ||||
| 		return lexCommentStart | ||||
| 	case r == comma: | ||||
| 		return lx.errorf("unexpected comma") | ||||
| 	case r == inlineTableEnd: | ||||
| 		return lexInlineTableEnd | ||||
| 	} | ||||
| 	lx.backup() | ||||
| 	lx.push(lexInlineTableValueEnd) | ||||
| 	return lexKeyStart | ||||
| } | ||||
|  | ||||
| // lexInlineTableValueEnd consumes everything between the end of an inline table | ||||
| // key/value pair and the next pair (or the end of the table): | ||||
| // it ignores whitespace and expects either a ',' or a '}'. | ||||
| func lexInlineTableValueEnd(lx *lexer) stateFn { | ||||
| 	r := lx.next() | ||||
| 	switch { | ||||
| 	case isWhitespace(r): | ||||
| 		return lexSkip(lx, lexInlineTableValueEnd) | ||||
| 	case isNL(r): | ||||
| 		return lx.errorf("newlines not allowed within inline tables") | ||||
| 	case r == commentStart: | ||||
| 		lx.push(lexInlineTableValueEnd) | ||||
| 		return lexCommentStart | ||||
| 	case r == comma: | ||||
| 		lx.ignore() | ||||
| 		return lexInlineTableValue | ||||
| 	case r == inlineTableEnd: | ||||
| 		return lexInlineTableEnd | ||||
| 	} | ||||
| 	return lx.errorf("expected a comma or an inline table terminator %q, "+ | ||||
| 		"but got %q instead", inlineTableEnd, r) | ||||
| } | ||||
|  | ||||
| // lexInlineTableEnd finishes the lexing of an inline table. | ||||
| // It assumes that a '}' has just been consumed. | ||||
| func lexInlineTableEnd(lx *lexer) stateFn { | ||||
| 	lx.ignore() | ||||
| 	lx.emit(itemInlineTableEnd) | ||||
| 	return lx.pop() | ||||
| } | ||||
|  | ||||
| // lexString consumes the inner contents of a string. It assumes that the | ||||
| // beginning '"' has already been consumed and ignored. | ||||
| func lexString(lx *lexer) stateFn { | ||||
| 	r := lx.next() | ||||
| 	switch { | ||||
| 	case r == eof: | ||||
| 		return lx.errorf("unexpected EOF") | ||||
| 	case isNL(r): | ||||
| 		return lx.errorf("Strings cannot contain new lines.") | ||||
| 		return lx.errorf("strings cannot contain newlines") | ||||
| 	case r == '\\': | ||||
| 		lx.push(lexString) | ||||
| 		return lexStringEscape | ||||
| @@ -506,11 +598,12 @@ func lexString(lx *lexer) stateFn { | ||||
| // lexMultilineString consumes the inner contents of a string. It assumes that | ||||
| // the beginning '"""' has already been consumed and ignored. | ||||
| func lexMultilineString(lx *lexer) stateFn { | ||||
| 	r := lx.next() | ||||
| 	switch { | ||||
| 	case r == '\\': | ||||
| 	switch lx.next() { | ||||
| 	case eof: | ||||
| 		return lx.errorf("unexpected EOF") | ||||
| 	case '\\': | ||||
| 		return lexMultilineStringEscape | ||||
| 	case r == stringEnd: | ||||
| 	case stringEnd: | ||||
| 		if lx.accept(stringEnd) { | ||||
| 			if lx.accept(stringEnd) { | ||||
| 				lx.backup() | ||||
| @@ -534,8 +627,10 @@ func lexMultilineString(lx *lexer) stateFn { | ||||
| func lexRawString(lx *lexer) stateFn { | ||||
| 	r := lx.next() | ||||
| 	switch { | ||||
| 	case r == eof: | ||||
| 		return lx.errorf("unexpected EOF") | ||||
| 	case isNL(r): | ||||
| 		return lx.errorf("Strings cannot contain new lines.") | ||||
| 		return lx.errorf("strings cannot contain newlines") | ||||
| 	case r == rawStringEnd: | ||||
| 		lx.backup() | ||||
| 		lx.emit(itemRawString) | ||||
| @@ -547,12 +642,13 @@ func lexRawString(lx *lexer) stateFn { | ||||
| } | ||||
|  | ||||
| // lexMultilineRawString consumes a raw string. Nothing can be escaped in such | ||||
| // a string. It assumes that the beginning "'" has already been consumed and | ||||
| // a string. It assumes that the beginning "'''" has already been consumed and | ||||
| // ignored. | ||||
| func lexMultilineRawString(lx *lexer) stateFn { | ||||
| 	r := lx.next() | ||||
| 	switch { | ||||
| 	case r == rawStringEnd: | ||||
| 	switch lx.next() { | ||||
| 	case eof: | ||||
| 		return lx.errorf("unexpected EOF") | ||||
| 	case rawStringEnd: | ||||
| 		if lx.accept(rawStringEnd) { | ||||
| 			if lx.accept(rawStringEnd) { | ||||
| 				lx.backup() | ||||
| @@ -605,10 +701,9 @@ func lexStringEscape(lx *lexer) stateFn { | ||||
| 	case 'U': | ||||
| 		return lexLongUnicodeEscape | ||||
| 	} | ||||
| 	return lx.errorf("Invalid escape character %q. Only the following "+ | ||||
| 	return lx.errorf("invalid escape character %q; only the following "+ | ||||
| 		"escape characters are allowed: "+ | ||||
| 		"\\b, \\t, \\n, \\f, \\r, \\\", \\/, \\\\, "+ | ||||
| 		"\\uXXXX and \\UXXXXXXXX.", r) | ||||
| 		`\b, \t, \n, \f, \r, \", \\, \uXXXX, and \UXXXXXXXX`, r) | ||||
| } | ||||
|  | ||||
| func lexShortUnicodeEscape(lx *lexer) stateFn { | ||||
| @@ -616,8 +711,8 @@ func lexShortUnicodeEscape(lx *lexer) stateFn { | ||||
| 	for i := 0; i < 4; i++ { | ||||
| 		r = lx.next() | ||||
| 		if !isHexadecimal(r) { | ||||
| 			return lx.errorf("Expected four hexadecimal digits after '\\u', "+ | ||||
| 				"but got '%s' instead.", lx.current()) | ||||
| 			return lx.errorf(`expected four hexadecimal digits after '\u', `+ | ||||
| 				"but got %q instead", lx.current()) | ||||
| 		} | ||||
| 	} | ||||
| 	return lx.pop() | ||||
| @@ -628,8 +723,8 @@ func lexLongUnicodeEscape(lx *lexer) stateFn { | ||||
| 	for i := 0; i < 8; i++ { | ||||
| 		r = lx.next() | ||||
| 		if !isHexadecimal(r) { | ||||
| 			return lx.errorf("Expected eight hexadecimal digits after '\\U', "+ | ||||
| 				"but got '%s' instead.", lx.current()) | ||||
| 			return lx.errorf(`expected eight hexadecimal digits after '\U', `+ | ||||
| 				"but got %q instead", lx.current()) | ||||
| 		} | ||||
| 	} | ||||
| 	return lx.pop() | ||||
| @@ -647,9 +742,9 @@ func lexNumberOrDateStart(lx *lexer) stateFn { | ||||
| 	case 'e', 'E': | ||||
| 		return lexFloat | ||||
| 	case '.': | ||||
| 		return lx.errorf("Floats must start with a digit, not '.'.") | ||||
| 		return lx.errorf("floats must start with a digit, not '.'") | ||||
| 	} | ||||
| 	return lx.errorf("Expected a digit but got %q.", r) | ||||
| 	return lx.errorf("expected a digit but got %q", r) | ||||
| } | ||||
|  | ||||
| // lexNumberOrDate consumes either an integer, float or datetime. | ||||
| @@ -697,9 +792,9 @@ func lexNumberStart(lx *lexer) stateFn { | ||||
| 	r := lx.next() | ||||
| 	if !isDigit(r) { | ||||
| 		if r == '.' { | ||||
| 			return lx.errorf("Floats must start with a digit, not '.'.") | ||||
| 			return lx.errorf("floats must start with a digit, not '.'") | ||||
| 		} | ||||
| 		return lx.errorf("Expected a digit but got %q.", r) | ||||
| 		return lx.errorf("expected a digit but got %q", r) | ||||
| 	} | ||||
| 	return lexNumber | ||||
| } | ||||
| @@ -757,7 +852,7 @@ func lexBool(lx *lexer) stateFn { | ||||
| 		lx.emit(itemBool) | ||||
| 		return lx.pop() | ||||
| 	} | ||||
| 	return lx.errorf("Expected value but found %q instead.", s) | ||||
| 	return lx.errorf("expected value but found %q instead", s) | ||||
| } | ||||
|  | ||||
| // lexCommentStart begins the lexing of a comment. It will emit | ||||
| @@ -769,7 +864,7 @@ func lexCommentStart(lx *lexer) stateFn { | ||||
| } | ||||
|  | ||||
| // lexComment lexes an entire comment. It assumes that '#' has been consumed. | ||||
| // It will consume *up to* the first new line character, and pass control | ||||
| // It will consume *up to* the first newline character, and pass control | ||||
| // back to the last state on the stack. | ||||
| func lexComment(lx *lexer) stateFn { | ||||
| 	r := lx.peek() | ||||
|   | ||||
							
								
								
									
										35
									
								
								vendor/github.com/BurntSushi/toml/parse.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								vendor/github.com/BurntSushi/toml/parse.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -269,6 +269,41 @@ func (p *parser) value(it item) (interface{}, tomlType) { | ||||
| 			types = append(types, typ) | ||||
| 		} | ||||
| 		return array, p.typeOfArray(types) | ||||
| 	case itemInlineTableStart: | ||||
| 		var ( | ||||
| 			hash         = make(map[string]interface{}) | ||||
| 			outerContext = p.context | ||||
| 			outerKey     = p.currentKey | ||||
| 		) | ||||
|  | ||||
| 		p.context = append(p.context, p.currentKey) | ||||
| 		p.currentKey = "" | ||||
| 		for it := p.next(); it.typ != itemInlineTableEnd; it = p.next() { | ||||
| 			if it.typ != itemKeyStart { | ||||
| 				p.bug("Expected key start but instead found %q, around line %d", | ||||
| 					it.val, p.approxLine) | ||||
| 			} | ||||
| 			if it.typ == itemCommentStart { | ||||
| 				p.expect(itemText) | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			// retrieve key | ||||
| 			k := p.next() | ||||
| 			p.approxLine = k.line | ||||
| 			kname := p.keyString(k) | ||||
|  | ||||
| 			// retrieve value | ||||
| 			p.currentKey = kname | ||||
| 			val, typ := p.value(p.next()) | ||||
| 			// make sure we keep metadata up to date | ||||
| 			p.setType(kname, typ) | ||||
| 			p.ordered = append(p.ordered, p.context.add(p.currentKey)) | ||||
| 			hash[kname] = val | ||||
| 		} | ||||
| 		p.context = outerContext | ||||
| 		p.currentKey = outerKey | ||||
| 		return hash, tomlHash | ||||
| 	} | ||||
| 	p.bug("Unexpected value type: %s", it.typ) | ||||
| 	panic("unreachable") | ||||
|   | ||||
							
								
								
									
										64
									
								
								vendor/github.com/Sirupsen/logrus/alt_exit.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/Sirupsen/logrus/alt_exit.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| package logrus | ||||
|  | ||||
| // The following code was sourced and modified from the | ||||
| // https://github.com/tebeka/atexit package governed by the following license: | ||||
| // | ||||
| // Copyright (c) 2012 Miki Tebeka <miki.tebeka@gmail.com>. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy of | ||||
| // this software and associated documentation files (the "Software"), to deal in | ||||
| // the Software without restriction, including without limitation the rights to | ||||
| // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||||
| // the Software, and to permit persons to whom the Software is furnished to do so, | ||||
| // subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in all | ||||
| // copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||||
| // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||||
| // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||||
| // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||
| // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| ) | ||||
|  | ||||
| var handlers = []func(){} | ||||
|  | ||||
| func runHandler(handler func()) { | ||||
| 	defer func() { | ||||
| 		if err := recover(); err != nil { | ||||
| 			fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err) | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	handler() | ||||
| } | ||||
|  | ||||
| func runHandlers() { | ||||
| 	for _, handler := range handlers { | ||||
| 		runHandler(handler) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code) | ||||
| func Exit(code int) { | ||||
| 	runHandlers() | ||||
| 	os.Exit(code) | ||||
| } | ||||
|  | ||||
| // RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke | ||||
| // all handlers. The handlers will also be invoked when any Fatal log entry is | ||||
| // made. | ||||
| // | ||||
| // This method is useful when a caller wishes to use logrus to log a fatal | ||||
| // message but also needs to gracefully shutdown. An example usecase could be | ||||
| // closing database connections, or sending a alert that the application is | ||||
| // closing. | ||||
| func RegisterExitHandler(handler func()) { | ||||
| 	handlers = append(handlers, handler) | ||||
| } | ||||
							
								
								
									
										57
									
								
								vendor/github.com/Sirupsen/logrus/entry.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										57
									
								
								vendor/github.com/Sirupsen/logrus/entry.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,11 +3,21 @@ package logrus | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"sync" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| var bufferPool *sync.Pool | ||||
|  | ||||
| func init() { | ||||
| 	bufferPool = &sync.Pool{ | ||||
| 		New: func() interface{} { | ||||
| 			return new(bytes.Buffer) | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Defines the key when adding errors using WithError. | ||||
| var ErrorKey = "error" | ||||
|  | ||||
| @@ -29,6 +39,9 @@ type Entry struct { | ||||
|  | ||||
| 	// Message passed to Debug, Info, Warn, Error, Fatal or Panic | ||||
| 	Message string | ||||
|  | ||||
| 	// When formatter is called in entry.log(), an Buffer may be set to entry | ||||
| 	Buffer *bytes.Buffer | ||||
| } | ||||
|  | ||||
| func NewEntry(logger *Logger) *Entry { | ||||
| @@ -39,21 +52,15 @@ func NewEntry(logger *Logger) *Entry { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Returns a reader for the entry, which is a proxy to the formatter. | ||||
| func (entry *Entry) Reader() (*bytes.Buffer, error) { | ||||
| 	serialized, err := entry.Logger.Formatter.Format(entry) | ||||
| 	return bytes.NewBuffer(serialized), err | ||||
| } | ||||
|  | ||||
| // Returns the string representation from the reader and ultimately the | ||||
| // formatter. | ||||
| func (entry *Entry) String() (string, error) { | ||||
| 	reader, err := entry.Reader() | ||||
| 	serialized, err := entry.Logger.Formatter.Format(entry) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	return reader.String(), err | ||||
| 	str := string(serialized) | ||||
| 	return str, nil | ||||
| } | ||||
|  | ||||
| // Add an error as single field (using the key defined in ErrorKey) to the Entry. | ||||
| @@ -81,6 +88,7 @@ func (entry *Entry) WithFields(fields Fields) *Entry { | ||||
| // This function is not declared with a pointer value because otherwise | ||||
| // race conditions will occur when using multiple goroutines | ||||
| func (entry Entry) log(level Level, msg string) { | ||||
| 	var buffer *bytes.Buffer | ||||
| 	entry.Time = time.Now() | ||||
| 	entry.Level = level | ||||
| 	entry.Message = msg | ||||
| @@ -90,20 +98,23 @@ func (entry Entry) log(level Level, msg string) { | ||||
| 		fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) | ||||
| 		entry.Logger.mu.Unlock() | ||||
| 	} | ||||
|  | ||||
| 	reader, err := entry.Reader() | ||||
| 	buffer = bufferPool.Get().(*bytes.Buffer) | ||||
| 	buffer.Reset() | ||||
| 	defer bufferPool.Put(buffer) | ||||
| 	entry.Buffer = buffer | ||||
| 	serialized, err := entry.Logger.Formatter.Format(&entry) | ||||
| 	entry.Buffer = nil | ||||
| 	if err != nil { | ||||
| 		entry.Logger.mu.Lock() | ||||
| 		fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) | ||||
| 		entry.Logger.mu.Unlock() | ||||
| 	} | ||||
|  | ||||
| 	entry.Logger.mu.Lock() | ||||
| 	defer entry.Logger.mu.Unlock() | ||||
|  | ||||
| 	_, err = io.Copy(entry.Logger.Out, reader) | ||||
| 	if err != nil { | ||||
| 		fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) | ||||
| 	} else { | ||||
| 		entry.Logger.mu.Lock() | ||||
| 		_, err = entry.Logger.Out.Write(serialized) | ||||
| 		if err != nil { | ||||
| 			fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) | ||||
| 		} | ||||
| 		entry.Logger.mu.Unlock() | ||||
| 	} | ||||
|  | ||||
| 	// To avoid Entry#log() returning a value that only would make sense for | ||||
| @@ -150,7 +161,7 @@ func (entry *Entry) Fatal(args ...interface{}) { | ||||
| 	if entry.Logger.Level >= FatalLevel { | ||||
| 		entry.log(FatalLevel, fmt.Sprint(args...)) | ||||
| 	} | ||||
| 	os.Exit(1) | ||||
| 	Exit(1) | ||||
| } | ||||
|  | ||||
| func (entry *Entry) Panic(args ...interface{}) { | ||||
| @@ -198,7 +209,7 @@ func (entry *Entry) Fatalf(format string, args ...interface{}) { | ||||
| 	if entry.Logger.Level >= FatalLevel { | ||||
| 		entry.Fatal(fmt.Sprintf(format, args...)) | ||||
| 	} | ||||
| 	os.Exit(1) | ||||
| 	Exit(1) | ||||
| } | ||||
|  | ||||
| func (entry *Entry) Panicf(format string, args ...interface{}) { | ||||
| @@ -245,7 +256,7 @@ func (entry *Entry) Fatalln(args ...interface{}) { | ||||
| 	if entry.Logger.Level >= FatalLevel { | ||||
| 		entry.Fatal(entry.sprintlnn(args...)) | ||||
| 	} | ||||
| 	os.Exit(1) | ||||
| 	Exit(1) | ||||
| } | ||||
|  | ||||
| func (entry *Entry) Panicln(args ...interface{}) { | ||||
|   | ||||
							
								
								
									
										9
									
								
								vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/Sirupsen/logrus/examples/basic/basic.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -2,6 +2,7 @@ package main | ||||
|  | ||||
| import ( | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	// "os" | ||||
| ) | ||||
|  | ||||
| var log = logrus.New() | ||||
| @@ -9,6 +10,14 @@ var log = logrus.New() | ||||
| func init() { | ||||
| 	log.Formatter = new(logrus.JSONFormatter) | ||||
| 	log.Formatter = new(logrus.TextFormatter) // default | ||||
|  | ||||
| 	// file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666) | ||||
| 	// if err == nil { | ||||
| 	// 	log.Out = file | ||||
| 	// } else { | ||||
| 	// 	log.Info("Failed to log to file, using default stderr") | ||||
| 	// } | ||||
|  | ||||
| 	log.Level = logrus.DebugLevel | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										15
									
								
								vendor/github.com/Sirupsen/logrus/formatter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/Sirupsen/logrus/formatter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -31,18 +31,15 @@ type Formatter interface { | ||||
| // It's not exported because it's still using Data in an opinionated way. It's to | ||||
| // avoid code duplication between the two default formatters. | ||||
| func prefixFieldClashes(data Fields) { | ||||
| 	_, ok := data["time"] | ||||
| 	if ok { | ||||
| 		data["fields.time"] = data["time"] | ||||
| 	if t, ok := data["time"]; ok { | ||||
| 		data["fields.time"] = t | ||||
| 	} | ||||
|  | ||||
| 	_, ok = data["msg"] | ||||
| 	if ok { | ||||
| 		data["fields.msg"] = data["msg"] | ||||
| 	if m, ok := data["msg"]; ok { | ||||
| 		data["fields.msg"] = m | ||||
| 	} | ||||
|  | ||||
| 	_, ok = data["level"] | ||||
| 	if ok { | ||||
| 		data["fields.level"] = data["level"] | ||||
| 	if l, ok := data["level"]; ok { | ||||
| 		data["fields.level"] = l | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										61
									
								
								vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,61 +0,0 @@ | ||||
| package logstash | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| ) | ||||
|  | ||||
| // Formatter generates json in logstash format. | ||||
| // Logstash site: http://logstash.net/ | ||||
| type LogstashFormatter struct { | ||||
| 	Type string // if not empty use for logstash type field. | ||||
|  | ||||
| 	// TimestampFormat sets the format used for timestamps. | ||||
| 	TimestampFormat string | ||||
| } | ||||
|  | ||||
| func (f *LogstashFormatter) Format(entry *logrus.Entry) ([]byte, error) { | ||||
| 	fields := make(logrus.Fields) | ||||
| 	for k, v := range entry.Data { | ||||
| 		fields[k] = v | ||||
| 	} | ||||
|  | ||||
| 	fields["@version"] = 1 | ||||
|  | ||||
| 	if f.TimestampFormat == "" { | ||||
| 		f.TimestampFormat = logrus.DefaultTimestampFormat | ||||
| 	} | ||||
|  | ||||
| 	fields["@timestamp"] = entry.Time.Format(f.TimestampFormat) | ||||
|  | ||||
| 	// set message field | ||||
| 	v, ok := entry.Data["message"] | ||||
| 	if ok { | ||||
| 		fields["fields.message"] = v | ||||
| 	} | ||||
| 	fields["message"] = entry.Message | ||||
|  | ||||
| 	// set level field | ||||
| 	v, ok = entry.Data["level"] | ||||
| 	if ok { | ||||
| 		fields["fields.level"] = v | ||||
| 	} | ||||
| 	fields["level"] = entry.Level.String() | ||||
|  | ||||
| 	// set type field | ||||
| 	if f.Type != "" { | ||||
| 		v, ok = entry.Data["type"] | ||||
| 		if ok { | ||||
| 			fields["fields.type"] = v | ||||
| 		} | ||||
| 		fields["type"] = f.Type | ||||
| 	} | ||||
|  | ||||
| 	serialized, err := json.Marshal(fields) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) | ||||
| 	} | ||||
| 	return append(serialized, '\n'), nil | ||||
| } | ||||
							
								
								
									
										39
									
								
								vendor/github.com/Sirupsen/logrus/json_formatter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								vendor/github.com/Sirupsen/logrus/json_formatter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -5,9 +5,40 @@ import ( | ||||
| 	"fmt" | ||||
| ) | ||||
|  | ||||
| type fieldKey string | ||||
| type FieldMap map[fieldKey]string | ||||
|  | ||||
| const ( | ||||
| 	FieldKeyMsg   = "msg" | ||||
| 	FieldKeyLevel = "level" | ||||
| 	FieldKeyTime  = "time" | ||||
| ) | ||||
|  | ||||
| func (f FieldMap) resolve(key fieldKey) string { | ||||
| 	if k, ok := f[key]; ok { | ||||
| 		return k | ||||
| 	} | ||||
|  | ||||
| 	return string(key) | ||||
| } | ||||
|  | ||||
| type JSONFormatter struct { | ||||
| 	// TimestampFormat sets the format used for marshaling timestamps. | ||||
| 	TimestampFormat string | ||||
|  | ||||
| 	// DisableTimestamp allows disabling automatic timestamps in output | ||||
| 	DisableTimestamp bool | ||||
|  | ||||
| 	// FieldMap allows users to customize the names of keys for various fields. | ||||
| 	// As an example: | ||||
| 	// formatter := &JSONFormatter{ | ||||
| 	//   	FieldMap: FieldMap{ | ||||
| 	// 		 FieldKeyTime: "@timestamp", | ||||
| 	// 		 FieldKeyLevel: "@level", | ||||
| 	// 		 FieldKeyLevel: "@message", | ||||
| 	//    }, | ||||
| 	// } | ||||
| 	FieldMap FieldMap | ||||
| } | ||||
|  | ||||
| func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { | ||||
| @@ -29,9 +60,11 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { | ||||
| 		timestampFormat = DefaultTimestampFormat | ||||
| 	} | ||||
|  | ||||
| 	data["time"] = entry.Time.Format(timestampFormat) | ||||
| 	data["msg"] = entry.Message | ||||
| 	data["level"] = entry.Level.String() | ||||
| 	if !f.DisableTimestamp { | ||||
| 		data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat) | ||||
| 	} | ||||
| 	data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message | ||||
| 	data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String() | ||||
|  | ||||
| 	serialized, err := json.Marshal(data) | ||||
| 	if err != nil { | ||||
|   | ||||
							
								
								
									
										162
									
								
								vendor/github.com/Sirupsen/logrus/logger.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										162
									
								
								vendor/github.com/Sirupsen/logrus/logger.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -26,8 +26,31 @@ type Logger struct { | ||||
| 	// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be | ||||
| 	// logged. `logrus.Debug` is useful in | ||||
| 	Level Level | ||||
| 	// Used to sync writing to the log. | ||||
| 	mu sync.Mutex | ||||
| 	// Used to sync writing to the log. Locking is enabled by Default | ||||
| 	mu MutexWrap | ||||
| 	// Reusable empty entry | ||||
| 	entryPool sync.Pool | ||||
| } | ||||
|  | ||||
| type MutexWrap struct { | ||||
| 	lock     sync.Mutex | ||||
| 	disabled bool | ||||
| } | ||||
|  | ||||
| func (mw *MutexWrap) Lock() { | ||||
| 	if !mw.disabled { | ||||
| 		mw.lock.Lock() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (mw *MutexWrap) Unlock() { | ||||
| 	if !mw.disabled { | ||||
| 		mw.lock.Unlock() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (mw *MutexWrap) Disable() { | ||||
| 	mw.disabled = true | ||||
| } | ||||
|  | ||||
| // Creates a new logger. Configuration should be set by changing `Formatter`, | ||||
| @@ -51,162 +74,235 @@ func New() *Logger { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Adds a field to the log entry, note that you it doesn't log until you call | ||||
| func (logger *Logger) newEntry() *Entry { | ||||
| 	entry, ok := logger.entryPool.Get().(*Entry) | ||||
| 	if ok { | ||||
| 		return entry | ||||
| 	} | ||||
| 	return NewEntry(logger) | ||||
| } | ||||
|  | ||||
| func (logger *Logger) releaseEntry(entry *Entry) { | ||||
| 	logger.entryPool.Put(entry) | ||||
| } | ||||
|  | ||||
| // Adds a field to the log entry, note that it doesn't log until you call | ||||
| // Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry. | ||||
| // If you want multiple fields, use `WithFields`. | ||||
| func (logger *Logger) WithField(key string, value interface{}) *Entry { | ||||
| 	return NewEntry(logger).WithField(key, value) | ||||
| 	entry := logger.newEntry() | ||||
| 	defer logger.releaseEntry(entry) | ||||
| 	return entry.WithField(key, value) | ||||
| } | ||||
|  | ||||
| // Adds a struct of fields to the log entry. All it does is call `WithField` for | ||||
| // each `Field`. | ||||
| func (logger *Logger) WithFields(fields Fields) *Entry { | ||||
| 	return NewEntry(logger).WithFields(fields) | ||||
| 	entry := logger.newEntry() | ||||
| 	defer logger.releaseEntry(entry) | ||||
| 	return entry.WithFields(fields) | ||||
| } | ||||
|  | ||||
| // Add an error as single field to the log entry.  All it does is call | ||||
| // `WithError` for the given `error`. | ||||
| func (logger *Logger) WithError(err error) *Entry { | ||||
| 	return NewEntry(logger).WithError(err) | ||||
| 	entry := logger.newEntry() | ||||
| 	defer logger.releaseEntry(entry) | ||||
| 	return entry.WithError(err) | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Debugf(format string, args ...interface{}) { | ||||
| 	if logger.Level >= DebugLevel { | ||||
| 		NewEntry(logger).Debugf(format, args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Debugf(format, args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Infof(format string, args ...interface{}) { | ||||
| 	if logger.Level >= InfoLevel { | ||||
| 		NewEntry(logger).Infof(format, args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Infof(format, args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Printf(format string, args ...interface{}) { | ||||
| 	NewEntry(logger).Printf(format, args...) | ||||
| 	entry := logger.newEntry() | ||||
| 	entry.Printf(format, args...) | ||||
| 	logger.releaseEntry(entry) | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Warnf(format string, args ...interface{}) { | ||||
| 	if logger.Level >= WarnLevel { | ||||
| 		NewEntry(logger).Warnf(format, args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Warnf(format, args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Warningf(format string, args ...interface{}) { | ||||
| 	if logger.Level >= WarnLevel { | ||||
| 		NewEntry(logger).Warnf(format, args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Warnf(format, args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Errorf(format string, args ...interface{}) { | ||||
| 	if logger.Level >= ErrorLevel { | ||||
| 		NewEntry(logger).Errorf(format, args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Errorf(format, args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Fatalf(format string, args ...interface{}) { | ||||
| 	if logger.Level >= FatalLevel { | ||||
| 		NewEntry(logger).Fatalf(format, args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Fatalf(format, args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| 	os.Exit(1) | ||||
| 	Exit(1) | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Panicf(format string, args ...interface{}) { | ||||
| 	if logger.Level >= PanicLevel { | ||||
| 		NewEntry(logger).Panicf(format, args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Panicf(format, args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Debug(args ...interface{}) { | ||||
| 	if logger.Level >= DebugLevel { | ||||
| 		NewEntry(logger).Debug(args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Debug(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Info(args ...interface{}) { | ||||
| 	if logger.Level >= InfoLevel { | ||||
| 		NewEntry(logger).Info(args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Info(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Print(args ...interface{}) { | ||||
| 	NewEntry(logger).Info(args...) | ||||
| 	entry := logger.newEntry() | ||||
| 	entry.Info(args...) | ||||
| 	logger.releaseEntry(entry) | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Warn(args ...interface{}) { | ||||
| 	if logger.Level >= WarnLevel { | ||||
| 		NewEntry(logger).Warn(args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Warn(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Warning(args ...interface{}) { | ||||
| 	if logger.Level >= WarnLevel { | ||||
| 		NewEntry(logger).Warn(args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Warn(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Error(args ...interface{}) { | ||||
| 	if logger.Level >= ErrorLevel { | ||||
| 		NewEntry(logger).Error(args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Error(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Fatal(args ...interface{}) { | ||||
| 	if logger.Level >= FatalLevel { | ||||
| 		NewEntry(logger).Fatal(args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Fatal(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| 	os.Exit(1) | ||||
| 	Exit(1) | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Panic(args ...interface{}) { | ||||
| 	if logger.Level >= PanicLevel { | ||||
| 		NewEntry(logger).Panic(args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Panic(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Debugln(args ...interface{}) { | ||||
| 	if logger.Level >= DebugLevel { | ||||
| 		NewEntry(logger).Debugln(args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Debugln(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Infoln(args ...interface{}) { | ||||
| 	if logger.Level >= InfoLevel { | ||||
| 		NewEntry(logger).Infoln(args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Infoln(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Println(args ...interface{}) { | ||||
| 	NewEntry(logger).Println(args...) | ||||
| 	entry := logger.newEntry() | ||||
| 	entry.Println(args...) | ||||
| 	logger.releaseEntry(entry) | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Warnln(args ...interface{}) { | ||||
| 	if logger.Level >= WarnLevel { | ||||
| 		NewEntry(logger).Warnln(args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Warnln(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Warningln(args ...interface{}) { | ||||
| 	if logger.Level >= WarnLevel { | ||||
| 		NewEntry(logger).Warnln(args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Warnln(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Errorln(args ...interface{}) { | ||||
| 	if logger.Level >= ErrorLevel { | ||||
| 		NewEntry(logger).Errorln(args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Errorln(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Fatalln(args ...interface{}) { | ||||
| 	if logger.Level >= FatalLevel { | ||||
| 		NewEntry(logger).Fatalln(args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Fatalln(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| 	os.Exit(1) | ||||
| 	Exit(1) | ||||
| } | ||||
|  | ||||
| func (logger *Logger) Panicln(args ...interface{}) { | ||||
| 	if logger.Level >= PanicLevel { | ||||
| 		NewEntry(logger).Panicln(args...) | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Panicln(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| //When file is opened with appending mode, it's safe to | ||||
| //write concurrently to a file (within 4k message on Linux). | ||||
| //In these cases user can choose to disable the lock. | ||||
| func (logger *Logger) SetNoLock() { | ||||
| 	logger.mu.Disable() | ||||
| } | ||||
|   | ||||
							
								
								
									
										10
									
								
								vendor/github.com/Sirupsen/logrus/terminal_appengine.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/Sirupsen/logrus/terminal_appengine.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| // +build appengine | ||||
|  | ||||
| package logrus | ||||
|  | ||||
| import "io" | ||||
|  | ||||
| // IsTerminal returns true if stderr's file descriptor is a terminal. | ||||
| func IsTerminal(f io.Writer) bool { | ||||
| 	return true | ||||
| } | ||||
							
								
								
									
										1
									
								
								vendor/github.com/Sirupsen/logrus/terminal_bsd.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/Sirupsen/logrus/terminal_bsd.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,5 @@ | ||||
| // +build darwin freebsd openbsd netbsd dragonfly | ||||
| // +build !appengine | ||||
|  | ||||
| package logrus | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/Sirupsen/logrus/terminal_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/Sirupsen/logrus/terminal_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,6 +3,8 @@ | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // +build !appengine | ||||
|  | ||||
| package logrus | ||||
|  | ||||
| import "syscall" | ||||
|   | ||||
							
								
								
									
										15
									
								
								vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -4,18 +4,25 @@ | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // +build linux darwin freebsd openbsd netbsd dragonfly | ||||
| // +build !appengine | ||||
|  | ||||
| package logrus | ||||
|  | ||||
| import ( | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"syscall" | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| // IsTerminal returns true if stderr's file descriptor is a terminal. | ||||
| func IsTerminal() bool { | ||||
| 	fd := syscall.Stderr | ||||
| func IsTerminal(f io.Writer) bool { | ||||
| 	var termios Termios | ||||
| 	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) | ||||
| 	return err == 0 | ||||
| 	switch v := f.(type) { | ||||
| 	case *os.File: | ||||
| 		_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(v.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) | ||||
| 		return err == 0 | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										14
									
								
								vendor/github.com/Sirupsen/logrus/terminal_solaris.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/Sirupsen/logrus/terminal_solaris.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,15 +1,21 @@ | ||||
| // +build solaris | ||||
| // +build solaris,!appengine | ||||
|  | ||||
| package logrus | ||||
|  | ||||
| import ( | ||||
| 	"io" | ||||
| 	"os" | ||||
|  | ||||
| 	"golang.org/x/sys/unix" | ||||
| ) | ||||
|  | ||||
| // IsTerminal returns true if the given file descriptor is a terminal. | ||||
| func IsTerminal() bool { | ||||
| 	_, err := unix.IoctlGetTermios(int(os.Stdout.Fd()), unix.TCGETA) | ||||
| 	return err == nil | ||||
| func IsTerminal(f io.Writer) bool { | ||||
| 	switch v := f.(type) { | ||||
| 	case *os.File: | ||||
| 		_, err := unix.IoctlGetTermios(int(v.Fd()), unix.TCGETA) | ||||
| 		return err == nil | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										18
									
								
								vendor/github.com/Sirupsen/logrus/terminal_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/Sirupsen/logrus/terminal_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,11 +3,13 @@ | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // +build windows | ||||
| // +build windows,!appengine | ||||
|  | ||||
| package logrus | ||||
|  | ||||
| import ( | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"syscall" | ||||
| 	"unsafe" | ||||
| ) | ||||
| @@ -19,9 +21,13 @@ var ( | ||||
| ) | ||||
|  | ||||
| // IsTerminal returns true if stderr's file descriptor is a terminal. | ||||
| func IsTerminal() bool { | ||||
| 	fd := syscall.Stderr | ||||
| 	var st uint32 | ||||
| 	r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) | ||||
| 	return r != 0 && e == 0 | ||||
| func IsTerminal(f io.Writer) bool { | ||||
| 	switch v := f.(type) { | ||||
| 	case *os.File: | ||||
| 		var st uint32 | ||||
| 		r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0) | ||||
| 		return r != 0 && e == 0 | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										76
									
								
								vendor/github.com/Sirupsen/logrus/text_formatter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										76
									
								
								vendor/github.com/Sirupsen/logrus/text_formatter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,9 +3,9 @@ package logrus | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"runtime" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| @@ -20,16 +20,10 @@ const ( | ||||
|  | ||||
| var ( | ||||
| 	baseTimestamp time.Time | ||||
| 	isTerminal    bool | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	baseTimestamp = time.Now() | ||||
| 	isTerminal = IsTerminal() | ||||
| } | ||||
|  | ||||
| func miniTS() int { | ||||
| 	return int(time.Since(baseTimestamp) / time.Second) | ||||
| } | ||||
|  | ||||
| type TextFormatter struct { | ||||
| @@ -54,10 +48,32 @@ type TextFormatter struct { | ||||
| 	// that log extremely frequently and don't use the JSON formatter this may not | ||||
| 	// be desired. | ||||
| 	DisableSorting bool | ||||
|  | ||||
| 	// QuoteEmptyFields will wrap empty fields in quotes if true | ||||
| 	QuoteEmptyFields bool | ||||
|  | ||||
| 	// QuoteCharacter can be set to the override the default quoting character " | ||||
| 	// with something else. For example: ', or `. | ||||
| 	QuoteCharacter string | ||||
|  | ||||
| 	// Whether the logger's out is to a terminal | ||||
| 	isTerminal bool | ||||
|  | ||||
| 	sync.Once | ||||
| } | ||||
|  | ||||
| func (f *TextFormatter) init(entry *Entry) { | ||||
| 	if len(f.QuoteCharacter) == 0 { | ||||
| 		f.QuoteCharacter = "\"" | ||||
| 	} | ||||
| 	if entry.Logger != nil { | ||||
| 		f.isTerminal = IsTerminal(entry.Logger.Out) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { | ||||
| 	var keys []string = make([]string, 0, len(entry.Data)) | ||||
| 	var b *bytes.Buffer | ||||
| 	keys := make([]string, 0, len(entry.Data)) | ||||
| 	for k := range entry.Data { | ||||
| 		keys = append(keys, k) | ||||
| 	} | ||||
| @@ -65,13 +81,17 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { | ||||
| 	if !f.DisableSorting { | ||||
| 		sort.Strings(keys) | ||||
| 	} | ||||
|  | ||||
| 	b := &bytes.Buffer{} | ||||
| 	if entry.Buffer != nil { | ||||
| 		b = entry.Buffer | ||||
| 	} else { | ||||
| 		b = &bytes.Buffer{} | ||||
| 	} | ||||
|  | ||||
| 	prefixFieldClashes(entry.Data) | ||||
|  | ||||
| 	isColorTerminal := isTerminal && (runtime.GOOS != "windows") | ||||
| 	isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors | ||||
| 	f.Do(func() { f.init(entry) }) | ||||
|  | ||||
| 	isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors | ||||
|  | ||||
| 	timestampFormat := f.TimestampFormat | ||||
| 	if timestampFormat == "" { | ||||
| @@ -111,51 +131,59 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin | ||||
|  | ||||
| 	levelText := strings.ToUpper(entry.Level.String())[0:4] | ||||
|  | ||||
| 	if !f.FullTimestamp { | ||||
| 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message) | ||||
| 	if f.DisableTimestamp { | ||||
| 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message) | ||||
| 	} else if !f.FullTimestamp { | ||||
| 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message) | ||||
| 	} else { | ||||
| 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message) | ||||
| 	} | ||||
| 	for _, k := range keys { | ||||
| 		v := entry.Data[k] | ||||
| 		fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%+v", levelColor, k, v) | ||||
| 		fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k) | ||||
| 		f.appendValue(b, v) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func needsQuoting(text string) bool { | ||||
| func (f *TextFormatter) needsQuoting(text string) bool { | ||||
| 	if f.QuoteEmptyFields && len(text) == 0 { | ||||
| 		return true | ||||
| 	} | ||||
| 	for _, ch := range text { | ||||
| 		if !((ch >= 'a' && ch <= 'z') || | ||||
| 			(ch >= 'A' && ch <= 'Z') || | ||||
| 			(ch >= '0' && ch <= '9') || | ||||
| 			ch == '-' || ch == '.') { | ||||
| 			return false | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) { | ||||
|  | ||||
| 	b.WriteString(key) | ||||
| 	b.WriteByte('=') | ||||
| 	f.appendValue(b, value) | ||||
| 	b.WriteByte(' ') | ||||
| } | ||||
|  | ||||
| func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) { | ||||
| 	switch value := value.(type) { | ||||
| 	case string: | ||||
| 		if needsQuoting(value) { | ||||
| 		if !f.needsQuoting(value) { | ||||
| 			b.WriteString(value) | ||||
| 		} else { | ||||
| 			fmt.Fprintf(b, "%q", value) | ||||
| 			fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, value, f.QuoteCharacter) | ||||
| 		} | ||||
| 	case error: | ||||
| 		errmsg := value.Error() | ||||
| 		if needsQuoting(errmsg) { | ||||
| 		if !f.needsQuoting(errmsg) { | ||||
| 			b.WriteString(errmsg) | ||||
| 		} else { | ||||
| 			fmt.Fprintf(b, "%q", value) | ||||
| 			fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, errmsg, f.QuoteCharacter) | ||||
| 		} | ||||
| 	default: | ||||
| 		fmt.Fprint(b, value) | ||||
| 	} | ||||
|  | ||||
| 	b.WriteByte(' ') | ||||
| } | ||||
|   | ||||
							
								
								
									
										39
									
								
								vendor/github.com/Sirupsen/logrus/writer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								vendor/github.com/Sirupsen/logrus/writer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -7,21 +7,52 @@ import ( | ||||
| ) | ||||
|  | ||||
| func (logger *Logger) Writer() *io.PipeWriter { | ||||
| 	return logger.WriterLevel(InfoLevel) | ||||
| } | ||||
|  | ||||
| func (logger *Logger) WriterLevel(level Level) *io.PipeWriter { | ||||
| 	return NewEntry(logger).WriterLevel(level) | ||||
| } | ||||
|  | ||||
| func (entry *Entry) Writer() *io.PipeWriter { | ||||
| 	return entry.WriterLevel(InfoLevel) | ||||
| } | ||||
|  | ||||
| func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { | ||||
| 	reader, writer := io.Pipe() | ||||
|  | ||||
| 	go logger.writerScanner(reader) | ||||
| 	var printFunc func(args ...interface{}) | ||||
|  | ||||
| 	switch level { | ||||
| 	case DebugLevel: | ||||
| 		printFunc = entry.Debug | ||||
| 	case InfoLevel: | ||||
| 		printFunc = entry.Info | ||||
| 	case WarnLevel: | ||||
| 		printFunc = entry.Warn | ||||
| 	case ErrorLevel: | ||||
| 		printFunc = entry.Error | ||||
| 	case FatalLevel: | ||||
| 		printFunc = entry.Fatal | ||||
| 	case PanicLevel: | ||||
| 		printFunc = entry.Panic | ||||
| 	default: | ||||
| 		printFunc = entry.Print | ||||
| 	} | ||||
|  | ||||
| 	go entry.writerScanner(reader, printFunc) | ||||
| 	runtime.SetFinalizer(writer, writerFinalizer) | ||||
|  | ||||
| 	return writer | ||||
| } | ||||
|  | ||||
| func (logger *Logger) writerScanner(reader *io.PipeReader) { | ||||
| func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) { | ||||
| 	scanner := bufio.NewScanner(reader) | ||||
| 	for scanner.Scan() { | ||||
| 		logger.Print(scanner.Text()) | ||||
| 		printFunc(scanner.Text()) | ||||
| 	} | ||||
| 	if err := scanner.Err(); err != nil { | ||||
| 		logger.Errorf("Error while reading from Writer: %s", err) | ||||
| 		entry.Errorf("Error while reading from Writer: %s", err) | ||||
| 	} | ||||
| 	reader.Close() | ||||
| } | ||||
|   | ||||
							
								
								
									
										17
									
								
								vendor/github.com/go-telegram-bot-api/telegram-bot-api/bot.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/go-telegram-bot-api/telegram-bot-api/bot.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -21,8 +21,10 @@ import ( | ||||
|  | ||||
| // BotAPI allows you to interact with the Telegram Bot API. | ||||
| type BotAPI struct { | ||||
| 	Token  string       `json:"token"` | ||||
| 	Debug  bool         `json:"debug"` | ||||
| 	Token  string `json:"token"` | ||||
| 	Debug  bool   `json:"debug"` | ||||
| 	Buffer int    `json:"buffer"` | ||||
|  | ||||
| 	Self   User         `json:"-"` | ||||
| 	Client *http.Client `json:"-"` | ||||
| } | ||||
| @@ -42,11 +44,12 @@ func NewBotAPIWithClient(token string, client *http.Client) (*BotAPI, error) { | ||||
| 	bot := &BotAPI{ | ||||
| 		Token:  token, | ||||
| 		Client: client, | ||||
| 		Buffer: 100, | ||||
| 	} | ||||
|  | ||||
| 	self, err := bot.GetMe() | ||||
| 	if err != nil { | ||||
| 		return &BotAPI{}, err | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	bot.Self = self | ||||
| @@ -68,6 +71,10 @@ func (bot *BotAPI) MakeRequest(endpoint string, params url.Values) (APIResponse, | ||||
| 		return APIResponse{}, errors.New(ErrAPIForbidden) | ||||
| 	} | ||||
|  | ||||
| 	if resp.StatusCode != http.StatusOK { | ||||
| 		return APIResponse{}, errors.New(http.StatusText(resp.StatusCode)) | ||||
| 	} | ||||
|  | ||||
| 	bytes, err := ioutil.ReadAll(resp.Body) | ||||
| 	if err != nil { | ||||
| 		return APIResponse{}, err | ||||
| @@ -457,7 +464,7 @@ func (bot *BotAPI) GetWebhookInfo() (WebhookInfo, error) { | ||||
|  | ||||
| // GetUpdatesChan starts and returns a channel for getting updates. | ||||
| func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (UpdatesChannel, error) { | ||||
| 	ch := make(chan Update, 100) | ||||
| 	ch := make(chan Update, bot.Buffer) | ||||
|  | ||||
| 	go func() { | ||||
| 		for { | ||||
| @@ -484,7 +491,7 @@ func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (UpdatesChannel, error) { | ||||
|  | ||||
| // ListenForWebhook registers a http handler for a webhook. | ||||
| func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel { | ||||
| 	ch := make(chan Update, 100) | ||||
| 	ch := make(chan Update, bot.Buffer) | ||||
|  | ||||
| 	http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { | ||||
| 		bytes, _ := ioutil.ReadAll(r.Body) | ||||
|   | ||||
							
								
								
									
										4
									
								
								vendor/github.com/go-telegram-bot-api/telegram-bot-api/configs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/go-telegram-bot-api/telegram-bot-api/configs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -768,8 +768,8 @@ type UpdateConfig struct { | ||||
|  | ||||
| // WebhookConfig contains information about a SetWebhook request. | ||||
| type WebhookConfig struct { | ||||
| 	URL         *url.URL | ||||
| 	Certificate interface{} | ||||
| 	URL            *url.URL | ||||
| 	Certificate    interface{} | ||||
| 	MaxConnections int | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										15
									
								
								vendor/github.com/go-telegram-bot-api/telegram-bot-api/helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/go-telegram-bot-api/telegram-bot-api/helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -318,21 +318,6 @@ func NewWebhookWithCert(link string, file interface{}) WebhookConfig { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // NewWebhookWithCert creates a new webhook with a certificate and max_connections. | ||||
| // | ||||
| // link is the url you wish to get webhooks, | ||||
| // file contains a string to a file, FileReader, or FileBytes. | ||||
| // maxConnections defines maximum number of connections from telegram to your server | ||||
| func NewWebhookWithCertAndMaxConnections(link string, file interface{}, maxConnections int) WebhookConfig { | ||||
| 	u, _ := url.Parse(link) | ||||
|  | ||||
| 	return WebhookConfig{ | ||||
| 		URL:         u, | ||||
| 		Certificate: file, | ||||
| 		MaxConnections: maxConnections, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // NewInlineQueryResultArticle creates a new inline query article. | ||||
| func NewInlineQueryResultArticle(id, title, messageText string) InlineQueryResultArticle { | ||||
| 	return InlineQueryResultArticle{ | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/go-telegram-bot-api/telegram-bot-api/types.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/go-telegram-bot-api/telegram-bot-api/types.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -194,7 +194,7 @@ func (m *Message) CommandArguments() string { | ||||
| 		return "" | ||||
| 	} | ||||
|  | ||||
| 	return strings.SplitN(m.Text, " ", 2)[1] | ||||
| 	return split[1] | ||||
| } | ||||
|  | ||||
| // MessageEntity contains information about data in a Message. | ||||
|   | ||||
							
								
								
									
										27
									
								
								vendor/github.com/google/gops/agent/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/google/gops/agent/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| Copyright (c) 2016 The Go Authors. All rights reserved. | ||||
|  | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
|  | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the name of Google Inc. nor the names of its | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
|  | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										237
									
								
								vendor/github.com/google/gops/agent/agent.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								vendor/github.com/google/gops/agent/agent.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,237 @@ | ||||
| // Copyright 2016 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // Package agent provides hooks programs can register to retrieve | ||||
| // diagnostics data by using gops. | ||||
| package agent | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"net" | ||||
| 	"os" | ||||
| 	gosignal "os/signal" | ||||
| 	"runtime" | ||||
| 	"runtime/pprof" | ||||
| 	"runtime/trace" | ||||
| 	"strconv" | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	"bufio" | ||||
|  | ||||
| 	"github.com/google/gops/internal" | ||||
| 	"github.com/google/gops/signal" | ||||
| 	"github.com/kardianos/osext" | ||||
| ) | ||||
|  | ||||
| const defaultAddr = "127.0.0.1:0" | ||||
|  | ||||
| var ( | ||||
| 	mu       sync.Mutex | ||||
| 	portfile string | ||||
| 	listener net.Listener | ||||
|  | ||||
| 	units = []string{" bytes", "KB", "MB", "GB", "TB", "PB"} | ||||
| ) | ||||
|  | ||||
| // Options allows configuring the started agent. | ||||
| type Options struct { | ||||
| 	// Addr is the host:port the agent will be listening at. | ||||
| 	// Optional. | ||||
| 	Addr string | ||||
|  | ||||
| 	// NoShutdownCleanup tells the agent not to automatically cleanup | ||||
| 	// resources if the running process receives an interrupt. | ||||
| 	// Optional. | ||||
| 	NoShutdownCleanup bool | ||||
| } | ||||
|  | ||||
| // Listen starts the gops agent on a host process. Once agent started, users | ||||
| // can use the advanced gops features. The agent will listen to Interrupt | ||||
| // signals and exit the process, if you need to perform further work on the | ||||
| // Interrupt signal use the options parameter to configure the agent | ||||
| // accordingly. | ||||
| // | ||||
| // Note: The agent exposes an endpoint via a TCP connection that can be used by | ||||
| // any program on the system. Review your security requirements before starting | ||||
| // the agent. | ||||
| func Listen(opts *Options) error { | ||||
| 	mu.Lock() | ||||
| 	defer mu.Unlock() | ||||
|  | ||||
| 	if opts == nil { | ||||
| 		opts = &Options{} | ||||
| 	} | ||||
| 	if portfile != "" { | ||||
| 		return fmt.Errorf("gops: agent already listening at: %v", listener.Addr()) | ||||
| 	} | ||||
|  | ||||
| 	gopsdir, err := internal.ConfigDir() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	err = os.MkdirAll(gopsdir, os.ModePerm) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if !opts.NoShutdownCleanup { | ||||
| 		gracefulShutdown() | ||||
| 	} | ||||
|  | ||||
| 	addr := opts.Addr | ||||
| 	if addr == "" { | ||||
| 		addr = defaultAddr | ||||
| 	} | ||||
| 	ln, err := net.Listen("tcp", addr) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	listener = ln | ||||
| 	port := listener.Addr().(*net.TCPAddr).Port | ||||
| 	portfile = fmt.Sprintf("%s/%d", gopsdir, os.Getpid()) | ||||
| 	err = ioutil.WriteFile(portfile, []byte(strconv.Itoa(port)), os.ModePerm) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	go listen() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func listen() { | ||||
| 	buf := make([]byte, 1) | ||||
| 	for { | ||||
| 		fd, err := listener.Accept() | ||||
| 		if err != nil { | ||||
| 			fmt.Fprintf(os.Stderr, "gops: %v", err) | ||||
| 			if netErr, ok := err.(net.Error); ok && !netErr.Temporary() { | ||||
| 				break | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
| 		if _, err := fd.Read(buf); err != nil { | ||||
| 			fmt.Fprintf(os.Stderr, "gops: %v", err) | ||||
| 			continue | ||||
| 		} | ||||
| 		if err := handle(fd, buf); err != nil { | ||||
| 			fmt.Fprintf(os.Stderr, "gops: %v", err) | ||||
| 			continue | ||||
| 		} | ||||
| 		fd.Close() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func gracefulShutdown() { | ||||
| 	c := make(chan os.Signal, 1) | ||||
| 	gosignal.Notify(c, os.Interrupt) | ||||
| 	go func() { | ||||
| 		// cleanup the socket on shutdown. | ||||
| 		<-c | ||||
| 		Close() | ||||
| 		os.Exit(1) | ||||
| 	}() | ||||
| } | ||||
|  | ||||
| // Close closes the agent, removing temporary files and closing the TCP listener. | ||||
| // If no agent is listening, Close does nothing. | ||||
| func Close() { | ||||
| 	mu.Lock() | ||||
| 	defer mu.Unlock() | ||||
|  | ||||
| 	if portfile != "" { | ||||
| 		os.Remove(portfile) | ||||
| 		portfile = "" | ||||
| 	} | ||||
| 	if listener != nil { | ||||
| 		listener.Close() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func formatBytes(val uint64) string { | ||||
| 	var i int | ||||
| 	var target uint64 | ||||
| 	for i = range units { | ||||
| 		target = 1 << uint(10*(i+1)) | ||||
| 		if val < target { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	if i > 0 { | ||||
| 		return fmt.Sprintf("%0.2f%s (%d bytes)", float64(val)/(float64(target)/1024), units[i], val) | ||||
| 	} | ||||
| 	return fmt.Sprintf("%d bytes", val) | ||||
| } | ||||
|  | ||||
| func handle(conn io.Writer, msg []byte) error { | ||||
| 	switch msg[0] { | ||||
| 	case signal.StackTrace: | ||||
| 		return pprof.Lookup("goroutine").WriteTo(conn, 2) | ||||
| 	case signal.GC: | ||||
| 		runtime.GC() | ||||
| 		_, err := conn.Write([]byte("ok")) | ||||
| 		return err | ||||
| 	case signal.MemStats: | ||||
| 		var s runtime.MemStats | ||||
| 		runtime.ReadMemStats(&s) | ||||
| 		fmt.Fprintf(conn, "alloc: %v\n", formatBytes(s.Alloc)) | ||||
| 		fmt.Fprintf(conn, "total-alloc: %v\n", formatBytes(s.TotalAlloc)) | ||||
| 		fmt.Fprintf(conn, "sys: %v\n", formatBytes(s.Sys)) | ||||
| 		fmt.Fprintf(conn, "lookups: %v\n", s.Lookups) | ||||
| 		fmt.Fprintf(conn, "mallocs: %v\n", s.Mallocs) | ||||
| 		fmt.Fprintf(conn, "frees: %v\n", s.Frees) | ||||
| 		fmt.Fprintf(conn, "heap-alloc: %v\n", formatBytes(s.HeapAlloc)) | ||||
| 		fmt.Fprintf(conn, "heap-sys: %v\n", formatBytes(s.HeapSys)) | ||||
| 		fmt.Fprintf(conn, "heap-idle: %v\n", formatBytes(s.HeapIdle)) | ||||
| 		fmt.Fprintf(conn, "heap-in-use: %v\n", formatBytes(s.HeapInuse)) | ||||
| 		fmt.Fprintf(conn, "heap-released: %v\n", formatBytes(s.HeapReleased)) | ||||
| 		fmt.Fprintf(conn, "heap-objects: %v\n", s.HeapObjects) | ||||
| 		fmt.Fprintf(conn, "stack-in-use: %v\n", formatBytes(s.StackInuse)) | ||||
| 		fmt.Fprintf(conn, "stack-sys: %v\n", formatBytes(s.StackSys)) | ||||
| 		fmt.Fprintf(conn, "next-gc: when heap-alloc >= %v\n", formatBytes(s.NextGC)) | ||||
| 		lastGC := "-" | ||||
| 		if s.LastGC != 0 { | ||||
| 			lastGC = fmt.Sprint(time.Unix(0, int64(s.LastGC))) | ||||
| 		} | ||||
| 		fmt.Fprintf(conn, "last-gc: %v\n", lastGC) | ||||
| 		fmt.Fprintf(conn, "gc-pause: %v\n", time.Duration(s.PauseTotalNs)) | ||||
| 		fmt.Fprintf(conn, "num-gc: %v\n", s.NumGC) | ||||
| 		fmt.Fprintf(conn, "enable-gc: %v\n", s.EnableGC) | ||||
| 		fmt.Fprintf(conn, "debug-gc: %v\n", s.DebugGC) | ||||
| 	case signal.Version: | ||||
| 		fmt.Fprintf(conn, "%v\n", runtime.Version()) | ||||
| 	case signal.HeapProfile: | ||||
| 		pprof.WriteHeapProfile(conn) | ||||
| 	case signal.CPUProfile: | ||||
| 		if err := pprof.StartCPUProfile(conn); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		time.Sleep(30 * time.Second) | ||||
| 		pprof.StopCPUProfile() | ||||
| 	case signal.Stats: | ||||
| 		fmt.Fprintf(conn, "goroutines: %v\n", runtime.NumGoroutine()) | ||||
| 		fmt.Fprintf(conn, "OS threads: %v\n", pprof.Lookup("threadcreate").Count()) | ||||
| 		fmt.Fprintf(conn, "GOMAXPROCS: %v\n", runtime.GOMAXPROCS(0)) | ||||
| 		fmt.Fprintf(conn, "num CPU: %v\n", runtime.NumCPU()) | ||||
| 	case signal.BinaryDump: | ||||
| 		path, err := osext.Executable() | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		f, err := os.Open(path) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		defer f.Close() | ||||
|  | ||||
| 		_, err = bufio.NewReader(f).WriteTo(conn) | ||||
| 		return err | ||||
| 	case signal.Trace: | ||||
| 		trace.Start(conn) | ||||
| 		time.Sleep(5 * time.Second) | ||||
| 		trace.Stop() | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										27
									
								
								vendor/github.com/google/gops/internal/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/google/gops/internal/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| Copyright (c) 2016 The Go Authors. All rights reserved. | ||||
|  | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
|  | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the name of Google Inc. nor the names of its | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
|  | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										600
									
								
								vendor/github.com/google/gops/internal/dwarf/dwarf.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										600
									
								
								vendor/github.com/google/gops/internal/dwarf/dwarf.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,600 @@ | ||||
| // Copyright 2016 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // Package dwarf generates DWARF debugging information. | ||||
| // DWARF generation is split between the compiler and the linker, | ||||
| // this package contains the shared code. | ||||
| package dwarf | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| ) | ||||
|  | ||||
| // InfoPrefix is the prefix for all the symbols containing DWARF info entries. | ||||
| const InfoPrefix = "go.info." | ||||
|  | ||||
| // Sym represents a symbol. | ||||
| type Sym interface { | ||||
| } | ||||
|  | ||||
| // A Var represents a local variable or a function parameter. | ||||
| type Var struct { | ||||
| 	Name   string | ||||
| 	Abbrev int // Either DW_ABRV_AUTO or DW_ABRV_PARAM | ||||
| 	Offset int32 | ||||
| 	Type   Sym | ||||
| 	Link   *Var | ||||
| } | ||||
|  | ||||
| // A Context specifies how to add data to a Sym. | ||||
| type Context interface { | ||||
| 	PtrSize() int | ||||
| 	AddInt(s Sym, size int, i int64) | ||||
| 	AddBytes(s Sym, b []byte) | ||||
| 	AddAddress(s Sym, t interface{}, ofs int64) | ||||
| 	AddSectionOffset(s Sym, size int, t interface{}, ofs int64) | ||||
| 	AddString(s Sym, v string) | ||||
| 	SymValue(s Sym) int64 | ||||
| } | ||||
|  | ||||
| // AppendUleb128 appends v to b using DWARF's unsigned LEB128 encoding. | ||||
| func AppendUleb128(b []byte, v uint64) []byte { | ||||
| 	for { | ||||
| 		c := uint8(v & 0x7f) | ||||
| 		v >>= 7 | ||||
| 		if v != 0 { | ||||
| 			c |= 0x80 | ||||
| 		} | ||||
| 		b = append(b, c) | ||||
| 		if c&0x80 == 0 { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| // AppendSleb128 appends v to b using DWARF's signed LEB128 encoding. | ||||
| func AppendSleb128(b []byte, v int64) []byte { | ||||
| 	for { | ||||
| 		c := uint8(v & 0x7f) | ||||
| 		s := uint8(v & 0x40) | ||||
| 		v >>= 7 | ||||
| 		if (v != -1 || s == 0) && (v != 0 || s != 0) { | ||||
| 			c |= 0x80 | ||||
| 		} | ||||
| 		b = append(b, c) | ||||
| 		if c&0x80 == 0 { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| var encbuf [20]byte | ||||
|  | ||||
| // AppendUleb128 appends v to s using DWARF's unsigned LEB128 encoding. | ||||
| func Uleb128put(ctxt Context, s Sym, v int64) { | ||||
| 	b := AppendUleb128(encbuf[:0], uint64(v)) | ||||
| 	ctxt.AddBytes(s, b) | ||||
| } | ||||
|  | ||||
| // AppendUleb128 appends v to s using DWARF's signed LEB128 encoding. | ||||
| func Sleb128put(ctxt Context, s Sym, v int64) { | ||||
| 	b := AppendSleb128(encbuf[:0], v) | ||||
| 	ctxt.AddBytes(s, b) | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Defining Abbrevs.  This is hardcoded, and there will be | ||||
|  * only a handful of them.  The DWARF spec places no restriction on | ||||
|  * the ordering of attributes in the Abbrevs and DIEs, and we will | ||||
|  * always write them out in the order of declaration in the abbrev. | ||||
|  */ | ||||
| type dwAttrForm struct { | ||||
| 	attr uint16 | ||||
| 	form uint8 | ||||
| } | ||||
|  | ||||
| // Go-specific type attributes. | ||||
| const ( | ||||
| 	DW_AT_go_kind = 0x2900 | ||||
| 	DW_AT_go_key  = 0x2901 | ||||
| 	DW_AT_go_elem = 0x2902 | ||||
|  | ||||
| 	DW_AT_internal_location = 253 // params and locals; not emitted | ||||
| ) | ||||
|  | ||||
| // Index into the abbrevs table below. | ||||
| // Keep in sync with ispubname() and ispubtype() below. | ||||
| // ispubtype considers >= NULLTYPE public | ||||
| const ( | ||||
| 	DW_ABRV_NULL = iota | ||||
| 	DW_ABRV_COMPUNIT | ||||
| 	DW_ABRV_FUNCTION | ||||
| 	DW_ABRV_VARIABLE | ||||
| 	DW_ABRV_AUTO | ||||
| 	DW_ABRV_PARAM | ||||
| 	DW_ABRV_STRUCTFIELD | ||||
| 	DW_ABRV_FUNCTYPEPARAM | ||||
| 	DW_ABRV_DOTDOTDOT | ||||
| 	DW_ABRV_ARRAYRANGE | ||||
| 	DW_ABRV_NULLTYPE | ||||
| 	DW_ABRV_BASETYPE | ||||
| 	DW_ABRV_ARRAYTYPE | ||||
| 	DW_ABRV_CHANTYPE | ||||
| 	DW_ABRV_FUNCTYPE | ||||
| 	DW_ABRV_IFACETYPE | ||||
| 	DW_ABRV_MAPTYPE | ||||
| 	DW_ABRV_PTRTYPE | ||||
| 	DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6. | ||||
| 	DW_ABRV_SLICETYPE | ||||
| 	DW_ABRV_STRINGTYPE | ||||
| 	DW_ABRV_STRUCTTYPE | ||||
| 	DW_ABRV_TYPEDECL | ||||
| 	DW_NABRV | ||||
| ) | ||||
|  | ||||
| type dwAbbrev struct { | ||||
| 	tag      uint8 | ||||
| 	children uint8 | ||||
| 	attr     []dwAttrForm | ||||
| } | ||||
|  | ||||
| var abbrevs = [DW_NABRV]dwAbbrev{ | ||||
| 	/* The mandatory DW_ABRV_NULL entry. */ | ||||
| 	{0, 0, []dwAttrForm{}}, | ||||
|  | ||||
| 	/* COMPUNIT */ | ||||
| 	{ | ||||
| 		DW_TAG_compile_unit, | ||||
| 		DW_CHILDREN_yes, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_language, DW_FORM_data1}, | ||||
| 			{DW_AT_low_pc, DW_FORM_addr}, | ||||
| 			{DW_AT_high_pc, DW_FORM_addr}, | ||||
| 			{DW_AT_stmt_list, DW_FORM_data4}, | ||||
| 			{DW_AT_comp_dir, DW_FORM_string}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* FUNCTION */ | ||||
| 	{ | ||||
| 		DW_TAG_subprogram, | ||||
| 		DW_CHILDREN_yes, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_low_pc, DW_FORM_addr}, | ||||
| 			{DW_AT_high_pc, DW_FORM_addr}, | ||||
| 			{DW_AT_external, DW_FORM_flag}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* VARIABLE */ | ||||
| 	{ | ||||
| 		DW_TAG_variable, | ||||
| 		DW_CHILDREN_no, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_location, DW_FORM_block1}, | ||||
| 			{DW_AT_type, DW_FORM_ref_addr}, | ||||
| 			{DW_AT_external, DW_FORM_flag}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* AUTO */ | ||||
| 	{ | ||||
| 		DW_TAG_variable, | ||||
| 		DW_CHILDREN_no, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_location, DW_FORM_block1}, | ||||
| 			{DW_AT_type, DW_FORM_ref_addr}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* PARAM */ | ||||
| 	{ | ||||
| 		DW_TAG_formal_parameter, | ||||
| 		DW_CHILDREN_no, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_location, DW_FORM_block1}, | ||||
| 			{DW_AT_type, DW_FORM_ref_addr}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* STRUCTFIELD */ | ||||
| 	{ | ||||
| 		DW_TAG_member, | ||||
| 		DW_CHILDREN_no, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_data_member_location, DW_FORM_block1}, | ||||
| 			{DW_AT_type, DW_FORM_ref_addr}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* FUNCTYPEPARAM */ | ||||
| 	{ | ||||
| 		DW_TAG_formal_parameter, | ||||
| 		DW_CHILDREN_no, | ||||
|  | ||||
| 		// No name! | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_type, DW_FORM_ref_addr}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* DOTDOTDOT */ | ||||
| 	{ | ||||
| 		DW_TAG_unspecified_parameters, | ||||
| 		DW_CHILDREN_no, | ||||
| 		[]dwAttrForm{}, | ||||
| 	}, | ||||
|  | ||||
| 	/* ARRAYRANGE */ | ||||
| 	{ | ||||
| 		DW_TAG_subrange_type, | ||||
| 		DW_CHILDREN_no, | ||||
|  | ||||
| 		// No name! | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_type, DW_FORM_ref_addr}, | ||||
| 			{DW_AT_count, DW_FORM_udata}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	// Below here are the types considered public by ispubtype | ||||
| 	/* NULLTYPE */ | ||||
| 	{ | ||||
| 		DW_TAG_unspecified_type, | ||||
| 		DW_CHILDREN_no, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* BASETYPE */ | ||||
| 	{ | ||||
| 		DW_TAG_base_type, | ||||
| 		DW_CHILDREN_no, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_encoding, DW_FORM_data1}, | ||||
| 			{DW_AT_byte_size, DW_FORM_data1}, | ||||
| 			{DW_AT_go_kind, DW_FORM_data1}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* ARRAYTYPE */ | ||||
| 	// child is subrange with upper bound | ||||
| 	{ | ||||
| 		DW_TAG_array_type, | ||||
| 		DW_CHILDREN_yes, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_type, DW_FORM_ref_addr}, | ||||
| 			{DW_AT_byte_size, DW_FORM_udata}, | ||||
| 			{DW_AT_go_kind, DW_FORM_data1}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* CHANTYPE */ | ||||
| 	{ | ||||
| 		DW_TAG_typedef, | ||||
| 		DW_CHILDREN_no, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_type, DW_FORM_ref_addr}, | ||||
| 			{DW_AT_go_kind, DW_FORM_data1}, | ||||
| 			{DW_AT_go_elem, DW_FORM_ref_addr}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* FUNCTYPE */ | ||||
| 	{ | ||||
| 		DW_TAG_subroutine_type, | ||||
| 		DW_CHILDREN_yes, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			// {DW_AT_type,	DW_FORM_ref_addr}, | ||||
| 			{DW_AT_go_kind, DW_FORM_data1}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* IFACETYPE */ | ||||
| 	{ | ||||
| 		DW_TAG_typedef, | ||||
| 		DW_CHILDREN_yes, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_type, DW_FORM_ref_addr}, | ||||
| 			{DW_AT_go_kind, DW_FORM_data1}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* MAPTYPE */ | ||||
| 	{ | ||||
| 		DW_TAG_typedef, | ||||
| 		DW_CHILDREN_no, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_type, DW_FORM_ref_addr}, | ||||
| 			{DW_AT_go_kind, DW_FORM_data1}, | ||||
| 			{DW_AT_go_key, DW_FORM_ref_addr}, | ||||
| 			{DW_AT_go_elem, DW_FORM_ref_addr}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* PTRTYPE */ | ||||
| 	{ | ||||
| 		DW_TAG_pointer_type, | ||||
| 		DW_CHILDREN_no, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_type, DW_FORM_ref_addr}, | ||||
| 			{DW_AT_go_kind, DW_FORM_data1}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* BARE_PTRTYPE */ | ||||
| 	{ | ||||
| 		DW_TAG_pointer_type, | ||||
| 		DW_CHILDREN_no, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* SLICETYPE */ | ||||
| 	{ | ||||
| 		DW_TAG_structure_type, | ||||
| 		DW_CHILDREN_yes, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_byte_size, DW_FORM_udata}, | ||||
| 			{DW_AT_go_kind, DW_FORM_data1}, | ||||
| 			{DW_AT_go_elem, DW_FORM_ref_addr}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* STRINGTYPE */ | ||||
| 	{ | ||||
| 		DW_TAG_structure_type, | ||||
| 		DW_CHILDREN_yes, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_byte_size, DW_FORM_udata}, | ||||
| 			{DW_AT_go_kind, DW_FORM_data1}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* STRUCTTYPE */ | ||||
| 	{ | ||||
| 		DW_TAG_structure_type, | ||||
| 		DW_CHILDREN_yes, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_byte_size, DW_FORM_udata}, | ||||
| 			{DW_AT_go_kind, DW_FORM_data1}, | ||||
| 		}, | ||||
| 	}, | ||||
|  | ||||
| 	/* TYPEDECL */ | ||||
| 	{ | ||||
| 		DW_TAG_typedef, | ||||
| 		DW_CHILDREN_no, | ||||
| 		[]dwAttrForm{ | ||||
| 			{DW_AT_name, DW_FORM_string}, | ||||
| 			{DW_AT_type, DW_FORM_ref_addr}, | ||||
| 		}, | ||||
| 	}, | ||||
| } | ||||
|  | ||||
| // GetAbbrev returns the contents of the .debug_abbrev section. | ||||
| func GetAbbrev() []byte { | ||||
| 	var buf []byte | ||||
| 	for i := 1; i < DW_NABRV; i++ { | ||||
| 		// See section 7.5.3 | ||||
| 		buf = AppendUleb128(buf, uint64(i)) | ||||
|  | ||||
| 		buf = AppendUleb128(buf, uint64(abbrevs[i].tag)) | ||||
| 		buf = append(buf, byte(abbrevs[i].children)) | ||||
| 		for _, f := range abbrevs[i].attr { | ||||
| 			buf = AppendUleb128(buf, uint64(f.attr)) | ||||
| 			buf = AppendUleb128(buf, uint64(f.form)) | ||||
| 		} | ||||
| 		buf = append(buf, 0, 0) | ||||
| 	} | ||||
| 	return append(buf, 0) | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Debugging Information Entries and their attributes. | ||||
|  */ | ||||
|  | ||||
| // DWAttr represents an attribute of a DWDie. | ||||
| // | ||||
| // For DW_CLS_string and _block, value should contain the length, and | ||||
| // data the data, for _reference, value is 0 and data is a DWDie* to | ||||
| // the referenced instance, for all others, value is the whole thing | ||||
| // and data is null. | ||||
| type DWAttr struct { | ||||
| 	Link  *DWAttr | ||||
| 	Atr   uint16 // DW_AT_ | ||||
| 	Cls   uint8  // DW_CLS_ | ||||
| 	Value int64 | ||||
| 	Data  interface{} | ||||
| } | ||||
|  | ||||
| // DWDie represents a DWARF debug info entry. | ||||
| type DWDie struct { | ||||
| 	Abbrev int | ||||
| 	Link   *DWDie | ||||
| 	Child  *DWDie | ||||
| 	Attr   *DWAttr | ||||
| 	Sym    Sym | ||||
| } | ||||
|  | ||||
| func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, data interface{}) error { | ||||
| 	switch form { | ||||
| 	case DW_FORM_addr: // address | ||||
| 		ctxt.AddAddress(s, data, value) | ||||
|  | ||||
| 	case DW_FORM_block1: // block | ||||
| 		if cls == DW_CLS_ADDRESS { | ||||
| 			ctxt.AddInt(s, 1, int64(1+ctxt.PtrSize())) | ||||
| 			ctxt.AddInt(s, 1, DW_OP_addr) | ||||
| 			ctxt.AddAddress(s, data, 0) | ||||
| 			break | ||||
| 		} | ||||
|  | ||||
| 		value &= 0xff | ||||
| 		ctxt.AddInt(s, 1, value) | ||||
| 		p := data.([]byte)[:value] | ||||
| 		ctxt.AddBytes(s, p) | ||||
|  | ||||
| 	case DW_FORM_block2: // block | ||||
| 		value &= 0xffff | ||||
|  | ||||
| 		ctxt.AddInt(s, 2, value) | ||||
| 		p := data.([]byte)[:value] | ||||
| 		ctxt.AddBytes(s, p) | ||||
|  | ||||
| 	case DW_FORM_block4: // block | ||||
| 		value &= 0xffffffff | ||||
|  | ||||
| 		ctxt.AddInt(s, 4, value) | ||||
| 		p := data.([]byte)[:value] | ||||
| 		ctxt.AddBytes(s, p) | ||||
|  | ||||
| 	case DW_FORM_block: // block | ||||
| 		Uleb128put(ctxt, s, value) | ||||
|  | ||||
| 		p := data.([]byte)[:value] | ||||
| 		ctxt.AddBytes(s, p) | ||||
|  | ||||
| 	case DW_FORM_data1: // constant | ||||
| 		ctxt.AddInt(s, 1, value) | ||||
|  | ||||
| 	case DW_FORM_data2: // constant | ||||
| 		ctxt.AddInt(s, 2, value) | ||||
|  | ||||
| 	case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr | ||||
| 		if cls == DW_CLS_PTR { // DW_AT_stmt_list | ||||
| 			ctxt.AddSectionOffset(s, 4, data, 0) | ||||
| 			break | ||||
| 		} | ||||
| 		ctxt.AddInt(s, 4, value) | ||||
|  | ||||
| 	case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr | ||||
| 		ctxt.AddInt(s, 8, value) | ||||
|  | ||||
| 	case DW_FORM_sdata: // constant | ||||
| 		Sleb128put(ctxt, s, value) | ||||
|  | ||||
| 	case DW_FORM_udata: // constant | ||||
| 		Uleb128put(ctxt, s, value) | ||||
|  | ||||
| 	case DW_FORM_string: // string | ||||
| 		str := data.(string) | ||||
| 		ctxt.AddString(s, str) | ||||
| 		// TODO(ribrdb): verify padded strings are never used and remove this | ||||
| 		for i := int64(len(str)); i < value; i++ { | ||||
| 			ctxt.AddInt(s, 1, 0) | ||||
| 		} | ||||
|  | ||||
| 	case DW_FORM_flag: // flag | ||||
| 		if value != 0 { | ||||
| 			ctxt.AddInt(s, 1, 1) | ||||
| 		} else { | ||||
| 			ctxt.AddInt(s, 1, 0) | ||||
| 		} | ||||
|  | ||||
| 	// In DWARF 2 (which is what we claim to generate), | ||||
| 	// the ref_addr is the same size as a normal address. | ||||
| 	// In DWARF 3 it is always 32 bits, unless emitting a large | ||||
| 	// (> 4 GB of debug info aka "64-bit") unit, which we don't implement. | ||||
| 	case DW_FORM_ref_addr: // reference to a DIE in the .info section | ||||
| 		if data == nil { | ||||
| 			return fmt.Errorf("dwarf: null reference in %d", abbrev) | ||||
| 		} else { | ||||
| 			ctxt.AddSectionOffset(s, ctxt.PtrSize(), data, 0) | ||||
| 		} | ||||
|  | ||||
| 	case DW_FORM_ref1, // reference within the compilation unit | ||||
| 		DW_FORM_ref2,      // reference | ||||
| 		DW_FORM_ref4,      // reference | ||||
| 		DW_FORM_ref8,      // reference | ||||
| 		DW_FORM_ref_udata, // reference | ||||
|  | ||||
| 		DW_FORM_strp,     // string | ||||
| 		DW_FORM_indirect: // (see Section 7.5.3) | ||||
| 		fallthrough | ||||
| 	default: | ||||
| 		return fmt.Errorf("dwarf: unsupported attribute form %d / class %d", form, cls) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // PutAttrs writes the attributes for a DIE to symbol 's'. | ||||
| // | ||||
| // Note that we can (and do) add arbitrary attributes to a DIE, but | ||||
| // only the ones actually listed in the Abbrev will be written out. | ||||
| func PutAttrs(ctxt Context, s Sym, abbrev int, attr *DWAttr) { | ||||
| Outer: | ||||
| 	for _, f := range abbrevs[abbrev].attr { | ||||
| 		for ap := attr; ap != nil; ap = ap.Link { | ||||
| 			if ap.Atr == f.attr { | ||||
| 				putattr(ctxt, s, abbrev, int(f.form), int(ap.Cls), ap.Value, ap.Data) | ||||
| 				continue Outer | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		putattr(ctxt, s, abbrev, int(f.form), 0, 0, nil) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // HasChildren returns true if 'die' uses an abbrev that supports children. | ||||
| func HasChildren(die *DWDie) bool { | ||||
| 	return abbrevs[die.Abbrev].children != 0 | ||||
| } | ||||
|  | ||||
| // PutFunc writes a DIE for a function to s. | ||||
| // It also writes child DIEs for each variable in vars. | ||||
| func PutFunc(ctxt Context, s Sym, name string, external bool, startPC Sym, size int64, vars *Var) { | ||||
| 	Uleb128put(ctxt, s, DW_ABRV_FUNCTION) | ||||
| 	putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name) | ||||
| 	putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_addr, DW_CLS_ADDRESS, 0, startPC) | ||||
| 	putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_addr, DW_CLS_ADDRESS, size+ctxt.SymValue(startPC), startPC) | ||||
| 	var ev int64 | ||||
| 	if external { | ||||
| 		ev = 1 | ||||
| 	} | ||||
| 	putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_flag, DW_CLS_FLAG, ev, 0) | ||||
| 	names := make(map[string]bool) | ||||
| 	for v := vars; v != nil; v = v.Link { | ||||
| 		var n string | ||||
| 		if names[v.Name] { | ||||
| 			n = fmt.Sprintf("%s#%d", v.Name, len(names)) | ||||
| 		} else { | ||||
| 			n = v.Name | ||||
| 		} | ||||
| 		names[n] = true | ||||
|  | ||||
| 		Uleb128put(ctxt, s, int64(v.Abbrev)) | ||||
| 		putattr(ctxt, s, v.Abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n) | ||||
| 		loc := append(encbuf[:0], DW_OP_call_frame_cfa) | ||||
| 		if v.Offset != 0 { | ||||
| 			loc = append(loc, DW_OP_consts) | ||||
| 			loc = AppendSleb128(loc, int64(v.Offset)) | ||||
| 			loc = append(loc, DW_OP_plus) | ||||
| 		} | ||||
| 		putattr(ctxt, s, v.Abbrev, DW_FORM_block1, DW_CLS_BLOCK, int64(len(loc)), loc) | ||||
| 		putattr(ctxt, s, v.Abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type) | ||||
|  | ||||
| 	} | ||||
| 	Uleb128put(ctxt, s, 0) | ||||
| } | ||||
							
								
								
									
										483
									
								
								vendor/github.com/google/gops/internal/dwarf/dwarf_defs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										483
									
								
								vendor/github.com/google/gops/internal/dwarf/dwarf_defs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,483 @@ | ||||
| // Copyright 2010 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package dwarf | ||||
|  | ||||
| // Cut, pasted, tr-and-awk'ed from tables in | ||||
| // http://dwarfstd.org/doc/Dwarf3.pdf | ||||
|  | ||||
| // Table 18 | ||||
| const ( | ||||
| 	DW_TAG_array_type               = 0x01 | ||||
| 	DW_TAG_class_type               = 0x02 | ||||
| 	DW_TAG_entry_point              = 0x03 | ||||
| 	DW_TAG_enumeration_type         = 0x04 | ||||
| 	DW_TAG_formal_parameter         = 0x05 | ||||
| 	DW_TAG_imported_declaration     = 0x08 | ||||
| 	DW_TAG_label                    = 0x0a | ||||
| 	DW_TAG_lexical_block            = 0x0b | ||||
| 	DW_TAG_member                   = 0x0d | ||||
| 	DW_TAG_pointer_type             = 0x0f | ||||
| 	DW_TAG_reference_type           = 0x10 | ||||
| 	DW_TAG_compile_unit             = 0x11 | ||||
| 	DW_TAG_string_type              = 0x12 | ||||
| 	DW_TAG_structure_type           = 0x13 | ||||
| 	DW_TAG_subroutine_type          = 0x15 | ||||
| 	DW_TAG_typedef                  = 0x16 | ||||
| 	DW_TAG_union_type               = 0x17 | ||||
| 	DW_TAG_unspecified_parameters   = 0x18 | ||||
| 	DW_TAG_variant                  = 0x19 | ||||
| 	DW_TAG_common_block             = 0x1a | ||||
| 	DW_TAG_common_inclusion         = 0x1b | ||||
| 	DW_TAG_inheritance              = 0x1c | ||||
| 	DW_TAG_inlined_subroutine       = 0x1d | ||||
| 	DW_TAG_module                   = 0x1e | ||||
| 	DW_TAG_ptr_to_member_type       = 0x1f | ||||
| 	DW_TAG_set_type                 = 0x20 | ||||
| 	DW_TAG_subrange_type            = 0x21 | ||||
| 	DW_TAG_with_stmt                = 0x22 | ||||
| 	DW_TAG_access_declaration       = 0x23 | ||||
| 	DW_TAG_base_type                = 0x24 | ||||
| 	DW_TAG_catch_block              = 0x25 | ||||
| 	DW_TAG_const_type               = 0x26 | ||||
| 	DW_TAG_constant                 = 0x27 | ||||
| 	DW_TAG_enumerator               = 0x28 | ||||
| 	DW_TAG_file_type                = 0x29 | ||||
| 	DW_TAG_friend                   = 0x2a | ||||
| 	DW_TAG_namelist                 = 0x2b | ||||
| 	DW_TAG_namelist_item            = 0x2c | ||||
| 	DW_TAG_packed_type              = 0x2d | ||||
| 	DW_TAG_subprogram               = 0x2e | ||||
| 	DW_TAG_template_type_parameter  = 0x2f | ||||
| 	DW_TAG_template_value_parameter = 0x30 | ||||
| 	DW_TAG_thrown_type              = 0x31 | ||||
| 	DW_TAG_try_block                = 0x32 | ||||
| 	DW_TAG_variant_part             = 0x33 | ||||
| 	DW_TAG_variable                 = 0x34 | ||||
| 	DW_TAG_volatile_type            = 0x35 | ||||
| 	// Dwarf3 | ||||
| 	DW_TAG_dwarf_procedure  = 0x36 | ||||
| 	DW_TAG_restrict_type    = 0x37 | ||||
| 	DW_TAG_interface_type   = 0x38 | ||||
| 	DW_TAG_namespace        = 0x39 | ||||
| 	DW_TAG_imported_module  = 0x3a | ||||
| 	DW_TAG_unspecified_type = 0x3b | ||||
| 	DW_TAG_partial_unit     = 0x3c | ||||
| 	DW_TAG_imported_unit    = 0x3d | ||||
| 	DW_TAG_condition        = 0x3f | ||||
| 	DW_TAG_shared_type      = 0x40 | ||||
| 	// Dwarf4 | ||||
| 	DW_TAG_type_unit             = 0x41 | ||||
| 	DW_TAG_rvalue_reference_type = 0x42 | ||||
| 	DW_TAG_template_alias        = 0x43 | ||||
|  | ||||
| 	// User defined | ||||
| 	DW_TAG_lo_user = 0x4080 | ||||
| 	DW_TAG_hi_user = 0xffff | ||||
| ) | ||||
|  | ||||
| // Table 19 | ||||
| const ( | ||||
| 	DW_CHILDREN_no  = 0x00 | ||||
| 	DW_CHILDREN_yes = 0x01 | ||||
| ) | ||||
|  | ||||
| // Not from the spec, but logically belongs here | ||||
| const ( | ||||
| 	DW_CLS_ADDRESS = 0x01 + iota | ||||
| 	DW_CLS_BLOCK | ||||
| 	DW_CLS_CONSTANT | ||||
| 	DW_CLS_FLAG | ||||
| 	DW_CLS_PTR // lineptr, loclistptr, macptr, rangelistptr | ||||
| 	DW_CLS_REFERENCE | ||||
| 	DW_CLS_ADDRLOC | ||||
| 	DW_CLS_STRING | ||||
| ) | ||||
|  | ||||
| // Table 20 | ||||
| const ( | ||||
| 	DW_AT_sibling              = 0x01 // reference | ||||
| 	DW_AT_location             = 0x02 // block, loclistptr | ||||
| 	DW_AT_name                 = 0x03 // string | ||||
| 	DW_AT_ordering             = 0x09 // constant | ||||
| 	DW_AT_byte_size            = 0x0b // block, constant, reference | ||||
| 	DW_AT_bit_offset           = 0x0c // block, constant, reference | ||||
| 	DW_AT_bit_size             = 0x0d // block, constant, reference | ||||
| 	DW_AT_stmt_list            = 0x10 // lineptr | ||||
| 	DW_AT_low_pc               = 0x11 // address | ||||
| 	DW_AT_high_pc              = 0x12 // address | ||||
| 	DW_AT_language             = 0x13 // constant | ||||
| 	DW_AT_discr                = 0x15 // reference | ||||
| 	DW_AT_discr_value          = 0x16 // constant | ||||
| 	DW_AT_visibility           = 0x17 // constant | ||||
| 	DW_AT_import               = 0x18 // reference | ||||
| 	DW_AT_string_length        = 0x19 // block, loclistptr | ||||
| 	DW_AT_common_reference     = 0x1a // reference | ||||
| 	DW_AT_comp_dir             = 0x1b // string | ||||
| 	DW_AT_const_value          = 0x1c // block, constant, string | ||||
| 	DW_AT_containing_type      = 0x1d // reference | ||||
| 	DW_AT_default_value        = 0x1e // reference | ||||
| 	DW_AT_inline               = 0x20 // constant | ||||
| 	DW_AT_is_optional          = 0x21 // flag | ||||
| 	DW_AT_lower_bound          = 0x22 // block, constant, reference | ||||
| 	DW_AT_producer             = 0x25 // string | ||||
| 	DW_AT_prototyped           = 0x27 // flag | ||||
| 	DW_AT_return_addr          = 0x2a // block, loclistptr | ||||
| 	DW_AT_start_scope          = 0x2c // constant | ||||
| 	DW_AT_bit_stride           = 0x2e // constant | ||||
| 	DW_AT_upper_bound          = 0x2f // block, constant, reference | ||||
| 	DW_AT_abstract_origin      = 0x31 // reference | ||||
| 	DW_AT_accessibility        = 0x32 // constant | ||||
| 	DW_AT_address_class        = 0x33 // constant | ||||
| 	DW_AT_artificial           = 0x34 // flag | ||||
| 	DW_AT_base_types           = 0x35 // reference | ||||
| 	DW_AT_calling_convention   = 0x36 // constant | ||||
| 	DW_AT_count                = 0x37 // block, constant, reference | ||||
| 	DW_AT_data_member_location = 0x38 // block, constant, loclistptr | ||||
| 	DW_AT_decl_column          = 0x39 // constant | ||||
| 	DW_AT_decl_file            = 0x3a // constant | ||||
| 	DW_AT_decl_line            = 0x3b // constant | ||||
| 	DW_AT_declaration          = 0x3c // flag | ||||
| 	DW_AT_discr_list           = 0x3d // block | ||||
| 	DW_AT_encoding             = 0x3e // constant | ||||
| 	DW_AT_external             = 0x3f // flag | ||||
| 	DW_AT_frame_base           = 0x40 // block, loclistptr | ||||
| 	DW_AT_friend               = 0x41 // reference | ||||
| 	DW_AT_identifier_case      = 0x42 // constant | ||||
| 	DW_AT_macro_info           = 0x43 // macptr | ||||
| 	DW_AT_namelist_item        = 0x44 // block | ||||
| 	DW_AT_priority             = 0x45 // reference | ||||
| 	DW_AT_segment              = 0x46 // block, loclistptr | ||||
| 	DW_AT_specification        = 0x47 // reference | ||||
| 	DW_AT_static_link          = 0x48 // block, loclistptr | ||||
| 	DW_AT_type                 = 0x49 // reference | ||||
| 	DW_AT_use_location         = 0x4a // block, loclistptr | ||||
| 	DW_AT_variable_parameter   = 0x4b // flag | ||||
| 	DW_AT_virtuality           = 0x4c // constant | ||||
| 	DW_AT_vtable_elem_location = 0x4d // block, loclistptr | ||||
| 	// Dwarf3 | ||||
| 	DW_AT_allocated      = 0x4e // block, constant, reference | ||||
| 	DW_AT_associated     = 0x4f // block, constant, reference | ||||
| 	DW_AT_data_location  = 0x50 // block | ||||
| 	DW_AT_byte_stride    = 0x51 // block, constant, reference | ||||
| 	DW_AT_entry_pc       = 0x52 // address | ||||
| 	DW_AT_use_UTF8       = 0x53 // flag | ||||
| 	DW_AT_extension      = 0x54 // reference | ||||
| 	DW_AT_ranges         = 0x55 // rangelistptr | ||||
| 	DW_AT_trampoline     = 0x56 // address, flag, reference, string | ||||
| 	DW_AT_call_column    = 0x57 // constant | ||||
| 	DW_AT_call_file      = 0x58 // constant | ||||
| 	DW_AT_call_line      = 0x59 // constant | ||||
| 	DW_AT_description    = 0x5a // string | ||||
| 	DW_AT_binary_scale   = 0x5b // constant | ||||
| 	DW_AT_decimal_scale  = 0x5c // constant | ||||
| 	DW_AT_small          = 0x5d // reference | ||||
| 	DW_AT_decimal_sign   = 0x5e // constant | ||||
| 	DW_AT_digit_count    = 0x5f // constant | ||||
| 	DW_AT_picture_string = 0x60 // string | ||||
| 	DW_AT_mutable        = 0x61 // flag | ||||
| 	DW_AT_threads_scaled = 0x62 // flag | ||||
| 	DW_AT_explicit       = 0x63 // flag | ||||
| 	DW_AT_object_pointer = 0x64 // reference | ||||
| 	DW_AT_endianity      = 0x65 // constant | ||||
| 	DW_AT_elemental      = 0x66 // flag | ||||
| 	DW_AT_pure           = 0x67 // flag | ||||
| 	DW_AT_recursive      = 0x68 // flag | ||||
|  | ||||
| 	DW_AT_lo_user = 0x2000 // --- | ||||
| 	DW_AT_hi_user = 0x3fff // --- | ||||
| ) | ||||
|  | ||||
| // Table 21 | ||||
| const ( | ||||
| 	DW_FORM_addr      = 0x01 // address | ||||
| 	DW_FORM_block2    = 0x03 // block | ||||
| 	DW_FORM_block4    = 0x04 // block | ||||
| 	DW_FORM_data2     = 0x05 // constant | ||||
| 	DW_FORM_data4     = 0x06 // constant, lineptr, loclistptr, macptr, rangelistptr | ||||
| 	DW_FORM_data8     = 0x07 // constant, lineptr, loclistptr, macptr, rangelistptr | ||||
| 	DW_FORM_string    = 0x08 // string | ||||
| 	DW_FORM_block     = 0x09 // block | ||||
| 	DW_FORM_block1    = 0x0a // block | ||||
| 	DW_FORM_data1     = 0x0b // constant | ||||
| 	DW_FORM_flag      = 0x0c // flag | ||||
| 	DW_FORM_sdata     = 0x0d // constant | ||||
| 	DW_FORM_strp      = 0x0e // string | ||||
| 	DW_FORM_udata     = 0x0f // constant | ||||
| 	DW_FORM_ref_addr  = 0x10 // reference | ||||
| 	DW_FORM_ref1      = 0x11 // reference | ||||
| 	DW_FORM_ref2      = 0x12 // reference | ||||
| 	DW_FORM_ref4      = 0x13 // reference | ||||
| 	DW_FORM_ref8      = 0x14 // reference | ||||
| 	DW_FORM_ref_udata = 0x15 // reference | ||||
| 	DW_FORM_indirect  = 0x16 // (see Section 7.5.3) | ||||
| ) | ||||
|  | ||||
| // Table 24 (#operands, notes) | ||||
| const ( | ||||
| 	DW_OP_addr                = 0x03 // 1 constant address (size target specific) | ||||
| 	DW_OP_deref               = 0x06 // 0 | ||||
| 	DW_OP_const1u             = 0x08 // 1 1-byte constant | ||||
| 	DW_OP_const1s             = 0x09 // 1 1-byte constant | ||||
| 	DW_OP_const2u             = 0x0a // 1 2-byte constant | ||||
| 	DW_OP_const2s             = 0x0b // 1 2-byte constant | ||||
| 	DW_OP_const4u             = 0x0c // 1 4-byte constant | ||||
| 	DW_OP_const4s             = 0x0d // 1 4-byte constant | ||||
| 	DW_OP_const8u             = 0x0e // 1 8-byte constant | ||||
| 	DW_OP_const8s             = 0x0f // 1 8-byte constant | ||||
| 	DW_OP_constu              = 0x10 // 1 ULEB128 constant | ||||
| 	DW_OP_consts              = 0x11 // 1 SLEB128 constant | ||||
| 	DW_OP_dup                 = 0x12 // 0 | ||||
| 	DW_OP_drop                = 0x13 // 0 | ||||
| 	DW_OP_over                = 0x14 // 0 | ||||
| 	DW_OP_pick                = 0x15 // 1 1-byte stack index | ||||
| 	DW_OP_swap                = 0x16 // 0 | ||||
| 	DW_OP_rot                 = 0x17 // 0 | ||||
| 	DW_OP_xderef              = 0x18 // 0 | ||||
| 	DW_OP_abs                 = 0x19 // 0 | ||||
| 	DW_OP_and                 = 0x1a // 0 | ||||
| 	DW_OP_div                 = 0x1b // 0 | ||||
| 	DW_OP_minus               = 0x1c // 0 | ||||
| 	DW_OP_mod                 = 0x1d // 0 | ||||
| 	DW_OP_mul                 = 0x1e // 0 | ||||
| 	DW_OP_neg                 = 0x1f // 0 | ||||
| 	DW_OP_not                 = 0x20 // 0 | ||||
| 	DW_OP_or                  = 0x21 // 0 | ||||
| 	DW_OP_plus                = 0x22 // 0 | ||||
| 	DW_OP_plus_uconst         = 0x23 // 1 ULEB128 addend | ||||
| 	DW_OP_shl                 = 0x24 // 0 | ||||
| 	DW_OP_shr                 = 0x25 // 0 | ||||
| 	DW_OP_shra                = 0x26 // 0 | ||||
| 	DW_OP_xor                 = 0x27 // 0 | ||||
| 	DW_OP_skip                = 0x2f // 1 signed 2-byte constant | ||||
| 	DW_OP_bra                 = 0x28 // 1 signed 2-byte constant | ||||
| 	DW_OP_eq                  = 0x29 // 0 | ||||
| 	DW_OP_ge                  = 0x2a // 0 | ||||
| 	DW_OP_gt                  = 0x2b // 0 | ||||
| 	DW_OP_le                  = 0x2c // 0 | ||||
| 	DW_OP_lt                  = 0x2d // 0 | ||||
| 	DW_OP_ne                  = 0x2e // 0 | ||||
| 	DW_OP_lit0                = 0x30 // 0 ... | ||||
| 	DW_OP_lit31               = 0x4f // 0 literals 0..31 = (DW_OP_lit0 + literal) | ||||
| 	DW_OP_reg0                = 0x50 // 0 .. | ||||
| 	DW_OP_reg31               = 0x6f // 0 reg 0..31 = (DW_OP_reg0 + regnum) | ||||
| 	DW_OP_breg0               = 0x70 // 1 ... | ||||
| 	DW_OP_breg31              = 0x8f // 1 SLEB128 offset base register 0..31 = (DW_OP_breg0 + regnum) | ||||
| 	DW_OP_regx                = 0x90 // 1 ULEB128 register | ||||
| 	DW_OP_fbreg               = 0x91 // 1 SLEB128 offset | ||||
| 	DW_OP_bregx               = 0x92 // 2 ULEB128 register followed by SLEB128 offset | ||||
| 	DW_OP_piece               = 0x93 // 1 ULEB128 size of piece addressed | ||||
| 	DW_OP_deref_size          = 0x94 // 1 1-byte size of data retrieved | ||||
| 	DW_OP_xderef_size         = 0x95 // 1 1-byte size of data retrieved | ||||
| 	DW_OP_nop                 = 0x96 // 0 | ||||
| 	DW_OP_push_object_address = 0x97 // 0 | ||||
| 	DW_OP_call2               = 0x98 // 1 2-byte offset of DIE | ||||
| 	DW_OP_call4               = 0x99 // 1 4-byte offset of DIE | ||||
| 	DW_OP_call_ref            = 0x9a // 1 4- or 8-byte offset of DIE | ||||
| 	DW_OP_form_tls_address    = 0x9b // 0 | ||||
| 	DW_OP_call_frame_cfa      = 0x9c // 0 | ||||
| 	DW_OP_bit_piece           = 0x9d // 2 | ||||
| 	DW_OP_lo_user             = 0xe0 | ||||
| 	DW_OP_hi_user             = 0xff | ||||
| ) | ||||
|  | ||||
| // Table 25 | ||||
| const ( | ||||
| 	DW_ATE_address         = 0x01 | ||||
| 	DW_ATE_boolean         = 0x02 | ||||
| 	DW_ATE_complex_float   = 0x03 | ||||
| 	DW_ATE_float           = 0x04 | ||||
| 	DW_ATE_signed          = 0x05 | ||||
| 	DW_ATE_signed_char     = 0x06 | ||||
| 	DW_ATE_unsigned        = 0x07 | ||||
| 	DW_ATE_unsigned_char   = 0x08 | ||||
| 	DW_ATE_imaginary_float = 0x09 | ||||
| 	DW_ATE_packed_decimal  = 0x0a | ||||
| 	DW_ATE_numeric_string  = 0x0b | ||||
| 	DW_ATE_edited          = 0x0c | ||||
| 	DW_ATE_signed_fixed    = 0x0d | ||||
| 	DW_ATE_unsigned_fixed  = 0x0e | ||||
| 	DW_ATE_decimal_float   = 0x0f | ||||
| 	DW_ATE_lo_user         = 0x80 | ||||
| 	DW_ATE_hi_user         = 0xff | ||||
| ) | ||||
|  | ||||
| // Table 26 | ||||
| const ( | ||||
| 	DW_DS_unsigned           = 0x01 | ||||
| 	DW_DS_leading_overpunch  = 0x02 | ||||
| 	DW_DS_trailing_overpunch = 0x03 | ||||
| 	DW_DS_leading_separate   = 0x04 | ||||
| 	DW_DS_trailing_separate  = 0x05 | ||||
| ) | ||||
|  | ||||
| // Table 27 | ||||
| const ( | ||||
| 	DW_END_default = 0x00 | ||||
| 	DW_END_big     = 0x01 | ||||
| 	DW_END_little  = 0x02 | ||||
| 	DW_END_lo_user = 0x40 | ||||
| 	DW_END_hi_user = 0xff | ||||
| ) | ||||
|  | ||||
| // Table 28 | ||||
| const ( | ||||
| 	DW_ACCESS_public    = 0x01 | ||||
| 	DW_ACCESS_protected = 0x02 | ||||
| 	DW_ACCESS_private   = 0x03 | ||||
| ) | ||||
|  | ||||
| // Table 29 | ||||
| const ( | ||||
| 	DW_VIS_local     = 0x01 | ||||
| 	DW_VIS_exported  = 0x02 | ||||
| 	DW_VIS_qualified = 0x03 | ||||
| ) | ||||
|  | ||||
| // Table 30 | ||||
| const ( | ||||
| 	DW_VIRTUALITY_none         = 0x00 | ||||
| 	DW_VIRTUALITY_virtual      = 0x01 | ||||
| 	DW_VIRTUALITY_pure_virtual = 0x02 | ||||
| ) | ||||
|  | ||||
| // Table 31 | ||||
| const ( | ||||
| 	DW_LANG_C89         = 0x0001 | ||||
| 	DW_LANG_C           = 0x0002 | ||||
| 	DW_LANG_Ada83       = 0x0003 | ||||
| 	DW_LANG_C_plus_plus = 0x0004 | ||||
| 	DW_LANG_Cobol74     = 0x0005 | ||||
| 	DW_LANG_Cobol85     = 0x0006 | ||||
| 	DW_LANG_Fortran77   = 0x0007 | ||||
| 	DW_LANG_Fortran90   = 0x0008 | ||||
| 	DW_LANG_Pascal83    = 0x0009 | ||||
| 	DW_LANG_Modula2     = 0x000a | ||||
| 	// Dwarf3 | ||||
| 	DW_LANG_Java           = 0x000b | ||||
| 	DW_LANG_C99            = 0x000c | ||||
| 	DW_LANG_Ada95          = 0x000d | ||||
| 	DW_LANG_Fortran95      = 0x000e | ||||
| 	DW_LANG_PLI            = 0x000f | ||||
| 	DW_LANG_ObjC           = 0x0010 | ||||
| 	DW_LANG_ObjC_plus_plus = 0x0011 | ||||
| 	DW_LANG_UPC            = 0x0012 | ||||
| 	DW_LANG_D              = 0x0013 | ||||
| 	// Dwarf4 | ||||
| 	DW_LANG_Python = 0x0014 | ||||
| 	// Dwarf5 | ||||
| 	DW_LANG_Go = 0x0016 | ||||
|  | ||||
| 	DW_LANG_lo_user = 0x8000 | ||||
| 	DW_LANG_hi_user = 0xffff | ||||
| ) | ||||
|  | ||||
| // Table 32 | ||||
| const ( | ||||
| 	DW_ID_case_sensitive   = 0x00 | ||||
| 	DW_ID_up_case          = 0x01 | ||||
| 	DW_ID_down_case        = 0x02 | ||||
| 	DW_ID_case_insensitive = 0x03 | ||||
| ) | ||||
|  | ||||
| // Table 33 | ||||
| const ( | ||||
| 	DW_CC_normal  = 0x01 | ||||
| 	DW_CC_program = 0x02 | ||||
| 	DW_CC_nocall  = 0x03 | ||||
| 	DW_CC_lo_user = 0x40 | ||||
| 	DW_CC_hi_user = 0xff | ||||
| ) | ||||
|  | ||||
| // Table 34 | ||||
| const ( | ||||
| 	DW_INL_not_inlined          = 0x00 | ||||
| 	DW_INL_inlined              = 0x01 | ||||
| 	DW_INL_declared_not_inlined = 0x02 | ||||
| 	DW_INL_declared_inlined     = 0x03 | ||||
| ) | ||||
|  | ||||
| // Table 35 | ||||
| const ( | ||||
| 	DW_ORD_row_major = 0x00 | ||||
| 	DW_ORD_col_major = 0x01 | ||||
| ) | ||||
|  | ||||
| // Table 36 | ||||
| const ( | ||||
| 	DW_DSC_label = 0x00 | ||||
| 	DW_DSC_range = 0x01 | ||||
| ) | ||||
|  | ||||
| // Table 37 | ||||
| const ( | ||||
| 	DW_LNS_copy             = 0x01 | ||||
| 	DW_LNS_advance_pc       = 0x02 | ||||
| 	DW_LNS_advance_line     = 0x03 | ||||
| 	DW_LNS_set_file         = 0x04 | ||||
| 	DW_LNS_set_column       = 0x05 | ||||
| 	DW_LNS_negate_stmt      = 0x06 | ||||
| 	DW_LNS_set_basic_block  = 0x07 | ||||
| 	DW_LNS_const_add_pc     = 0x08 | ||||
| 	DW_LNS_fixed_advance_pc = 0x09 | ||||
| 	// Dwarf3 | ||||
| 	DW_LNS_set_prologue_end   = 0x0a | ||||
| 	DW_LNS_set_epilogue_begin = 0x0b | ||||
| 	DW_LNS_set_isa            = 0x0c | ||||
| ) | ||||
|  | ||||
| // Table 38 | ||||
| const ( | ||||
| 	DW_LNE_end_sequence = 0x01 | ||||
| 	DW_LNE_set_address  = 0x02 | ||||
| 	DW_LNE_define_file  = 0x03 | ||||
| 	DW_LNE_lo_user      = 0x80 | ||||
| 	DW_LNE_hi_user      = 0xff | ||||
| ) | ||||
|  | ||||
| // Table 39 | ||||
| const ( | ||||
| 	DW_MACINFO_define     = 0x01 | ||||
| 	DW_MACINFO_undef      = 0x02 | ||||
| 	DW_MACINFO_start_file = 0x03 | ||||
| 	DW_MACINFO_end_file   = 0x04 | ||||
| 	DW_MACINFO_vendor_ext = 0xff | ||||
| ) | ||||
|  | ||||
| // Table 40. | ||||
| const ( | ||||
| 	// operand,... | ||||
| 	DW_CFA_nop              = 0x00 | ||||
| 	DW_CFA_set_loc          = 0x01 // address | ||||
| 	DW_CFA_advance_loc1     = 0x02 // 1-byte delta | ||||
| 	DW_CFA_advance_loc2     = 0x03 // 2-byte delta | ||||
| 	DW_CFA_advance_loc4     = 0x04 // 4-byte delta | ||||
| 	DW_CFA_offset_extended  = 0x05 // ULEB128 register, ULEB128 offset | ||||
| 	DW_CFA_restore_extended = 0x06 // ULEB128 register | ||||
| 	DW_CFA_undefined        = 0x07 // ULEB128 register | ||||
| 	DW_CFA_same_value       = 0x08 // ULEB128 register | ||||
| 	DW_CFA_register         = 0x09 // ULEB128 register, ULEB128 register | ||||
| 	DW_CFA_remember_state   = 0x0a | ||||
| 	DW_CFA_restore_state    = 0x0b | ||||
|  | ||||
| 	DW_CFA_def_cfa            = 0x0c // ULEB128 register, ULEB128 offset | ||||
| 	DW_CFA_def_cfa_register   = 0x0d // ULEB128 register | ||||
| 	DW_CFA_def_cfa_offset     = 0x0e // ULEB128 offset | ||||
| 	DW_CFA_def_cfa_expression = 0x0f // BLOCK | ||||
| 	DW_CFA_expression         = 0x10 // ULEB128 register, BLOCK | ||||
| 	DW_CFA_offset_extended_sf = 0x11 // ULEB128 register, SLEB128 offset | ||||
| 	DW_CFA_def_cfa_sf         = 0x12 // ULEB128 register, SLEB128 offset | ||||
| 	DW_CFA_def_cfa_offset_sf  = 0x13 // SLEB128 offset | ||||
| 	DW_CFA_val_offset         = 0x14 // ULEB128, ULEB128 | ||||
| 	DW_CFA_val_offset_sf      = 0x15 // ULEB128, SLEB128 | ||||
| 	DW_CFA_val_expression     = 0x16 // ULEB128, BLOCK | ||||
|  | ||||
| 	DW_CFA_lo_user = 0x1c | ||||
| 	DW_CFA_hi_user = 0x3f | ||||
|  | ||||
| 	// Opcodes that take an addend operand. | ||||
| 	DW_CFA_advance_loc = 0x1 << 6 // +delta | ||||
| 	DW_CFA_offset      = 0x2 << 6 // +register (ULEB128 offset) | ||||
| 	DW_CFA_restore     = 0x3 << 6 // +register | ||||
| ) | ||||
							
								
								
									
										714
									
								
								vendor/github.com/google/gops/internal/goobj/read.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										714
									
								
								vendor/github.com/google/gops/internal/goobj/read.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,714 @@ | ||||
| // Copyright 2013 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // Package goobj implements reading of Go object files and archives. | ||||
| // | ||||
| // TODO(rsc): Decide where this package should live. (golang.org/issue/6932) | ||||
| // TODO(rsc): Decide the appropriate integer types for various fields. | ||||
| // TODO(rsc): Write tests. (File format still up in the air a little.) | ||||
| package goobj | ||||
|  | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/google/gops/internal/obj" | ||||
| ) | ||||
|  | ||||
| // A SymKind describes the kind of memory represented by a symbol. | ||||
| type SymKind int | ||||
|  | ||||
| // This list is taken from include/link.h. | ||||
|  | ||||
| // Defined SymKind values. | ||||
| // TODO(rsc): Give idiomatic Go names. | ||||
| // TODO(rsc): Reduce the number of symbol types in the object files. | ||||
| const ( | ||||
| 	// readonly, executable | ||||
| 	STEXT      = SymKind(obj.STEXT) | ||||
| 	SELFRXSECT = SymKind(obj.SELFRXSECT) | ||||
|  | ||||
| 	// readonly, non-executable | ||||
| 	STYPE      = SymKind(obj.STYPE) | ||||
| 	SSTRING    = SymKind(obj.SSTRING) | ||||
| 	SGOSTRING  = SymKind(obj.SGOSTRING) | ||||
| 	SGOFUNC    = SymKind(obj.SGOFUNC) | ||||
| 	SRODATA    = SymKind(obj.SRODATA) | ||||
| 	SFUNCTAB   = SymKind(obj.SFUNCTAB) | ||||
| 	STYPELINK  = SymKind(obj.STYPELINK) | ||||
| 	SITABLINK  = SymKind(obj.SITABLINK) | ||||
| 	SSYMTAB    = SymKind(obj.SSYMTAB) // TODO: move to unmapped section | ||||
| 	SPCLNTAB   = SymKind(obj.SPCLNTAB) | ||||
| 	SELFROSECT = SymKind(obj.SELFROSECT) | ||||
|  | ||||
| 	// writable, non-executable | ||||
| 	SMACHOPLT  = SymKind(obj.SMACHOPLT) | ||||
| 	SELFSECT   = SymKind(obj.SELFSECT) | ||||
| 	SMACHO     = SymKind(obj.SMACHO) // Mach-O __nl_symbol_ptr | ||||
| 	SMACHOGOT  = SymKind(obj.SMACHOGOT) | ||||
| 	SWINDOWS   = SymKind(obj.SWINDOWS) | ||||
| 	SELFGOT    = SymKind(obj.SELFGOT) | ||||
| 	SNOPTRDATA = SymKind(obj.SNOPTRDATA) | ||||
| 	SINITARR   = SymKind(obj.SINITARR) | ||||
| 	SDATA      = SymKind(obj.SDATA) | ||||
| 	SBSS       = SymKind(obj.SBSS) | ||||
| 	SNOPTRBSS  = SymKind(obj.SNOPTRBSS) | ||||
| 	STLSBSS    = SymKind(obj.STLSBSS) | ||||
|  | ||||
| 	// not mapped | ||||
| 	SXREF             = SymKind(obj.SXREF) | ||||
| 	SMACHOSYMSTR      = SymKind(obj.SMACHOSYMSTR) | ||||
| 	SMACHOSYMTAB      = SymKind(obj.SMACHOSYMTAB) | ||||
| 	SMACHOINDIRECTPLT = SymKind(obj.SMACHOINDIRECTPLT) | ||||
| 	SMACHOINDIRECTGOT = SymKind(obj.SMACHOINDIRECTGOT) | ||||
| 	SFILE             = SymKind(obj.SFILE) | ||||
| 	SFILEPATH         = SymKind(obj.SFILEPATH) | ||||
| 	SCONST            = SymKind(obj.SCONST) | ||||
| 	SDYNIMPORT        = SymKind(obj.SDYNIMPORT) | ||||
| 	SHOSTOBJ          = SymKind(obj.SHOSTOBJ) | ||||
| ) | ||||
|  | ||||
| var symKindStrings = []string{ | ||||
| 	SBSS:              "SBSS", | ||||
| 	SCONST:            "SCONST", | ||||
| 	SDATA:             "SDATA", | ||||
| 	SDYNIMPORT:        "SDYNIMPORT", | ||||
| 	SELFROSECT:        "SELFROSECT", | ||||
| 	SELFRXSECT:        "SELFRXSECT", | ||||
| 	SELFSECT:          "SELFSECT", | ||||
| 	SFILE:             "SFILE", | ||||
| 	SFILEPATH:         "SFILEPATH", | ||||
| 	SFUNCTAB:          "SFUNCTAB", | ||||
| 	SGOFUNC:           "SGOFUNC", | ||||
| 	SGOSTRING:         "SGOSTRING", | ||||
| 	SHOSTOBJ:          "SHOSTOBJ", | ||||
| 	SINITARR:          "SINITARR", | ||||
| 	SMACHO:            "SMACHO", | ||||
| 	SMACHOGOT:         "SMACHOGOT", | ||||
| 	SMACHOINDIRECTGOT: "SMACHOINDIRECTGOT", | ||||
| 	SMACHOINDIRECTPLT: "SMACHOINDIRECTPLT", | ||||
| 	SMACHOPLT:         "SMACHOPLT", | ||||
| 	SMACHOSYMSTR:      "SMACHOSYMSTR", | ||||
| 	SMACHOSYMTAB:      "SMACHOSYMTAB", | ||||
| 	SNOPTRBSS:         "SNOPTRBSS", | ||||
| 	SNOPTRDATA:        "SNOPTRDATA", | ||||
| 	SPCLNTAB:          "SPCLNTAB", | ||||
| 	SRODATA:           "SRODATA", | ||||
| 	SSTRING:           "SSTRING", | ||||
| 	SSYMTAB:           "SSYMTAB", | ||||
| 	STEXT:             "STEXT", | ||||
| 	STLSBSS:           "STLSBSS", | ||||
| 	STYPE:             "STYPE", | ||||
| 	STYPELINK:         "STYPELINK", | ||||
| 	SITABLINK:         "SITABLINK", | ||||
| 	SWINDOWS:          "SWINDOWS", | ||||
| 	SXREF:             "SXREF", | ||||
| } | ||||
|  | ||||
| func (k SymKind) String() string { | ||||
| 	if k < 0 || int(k) >= len(symKindStrings) { | ||||
| 		return fmt.Sprintf("SymKind(%d)", k) | ||||
| 	} | ||||
| 	return symKindStrings[k] | ||||
| } | ||||
|  | ||||
| // A Sym is a named symbol in an object file. | ||||
| type Sym struct { | ||||
| 	SymID         // symbol identifier (name and version) | ||||
| 	Kind  SymKind // kind of symbol | ||||
| 	DupOK bool    // are duplicate definitions okay? | ||||
| 	Size  int     // size of corresponding data | ||||
| 	Type  SymID   // symbol for Go type information | ||||
| 	Data  Data    // memory image of symbol | ||||
| 	Reloc []Reloc // relocations to apply to Data | ||||
| 	Func  *Func   // additional data for functions | ||||
| } | ||||
|  | ||||
| // A SymID - the combination of Name and Version - uniquely identifies | ||||
| // a symbol within a package. | ||||
| type SymID struct { | ||||
| 	// Name is the name of a symbol. | ||||
| 	Name string | ||||
|  | ||||
| 	// Version is zero for symbols with global visibility. | ||||
| 	// Symbols with only file visibility (such as file-level static | ||||
| 	// declarations in C) have a non-zero version distinguishing | ||||
| 	// a symbol in one file from a symbol of the same name | ||||
| 	// in another file | ||||
| 	Version int | ||||
| } | ||||
|  | ||||
| func (s SymID) String() string { | ||||
| 	if s.Version == 0 { | ||||
| 		return s.Name | ||||
| 	} | ||||
| 	return fmt.Sprintf("%s<%d>", s.Name, s.Version) | ||||
| } | ||||
|  | ||||
| // A Data is a reference to data stored in an object file. | ||||
| // It records the offset and size of the data, so that a client can | ||||
| // read the data only if necessary. | ||||
| type Data struct { | ||||
| 	Offset int64 | ||||
| 	Size   int64 | ||||
| } | ||||
|  | ||||
| // A Reloc describes a relocation applied to a memory image to refer | ||||
| // to an address within a particular symbol. | ||||
| type Reloc struct { | ||||
| 	// The bytes at [Offset, Offset+Size) within the containing Sym | ||||
| 	// should be updated to refer to the address Add bytes after the start | ||||
| 	// of the symbol Sym. | ||||
| 	Offset int | ||||
| 	Size   int | ||||
| 	Sym    SymID | ||||
| 	Add    int | ||||
|  | ||||
| 	// The Type records the form of address expected in the bytes | ||||
| 	// described by the previous fields: absolute, PC-relative, and so on. | ||||
| 	// TODO(rsc): The interpretation of Type is not exposed by this package. | ||||
| 	Type obj.RelocType | ||||
| } | ||||
|  | ||||
| // A Var describes a variable in a function stack frame: a declared | ||||
| // local variable, an input argument, or an output result. | ||||
| type Var struct { | ||||
| 	// The combination of Name, Kind, and Offset uniquely | ||||
| 	// identifies a variable in a function stack frame. | ||||
| 	// Using fewer of these - in particular, using only Name - does not. | ||||
| 	Name   string // Name of variable. | ||||
| 	Kind   int    // TODO(rsc): Define meaning. | ||||
| 	Offset int    // Frame offset. TODO(rsc): Define meaning. | ||||
|  | ||||
| 	Type SymID // Go type for variable. | ||||
| } | ||||
|  | ||||
| // Func contains additional per-symbol information specific to functions. | ||||
| type Func struct { | ||||
| 	Args     int        // size in bytes of argument frame: inputs and outputs | ||||
| 	Frame    int        // size in bytes of local variable frame | ||||
| 	Leaf     bool       // function omits save of link register (ARM) | ||||
| 	NoSplit  bool       // function omits stack split prologue | ||||
| 	Var      []Var      // detail about local variables | ||||
| 	PCSP     Data       // PC → SP offset map | ||||
| 	PCFile   Data       // PC → file number map (index into File) | ||||
| 	PCLine   Data       // PC → line number map | ||||
| 	PCData   []Data     // PC → runtime support data map | ||||
| 	FuncData []FuncData // non-PC-specific runtime support data | ||||
| 	File     []string   // paths indexed by PCFile | ||||
| } | ||||
|  | ||||
| // TODO: Add PCData []byte and PCDataIter (similar to liblink). | ||||
|  | ||||
| // A FuncData is a single function-specific data value. | ||||
| type FuncData struct { | ||||
| 	Sym    SymID // symbol holding data | ||||
| 	Offset int64 // offset into symbol for funcdata pointer | ||||
| } | ||||
|  | ||||
| // A Package is a parsed Go object file or archive defining a Go package. | ||||
| type Package struct { | ||||
| 	ImportPath string   // import path denoting this package | ||||
| 	Imports    []string // packages imported by this package | ||||
| 	SymRefs    []SymID  // list of symbol names and versions referred to by this pack | ||||
| 	Syms       []*Sym   // symbols defined by this package | ||||
| 	MaxVersion int      // maximum Version in any SymID in Syms | ||||
| 	Arch       string   // architecture | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	archiveHeader = []byte("!<arch>\n") | ||||
| 	archiveMagic  = []byte("`\n") | ||||
| 	goobjHeader   = []byte("go objec") // truncated to size of archiveHeader | ||||
|  | ||||
| 	errCorruptArchive   = errors.New("corrupt archive") | ||||
| 	errTruncatedArchive = errors.New("truncated archive") | ||||
| 	errCorruptObject    = errors.New("corrupt object file") | ||||
| 	errNotObject        = errors.New("unrecognized object file format") | ||||
| ) | ||||
|  | ||||
| // An objReader is an object file reader. | ||||
| type objReader struct { | ||||
| 	p          *Package | ||||
| 	b          *bufio.Reader | ||||
| 	f          io.ReadSeeker | ||||
| 	err        error | ||||
| 	offset     int64 | ||||
| 	dataOffset int64 | ||||
| 	limit      int64 | ||||
| 	tmp        [256]byte | ||||
| 	pkgprefix  string | ||||
| } | ||||
|  | ||||
| // importPathToPrefix returns the prefix that will be used in the | ||||
| // final symbol table for the given import path. | ||||
| // We escape '%', '"', all control characters and non-ASCII bytes, | ||||
| // and any '.' after the final slash. | ||||
| // | ||||
| // See ../../../cmd/ld/lib.c:/^pathtoprefix and | ||||
| // ../../../cmd/gc/subr.c:/^pathtoprefix. | ||||
| func importPathToPrefix(s string) string { | ||||
| 	// find index of last slash, if any, or else -1. | ||||
| 	// used for determining whether an index is after the last slash. | ||||
| 	slash := strings.LastIndex(s, "/") | ||||
|  | ||||
| 	// check for chars that need escaping | ||||
| 	n := 0 | ||||
| 	for r := 0; r < len(s); r++ { | ||||
| 		if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F { | ||||
| 			n++ | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// quick exit | ||||
| 	if n == 0 { | ||||
| 		return s | ||||
| 	} | ||||
|  | ||||
| 	// escape | ||||
| 	const hex = "0123456789abcdef" | ||||
| 	p := make([]byte, 0, len(s)+2*n) | ||||
| 	for r := 0; r < len(s); r++ { | ||||
| 		if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F { | ||||
| 			p = append(p, '%', hex[c>>4], hex[c&0xF]) | ||||
| 		} else { | ||||
| 			p = append(p, c) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return string(p) | ||||
| } | ||||
|  | ||||
| // init initializes r to read package p from f. | ||||
| func (r *objReader) init(f io.ReadSeeker, p *Package) { | ||||
| 	r.f = f | ||||
| 	r.p = p | ||||
| 	r.offset, _ = f.Seek(0, io.SeekCurrent) | ||||
| 	r.limit, _ = f.Seek(0, io.SeekEnd) | ||||
| 	f.Seek(r.offset, io.SeekStart) | ||||
| 	r.b = bufio.NewReader(f) | ||||
| 	r.pkgprefix = importPathToPrefix(p.ImportPath) + "." | ||||
| } | ||||
|  | ||||
| // error records that an error occurred. | ||||
| // It returns only the first error, so that an error | ||||
| // caused by an earlier error does not discard information | ||||
| // about the earlier error. | ||||
| func (r *objReader) error(err error) error { | ||||
| 	if r.err == nil { | ||||
| 		if err == io.EOF { | ||||
| 			err = io.ErrUnexpectedEOF | ||||
| 		} | ||||
| 		r.err = err | ||||
| 	} | ||||
| 	// panic("corrupt") // useful for debugging | ||||
| 	return r.err | ||||
| } | ||||
|  | ||||
| // readByte reads and returns a byte from the input file. | ||||
| // On I/O error or EOF, it records the error but returns byte 0. | ||||
| // A sequence of 0 bytes will eventually terminate any | ||||
| // parsing state in the object file. In particular, it ends the | ||||
| // reading of a varint. | ||||
| func (r *objReader) readByte() byte { | ||||
| 	if r.err != nil { | ||||
| 		return 0 | ||||
| 	} | ||||
| 	if r.offset >= r.limit { | ||||
| 		r.error(io.ErrUnexpectedEOF) | ||||
| 		return 0 | ||||
| 	} | ||||
| 	b, err := r.b.ReadByte() | ||||
| 	if err != nil { | ||||
| 		if err == io.EOF { | ||||
| 			err = io.ErrUnexpectedEOF | ||||
| 		} | ||||
| 		r.error(err) | ||||
| 		b = 0 | ||||
| 	} else { | ||||
| 		r.offset++ | ||||
| 	} | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| // read reads exactly len(b) bytes from the input file. | ||||
| // If an error occurs, read returns the error but also | ||||
| // records it, so it is safe for callers to ignore the result | ||||
| // as long as delaying the report is not a problem. | ||||
| func (r *objReader) readFull(b []byte) error { | ||||
| 	if r.err != nil { | ||||
| 		return r.err | ||||
| 	} | ||||
| 	if r.offset+int64(len(b)) > r.limit { | ||||
| 		return r.error(io.ErrUnexpectedEOF) | ||||
| 	} | ||||
| 	n, err := io.ReadFull(r.b, b) | ||||
| 	r.offset += int64(n) | ||||
| 	if err != nil { | ||||
| 		return r.error(err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // readInt reads a zigzag varint from the input file. | ||||
| func (r *objReader) readInt() int { | ||||
| 	var u uint64 | ||||
|  | ||||
| 	for shift := uint(0); ; shift += 7 { | ||||
| 		if shift >= 64 { | ||||
| 			r.error(errCorruptObject) | ||||
| 			return 0 | ||||
| 		} | ||||
| 		c := r.readByte() | ||||
| 		u |= uint64(c&0x7F) << shift | ||||
| 		if c&0x80 == 0 { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	v := int64(u>>1) ^ (int64(u) << 63 >> 63) | ||||
| 	if int64(int(v)) != v { | ||||
| 		r.error(errCorruptObject) // TODO | ||||
| 		return 0 | ||||
| 	} | ||||
| 	return int(v) | ||||
| } | ||||
|  | ||||
| // readString reads a length-delimited string from the input file. | ||||
| func (r *objReader) readString() string { | ||||
| 	n := r.readInt() | ||||
| 	buf := make([]byte, n) | ||||
| 	r.readFull(buf) | ||||
| 	return string(buf) | ||||
| } | ||||
|  | ||||
| // readSymID reads a SymID from the input file. | ||||
| func (r *objReader) readSymID() SymID { | ||||
| 	i := r.readInt() | ||||
| 	return r.p.SymRefs[i] | ||||
| } | ||||
|  | ||||
| func (r *objReader) readRef() { | ||||
| 	name, vers := r.readString(), r.readInt() | ||||
|  | ||||
| 	// In a symbol name in an object file, "". denotes the | ||||
| 	// prefix for the package in which the object file has been found. | ||||
| 	// Expand it. | ||||
| 	name = strings.Replace(name, `"".`, r.pkgprefix, -1) | ||||
|  | ||||
| 	// An individual object file only records version 0 (extern) or 1 (static). | ||||
| 	// To make static symbols unique across all files being read, we | ||||
| 	// replace version 1 with the version corresponding to the current | ||||
| 	// file number. The number is incremented on each call to parseObject. | ||||
| 	if vers != 0 { | ||||
| 		vers = r.p.MaxVersion | ||||
| 	} | ||||
| 	r.p.SymRefs = append(r.p.SymRefs, SymID{name, vers}) | ||||
| } | ||||
|  | ||||
| // readData reads a data reference from the input file. | ||||
| func (r *objReader) readData() Data { | ||||
| 	n := r.readInt() | ||||
| 	d := Data{Offset: r.dataOffset, Size: int64(n)} | ||||
| 	r.dataOffset += int64(n) | ||||
| 	return d | ||||
| } | ||||
|  | ||||
| // skip skips n bytes in the input. | ||||
| func (r *objReader) skip(n int64) { | ||||
| 	if n < 0 { | ||||
| 		r.error(fmt.Errorf("debug/goobj: internal error: misuse of skip")) | ||||
| 	} | ||||
| 	if n < int64(len(r.tmp)) { | ||||
| 		// Since the data is so small, a just reading from the buffered | ||||
| 		// reader is better than flushing the buffer and seeking. | ||||
| 		r.readFull(r.tmp[:n]) | ||||
| 	} else if n <= int64(r.b.Buffered()) { | ||||
| 		// Even though the data is not small, it has already been read. | ||||
| 		// Advance the buffer instead of seeking. | ||||
| 		for n > int64(len(r.tmp)) { | ||||
| 			r.readFull(r.tmp[:]) | ||||
| 			n -= int64(len(r.tmp)) | ||||
| 		} | ||||
| 		r.readFull(r.tmp[:n]) | ||||
| 	} else { | ||||
| 		// Seek, giving up buffered data. | ||||
| 		_, err := r.f.Seek(r.offset+n, io.SeekStart) | ||||
| 		if err != nil { | ||||
| 			r.error(err) | ||||
| 		} | ||||
| 		r.offset += n | ||||
| 		r.b.Reset(r.f) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Parse parses an object file or archive from r, | ||||
| // assuming that its import path is pkgpath. | ||||
| func Parse(r io.ReadSeeker, pkgpath string) (*Package, error) { | ||||
| 	if pkgpath == "" { | ||||
| 		pkgpath = `""` | ||||
| 	} | ||||
| 	p := new(Package) | ||||
| 	p.ImportPath = pkgpath | ||||
|  | ||||
| 	var rd objReader | ||||
| 	rd.init(r, p) | ||||
| 	err := rd.readFull(rd.tmp[:8]) | ||||
| 	if err != nil { | ||||
| 		if err == io.EOF { | ||||
| 			err = io.ErrUnexpectedEOF | ||||
| 		} | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	switch { | ||||
| 	default: | ||||
| 		return nil, errNotObject | ||||
|  | ||||
| 	case bytes.Equal(rd.tmp[:8], archiveHeader): | ||||
| 		if err := rd.parseArchive(); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	case bytes.Equal(rd.tmp[:8], goobjHeader): | ||||
| 		if err := rd.parseObject(goobjHeader); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return p, nil | ||||
| } | ||||
|  | ||||
| // trimSpace removes trailing spaces from b and returns the corresponding string. | ||||
| // This effectively parses the form used in archive headers. | ||||
| func trimSpace(b []byte) string { | ||||
| 	return string(bytes.TrimRight(b, " ")) | ||||
| } | ||||
|  | ||||
| // parseArchive parses a Unix archive of Go object files. | ||||
| // TODO(rsc): Need to skip non-Go object files. | ||||
| // TODO(rsc): Maybe record table of contents in r.p so that | ||||
| // linker can avoid having code to parse archives too. | ||||
| func (r *objReader) parseArchive() error { | ||||
| 	for r.offset < r.limit { | ||||
| 		if err := r.readFull(r.tmp[:60]); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		data := r.tmp[:60] | ||||
|  | ||||
| 		// Each file is preceded by this text header (slice indices in first column): | ||||
| 		//	 0:16	name | ||||
| 		//	16:28 date | ||||
| 		//	28:34 uid | ||||
| 		//	34:40 gid | ||||
| 		//	40:48 mode | ||||
| 		//	48:58 size | ||||
| 		//	58:60 magic - `\n | ||||
| 		// We only care about name, size, and magic. | ||||
| 		// The fields are space-padded on the right. | ||||
| 		// The size is in decimal. | ||||
| 		// The file data - size bytes - follows the header. | ||||
| 		// Headers are 2-byte aligned, so if size is odd, an extra padding | ||||
| 		// byte sits between the file data and the next header. | ||||
| 		// The file data that follows is padded to an even number of bytes: | ||||
| 		// if size is odd, an extra padding byte is inserted betw the next header. | ||||
| 		if len(data) < 60 { | ||||
| 			return errTruncatedArchive | ||||
| 		} | ||||
| 		if !bytes.Equal(data[58:60], archiveMagic) { | ||||
| 			return errCorruptArchive | ||||
| 		} | ||||
| 		name := trimSpace(data[0:16]) | ||||
| 		size, err := strconv.ParseInt(trimSpace(data[48:58]), 10, 64) | ||||
| 		if err != nil { | ||||
| 			return errCorruptArchive | ||||
| 		} | ||||
| 		data = data[60:] | ||||
| 		fsize := size + size&1 | ||||
| 		if fsize < 0 || fsize < size { | ||||
| 			return errCorruptArchive | ||||
| 		} | ||||
| 		switch name { | ||||
| 		case "__.PKGDEF": | ||||
| 			r.skip(size) | ||||
| 		default: | ||||
| 			oldLimit := r.limit | ||||
| 			r.limit = r.offset + size | ||||
| 			if err := r.parseObject(nil); err != nil { | ||||
| 				return fmt.Errorf("parsing archive member %q: %v", name, err) | ||||
| 			} | ||||
| 			r.skip(r.limit - r.offset) | ||||
| 			r.limit = oldLimit | ||||
| 		} | ||||
| 		if size&1 != 0 { | ||||
| 			r.skip(1) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // parseObject parses a single Go object file. | ||||
| // The prefix is the bytes already read from the file, | ||||
| // typically in order to detect that this is an object file. | ||||
| // The object file consists of a textual header ending in "\n!\n" | ||||
| // and then the part we want to parse begins. | ||||
| // The format of that part is defined in a comment at the top | ||||
| // of src/liblink/objfile.c. | ||||
| func (r *objReader) parseObject(prefix []byte) error { | ||||
| 	r.p.MaxVersion++ | ||||
| 	h := make([]byte, 0, 256) | ||||
| 	h = append(h, prefix...) | ||||
| 	var c1, c2, c3 byte | ||||
| 	for { | ||||
| 		c1, c2, c3 = c2, c3, r.readByte() | ||||
| 		h = append(h, c3) | ||||
| 		// The new export format can contain 0 bytes. | ||||
| 		// Don't consider them errors, only look for r.err != nil. | ||||
| 		if r.err != nil { | ||||
| 			return errCorruptObject | ||||
| 		} | ||||
| 		if c1 == '\n' && c2 == '!' && c3 == '\n' { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	hs := strings.Fields(string(h)) | ||||
| 	if len(hs) >= 4 { | ||||
| 		r.p.Arch = hs[3] | ||||
| 	} | ||||
| 	// TODO: extract OS + build ID if/when we need it | ||||
|  | ||||
| 	r.readFull(r.tmp[:8]) | ||||
| 	if !bytes.Equal(r.tmp[:8], []byte("\x00\x00go17ld")) { | ||||
| 		return r.error(errCorruptObject) | ||||
| 	} | ||||
|  | ||||
| 	b := r.readByte() | ||||
| 	if b != 1 { | ||||
| 		return r.error(errCorruptObject) | ||||
| 	} | ||||
|  | ||||
| 	// Direct package dependencies. | ||||
| 	for { | ||||
| 		s := r.readString() | ||||
| 		if s == "" { | ||||
| 			break | ||||
| 		} | ||||
| 		r.p.Imports = append(r.p.Imports, s) | ||||
| 	} | ||||
|  | ||||
| 	r.p.SymRefs = []SymID{{"", 0}} | ||||
| 	for { | ||||
| 		if b := r.readByte(); b != 0xfe { | ||||
| 			if b != 0xff { | ||||
| 				return r.error(errCorruptObject) | ||||
| 			} | ||||
| 			break | ||||
| 		} | ||||
|  | ||||
| 		r.readRef() | ||||
| 	} | ||||
|  | ||||
| 	dataLength := r.readInt() | ||||
| 	r.readInt() // n relocations - ignore | ||||
| 	r.readInt() // n pcdata - ignore | ||||
| 	r.readInt() // n autom - ignore | ||||
| 	r.readInt() // n funcdata - ignore | ||||
| 	r.readInt() // n files - ignore | ||||
|  | ||||
| 	r.dataOffset = r.offset | ||||
| 	r.skip(int64(dataLength)) | ||||
|  | ||||
| 	// Symbols. | ||||
| 	for { | ||||
| 		if b := r.readByte(); b != 0xfe { | ||||
| 			if b != 0xff { | ||||
| 				return r.error(errCorruptObject) | ||||
| 			} | ||||
| 			break | ||||
| 		} | ||||
|  | ||||
| 		typ := r.readInt() | ||||
| 		s := &Sym{SymID: r.readSymID()} | ||||
| 		r.p.Syms = append(r.p.Syms, s) | ||||
| 		s.Kind = SymKind(typ) | ||||
| 		flags := r.readInt() | ||||
| 		s.DupOK = flags&1 != 0 | ||||
| 		s.Size = r.readInt() | ||||
| 		s.Type = r.readSymID() | ||||
| 		s.Data = r.readData() | ||||
| 		s.Reloc = make([]Reloc, r.readInt()) | ||||
| 		for i := range s.Reloc { | ||||
| 			rel := &s.Reloc[i] | ||||
| 			rel.Offset = r.readInt() | ||||
| 			rel.Size = r.readInt() | ||||
| 			rel.Type = obj.RelocType(r.readInt()) | ||||
| 			rel.Add = r.readInt() | ||||
| 			rel.Sym = r.readSymID() | ||||
| 		} | ||||
|  | ||||
| 		if s.Kind == STEXT { | ||||
| 			f := new(Func) | ||||
| 			s.Func = f | ||||
| 			f.Args = r.readInt() | ||||
| 			f.Frame = r.readInt() | ||||
| 			flags := r.readInt() | ||||
| 			f.Leaf = flags&1 != 0 | ||||
| 			f.NoSplit = r.readInt() != 0 | ||||
| 			f.Var = make([]Var, r.readInt()) | ||||
| 			for i := range f.Var { | ||||
| 				v := &f.Var[i] | ||||
| 				v.Name = r.readSymID().Name | ||||
| 				v.Offset = r.readInt() | ||||
| 				v.Kind = r.readInt() | ||||
| 				v.Type = r.readSymID() | ||||
| 			} | ||||
|  | ||||
| 			f.PCSP = r.readData() | ||||
| 			f.PCFile = r.readData() | ||||
| 			f.PCLine = r.readData() | ||||
| 			f.PCData = make([]Data, r.readInt()) | ||||
| 			for i := range f.PCData { | ||||
| 				f.PCData[i] = r.readData() | ||||
| 			} | ||||
| 			f.FuncData = make([]FuncData, r.readInt()) | ||||
| 			for i := range f.FuncData { | ||||
| 				f.FuncData[i].Sym = r.readSymID() | ||||
| 			} | ||||
| 			for i := range f.FuncData { | ||||
| 				f.FuncData[i].Offset = int64(r.readInt()) // TODO | ||||
| 			} | ||||
| 			f.File = make([]string, r.readInt()) | ||||
| 			for i := range f.File { | ||||
| 				f.File[i] = r.readSymID().Name | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	r.readFull(r.tmp[:7]) | ||||
| 	if !bytes.Equal(r.tmp[:7], []byte("\xffgo17ld")) { | ||||
| 		return r.error(errCorruptObject) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (r *Reloc) String(insnOffset uint64) string { | ||||
| 	delta := r.Offset - int(insnOffset) | ||||
| 	s := fmt.Sprintf("[%d:%d]%s", delta, delta+r.Size, r.Type) | ||||
| 	if r.Sym.Name != "" { | ||||
| 		if r.Add != 0 { | ||||
| 			return fmt.Sprintf("%s:%s+%d", s, r.Sym.Name, r.Add) | ||||
| 		} | ||||
| 		return fmt.Sprintf("%s:%s", s, r.Sym.Name) | ||||
| 	} | ||||
| 	if r.Add != 0 { | ||||
| 		return fmt.Sprintf("%s:%d", s, r.Add) | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
							
								
								
									
										52
									
								
								vendor/github.com/google/gops/internal/internal.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/google/gops/internal/internal.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| package internal | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"os/user" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| func ConfigDir() (string, error) { | ||||
| 	if runtime.GOOS == "windows" { | ||||
| 		return filepath.Join(os.Getenv("APPDATA"), "gops"), nil | ||||
| 	} | ||||
| 	homeDir := guessUnixHomeDir() | ||||
| 	if homeDir == "" { | ||||
| 		return "", errors.New("unable to get current user home directory: os/user lookup failed; $HOME is empty") | ||||
| 	} | ||||
| 	return filepath.Join(homeDir, ".config", "gops"), nil | ||||
| } | ||||
|  | ||||
| func guessUnixHomeDir() string { | ||||
| 	usr, err := user.Current() | ||||
| 	if err == nil { | ||||
| 		return usr.HomeDir | ||||
| 	} | ||||
| 	return os.Getenv("HOME") | ||||
| } | ||||
|  | ||||
| func PIDFile(pid int) (string, error) { | ||||
| 	gopsdir, err := ConfigDir() | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return fmt.Sprintf("%s/%d", gopsdir, pid), nil | ||||
| } | ||||
|  | ||||
| func GetPort(pid int) (string, error) { | ||||
| 	portfile, err := PIDFile(pid) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	b, err := ioutil.ReadFile(portfile) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	port := strings.TrimSpace(string(b)) | ||||
| 	return port, nil | ||||
| } | ||||
							
								
								
									
										27
									
								
								vendor/github.com/google/gops/internal/obj/addrtype_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/google/gops/internal/obj/addrtype_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| // Code generated by "stringer -type AddrType cmd/internal/obj"; DO NOT EDIT | ||||
|  | ||||
| package obj | ||||
|  | ||||
| import "fmt" | ||||
|  | ||||
| const ( | ||||
| 	_AddrType_name_0 = "TYPE_NONE" | ||||
| 	_AddrType_name_1 = "TYPE_BRANCHTYPE_TEXTSIZETYPE_MEMTYPE_CONSTTYPE_FCONSTTYPE_SCONSTTYPE_REGTYPE_ADDRTYPE_SHIFTTYPE_REGREGTYPE_REGREG2TYPE_INDIRTYPE_REGLIST" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	_AddrType_index_0 = [...]uint8{0, 9} | ||||
| 	_AddrType_index_1 = [...]uint8{0, 11, 24, 32, 42, 53, 64, 72, 81, 91, 102, 114, 124, 136} | ||||
| ) | ||||
|  | ||||
| func (i AddrType) String() string { | ||||
| 	switch { | ||||
| 	case i == 0: | ||||
| 		return _AddrType_name_0 | ||||
| 	case 6 <= i && i <= 18: | ||||
| 		i -= 6 | ||||
| 		return _AddrType_name_1[_AddrType_index_1[i]:_AddrType_index_1[i+1]] | ||||
| 	default: | ||||
| 		return fmt.Sprintf("AddrType(%d)", i) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										338
									
								
								vendor/github.com/google/gops/internal/obj/arm/a.out.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										338
									
								
								vendor/github.com/google/gops/internal/obj/arm/a.out.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,338 @@ | ||||
| // Inferno utils/5c/5.out.h | ||||
| // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5c/5.out.h | ||||
| // | ||||
| //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | ||||
| //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| //	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others | ||||
| //	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package arm | ||||
|  | ||||
| import "github.com/google/gops/internal/obj" | ||||
|  | ||||
| //go:generate go run ../stringer.go -i $GOFILE -o anames.go -p arm | ||||
|  | ||||
| const ( | ||||
| 	NSNAME = 8 | ||||
| 	NSYM   = 50 | ||||
| 	NREG   = 16 | ||||
| ) | ||||
|  | ||||
| /* -1 disables use of REGARG */ | ||||
| const ( | ||||
| 	REGARG = -1 | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	REG_R0 = obj.RBaseARM + iota // must be 16-aligned | ||||
| 	REG_R1 | ||||
| 	REG_R2 | ||||
| 	REG_R3 | ||||
| 	REG_R4 | ||||
| 	REG_R5 | ||||
| 	REG_R6 | ||||
| 	REG_R7 | ||||
| 	REG_R8 | ||||
| 	REG_R9 | ||||
| 	REG_R10 | ||||
| 	REG_R11 | ||||
| 	REG_R12 | ||||
| 	REG_R13 | ||||
| 	REG_R14 | ||||
| 	REG_R15 | ||||
|  | ||||
| 	REG_F0 // must be 16-aligned | ||||
| 	REG_F1 | ||||
| 	REG_F2 | ||||
| 	REG_F3 | ||||
| 	REG_F4 | ||||
| 	REG_F5 | ||||
| 	REG_F6 | ||||
| 	REG_F7 | ||||
| 	REG_F8 | ||||
| 	REG_F9 | ||||
| 	REG_F10 | ||||
| 	REG_F11 | ||||
| 	REG_F12 | ||||
| 	REG_F13 | ||||
| 	REG_F14 | ||||
| 	REG_F15 | ||||
|  | ||||
| 	REG_FPSR // must be 2-aligned | ||||
| 	REG_FPCR | ||||
|  | ||||
| 	REG_CPSR // must be 2-aligned | ||||
| 	REG_SPSR | ||||
|  | ||||
| 	MAXREG | ||||
| 	REGRET = REG_R0 | ||||
| 	/* compiler allocates R1 up as temps */ | ||||
| 	/* compiler allocates register variables R3 up */ | ||||
| 	/* compiler allocates external registers R10 down */ | ||||
| 	REGEXT = REG_R10 | ||||
| 	/* these two registers are declared in runtime.h */ | ||||
| 	REGG = REGEXT - 0 | ||||
| 	REGM = REGEXT - 1 | ||||
|  | ||||
| 	REGCTXT = REG_R7 | ||||
| 	REGTMP  = REG_R11 | ||||
| 	REGSP   = REG_R13 | ||||
| 	REGLINK = REG_R14 | ||||
| 	REGPC   = REG_R15 | ||||
|  | ||||
| 	NFREG = 16 | ||||
| 	/* compiler allocates register variables F0 up */ | ||||
| 	/* compiler allocates external registers F7 down */ | ||||
| 	FREGRET = REG_F0 | ||||
| 	FREGEXT = REG_F7 | ||||
| 	FREGTMP = REG_F15 | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	C_NONE = iota | ||||
| 	C_REG | ||||
| 	C_REGREG | ||||
| 	C_REGREG2 | ||||
| 	C_REGLIST | ||||
| 	C_SHIFT | ||||
| 	C_FREG | ||||
| 	C_PSR | ||||
| 	C_FCR | ||||
|  | ||||
| 	C_RCON /* 0xff rotated */ | ||||
| 	C_NCON /* ~RCON */ | ||||
| 	C_SCON /* 0xffff */ | ||||
| 	C_LCON | ||||
| 	C_LCONADDR | ||||
| 	C_ZFCON | ||||
| 	C_SFCON | ||||
| 	C_LFCON | ||||
|  | ||||
| 	C_RACON | ||||
| 	C_LACON | ||||
|  | ||||
| 	C_SBRA | ||||
| 	C_LBRA | ||||
|  | ||||
| 	C_HAUTO  /* halfword insn offset (-0xff to 0xff) */ | ||||
| 	C_FAUTO  /* float insn offset (0 to 0x3fc, word aligned) */ | ||||
| 	C_HFAUTO /* both H and F */ | ||||
| 	C_SAUTO  /* -0xfff to 0xfff */ | ||||
| 	C_LAUTO | ||||
|  | ||||
| 	C_HOREG | ||||
| 	C_FOREG | ||||
| 	C_HFOREG | ||||
| 	C_SOREG | ||||
| 	C_ROREG | ||||
| 	C_SROREG /* both nil and R */ | ||||
| 	C_LOREG | ||||
|  | ||||
| 	C_PC | ||||
| 	C_SP | ||||
| 	C_HREG | ||||
|  | ||||
| 	C_ADDR /* reference to relocatable address */ | ||||
|  | ||||
| 	// TLS "var" in local exec mode: will become a constant offset from | ||||
| 	// thread local base that is ultimately chosen by the program linker. | ||||
| 	C_TLS_LE | ||||
|  | ||||
| 	// TLS "var" in initial exec mode: will become a memory address (chosen | ||||
| 	// by the program linker) that the dynamic linker will fill with the | ||||
| 	// offset from the thread local base. | ||||
| 	C_TLS_IE | ||||
|  | ||||
| 	C_TEXTSIZE | ||||
|  | ||||
| 	C_GOK | ||||
|  | ||||
| 	C_NCLASS /* must be the last */ | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	AAND = obj.ABaseARM + obj.A_ARCHSPECIFIC + iota | ||||
| 	AEOR | ||||
| 	ASUB | ||||
| 	ARSB | ||||
| 	AADD | ||||
| 	AADC | ||||
| 	ASBC | ||||
| 	ARSC | ||||
| 	ATST | ||||
| 	ATEQ | ||||
| 	ACMP | ||||
| 	ACMN | ||||
| 	AORR | ||||
| 	ABIC | ||||
|  | ||||
| 	AMVN | ||||
|  | ||||
| 	/* | ||||
| 	 * Do not reorder or fragment the conditional branch | ||||
| 	 * opcodes, or the predication code will break | ||||
| 	 */ | ||||
| 	ABEQ | ||||
| 	ABNE | ||||
| 	ABCS | ||||
| 	ABHS | ||||
| 	ABCC | ||||
| 	ABLO | ||||
| 	ABMI | ||||
| 	ABPL | ||||
| 	ABVS | ||||
| 	ABVC | ||||
| 	ABHI | ||||
| 	ABLS | ||||
| 	ABGE | ||||
| 	ABLT | ||||
| 	ABGT | ||||
| 	ABLE | ||||
|  | ||||
| 	AMOVWD | ||||
| 	AMOVWF | ||||
| 	AMOVDW | ||||
| 	AMOVFW | ||||
| 	AMOVFD | ||||
| 	AMOVDF | ||||
| 	AMOVF | ||||
| 	AMOVD | ||||
|  | ||||
| 	ACMPF | ||||
| 	ACMPD | ||||
| 	AADDF | ||||
| 	AADDD | ||||
| 	ASUBF | ||||
| 	ASUBD | ||||
| 	AMULF | ||||
| 	AMULD | ||||
| 	ADIVF | ||||
| 	ADIVD | ||||
| 	ASQRTF | ||||
| 	ASQRTD | ||||
| 	AABSF | ||||
| 	AABSD | ||||
| 	ANEGF | ||||
| 	ANEGD | ||||
|  | ||||
| 	ASRL | ||||
| 	ASRA | ||||
| 	ASLL | ||||
| 	AMULU | ||||
| 	ADIVU | ||||
| 	AMUL | ||||
| 	ADIV | ||||
| 	AMOD | ||||
| 	AMODU | ||||
|  | ||||
| 	AMOVB | ||||
| 	AMOVBS | ||||
| 	AMOVBU | ||||
| 	AMOVH | ||||
| 	AMOVHS | ||||
| 	AMOVHU | ||||
| 	AMOVW | ||||
| 	AMOVM | ||||
| 	ASWPBU | ||||
| 	ASWPW | ||||
|  | ||||
| 	ARFE | ||||
| 	ASWI | ||||
| 	AMULA | ||||
|  | ||||
| 	AWORD | ||||
|  | ||||
| 	AMULL | ||||
| 	AMULAL | ||||
| 	AMULLU | ||||
| 	AMULALU | ||||
|  | ||||
| 	ABX | ||||
| 	ABXRET | ||||
| 	ADWORD | ||||
|  | ||||
| 	ALDREX | ||||
| 	ASTREX | ||||
| 	ALDREXD | ||||
| 	ASTREXD | ||||
|  | ||||
| 	APLD | ||||
|  | ||||
| 	ACLZ | ||||
|  | ||||
| 	AMULWT | ||||
| 	AMULWB | ||||
| 	AMULAWT | ||||
| 	AMULAWB | ||||
|  | ||||
| 	ADATABUNDLE | ||||
| 	ADATABUNDLEEND | ||||
|  | ||||
| 	AMRC // MRC/MCR | ||||
|  | ||||
| 	ALAST | ||||
|  | ||||
| 	// aliases | ||||
| 	AB  = obj.AJMP | ||||
| 	ABL = obj.ACALL | ||||
| ) | ||||
|  | ||||
| /* scond byte */ | ||||
| const ( | ||||
| 	C_SCOND = (1 << 4) - 1 | ||||
| 	C_SBIT  = 1 << 4 | ||||
| 	C_PBIT  = 1 << 5 | ||||
| 	C_WBIT  = 1 << 6 | ||||
| 	C_FBIT  = 1 << 7 /* psr flags-only */ | ||||
| 	C_UBIT  = 1 << 7 /* up bit, unsigned bit */ | ||||
|  | ||||
| 	// These constants are the ARM condition codes encodings, | ||||
| 	// XORed with 14 so that C_SCOND_NONE has value 0, | ||||
| 	// so that a zeroed Prog.scond means "always execute". | ||||
| 	C_SCOND_XOR = 14 | ||||
|  | ||||
| 	C_SCOND_EQ   = 0 ^ C_SCOND_XOR | ||||
| 	C_SCOND_NE   = 1 ^ C_SCOND_XOR | ||||
| 	C_SCOND_HS   = 2 ^ C_SCOND_XOR | ||||
| 	C_SCOND_LO   = 3 ^ C_SCOND_XOR | ||||
| 	C_SCOND_MI   = 4 ^ C_SCOND_XOR | ||||
| 	C_SCOND_PL   = 5 ^ C_SCOND_XOR | ||||
| 	C_SCOND_VS   = 6 ^ C_SCOND_XOR | ||||
| 	C_SCOND_VC   = 7 ^ C_SCOND_XOR | ||||
| 	C_SCOND_HI   = 8 ^ C_SCOND_XOR | ||||
| 	C_SCOND_LS   = 9 ^ C_SCOND_XOR | ||||
| 	C_SCOND_GE   = 10 ^ C_SCOND_XOR | ||||
| 	C_SCOND_LT   = 11 ^ C_SCOND_XOR | ||||
| 	C_SCOND_GT   = 12 ^ C_SCOND_XOR | ||||
| 	C_SCOND_LE   = 13 ^ C_SCOND_XOR | ||||
| 	C_SCOND_NONE = 14 ^ C_SCOND_XOR | ||||
| 	C_SCOND_NV   = 15 ^ C_SCOND_XOR | ||||
|  | ||||
| 	/* D_SHIFT type */ | ||||
| 	SHIFT_LL = 0 << 5 | ||||
| 	SHIFT_LR = 1 << 5 | ||||
| 	SHIFT_AR = 2 << 5 | ||||
| 	SHIFT_RR = 3 << 5 | ||||
| ) | ||||
							
								
								
									
										108
									
								
								vendor/github.com/google/gops/internal/obj/arm/anames.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								vendor/github.com/google/gops/internal/obj/arm/anames.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| // Generated by stringer -i a.out.go -o anames.go -p arm | ||||
| // Do not edit. | ||||
|  | ||||
| package arm | ||||
|  | ||||
| import "github.com/google/gops/internal/obj" | ||||
|  | ||||
| var Anames = []string{ | ||||
| 	obj.A_ARCHSPECIFIC: "AND", | ||||
| 	"EOR", | ||||
| 	"SUB", | ||||
| 	"RSB", | ||||
| 	"ADD", | ||||
| 	"ADC", | ||||
| 	"SBC", | ||||
| 	"RSC", | ||||
| 	"TST", | ||||
| 	"TEQ", | ||||
| 	"CMP", | ||||
| 	"CMN", | ||||
| 	"ORR", | ||||
| 	"BIC", | ||||
| 	"MVN", | ||||
| 	"BEQ", | ||||
| 	"BNE", | ||||
| 	"BCS", | ||||
| 	"BHS", | ||||
| 	"BCC", | ||||
| 	"BLO", | ||||
| 	"BMI", | ||||
| 	"BPL", | ||||
| 	"BVS", | ||||
| 	"BVC", | ||||
| 	"BHI", | ||||
| 	"BLS", | ||||
| 	"BGE", | ||||
| 	"BLT", | ||||
| 	"BGT", | ||||
| 	"BLE", | ||||
| 	"MOVWD", | ||||
| 	"MOVWF", | ||||
| 	"MOVDW", | ||||
| 	"MOVFW", | ||||
| 	"MOVFD", | ||||
| 	"MOVDF", | ||||
| 	"MOVF", | ||||
| 	"MOVD", | ||||
| 	"CMPF", | ||||
| 	"CMPD", | ||||
| 	"ADDF", | ||||
| 	"ADDD", | ||||
| 	"SUBF", | ||||
| 	"SUBD", | ||||
| 	"MULF", | ||||
| 	"MULD", | ||||
| 	"DIVF", | ||||
| 	"DIVD", | ||||
| 	"SQRTF", | ||||
| 	"SQRTD", | ||||
| 	"ABSF", | ||||
| 	"ABSD", | ||||
| 	"NEGF", | ||||
| 	"NEGD", | ||||
| 	"SRL", | ||||
| 	"SRA", | ||||
| 	"SLL", | ||||
| 	"MULU", | ||||
| 	"DIVU", | ||||
| 	"MUL", | ||||
| 	"DIV", | ||||
| 	"MOD", | ||||
| 	"MODU", | ||||
| 	"MOVB", | ||||
| 	"MOVBS", | ||||
| 	"MOVBU", | ||||
| 	"MOVH", | ||||
| 	"MOVHS", | ||||
| 	"MOVHU", | ||||
| 	"MOVW", | ||||
| 	"MOVM", | ||||
| 	"SWPBU", | ||||
| 	"SWPW", | ||||
| 	"RFE", | ||||
| 	"SWI", | ||||
| 	"MULA", | ||||
| 	"WORD", | ||||
| 	"MULL", | ||||
| 	"MULAL", | ||||
| 	"MULLU", | ||||
| 	"MULALU", | ||||
| 	"BX", | ||||
| 	"BXRET", | ||||
| 	"DWORD", | ||||
| 	"LDREX", | ||||
| 	"STREX", | ||||
| 	"LDREXD", | ||||
| 	"STREXD", | ||||
| 	"PLD", | ||||
| 	"CLZ", | ||||
| 	"MULWT", | ||||
| 	"MULWB", | ||||
| 	"MULAWT", | ||||
| 	"MULAWB", | ||||
| 	"DATABUNDLE", | ||||
| 	"DATABUNDLEEND", | ||||
| 	"MRC", | ||||
| 	"LAST", | ||||
| } | ||||
							
								
								
									
										73
									
								
								vendor/github.com/google/gops/internal/obj/arm/anames5.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								vendor/github.com/google/gops/internal/obj/arm/anames5.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| // Copyright 2015 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package arm | ||||
|  | ||||
| var cnames5 = []string{ | ||||
| 	"NONE", | ||||
| 	"REG", | ||||
| 	"REGREG", | ||||
| 	"REGREG2", | ||||
| 	"REGLIST", | ||||
| 	"SHIFT", | ||||
| 	"FREG", | ||||
| 	"PSR", | ||||
| 	"FCR", | ||||
| 	"RCON", | ||||
| 	"NCON", | ||||
| 	"SCON", | ||||
| 	"LCON", | ||||
| 	"LCONADDR", | ||||
| 	"ZFCON", | ||||
| 	"SFCON", | ||||
| 	"LFCON", | ||||
| 	"RACON", | ||||
| 	"LACON", | ||||
| 	"SBRA", | ||||
| 	"LBRA", | ||||
| 	"HAUTO", | ||||
| 	"FAUTO", | ||||
| 	"HFAUTO", | ||||
| 	"SAUTO", | ||||
| 	"LAUTO", | ||||
| 	"HOREG", | ||||
| 	"FOREG", | ||||
| 	"HFOREG", | ||||
| 	"SOREG", | ||||
| 	"ROREG", | ||||
| 	"SROREG", | ||||
| 	"LOREG", | ||||
| 	"PC", | ||||
| 	"SP", | ||||
| 	"HREG", | ||||
| 	"ADDR", | ||||
| 	"C_TLS_LE", | ||||
| 	"C_TLS_IE", | ||||
| 	"TEXTSIZE", | ||||
| 	"GOK", | ||||
| 	"NCLASS", | ||||
| 	"SCOND = (1<<4)-1", | ||||
| 	"SBIT = 1<<4", | ||||
| 	"PBIT = 1<<5", | ||||
| 	"WBIT = 1<<6", | ||||
| 	"FBIT = 1<<7", | ||||
| 	"UBIT = 1<<7", | ||||
| 	"SCOND_XOR = 14", | ||||
| 	"SCOND_EQ = 0 ^ C_SCOND_XOR", | ||||
| 	"SCOND_NE = 1 ^ C_SCOND_XOR", | ||||
| 	"SCOND_HS = 2 ^ C_SCOND_XOR", | ||||
| 	"SCOND_LO = 3 ^ C_SCOND_XOR", | ||||
| 	"SCOND_MI = 4 ^ C_SCOND_XOR", | ||||
| 	"SCOND_PL = 5 ^ C_SCOND_XOR", | ||||
| 	"SCOND_VS = 6 ^ C_SCOND_XOR", | ||||
| 	"SCOND_VC = 7 ^ C_SCOND_XOR", | ||||
| 	"SCOND_HI = 8 ^ C_SCOND_XOR", | ||||
| 	"SCOND_LS = 9 ^ C_SCOND_XOR", | ||||
| 	"SCOND_GE = 10 ^ C_SCOND_XOR", | ||||
| 	"SCOND_LT = 11 ^ C_SCOND_XOR", | ||||
| 	"SCOND_GT = 12 ^ C_SCOND_XOR", | ||||
| 	"SCOND_LE = 13 ^ C_SCOND_XOR", | ||||
| 	"SCOND_NONE = 14 ^ C_SCOND_XOR", | ||||
| 	"SCOND_NV = 15 ^ C_SCOND_XOR", | ||||
| } | ||||
							
								
								
									
										2846
									
								
								vendor/github.com/google/gops/internal/obj/arm/asm5.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2846
									
								
								vendor/github.com/google/gops/internal/obj/arm/asm5.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										84
									
								
								vendor/github.com/google/gops/internal/obj/arm/list5.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								vendor/github.com/google/gops/internal/obj/arm/list5.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| // Inferno utils/5c/list.c | ||||
| // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5c/list.c | ||||
| // | ||||
| //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | ||||
| //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| //	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others | ||||
| //	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package arm | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/google/gops/internal/obj" | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	obj.RegisterRegister(obj.RBaseARM, MAXREG, Rconv) | ||||
| 	obj.RegisterOpcode(obj.ABaseARM, Anames) | ||||
| } | ||||
|  | ||||
| func Rconv(r int) string { | ||||
| 	if r == 0 { | ||||
| 		return "NONE" | ||||
| 	} | ||||
| 	if r == REGG { | ||||
| 		// Special case. | ||||
| 		return "g" | ||||
| 	} | ||||
| 	if REG_R0 <= r && r <= REG_R15 { | ||||
| 		return fmt.Sprintf("R%d", r-REG_R0) | ||||
| 	} | ||||
| 	if REG_F0 <= r && r <= REG_F15 { | ||||
| 		return fmt.Sprintf("F%d", r-REG_F0) | ||||
| 	} | ||||
|  | ||||
| 	switch r { | ||||
| 	case REG_FPSR: | ||||
| 		return "FPSR" | ||||
|  | ||||
| 	case REG_FPCR: | ||||
| 		return "FPCR" | ||||
|  | ||||
| 	case REG_CPSR: | ||||
| 		return "CPSR" | ||||
|  | ||||
| 	case REG_SPSR: | ||||
| 		return "SPSR" | ||||
| 	} | ||||
|  | ||||
| 	return fmt.Sprintf("Rgok(%d)", r-obj.RBaseARM) | ||||
| } | ||||
|  | ||||
| func DRconv(a int) string { | ||||
| 	s := "C_??" | ||||
| 	if a >= C_NONE && a <= C_NCLASS { | ||||
| 		s = cnames5[a] | ||||
| 	} | ||||
| 	var fp string | ||||
| 	fp += s | ||||
| 	return fp | ||||
| } | ||||
							
								
								
									
										1055
									
								
								vendor/github.com/google/gops/internal/obj/arm/obj5.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1055
									
								
								vendor/github.com/google/gops/internal/obj/arm/obj5.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										719
									
								
								vendor/github.com/google/gops/internal/obj/arm64/a.out.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										719
									
								
								vendor/github.com/google/gops/internal/obj/arm64/a.out.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,719 @@ | ||||
| // cmd/7c/7.out.h  from Vita Nuova. | ||||
| // https://code.google.com/p/ken-cc/source/browse/src/cmd/7c/7.out.h | ||||
| // | ||||
| // 	Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. | ||||
| // 	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| // 	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| // 	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| // 	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| // 	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| // 	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others | ||||
| // 	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package arm64 | ||||
|  | ||||
| import "github.com/google/gops/internal/obj" | ||||
|  | ||||
| const ( | ||||
| 	NSNAME = 8 | ||||
| 	NSYM   = 50 | ||||
| 	NREG   = 32 /* number of general registers */ | ||||
| 	NFREG  = 32 /* number of floating point registers */ | ||||
| ) | ||||
|  | ||||
| // General purpose registers, kept in the low bits of Prog.Reg. | ||||
| const ( | ||||
| 	// integer | ||||
| 	REG_R0 = obj.RBaseARM64 + iota | ||||
| 	REG_R1 | ||||
| 	REG_R2 | ||||
| 	REG_R3 | ||||
| 	REG_R4 | ||||
| 	REG_R5 | ||||
| 	REG_R6 | ||||
| 	REG_R7 | ||||
| 	REG_R8 | ||||
| 	REG_R9 | ||||
| 	REG_R10 | ||||
| 	REG_R11 | ||||
| 	REG_R12 | ||||
| 	REG_R13 | ||||
| 	REG_R14 | ||||
| 	REG_R15 | ||||
| 	REG_R16 | ||||
| 	REG_R17 | ||||
| 	REG_R18 | ||||
| 	REG_R19 | ||||
| 	REG_R20 | ||||
| 	REG_R21 | ||||
| 	REG_R22 | ||||
| 	REG_R23 | ||||
| 	REG_R24 | ||||
| 	REG_R25 | ||||
| 	REG_R26 | ||||
| 	REG_R27 | ||||
| 	REG_R28 | ||||
| 	REG_R29 | ||||
| 	REG_R30 | ||||
| 	REG_R31 | ||||
|  | ||||
| 	// scalar floating point | ||||
| 	REG_F0 | ||||
| 	REG_F1 | ||||
| 	REG_F2 | ||||
| 	REG_F3 | ||||
| 	REG_F4 | ||||
| 	REG_F5 | ||||
| 	REG_F6 | ||||
| 	REG_F7 | ||||
| 	REG_F8 | ||||
| 	REG_F9 | ||||
| 	REG_F10 | ||||
| 	REG_F11 | ||||
| 	REG_F12 | ||||
| 	REG_F13 | ||||
| 	REG_F14 | ||||
| 	REG_F15 | ||||
| 	REG_F16 | ||||
| 	REG_F17 | ||||
| 	REG_F18 | ||||
| 	REG_F19 | ||||
| 	REG_F20 | ||||
| 	REG_F21 | ||||
| 	REG_F22 | ||||
| 	REG_F23 | ||||
| 	REG_F24 | ||||
| 	REG_F25 | ||||
| 	REG_F26 | ||||
| 	REG_F27 | ||||
| 	REG_F28 | ||||
| 	REG_F29 | ||||
| 	REG_F30 | ||||
| 	REG_F31 | ||||
|  | ||||
| 	// SIMD | ||||
| 	REG_V0 | ||||
| 	REG_V1 | ||||
| 	REG_V2 | ||||
| 	REG_V3 | ||||
| 	REG_V4 | ||||
| 	REG_V5 | ||||
| 	REG_V6 | ||||
| 	REG_V7 | ||||
| 	REG_V8 | ||||
| 	REG_V9 | ||||
| 	REG_V10 | ||||
| 	REG_V11 | ||||
| 	REG_V12 | ||||
| 	REG_V13 | ||||
| 	REG_V14 | ||||
| 	REG_V15 | ||||
| 	REG_V16 | ||||
| 	REG_V17 | ||||
| 	REG_V18 | ||||
| 	REG_V19 | ||||
| 	REG_V20 | ||||
| 	REG_V21 | ||||
| 	REG_V22 | ||||
| 	REG_V23 | ||||
| 	REG_V24 | ||||
| 	REG_V25 | ||||
| 	REG_V26 | ||||
| 	REG_V27 | ||||
| 	REG_V28 | ||||
| 	REG_V29 | ||||
| 	REG_V30 | ||||
| 	REG_V31 | ||||
|  | ||||
| 	// The EQ in | ||||
| 	// 	CSET	EQ, R0 | ||||
| 	// is encoded as TYPE_REG, even though it's not really a register. | ||||
| 	COND_EQ | ||||
| 	COND_NE | ||||
| 	COND_HS | ||||
| 	COND_LO | ||||
| 	COND_MI | ||||
| 	COND_PL | ||||
| 	COND_VS | ||||
| 	COND_VC | ||||
| 	COND_HI | ||||
| 	COND_LS | ||||
| 	COND_GE | ||||
| 	COND_LT | ||||
| 	COND_GT | ||||
| 	COND_LE | ||||
| 	COND_AL | ||||
| 	COND_NV | ||||
|  | ||||
| 	REG_RSP = REG_V31 + 32 // to differentiate ZR/SP, REG_RSP&0x1f = 31 | ||||
| ) | ||||
|  | ||||
| // Not registers, but flags that can be combined with regular register | ||||
| // constants to indicate extended register conversion. When checking, | ||||
| // you should subtract obj.RBaseARM64 first. From this difference, bit 11 | ||||
| // indicates extended register, bits 8-10 select the conversion mode. | ||||
| const REG_EXT = obj.RBaseARM64 + 1<<11 | ||||
|  | ||||
| const ( | ||||
| 	REG_UXTB = REG_EXT + iota<<8 | ||||
| 	REG_UXTH | ||||
| 	REG_UXTW | ||||
| 	REG_UXTX | ||||
| 	REG_SXTB | ||||
| 	REG_SXTH | ||||
| 	REG_SXTW | ||||
| 	REG_SXTX | ||||
| ) | ||||
|  | ||||
| // Special registers, after subtracting obj.RBaseARM64, bit 12 indicates | ||||
| // a special register and the low bits select the register. | ||||
| const ( | ||||
| 	REG_SPECIAL = obj.RBaseARM64 + 1<<12 + iota | ||||
| 	REG_DAIF | ||||
| 	REG_NZCV | ||||
| 	REG_FPSR | ||||
| 	REG_FPCR | ||||
| 	REG_SPSR_EL1 | ||||
| 	REG_ELR_EL1 | ||||
| 	REG_SPSR_EL2 | ||||
| 	REG_ELR_EL2 | ||||
| 	REG_CurrentEL | ||||
| 	REG_SP_EL0 | ||||
| 	REG_SPSel | ||||
| 	REG_DAIFSet | ||||
| 	REG_DAIFClr | ||||
| ) | ||||
|  | ||||
| // Register assignments: | ||||
| // | ||||
| // compiler allocates R0 up as temps | ||||
| // compiler allocates register variables R7-R25 | ||||
| // compiler allocates external registers R26 down | ||||
| // | ||||
| // compiler allocates register variables F7-F26 | ||||
| // compiler allocates external registers F26 down | ||||
| const ( | ||||
| 	REGMIN = REG_R7  // register variables allocated from here to REGMAX | ||||
| 	REGRT1 = REG_R16 // ARM64 IP0, for external linker, runtime, duffzero and duffcopy | ||||
| 	REGRT2 = REG_R17 // ARM64 IP1, for external linker, runtime, duffcopy | ||||
| 	REGPR  = REG_R18 // ARM64 platform register, unused in the Go toolchain | ||||
| 	REGMAX = REG_R25 | ||||
|  | ||||
| 	REGCTXT = REG_R26 // environment for closures | ||||
| 	REGTMP  = REG_R27 // reserved for liblink | ||||
| 	REGG    = REG_R28 // G | ||||
| 	REGFP   = REG_R29 // frame pointer, unused in the Go toolchain | ||||
| 	REGLINK = REG_R30 | ||||
|  | ||||
| 	// ARM64 uses R31 as both stack pointer and zero register, | ||||
| 	// depending on the instruction. To differentiate RSP from ZR, | ||||
| 	// we use a different numeric value for REGZERO and REGSP. | ||||
| 	REGZERO = REG_R31 | ||||
| 	REGSP   = REG_RSP | ||||
|  | ||||
| 	FREGRET = REG_F0 | ||||
| 	FREGMIN = REG_F7  // first register variable | ||||
| 	FREGMAX = REG_F26 // last register variable for 7g only | ||||
| 	FREGEXT = REG_F26 // first external register | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	BIG = 2048 - 8 | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	/* mark flags */ | ||||
| 	LABEL = 1 << iota | ||||
| 	LEAF | ||||
| 	FLOAT | ||||
| 	BRANCH | ||||
| 	LOAD | ||||
| 	FCMP | ||||
| 	SYNC | ||||
| 	LIST | ||||
| 	FOLL | ||||
| 	NOSCHED | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	C_NONE   = iota | ||||
| 	C_REG    // R0..R30 | ||||
| 	C_RSP    // R0..R30, RSP | ||||
| 	C_FREG   // F0..F31 | ||||
| 	C_VREG   // V0..V31 | ||||
| 	C_PAIR   // (Rn, Rm) | ||||
| 	C_SHIFT  // Rn<<2 | ||||
| 	C_EXTREG // Rn.UXTB<<3 | ||||
| 	C_SPR    // REG_NZCV | ||||
| 	C_COND   // EQ, NE, etc | ||||
|  | ||||
| 	C_ZCON     // $0 or ZR | ||||
| 	C_ADDCON0  // 12-bit unsigned, unshifted | ||||
| 	C_ADDCON   // 12-bit unsigned, shifted left by 0 or 12 | ||||
| 	C_MOVCON   // generated by a 16-bit constant, optionally inverted and/or shifted by multiple of 16 | ||||
| 	C_BITCON   // bitfield and logical immediate masks | ||||
| 	C_ABCON0   // could be C_ADDCON0 or C_BITCON | ||||
| 	C_ABCON    // could be C_ADDCON or C_BITCON | ||||
| 	C_MBCON    // could be C_MOVCON or C_BITCON | ||||
| 	C_LCON     // 32-bit constant | ||||
| 	C_VCON     // 64-bit constant | ||||
| 	C_FCON     // floating-point constant | ||||
| 	C_VCONADDR // 64-bit memory address | ||||
|  | ||||
| 	C_AACON // ADDCON offset in auto constant $a(FP) | ||||
| 	C_LACON // 32-bit offset in auto constant $a(FP) | ||||
| 	C_AECON // ADDCON offset in extern constant $e(SB) | ||||
|  | ||||
| 	// TODO(aram): only one branch class should be enough | ||||
| 	C_SBRA // for TYPE_BRANCH | ||||
| 	C_LBRA | ||||
|  | ||||
| 	C_NPAUTO   // -512 <= x < 0, 0 mod 8 | ||||
| 	C_NSAUTO   // -256 <= x < 0 | ||||
| 	C_PSAUTO   // 0 to 255 | ||||
| 	C_PPAUTO   // 0 to 504, 0 mod 8 | ||||
| 	C_UAUTO4K  // 0 to 4095 | ||||
| 	C_UAUTO8K  // 0 to 8190, 0 mod 2 | ||||
| 	C_UAUTO16K // 0 to 16380, 0 mod 4 | ||||
| 	C_UAUTO32K // 0 to 32760, 0 mod 8 | ||||
| 	C_UAUTO64K // 0 to 65520, 0 mod 16 | ||||
| 	C_LAUTO    // any other 32-bit constant | ||||
|  | ||||
| 	C_SEXT1  // 0 to 4095, direct | ||||
| 	C_SEXT2  // 0 to 8190 | ||||
| 	C_SEXT4  // 0 to 16380 | ||||
| 	C_SEXT8  // 0 to 32760 | ||||
| 	C_SEXT16 // 0 to 65520 | ||||
| 	C_LEXT | ||||
|  | ||||
| 	// TODO(aram): s/AUTO/INDIR/ | ||||
| 	C_ZOREG  // 0(R) | ||||
| 	C_NPOREG // mirror NPAUTO, etc | ||||
| 	C_NSOREG | ||||
| 	C_PSOREG | ||||
| 	C_PPOREG | ||||
| 	C_UOREG4K | ||||
| 	C_UOREG8K | ||||
| 	C_UOREG16K | ||||
| 	C_UOREG32K | ||||
| 	C_UOREG64K | ||||
| 	C_LOREG | ||||
|  | ||||
| 	C_ADDR // TODO(aram): explain difference from C_VCONADDR | ||||
|  | ||||
| 	// The GOT slot for a symbol in -dynlink mode. | ||||
| 	C_GOTADDR | ||||
|  | ||||
| 	// TLS "var" in local exec mode: will become a constant offset from | ||||
| 	// thread local base that is ultimately chosen by the program linker. | ||||
| 	C_TLS_LE | ||||
|  | ||||
| 	// TLS "var" in initial exec mode: will become a memory address (chosen | ||||
| 	// by the program linker) that the dynamic linker will fill with the | ||||
| 	// offset from the thread local base. | ||||
| 	C_TLS_IE | ||||
|  | ||||
| 	C_ROFF // register offset (including register extended) | ||||
|  | ||||
| 	C_GOK | ||||
| 	C_TEXTSIZE | ||||
| 	C_NCLASS // must be last | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	C_XPRE  = 1 << 6 // match arm.C_WBIT, so Prog.String know how to print it | ||||
| 	C_XPOST = 1 << 5 // match arm.C_PBIT, so Prog.String know how to print it | ||||
| ) | ||||
|  | ||||
| //go:generate go run ../stringer.go -i $GOFILE -o anames.go -p arm64 | ||||
|  | ||||
| const ( | ||||
| 	AADC = obj.ABaseARM64 + obj.A_ARCHSPECIFIC + iota | ||||
| 	AADCS | ||||
| 	AADCSW | ||||
| 	AADCW | ||||
| 	AADD | ||||
| 	AADDS | ||||
| 	AADDSW | ||||
| 	AADDW | ||||
| 	AADR | ||||
| 	AADRP | ||||
| 	AAND | ||||
| 	AANDS | ||||
| 	AANDSW | ||||
| 	AANDW | ||||
| 	AASR | ||||
| 	AASRW | ||||
| 	AAT | ||||
| 	ABFI | ||||
| 	ABFIW | ||||
| 	ABFM | ||||
| 	ABFMW | ||||
| 	ABFXIL | ||||
| 	ABFXILW | ||||
| 	ABIC | ||||
| 	ABICS | ||||
| 	ABICSW | ||||
| 	ABICW | ||||
| 	ABRK | ||||
| 	ACBNZ | ||||
| 	ACBNZW | ||||
| 	ACBZ | ||||
| 	ACBZW | ||||
| 	ACCMN | ||||
| 	ACCMNW | ||||
| 	ACCMP | ||||
| 	ACCMPW | ||||
| 	ACINC | ||||
| 	ACINCW | ||||
| 	ACINV | ||||
| 	ACINVW | ||||
| 	ACLREX | ||||
| 	ACLS | ||||
| 	ACLSW | ||||
| 	ACLZ | ||||
| 	ACLZW | ||||
| 	ACMN | ||||
| 	ACMNW | ||||
| 	ACMP | ||||
| 	ACMPW | ||||
| 	ACNEG | ||||
| 	ACNEGW | ||||
| 	ACRC32B | ||||
| 	ACRC32CB | ||||
| 	ACRC32CH | ||||
| 	ACRC32CW | ||||
| 	ACRC32CX | ||||
| 	ACRC32H | ||||
| 	ACRC32W | ||||
| 	ACRC32X | ||||
| 	ACSEL | ||||
| 	ACSELW | ||||
| 	ACSET | ||||
| 	ACSETM | ||||
| 	ACSETMW | ||||
| 	ACSETW | ||||
| 	ACSINC | ||||
| 	ACSINCW | ||||
| 	ACSINV | ||||
| 	ACSINVW | ||||
| 	ACSNEG | ||||
| 	ACSNEGW | ||||
| 	ADC | ||||
| 	ADCPS1 | ||||
| 	ADCPS2 | ||||
| 	ADCPS3 | ||||
| 	ADMB | ||||
| 	ADRPS | ||||
| 	ADSB | ||||
| 	AEON | ||||
| 	AEONW | ||||
| 	AEOR | ||||
| 	AEORW | ||||
| 	AERET | ||||
| 	AEXTR | ||||
| 	AEXTRW | ||||
| 	AHINT | ||||
| 	AHLT | ||||
| 	AHVC | ||||
| 	AIC | ||||
| 	AISB | ||||
| 	ALDAR | ||||
| 	ALDARB | ||||
| 	ALDARH | ||||
| 	ALDARW | ||||
| 	ALDAXP | ||||
| 	ALDAXPW | ||||
| 	ALDAXR | ||||
| 	ALDAXRB | ||||
| 	ALDAXRH | ||||
| 	ALDAXRW | ||||
| 	ALDP | ||||
| 	ALDXR | ||||
| 	ALDXRB | ||||
| 	ALDXRH | ||||
| 	ALDXRW | ||||
| 	ALDXP | ||||
| 	ALDXPW | ||||
| 	ALSL | ||||
| 	ALSLW | ||||
| 	ALSR | ||||
| 	ALSRW | ||||
| 	AMADD | ||||
| 	AMADDW | ||||
| 	AMNEG | ||||
| 	AMNEGW | ||||
| 	AMOVK | ||||
| 	AMOVKW | ||||
| 	AMOVN | ||||
| 	AMOVNW | ||||
| 	AMOVZ | ||||
| 	AMOVZW | ||||
| 	AMRS | ||||
| 	AMSR | ||||
| 	AMSUB | ||||
| 	AMSUBW | ||||
| 	AMUL | ||||
| 	AMULW | ||||
| 	AMVN | ||||
| 	AMVNW | ||||
| 	ANEG | ||||
| 	ANEGS | ||||
| 	ANEGSW | ||||
| 	ANEGW | ||||
| 	ANGC | ||||
| 	ANGCS | ||||
| 	ANGCSW | ||||
| 	ANGCW | ||||
| 	AORN | ||||
| 	AORNW | ||||
| 	AORR | ||||
| 	AORRW | ||||
| 	APRFM | ||||
| 	APRFUM | ||||
| 	ARBIT | ||||
| 	ARBITW | ||||
| 	AREM | ||||
| 	AREMW | ||||
| 	AREV | ||||
| 	AREV16 | ||||
| 	AREV16W | ||||
| 	AREV32 | ||||
| 	AREVW | ||||
| 	AROR | ||||
| 	ARORW | ||||
| 	ASBC | ||||
| 	ASBCS | ||||
| 	ASBCSW | ||||
| 	ASBCW | ||||
| 	ASBFIZ | ||||
| 	ASBFIZW | ||||
| 	ASBFM | ||||
| 	ASBFMW | ||||
| 	ASBFX | ||||
| 	ASBFXW | ||||
| 	ASDIV | ||||
| 	ASDIVW | ||||
| 	ASEV | ||||
| 	ASEVL | ||||
| 	ASMADDL | ||||
| 	ASMC | ||||
| 	ASMNEGL | ||||
| 	ASMSUBL | ||||
| 	ASMULH | ||||
| 	ASMULL | ||||
| 	ASTXR | ||||
| 	ASTXRB | ||||
| 	ASTXRH | ||||
| 	ASTXP | ||||
| 	ASTXPW | ||||
| 	ASTXRW | ||||
| 	ASTLP | ||||
| 	ASTLPW | ||||
| 	ASTLR | ||||
| 	ASTLRB | ||||
| 	ASTLRH | ||||
| 	ASTLRW | ||||
| 	ASTLXP | ||||
| 	ASTLXPW | ||||
| 	ASTLXR | ||||
| 	ASTLXRB | ||||
| 	ASTLXRH | ||||
| 	ASTLXRW | ||||
| 	ASTP | ||||
| 	ASUB | ||||
| 	ASUBS | ||||
| 	ASUBSW | ||||
| 	ASUBW | ||||
| 	ASVC | ||||
| 	ASXTB | ||||
| 	ASXTBW | ||||
| 	ASXTH | ||||
| 	ASXTHW | ||||
| 	ASXTW | ||||
| 	ASYS | ||||
| 	ASYSL | ||||
| 	ATBNZ | ||||
| 	ATBZ | ||||
| 	ATLBI | ||||
| 	ATST | ||||
| 	ATSTW | ||||
| 	AUBFIZ | ||||
| 	AUBFIZW | ||||
| 	AUBFM | ||||
| 	AUBFMW | ||||
| 	AUBFX | ||||
| 	AUBFXW | ||||
| 	AUDIV | ||||
| 	AUDIVW | ||||
| 	AUMADDL | ||||
| 	AUMNEGL | ||||
| 	AUMSUBL | ||||
| 	AUMULH | ||||
| 	AUMULL | ||||
| 	AUREM | ||||
| 	AUREMW | ||||
| 	AUXTB | ||||
| 	AUXTH | ||||
| 	AUXTW | ||||
| 	AUXTBW | ||||
| 	AUXTHW | ||||
| 	AWFE | ||||
| 	AWFI | ||||
| 	AYIELD | ||||
| 	AMOVB | ||||
| 	AMOVBU | ||||
| 	AMOVH | ||||
| 	AMOVHU | ||||
| 	AMOVW | ||||
| 	AMOVWU | ||||
| 	AMOVD | ||||
| 	AMOVNP | ||||
| 	AMOVNPW | ||||
| 	AMOVP | ||||
| 	AMOVPD | ||||
| 	AMOVPQ | ||||
| 	AMOVPS | ||||
| 	AMOVPSW | ||||
| 	AMOVPW | ||||
| 	ABEQ | ||||
| 	ABNE | ||||
| 	ABCS | ||||
| 	ABHS | ||||
| 	ABCC | ||||
| 	ABLO | ||||
| 	ABMI | ||||
| 	ABPL | ||||
| 	ABVS | ||||
| 	ABVC | ||||
| 	ABHI | ||||
| 	ABLS | ||||
| 	ABGE | ||||
| 	ABLT | ||||
| 	ABGT | ||||
| 	ABLE | ||||
| 	AFABSD | ||||
| 	AFABSS | ||||
| 	AFADDD | ||||
| 	AFADDS | ||||
| 	AFCCMPD | ||||
| 	AFCCMPED | ||||
| 	AFCCMPS | ||||
| 	AFCCMPES | ||||
| 	AFCMPD | ||||
| 	AFCMPED | ||||
| 	AFCMPES | ||||
| 	AFCMPS | ||||
| 	AFCVTSD | ||||
| 	AFCVTDS | ||||
| 	AFCVTZSD | ||||
| 	AFCVTZSDW | ||||
| 	AFCVTZSS | ||||
| 	AFCVTZSSW | ||||
| 	AFCVTZUD | ||||
| 	AFCVTZUDW | ||||
| 	AFCVTZUS | ||||
| 	AFCVTZUSW | ||||
| 	AFDIVD | ||||
| 	AFDIVS | ||||
| 	AFMOVD | ||||
| 	AFMOVS | ||||
| 	AFMULD | ||||
| 	AFMULS | ||||
| 	AFNEGD | ||||
| 	AFNEGS | ||||
| 	AFSQRTD | ||||
| 	AFSQRTS | ||||
| 	AFSUBD | ||||
| 	AFSUBS | ||||
| 	ASCVTFD | ||||
| 	ASCVTFS | ||||
| 	ASCVTFWD | ||||
| 	ASCVTFWS | ||||
| 	AUCVTFD | ||||
| 	AUCVTFS | ||||
| 	AUCVTFWD | ||||
| 	AUCVTFWS | ||||
| 	AWORD | ||||
| 	ADWORD | ||||
| 	AFCSELS | ||||
| 	AFCSELD | ||||
| 	AFMAXS | ||||
| 	AFMINS | ||||
| 	AFMAXD | ||||
| 	AFMIND | ||||
| 	AFMAXNMS | ||||
| 	AFMAXNMD | ||||
| 	AFNMULS | ||||
| 	AFNMULD | ||||
| 	AFRINTNS | ||||
| 	AFRINTND | ||||
| 	AFRINTPS | ||||
| 	AFRINTPD | ||||
| 	AFRINTMS | ||||
| 	AFRINTMD | ||||
| 	AFRINTZS | ||||
| 	AFRINTZD | ||||
| 	AFRINTAS | ||||
| 	AFRINTAD | ||||
| 	AFRINTXS | ||||
| 	AFRINTXD | ||||
| 	AFRINTIS | ||||
| 	AFRINTID | ||||
| 	AFMADDS | ||||
| 	AFMADDD | ||||
| 	AFMSUBS | ||||
| 	AFMSUBD | ||||
| 	AFNMADDS | ||||
| 	AFNMADDD | ||||
| 	AFNMSUBS | ||||
| 	AFNMSUBD | ||||
| 	AFMINNMS | ||||
| 	AFMINNMD | ||||
| 	AFCVTDH | ||||
| 	AFCVTHS | ||||
| 	AFCVTHD | ||||
| 	AFCVTSH | ||||
| 	AAESD | ||||
| 	AAESE | ||||
| 	AAESIMC | ||||
| 	AAESMC | ||||
| 	ASHA1C | ||||
| 	ASHA1H | ||||
| 	ASHA1M | ||||
| 	ASHA1P | ||||
| 	ASHA1SU0 | ||||
| 	ASHA1SU1 | ||||
| 	ASHA256H | ||||
| 	ASHA256H2 | ||||
| 	ASHA256SU0 | ||||
| 	ASHA256SU1 | ||||
| 	ALAST | ||||
| 	AB  = obj.AJMP | ||||
| 	ABL = obj.ACALL | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// shift types | ||||
| 	SHIFT_LL = 0 << 22 | ||||
| 	SHIFT_LR = 1 << 22 | ||||
| 	SHIFT_AR = 2 << 22 | ||||
| ) | ||||
							
								
								
									
										370
									
								
								vendor/github.com/google/gops/internal/obj/arm64/anames.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										370
									
								
								vendor/github.com/google/gops/internal/obj/arm64/anames.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,370 @@ | ||||
| // Generated by stringer -i a.out.go -o anames.go -p arm64 | ||||
| // Do not edit. | ||||
|  | ||||
| package arm64 | ||||
|  | ||||
| import "github.com/google/gops/internal/obj" | ||||
|  | ||||
| var Anames = []string{ | ||||
| 	obj.A_ARCHSPECIFIC: "ADC", | ||||
| 	"ADCS", | ||||
| 	"ADCSW", | ||||
| 	"ADCW", | ||||
| 	"ADD", | ||||
| 	"ADDS", | ||||
| 	"ADDSW", | ||||
| 	"ADDW", | ||||
| 	"ADR", | ||||
| 	"ADRP", | ||||
| 	"AND", | ||||
| 	"ANDS", | ||||
| 	"ANDSW", | ||||
| 	"ANDW", | ||||
| 	"ASR", | ||||
| 	"ASRW", | ||||
| 	"AT", | ||||
| 	"BFI", | ||||
| 	"BFIW", | ||||
| 	"BFM", | ||||
| 	"BFMW", | ||||
| 	"BFXIL", | ||||
| 	"BFXILW", | ||||
| 	"BIC", | ||||
| 	"BICS", | ||||
| 	"BICSW", | ||||
| 	"BICW", | ||||
| 	"BRK", | ||||
| 	"CBNZ", | ||||
| 	"CBNZW", | ||||
| 	"CBZ", | ||||
| 	"CBZW", | ||||
| 	"CCMN", | ||||
| 	"CCMNW", | ||||
| 	"CCMP", | ||||
| 	"CCMPW", | ||||
| 	"CINC", | ||||
| 	"CINCW", | ||||
| 	"CINV", | ||||
| 	"CINVW", | ||||
| 	"CLREX", | ||||
| 	"CLS", | ||||
| 	"CLSW", | ||||
| 	"CLZ", | ||||
| 	"CLZW", | ||||
| 	"CMN", | ||||
| 	"CMNW", | ||||
| 	"CMP", | ||||
| 	"CMPW", | ||||
| 	"CNEG", | ||||
| 	"CNEGW", | ||||
| 	"CRC32B", | ||||
| 	"CRC32CB", | ||||
| 	"CRC32CH", | ||||
| 	"CRC32CW", | ||||
| 	"CRC32CX", | ||||
| 	"CRC32H", | ||||
| 	"CRC32W", | ||||
| 	"CRC32X", | ||||
| 	"CSEL", | ||||
| 	"CSELW", | ||||
| 	"CSET", | ||||
| 	"CSETM", | ||||
| 	"CSETMW", | ||||
| 	"CSETW", | ||||
| 	"CSINC", | ||||
| 	"CSINCW", | ||||
| 	"CSINV", | ||||
| 	"CSINVW", | ||||
| 	"CSNEG", | ||||
| 	"CSNEGW", | ||||
| 	"DC", | ||||
| 	"DCPS1", | ||||
| 	"DCPS2", | ||||
| 	"DCPS3", | ||||
| 	"DMB", | ||||
| 	"DRPS", | ||||
| 	"DSB", | ||||
| 	"EON", | ||||
| 	"EONW", | ||||
| 	"EOR", | ||||
| 	"EORW", | ||||
| 	"ERET", | ||||
| 	"EXTR", | ||||
| 	"EXTRW", | ||||
| 	"HINT", | ||||
| 	"HLT", | ||||
| 	"HVC", | ||||
| 	"IC", | ||||
| 	"ISB", | ||||
| 	"LDAR", | ||||
| 	"LDARB", | ||||
| 	"LDARH", | ||||
| 	"LDARW", | ||||
| 	"LDAXP", | ||||
| 	"LDAXPW", | ||||
| 	"LDAXR", | ||||
| 	"LDAXRB", | ||||
| 	"LDAXRH", | ||||
| 	"LDAXRW", | ||||
| 	"LDP", | ||||
| 	"LDXR", | ||||
| 	"LDXRB", | ||||
| 	"LDXRH", | ||||
| 	"LDXRW", | ||||
| 	"LDXP", | ||||
| 	"LDXPW", | ||||
| 	"LSL", | ||||
| 	"LSLW", | ||||
| 	"LSR", | ||||
| 	"LSRW", | ||||
| 	"MADD", | ||||
| 	"MADDW", | ||||
| 	"MNEG", | ||||
| 	"MNEGW", | ||||
| 	"MOVK", | ||||
| 	"MOVKW", | ||||
| 	"MOVN", | ||||
| 	"MOVNW", | ||||
| 	"MOVZ", | ||||
| 	"MOVZW", | ||||
| 	"MRS", | ||||
| 	"MSR", | ||||
| 	"MSUB", | ||||
| 	"MSUBW", | ||||
| 	"MUL", | ||||
| 	"MULW", | ||||
| 	"MVN", | ||||
| 	"MVNW", | ||||
| 	"NEG", | ||||
| 	"NEGS", | ||||
| 	"NEGSW", | ||||
| 	"NEGW", | ||||
| 	"NGC", | ||||
| 	"NGCS", | ||||
| 	"NGCSW", | ||||
| 	"NGCW", | ||||
| 	"ORN", | ||||
| 	"ORNW", | ||||
| 	"ORR", | ||||
| 	"ORRW", | ||||
| 	"PRFM", | ||||
| 	"PRFUM", | ||||
| 	"RBIT", | ||||
| 	"RBITW", | ||||
| 	"REM", | ||||
| 	"REMW", | ||||
| 	"REV", | ||||
| 	"REV16", | ||||
| 	"REV16W", | ||||
| 	"REV32", | ||||
| 	"REVW", | ||||
| 	"ROR", | ||||
| 	"RORW", | ||||
| 	"SBC", | ||||
| 	"SBCS", | ||||
| 	"SBCSW", | ||||
| 	"SBCW", | ||||
| 	"SBFIZ", | ||||
| 	"SBFIZW", | ||||
| 	"SBFM", | ||||
| 	"SBFMW", | ||||
| 	"SBFX", | ||||
| 	"SBFXW", | ||||
| 	"SDIV", | ||||
| 	"SDIVW", | ||||
| 	"SEV", | ||||
| 	"SEVL", | ||||
| 	"SMADDL", | ||||
| 	"SMC", | ||||
| 	"SMNEGL", | ||||
| 	"SMSUBL", | ||||
| 	"SMULH", | ||||
| 	"SMULL", | ||||
| 	"STXR", | ||||
| 	"STXRB", | ||||
| 	"STXRH", | ||||
| 	"STXP", | ||||
| 	"STXPW", | ||||
| 	"STXRW", | ||||
| 	"STLP", | ||||
| 	"STLPW", | ||||
| 	"STLR", | ||||
| 	"STLRB", | ||||
| 	"STLRH", | ||||
| 	"STLRW", | ||||
| 	"STLXP", | ||||
| 	"STLXPW", | ||||
| 	"STLXR", | ||||
| 	"STLXRB", | ||||
| 	"STLXRH", | ||||
| 	"STLXRW", | ||||
| 	"STP", | ||||
| 	"SUB", | ||||
| 	"SUBS", | ||||
| 	"SUBSW", | ||||
| 	"SUBW", | ||||
| 	"SVC", | ||||
| 	"SXTB", | ||||
| 	"SXTBW", | ||||
| 	"SXTH", | ||||
| 	"SXTHW", | ||||
| 	"SXTW", | ||||
| 	"SYS", | ||||
| 	"SYSL", | ||||
| 	"TBNZ", | ||||
| 	"TBZ", | ||||
| 	"TLBI", | ||||
| 	"TST", | ||||
| 	"TSTW", | ||||
| 	"UBFIZ", | ||||
| 	"UBFIZW", | ||||
| 	"UBFM", | ||||
| 	"UBFMW", | ||||
| 	"UBFX", | ||||
| 	"UBFXW", | ||||
| 	"UDIV", | ||||
| 	"UDIVW", | ||||
| 	"UMADDL", | ||||
| 	"UMNEGL", | ||||
| 	"UMSUBL", | ||||
| 	"UMULH", | ||||
| 	"UMULL", | ||||
| 	"UREM", | ||||
| 	"UREMW", | ||||
| 	"UXTB", | ||||
| 	"UXTH", | ||||
| 	"UXTW", | ||||
| 	"UXTBW", | ||||
| 	"UXTHW", | ||||
| 	"WFE", | ||||
| 	"WFI", | ||||
| 	"YIELD", | ||||
| 	"MOVB", | ||||
| 	"MOVBU", | ||||
| 	"MOVH", | ||||
| 	"MOVHU", | ||||
| 	"MOVW", | ||||
| 	"MOVWU", | ||||
| 	"MOVD", | ||||
| 	"MOVNP", | ||||
| 	"MOVNPW", | ||||
| 	"MOVP", | ||||
| 	"MOVPD", | ||||
| 	"MOVPQ", | ||||
| 	"MOVPS", | ||||
| 	"MOVPSW", | ||||
| 	"MOVPW", | ||||
| 	"BEQ", | ||||
| 	"BNE", | ||||
| 	"BCS", | ||||
| 	"BHS", | ||||
| 	"BCC", | ||||
| 	"BLO", | ||||
| 	"BMI", | ||||
| 	"BPL", | ||||
| 	"BVS", | ||||
| 	"BVC", | ||||
| 	"BHI", | ||||
| 	"BLS", | ||||
| 	"BGE", | ||||
| 	"BLT", | ||||
| 	"BGT", | ||||
| 	"BLE", | ||||
| 	"FABSD", | ||||
| 	"FABSS", | ||||
| 	"FADDD", | ||||
| 	"FADDS", | ||||
| 	"FCCMPD", | ||||
| 	"FCCMPED", | ||||
| 	"FCCMPS", | ||||
| 	"FCCMPES", | ||||
| 	"FCMPD", | ||||
| 	"FCMPED", | ||||
| 	"FCMPES", | ||||
| 	"FCMPS", | ||||
| 	"FCVTSD", | ||||
| 	"FCVTDS", | ||||
| 	"FCVTZSD", | ||||
| 	"FCVTZSDW", | ||||
| 	"FCVTZSS", | ||||
| 	"FCVTZSSW", | ||||
| 	"FCVTZUD", | ||||
| 	"FCVTZUDW", | ||||
| 	"FCVTZUS", | ||||
| 	"FCVTZUSW", | ||||
| 	"FDIVD", | ||||
| 	"FDIVS", | ||||
| 	"FMOVD", | ||||
| 	"FMOVS", | ||||
| 	"FMULD", | ||||
| 	"FMULS", | ||||
| 	"FNEGD", | ||||
| 	"FNEGS", | ||||
| 	"FSQRTD", | ||||
| 	"FSQRTS", | ||||
| 	"FSUBD", | ||||
| 	"FSUBS", | ||||
| 	"SCVTFD", | ||||
| 	"SCVTFS", | ||||
| 	"SCVTFWD", | ||||
| 	"SCVTFWS", | ||||
| 	"UCVTFD", | ||||
| 	"UCVTFS", | ||||
| 	"UCVTFWD", | ||||
| 	"UCVTFWS", | ||||
| 	"WORD", | ||||
| 	"DWORD", | ||||
| 	"FCSELS", | ||||
| 	"FCSELD", | ||||
| 	"FMAXS", | ||||
| 	"FMINS", | ||||
| 	"FMAXD", | ||||
| 	"FMIND", | ||||
| 	"FMAXNMS", | ||||
| 	"FMAXNMD", | ||||
| 	"FNMULS", | ||||
| 	"FNMULD", | ||||
| 	"FRINTNS", | ||||
| 	"FRINTND", | ||||
| 	"FRINTPS", | ||||
| 	"FRINTPD", | ||||
| 	"FRINTMS", | ||||
| 	"FRINTMD", | ||||
| 	"FRINTZS", | ||||
| 	"FRINTZD", | ||||
| 	"FRINTAS", | ||||
| 	"FRINTAD", | ||||
| 	"FRINTXS", | ||||
| 	"FRINTXD", | ||||
| 	"FRINTIS", | ||||
| 	"FRINTID", | ||||
| 	"FMADDS", | ||||
| 	"FMADDD", | ||||
| 	"FMSUBS", | ||||
| 	"FMSUBD", | ||||
| 	"FNMADDS", | ||||
| 	"FNMADDD", | ||||
| 	"FNMSUBS", | ||||
| 	"FNMSUBD", | ||||
| 	"FMINNMS", | ||||
| 	"FMINNMD", | ||||
| 	"FCVTDH", | ||||
| 	"FCVTHS", | ||||
| 	"FCVTHD", | ||||
| 	"FCVTSH", | ||||
| 	"AESD", | ||||
| 	"AESE", | ||||
| 	"AESIMC", | ||||
| 	"AESMC", | ||||
| 	"SHA1C", | ||||
| 	"SHA1H", | ||||
| 	"SHA1M", | ||||
| 	"SHA1P", | ||||
| 	"SHA1SU0", | ||||
| 	"SHA1SU1", | ||||
| 	"SHA256H", | ||||
| 	"SHA256H2", | ||||
| 	"SHA256SU0", | ||||
| 	"SHA256SU1", | ||||
| 	"LAST", | ||||
| } | ||||
							
								
								
									
										70
									
								
								vendor/github.com/google/gops/internal/obj/arm64/anames7.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								vendor/github.com/google/gops/internal/obj/arm64/anames7.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| // Copyright 2015 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package arm64 | ||||
|  | ||||
| var cnames7 = []string{ | ||||
| 	"NONE", | ||||
| 	"REG", | ||||
| 	"RSP", | ||||
| 	"FREG", | ||||
| 	"VREG", | ||||
| 	"PAIR", | ||||
| 	"SHIFT", | ||||
| 	"EXTREG", | ||||
| 	"SPR", | ||||
| 	"COND", | ||||
| 	"ZCON", | ||||
| 	"ADDCON0", | ||||
| 	"ADDCON", | ||||
| 	"MOVCON", | ||||
| 	"BITCON", | ||||
| 	"ABCON0", | ||||
| 	"ABCON", | ||||
| 	"MBCON", | ||||
| 	"LCON", | ||||
| 	"VCON", | ||||
| 	"FCON", | ||||
| 	"VCONADDR", | ||||
| 	"AACON", | ||||
| 	"LACON", | ||||
| 	"AECON", | ||||
| 	"SBRA", | ||||
| 	"LBRA", | ||||
| 	"NPAUTO", | ||||
| 	"NSAUTO", | ||||
| 	"PSAUTO", | ||||
| 	"PPAUTO", | ||||
| 	"UAUTO4K", | ||||
| 	"UAUTO8K", | ||||
| 	"UAUTO16K", | ||||
| 	"UAUTO32K", | ||||
| 	"UAUTO64K", | ||||
| 	"LAUTO", | ||||
| 	"SEXT1", | ||||
| 	"SEXT2", | ||||
| 	"SEXT4", | ||||
| 	"SEXT8", | ||||
| 	"SEXT16", | ||||
| 	"LEXT", | ||||
| 	"ZOREG", | ||||
| 	"NPOREG", | ||||
| 	"NSOREG", | ||||
| 	"PSOREG", | ||||
| 	"PPOREG", | ||||
| 	"UOREG4K", | ||||
| 	"UOREG8K", | ||||
| 	"UOREG16K", | ||||
| 	"UOREG32K", | ||||
| 	"UOREG64K", | ||||
| 	"LOREG", | ||||
| 	"ADDR", | ||||
| 	"GOTADDR", | ||||
| 	"TLS_LE", | ||||
| 	"TLS_IE", | ||||
| 	"ROFF", | ||||
| 	"GOK", | ||||
| 	"TEXTSIZE", | ||||
| 	"NCLASS", | ||||
| } | ||||
							
								
								
									
										4374
									
								
								vendor/github.com/google/gops/internal/obj/arm64/asm7.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4374
									
								
								vendor/github.com/google/gops/internal/obj/arm64/asm7.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										115
									
								
								vendor/github.com/google/gops/internal/obj/arm64/list7.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								vendor/github.com/google/gops/internal/obj/arm64/list7.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| // cmd/7l/list.c and cmd/7l/sub.c from Vita Nuova. | ||||
| // https://code.google.com/p/ken-cc/source/browse/ | ||||
| // | ||||
| // 	Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. | ||||
| // 	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| // 	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| // 	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| // 	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| // 	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| // 	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others | ||||
| // 	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package arm64 | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/google/gops/internal/obj" | ||||
| ) | ||||
|  | ||||
| var strcond = [16]string{ | ||||
| 	"EQ", | ||||
| 	"NE", | ||||
| 	"HS", | ||||
| 	"LO", | ||||
| 	"MI", | ||||
| 	"PL", | ||||
| 	"VS", | ||||
| 	"VC", | ||||
| 	"HI", | ||||
| 	"LS", | ||||
| 	"GE", | ||||
| 	"LT", | ||||
| 	"GT", | ||||
| 	"LE", | ||||
| 	"AL", | ||||
| 	"NV", | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	obj.RegisterRegister(obj.RBaseARM64, REG_SPECIAL+1024, Rconv) | ||||
| 	obj.RegisterOpcode(obj.ABaseARM64, Anames) | ||||
| } | ||||
|  | ||||
| func Rconv(r int) string { | ||||
| 	if r == REGG { | ||||
| 		return "g" | ||||
| 	} | ||||
| 	switch { | ||||
| 	case REG_R0 <= r && r <= REG_R30: | ||||
| 		return fmt.Sprintf("R%d", r-REG_R0) | ||||
| 	case r == REG_R31: | ||||
| 		return "ZR" | ||||
| 	case REG_F0 <= r && r <= REG_F31: | ||||
| 		return fmt.Sprintf("F%d", r-REG_F0) | ||||
| 	case REG_V0 <= r && r <= REG_V31: | ||||
| 		return fmt.Sprintf("V%d", r-REG_V0) | ||||
| 	case COND_EQ <= r && r <= COND_NV: | ||||
| 		return strcond[r-COND_EQ] | ||||
| 	case r == REGSP: | ||||
| 		return "RSP" | ||||
| 	case r == REG_DAIF: | ||||
| 		return "DAIF" | ||||
| 	case r == REG_NZCV: | ||||
| 		return "NZCV" | ||||
| 	case r == REG_FPSR: | ||||
| 		return "FPSR" | ||||
| 	case r == REG_FPCR: | ||||
| 		return "FPCR" | ||||
| 	case r == REG_SPSR_EL1: | ||||
| 		return "SPSR_EL1" | ||||
| 	case r == REG_ELR_EL1: | ||||
| 		return "ELR_EL1" | ||||
| 	case r == REG_SPSR_EL2: | ||||
| 		return "SPSR_EL2" | ||||
| 	case r == REG_ELR_EL2: | ||||
| 		return "ELR_EL2" | ||||
| 	case r == REG_CurrentEL: | ||||
| 		return "CurrentEL" | ||||
| 	case r == REG_SP_EL0: | ||||
| 		return "SP_EL0" | ||||
| 	case r == REG_SPSel: | ||||
| 		return "SPSel" | ||||
| 	case r == REG_DAIFSet: | ||||
| 		return "DAIFSet" | ||||
| 	case r == REG_DAIFClr: | ||||
| 		return "DAIFClr" | ||||
| 	} | ||||
| 	return fmt.Sprintf("badreg(%d)", r) | ||||
| } | ||||
|  | ||||
| func DRconv(a int) string { | ||||
| 	if a >= C_NONE && a <= C_NCLASS { | ||||
| 		return cnames7[a] | ||||
| 	} | ||||
| 	return "C_??" | ||||
| } | ||||
							
								
								
									
										1005
									
								
								vendor/github.com/google/gops/internal/obj/arm64/obj7.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1005
									
								
								vendor/github.com/google/gops/internal/obj/arm64/obj7.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										190
									
								
								vendor/github.com/google/gops/internal/obj/data.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								vendor/github.com/google/gops/internal/obj/data.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,190 @@ | ||||
| // Derived from Inferno utils/6l/obj.c and utils/6l/span.c | ||||
| // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c | ||||
| // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c | ||||
| // | ||||
| //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | ||||
| //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| //	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others | ||||
| //	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| import ( | ||||
| 	"log" | ||||
| 	"math" | ||||
| ) | ||||
|  | ||||
| // Grow increases the length of s.P to lsiz. | ||||
| func (s *LSym) Grow(lsiz int64) { | ||||
| 	siz := int(lsiz) | ||||
| 	if int64(siz) != lsiz { | ||||
| 		log.Fatalf("LSym.Grow size %d too long", lsiz) | ||||
| 	} | ||||
| 	if len(s.P) >= siz { | ||||
| 		return | ||||
| 	} | ||||
| 	// TODO(dfc) append cap-len at once, rather than | ||||
| 	// one byte at a time. | ||||
| 	for cap(s.P) < siz { | ||||
| 		s.P = append(s.P[:cap(s.P)], 0) | ||||
| 	} | ||||
| 	s.P = s.P[:siz] | ||||
| } | ||||
|  | ||||
| // GrowCap increases the capacity of s.P to c. | ||||
| func (s *LSym) GrowCap(c int64) { | ||||
| 	if int64(cap(s.P)) >= c { | ||||
| 		return | ||||
| 	} | ||||
| 	if s.P == nil { | ||||
| 		s.P = make([]byte, 0, c) | ||||
| 		return | ||||
| 	} | ||||
| 	b := make([]byte, len(s.P), c) | ||||
| 	copy(b, s.P) | ||||
| 	s.P = b | ||||
| } | ||||
|  | ||||
| // prepwrite prepares to write data of size siz into s at offset off. | ||||
| func (s *LSym) prepwrite(ctxt *Link, off int64, siz int) { | ||||
| 	if off < 0 || siz < 0 || off >= 1<<30 { | ||||
| 		log.Fatalf("prepwrite: bad off=%d siz=%d", off, siz) | ||||
| 	} | ||||
| 	if s.Type == SBSS || s.Type == STLSBSS { | ||||
| 		ctxt.Diag("cannot supply data for BSS var") | ||||
| 	} | ||||
| 	l := off + int64(siz) | ||||
| 	s.Grow(l) | ||||
| 	if l > s.Size { | ||||
| 		s.Size = l | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // WriteFloat32 writes f into s at offset off. | ||||
| func (s *LSym) WriteFloat32(ctxt *Link, off int64, f float32) { | ||||
| 	s.prepwrite(ctxt, off, 4) | ||||
| 	ctxt.Arch.ByteOrder.PutUint32(s.P[off:], math.Float32bits(f)) | ||||
| } | ||||
|  | ||||
| // WriteFloat64 writes f into s at offset off. | ||||
| func (s *LSym) WriteFloat64(ctxt *Link, off int64, f float64) { | ||||
| 	s.prepwrite(ctxt, off, 8) | ||||
| 	ctxt.Arch.ByteOrder.PutUint64(s.P[off:], math.Float64bits(f)) | ||||
| } | ||||
|  | ||||
| // WriteInt writes an integer i of size siz into s at offset off. | ||||
| func (s *LSym) WriteInt(ctxt *Link, off int64, siz int, i int64) { | ||||
| 	s.prepwrite(ctxt, off, siz) | ||||
| 	switch siz { | ||||
| 	default: | ||||
| 		ctxt.Diag("WriteInt: bad integer size: %d", siz) | ||||
| 	case 1: | ||||
| 		s.P[off] = byte(i) | ||||
| 	case 2: | ||||
| 		ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(i)) | ||||
| 	case 4: | ||||
| 		ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(i)) | ||||
| 	case 8: | ||||
| 		ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(i)) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // WriteAddr writes an address of size siz into s at offset off. | ||||
| // rsym and roff specify the relocation for the address. | ||||
| func (s *LSym) WriteAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) { | ||||
| 	if siz != ctxt.Arch.PtrSize { | ||||
| 		ctxt.Diag("WriteAddr: bad address size %d in %s", siz, s.Name) | ||||
| 	} | ||||
| 	s.prepwrite(ctxt, off, siz) | ||||
| 	r := Addrel(s) | ||||
| 	r.Off = int32(off) | ||||
| 	if int64(r.Off) != off { | ||||
| 		ctxt.Diag("WriteAddr: off overflow %d in %s", off, s.Name) | ||||
| 	} | ||||
| 	r.Siz = uint8(siz) | ||||
| 	r.Sym = rsym | ||||
| 	r.Type = R_ADDR | ||||
| 	r.Add = roff | ||||
| } | ||||
|  | ||||
| // WriteOff writes a 4 byte offset to rsym+roff into s at offset off. | ||||
| // After linking the 4 bytes stored at s+off will be | ||||
| // rsym+roff-(start of section that s is in). | ||||
| func (s *LSym) WriteOff(ctxt *Link, off int64, rsym *LSym, roff int64) { | ||||
| 	s.prepwrite(ctxt, off, 4) | ||||
| 	r := Addrel(s) | ||||
| 	r.Off = int32(off) | ||||
| 	if int64(r.Off) != off { | ||||
| 		ctxt.Diag("WriteOff: off overflow %d in %s", off, s.Name) | ||||
| 	} | ||||
| 	r.Siz = 4 | ||||
| 	r.Sym = rsym | ||||
| 	r.Type = R_ADDROFF | ||||
| 	r.Add = roff | ||||
| } | ||||
|  | ||||
| // WriteString writes a string of size siz into s at offset off. | ||||
| func (s *LSym) WriteString(ctxt *Link, off int64, siz int, str string) { | ||||
| 	if siz < len(str) { | ||||
| 		ctxt.Diag("WriteString: bad string size: %d < %d", siz, len(str)) | ||||
| 	} | ||||
| 	s.prepwrite(ctxt, off, siz) | ||||
| 	copy(s.P[off:off+int64(siz)], str) | ||||
| } | ||||
|  | ||||
| // WriteBytes writes a slice of bytes into s at offset off. | ||||
| func (s *LSym) WriteBytes(ctxt *Link, off int64, b []byte) int64 { | ||||
| 	s.prepwrite(ctxt, off, len(b)) | ||||
| 	copy(s.P[off:], b) | ||||
| 	return off + int64(len(b)) | ||||
| } | ||||
|  | ||||
| func Addrel(s *LSym) *Reloc { | ||||
| 	s.R = append(s.R, Reloc{}) | ||||
| 	return &s.R[len(s.R)-1] | ||||
| } | ||||
|  | ||||
| func Setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 { | ||||
| 	if s.Type == 0 { | ||||
| 		s.Type = SDATA | ||||
| 	} | ||||
| 	if s.Size < off+wid { | ||||
| 		s.Size = off + wid | ||||
| 		s.Grow(s.Size) | ||||
| 	} | ||||
|  | ||||
| 	switch wid { | ||||
| 	case 1: | ||||
| 		s.P[off] = uint8(v) | ||||
| 	case 2: | ||||
| 		ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(v)) | ||||
| 	case 4: | ||||
| 		ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(v)) | ||||
| 	case 8: | ||||
| 		ctxt.Arch.ByteOrder.PutUint64(s.P[off:], v) | ||||
| 	} | ||||
|  | ||||
| 	return off + wid | ||||
| } | ||||
							
								
								
									
										115
									
								
								vendor/github.com/google/gops/internal/obj/flag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								vendor/github.com/google/gops/internal/obj/flag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| // Copyright 2015 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| import ( | ||||
| 	"flag" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"strconv" | ||||
| ) | ||||
|  | ||||
| func Flagfn2(string, string, func(string, string)) { panic("flag") } | ||||
|  | ||||
| func Flagcount(name, usage string, val *int) { | ||||
| 	flag.Var((*count)(val), name, usage) | ||||
| } | ||||
|  | ||||
| func Flagint32(name, usage string, val *int32) { | ||||
| 	flag.Var((*int32Value)(val), name, usage) | ||||
| } | ||||
|  | ||||
| func Flagint64(name, usage string, val *int64) { | ||||
| 	flag.Int64Var(val, name, *val, usage) | ||||
| } | ||||
|  | ||||
| func Flagstr(name, usage string, val *string) { | ||||
| 	flag.StringVar(val, name, *val, usage) | ||||
| } | ||||
|  | ||||
| func Flagfn0(name, usage string, f func()) { | ||||
| 	flag.Var(fn0(f), name, usage) | ||||
| } | ||||
|  | ||||
| func Flagfn1(name, usage string, f func(string)) { | ||||
| 	flag.Var(fn1(f), name, usage) | ||||
| } | ||||
|  | ||||
| func Flagprint(fd int) { | ||||
| 	if fd == 1 { | ||||
| 		flag.CommandLine.SetOutput(os.Stdout) | ||||
| 	} | ||||
| 	flag.PrintDefaults() | ||||
| } | ||||
|  | ||||
| func Flagparse(usage func()) { | ||||
| 	flag.Usage = usage | ||||
| 	flag.Parse() | ||||
| } | ||||
|  | ||||
| // count is a flag.Value that is like a flag.Bool and a flag.Int. | ||||
| // If used as -name, it increments the count, but -name=x sets the count. | ||||
| // Used for verbose flag -v. | ||||
| type count int | ||||
|  | ||||
| func (c *count) String() string { | ||||
| 	return fmt.Sprint(int(*c)) | ||||
| } | ||||
|  | ||||
| func (c *count) Set(s string) error { | ||||
| 	switch s { | ||||
| 	case "true": | ||||
| 		*c++ | ||||
| 	case "false": | ||||
| 		*c = 0 | ||||
| 	default: | ||||
| 		n, err := strconv.Atoi(s) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("invalid count %q", s) | ||||
| 		} | ||||
| 		*c = count(n) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (c *count) IsBoolFlag() bool { | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| type int32Value int32 | ||||
|  | ||||
| func (i *int32Value) Set(s string) error { | ||||
| 	v, err := strconv.ParseInt(s, 0, 64) | ||||
| 	*i = int32Value(v) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func (i *int32Value) Get() interface{} { return int32(*i) } | ||||
|  | ||||
| func (i *int32Value) String() string { return fmt.Sprint(*i) } | ||||
|  | ||||
| type fn0 func() | ||||
|  | ||||
| func (f fn0) Set(s string) error { | ||||
| 	f() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (f fn0) Get() interface{} { return nil } | ||||
|  | ||||
| func (f fn0) String() string { return "" } | ||||
|  | ||||
| func (f fn0) IsBoolFlag() bool { | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| type fn1 func(string) | ||||
|  | ||||
| func (f fn1) Set(s string) error { | ||||
| 	f(s) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (f fn1) String() string { return "" } | ||||
							
								
								
									
										48
									
								
								vendor/github.com/google/gops/internal/obj/funcdata.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vendor/github.com/google/gops/internal/obj/funcdata.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| // Copyright 2013 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| // This file defines the IDs for PCDATA and FUNCDATA instructions | ||||
| // in Go binaries. It is included by assembly sources, so it must | ||||
| // be written using #defines. | ||||
| // | ||||
| // The Go compiler also #includes this file, for now. | ||||
| // | ||||
| // symtab.go also contains a copy of these constants. | ||||
|  | ||||
| // Pseudo-assembly statements. | ||||
|  | ||||
| // GO_ARGS, GO_RESULTS_INITIALIZED, and NO_LOCAL_POINTERS are macros | ||||
| // that communicate to the runtime information about the location and liveness | ||||
| // of pointers in an assembly function's arguments, results, and stack frame. | ||||
| // This communication is only required in assembly functions that make calls | ||||
| // to other functions that might be preempted or grow the stack. | ||||
| // NOSPLIT functions that make no calls do not need to use these macros. | ||||
|  | ||||
| // GO_ARGS indicates that the Go prototype for this assembly function | ||||
| // defines the pointer map for the function's arguments. | ||||
| // GO_ARGS should be the first instruction in a function that uses it. | ||||
| // It can be omitted if there are no arguments at all. | ||||
| // GO_ARGS is inserted implicitly by the linker for any function | ||||
| // that also has a Go prototype and therefore is usually not necessary | ||||
| // to write explicitly. | ||||
|  | ||||
| // GO_RESULTS_INITIALIZED indicates that the assembly function | ||||
| // has initialized the stack space for its results and that those results | ||||
| // should be considered live for the remainder of the function. | ||||
|  | ||||
| // NO_LOCAL_POINTERS indicates that the assembly function stores | ||||
| // no pointers to heap objects in its local stack variables. | ||||
|  | ||||
| // ArgsSizeUnknown is set in Func.argsize to mark all functions | ||||
| // whose argument size is unknown (C vararg functions, and | ||||
| // assembly code without an explicit specification). | ||||
| // This value is generated by the compiler, assembler, or linker. | ||||
| const ( | ||||
| 	PCDATA_StackMapIndex       = 0 | ||||
| 	FUNCDATA_ArgsPointerMaps   = 0 | ||||
| 	FUNCDATA_LocalsPointerMaps = 1 | ||||
| 	ArgsSizeUnknown            = -0x80000000 | ||||
| ) | ||||
							
								
								
									
										86
									
								
								vendor/github.com/google/gops/internal/obj/go.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								vendor/github.com/google/gops/internal/obj/go.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| // Copyright 2009 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // go-specific code shared across loaders (5l, 6l, 8l). | ||||
|  | ||||
| var ( | ||||
| 	framepointer_enabled int | ||||
| 	Fieldtrack_enabled   int | ||||
| ) | ||||
|  | ||||
| // Toolchain experiments. | ||||
| // These are controlled by the GOEXPERIMENT environment | ||||
| // variable recorded when the toolchain is built. | ||||
| // This list is also known to cmd/gc. | ||||
| var exper = []struct { | ||||
| 	name string | ||||
| 	val  *int | ||||
| }{ | ||||
| 	{"fieldtrack", &Fieldtrack_enabled}, | ||||
| 	{"framepointer", &framepointer_enabled}, | ||||
| } | ||||
|  | ||||
| func addexp(s string) { | ||||
| 	// Could do general integer parsing here, but the runtime copy doesn't yet. | ||||
| 	v := 1 | ||||
| 	name := s | ||||
| 	if len(name) > 2 && name[:2] == "no" { | ||||
| 		v = 0 | ||||
| 		name = name[2:] | ||||
| 	} | ||||
| 	for i := 0; i < len(exper); i++ { | ||||
| 		if exper[i].name == name { | ||||
| 			if exper[i].val != nil { | ||||
| 				*exper[i].val = v | ||||
| 			} | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	fmt.Printf("unknown experiment %s\n", s) | ||||
| 	os.Exit(2) | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	framepointer_enabled = 1 // default | ||||
| 	for _, f := range strings.Split(goexperiment, ",") { | ||||
| 		if f != "" { | ||||
| 			addexp(f) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Framepointer_enabled(goos, goarch string) bool { | ||||
| 	return framepointer_enabled != 0 && goarch == "amd64" && goos != "nacl" | ||||
| } | ||||
|  | ||||
| func Nopout(p *Prog) { | ||||
| 	p.As = ANOP | ||||
| 	p.Scond = 0 | ||||
| 	p.From = Addr{} | ||||
| 	p.From3 = nil | ||||
| 	p.Reg = 0 | ||||
| 	p.To = Addr{} | ||||
| } | ||||
|  | ||||
| func Expstring() string { | ||||
| 	buf := "X" | ||||
| 	for i := range exper { | ||||
| 		if *exper[i].val != 0 { | ||||
| 			buf += "," + exper[i].name | ||||
| 		} | ||||
| 	} | ||||
| 	if buf == "X" { | ||||
| 		buf += ",none" | ||||
| 	} | ||||
| 	return "X:" + buf[2:] | ||||
| } | ||||
							
								
								
									
										92
									
								
								vendor/github.com/google/gops/internal/obj/ld.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								vendor/github.com/google/gops/internal/obj/ld.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| // Derived from Inferno utils/6l/obj.c and utils/6l/span.c | ||||
| // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c | ||||
| // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c | ||||
| // | ||||
| //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | ||||
| //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| //	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others | ||||
| //	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| /* | ||||
|  * add library to library list. | ||||
|  *	srcref: src file referring to package | ||||
|  *	objref: object file referring to package | ||||
|  *	file: object file, e.g., /home/rsc/go/pkg/container/vector.a | ||||
|  *	pkg: package import path, e.g. container/vector | ||||
|  */ | ||||
|  | ||||
| const ( | ||||
| 	LOG = 5 | ||||
| ) | ||||
|  | ||||
| func mkfwd(sym *LSym) { | ||||
| 	var dwn [LOG]int32 | ||||
| 	var cnt [LOG]int32 | ||||
| 	var lst [LOG]*Prog | ||||
|  | ||||
| 	for i := 0; i < LOG; i++ { | ||||
| 		if i == 0 { | ||||
| 			cnt[i] = 1 | ||||
| 		} else { | ||||
| 			cnt[i] = LOG * cnt[i-1] | ||||
| 		} | ||||
| 		dwn[i] = 1 | ||||
| 		lst[i] = nil | ||||
| 	} | ||||
|  | ||||
| 	i := 0 | ||||
| 	for p := sym.Text; p != nil && p.Link != nil; p = p.Link { | ||||
| 		i-- | ||||
| 		if i < 0 { | ||||
| 			i = LOG - 1 | ||||
| 		} | ||||
| 		p.Forwd = nil | ||||
| 		dwn[i]-- | ||||
| 		if dwn[i] <= 0 { | ||||
| 			dwn[i] = cnt[i] | ||||
| 			if lst[i] != nil { | ||||
| 				lst[i].Forwd = p | ||||
| 			} | ||||
| 			lst[i] = p | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Copyp(ctxt *Link, q *Prog) *Prog { | ||||
| 	p := ctxt.NewProg() | ||||
| 	*p = *q | ||||
| 	return p | ||||
| } | ||||
|  | ||||
| func Appendp(ctxt *Link, q *Prog) *Prog { | ||||
| 	p := ctxt.NewProg() | ||||
| 	p.Link = q.Link | ||||
| 	q.Link = p | ||||
| 	p.Lineno = q.Lineno | ||||
| 	p.Mode = q.Mode | ||||
| 	return p | ||||
| } | ||||
							
								
								
									
										974
									
								
								vendor/github.com/google/gops/internal/obj/link.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										974
									
								
								vendor/github.com/google/gops/internal/obj/link.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,974 @@ | ||||
| // Derived from Inferno utils/6l/l.h and related files. | ||||
| // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h | ||||
| // | ||||
| //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | ||||
| //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| //	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others | ||||
| //	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/google/gops/internal/sys" | ||||
| ) | ||||
|  | ||||
| // An Addr is an argument to an instruction. | ||||
| // The general forms and their encodings are: | ||||
| // | ||||
| //	sym±offset(symkind)(reg)(index*scale) | ||||
| //		Memory reference at address &sym(symkind) + offset + reg + index*scale. | ||||
| //		Any of sym(symkind), ±offset, (reg), (index*scale), and *scale can be omitted. | ||||
| //		If (reg) and *scale are both omitted, the resulting expression (index) is parsed as (reg). | ||||
| //		To force a parsing as index*scale, write (index*1). | ||||
| //		Encoding: | ||||
| //			type = TYPE_MEM | ||||
| //			name = symkind (NAME_AUTO, ...) or 0 (NAME_NONE) | ||||
| //			sym = sym | ||||
| //			offset = ±offset | ||||
| //			reg = reg (REG_*) | ||||
| //			index = index (REG_*) | ||||
| //			scale = scale (1, 2, 4, 8) | ||||
| // | ||||
| //	$<mem> | ||||
| //		Effective address of memory reference <mem>, defined above. | ||||
| //		Encoding: same as memory reference, but type = TYPE_ADDR. | ||||
| // | ||||
| //	$<±integer value> | ||||
| //		This is a special case of $<mem>, in which only ±offset is present. | ||||
| //		It has a separate type for easy recognition. | ||||
| //		Encoding: | ||||
| //			type = TYPE_CONST | ||||
| //			offset = ±integer value | ||||
| // | ||||
| //	*<mem> | ||||
| //		Indirect reference through memory reference <mem>, defined above. | ||||
| //		Only used on x86 for CALL/JMP *sym(SB), which calls/jumps to a function | ||||
| //		pointer stored in the data word sym(SB), not a function named sym(SB). | ||||
| //		Encoding: same as above, but type = TYPE_INDIR. | ||||
| // | ||||
| //	$*$<mem> | ||||
| //		No longer used. | ||||
| //		On machines with actual SB registers, $*$<mem> forced the | ||||
| //		instruction encoding to use a full 32-bit constant, never a | ||||
| //		reference relative to SB. | ||||
| // | ||||
| //	$<floating point literal> | ||||
| //		Floating point constant value. | ||||
| //		Encoding: | ||||
| //			type = TYPE_FCONST | ||||
| //			val = floating point value | ||||
| // | ||||
| //	$<string literal, up to 8 chars> | ||||
| //		String literal value (raw bytes used for DATA instruction). | ||||
| //		Encoding: | ||||
| //			type = TYPE_SCONST | ||||
| //			val = string | ||||
| // | ||||
| //	<register name> | ||||
| //		Any register: integer, floating point, control, segment, and so on. | ||||
| //		If looking for specific register kind, must check type and reg value range. | ||||
| //		Encoding: | ||||
| //			type = TYPE_REG | ||||
| //			reg = reg (REG_*) | ||||
| // | ||||
| //	x(PC) | ||||
| //		Encoding: | ||||
| //			type = TYPE_BRANCH | ||||
| //			val = Prog* reference OR ELSE offset = target pc (branch takes priority) | ||||
| // | ||||
| //	$±x-±y | ||||
| //		Final argument to TEXT, specifying local frame size x and argument size y. | ||||
| //		In this form, x and y are integer literals only, not arbitrary expressions. | ||||
| //		This avoids parsing ambiguities due to the use of - as a separator. | ||||
| //		The ± are optional. | ||||
| //		If the final argument to TEXT omits the -±y, the encoding should still | ||||
| //		use TYPE_TEXTSIZE (not TYPE_CONST), with u.argsize = ArgsSizeUnknown. | ||||
| //		Encoding: | ||||
| //			type = TYPE_TEXTSIZE | ||||
| //			offset = x | ||||
| //			val = int32(y) | ||||
| // | ||||
| //	reg<<shift, reg>>shift, reg->shift, reg@>shift | ||||
| //		Shifted register value, for ARM and ARM64. | ||||
| //		In this form, reg must be a register and shift can be a register or an integer constant. | ||||
| //		Encoding: | ||||
| //			type = TYPE_SHIFT | ||||
| //		On ARM: | ||||
| //			offset = (reg&15) | shifttype<<5 | count | ||||
| //			shifttype = 0, 1, 2, 3 for <<, >>, ->, @> | ||||
| //			count = (reg&15)<<8 | 1<<4 for a register shift count, (n&31)<<7 for an integer constant. | ||||
| //		On ARM64: | ||||
| //			offset = (reg&31)<<16 | shifttype<<22 | (count&63)<<10 | ||||
| //			shifttype = 0, 1, 2 for <<, >>, -> | ||||
| // | ||||
| //	(reg, reg) | ||||
| //		A destination register pair. When used as the last argument of an instruction, | ||||
| //		this form makes clear that both registers are destinations. | ||||
| //		Encoding: | ||||
| //			type = TYPE_REGREG | ||||
| //			reg = first register | ||||
| //			offset = second register | ||||
| // | ||||
| //	[reg, reg, reg-reg] | ||||
| //		Register list for ARM. | ||||
| //		Encoding: | ||||
| //			type = TYPE_REGLIST | ||||
| //			offset = bit mask of registers in list; R0 is low bit. | ||||
| // | ||||
| //	reg, reg | ||||
| //		Register pair for ARM. | ||||
| //		TYPE_REGREG2 | ||||
| // | ||||
| //	(reg+reg) | ||||
| //		Register pair for PPC64. | ||||
| //		Encoding: | ||||
| //			type = TYPE_MEM | ||||
| //			reg = first register | ||||
| //			index = second register | ||||
| //			scale = 1 | ||||
| // | ||||
| type Addr struct { | ||||
| 	Reg    int16 | ||||
| 	Index  int16 | ||||
| 	Scale  int16 // Sometimes holds a register. | ||||
| 	Type   AddrType | ||||
| 	Name   int8 | ||||
| 	Class  int8 | ||||
| 	Offset int64 | ||||
| 	Sym    *LSym | ||||
|  | ||||
| 	// argument value: | ||||
| 	//	for TYPE_SCONST, a string | ||||
| 	//	for TYPE_FCONST, a float64 | ||||
| 	//	for TYPE_BRANCH, a *Prog (optional) | ||||
| 	//	for TYPE_TEXTSIZE, an int32 (optional) | ||||
| 	Val interface{} | ||||
|  | ||||
| 	Node interface{} // for use by compiler | ||||
| } | ||||
|  | ||||
| type AddrType uint8 | ||||
|  | ||||
| const ( | ||||
| 	NAME_NONE = 0 + iota | ||||
| 	NAME_EXTERN | ||||
| 	NAME_STATIC | ||||
| 	NAME_AUTO | ||||
| 	NAME_PARAM | ||||
| 	// A reference to name@GOT(SB) is a reference to the entry in the global offset | ||||
| 	// table for 'name'. | ||||
| 	NAME_GOTREF | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	TYPE_NONE AddrType = 0 | ||||
|  | ||||
| 	TYPE_BRANCH AddrType = 5 + iota | ||||
| 	TYPE_TEXTSIZE | ||||
| 	TYPE_MEM | ||||
| 	TYPE_CONST | ||||
| 	TYPE_FCONST | ||||
| 	TYPE_SCONST | ||||
| 	TYPE_REG | ||||
| 	TYPE_ADDR | ||||
| 	TYPE_SHIFT | ||||
| 	TYPE_REGREG | ||||
| 	TYPE_REGREG2 | ||||
| 	TYPE_INDIR | ||||
| 	TYPE_REGLIST | ||||
| ) | ||||
|  | ||||
| // Prog describes a single machine instruction. | ||||
| // | ||||
| // The general instruction form is: | ||||
| // | ||||
| //	As.Scond From, Reg, From3, To, RegTo2 | ||||
| // | ||||
| // where As is an opcode and the others are arguments: | ||||
| // From, Reg, From3 are sources, and To, RegTo2 are destinations. | ||||
| // Usually, not all arguments are present. | ||||
| // For example, MOVL R1, R2 encodes using only As=MOVL, From=R1, To=R2. | ||||
| // The Scond field holds additional condition bits for systems (like arm) | ||||
| // that have generalized conditional execution. | ||||
| // | ||||
| // Jump instructions use the Pcond field to point to the target instruction, | ||||
| // which must be in the same linked list as the jump instruction. | ||||
| // | ||||
| // The Progs for a given function are arranged in a list linked through the Link field. | ||||
| // | ||||
| // Each Prog is charged to a specific source line in the debug information, | ||||
| // specified by Lineno, an index into the line history (see LineHist). | ||||
| // Every Prog has a Ctxt field that defines various context, including the current LineHist. | ||||
| // Progs should be allocated using ctxt.NewProg(), not new(Prog). | ||||
| // | ||||
| // The other fields not yet mentioned are for use by the back ends and should | ||||
| // be left zeroed by creators of Prog lists. | ||||
| type Prog struct { | ||||
| 	Ctxt   *Link       // linker context | ||||
| 	Link   *Prog       // next Prog in linked list | ||||
| 	From   Addr        // first source operand | ||||
| 	From3  *Addr       // third source operand (second is Reg below) | ||||
| 	To     Addr        // destination operand (second is RegTo2 below) | ||||
| 	Pcond  *Prog       // target of conditional jump | ||||
| 	Opt    interface{} // available to optimization passes to hold per-Prog state | ||||
| 	Forwd  *Prog       // for x86 back end | ||||
| 	Rel    *Prog       // for x86, arm back ends | ||||
| 	Pc     int64       // for back ends or assembler: virtual or actual program counter, depending on phase | ||||
| 	Lineno int32       // line number of this instruction | ||||
| 	Spadj  int32       // effect of instruction on stack pointer (increment or decrement amount) | ||||
| 	As     As          // assembler opcode | ||||
| 	Reg    int16       // 2nd source operand | ||||
| 	RegTo2 int16       // 2nd destination operand | ||||
| 	Mark   uint16      // bitmask of arch-specific items | ||||
| 	Optab  uint16      // arch-specific opcode index | ||||
| 	Scond  uint8       // condition bits for conditional instruction (e.g., on ARM) | ||||
| 	Back   uint8       // for x86 back end: backwards branch state | ||||
| 	Ft     uint8       // for x86 back end: type index of Prog.From | ||||
| 	Tt     uint8       // for x86 back end: type index of Prog.To | ||||
| 	Isize  uint8       // for x86 back end: size of the instruction in bytes | ||||
| 	Mode   int8        // for x86 back end: 32- or 64-bit mode | ||||
| } | ||||
|  | ||||
| // From3Type returns From3.Type, or TYPE_NONE when From3 is nil. | ||||
| func (p *Prog) From3Type() AddrType { | ||||
| 	if p.From3 == nil { | ||||
| 		return TYPE_NONE | ||||
| 	} | ||||
| 	return p.From3.Type | ||||
| } | ||||
|  | ||||
| // From3Offset returns From3.Offset, or 0 when From3 is nil. | ||||
| func (p *Prog) From3Offset() int64 { | ||||
| 	if p.From3 == nil { | ||||
| 		return 0 | ||||
| 	} | ||||
| 	return p.From3.Offset | ||||
| } | ||||
|  | ||||
| // An As denotes an assembler opcode. | ||||
| // There are some portable opcodes, declared here in package obj, | ||||
| // that are common to all architectures. | ||||
| // However, the majority of opcodes are arch-specific | ||||
| // and are declared in their respective architecture's subpackage. | ||||
| type As int16 | ||||
|  | ||||
| // These are the portable opcodes. | ||||
| const ( | ||||
| 	AXXX As = iota | ||||
| 	ACALL | ||||
| 	ADUFFCOPY | ||||
| 	ADUFFZERO | ||||
| 	AEND | ||||
| 	AFUNCDATA | ||||
| 	AJMP | ||||
| 	ANOP | ||||
| 	APCDATA | ||||
| 	ARET | ||||
| 	ATEXT | ||||
| 	ATYPE | ||||
| 	AUNDEF | ||||
| 	AUSEFIELD | ||||
| 	AVARDEF | ||||
| 	AVARKILL | ||||
| 	AVARLIVE | ||||
| 	A_ARCHSPECIFIC | ||||
| ) | ||||
|  | ||||
| // Each architecture is allotted a distinct subspace of opcode values | ||||
| // for declaring its arch-specific opcodes. | ||||
| // Within this subspace, the first arch-specific opcode should be | ||||
| // at offset A_ARCHSPECIFIC. | ||||
| // | ||||
| // Subspaces are aligned to a power of two so opcodes can be masked | ||||
| // with AMask and used as compact array indices. | ||||
| const ( | ||||
| 	ABase386 = (1 + iota) << 10 | ||||
| 	ABaseARM | ||||
| 	ABaseAMD64 | ||||
| 	ABasePPC64 | ||||
| 	ABaseARM64 | ||||
| 	ABaseMIPS64 | ||||
| 	ABaseS390X | ||||
|  | ||||
| 	AllowedOpCodes = 1 << 10            // The number of opcodes available for any given architecture. | ||||
| 	AMask          = AllowedOpCodes - 1 // AND with this to use the opcode as an array index. | ||||
| ) | ||||
|  | ||||
| // An LSym is the sort of symbol that is written to an object file. | ||||
| type LSym struct { | ||||
| 	Name    string | ||||
| 	Type    SymKind | ||||
| 	Version int16 | ||||
| 	Attribute | ||||
|  | ||||
| 	RefIdx int // Index of this symbol in the symbol reference list. | ||||
| 	Args   int32 | ||||
| 	Locals int32 | ||||
| 	Size   int64 | ||||
| 	Gotype *LSym | ||||
| 	Autom  *Auto | ||||
| 	Text   *Prog | ||||
| 	Pcln   *Pcln | ||||
| 	P      []byte | ||||
| 	R      []Reloc | ||||
| } | ||||
|  | ||||
| // Attribute is a set of symbol attributes. | ||||
| type Attribute int16 | ||||
|  | ||||
| const ( | ||||
| 	AttrDuplicateOK Attribute = 1 << iota | ||||
| 	AttrCFunc | ||||
| 	AttrNoSplit | ||||
| 	AttrLeaf | ||||
| 	AttrSeenGlobl | ||||
| 	AttrOnList | ||||
|  | ||||
| 	// MakeTypelink means that the type should have an entry in the typelink table. | ||||
| 	AttrMakeTypelink | ||||
|  | ||||
| 	// ReflectMethod means the function may call reflect.Type.Method or | ||||
| 	// reflect.Type.MethodByName. Matching is imprecise (as reflect.Type | ||||
| 	// can be used through a custom interface), so ReflectMethod may be | ||||
| 	// set in some cases when the reflect package is not called. | ||||
| 	// | ||||
| 	// Used by the linker to determine what methods can be pruned. | ||||
| 	AttrReflectMethod | ||||
|  | ||||
| 	// Local means make the symbol local even when compiling Go code to reference Go | ||||
| 	// symbols in other shared libraries, as in this mode symbols are global by | ||||
| 	// default. "local" here means in the sense of the dynamic linker, i.e. not | ||||
| 	// visible outside of the module (shared library or executable) that contains its | ||||
| 	// definition. (When not compiling to support Go shared libraries, all symbols are | ||||
| 	// local in this sense unless there is a cgo_export_* directive). | ||||
| 	AttrLocal | ||||
| ) | ||||
|  | ||||
| func (a Attribute) DuplicateOK() bool   { return a&AttrDuplicateOK != 0 } | ||||
| func (a Attribute) MakeTypelink() bool  { return a&AttrMakeTypelink != 0 } | ||||
| func (a Attribute) CFunc() bool         { return a&AttrCFunc != 0 } | ||||
| func (a Attribute) NoSplit() bool       { return a&AttrNoSplit != 0 } | ||||
| func (a Attribute) Leaf() bool          { return a&AttrLeaf != 0 } | ||||
| func (a Attribute) SeenGlobl() bool     { return a&AttrSeenGlobl != 0 } | ||||
| func (a Attribute) OnList() bool        { return a&AttrOnList != 0 } | ||||
| func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 } | ||||
| func (a Attribute) Local() bool         { return a&AttrLocal != 0 } | ||||
|  | ||||
| func (a *Attribute) Set(flag Attribute, value bool) { | ||||
| 	if value { | ||||
| 		*a |= flag | ||||
| 	} else { | ||||
| 		*a &^= flag | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // The compiler needs LSym to satisfy fmt.Stringer, because it stores | ||||
| // an LSym in ssa.ExternSymbol. | ||||
| func (s *LSym) String() string { | ||||
| 	return s.Name | ||||
| } | ||||
|  | ||||
| type Pcln struct { | ||||
| 	Pcsp        Pcdata | ||||
| 	Pcfile      Pcdata | ||||
| 	Pcline      Pcdata | ||||
| 	Pcdata      []Pcdata | ||||
| 	Funcdata    []*LSym | ||||
| 	Funcdataoff []int64 | ||||
| 	File        []*LSym | ||||
| 	Lastfile    *LSym | ||||
| 	Lastindex   int | ||||
| } | ||||
|  | ||||
| // A SymKind describes the kind of memory represented by a symbol. | ||||
| type SymKind int16 | ||||
|  | ||||
| // Defined SymKind values. | ||||
| // | ||||
| // TODO(rsc): Give idiomatic Go names. | ||||
| // TODO(rsc): Reduce the number of symbol types in the object files. | ||||
| //go:generate stringer -type=SymKind | ||||
| const ( | ||||
| 	Sxxx SymKind = iota | ||||
| 	STEXT | ||||
| 	SELFRXSECT | ||||
|  | ||||
| 	// Read-only sections. | ||||
| 	STYPE | ||||
| 	SSTRING | ||||
| 	SGOSTRING | ||||
| 	SGOFUNC | ||||
| 	SGCBITS | ||||
| 	SRODATA | ||||
| 	SFUNCTAB | ||||
|  | ||||
| 	SELFROSECT | ||||
| 	SMACHOPLT | ||||
|  | ||||
| 	// Read-only sections with relocations. | ||||
| 	// | ||||
| 	// Types STYPE-SFUNCTAB above are written to the .rodata section by default. | ||||
| 	// When linking a shared object, some conceptually "read only" types need to | ||||
| 	// be written to by relocations and putting them in a section called | ||||
| 	// ".rodata" interacts poorly with the system linkers. The GNU linkers | ||||
| 	// support this situation by arranging for sections of the name | ||||
| 	// ".data.rel.ro.XXX" to be mprotected read only by the dynamic linker after | ||||
| 	// relocations have applied, so when the Go linker is creating a shared | ||||
| 	// object it checks all objects of the above types and bumps any object that | ||||
| 	// has a relocation to it to the corresponding type below, which are then | ||||
| 	// written to sections with appropriate magic names. | ||||
| 	STYPERELRO | ||||
| 	SSTRINGRELRO | ||||
| 	SGOSTRINGRELRO | ||||
| 	SGOFUNCRELRO | ||||
| 	SGCBITSRELRO | ||||
| 	SRODATARELRO | ||||
| 	SFUNCTABRELRO | ||||
|  | ||||
| 	// Part of .data.rel.ro if it exists, otherwise part of .rodata. | ||||
| 	STYPELINK | ||||
| 	SITABLINK | ||||
| 	SSYMTAB | ||||
| 	SPCLNTAB | ||||
|  | ||||
| 	// Writable sections. | ||||
| 	SELFSECT | ||||
| 	SMACHO | ||||
| 	SMACHOGOT | ||||
| 	SWINDOWS | ||||
| 	SELFGOT | ||||
| 	SNOPTRDATA | ||||
| 	SINITARR | ||||
| 	SDATA | ||||
| 	SBSS | ||||
| 	SNOPTRBSS | ||||
| 	STLSBSS | ||||
| 	SXREF | ||||
| 	SMACHOSYMSTR | ||||
| 	SMACHOSYMTAB | ||||
| 	SMACHOINDIRECTPLT | ||||
| 	SMACHOINDIRECTGOT | ||||
| 	SFILE | ||||
| 	SFILEPATH | ||||
| 	SCONST | ||||
| 	SDYNIMPORT | ||||
| 	SHOSTOBJ | ||||
| 	SDWARFSECT | ||||
| 	SDWARFINFO | ||||
| 	SSUB       = SymKind(1 << 8) | ||||
| 	SMASK      = SymKind(SSUB - 1) | ||||
| 	SHIDDEN    = SymKind(1 << 9) | ||||
| 	SCONTAINER = SymKind(1 << 10) // has a sub-symbol | ||||
| ) | ||||
|  | ||||
| // ReadOnly are the symbol kinds that form read-only sections. In some | ||||
| // cases, if they will require relocations, they are transformed into | ||||
| // rel-ro sections using RelROMap. | ||||
| var ReadOnly = []SymKind{ | ||||
| 	STYPE, | ||||
| 	SSTRING, | ||||
| 	SGOSTRING, | ||||
| 	SGOFUNC, | ||||
| 	SGCBITS, | ||||
| 	SRODATA, | ||||
| 	SFUNCTAB, | ||||
| } | ||||
|  | ||||
| // RelROMap describes the transformation of read-only symbols to rel-ro | ||||
| // symbols. | ||||
| var RelROMap = map[SymKind]SymKind{ | ||||
| 	STYPE:     STYPERELRO, | ||||
| 	SSTRING:   SSTRINGRELRO, | ||||
| 	SGOSTRING: SGOSTRINGRELRO, | ||||
| 	SGOFUNC:   SGOFUNCRELRO, | ||||
| 	SGCBITS:   SGCBITSRELRO, | ||||
| 	SRODATA:   SRODATARELRO, | ||||
| 	SFUNCTAB:  SFUNCTABRELRO, | ||||
| } | ||||
|  | ||||
| type Reloc struct { | ||||
| 	Off  int32 | ||||
| 	Siz  uint8 | ||||
| 	Type RelocType | ||||
| 	Add  int64 | ||||
| 	Sym  *LSym | ||||
| } | ||||
|  | ||||
| type RelocType int32 | ||||
|  | ||||
| //go:generate stringer -type=RelocType | ||||
| const ( | ||||
| 	R_ADDR RelocType = 1 + iota | ||||
| 	// R_ADDRPOWER relocates a pair of "D-form" instructions (instructions with 16-bit | ||||
| 	// immediates in the low half of the instruction word), usually addis followed by | ||||
| 	// another add or a load, inserting the "high adjusted" 16 bits of the address of | ||||
| 	// the referenced symbol into the immediate field of the first instruction and the | ||||
| 	// low 16 bits into that of the second instruction. | ||||
| 	R_ADDRPOWER | ||||
| 	// R_ADDRARM64 relocates an adrp, add pair to compute the address of the | ||||
| 	// referenced symbol. | ||||
| 	R_ADDRARM64 | ||||
| 	// R_ADDRMIPS (only used on mips64) resolves to the low 16 bits of an external | ||||
| 	// address, by encoding it into the instruction. | ||||
| 	R_ADDRMIPS | ||||
| 	// R_ADDROFF resolves to a 32-bit offset from the beginning of the section | ||||
| 	// holding the data being relocated to the referenced symbol. | ||||
| 	R_ADDROFF | ||||
| 	R_SIZE | ||||
| 	R_CALL | ||||
| 	R_CALLARM | ||||
| 	R_CALLARM64 | ||||
| 	R_CALLIND | ||||
| 	R_CALLPOWER | ||||
| 	// R_CALLMIPS (only used on mips64) resolves to non-PC-relative target address | ||||
| 	// of a CALL (JAL) instruction, by encoding the address into the instruction. | ||||
| 	R_CALLMIPS | ||||
| 	R_CONST | ||||
| 	R_PCREL | ||||
| 	// R_TLS_LE, used on 386, amd64, and ARM, resolves to the offset of the | ||||
| 	// thread-local symbol from the thread local base and is used to implement the | ||||
| 	// "local exec" model for tls access (r.Sym is not set on intel platforms but is | ||||
| 	// set to a TLS symbol -- runtime.tlsg -- in the linker when externally linking). | ||||
| 	R_TLS_LE | ||||
| 	// R_TLS_IE, used 386, amd64, and ARM resolves to the PC-relative offset to a GOT | ||||
| 	// slot containing the offset from the thread-local symbol from the thread local | ||||
| 	// base and is used to implemented the "initial exec" model for tls access (r.Sym | ||||
| 	// is not set on intel platforms but is set to a TLS symbol -- runtime.tlsg -- in | ||||
| 	// the linker when externally linking). | ||||
| 	R_TLS_IE | ||||
| 	R_GOTOFF | ||||
| 	R_PLT0 | ||||
| 	R_PLT1 | ||||
| 	R_PLT2 | ||||
| 	R_USEFIELD | ||||
| 	// R_USETYPE resolves to an *rtype, but no relocation is created. The | ||||
| 	// linker uses this as a signal that the pointed-to type information | ||||
| 	// should be linked into the final binary, even if there are no other | ||||
| 	// direct references. (This is used for types reachable by reflection.) | ||||
| 	R_USETYPE | ||||
| 	// R_METHODOFF resolves to a 32-bit offset from the beginning of the section | ||||
| 	// holding the data being relocated to the referenced symbol. | ||||
| 	// It is a variant of R_ADDROFF used when linking from the uncommonType of a | ||||
| 	// *rtype, and may be set to zero by the linker if it determines the method | ||||
| 	// text is unreachable by the linked program. | ||||
| 	R_METHODOFF | ||||
| 	R_POWER_TOC | ||||
| 	R_GOTPCREL | ||||
| 	// R_JMPMIPS (only used on mips64) resolves to non-PC-relative target address | ||||
| 	// of a JMP instruction, by encoding the address into the instruction. | ||||
| 	// The stack nosplit check ignores this since it is not a function call. | ||||
| 	R_JMPMIPS | ||||
| 	// R_DWARFREF resolves to the offset of the symbol from its section. | ||||
| 	R_DWARFREF | ||||
|  | ||||
| 	// Platform dependent relocations. Architectures with fixed width instructions | ||||
| 	// have the inherent issue that a 32-bit (or 64-bit!) displacement cannot be | ||||
| 	// stuffed into a 32-bit instruction, so an address needs to be spread across | ||||
| 	// several instructions, and in turn this requires a sequence of relocations, each | ||||
| 	// updating a part of an instruction. This leads to relocation codes that are | ||||
| 	// inherently processor specific. | ||||
|  | ||||
| 	// Arm64. | ||||
|  | ||||
| 	// Set a MOV[NZ] immediate field to bits [15:0] of the offset from the thread | ||||
| 	// local base to the thread local variable defined by the referenced (thread | ||||
| 	// local) symbol. Error if the offset does not fit into 16 bits. | ||||
| 	R_ARM64_TLS_LE | ||||
|  | ||||
| 	// Relocates an ADRP; LD64 instruction sequence to load the offset between | ||||
| 	// the thread local base and the thread local variable defined by the | ||||
| 	// referenced (thread local) symbol from the GOT. | ||||
| 	R_ARM64_TLS_IE | ||||
|  | ||||
| 	// R_ARM64_GOTPCREL relocates an adrp, ld64 pair to compute the address of the GOT | ||||
| 	// slot of the referenced symbol. | ||||
| 	R_ARM64_GOTPCREL | ||||
|  | ||||
| 	// PPC64. | ||||
|  | ||||
| 	// R_POWER_TLS_LE is used to implement the "local exec" model for tls | ||||
| 	// access. It resolves to the offset of the thread-local symbol from the | ||||
| 	// thread pointer (R13) and inserts this value into the low 16 bits of an | ||||
| 	// instruction word. | ||||
| 	R_POWER_TLS_LE | ||||
|  | ||||
| 	// R_POWER_TLS_IE is used to implement the "initial exec" model for tls access. It | ||||
| 	// relocates a D-form, DS-form instruction sequence like R_ADDRPOWER_DS. It | ||||
| 	// inserts to the offset of GOT slot for the thread-local symbol from the TOC (the | ||||
| 	// GOT slot is filled by the dynamic linker with the offset of the thread-local | ||||
| 	// symbol from the thread pointer (R13)). | ||||
| 	R_POWER_TLS_IE | ||||
|  | ||||
| 	// R_POWER_TLS marks an X-form instruction such as "MOVD 0(R13)(R31*1), g" as | ||||
| 	// accessing a particular thread-local symbol. It does not affect code generation | ||||
| 	// but is used by the system linker when relaxing "initial exec" model code to | ||||
| 	// "local exec" model code. | ||||
| 	R_POWER_TLS | ||||
|  | ||||
| 	// R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second | ||||
| 	// instruction is a "DS-form" instruction, which has an immediate field occupying | ||||
| 	// bits [15:2] of the instruction word. Bits [15:2] of the address of the | ||||
| 	// relocated symbol are inserted into this field; it is an error if the last two | ||||
| 	// bits of the address are not 0. | ||||
| 	R_ADDRPOWER_DS | ||||
|  | ||||
| 	// R_ADDRPOWER_PCREL relocates a D-form, DS-form instruction sequence like | ||||
| 	// R_ADDRPOWER_DS but inserts the offset of the GOT slot for the referenced symbol | ||||
| 	// from the TOC rather than the symbol's address. | ||||
| 	R_ADDRPOWER_GOT | ||||
|  | ||||
| 	// R_ADDRPOWER_PCREL relocates two D-form instructions like R_ADDRPOWER, but | ||||
| 	// inserts the displacement from the place being relocated to the address of the | ||||
| 	// the relocated symbol instead of just its address. | ||||
| 	R_ADDRPOWER_PCREL | ||||
|  | ||||
| 	// R_ADDRPOWER_TOCREL relocates two D-form instructions like R_ADDRPOWER, but | ||||
| 	// inserts the offset from the TOC to the address of the the relocated symbol | ||||
| 	// rather than the symbol's address. | ||||
| 	R_ADDRPOWER_TOCREL | ||||
|  | ||||
| 	// R_ADDRPOWER_TOCREL relocates a D-form, DS-form instruction sequence like | ||||
| 	// R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the the | ||||
| 	// relocated symbol rather than the symbol's address. | ||||
| 	R_ADDRPOWER_TOCREL_DS | ||||
|  | ||||
| 	// R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses. | ||||
| 	// TODO(mundaym): remove once variants can be serialized - see issue 14218. | ||||
| 	R_PCRELDBL | ||||
|  | ||||
| 	// R_ADDRMIPSU (only used on mips64) resolves to the sign-adjusted "upper" 16 | ||||
| 	// bits (bit 16-31) of an external address, by encoding it into the instruction. | ||||
| 	R_ADDRMIPSU | ||||
| 	// R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS | ||||
| 	// address (offset from thread pointer), by encoding it into the instruction. | ||||
| 	R_ADDRMIPSTLS | ||||
| ) | ||||
|  | ||||
| // IsDirectJump returns whether r is a relocation for a direct jump. | ||||
| // A direct jump is a CALL or JMP instruction that takes the target address | ||||
| // as immediate. The address is embedded into the instruction, possibly | ||||
| // with limited width. | ||||
| // An indirect jump is a CALL or JMP instruction that takes the target address | ||||
| // in register or memory. | ||||
| func (r RelocType) IsDirectJump() bool { | ||||
| 	switch r { | ||||
| 	case R_CALL, R_CALLARM, R_CALLARM64, R_CALLPOWER, R_CALLMIPS, R_JMPMIPS: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| type Auto struct { | ||||
| 	Asym    *LSym | ||||
| 	Link    *Auto | ||||
| 	Aoffset int32 | ||||
| 	Name    int16 | ||||
| 	Gotype  *LSym | ||||
| } | ||||
|  | ||||
| // Auto.name | ||||
| const ( | ||||
| 	A_AUTO = 1 + iota | ||||
| 	A_PARAM | ||||
| ) | ||||
|  | ||||
| type Pcdata struct { | ||||
| 	P []byte | ||||
| } | ||||
|  | ||||
| // symbol version, incremented each time a file is loaded. | ||||
| // version==1 is reserved for savehist. | ||||
| const ( | ||||
| 	HistVersion = 1 | ||||
| ) | ||||
|  | ||||
| // Link holds the context for writing object code from a compiler | ||||
| // to be linker input or for reading that input into the linker. | ||||
| type Link struct { | ||||
| 	Headtype      HeadType | ||||
| 	Arch          *LinkArch | ||||
| 	Debugasm      int32 | ||||
| 	Debugvlog     int32 | ||||
| 	Debugdivmod   int32 | ||||
| 	Debugpcln     int32 | ||||
| 	Flag_shared   bool | ||||
| 	Flag_dynlink  bool | ||||
| 	Flag_optimize bool | ||||
| 	Bso           *bufio.Writer | ||||
| 	Pathname      string | ||||
| 	Hash          map[SymVer]*LSym | ||||
| 	LineHist      LineHist | ||||
| 	Imports       []string | ||||
| 	Plists        []*Plist | ||||
| 	Sym_div       *LSym | ||||
| 	Sym_divu      *LSym | ||||
| 	Sym_mod       *LSym | ||||
| 	Sym_modu      *LSym | ||||
| 	Plan9privates *LSym | ||||
| 	Curp          *Prog | ||||
| 	Printp        *Prog | ||||
| 	Blitrl        *Prog | ||||
| 	Elitrl        *Prog | ||||
| 	Rexflag       int | ||||
| 	Vexflag       int | ||||
| 	Rep           int | ||||
| 	Repn          int | ||||
| 	Lock          int | ||||
| 	Asmode        int | ||||
| 	AsmBuf        AsmBuf // instruction buffer for x86 | ||||
| 	Instoffset    int64 | ||||
| 	Autosize      int32 | ||||
| 	Armsize       int32 | ||||
| 	Pc            int64 | ||||
| 	DiagFunc      func(string, ...interface{}) | ||||
| 	Mode          int | ||||
| 	Cursym        *LSym | ||||
| 	Version       int | ||||
| 	Errors        int | ||||
|  | ||||
| 	Framepointer_enabled bool | ||||
|  | ||||
| 	// state for writing objects | ||||
| 	Text []*LSym | ||||
| 	Data []*LSym | ||||
|  | ||||
| 	// Cache of Progs | ||||
| 	allocIdx int | ||||
| 	progs    [10000]Prog | ||||
| } | ||||
|  | ||||
| func (ctxt *Link) Diag(format string, args ...interface{}) { | ||||
| 	ctxt.Errors++ | ||||
| 	ctxt.DiagFunc(format, args...) | ||||
| } | ||||
|  | ||||
| func (ctxt *Link) Logf(format string, args ...interface{}) { | ||||
| 	fmt.Fprintf(ctxt.Bso, format, args...) | ||||
| 	ctxt.Bso.Flush() | ||||
| } | ||||
|  | ||||
| // The smallest possible offset from the hardware stack pointer to a local | ||||
| // variable on the stack. Architectures that use a link register save its value | ||||
| // on the stack in the function prologue and so always have a pointer between | ||||
| // the hardware stack pointer and the local variable area. | ||||
| func (ctxt *Link) FixedFrameSize() int64 { | ||||
| 	switch ctxt.Arch.Family { | ||||
| 	case sys.AMD64, sys.I386: | ||||
| 		return 0 | ||||
| 	case sys.PPC64: | ||||
| 		// PIC code on ppc64le requires 32 bytes of stack, and it's easier to | ||||
| 		// just use that much stack always on ppc64x. | ||||
| 		return int64(4 * ctxt.Arch.PtrSize) | ||||
| 	default: | ||||
| 		return int64(ctxt.Arch.PtrSize) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type SymVer struct { | ||||
| 	Name    string | ||||
| 	Version int // TODO: make int16 to match LSym.Version? | ||||
| } | ||||
|  | ||||
| // LinkArch is the definition of a single architecture. | ||||
| type LinkArch struct { | ||||
| 	*sys.Arch | ||||
| 	Preprocess func(*Link, *LSym) | ||||
| 	Assemble   func(*Link, *LSym) | ||||
| 	Follow     func(*Link, *LSym) | ||||
| 	Progedit   func(*Link, *Prog) | ||||
| 	UnaryDst   map[As]bool // Instruction takes one operand, a destination. | ||||
| } | ||||
|  | ||||
| // HeadType is the executable header type. | ||||
| type HeadType uint8 | ||||
|  | ||||
| const ( | ||||
| 	Hunknown HeadType = iota | ||||
| 	Hdarwin | ||||
| 	Hdragonfly | ||||
| 	Hfreebsd | ||||
| 	Hlinux | ||||
| 	Hnacl | ||||
| 	Hnetbsd | ||||
| 	Hopenbsd | ||||
| 	Hplan9 | ||||
| 	Hsolaris | ||||
| 	Hwindows | ||||
| 	Hwindowsgui | ||||
| ) | ||||
|  | ||||
| func (h *HeadType) Set(s string) error { | ||||
| 	switch s { | ||||
| 	case "darwin": | ||||
| 		*h = Hdarwin | ||||
| 	case "dragonfly": | ||||
| 		*h = Hdragonfly | ||||
| 	case "freebsd": | ||||
| 		*h = Hfreebsd | ||||
| 	case "linux", "android": | ||||
| 		*h = Hlinux | ||||
| 	case "nacl": | ||||
| 		*h = Hnacl | ||||
| 	case "netbsd": | ||||
| 		*h = Hnetbsd | ||||
| 	case "openbsd": | ||||
| 		*h = Hopenbsd | ||||
| 	case "plan9": | ||||
| 		*h = Hplan9 | ||||
| 	case "solaris": | ||||
| 		*h = Hsolaris | ||||
| 	case "windows": | ||||
| 		*h = Hwindows | ||||
| 	case "windowsgui": | ||||
| 		*h = Hwindowsgui | ||||
| 	default: | ||||
| 		return fmt.Errorf("invalid headtype: %q", s) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (h *HeadType) String() string { | ||||
| 	switch *h { | ||||
| 	case Hdarwin: | ||||
| 		return "darwin" | ||||
| 	case Hdragonfly: | ||||
| 		return "dragonfly" | ||||
| 	case Hfreebsd: | ||||
| 		return "freebsd" | ||||
| 	case Hlinux: | ||||
| 		return "linux" | ||||
| 	case Hnacl: | ||||
| 		return "nacl" | ||||
| 	case Hnetbsd: | ||||
| 		return "netbsd" | ||||
| 	case Hopenbsd: | ||||
| 		return "openbsd" | ||||
| 	case Hplan9: | ||||
| 		return "plan9" | ||||
| 	case Hsolaris: | ||||
| 		return "solaris" | ||||
| 	case Hwindows: | ||||
| 		return "windows" | ||||
| 	case Hwindowsgui: | ||||
| 		return "windowsgui" | ||||
| 	} | ||||
| 	return fmt.Sprintf("HeadType(%d)", *h) | ||||
| } | ||||
|  | ||||
| // AsmBuf is a simple buffer to assemble variable-length x86 instructions into. | ||||
| type AsmBuf struct { | ||||
| 	buf [100]byte | ||||
| 	off int | ||||
| } | ||||
|  | ||||
| // Put1 appends one byte to the end of the buffer. | ||||
| func (a *AsmBuf) Put1(x byte) { | ||||
| 	a.buf[a.off] = x | ||||
| 	a.off++ | ||||
| } | ||||
|  | ||||
| // Put2 appends two bytes to the end of the buffer. | ||||
| func (a *AsmBuf) Put2(x, y byte) { | ||||
| 	a.buf[a.off+0] = x | ||||
| 	a.buf[a.off+1] = y | ||||
| 	a.off += 2 | ||||
| } | ||||
|  | ||||
| // Put3 appends three bytes to the end of the buffer. | ||||
| func (a *AsmBuf) Put3(x, y, z byte) { | ||||
| 	a.buf[a.off+0] = x | ||||
| 	a.buf[a.off+1] = y | ||||
| 	a.buf[a.off+2] = z | ||||
| 	a.off += 3 | ||||
| } | ||||
|  | ||||
| // Put4 appends four bytes to the end of the buffer. | ||||
| func (a *AsmBuf) Put4(x, y, z, w byte) { | ||||
| 	a.buf[a.off+0] = x | ||||
| 	a.buf[a.off+1] = y | ||||
| 	a.buf[a.off+2] = z | ||||
| 	a.buf[a.off+3] = w | ||||
| 	a.off += 4 | ||||
| } | ||||
|  | ||||
| // PutInt16 writes v into the buffer using little-endian encoding. | ||||
| func (a *AsmBuf) PutInt16(v int16) { | ||||
| 	a.buf[a.off+0] = byte(v) | ||||
| 	a.buf[a.off+1] = byte(v >> 8) | ||||
| 	a.off += 2 | ||||
| } | ||||
|  | ||||
| // PutInt32 writes v into the buffer using little-endian encoding. | ||||
| func (a *AsmBuf) PutInt32(v int32) { | ||||
| 	a.buf[a.off+0] = byte(v) | ||||
| 	a.buf[a.off+1] = byte(v >> 8) | ||||
| 	a.buf[a.off+2] = byte(v >> 16) | ||||
| 	a.buf[a.off+3] = byte(v >> 24) | ||||
| 	a.off += 4 | ||||
| } | ||||
|  | ||||
| // PutInt64 writes v into the buffer using little-endian encoding. | ||||
| func (a *AsmBuf) PutInt64(v int64) { | ||||
| 	a.buf[a.off+0] = byte(v) | ||||
| 	a.buf[a.off+1] = byte(v >> 8) | ||||
| 	a.buf[a.off+2] = byte(v >> 16) | ||||
| 	a.buf[a.off+3] = byte(v >> 24) | ||||
| 	a.buf[a.off+4] = byte(v >> 32) | ||||
| 	a.buf[a.off+5] = byte(v >> 40) | ||||
| 	a.buf[a.off+6] = byte(v >> 48) | ||||
| 	a.buf[a.off+7] = byte(v >> 56) | ||||
| 	a.off += 8 | ||||
| } | ||||
|  | ||||
| // Put copies b into the buffer. | ||||
| func (a *AsmBuf) Put(b []byte) { | ||||
| 	copy(a.buf[a.off:], b) | ||||
| 	a.off += len(b) | ||||
| } | ||||
|  | ||||
| // Insert inserts b at offset i. | ||||
| func (a *AsmBuf) Insert(i int, b byte) { | ||||
| 	a.off++ | ||||
| 	copy(a.buf[i+1:a.off], a.buf[i:a.off-1]) | ||||
| 	a.buf[i] = b | ||||
| } | ||||
|  | ||||
| // Last returns the byte at the end of the buffer. | ||||
| func (a *AsmBuf) Last() byte { return a.buf[a.off-1] } | ||||
|  | ||||
| // Len returns the length of the buffer. | ||||
| func (a *AsmBuf) Len() int { return a.off } | ||||
|  | ||||
| // Bytes returns the contents of the buffer. | ||||
| func (a *AsmBuf) Bytes() []byte { return a.buf[:a.off] } | ||||
|  | ||||
| // Reset empties the buffer. | ||||
| func (a *AsmBuf) Reset() { a.off = 0 } | ||||
|  | ||||
| // Peek returns the byte at offset i. | ||||
| func (a *AsmBuf) Peek(i int) byte { return a.buf[i] } | ||||
							
								
								
									
										375
									
								
								vendor/github.com/google/gops/internal/obj/mips/a.out.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										375
									
								
								vendor/github.com/google/gops/internal/obj/mips/a.out.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,375 @@ | ||||
| // cmd/9c/9.out.h from Vita Nuova. | ||||
| // | ||||
| //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | ||||
| //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| //	Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| //	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others | ||||
| //	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package mips | ||||
|  | ||||
| import "github.com/google/gops/internal/obj" | ||||
|  | ||||
| //go:generate go run ../stringer.go -i $GOFILE -o anames.go -p mips | ||||
|  | ||||
| /* | ||||
|  * mips 64 | ||||
|  */ | ||||
| const ( | ||||
| 	NSNAME = 8 | ||||
| 	NSYM   = 50 | ||||
| 	NREG   = 32 /* number of general registers */ | ||||
| 	NFREG  = 32 /* number of floating point registers */ | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	REG_R0 = obj.RBaseMIPS64 + iota | ||||
| 	REG_R1 | ||||
| 	REG_R2 | ||||
| 	REG_R3 | ||||
| 	REG_R4 | ||||
| 	REG_R5 | ||||
| 	REG_R6 | ||||
| 	REG_R7 | ||||
| 	REG_R8 | ||||
| 	REG_R9 | ||||
| 	REG_R10 | ||||
| 	REG_R11 | ||||
| 	REG_R12 | ||||
| 	REG_R13 | ||||
| 	REG_R14 | ||||
| 	REG_R15 | ||||
| 	REG_R16 | ||||
| 	REG_R17 | ||||
| 	REG_R18 | ||||
| 	REG_R19 | ||||
| 	REG_R20 | ||||
| 	REG_R21 | ||||
| 	REG_R22 | ||||
| 	REG_R23 | ||||
| 	REG_R24 | ||||
| 	REG_R25 | ||||
| 	REG_R26 | ||||
| 	REG_R27 | ||||
| 	REG_R28 | ||||
| 	REG_R29 | ||||
| 	REG_R30 | ||||
| 	REG_R31 | ||||
|  | ||||
| 	REG_F0 | ||||
| 	REG_F1 | ||||
| 	REG_F2 | ||||
| 	REG_F3 | ||||
| 	REG_F4 | ||||
| 	REG_F5 | ||||
| 	REG_F6 | ||||
| 	REG_F7 | ||||
| 	REG_F8 | ||||
| 	REG_F9 | ||||
| 	REG_F10 | ||||
| 	REG_F11 | ||||
| 	REG_F12 | ||||
| 	REG_F13 | ||||
| 	REG_F14 | ||||
| 	REG_F15 | ||||
| 	REG_F16 | ||||
| 	REG_F17 | ||||
| 	REG_F18 | ||||
| 	REG_F19 | ||||
| 	REG_F20 | ||||
| 	REG_F21 | ||||
| 	REG_F22 | ||||
| 	REG_F23 | ||||
| 	REG_F24 | ||||
| 	REG_F25 | ||||
| 	REG_F26 | ||||
| 	REG_F27 | ||||
| 	REG_F28 | ||||
| 	REG_F29 | ||||
| 	REG_F30 | ||||
| 	REG_F31 | ||||
|  | ||||
| 	REG_HI | ||||
| 	REG_LO | ||||
|  | ||||
| 	// co-processor 0 control registers | ||||
| 	REG_M0 | ||||
| 	REG_M1 | ||||
| 	REG_M2 | ||||
| 	REG_M3 | ||||
| 	REG_M4 | ||||
| 	REG_M5 | ||||
| 	REG_M6 | ||||
| 	REG_M7 | ||||
| 	REG_M8 | ||||
| 	REG_M9 | ||||
| 	REG_M10 | ||||
| 	REG_M11 | ||||
| 	REG_M12 | ||||
| 	REG_M13 | ||||
| 	REG_M14 | ||||
| 	REG_M15 | ||||
| 	REG_M16 | ||||
| 	REG_M17 | ||||
| 	REG_M18 | ||||
| 	REG_M19 | ||||
| 	REG_M20 | ||||
| 	REG_M21 | ||||
| 	REG_M22 | ||||
| 	REG_M23 | ||||
| 	REG_M24 | ||||
| 	REG_M25 | ||||
| 	REG_M26 | ||||
| 	REG_M27 | ||||
| 	REG_M28 | ||||
| 	REG_M29 | ||||
| 	REG_M30 | ||||
| 	REG_M31 | ||||
|  | ||||
| 	// FPU control registers | ||||
| 	REG_FCR0 | ||||
| 	REG_FCR1 | ||||
| 	REG_FCR2 | ||||
| 	REG_FCR3 | ||||
| 	REG_FCR4 | ||||
| 	REG_FCR5 | ||||
| 	REG_FCR6 | ||||
| 	REG_FCR7 | ||||
| 	REG_FCR8 | ||||
| 	REG_FCR9 | ||||
| 	REG_FCR10 | ||||
| 	REG_FCR11 | ||||
| 	REG_FCR12 | ||||
| 	REG_FCR13 | ||||
| 	REG_FCR14 | ||||
| 	REG_FCR15 | ||||
| 	REG_FCR16 | ||||
| 	REG_FCR17 | ||||
| 	REG_FCR18 | ||||
| 	REG_FCR19 | ||||
| 	REG_FCR20 | ||||
| 	REG_FCR21 | ||||
| 	REG_FCR22 | ||||
| 	REG_FCR23 | ||||
| 	REG_FCR24 | ||||
| 	REG_FCR25 | ||||
| 	REG_FCR26 | ||||
| 	REG_FCR27 | ||||
| 	REG_FCR28 | ||||
| 	REG_FCR29 | ||||
| 	REG_FCR30 | ||||
| 	REG_FCR31 | ||||
|  | ||||
| 	REG_LAST = REG_FCR31 // the last defined register | ||||
|  | ||||
| 	REG_SPECIAL = REG_M0 | ||||
|  | ||||
| 	REGZERO = REG_R0 /* set to zero */ | ||||
| 	REGSP   = REG_R29 | ||||
| 	REGSB   = REG_R28 | ||||
| 	REGLINK = REG_R31 | ||||
| 	REGRET  = REG_R1 | ||||
| 	REGARG  = -1      /* -1 disables passing the first argument in register */ | ||||
| 	REGRT1  = REG_R1  /* reserved for runtime, duffzero and duffcopy */ | ||||
| 	REGRT2  = REG_R2  /* reserved for runtime, duffcopy */ | ||||
| 	REGCTXT = REG_R22 /* context for closures */ | ||||
| 	REGG    = REG_R30 /* G */ | ||||
| 	REGTMP  = REG_R23 /* used by the linker */ | ||||
| 	FREGRET = REG_F0 | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	BIG = 32766 | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	/* mark flags */ | ||||
| 	FOLL    = 1 << 0 | ||||
| 	LABEL   = 1 << 1 | ||||
| 	LEAF    = 1 << 2 | ||||
| 	SYNC    = 1 << 3 | ||||
| 	BRANCH  = 1 << 4 | ||||
| 	LOAD    = 1 << 5 | ||||
| 	FCMP    = 1 << 6 | ||||
| 	NOSCHED = 1 << 7 | ||||
|  | ||||
| 	NSCHED = 20 | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	C_NONE = iota | ||||
| 	C_REG | ||||
| 	C_FREG | ||||
| 	C_FCREG | ||||
| 	C_MREG /* special processor register */ | ||||
| 	C_HI | ||||
| 	C_LO | ||||
| 	C_ZCON | ||||
| 	C_SCON /* 16 bit signed */ | ||||
| 	C_UCON /* 32 bit signed, low 16 bits 0 */ | ||||
| 	C_ADD0CON | ||||
| 	C_AND0CON | ||||
| 	C_ADDCON /* -0x8000 <= v < 0 */ | ||||
| 	C_ANDCON /* 0 < v <= 0xFFFF */ | ||||
| 	C_LCON   /* other 32 */ | ||||
| 	C_DCON   /* other 64 (could subdivide further) */ | ||||
| 	C_SACON  /* $n(REG) where n <= int16 */ | ||||
| 	C_SECON | ||||
| 	C_LACON /* $n(REG) where int16 < n <= int32 */ | ||||
| 	C_LECON | ||||
| 	C_DACON /* $n(REG) where int32 < n */ | ||||
| 	C_STCON /* $tlsvar */ | ||||
| 	C_SBRA | ||||
| 	C_LBRA | ||||
| 	C_SAUTO | ||||
| 	C_LAUTO | ||||
| 	C_SEXT | ||||
| 	C_LEXT | ||||
| 	C_ZOREG | ||||
| 	C_SOREG | ||||
| 	C_LOREG | ||||
| 	C_GOK | ||||
| 	C_ADDR | ||||
| 	C_TLS | ||||
| 	C_TEXTSIZE | ||||
|  | ||||
| 	C_NCLASS /* must be the last */ | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	AABSD = obj.ABaseMIPS64 + obj.A_ARCHSPECIFIC + iota | ||||
| 	AABSF | ||||
| 	AABSW | ||||
| 	AADD | ||||
| 	AADDD | ||||
| 	AADDF | ||||
| 	AADDU | ||||
| 	AADDW | ||||
| 	AAND | ||||
| 	ABEQ | ||||
| 	ABFPF | ||||
| 	ABFPT | ||||
| 	ABGEZ | ||||
| 	ABGEZAL | ||||
| 	ABGTZ | ||||
| 	ABLEZ | ||||
| 	ABLTZ | ||||
| 	ABLTZAL | ||||
| 	ABNE | ||||
| 	ABREAK | ||||
| 	ACMPEQD | ||||
| 	ACMPEQF | ||||
| 	ACMPGED | ||||
| 	ACMPGEF | ||||
| 	ACMPGTD | ||||
| 	ACMPGTF | ||||
| 	ADIV | ||||
| 	ADIVD | ||||
| 	ADIVF | ||||
| 	ADIVU | ||||
| 	ADIVW | ||||
| 	AGOK | ||||
| 	ALUI | ||||
| 	AMOVB | ||||
| 	AMOVBU | ||||
| 	AMOVD | ||||
| 	AMOVDF | ||||
| 	AMOVDW | ||||
| 	AMOVF | ||||
| 	AMOVFD | ||||
| 	AMOVFW | ||||
| 	AMOVH | ||||
| 	AMOVHU | ||||
| 	AMOVW | ||||
| 	AMOVWD | ||||
| 	AMOVWF | ||||
| 	AMOVWL | ||||
| 	AMOVWR | ||||
| 	AMUL | ||||
| 	AMULD | ||||
| 	AMULF | ||||
| 	AMULU | ||||
| 	AMULW | ||||
| 	ANEGD | ||||
| 	ANEGF | ||||
| 	ANEGW | ||||
| 	ANOR | ||||
| 	AOR | ||||
| 	AREM | ||||
| 	AREMU | ||||
| 	ARFE | ||||
| 	ASGT | ||||
| 	ASGTU | ||||
| 	ASLL | ||||
| 	ASRA | ||||
| 	ASRL | ||||
| 	ASUB | ||||
| 	ASUBD | ||||
| 	ASUBF | ||||
| 	ASUBU | ||||
| 	ASUBW | ||||
| 	ASYSCALL | ||||
| 	ATLBP | ||||
| 	ATLBR | ||||
| 	ATLBWI | ||||
| 	ATLBWR | ||||
| 	AWORD | ||||
| 	AXOR | ||||
|  | ||||
| 	/* 64-bit */ | ||||
| 	AMOVV | ||||
| 	AMOVVL | ||||
| 	AMOVVR | ||||
| 	ASLLV | ||||
| 	ASRAV | ||||
| 	ASRLV | ||||
| 	ADIVV | ||||
| 	ADIVVU | ||||
| 	AREMV | ||||
| 	AREMVU | ||||
| 	AMULV | ||||
| 	AMULVU | ||||
| 	AADDV | ||||
| 	AADDVU | ||||
| 	ASUBV | ||||
| 	ASUBVU | ||||
|  | ||||
| 	/* 64-bit FP */ | ||||
| 	ATRUNCFV | ||||
| 	ATRUNCDV | ||||
| 	ATRUNCFW | ||||
| 	ATRUNCDW | ||||
| 	AMOVWU | ||||
| 	AMOVFV | ||||
| 	AMOVDV | ||||
| 	AMOVVF | ||||
| 	AMOVVD | ||||
|  | ||||
| 	ALAST | ||||
|  | ||||
| 	// aliases | ||||
| 	AJMP = obj.AJMP | ||||
| 	AJAL = obj.ACALL | ||||
| 	ARET = obj.ARET | ||||
| ) | ||||
							
								
								
									
										113
									
								
								vendor/github.com/google/gops/internal/obj/mips/anames.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								vendor/github.com/google/gops/internal/obj/mips/anames.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | ||||
| // Generated by stringer -i a.out.go -o anames.go -p mips | ||||
| // Do not edit. | ||||
|  | ||||
| package mips | ||||
|  | ||||
| import "github.com/google/gops/internal/obj" | ||||
|  | ||||
| var Anames = []string{ | ||||
| 	obj.A_ARCHSPECIFIC: "ABSD", | ||||
| 	"ABSF", | ||||
| 	"ABSW", | ||||
| 	"ADD", | ||||
| 	"ADDD", | ||||
| 	"ADDF", | ||||
| 	"ADDU", | ||||
| 	"ADDW", | ||||
| 	"AND", | ||||
| 	"BEQ", | ||||
| 	"BFPF", | ||||
| 	"BFPT", | ||||
| 	"BGEZ", | ||||
| 	"BGEZAL", | ||||
| 	"BGTZ", | ||||
| 	"BLEZ", | ||||
| 	"BLTZ", | ||||
| 	"BLTZAL", | ||||
| 	"BNE", | ||||
| 	"BREAK", | ||||
| 	"CMPEQD", | ||||
| 	"CMPEQF", | ||||
| 	"CMPGED", | ||||
| 	"CMPGEF", | ||||
| 	"CMPGTD", | ||||
| 	"CMPGTF", | ||||
| 	"DIV", | ||||
| 	"DIVD", | ||||
| 	"DIVF", | ||||
| 	"DIVU", | ||||
| 	"DIVW", | ||||
| 	"GOK", | ||||
| 	"LUI", | ||||
| 	"MOVB", | ||||
| 	"MOVBU", | ||||
| 	"MOVD", | ||||
| 	"MOVDF", | ||||
| 	"MOVDW", | ||||
| 	"MOVF", | ||||
| 	"MOVFD", | ||||
| 	"MOVFW", | ||||
| 	"MOVH", | ||||
| 	"MOVHU", | ||||
| 	"MOVW", | ||||
| 	"MOVWD", | ||||
| 	"MOVWF", | ||||
| 	"MOVWL", | ||||
| 	"MOVWR", | ||||
| 	"MUL", | ||||
| 	"MULD", | ||||
| 	"MULF", | ||||
| 	"MULU", | ||||
| 	"MULW", | ||||
| 	"NEGD", | ||||
| 	"NEGF", | ||||
| 	"NEGW", | ||||
| 	"NOR", | ||||
| 	"OR", | ||||
| 	"REM", | ||||
| 	"REMU", | ||||
| 	"RFE", | ||||
| 	"SGT", | ||||
| 	"SGTU", | ||||
| 	"SLL", | ||||
| 	"SRA", | ||||
| 	"SRL", | ||||
| 	"SUB", | ||||
| 	"SUBD", | ||||
| 	"SUBF", | ||||
| 	"SUBU", | ||||
| 	"SUBW", | ||||
| 	"SYSCALL", | ||||
| 	"TLBP", | ||||
| 	"TLBR", | ||||
| 	"TLBWI", | ||||
| 	"TLBWR", | ||||
| 	"WORD", | ||||
| 	"XOR", | ||||
| 	"MOVV", | ||||
| 	"MOVVL", | ||||
| 	"MOVVR", | ||||
| 	"SLLV", | ||||
| 	"SRAV", | ||||
| 	"SRLV", | ||||
| 	"DIVV", | ||||
| 	"DIVVU", | ||||
| 	"REMV", | ||||
| 	"REMVU", | ||||
| 	"MULV", | ||||
| 	"MULVU", | ||||
| 	"ADDV", | ||||
| 	"ADDVU", | ||||
| 	"SUBV", | ||||
| 	"SUBVU", | ||||
| 	"TRUNCFV", | ||||
| 	"TRUNCDV", | ||||
| 	"TRUNCFW", | ||||
| 	"TRUNCDW", | ||||
| 	"MOVWU", | ||||
| 	"MOVFV", | ||||
| 	"MOVDV", | ||||
| 	"MOVVF", | ||||
| 	"MOVVD", | ||||
| 	"LAST", | ||||
| } | ||||
							
								
								
									
										44
									
								
								vendor/github.com/google/gops/internal/obj/mips/anames0.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								vendor/github.com/google/gops/internal/obj/mips/anames0.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| // Copyright 2015 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package mips | ||||
|  | ||||
| var cnames0 = []string{ | ||||
| 	"NONE", | ||||
| 	"REG", | ||||
| 	"FREG", | ||||
| 	"FCREG", | ||||
| 	"MREG", | ||||
| 	"HI", | ||||
| 	"LO", | ||||
| 	"ZCON", | ||||
| 	"SCON", | ||||
| 	"UCON", | ||||
| 	"ADD0CON", | ||||
| 	"AND0CON", | ||||
| 	"ADDCON", | ||||
| 	"ANDCON", | ||||
| 	"LCON", | ||||
| 	"DCON", | ||||
| 	"SACON", | ||||
| 	"SECON", | ||||
| 	"LACON", | ||||
| 	"LECON", | ||||
| 	"DACON", | ||||
| 	"STCON", | ||||
| 	"SBRA", | ||||
| 	"LBRA", | ||||
| 	"SAUTO", | ||||
| 	"LAUTO", | ||||
| 	"SEXT", | ||||
| 	"LEXT", | ||||
| 	"ZOREG", | ||||
| 	"SOREG", | ||||
| 	"LOREG", | ||||
| 	"GOK", | ||||
| 	"ADDR", | ||||
| 	"TLS", | ||||
| 	"TEXTSIZE", | ||||
| 	"NCLASS", | ||||
| } | ||||
							
								
								
									
										1783
									
								
								vendor/github.com/google/gops/internal/obj/mips/asm0.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1783
									
								
								vendor/github.com/google/gops/internal/obj/mips/asm0.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										85
									
								
								vendor/github.com/google/gops/internal/obj/mips/list0.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								vendor/github.com/google/gops/internal/obj/mips/list0.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| // cmd/9l/list.c from Vita Nuova. | ||||
| // | ||||
| //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | ||||
| //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| //	Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| //	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others | ||||
| //	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package mips | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/google/gops/internal/obj" | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	obj.RegisterRegister(obj.RBaseMIPS64, REG_LAST&^1023+1024, Rconv) | ||||
| 	obj.RegisterOpcode(obj.ABaseMIPS64, Anames) | ||||
| } | ||||
|  | ||||
| func Rconv(r int) string { | ||||
| 	if r == 0 { | ||||
| 		return "NONE" | ||||
| 	} | ||||
| 	if r == REGG { | ||||
| 		// Special case. | ||||
| 		return "g" | ||||
| 	} | ||||
| 	if r == REGSB { | ||||
| 		// Special case. | ||||
| 		return "RSB" | ||||
| 	} | ||||
| 	if REG_R0 <= r && r <= REG_R31 { | ||||
| 		return fmt.Sprintf("R%d", r-REG_R0) | ||||
| 	} | ||||
| 	if REG_F0 <= r && r <= REG_F31 { | ||||
| 		return fmt.Sprintf("F%d", r-REG_F0) | ||||
| 	} | ||||
| 	if REG_M0 <= r && r <= REG_M31 { | ||||
| 		return fmt.Sprintf("M%d", r-REG_M0) | ||||
| 	} | ||||
| 	if REG_FCR0 <= r && r <= REG_FCR31 { | ||||
| 		return fmt.Sprintf("FCR%d", r-REG_FCR0) | ||||
| 	} | ||||
| 	if r == REG_HI { | ||||
| 		return "HI" | ||||
| 	} | ||||
| 	if r == REG_LO { | ||||
| 		return "LO" | ||||
| 	} | ||||
|  | ||||
| 	return fmt.Sprintf("Rgok(%d)", r-obj.RBaseMIPS64) | ||||
| } | ||||
|  | ||||
| func DRconv(a int) string { | ||||
| 	s := "C_??" | ||||
| 	if a >= C_NONE && a <= C_NCLASS { | ||||
| 		s = cnames0[a] | ||||
| 	} | ||||
| 	var fp string | ||||
| 	fp += s | ||||
| 	return fp | ||||
| } | ||||
							
								
								
									
										1497
									
								
								vendor/github.com/google/gops/internal/obj/mips/obj0.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1497
									
								
								vendor/github.com/google/gops/internal/obj/mips/obj0.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										306
									
								
								vendor/github.com/google/gops/internal/obj/obj.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										306
									
								
								vendor/github.com/google/gops/internal/obj/obj.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,306 @@ | ||||
| // Copyright 2009 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"path/filepath" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // A LineHist records the history of the file input stack, which maps the virtual line number, | ||||
| // an incrementing count of lines processed in any input file and typically named lineno, | ||||
| // to a stack of file:line pairs showing the path of inclusions that led to that position. | ||||
| // The first line directive (//line in Go, #line in assembly) is treated as pushing | ||||
| // a new entry on the stack, so that errors can report both the actual and translated | ||||
| // line number. | ||||
| // | ||||
| // In typical use, the virtual lineno begins at 1, and file line numbers also begin at 1, | ||||
| // but the only requirements placed upon the numbers by this code are: | ||||
| //	- calls to Push, Update, and Pop must be monotonically increasing in lineno | ||||
| //	- except as specified by those methods, virtual and file line number increase | ||||
| //	  together, so that given (only) calls Push(10, "x.go", 1) and Pop(15), | ||||
| //	  virtual line 12 corresponds to x.go line 3. | ||||
| type LineHist struct { | ||||
| 	Top               *LineStack  // current top of stack | ||||
| 	Ranges            []LineRange // ranges for lookup | ||||
| 	Dir               string      // directory to qualify relative paths | ||||
| 	TrimPathPrefix    string      // remove leading TrimPath from recorded file names | ||||
| 	PrintFilenameOnly bool        // ignore path when pretty-printing a line; internal use only | ||||
| 	GOROOT            string      // current GOROOT | ||||
| } | ||||
|  | ||||
| // A LineStack is an entry in the recorded line history. | ||||
| // Although the history at any given line number is a stack, | ||||
| // the record for all line processed forms a tree, with common | ||||
| // stack prefixes acting as parents. | ||||
| type LineStack struct { | ||||
| 	Parent    *LineStack // parent in inclusion stack | ||||
| 	Lineno    int        // virtual line number where this entry takes effect | ||||
| 	File      string     // file name used to open source file, for error messages | ||||
| 	AbsFile   string     // absolute file name, for pcln tables | ||||
| 	FileLine  int        // line number in file at Lineno | ||||
| 	Directive bool | ||||
| 	Sym       *LSym // for linkgetline - TODO(rsc): remove | ||||
| } | ||||
|  | ||||
| func (stk *LineStack) fileLineAt(lineno int) int { | ||||
| 	return stk.FileLine + lineno - stk.Lineno | ||||
| } | ||||
|  | ||||
| // The span of valid linenos in the recorded line history can be broken | ||||
| // into a set of ranges, each with a particular stack. | ||||
| // A LineRange records one such range. | ||||
| type LineRange struct { | ||||
| 	Start int        // starting lineno | ||||
| 	Stack *LineStack // top of stack for this range | ||||
| } | ||||
|  | ||||
| // startRange starts a new range with the given top of stack. | ||||
| func (h *LineHist) startRange(lineno int, top *LineStack) { | ||||
| 	h.Top = top | ||||
| 	h.Ranges = append(h.Ranges, LineRange{top.Lineno, top}) | ||||
| } | ||||
|  | ||||
| // setFile sets stk.File = file and also derives stk.AbsFile. | ||||
| func (h *LineHist) setFile(stk *LineStack, file string) { | ||||
| 	// Note: The exclusion of stk.Directive may be wrong but matches what we've done before. | ||||
| 	// The check for < avoids putting a path prefix on "<autogenerated>". | ||||
| 	abs := file | ||||
| 	if h.Dir != "" && !filepath.IsAbs(file) && !strings.HasPrefix(file, "<") && !stk.Directive { | ||||
| 		abs = filepath.Join(h.Dir, file) | ||||
| 	} | ||||
|  | ||||
| 	// Remove leading TrimPathPrefix, or else rewrite $GOROOT to literal $GOROOT. | ||||
| 	if h.TrimPathPrefix != "" && hasPathPrefix(abs, h.TrimPathPrefix) { | ||||
| 		if abs == h.TrimPathPrefix { | ||||
| 			abs = "" | ||||
| 		} else { | ||||
| 			abs = abs[len(h.TrimPathPrefix)+1:] | ||||
| 		} | ||||
| 	} else if hasPathPrefix(abs, h.GOROOT) { | ||||
| 		abs = "$GOROOT" + abs[len(h.GOROOT):] | ||||
| 	} | ||||
| 	if abs == "" { | ||||
| 		abs = "??" | ||||
| 	} | ||||
| 	abs = filepath.Clean(abs) | ||||
| 	stk.AbsFile = abs | ||||
|  | ||||
| 	if file == "" { | ||||
| 		file = "??" | ||||
| 	} | ||||
| 	stk.File = file | ||||
| } | ||||
|  | ||||
| // Does s have t as a path prefix? | ||||
| // That is, does s == t or does s begin with t followed by a slash? | ||||
| // For portability, we allow ASCII case folding, so that hasPathPrefix("a/b/c", "A/B") is true. | ||||
| // Similarly, we allow slash folding, so that hasPathPrefix("a/b/c", "a\\b") is true. | ||||
| // We do not allow full Unicode case folding, for fear of causing more confusion | ||||
| // or harm than good. (For an example of the kinds of things that can go wrong, | ||||
| // see http://article.gmane.org/gmane.linux.kernel/1853266.) | ||||
| func hasPathPrefix(s string, t string) bool { | ||||
| 	if len(t) > len(s) { | ||||
| 		return false | ||||
| 	} | ||||
| 	var i int | ||||
| 	for i = 0; i < len(t); i++ { | ||||
| 		cs := int(s[i]) | ||||
| 		ct := int(t[i]) | ||||
| 		if 'A' <= cs && cs <= 'Z' { | ||||
| 			cs += 'a' - 'A' | ||||
| 		} | ||||
| 		if 'A' <= ct && ct <= 'Z' { | ||||
| 			ct += 'a' - 'A' | ||||
| 		} | ||||
| 		if cs == '\\' { | ||||
| 			cs = '/' | ||||
| 		} | ||||
| 		if ct == '\\' { | ||||
| 			ct = '/' | ||||
| 		} | ||||
| 		if cs != ct { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return i >= len(s) || s[i] == '/' || s[i] == '\\' | ||||
| } | ||||
|  | ||||
| // Push records that at that lineno a new file with the given name was pushed onto the input stack. | ||||
| func (h *LineHist) Push(lineno int, file string) { | ||||
| 	stk := &LineStack{ | ||||
| 		Parent:   h.Top, | ||||
| 		Lineno:   lineno, | ||||
| 		FileLine: 1, | ||||
| 	} | ||||
| 	h.setFile(stk, file) | ||||
| 	h.startRange(lineno, stk) | ||||
| } | ||||
|  | ||||
| // Pop records that at lineno the current file was popped from the input stack. | ||||
| func (h *LineHist) Pop(lineno int) { | ||||
| 	top := h.Top | ||||
| 	if top == nil { | ||||
| 		return | ||||
| 	} | ||||
| 	if top.Directive && top.Parent != nil { // pop #line level too | ||||
| 		top = top.Parent | ||||
| 	} | ||||
| 	next := top.Parent | ||||
| 	if next == nil { | ||||
| 		h.Top = nil | ||||
| 		h.Ranges = append(h.Ranges, LineRange{lineno, nil}) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// Popping included file. Update parent offset to account for | ||||
| 	// the virtual line number range taken by the included file. | ||||
| 	// Cannot modify the LineStack directly, or else lookups | ||||
| 	// for the earlier line numbers will get the wrong answers, | ||||
| 	// so make a new one. | ||||
| 	stk := new(LineStack) | ||||
| 	*stk = *next | ||||
| 	stk.Lineno = lineno | ||||
| 	stk.FileLine = next.fileLineAt(top.Lineno) | ||||
| 	h.startRange(lineno, stk) | ||||
| } | ||||
|  | ||||
| // Update records that at lineno the file name and line number were changed using | ||||
| // a line directive (//line in Go, #line in assembly). | ||||
| func (h *LineHist) Update(lineno int, file string, line int) { | ||||
| 	top := h.Top | ||||
| 	if top == nil { | ||||
| 		return // shouldn't happen | ||||
| 	} | ||||
| 	var stk *LineStack | ||||
| 	if top.Directive { | ||||
| 		// Update existing entry, except make copy to avoid changing earlier history. | ||||
| 		stk = new(LineStack) | ||||
| 		*stk = *top | ||||
| 	} else { | ||||
| 		// Push new entry. | ||||
| 		stk = &LineStack{ | ||||
| 			Parent:    top, | ||||
| 			Directive: true, | ||||
| 		} | ||||
| 	} | ||||
| 	stk.Lineno = lineno | ||||
| 	if stk.File != file { | ||||
| 		h.setFile(stk, file) // only retain string if needed | ||||
| 	} | ||||
| 	stk.FileLine = line | ||||
| 	h.startRange(lineno, stk) | ||||
| } | ||||
|  | ||||
| // AddImport adds a package to the list of imported packages. | ||||
| func (ctxt *Link) AddImport(pkg string) { | ||||
| 	ctxt.Imports = append(ctxt.Imports, pkg) | ||||
| } | ||||
|  | ||||
| // At returns the input stack in effect at lineno. | ||||
| func (h *LineHist) At(lineno int) *LineStack { | ||||
| 	i := sort.Search(len(h.Ranges), func(i int) bool { | ||||
| 		return h.Ranges[i].Start > lineno | ||||
| 	}) | ||||
| 	// Found first entry beyond lineno. | ||||
| 	if i == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return h.Ranges[i-1].Stack | ||||
| } | ||||
|  | ||||
| // LineString returns a string giving the file and line number | ||||
| // corresponding to lineno, for use in error messages. | ||||
| func (h *LineHist) LineString(lineno int) string { | ||||
| 	stk := h.At(lineno) | ||||
| 	if stk == nil { | ||||
| 		return "<unknown line number>" | ||||
| 	} | ||||
|  | ||||
| 	filename := stk.File | ||||
| 	if h.PrintFilenameOnly { | ||||
| 		filename = filepath.Base(filename) | ||||
| 	} | ||||
| 	text := fmt.Sprintf("%s:%d", filename, stk.fileLineAt(lineno)) | ||||
| 	if stk.Directive && stk.Parent != nil { | ||||
| 		stk = stk.Parent | ||||
| 		filename = stk.File | ||||
| 		if h.PrintFilenameOnly { | ||||
| 			filename = filepath.Base(filename) | ||||
| 		} | ||||
| 		text += fmt.Sprintf("[%s:%d]", filename, stk.fileLineAt(lineno)) | ||||
| 	} | ||||
| 	const showFullStack = false // was used by old C compilers | ||||
| 	if showFullStack { | ||||
| 		for stk.Parent != nil { | ||||
| 			lineno = stk.Lineno - 1 | ||||
| 			stk = stk.Parent | ||||
| 			text += fmt.Sprintf(" %s:%d", filename, stk.fileLineAt(lineno)) | ||||
| 			if stk.Directive && stk.Parent != nil { | ||||
| 				stk = stk.Parent | ||||
| 				text += fmt.Sprintf("[%s:%d]", filename, stk.fileLineAt(lineno)) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return text | ||||
| } | ||||
|  | ||||
| // FileLine returns the file name and line number | ||||
| // at the top of the stack for the given lineno. | ||||
| func (h *LineHist) FileLine(lineno int) (file string, line int) { | ||||
| 	stk := h.At(lineno) | ||||
| 	if stk == nil { | ||||
| 		return "??", 0 | ||||
| 	} | ||||
| 	return stk.File, stk.fileLineAt(lineno) | ||||
| } | ||||
|  | ||||
| // AbsFileLine returns the absolute file name and line number | ||||
| // at the top of the stack for the given lineno. | ||||
| func (h *LineHist) AbsFileLine(lineno int) (file string, line int) { | ||||
| 	stk := h.At(lineno) | ||||
| 	if stk == nil { | ||||
| 		return "??", 0 | ||||
| 	} | ||||
| 	return stk.AbsFile, stk.fileLineAt(lineno) | ||||
| } | ||||
|  | ||||
| // This is a simplified copy of linklinefmt above. | ||||
| // It doesn't allow printing the full stack, and it returns the file name and line number separately. | ||||
| // TODO: Unify with linklinefmt somehow. | ||||
| func linkgetline(ctxt *Link, lineno int32) (f *LSym, l int32) { | ||||
| 	stk := ctxt.LineHist.At(int(lineno)) | ||||
| 	if stk == nil || stk.AbsFile == "" { | ||||
| 		return Linklookup(ctxt, "??", HistVersion), 0 | ||||
| 	} | ||||
| 	if stk.Sym == nil { | ||||
| 		stk.Sym = Linklookup(ctxt, stk.AbsFile, HistVersion) | ||||
| 	} | ||||
| 	return stk.Sym, int32(stk.fileLineAt(int(lineno))) | ||||
| } | ||||
|  | ||||
| func Linkprfile(ctxt *Link, line int) { | ||||
| 	fmt.Printf("%s ", ctxt.LineHist.LineString(line)) | ||||
| } | ||||
|  | ||||
| func fieldtrack(ctxt *Link, cursym *LSym) { | ||||
| 	p := cursym.Text | ||||
| 	if p == nil || p.Link == nil { // handle external functions and ELF section symbols | ||||
| 		return | ||||
| 	} | ||||
| 	ctxt.Cursym = cursym | ||||
|  | ||||
| 	for ; p != nil; p = p.Link { | ||||
| 		if p.As == AUSEFIELD { | ||||
| 			r := Addrel(ctxt.Cursym) | ||||
| 			r.Off = 0 | ||||
| 			r.Siz = 0 | ||||
| 			r.Sym = p.From.Sym | ||||
| 			r.Type = R_USEFIELD | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										606
									
								
								vendor/github.com/google/gops/internal/obj/objfile.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										606
									
								
								vendor/github.com/google/gops/internal/obj/objfile.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,606 @@ | ||||
| // Copyright 2013 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // Writing of Go object files. | ||||
| // | ||||
| // Originally, Go object files were Plan 9 object files, but no longer. | ||||
| // Now they are more like standard object files, in that each symbol is defined | ||||
| // by an associated memory image (bytes) and a list of relocations to apply | ||||
| // during linking. We do not (yet?) use a standard file format, however. | ||||
| // For now, the format is chosen to be as simple as possible to read and write. | ||||
| // It may change for reasons of efficiency, or we may even switch to a | ||||
| // standard file format if there are compelling benefits to doing so. | ||||
| // See golang.org/s/go13linker for more background. | ||||
| // | ||||
| // The file format is: | ||||
| // | ||||
| //	- magic header: "\x00\x00go17ld" | ||||
| //	- byte 1 - version number | ||||
| //	- sequence of strings giving dependencies (imported packages) | ||||
| //	- empty string (marks end of sequence) | ||||
| //	- sequence of symbol references used by the defined symbols | ||||
| //	- byte 0xff (marks end of sequence) | ||||
| //	- sequence of integer lengths: | ||||
| //		- total data length | ||||
| //		- total number of relocations | ||||
| //		- total number of pcdata | ||||
| //		- total number of automatics | ||||
| //		- total number of funcdata | ||||
| //		- total number of files | ||||
| //	- data, the content of the defined symbols | ||||
| //	- sequence of defined symbols | ||||
| //	- byte 0xff (marks end of sequence) | ||||
| //	- magic footer: "\xff\xffgo17ld" | ||||
| // | ||||
| // All integers are stored in a zigzag varint format. | ||||
| // See golang.org/s/go12symtab for a definition. | ||||
| // | ||||
| // Data blocks and strings are both stored as an integer | ||||
| // followed by that many bytes. | ||||
| // | ||||
| // A symbol reference is a string name followed by a version. | ||||
| // | ||||
| // A symbol points to other symbols using an index into the symbol | ||||
| // reference sequence. Index 0 corresponds to a nil LSym* pointer. | ||||
| // In the symbol layout described below "symref index" stands for this | ||||
| // index. | ||||
| // | ||||
| // Each symbol is laid out as the following fields (taken from LSym*): | ||||
| // | ||||
| //	- byte 0xfe (sanity check for synchronization) | ||||
| //	- type [int] | ||||
| //	- name & version [symref index] | ||||
| //	- flags [int] | ||||
| //		1<<0 dupok | ||||
| //		1<<1 local | ||||
| //		1<<2 add to typelink table | ||||
| //	- size [int] | ||||
| //	- gotype [symref index] | ||||
| //	- p [data block] | ||||
| //	- nr [int] | ||||
| //	- r [nr relocations, sorted by off] | ||||
| // | ||||
| // If type == STEXT, there are a few more fields: | ||||
| // | ||||
| //	- args [int] | ||||
| //	- locals [int] | ||||
| //	- nosplit [int] | ||||
| //	- flags [int] | ||||
| //		1<<0 leaf | ||||
| //		1<<1 C function | ||||
| //		1<<2 function may call reflect.Type.Method | ||||
| //	- nlocal [int] | ||||
| //	- local [nlocal automatics] | ||||
| //	- pcln [pcln table] | ||||
| // | ||||
| // Each relocation has the encoding: | ||||
| // | ||||
| //	- off [int] | ||||
| //	- siz [int] | ||||
| //	- type [int] | ||||
| //	- add [int] | ||||
| //	- sym [symref index] | ||||
| // | ||||
| // Each local has the encoding: | ||||
| // | ||||
| //	- asym [symref index] | ||||
| //	- offset [int] | ||||
| //	- type [int] | ||||
| //	- gotype [symref index] | ||||
| // | ||||
| // The pcln table has the encoding: | ||||
| // | ||||
| //	- pcsp [data block] | ||||
| //	- pcfile [data block] | ||||
| //	- pcline [data block] | ||||
| //	- npcdata [int] | ||||
| //	- pcdata [npcdata data blocks] | ||||
| //	- nfuncdata [int] | ||||
| //	- funcdata [nfuncdata symref index] | ||||
| //	- funcdatasym [nfuncdata ints] | ||||
| //	- nfile [int] | ||||
| //	- file [nfile symref index] | ||||
| // | ||||
| // The file layout and meaning of type integers are architecture-independent. | ||||
| // | ||||
| // TODO(rsc): The file format is good for a first pass but needs work. | ||||
| //	- There are SymID in the object file that should really just be strings. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"path/filepath" | ||||
| 	"sort" | ||||
|  | ||||
| 	"github.com/google/gops/internal/dwarf" | ||||
| 	"github.com/google/gops/internal/sys" | ||||
| ) | ||||
|  | ||||
| // The Go and C compilers, and the assembler, call writeobj to write | ||||
| // out a Go object file. The linker does not call this; the linker | ||||
| // does not write out object files. | ||||
| func Writeobjdirect(ctxt *Link, b *bufio.Writer) { | ||||
| 	Flushplist(ctxt) | ||||
| 	WriteObjFile(ctxt, b) | ||||
| } | ||||
|  | ||||
| // objWriter writes Go object files. | ||||
| type objWriter struct { | ||||
| 	wr   *bufio.Writer | ||||
| 	ctxt *Link | ||||
| 	// Temporary buffer for zigzag int writing. | ||||
| 	varintbuf [10]uint8 | ||||
|  | ||||
| 	// Provide the the index of a symbol reference by symbol name. | ||||
| 	// One map for versioned symbols and one for unversioned symbols. | ||||
| 	// Used for deduplicating the symbol reference list. | ||||
| 	refIdx  map[string]int | ||||
| 	vrefIdx map[string]int | ||||
|  | ||||
| 	// Number of objects written of each type. | ||||
| 	nRefs     int | ||||
| 	nData     int | ||||
| 	nReloc    int | ||||
| 	nPcdata   int | ||||
| 	nAutom    int | ||||
| 	nFuncdata int | ||||
| 	nFile     int | ||||
| } | ||||
|  | ||||
| func (w *objWriter) addLengths(s *LSym) { | ||||
| 	w.nData += len(s.P) | ||||
| 	w.nReloc += len(s.R) | ||||
|  | ||||
| 	if s.Type != STEXT { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	pc := s.Pcln | ||||
|  | ||||
| 	data := 0 | ||||
| 	data += len(pc.Pcsp.P) | ||||
| 	data += len(pc.Pcfile.P) | ||||
| 	data += len(pc.Pcline.P) | ||||
| 	for i := 0; i < len(pc.Pcdata); i++ { | ||||
| 		data += len(pc.Pcdata[i].P) | ||||
| 	} | ||||
|  | ||||
| 	w.nData += data | ||||
| 	w.nPcdata += len(pc.Pcdata) | ||||
|  | ||||
| 	autom := 0 | ||||
| 	for a := s.Autom; a != nil; a = a.Link { | ||||
| 		autom++ | ||||
| 	} | ||||
| 	w.nAutom += autom | ||||
| 	w.nFuncdata += len(pc.Funcdataoff) | ||||
| 	w.nFile += len(pc.File) | ||||
| } | ||||
|  | ||||
| func (w *objWriter) writeLengths() { | ||||
| 	w.writeInt(int64(w.nData)) | ||||
| 	w.writeInt(int64(w.nReloc)) | ||||
| 	w.writeInt(int64(w.nPcdata)) | ||||
| 	w.writeInt(int64(w.nAutom)) | ||||
| 	w.writeInt(int64(w.nFuncdata)) | ||||
| 	w.writeInt(int64(w.nFile)) | ||||
| } | ||||
|  | ||||
| func newObjWriter(ctxt *Link, b *bufio.Writer) *objWriter { | ||||
| 	return &objWriter{ | ||||
| 		ctxt:    ctxt, | ||||
| 		wr:      b, | ||||
| 		vrefIdx: make(map[string]int), | ||||
| 		refIdx:  make(map[string]int), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func WriteObjFile(ctxt *Link, b *bufio.Writer) { | ||||
| 	w := newObjWriter(ctxt, b) | ||||
|  | ||||
| 	// Magic header | ||||
| 	w.wr.WriteString("\x00\x00go17ld") | ||||
|  | ||||
| 	// Version | ||||
| 	w.wr.WriteByte(1) | ||||
|  | ||||
| 	// Autolib | ||||
| 	for _, pkg := range ctxt.Imports { | ||||
| 		w.writeString(pkg) | ||||
| 	} | ||||
| 	w.writeString("") | ||||
|  | ||||
| 	// Symbol references | ||||
| 	for _, s := range ctxt.Text { | ||||
| 		w.writeRefs(s) | ||||
| 		w.addLengths(s) | ||||
| 	} | ||||
| 	for _, s := range ctxt.Data { | ||||
| 		w.writeRefs(s) | ||||
| 		w.addLengths(s) | ||||
| 	} | ||||
| 	// End symbol references | ||||
| 	w.wr.WriteByte(0xff) | ||||
|  | ||||
| 	// Lengths | ||||
| 	w.writeLengths() | ||||
|  | ||||
| 	// Data block | ||||
| 	for _, s := range ctxt.Text { | ||||
| 		w.wr.Write(s.P) | ||||
| 		pc := s.Pcln | ||||
| 		w.wr.Write(pc.Pcsp.P) | ||||
| 		w.wr.Write(pc.Pcfile.P) | ||||
| 		w.wr.Write(pc.Pcline.P) | ||||
| 		for i := 0; i < len(pc.Pcdata); i++ { | ||||
| 			w.wr.Write(pc.Pcdata[i].P) | ||||
| 		} | ||||
| 	} | ||||
| 	for _, s := range ctxt.Data { | ||||
| 		w.wr.Write(s.P) | ||||
| 	} | ||||
|  | ||||
| 	// Symbols | ||||
| 	for _, s := range ctxt.Text { | ||||
| 		w.writeSym(s) | ||||
| 	} | ||||
| 	for _, s := range ctxt.Data { | ||||
| 		w.writeSym(s) | ||||
| 	} | ||||
|  | ||||
| 	// Magic footer | ||||
| 	w.wr.WriteString("\xff\xffgo17ld") | ||||
| } | ||||
|  | ||||
| // Symbols are prefixed so their content doesn't get confused with the magic footer. | ||||
| const symPrefix = 0xfe | ||||
|  | ||||
| func (w *objWriter) writeRef(s *LSym, isPath bool) { | ||||
| 	if s == nil || s.RefIdx != 0 { | ||||
| 		return | ||||
| 	} | ||||
| 	var m map[string]int | ||||
| 	switch s.Version { | ||||
| 	case 0: | ||||
| 		m = w.refIdx | ||||
| 	case 1: | ||||
| 		m = w.vrefIdx | ||||
| 	default: | ||||
| 		log.Fatalf("%s: invalid version number %d", s.Name, s.Version) | ||||
| 	} | ||||
|  | ||||
| 	idx := m[s.Name] | ||||
| 	if idx != 0 { | ||||
| 		s.RefIdx = idx | ||||
| 		return | ||||
| 	} | ||||
| 	w.wr.WriteByte(symPrefix) | ||||
| 	if isPath { | ||||
| 		w.writeString(filepath.ToSlash(s.Name)) | ||||
| 	} else { | ||||
| 		w.writeString(s.Name) | ||||
| 	} | ||||
| 	w.writeInt(int64(s.Version)) | ||||
| 	w.nRefs++ | ||||
| 	s.RefIdx = w.nRefs | ||||
| 	m[s.Name] = w.nRefs | ||||
| } | ||||
|  | ||||
| func (w *objWriter) writeRefs(s *LSym) { | ||||
| 	w.writeRef(s, false) | ||||
| 	w.writeRef(s.Gotype, false) | ||||
| 	for i := range s.R { | ||||
| 		w.writeRef(s.R[i].Sym, false) | ||||
| 	} | ||||
|  | ||||
| 	if s.Type == STEXT { | ||||
| 		for a := s.Autom; a != nil; a = a.Link { | ||||
| 			w.writeRef(a.Asym, false) | ||||
| 			w.writeRef(a.Gotype, false) | ||||
| 		} | ||||
| 		pc := s.Pcln | ||||
| 		for _, d := range pc.Funcdata { | ||||
| 			w.writeRef(d, false) | ||||
| 		} | ||||
| 		for _, f := range pc.File { | ||||
| 			w.writeRef(f, true) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (w *objWriter) writeSymDebug(s *LSym) { | ||||
| 	ctxt := w.ctxt | ||||
| 	fmt.Fprintf(ctxt.Bso, "%s ", s.Name) | ||||
| 	if s.Version != 0 { | ||||
| 		fmt.Fprintf(ctxt.Bso, "v=%d ", s.Version) | ||||
| 	} | ||||
| 	if s.Type != 0 { | ||||
| 		fmt.Fprintf(ctxt.Bso, "t=%d ", s.Type) | ||||
| 	} | ||||
| 	if s.DuplicateOK() { | ||||
| 		fmt.Fprintf(ctxt.Bso, "dupok ") | ||||
| 	} | ||||
| 	if s.CFunc() { | ||||
| 		fmt.Fprintf(ctxt.Bso, "cfunc ") | ||||
| 	} | ||||
| 	if s.NoSplit() { | ||||
| 		fmt.Fprintf(ctxt.Bso, "nosplit ") | ||||
| 	} | ||||
| 	fmt.Fprintf(ctxt.Bso, "size=%d", s.Size) | ||||
| 	if s.Type == STEXT { | ||||
| 		fmt.Fprintf(ctxt.Bso, " args=%#x locals=%#x", uint64(s.Args), uint64(s.Locals)) | ||||
| 		if s.Leaf() { | ||||
| 			fmt.Fprintf(ctxt.Bso, " leaf") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	fmt.Fprintf(ctxt.Bso, "\n") | ||||
| 	for p := s.Text; p != nil; p = p.Link { | ||||
| 		fmt.Fprintf(ctxt.Bso, "\t%#04x %v\n", uint(int(p.Pc)), p) | ||||
| 	} | ||||
| 	var c int | ||||
| 	var j int | ||||
| 	for i := 0; i < len(s.P); { | ||||
| 		fmt.Fprintf(ctxt.Bso, "\t%#04x", uint(i)) | ||||
| 		for j = i; j < i+16 && j < len(s.P); j++ { | ||||
| 			fmt.Fprintf(ctxt.Bso, " %02x", s.P[j]) | ||||
| 		} | ||||
| 		for ; j < i+16; j++ { | ||||
| 			fmt.Fprintf(ctxt.Bso, "   ") | ||||
| 		} | ||||
| 		fmt.Fprintf(ctxt.Bso, "  ") | ||||
| 		for j = i; j < i+16 && j < len(s.P); j++ { | ||||
| 			c = int(s.P[j]) | ||||
| 			if ' ' <= c && c <= 0x7e { | ||||
| 				fmt.Fprintf(ctxt.Bso, "%c", c) | ||||
| 			} else { | ||||
| 				fmt.Fprintf(ctxt.Bso, ".") | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		fmt.Fprintf(ctxt.Bso, "\n") | ||||
| 		i += 16 | ||||
| 	} | ||||
|  | ||||
| 	sort.Sort(relocByOff(s.R)) // generate stable output | ||||
| 	for _, r := range s.R { | ||||
| 		name := "" | ||||
| 		if r.Sym != nil { | ||||
| 			name = r.Sym.Name | ||||
| 		} else if r.Type == R_TLS_LE { | ||||
| 			name = "TLS" | ||||
| 		} | ||||
| 		if ctxt.Arch.InFamily(sys.ARM, sys.PPC64) { | ||||
| 			fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%x\n", int(r.Off), r.Siz, r.Type, name, uint64(r.Add)) | ||||
| 		} else { | ||||
| 			fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type, name, r.Add) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (w *objWriter) writeSym(s *LSym) { | ||||
| 	ctxt := w.ctxt | ||||
| 	if ctxt.Debugasm != 0 { | ||||
| 		w.writeSymDebug(s) | ||||
| 	} | ||||
|  | ||||
| 	w.wr.WriteByte(symPrefix) | ||||
| 	w.writeInt(int64(s.Type)) | ||||
| 	w.writeRefIndex(s) | ||||
| 	flags := int64(0) | ||||
| 	if s.DuplicateOK() { | ||||
| 		flags |= 1 | ||||
| 	} | ||||
| 	if s.Local() { | ||||
| 		flags |= 1 << 1 | ||||
| 	} | ||||
| 	if s.MakeTypelink() { | ||||
| 		flags |= 1 << 2 | ||||
| 	} | ||||
| 	w.writeInt(flags) | ||||
| 	w.writeInt(s.Size) | ||||
| 	w.writeRefIndex(s.Gotype) | ||||
| 	w.writeInt(int64(len(s.P))) | ||||
|  | ||||
| 	w.writeInt(int64(len(s.R))) | ||||
| 	var r *Reloc | ||||
| 	for i := 0; i < len(s.R); i++ { | ||||
| 		r = &s.R[i] | ||||
| 		w.writeInt(int64(r.Off)) | ||||
| 		w.writeInt(int64(r.Siz)) | ||||
| 		w.writeInt(int64(r.Type)) | ||||
| 		w.writeInt(r.Add) | ||||
| 		w.writeRefIndex(r.Sym) | ||||
| 	} | ||||
|  | ||||
| 	if s.Type != STEXT { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	w.writeInt(int64(s.Args)) | ||||
| 	w.writeInt(int64(s.Locals)) | ||||
| 	if s.NoSplit() { | ||||
| 		w.writeInt(1) | ||||
| 	} else { | ||||
| 		w.writeInt(0) | ||||
| 	} | ||||
| 	flags = int64(0) | ||||
| 	if s.Leaf() { | ||||
| 		flags |= 1 | ||||
| 	} | ||||
| 	if s.CFunc() { | ||||
| 		flags |= 1 << 1 | ||||
| 	} | ||||
| 	if s.ReflectMethod() { | ||||
| 		flags |= 1 << 2 | ||||
| 	} | ||||
| 	w.writeInt(flags) | ||||
| 	n := 0 | ||||
| 	for a := s.Autom; a != nil; a = a.Link { | ||||
| 		n++ | ||||
| 	} | ||||
| 	w.writeInt(int64(n)) | ||||
| 	for a := s.Autom; a != nil; a = a.Link { | ||||
| 		w.writeRefIndex(a.Asym) | ||||
| 		w.writeInt(int64(a.Aoffset)) | ||||
| 		if a.Name == NAME_AUTO { | ||||
| 			w.writeInt(A_AUTO) | ||||
| 		} else if a.Name == NAME_PARAM { | ||||
| 			w.writeInt(A_PARAM) | ||||
| 		} else { | ||||
| 			log.Fatalf("%s: invalid local variable type %d", s.Name, a.Name) | ||||
| 		} | ||||
| 		w.writeRefIndex(a.Gotype) | ||||
| 	} | ||||
|  | ||||
| 	pc := s.Pcln | ||||
| 	w.writeInt(int64(len(pc.Pcsp.P))) | ||||
| 	w.writeInt(int64(len(pc.Pcfile.P))) | ||||
| 	w.writeInt(int64(len(pc.Pcline.P))) | ||||
| 	w.writeInt(int64(len(pc.Pcdata))) | ||||
| 	for i := 0; i < len(pc.Pcdata); i++ { | ||||
| 		w.writeInt(int64(len(pc.Pcdata[i].P))) | ||||
| 	} | ||||
| 	w.writeInt(int64(len(pc.Funcdataoff))) | ||||
| 	for i := 0; i < len(pc.Funcdataoff); i++ { | ||||
| 		w.writeRefIndex(pc.Funcdata[i]) | ||||
| 	} | ||||
| 	for i := 0; i < len(pc.Funcdataoff); i++ { | ||||
| 		w.writeInt(pc.Funcdataoff[i]) | ||||
| 	} | ||||
| 	w.writeInt(int64(len(pc.File))) | ||||
| 	for _, f := range pc.File { | ||||
| 		w.writeRefIndex(f) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (w *objWriter) writeInt(sval int64) { | ||||
| 	var v uint64 | ||||
| 	uv := (uint64(sval) << 1) ^ uint64(sval>>63) | ||||
| 	p := w.varintbuf[:] | ||||
| 	for v = uv; v >= 0x80; v >>= 7 { | ||||
| 		p[0] = uint8(v | 0x80) | ||||
| 		p = p[1:] | ||||
| 	} | ||||
| 	p[0] = uint8(v) | ||||
| 	p = p[1:] | ||||
| 	w.wr.Write(w.varintbuf[:len(w.varintbuf)-len(p)]) | ||||
| } | ||||
|  | ||||
| func (w *objWriter) writeString(s string) { | ||||
| 	w.writeInt(int64(len(s))) | ||||
| 	w.wr.WriteString(s) | ||||
| } | ||||
|  | ||||
| func (w *objWriter) writeRefIndex(s *LSym) { | ||||
| 	if s == nil { | ||||
| 		w.writeInt(0) | ||||
| 		return | ||||
| 	} | ||||
| 	if s.RefIdx == 0 { | ||||
| 		log.Fatalln("writing an unreferenced symbol", s.Name) | ||||
| 	} | ||||
| 	w.writeInt(int64(s.RefIdx)) | ||||
| } | ||||
|  | ||||
| // relocByOff sorts relocations by their offsets. | ||||
| type relocByOff []Reloc | ||||
|  | ||||
| func (x relocByOff) Len() int           { return len(x) } | ||||
| func (x relocByOff) Less(i, j int) bool { return x[i].Off < x[j].Off } | ||||
| func (x relocByOff) Swap(i, j int)      { x[i], x[j] = x[j], x[i] } | ||||
|  | ||||
| // implement dwarf.Context | ||||
| type dwCtxt struct{ *Link } | ||||
|  | ||||
| func (c dwCtxt) PtrSize() int { | ||||
| 	return c.Arch.PtrSize | ||||
| } | ||||
| func (c dwCtxt) AddInt(s dwarf.Sym, size int, i int64) { | ||||
| 	ls := s.(*LSym) | ||||
| 	ls.WriteInt(c.Link, ls.Size, size, i) | ||||
| } | ||||
| func (c dwCtxt) AddBytes(s dwarf.Sym, b []byte) { | ||||
| 	ls := s.(*LSym) | ||||
| 	ls.WriteBytes(c.Link, ls.Size, b) | ||||
| } | ||||
| func (c dwCtxt) AddString(s dwarf.Sym, v string) { | ||||
| 	ls := s.(*LSym) | ||||
| 	ls.WriteString(c.Link, ls.Size, len(v), v) | ||||
| 	ls.WriteInt(c.Link, ls.Size, 1, 0) | ||||
| } | ||||
| func (c dwCtxt) SymValue(s dwarf.Sym) int64 { | ||||
| 	return 0 | ||||
| } | ||||
| func (c dwCtxt) AddAddress(s dwarf.Sym, data interface{}, value int64) { | ||||
| 	rsym := data.(*LSym) | ||||
| 	ls := s.(*LSym) | ||||
| 	size := c.PtrSize() | ||||
| 	ls.WriteAddr(c.Link, ls.Size, size, rsym, value) | ||||
| } | ||||
| func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) { | ||||
| 	ls := s.(*LSym) | ||||
| 	rsym := t.(*LSym) | ||||
| 	ls.WriteAddr(c.Link, ls.Size, size, rsym, ofs) | ||||
| 	r := &ls.R[len(ls.R)-1] | ||||
| 	r.Type = R_DWARFREF | ||||
| } | ||||
|  | ||||
| func gendwarf(ctxt *Link, text []*LSym) []*LSym { | ||||
| 	dctxt := dwCtxt{ctxt} | ||||
| 	var dw []*LSym | ||||
|  | ||||
| 	for _, s := range text { | ||||
| 		dsym := Linklookup(ctxt, dwarf.InfoPrefix+s.Name, int(s.Version)) | ||||
| 		if dsym.Size != 0 { | ||||
| 			continue | ||||
| 		} | ||||
| 		dw = append(dw, dsym) | ||||
| 		dsym.Type = SDWARFINFO | ||||
| 		dsym.Set(AttrDuplicateOK, s.DuplicateOK()) | ||||
| 		var vars dwarf.Var | ||||
| 		var abbrev int | ||||
| 		var offs int32 | ||||
| 		for a := s.Autom; a != nil; a = a.Link { | ||||
| 			switch a.Name { | ||||
| 			case NAME_AUTO: | ||||
| 				abbrev = dwarf.DW_ABRV_AUTO | ||||
| 				offs = a.Aoffset | ||||
| 				if ctxt.FixedFrameSize() == 0 { | ||||
| 					offs -= int32(ctxt.Arch.PtrSize) | ||||
| 				} | ||||
| 				if Framepointer_enabled(GOOS, GOARCH) { | ||||
| 					offs -= int32(ctxt.Arch.PtrSize) | ||||
| 				} | ||||
|  | ||||
| 			case NAME_PARAM: | ||||
| 				abbrev = dwarf.DW_ABRV_PARAM | ||||
| 				offs = a.Aoffset + int32(ctxt.FixedFrameSize()) | ||||
|  | ||||
| 			default: | ||||
| 				continue | ||||
| 			} | ||||
| 			typename := dwarf.InfoPrefix + a.Gotype.Name[len("type."):] | ||||
| 			dwvar := &dwarf.Var{ | ||||
| 				Name:   a.Asym.Name, | ||||
| 				Abbrev: abbrev, | ||||
| 				Offset: int32(offs), | ||||
| 				Type:   Linklookup(ctxt, typename, 0), | ||||
| 			} | ||||
| 			dws := &vars.Link | ||||
| 			for ; *dws != nil; dws = &(*dws).Link { | ||||
| 				if offs <= (*dws).Offset { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			dwvar.Link = *dws | ||||
| 			*dws = dwvar | ||||
| 		} | ||||
| 		dwarf.PutFunc(dctxt, dsym, s.Name, s.Version == 0, s, s.Size, vars.Link) | ||||
| 	} | ||||
| 	return dw | ||||
| } | ||||
							
								
								
									
										217
									
								
								vendor/github.com/google/gops/internal/obj/pass.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								vendor/github.com/google/gops/internal/obj/pass.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,217 @@ | ||||
| // Inferno utils/6l/pass.c | ||||
| // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/pass.c | ||||
| // | ||||
| //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | ||||
| //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| //	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others | ||||
| //	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| // Code and data passes. | ||||
|  | ||||
| func Brchain(ctxt *Link, p *Prog) *Prog { | ||||
| 	for i := 0; i < 20; i++ { | ||||
| 		if p == nil || p.As != AJMP || p.Pcond == nil { | ||||
| 			return p | ||||
| 		} | ||||
| 		p = p.Pcond | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func brloop(ctxt *Link, p *Prog) *Prog { | ||||
| 	var q *Prog | ||||
|  | ||||
| 	c := 0 | ||||
| 	for q = p; q != nil; q = q.Pcond { | ||||
| 		if q.As != AJMP || q.Pcond == nil { | ||||
| 			break | ||||
| 		} | ||||
| 		c++ | ||||
| 		if c >= 5000 { | ||||
| 			return nil | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return q | ||||
| } | ||||
|  | ||||
| func checkaddr(ctxt *Link, p *Prog, a *Addr) { | ||||
| 	// Check expected encoding, especially TYPE_CONST vs TYPE_ADDR. | ||||
| 	switch a.Type { | ||||
| 	case TYPE_NONE: | ||||
| 		return | ||||
|  | ||||
| 	case TYPE_BRANCH: | ||||
| 		if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 { | ||||
| 			break | ||||
| 		} | ||||
| 		return | ||||
|  | ||||
| 	case TYPE_TEXTSIZE: | ||||
| 		if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 { | ||||
| 			break | ||||
| 		} | ||||
| 		return | ||||
|  | ||||
| 		//if(a->u.bits != 0) | ||||
| 	//	break; | ||||
| 	case TYPE_MEM: | ||||
| 		return | ||||
|  | ||||
| 		// TODO(rsc): After fixing SHRQ, check a->index != 0 too. | ||||
| 	case TYPE_CONST: | ||||
| 		if a.Name != 0 || a.Sym != nil || a.Reg != 0 { | ||||
| 			ctxt.Diag("argument is TYPE_CONST, should be TYPE_ADDR, in %v", p) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		if a.Reg != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.Val != nil { | ||||
| 			break | ||||
| 		} | ||||
| 		return | ||||
|  | ||||
| 	case TYPE_FCONST, TYPE_SCONST: | ||||
| 		if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Offset != 0 || a.Sym != nil { | ||||
| 			break | ||||
| 		} | ||||
| 		return | ||||
|  | ||||
| 	// TODO(rsc): After fixing PINSRQ, check a->offset != 0 too. | ||||
| 	// TODO(rsc): After fixing SHRQ, check a->index != 0 too. | ||||
| 	case TYPE_REG: | ||||
| 		if a.Scale != 0 || a.Name != 0 || a.Sym != nil { | ||||
| 			break | ||||
| 		} | ||||
| 		return | ||||
|  | ||||
| 	case TYPE_ADDR: | ||||
| 		if a.Val != nil { | ||||
| 			break | ||||
| 		} | ||||
| 		if a.Reg == 0 && a.Index == 0 && a.Scale == 0 && a.Name == 0 && a.Sym == nil { | ||||
| 			ctxt.Diag("argument is TYPE_ADDR, should be TYPE_CONST, in %v", p) | ||||
| 		} | ||||
| 		return | ||||
|  | ||||
| 	case TYPE_SHIFT: | ||||
| 		if a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.Val != nil { | ||||
| 			break | ||||
| 		} | ||||
| 		return | ||||
|  | ||||
| 	case TYPE_REGREG: | ||||
| 		if a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.Val != nil { | ||||
| 			break | ||||
| 		} | ||||
| 		return | ||||
|  | ||||
| 	case TYPE_REGREG2: | ||||
| 		return | ||||
|  | ||||
| 	case TYPE_REGLIST: | ||||
| 		return | ||||
|  | ||||
| 	// Expect sym and name to be set, nothing else. | ||||
| 	// Technically more is allowed, but this is only used for *name(SB). | ||||
| 	case TYPE_INDIR: | ||||
| 		if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name == 0 || a.Offset != 0 || a.Sym == nil || a.Val != nil { | ||||
| 			break | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	ctxt.Diag("invalid encoding for argument %v", p) | ||||
| } | ||||
|  | ||||
| func linkpatch(ctxt *Link, sym *LSym) { | ||||
| 	var c int32 | ||||
| 	var name string | ||||
| 	var q *Prog | ||||
|  | ||||
| 	ctxt.Cursym = sym | ||||
|  | ||||
| 	for p := sym.Text; p != nil; p = p.Link { | ||||
| 		checkaddr(ctxt, p, &p.From) | ||||
| 		if p.From3 != nil { | ||||
| 			checkaddr(ctxt, p, p.From3) | ||||
| 		} | ||||
| 		checkaddr(ctxt, p, &p.To) | ||||
|  | ||||
| 		if ctxt.Arch.Progedit != nil { | ||||
| 			ctxt.Arch.Progedit(ctxt, p) | ||||
| 		} | ||||
| 		if p.To.Type != TYPE_BRANCH { | ||||
| 			continue | ||||
| 		} | ||||
| 		if p.To.Val != nil { | ||||
| 			// TODO: Remove To.Val.(*Prog) in favor of p->pcond. | ||||
| 			p.Pcond = p.To.Val.(*Prog) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if p.To.Sym != nil { | ||||
| 			continue | ||||
| 		} | ||||
| 		c = int32(p.To.Offset) | ||||
| 		for q = sym.Text; q != nil; { | ||||
| 			if int64(c) == q.Pc { | ||||
| 				break | ||||
| 			} | ||||
| 			if q.Forwd != nil && int64(c) >= q.Forwd.Pc { | ||||
| 				q = q.Forwd | ||||
| 			} else { | ||||
| 				q = q.Link | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if q == nil { | ||||
| 			name = "<nil>" | ||||
| 			if p.To.Sym != nil { | ||||
| 				name = p.To.Sym.Name | ||||
| 			} | ||||
| 			ctxt.Diag("branch out of range (%#x)\n%v [%s]", uint32(c), p, name) | ||||
| 			p.To.Type = TYPE_NONE | ||||
| 		} | ||||
|  | ||||
| 		p.To.Val = q | ||||
| 		p.Pcond = q | ||||
| 	} | ||||
|  | ||||
| 	if ctxt.Flag_optimize { | ||||
| 		for p := sym.Text; p != nil; p = p.Link { | ||||
| 			if p.Pcond != nil { | ||||
| 				p.Pcond = brloop(ctxt, p.Pcond) | ||||
| 				if p.Pcond != nil { | ||||
| 					if p.To.Type == TYPE_BRANCH { | ||||
| 						p.To.Offset = p.Pcond.Pc | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										281
									
								
								vendor/github.com/google/gops/internal/obj/pcln.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								vendor/github.com/google/gops/internal/obj/pcln.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,281 @@ | ||||
| // Copyright 2013 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| import "log" | ||||
|  | ||||
| func addvarint(ctxt *Link, d *Pcdata, val uint32) { | ||||
| 	var v uint32 | ||||
| 	for v = val; v >= 0x80; v >>= 7 { | ||||
| 		d.P = append(d.P, uint8(v|0x80)) | ||||
| 	} | ||||
| 	d.P = append(d.P, uint8(v)) | ||||
| } | ||||
|  | ||||
| // funcpctab writes to dst a pc-value table mapping the code in func to the values | ||||
| // returned by valfunc parameterized by arg. The invocation of valfunc to update the | ||||
| // current value is, for each p, | ||||
| // | ||||
| //	val = valfunc(func, val, p, 0, arg); | ||||
| //	record val as value at p->pc; | ||||
| //	val = valfunc(func, val, p, 1, arg); | ||||
| // | ||||
| // where func is the function, val is the current value, p is the instruction being | ||||
| // considered, and arg can be used to further parameterize valfunc. | ||||
| func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*Link, *LSym, int32, *Prog, int32, interface{}) int32, arg interface{}) { | ||||
| 	// To debug a specific function, uncomment lines and change name. | ||||
| 	dbg := 0 | ||||
|  | ||||
| 	//if func_.Name == "main.main" || desc == "pctospadj" { | ||||
| 	//	dbg = 1 | ||||
| 	//} | ||||
|  | ||||
| 	ctxt.Debugpcln += int32(dbg) | ||||
|  | ||||
| 	dst.P = dst.P[:0] | ||||
|  | ||||
| 	if ctxt.Debugpcln != 0 { | ||||
| 		ctxt.Logf("funcpctab %s [valfunc=%s]\n", func_.Name, desc) | ||||
| 	} | ||||
|  | ||||
| 	val := int32(-1) | ||||
| 	oldval := val | ||||
| 	if func_.Text == nil { | ||||
| 		ctxt.Debugpcln -= int32(dbg) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	pc := func_.Text.Pc | ||||
|  | ||||
| 	if ctxt.Debugpcln != 0 { | ||||
| 		ctxt.Logf("%6x %6d %v\n", uint64(pc), val, func_.Text) | ||||
| 	} | ||||
|  | ||||
| 	started := int32(0) | ||||
| 	var delta uint32 | ||||
| 	for p := func_.Text; p != nil; p = p.Link { | ||||
| 		// Update val. If it's not changing, keep going. | ||||
| 		val = valfunc(ctxt, func_, val, p, 0, arg) | ||||
|  | ||||
| 		if val == oldval && started != 0 { | ||||
| 			val = valfunc(ctxt, func_, val, p, 1, arg) | ||||
| 			if ctxt.Debugpcln != 0 { | ||||
| 				ctxt.Logf("%6x %6s %v\n", uint64(p.Pc), "", p) | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		// If the pc of the next instruction is the same as the | ||||
| 		// pc of this instruction, this instruction is not a real | ||||
| 		// instruction. Keep going, so that we only emit a delta | ||||
| 		// for a true instruction boundary in the program. | ||||
| 		if p.Link != nil && p.Link.Pc == p.Pc { | ||||
| 			val = valfunc(ctxt, func_, val, p, 1, arg) | ||||
| 			if ctxt.Debugpcln != 0 { | ||||
| 				ctxt.Logf("%6x %6s %v\n", uint64(p.Pc), "", p) | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		// The table is a sequence of (value, pc) pairs, where each | ||||
| 		// pair states that the given value is in effect from the current position | ||||
| 		// up to the given pc, which becomes the new current position. | ||||
| 		// To generate the table as we scan over the program instructions, | ||||
| 		// we emit a "(value" when pc == func->value, and then | ||||
| 		// each time we observe a change in value we emit ", pc) (value". | ||||
| 		// When the scan is over, we emit the closing ", pc)". | ||||
| 		// | ||||
| 		// The table is delta-encoded. The value deltas are signed and | ||||
| 		// transmitted in zig-zag form, where a complement bit is placed in bit 0, | ||||
| 		// and the pc deltas are unsigned. Both kinds of deltas are sent | ||||
| 		// as variable-length little-endian base-128 integers, | ||||
| 		// where the 0x80 bit indicates that the integer continues. | ||||
|  | ||||
| 		if ctxt.Debugpcln != 0 { | ||||
| 			ctxt.Logf("%6x %6d %v\n", uint64(p.Pc), val, p) | ||||
| 		} | ||||
|  | ||||
| 		if started != 0 { | ||||
| 			addvarint(ctxt, dst, uint32((p.Pc-pc)/int64(ctxt.Arch.MinLC))) | ||||
| 			pc = p.Pc | ||||
| 		} | ||||
|  | ||||
| 		delta = uint32(val) - uint32(oldval) | ||||
| 		if delta>>31 != 0 { | ||||
| 			delta = 1 | ^(delta << 1) | ||||
| 		} else { | ||||
| 			delta <<= 1 | ||||
| 		} | ||||
| 		addvarint(ctxt, dst, delta) | ||||
| 		oldval = val | ||||
| 		started = 1 | ||||
| 		val = valfunc(ctxt, func_, val, p, 1, arg) | ||||
| 	} | ||||
|  | ||||
| 	if started != 0 { | ||||
| 		if ctxt.Debugpcln != 0 { | ||||
| 			ctxt.Logf("%6x done\n", uint64(func_.Text.Pc+func_.Size)) | ||||
| 		} | ||||
| 		addvarint(ctxt, dst, uint32((func_.Size-pc)/int64(ctxt.Arch.MinLC))) | ||||
| 		addvarint(ctxt, dst, 0) // terminator | ||||
| 	} | ||||
|  | ||||
| 	if ctxt.Debugpcln != 0 { | ||||
| 		ctxt.Logf("wrote %d bytes to %p\n", len(dst.P), dst) | ||||
| 		for i := 0; i < len(dst.P); i++ { | ||||
| 			ctxt.Logf(" %02x", dst.P[i]) | ||||
| 		} | ||||
| 		ctxt.Logf("\n") | ||||
| 	} | ||||
|  | ||||
| 	ctxt.Debugpcln -= int32(dbg) | ||||
| } | ||||
|  | ||||
| // pctofileline computes either the file number (arg == 0) | ||||
| // or the line number (arg == 1) to use at p. | ||||
| // Because p->lineno applies to p, phase == 0 (before p) | ||||
| // takes care of the update. | ||||
| func pctofileline(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 { | ||||
| 	if p.As == ATEXT || p.As == ANOP || p.As == AUSEFIELD || p.Lineno == 0 || phase == 1 { | ||||
| 		return oldval | ||||
| 	} | ||||
| 	f, l := linkgetline(ctxt, p.Lineno) | ||||
| 	if f == nil { | ||||
| 		//	print("getline failed for %s %v\n", ctxt->cursym->name, p); | ||||
| 		return oldval | ||||
| 	} | ||||
|  | ||||
| 	if arg == nil { | ||||
| 		return l | ||||
| 	} | ||||
| 	pcln := arg.(*Pcln) | ||||
|  | ||||
| 	if f == pcln.Lastfile { | ||||
| 		return int32(pcln.Lastindex) | ||||
| 	} | ||||
|  | ||||
| 	for i, file := range pcln.File { | ||||
| 		if file == f { | ||||
| 			pcln.Lastfile = f | ||||
| 			pcln.Lastindex = i | ||||
| 			return int32(i) | ||||
| 		} | ||||
| 	} | ||||
| 	i := len(pcln.File) | ||||
| 	pcln.File = append(pcln.File, f) | ||||
| 	pcln.Lastfile = f | ||||
| 	pcln.Lastindex = i | ||||
| 	return int32(i) | ||||
| } | ||||
|  | ||||
| // pctospadj computes the sp adjustment in effect. | ||||
| // It is oldval plus any adjustment made by p itself. | ||||
| // The adjustment by p takes effect only after p, so we | ||||
| // apply the change during phase == 1. | ||||
| func pctospadj(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 { | ||||
| 	if oldval == -1 { // starting | ||||
| 		oldval = 0 | ||||
| 	} | ||||
| 	if phase == 0 { | ||||
| 		return oldval | ||||
| 	} | ||||
| 	if oldval+p.Spadj < -10000 || oldval+p.Spadj > 1100000000 { | ||||
| 		ctxt.Diag("overflow in spadj: %d + %d = %d", oldval, p.Spadj, oldval+p.Spadj) | ||||
| 		log.Fatalf("bad code") | ||||
| 	} | ||||
|  | ||||
| 	return oldval + p.Spadj | ||||
| } | ||||
|  | ||||
| // pctopcdata computes the pcdata value in effect at p. | ||||
| // A PCDATA instruction sets the value in effect at future | ||||
| // non-PCDATA instructions. | ||||
| // Since PCDATA instructions have no width in the final code, | ||||
| // it does not matter which phase we use for the update. | ||||
| func pctopcdata(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 { | ||||
| 	if phase == 0 || p.As != APCDATA || p.From.Offset != int64(arg.(uint32)) { | ||||
| 		return oldval | ||||
| 	} | ||||
| 	if int64(int32(p.To.Offset)) != p.To.Offset { | ||||
| 		ctxt.Diag("overflow in PCDATA instruction: %v", p) | ||||
| 		log.Fatalf("bad code") | ||||
| 	} | ||||
|  | ||||
| 	return int32(p.To.Offset) | ||||
| } | ||||
|  | ||||
| func linkpcln(ctxt *Link, cursym *LSym) { | ||||
| 	ctxt.Cursym = cursym | ||||
|  | ||||
| 	pcln := new(Pcln) | ||||
| 	cursym.Pcln = pcln | ||||
|  | ||||
| 	npcdata := 0 | ||||
| 	nfuncdata := 0 | ||||
| 	for p := cursym.Text; p != nil; p = p.Link { | ||||
| 		// Find the highest ID of any used PCDATA table. This ignores PCDATA table | ||||
| 		// that consist entirely of "-1", since that's the assumed default value. | ||||
| 		//   From.Offset is table ID | ||||
| 		//   To.Offset is data | ||||
| 		if p.As == APCDATA && p.From.Offset >= int64(npcdata) && p.To.Offset != -1 { // ignore -1 as we start at -1, if we only see -1, nothing changed | ||||
| 			npcdata = int(p.From.Offset + 1) | ||||
| 		} | ||||
| 		// Find the highest ID of any FUNCDATA table. | ||||
| 		//   From.Offset is table ID | ||||
| 		if p.As == AFUNCDATA && p.From.Offset >= int64(nfuncdata) { | ||||
| 			nfuncdata = int(p.From.Offset + 1) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	pcln.Pcdata = make([]Pcdata, npcdata) | ||||
| 	pcln.Pcdata = pcln.Pcdata[:npcdata] | ||||
| 	pcln.Funcdata = make([]*LSym, nfuncdata) | ||||
| 	pcln.Funcdataoff = make([]int64, nfuncdata) | ||||
| 	pcln.Funcdataoff = pcln.Funcdataoff[:nfuncdata] | ||||
|  | ||||
| 	funcpctab(ctxt, &pcln.Pcsp, cursym, "pctospadj", pctospadj, nil) | ||||
| 	funcpctab(ctxt, &pcln.Pcfile, cursym, "pctofile", pctofileline, pcln) | ||||
| 	funcpctab(ctxt, &pcln.Pcline, cursym, "pctoline", pctofileline, nil) | ||||
|  | ||||
| 	// tabulate which pc and func data we have. | ||||
| 	havepc := make([]uint32, (npcdata+31)/32) | ||||
| 	havefunc := make([]uint32, (nfuncdata+31)/32) | ||||
| 	for p := cursym.Text; p != nil; p = p.Link { | ||||
| 		if p.As == AFUNCDATA { | ||||
| 			if (havefunc[p.From.Offset/32]>>uint64(p.From.Offset%32))&1 != 0 { | ||||
| 				ctxt.Diag("multiple definitions for FUNCDATA $%d", p.From.Offset) | ||||
| 			} | ||||
| 			havefunc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32) | ||||
| 		} | ||||
|  | ||||
| 		if p.As == APCDATA && p.To.Offset != -1 { | ||||
| 			havepc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// pcdata. | ||||
| 	for i := 0; i < npcdata; i++ { | ||||
| 		if (havepc[i/32]>>uint(i%32))&1 == 0 { | ||||
| 			continue | ||||
| 		} | ||||
| 		funcpctab(ctxt, &pcln.Pcdata[i], cursym, "pctopcdata", pctopcdata, interface{}(uint32(i))) | ||||
| 	} | ||||
|  | ||||
| 	// funcdata | ||||
| 	if nfuncdata > 0 { | ||||
| 		var i int | ||||
| 		for p := cursym.Text; p != nil; p = p.Link { | ||||
| 			if p.As == AFUNCDATA { | ||||
| 				i = int(p.From.Offset) | ||||
| 				pcln.Funcdataoff[i] = p.To.Offset | ||||
| 				if p.To.Type != TYPE_CONST { | ||||
| 					// TODO: Dedup. | ||||
| 					//funcdata_bytes += p->to.sym->size; | ||||
| 					pcln.Funcdata[i] = p.To.Sym | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										208
									
								
								vendor/github.com/google/gops/internal/obj/plist.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								vendor/github.com/google/gops/internal/obj/plist.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,208 @@ | ||||
| // Copyright 2013 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| type Plist struct { | ||||
| 	Firstpc *Prog | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * start a new Prog list. | ||||
|  */ | ||||
| func Linknewplist(ctxt *Link) *Plist { | ||||
| 	pl := new(Plist) | ||||
| 	ctxt.Plists = append(ctxt.Plists, pl) | ||||
| 	return pl | ||||
| } | ||||
|  | ||||
| func Flushplist(ctxt *Link) { | ||||
| 	flushplist(ctxt, ctxt.Debugasm == 0) | ||||
| } | ||||
| func FlushplistNoFree(ctxt *Link) { | ||||
| 	flushplist(ctxt, false) | ||||
| } | ||||
| func flushplist(ctxt *Link, freeProgs bool) { | ||||
| 	// Build list of symbols, and assign instructions to lists. | ||||
| 	// Ignore ctxt->plist boundaries. There are no guarantees there, | ||||
| 	// and the assemblers just use one big list. | ||||
| 	var curtext *LSym | ||||
| 	var etext *Prog | ||||
| 	var text []*LSym | ||||
|  | ||||
| 	for _, pl := range ctxt.Plists { | ||||
| 		var plink *Prog | ||||
| 		for p := pl.Firstpc; p != nil; p = plink { | ||||
| 			if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 { | ||||
| 				fmt.Printf("obj: %v\n", p) | ||||
| 			} | ||||
| 			plink = p.Link | ||||
| 			p.Link = nil | ||||
|  | ||||
| 			switch p.As { | ||||
| 			case AEND: | ||||
| 				continue | ||||
|  | ||||
| 			case ATYPE: | ||||
| 				// Assume each TYPE instruction describes | ||||
| 				// a different local variable or parameter, | ||||
| 				// so no dedup. | ||||
| 				// Using only the TYPE instructions means | ||||
| 				// that we discard location information about local variables | ||||
| 				// in C and assembly functions; that information is inferred | ||||
| 				// from ordinary references, because there are no TYPE | ||||
| 				// instructions there. Without the type information, gdb can't | ||||
| 				// use the locations, so we don't bother to save them. | ||||
| 				// If something else could use them, we could arrange to | ||||
| 				// preserve them. | ||||
| 				if curtext == nil { | ||||
| 					continue | ||||
| 				} | ||||
| 				a := new(Auto) | ||||
| 				a.Asym = p.From.Sym | ||||
| 				a.Aoffset = int32(p.From.Offset) | ||||
| 				a.Name = int16(p.From.Name) | ||||
| 				a.Gotype = p.To.Sym | ||||
| 				a.Link = curtext.Autom | ||||
| 				curtext.Autom = a | ||||
| 				continue | ||||
|  | ||||
| 			case ATEXT: | ||||
| 				s := p.From.Sym | ||||
| 				if s == nil { | ||||
| 					// func _() { } | ||||
| 					curtext = nil | ||||
|  | ||||
| 					continue | ||||
| 				} | ||||
|  | ||||
| 				if s.Text != nil { | ||||
| 					log.Fatalf("duplicate TEXT for %s", s.Name) | ||||
| 				} | ||||
| 				if s.OnList() { | ||||
| 					log.Fatalf("symbol %s listed multiple times", s.Name) | ||||
| 				} | ||||
| 				s.Set(AttrOnList, true) | ||||
| 				text = append(text, s) | ||||
| 				flag := int(p.From3Offset()) | ||||
| 				if flag&DUPOK != 0 { | ||||
| 					s.Set(AttrDuplicateOK, true) | ||||
| 				} | ||||
| 				if flag&NOSPLIT != 0 { | ||||
| 					s.Set(AttrNoSplit, true) | ||||
| 				} | ||||
| 				if flag&REFLECTMETHOD != 0 { | ||||
| 					s.Set(AttrReflectMethod, true) | ||||
| 				} | ||||
| 				s.Type = STEXT | ||||
| 				s.Text = p | ||||
| 				etext = p | ||||
| 				curtext = s | ||||
| 				continue | ||||
|  | ||||
| 			case AFUNCDATA: | ||||
| 				// Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information. | ||||
| 				if curtext == nil { // func _() {} | ||||
| 					continue | ||||
| 				} | ||||
| 				if p.To.Sym.Name == "go_args_stackmap" { | ||||
| 					if p.From.Type != TYPE_CONST || p.From.Offset != FUNCDATA_ArgsPointerMaps { | ||||
| 						ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps") | ||||
| 					} | ||||
| 					p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", curtext.Name), int(curtext.Version)) | ||||
| 				} | ||||
|  | ||||
| 			} | ||||
|  | ||||
| 			if curtext == nil { | ||||
| 				etext = nil | ||||
| 				continue | ||||
| 			} | ||||
| 			etext.Link = p | ||||
| 			etext = p | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Add reference to Go arguments for C or assembly functions without them. | ||||
| 	for _, s := range text { | ||||
| 		if !strings.HasPrefix(s.Name, "\"\".") { | ||||
| 			continue | ||||
| 		} | ||||
| 		found := false | ||||
| 		var p *Prog | ||||
| 		for p = s.Text; p != nil; p = p.Link { | ||||
| 			if p.As == AFUNCDATA && p.From.Type == TYPE_CONST && p.From.Offset == FUNCDATA_ArgsPointerMaps { | ||||
| 				found = true | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if !found { | ||||
| 			p = Appendp(ctxt, s.Text) | ||||
| 			p.As = AFUNCDATA | ||||
| 			p.From.Type = TYPE_CONST | ||||
| 			p.From.Offset = FUNCDATA_ArgsPointerMaps | ||||
| 			p.To.Type = TYPE_MEM | ||||
| 			p.To.Name = NAME_EXTERN | ||||
| 			p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", s.Name), int(s.Version)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Turn functions into machine code images. | ||||
| 	for _, s := range text { | ||||
| 		mkfwd(s) | ||||
| 		linkpatch(ctxt, s) | ||||
| 		if ctxt.Flag_optimize { | ||||
| 			ctxt.Arch.Follow(ctxt, s) | ||||
| 		} | ||||
| 		ctxt.Arch.Preprocess(ctxt, s) | ||||
| 		ctxt.Arch.Assemble(ctxt, s) | ||||
| 		fieldtrack(ctxt, s) | ||||
| 		linkpcln(ctxt, s) | ||||
| 		if freeProgs { | ||||
| 			s.Text = nil | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Add to running list in ctxt. | ||||
| 	ctxt.Text = append(ctxt.Text, text...) | ||||
| 	ctxt.Data = append(ctxt.Data, gendwarf(ctxt, text)...) | ||||
| 	ctxt.Plists = nil | ||||
| 	ctxt.Curp = nil | ||||
| 	if freeProgs { | ||||
| 		ctxt.freeProgs() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (ctxt *Link) Globl(s *LSym, size int64, flag int) { | ||||
| 	if s.SeenGlobl() { | ||||
| 		fmt.Printf("duplicate %v\n", s) | ||||
| 	} | ||||
| 	s.Set(AttrSeenGlobl, true) | ||||
| 	if s.OnList() { | ||||
| 		log.Fatalf("symbol %s listed multiple times", s.Name) | ||||
| 	} | ||||
| 	s.Set(AttrOnList, true) | ||||
| 	ctxt.Data = append(ctxt.Data, s) | ||||
| 	s.Size = size | ||||
| 	if s.Type == 0 || s.Type == SXREF { | ||||
| 		s.Type = SBSS | ||||
| 	} | ||||
| 	if flag&DUPOK != 0 { | ||||
| 		s.Set(AttrDuplicateOK, true) | ||||
| 	} | ||||
| 	if flag&RODATA != 0 { | ||||
| 		s.Type = SRODATA | ||||
| 	} else if flag&NOPTR != 0 { | ||||
| 		s.Type = SNOPTRBSS | ||||
| 	} else if flag&TLSBSS != 0 { | ||||
| 		s.Type = STLSBSS | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										941
									
								
								vendor/github.com/google/gops/internal/obj/ppc64/a.out.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										941
									
								
								vendor/github.com/google/gops/internal/obj/ppc64/a.out.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,941 @@ | ||||
| // cmd/9c/9.out.h from Vita Nuova. | ||||
| // | ||||
| //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | ||||
| //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| //	Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| //	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others | ||||
| //	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package ppc64 | ||||
|  | ||||
| import "github.com/google/gops/internal/obj" | ||||
|  | ||||
| //go:generate go run ../stringer.go -i $GOFILE -o anames.go -p ppc64 | ||||
|  | ||||
| /* | ||||
|  * powerpc 64 | ||||
|  */ | ||||
| const ( | ||||
| 	NSNAME = 8 | ||||
| 	NSYM   = 50 | ||||
| 	NREG   = 32 /* number of general registers */ | ||||
| 	NFREG  = 32 /* number of floating point registers */ | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	/* RBasePPC64 = 4096 */ | ||||
| 	/* R0=4096 ... R31=4127 */ | ||||
| 	REG_R0 = obj.RBasePPC64 + iota | ||||
| 	REG_R1 | ||||
| 	REG_R2 | ||||
| 	REG_R3 | ||||
| 	REG_R4 | ||||
| 	REG_R5 | ||||
| 	REG_R6 | ||||
| 	REG_R7 | ||||
| 	REG_R8 | ||||
| 	REG_R9 | ||||
| 	REG_R10 | ||||
| 	REG_R11 | ||||
| 	REG_R12 | ||||
| 	REG_R13 | ||||
| 	REG_R14 | ||||
| 	REG_R15 | ||||
| 	REG_R16 | ||||
| 	REG_R17 | ||||
| 	REG_R18 | ||||
| 	REG_R19 | ||||
| 	REG_R20 | ||||
| 	REG_R21 | ||||
| 	REG_R22 | ||||
| 	REG_R23 | ||||
| 	REG_R24 | ||||
| 	REG_R25 | ||||
| 	REG_R26 | ||||
| 	REG_R27 | ||||
| 	REG_R28 | ||||
| 	REG_R29 | ||||
| 	REG_R30 | ||||
| 	REG_R31 | ||||
|  | ||||
| 	/* F0=4128 ... F31=4159 */ | ||||
| 	REG_F0 | ||||
| 	REG_F1 | ||||
| 	REG_F2 | ||||
| 	REG_F3 | ||||
| 	REG_F4 | ||||
| 	REG_F5 | ||||
| 	REG_F6 | ||||
| 	REG_F7 | ||||
| 	REG_F8 | ||||
| 	REG_F9 | ||||
| 	REG_F10 | ||||
| 	REG_F11 | ||||
| 	REG_F12 | ||||
| 	REG_F13 | ||||
| 	REG_F14 | ||||
| 	REG_F15 | ||||
| 	REG_F16 | ||||
| 	REG_F17 | ||||
| 	REG_F18 | ||||
| 	REG_F19 | ||||
| 	REG_F20 | ||||
| 	REG_F21 | ||||
| 	REG_F22 | ||||
| 	REG_F23 | ||||
| 	REG_F24 | ||||
| 	REG_F25 | ||||
| 	REG_F26 | ||||
| 	REG_F27 | ||||
| 	REG_F28 | ||||
| 	REG_F29 | ||||
| 	REG_F30 | ||||
| 	REG_F31 | ||||
|  | ||||
| 	/* V0=4160 ... V31=4191 */ | ||||
| 	REG_V0 | ||||
| 	REG_V1 | ||||
| 	REG_V2 | ||||
| 	REG_V3 | ||||
| 	REG_V4 | ||||
| 	REG_V5 | ||||
| 	REG_V6 | ||||
| 	REG_V7 | ||||
| 	REG_V8 | ||||
| 	REG_V9 | ||||
| 	REG_V10 | ||||
| 	REG_V11 | ||||
| 	REG_V12 | ||||
| 	REG_V13 | ||||
| 	REG_V14 | ||||
| 	REG_V15 | ||||
| 	REG_V16 | ||||
| 	REG_V17 | ||||
| 	REG_V18 | ||||
| 	REG_V19 | ||||
| 	REG_V20 | ||||
| 	REG_V21 | ||||
| 	REG_V22 | ||||
| 	REG_V23 | ||||
| 	REG_V24 | ||||
| 	REG_V25 | ||||
| 	REG_V26 | ||||
| 	REG_V27 | ||||
| 	REG_V28 | ||||
| 	REG_V29 | ||||
| 	REG_V30 | ||||
| 	REG_V31 | ||||
|  | ||||
| 	/* VS0=4192 ... VS63=4255 */ | ||||
| 	REG_VS0 | ||||
| 	REG_VS1 | ||||
| 	REG_VS2 | ||||
| 	REG_VS3 | ||||
| 	REG_VS4 | ||||
| 	REG_VS5 | ||||
| 	REG_VS6 | ||||
| 	REG_VS7 | ||||
| 	REG_VS8 | ||||
| 	REG_VS9 | ||||
| 	REG_VS10 | ||||
| 	REG_VS11 | ||||
| 	REG_VS12 | ||||
| 	REG_VS13 | ||||
| 	REG_VS14 | ||||
| 	REG_VS15 | ||||
| 	REG_VS16 | ||||
| 	REG_VS17 | ||||
| 	REG_VS18 | ||||
| 	REG_VS19 | ||||
| 	REG_VS20 | ||||
| 	REG_VS21 | ||||
| 	REG_VS22 | ||||
| 	REG_VS23 | ||||
| 	REG_VS24 | ||||
| 	REG_VS25 | ||||
| 	REG_VS26 | ||||
| 	REG_VS27 | ||||
| 	REG_VS28 | ||||
| 	REG_VS29 | ||||
| 	REG_VS30 | ||||
| 	REG_VS31 | ||||
| 	REG_VS32 | ||||
| 	REG_VS33 | ||||
| 	REG_VS34 | ||||
| 	REG_VS35 | ||||
| 	REG_VS36 | ||||
| 	REG_VS37 | ||||
| 	REG_VS38 | ||||
| 	REG_VS39 | ||||
| 	REG_VS40 | ||||
| 	REG_VS41 | ||||
| 	REG_VS42 | ||||
| 	REG_VS43 | ||||
| 	REG_VS44 | ||||
| 	REG_VS45 | ||||
| 	REG_VS46 | ||||
| 	REG_VS47 | ||||
| 	REG_VS48 | ||||
| 	REG_VS49 | ||||
| 	REG_VS50 | ||||
| 	REG_VS51 | ||||
| 	REG_VS52 | ||||
| 	REG_VS53 | ||||
| 	REG_VS54 | ||||
| 	REG_VS55 | ||||
| 	REG_VS56 | ||||
| 	REG_VS57 | ||||
| 	REG_VS58 | ||||
| 	REG_VS59 | ||||
| 	REG_VS60 | ||||
| 	REG_VS61 | ||||
| 	REG_VS62 | ||||
| 	REG_VS63 | ||||
|  | ||||
| 	REG_CR0 | ||||
| 	REG_CR1 | ||||
| 	REG_CR2 | ||||
| 	REG_CR3 | ||||
| 	REG_CR4 | ||||
| 	REG_CR5 | ||||
| 	REG_CR6 | ||||
| 	REG_CR7 | ||||
|  | ||||
| 	REG_MSR | ||||
| 	REG_FPSCR | ||||
| 	REG_CR | ||||
|  | ||||
| 	REG_SPECIAL = REG_CR0 | ||||
|  | ||||
| 	REG_SPR0 = obj.RBasePPC64 + 1024 // first of 1024 registers | ||||
| 	REG_DCR0 = obj.RBasePPC64 + 2048 // first of 1024 registers | ||||
|  | ||||
| 	REG_XER = REG_SPR0 + 1 | ||||
| 	REG_LR  = REG_SPR0 + 8 | ||||
| 	REG_CTR = REG_SPR0 + 9 | ||||
|  | ||||
| 	REGZERO = REG_R0 /* set to zero */ | ||||
| 	REGSP   = REG_R1 | ||||
| 	REGSB   = REG_R2 | ||||
| 	REGRET  = REG_R3 | ||||
| 	REGARG  = -1      /* -1 disables passing the first argument in register */ | ||||
| 	REGRT1  = REG_R3  /* reserved for runtime, duffzero and duffcopy */ | ||||
| 	REGRT2  = REG_R4  /* reserved for runtime, duffcopy */ | ||||
| 	REGMIN  = REG_R7  /* register variables allocated from here to REGMAX */ | ||||
| 	REGCTXT = REG_R11 /* context for closures */ | ||||
| 	REGTLS  = REG_R13 /* C ABI TLS base pointer */ | ||||
| 	REGMAX  = REG_R27 | ||||
| 	REGEXT  = REG_R30 /* external registers allocated from here down */ | ||||
| 	REGG    = REG_R30 /* G */ | ||||
| 	REGTMP  = REG_R31 /* used by the linker */ | ||||
| 	FREGRET = REG_F0 | ||||
| 	FREGMIN = REG_F17 /* first register variable */ | ||||
| 	FREGMAX = REG_F26 /* last register variable for 9g only */ | ||||
| 	FREGEXT = REG_F26 /* first external register */ | ||||
| ) | ||||
|  | ||||
| /* | ||||
|  * GENERAL: | ||||
|  * | ||||
|  * compiler allocates R3 up as temps | ||||
|  * compiler allocates register variables R7-R27 | ||||
|  * compiler allocates external registers R30 down | ||||
|  * | ||||
|  * compiler allocates register variables F17-F26 | ||||
|  * compiler allocates external registers F26 down | ||||
|  */ | ||||
| const ( | ||||
| 	BIG = 32768 - 8 | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	/* mark flags */ | ||||
| 	LABEL   = 1 << 0 | ||||
| 	LEAF    = 1 << 1 | ||||
| 	FLOAT   = 1 << 2 | ||||
| 	BRANCH  = 1 << 3 | ||||
| 	LOAD    = 1 << 4 | ||||
| 	FCMP    = 1 << 5 | ||||
| 	SYNC    = 1 << 6 | ||||
| 	LIST    = 1 << 7 | ||||
| 	FOLL    = 1 << 8 | ||||
| 	NOSCHED = 1 << 9 | ||||
| ) | ||||
|  | ||||
| // Values for use in branch instruction BC | ||||
| // BC B0,BI,label | ||||
| // BO is type of branch + likely bits described below | ||||
| // BI is CR value + branch type | ||||
| // ex: BEQ CR2,label is BC 12,10,label | ||||
| //   12 = BO_BCR | ||||
| //   10 = BI_CR2 + BI_EQ | ||||
|  | ||||
| const ( | ||||
| 	BI_CR0 = 0 | ||||
| 	BI_CR1 = 4 | ||||
| 	BI_CR2 = 8 | ||||
| 	BI_CR3 = 12 | ||||
| 	BI_CR4 = 16 | ||||
| 	BI_CR5 = 20 | ||||
| 	BI_CR6 = 24 | ||||
| 	BI_CR7 = 28 | ||||
| 	BI_LT  = 0 | ||||
| 	BI_GT  = 1 | ||||
| 	BI_EQ  = 2 | ||||
| 	BI_OVF = 3 | ||||
| ) | ||||
|  | ||||
| // Values for the BO field.  Add the branch type to | ||||
| // the likely bits, if a likely setting is known. | ||||
| // If branch likely or unlikely is not known, don't set it. | ||||
| // e.g. branch on cr+likely = 15 | ||||
|  | ||||
| const ( | ||||
| 	BO_BCTR     = 16 // branch on ctr value | ||||
| 	BO_BCR      = 12 // branch on cr value | ||||
| 	BO_BCRBCTR  = 8  // branch on ctr and cr value | ||||
| 	BO_NOTBCR   = 4  // branch on not cr value | ||||
| 	BO_UNLIKELY = 2  // value for unlikely | ||||
| 	BO_LIKELY   = 3  // value for likely | ||||
| ) | ||||
|  | ||||
| // Bit settings from the CR | ||||
|  | ||||
| const ( | ||||
| 	C_COND_LT = iota // 0 result is negative | ||||
| 	C_COND_GT        // 1 result is positive | ||||
| 	C_COND_EQ        // 2 result is zero | ||||
| 	C_COND_SO        // 3 summary overflow or FP compare w/ NaN | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	C_NONE = iota | ||||
| 	C_REG | ||||
| 	C_FREG | ||||
| 	C_VREG | ||||
| 	C_VSREG | ||||
| 	C_CREG | ||||
| 	C_SPR /* special processor register */ | ||||
| 	C_ZCON | ||||
| 	C_SCON   /* 16 bit signed */ | ||||
| 	C_UCON   /* 32 bit signed, low 16 bits 0 */ | ||||
| 	C_ADDCON /* -0x8000 <= v < 0 */ | ||||
| 	C_ANDCON /* 0 < v <= 0xFFFF */ | ||||
| 	C_LCON   /* other 32 */ | ||||
| 	C_DCON   /* other 64 (could subdivide further) */ | ||||
| 	C_SACON  /* $n(REG) where n <= int16 */ | ||||
| 	C_SECON | ||||
| 	C_LACON /* $n(REG) where int16 < n <= int32 */ | ||||
| 	C_LECON | ||||
| 	C_DACON /* $n(REG) where int32 < n */ | ||||
| 	C_SBRA | ||||
| 	C_LBRA | ||||
| 	C_LBRAPIC | ||||
| 	C_SAUTO | ||||
| 	C_LAUTO | ||||
| 	C_SEXT | ||||
| 	C_LEXT | ||||
| 	C_ZOREG // conjecture: either (1) register + zeroed offset, or (2) "R0" implies zero or C_REG | ||||
| 	C_SOREG // register + signed offset | ||||
| 	C_LOREG | ||||
| 	C_FPSCR | ||||
| 	C_MSR | ||||
| 	C_XER | ||||
| 	C_LR | ||||
| 	C_CTR | ||||
| 	C_ANY | ||||
| 	C_GOK | ||||
| 	C_ADDR | ||||
| 	C_GOTADDR | ||||
| 	C_TLS_LE | ||||
| 	C_TLS_IE | ||||
| 	C_TEXTSIZE | ||||
|  | ||||
| 	C_NCLASS /* must be the last */ | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	AADD = obj.ABasePPC64 + obj.A_ARCHSPECIFIC + iota | ||||
| 	AADDCC | ||||
| 	AADDV | ||||
| 	AADDVCC | ||||
| 	AADDC | ||||
| 	AADDCCC | ||||
| 	AADDCV | ||||
| 	AADDCVCC | ||||
| 	AADDME | ||||
| 	AADDMECC | ||||
| 	AADDMEVCC | ||||
| 	AADDMEV | ||||
| 	AADDE | ||||
| 	AADDECC | ||||
| 	AADDEVCC | ||||
| 	AADDEV | ||||
| 	AADDZE | ||||
| 	AADDZECC | ||||
| 	AADDZEVCC | ||||
| 	AADDZEV | ||||
| 	AAND | ||||
| 	AANDCC | ||||
| 	AANDN | ||||
| 	AANDNCC | ||||
| 	ABC | ||||
| 	ABCL | ||||
| 	ABEQ | ||||
| 	ABGE // not LT = G/E/U | ||||
| 	ABGT | ||||
| 	ABLE // not GT = L/E/U | ||||
| 	ABLT | ||||
| 	ABNE // not EQ = L/G/U | ||||
| 	ABVC // Unordered-clear | ||||
| 	ABVS // Unordered-set | ||||
| 	ACMP | ||||
| 	ACMPU | ||||
| 	ACNTLZW | ||||
| 	ACNTLZWCC | ||||
| 	ACRAND | ||||
| 	ACRANDN | ||||
| 	ACREQV | ||||
| 	ACRNAND | ||||
| 	ACRNOR | ||||
| 	ACROR | ||||
| 	ACRORN | ||||
| 	ACRXOR | ||||
| 	ADIVW | ||||
| 	ADIVWCC | ||||
| 	ADIVWVCC | ||||
| 	ADIVWV | ||||
| 	ADIVWU | ||||
| 	ADIVWUCC | ||||
| 	ADIVWUVCC | ||||
| 	ADIVWUV | ||||
| 	AEQV | ||||
| 	AEQVCC | ||||
| 	AEXTSB | ||||
| 	AEXTSBCC | ||||
| 	AEXTSH | ||||
| 	AEXTSHCC | ||||
| 	AFABS | ||||
| 	AFABSCC | ||||
| 	AFADD | ||||
| 	AFADDCC | ||||
| 	AFADDS | ||||
| 	AFADDSCC | ||||
| 	AFCMPO | ||||
| 	AFCMPU | ||||
| 	AFCTIW | ||||
| 	AFCTIWCC | ||||
| 	AFCTIWZ | ||||
| 	AFCTIWZCC | ||||
| 	AFDIV | ||||
| 	AFDIVCC | ||||
| 	AFDIVS | ||||
| 	AFDIVSCC | ||||
| 	AFMADD | ||||
| 	AFMADDCC | ||||
| 	AFMADDS | ||||
| 	AFMADDSCC | ||||
| 	AFMOVD | ||||
| 	AFMOVDCC | ||||
| 	AFMOVDU | ||||
| 	AFMOVS | ||||
| 	AFMOVSU | ||||
| 	AFMOVSX | ||||
| 	AFMOVSZ | ||||
| 	AFMSUB | ||||
| 	AFMSUBCC | ||||
| 	AFMSUBS | ||||
| 	AFMSUBSCC | ||||
| 	AFMUL | ||||
| 	AFMULCC | ||||
| 	AFMULS | ||||
| 	AFMULSCC | ||||
| 	AFNABS | ||||
| 	AFNABSCC | ||||
| 	AFNEG | ||||
| 	AFNEGCC | ||||
| 	AFNMADD | ||||
| 	AFNMADDCC | ||||
| 	AFNMADDS | ||||
| 	AFNMADDSCC | ||||
| 	AFNMSUB | ||||
| 	AFNMSUBCC | ||||
| 	AFNMSUBS | ||||
| 	AFNMSUBSCC | ||||
| 	AFRSP | ||||
| 	AFRSPCC | ||||
| 	AFSUB | ||||
| 	AFSUBCC | ||||
| 	AFSUBS | ||||
| 	AFSUBSCC | ||||
| 	AISEL | ||||
| 	AMOVMW | ||||
| 	ALBAR | ||||
| 	ALSW | ||||
| 	ALWAR | ||||
| 	ALWSYNC | ||||
| 	AMOVDBR | ||||
| 	AMOVWBR | ||||
| 	AMOVB | ||||
| 	AMOVBU | ||||
| 	AMOVBZ | ||||
| 	AMOVBZU | ||||
| 	AMOVH | ||||
| 	AMOVHBR | ||||
| 	AMOVHU | ||||
| 	AMOVHZ | ||||
| 	AMOVHZU | ||||
| 	AMOVW | ||||
| 	AMOVWU | ||||
| 	AMOVFL | ||||
| 	AMOVCRFS | ||||
| 	AMTFSB0 | ||||
| 	AMTFSB0CC | ||||
| 	AMTFSB1 | ||||
| 	AMTFSB1CC | ||||
| 	AMULHW | ||||
| 	AMULHWCC | ||||
| 	AMULHWU | ||||
| 	AMULHWUCC | ||||
| 	AMULLW | ||||
| 	AMULLWCC | ||||
| 	AMULLWVCC | ||||
| 	AMULLWV | ||||
| 	ANAND | ||||
| 	ANANDCC | ||||
| 	ANEG | ||||
| 	ANEGCC | ||||
| 	ANEGVCC | ||||
| 	ANEGV | ||||
| 	ANOR | ||||
| 	ANORCC | ||||
| 	AOR | ||||
| 	AORCC | ||||
| 	AORN | ||||
| 	AORNCC | ||||
| 	AREM | ||||
| 	AREMCC | ||||
| 	AREMV | ||||
| 	AREMVCC | ||||
| 	AREMU | ||||
| 	AREMUCC | ||||
| 	AREMUV | ||||
| 	AREMUVCC | ||||
| 	ARFI | ||||
| 	ARLWMI | ||||
| 	ARLWMICC | ||||
| 	ARLWNM | ||||
| 	ARLWNMCC | ||||
| 	ASLW | ||||
| 	ASLWCC | ||||
| 	ASRW | ||||
| 	ASRAW | ||||
| 	ASRAWCC | ||||
| 	ASRWCC | ||||
| 	ASTBCCC | ||||
| 	ASTSW | ||||
| 	ASTWCCC | ||||
| 	ASUB | ||||
| 	ASUBCC | ||||
| 	ASUBVCC | ||||
| 	ASUBC | ||||
| 	ASUBCCC | ||||
| 	ASUBCV | ||||
| 	ASUBCVCC | ||||
| 	ASUBME | ||||
| 	ASUBMECC | ||||
| 	ASUBMEVCC | ||||
| 	ASUBMEV | ||||
| 	ASUBV | ||||
| 	ASUBE | ||||
| 	ASUBECC | ||||
| 	ASUBEV | ||||
| 	ASUBEVCC | ||||
| 	ASUBZE | ||||
| 	ASUBZECC | ||||
| 	ASUBZEVCC | ||||
| 	ASUBZEV | ||||
| 	ASYNC | ||||
| 	AXOR | ||||
| 	AXORCC | ||||
|  | ||||
| 	ADCBF | ||||
| 	ADCBI | ||||
| 	ADCBST | ||||
| 	ADCBT | ||||
| 	ADCBTST | ||||
| 	ADCBZ | ||||
| 	AECIWX | ||||
| 	AECOWX | ||||
| 	AEIEIO | ||||
| 	AICBI | ||||
| 	AISYNC | ||||
| 	APTESYNC | ||||
| 	ATLBIE | ||||
| 	ATLBIEL | ||||
| 	ATLBSYNC | ||||
| 	ATW | ||||
|  | ||||
| 	ASYSCALL | ||||
| 	AWORD | ||||
|  | ||||
| 	ARFCI | ||||
|  | ||||
| 	/* optional on 32-bit */ | ||||
| 	AFRES | ||||
| 	AFRESCC | ||||
| 	AFRIM | ||||
| 	AFRIMCC | ||||
| 	AFRIP | ||||
| 	AFRIPCC | ||||
| 	AFRIZ | ||||
| 	AFRIZCC | ||||
| 	AFRSQRTE | ||||
| 	AFRSQRTECC | ||||
| 	AFSEL | ||||
| 	AFSELCC | ||||
| 	AFSQRT | ||||
| 	AFSQRTCC | ||||
| 	AFSQRTS | ||||
| 	AFSQRTSCC | ||||
|  | ||||
| 	/* 64-bit */ | ||||
|  | ||||
| 	ACNTLZD | ||||
| 	ACNTLZDCC | ||||
| 	ACMPW /* CMP with L=0 */ | ||||
| 	ACMPWU | ||||
| 	ADIVD | ||||
| 	ADIVDCC | ||||
| 	ADIVDE | ||||
| 	ADIVDECC | ||||
| 	ADIVDEU | ||||
| 	ADIVDEUCC | ||||
| 	ADIVDVCC | ||||
| 	ADIVDV | ||||
| 	ADIVDU | ||||
| 	ADIVDUCC | ||||
| 	ADIVDUVCC | ||||
| 	ADIVDUV | ||||
| 	AEXTSW | ||||
| 	AEXTSWCC | ||||
| 	/* AFCFIW; AFCFIWCC */ | ||||
| 	AFCFID | ||||
| 	AFCFIDCC | ||||
| 	AFCFIDU | ||||
| 	AFCFIDUCC | ||||
| 	AFCTID | ||||
| 	AFCTIDCC | ||||
| 	AFCTIDZ | ||||
| 	AFCTIDZCC | ||||
| 	ALDAR | ||||
| 	AMOVD | ||||
| 	AMOVDU | ||||
| 	AMOVWZ | ||||
| 	AMOVWZU | ||||
| 	AMULHD | ||||
| 	AMULHDCC | ||||
| 	AMULHDU | ||||
| 	AMULHDUCC | ||||
| 	AMULLD | ||||
| 	AMULLDCC | ||||
| 	AMULLDVCC | ||||
| 	AMULLDV | ||||
| 	ARFID | ||||
| 	ARLDMI | ||||
| 	ARLDMICC | ||||
| 	ARLDIMI | ||||
| 	ARLDIMICC | ||||
| 	ARLDC | ||||
| 	ARLDCCC | ||||
| 	ARLDCR | ||||
| 	ARLDCRCC | ||||
| 	ARLDICR | ||||
| 	ARLDICRCC | ||||
| 	ARLDCL | ||||
| 	ARLDCLCC | ||||
| 	ARLDICL | ||||
| 	ARLDICLCC | ||||
| 	ASLBIA | ||||
| 	ASLBIE | ||||
| 	ASLBMFEE | ||||
| 	ASLBMFEV | ||||
| 	ASLBMTE | ||||
| 	ASLD | ||||
| 	ASLDCC | ||||
| 	ASRD | ||||
| 	ASRAD | ||||
| 	ASRADCC | ||||
| 	ASRDCC | ||||
| 	ASTDCCC | ||||
| 	ATD | ||||
|  | ||||
| 	/* 64-bit pseudo operation */ | ||||
| 	ADWORD | ||||
| 	AREMD | ||||
| 	AREMDCC | ||||
| 	AREMDV | ||||
| 	AREMDVCC | ||||
| 	AREMDU | ||||
| 	AREMDUCC | ||||
| 	AREMDUV | ||||
| 	AREMDUVCC | ||||
|  | ||||
| 	/* more 64-bit operations */ | ||||
| 	AHRFID | ||||
|  | ||||
| 	/* Vector */ | ||||
| 	ALV | ||||
| 	ALVEBX | ||||
| 	ALVEHX | ||||
| 	ALVEWX | ||||
| 	ALVX | ||||
| 	ALVXL | ||||
| 	ALVSL | ||||
| 	ALVSR | ||||
| 	ASTV | ||||
| 	ASTVEBX | ||||
| 	ASTVEHX | ||||
| 	ASTVEWX | ||||
| 	ASTVX | ||||
| 	ASTVXL | ||||
| 	AVAND | ||||
| 	AVANDL | ||||
| 	AVANDC | ||||
| 	AVNAND | ||||
| 	AVOR | ||||
| 	AVORL | ||||
| 	AVORC | ||||
| 	AVNOR | ||||
| 	AVXOR | ||||
| 	AVEQV | ||||
| 	AVADDUM | ||||
| 	AVADDUBM | ||||
| 	AVADDUHM | ||||
| 	AVADDUWM | ||||
| 	AVADDUDM | ||||
| 	AVADDUQM | ||||
| 	AVADDCU | ||||
| 	AVADDCUQ | ||||
| 	AVADDCUW | ||||
| 	AVADDUS | ||||
| 	AVADDUBS | ||||
| 	AVADDUHS | ||||
| 	AVADDUWS | ||||
| 	AVADDSS | ||||
| 	AVADDSBS | ||||
| 	AVADDSHS | ||||
| 	AVADDSWS | ||||
| 	AVADDE | ||||
| 	AVADDEUQM | ||||
| 	AVADDECUQ | ||||
| 	AVSUBUM | ||||
| 	AVSUBUBM | ||||
| 	AVSUBUHM | ||||
| 	AVSUBUWM | ||||
| 	AVSUBUDM | ||||
| 	AVSUBUQM | ||||
| 	AVSUBCU | ||||
| 	AVSUBCUQ | ||||
| 	AVSUBCUW | ||||
| 	AVSUBUS | ||||
| 	AVSUBUBS | ||||
| 	AVSUBUHS | ||||
| 	AVSUBUWS | ||||
| 	AVSUBSS | ||||
| 	AVSUBSBS | ||||
| 	AVSUBSHS | ||||
| 	AVSUBSWS | ||||
| 	AVSUBE | ||||
| 	AVSUBEUQM | ||||
| 	AVSUBECUQ | ||||
| 	AVR | ||||
| 	AVRLB | ||||
| 	AVRLH | ||||
| 	AVRLW | ||||
| 	AVRLD | ||||
| 	AVS | ||||
| 	AVSLB | ||||
| 	AVSLH | ||||
| 	AVSLW | ||||
| 	AVSL | ||||
| 	AVSLO | ||||
| 	AVSRB | ||||
| 	AVSRH | ||||
| 	AVSRW | ||||
| 	AVSR | ||||
| 	AVSRO | ||||
| 	AVSLD | ||||
| 	AVSRD | ||||
| 	AVSA | ||||
| 	AVSRAB | ||||
| 	AVSRAH | ||||
| 	AVSRAW | ||||
| 	AVSRAD | ||||
| 	AVSOI | ||||
| 	AVSLDOI | ||||
| 	AVCLZ | ||||
| 	AVCLZB | ||||
| 	AVCLZH | ||||
| 	AVCLZW | ||||
| 	AVCLZD | ||||
| 	AVPOPCNT | ||||
| 	AVPOPCNTB | ||||
| 	AVPOPCNTH | ||||
| 	AVPOPCNTW | ||||
| 	AVPOPCNTD | ||||
| 	AVCMPEQ | ||||
| 	AVCMPEQUB | ||||
| 	AVCMPEQUBCC | ||||
| 	AVCMPEQUH | ||||
| 	AVCMPEQUHCC | ||||
| 	AVCMPEQUW | ||||
| 	AVCMPEQUWCC | ||||
| 	AVCMPEQUD | ||||
| 	AVCMPEQUDCC | ||||
| 	AVCMPGT | ||||
| 	AVCMPGTUB | ||||
| 	AVCMPGTUBCC | ||||
| 	AVCMPGTUH | ||||
| 	AVCMPGTUHCC | ||||
| 	AVCMPGTUW | ||||
| 	AVCMPGTUWCC | ||||
| 	AVCMPGTUD | ||||
| 	AVCMPGTUDCC | ||||
| 	AVCMPGTSB | ||||
| 	AVCMPGTSBCC | ||||
| 	AVCMPGTSH | ||||
| 	AVCMPGTSHCC | ||||
| 	AVCMPGTSW | ||||
| 	AVCMPGTSWCC | ||||
| 	AVCMPGTSD | ||||
| 	AVCMPGTSDCC | ||||
| 	AVPERM | ||||
| 	AVSEL | ||||
| 	AVSPLT | ||||
| 	AVSPLTB | ||||
| 	AVSPLTH | ||||
| 	AVSPLTW | ||||
| 	AVSPLTI | ||||
| 	AVSPLTISB | ||||
| 	AVSPLTISH | ||||
| 	AVSPLTISW | ||||
| 	AVCIPH | ||||
| 	AVCIPHER | ||||
| 	AVCIPHERLAST | ||||
| 	AVNCIPH | ||||
| 	AVNCIPHER | ||||
| 	AVNCIPHERLAST | ||||
| 	AVSBOX | ||||
| 	AVSHASIGMA | ||||
| 	AVSHASIGMAW | ||||
| 	AVSHASIGMAD | ||||
|  | ||||
| 	/* VSX */ | ||||
| 	ALXV | ||||
| 	ALXVD2X | ||||
| 	ALXVDSX | ||||
| 	ALXVW4X | ||||
| 	ASTXV | ||||
| 	ASTXVD2X | ||||
| 	ASTXVW4X | ||||
| 	ALXS | ||||
| 	ALXSDX | ||||
| 	ASTXS | ||||
| 	ASTXSDX | ||||
| 	ALXSI | ||||
| 	ALXSIWAX | ||||
| 	ALXSIWZX | ||||
| 	ASTXSI | ||||
| 	ASTXSIWX | ||||
| 	AMFVSR | ||||
| 	AMFVSRD | ||||
| 	AMFVSRWZ | ||||
| 	AMTVSR | ||||
| 	AMTVSRD | ||||
| 	AMTVSRWA | ||||
| 	AMTVSRWZ | ||||
| 	AXXLAND | ||||
| 	AXXLANDQ | ||||
| 	AXXLANDC | ||||
| 	AXXLEQV | ||||
| 	AXXLNAND | ||||
| 	AXXLOR | ||||
| 	AXXLORC | ||||
| 	AXXLNOR | ||||
| 	AXXLORQ | ||||
| 	AXXLXOR | ||||
| 	AXXSEL | ||||
| 	AXXMRG | ||||
| 	AXXMRGHW | ||||
| 	AXXMRGLW | ||||
| 	AXXSPLT | ||||
| 	AXXSPLTW | ||||
| 	AXXPERM | ||||
| 	AXXPERMDI | ||||
| 	AXXSI | ||||
| 	AXXSLDWI | ||||
| 	AXSCV | ||||
| 	AXSCVDPSP | ||||
| 	AXSCVSPDP | ||||
| 	AXSCVDPSPN | ||||
| 	AXSCVSPDPN | ||||
| 	AXVCV | ||||
| 	AXVCVDPSP | ||||
| 	AXVCVSPDP | ||||
| 	AXSCVX | ||||
| 	AXSCVDPSXDS | ||||
| 	AXSCVDPSXWS | ||||
| 	AXSCVDPUXDS | ||||
| 	AXSCVDPUXWS | ||||
| 	AXSCVXP | ||||
| 	AXSCVSXDDP | ||||
| 	AXSCVUXDDP | ||||
| 	AXSCVSXDSP | ||||
| 	AXSCVUXDSP | ||||
| 	AXVCVX | ||||
| 	AXVCVDPSXDS | ||||
| 	AXVCVDPSXWS | ||||
| 	AXVCVDPUXDS | ||||
| 	AXVCVDPUXWS | ||||
| 	AXVCVSPSXDS | ||||
| 	AXVCVSPSXWS | ||||
| 	AXVCVSPUXDS | ||||
| 	AXVCVSPUXWS | ||||
| 	AXVCVXP | ||||
| 	AXVCVSXDDP | ||||
| 	AXVCVSXWDP | ||||
| 	AXVCVUXDDP | ||||
| 	AXVCVUXWDP | ||||
| 	AXVCVSXDSP | ||||
| 	AXVCVSXWSP | ||||
| 	AXVCVUXDSP | ||||
| 	AXVCVUXWSP | ||||
|  | ||||
| 	ALAST | ||||
|  | ||||
| 	// aliases | ||||
| 	ABR = obj.AJMP | ||||
| 	ABL = obj.ACALL | ||||
| ) | ||||
							
								
								
									
										549
									
								
								vendor/github.com/google/gops/internal/obj/ppc64/anames.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										549
									
								
								vendor/github.com/google/gops/internal/obj/ppc64/anames.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,549 @@ | ||||
| // Generated by stringer -i a.out.go -o anames.go -p ppc64 | ||||
| // Do not edit. | ||||
|  | ||||
| package ppc64 | ||||
|  | ||||
| import "github.com/google/gops/internal/obj" | ||||
|  | ||||
| var Anames = []string{ | ||||
| 	obj.A_ARCHSPECIFIC: "ADD", | ||||
| 	"ADDCC", | ||||
| 	"ADDV", | ||||
| 	"ADDVCC", | ||||
| 	"ADDC", | ||||
| 	"ADDCCC", | ||||
| 	"ADDCV", | ||||
| 	"ADDCVCC", | ||||
| 	"ADDME", | ||||
| 	"ADDMECC", | ||||
| 	"ADDMEVCC", | ||||
| 	"ADDMEV", | ||||
| 	"ADDE", | ||||
| 	"ADDECC", | ||||
| 	"ADDEVCC", | ||||
| 	"ADDEV", | ||||
| 	"ADDZE", | ||||
| 	"ADDZECC", | ||||
| 	"ADDZEVCC", | ||||
| 	"ADDZEV", | ||||
| 	"AND", | ||||
| 	"ANDCC", | ||||
| 	"ANDN", | ||||
| 	"ANDNCC", | ||||
| 	"BC", | ||||
| 	"BCL", | ||||
| 	"BEQ", | ||||
| 	"BGE", | ||||
| 	"BGT", | ||||
| 	"BLE", | ||||
| 	"BLT", | ||||
| 	"BNE", | ||||
| 	"BVC", | ||||
| 	"BVS", | ||||
| 	"CMP", | ||||
| 	"CMPU", | ||||
| 	"CNTLZW", | ||||
| 	"CNTLZWCC", | ||||
| 	"CRAND", | ||||
| 	"CRANDN", | ||||
| 	"CREQV", | ||||
| 	"CRNAND", | ||||
| 	"CRNOR", | ||||
| 	"CROR", | ||||
| 	"CRORN", | ||||
| 	"CRXOR", | ||||
| 	"DIVW", | ||||
| 	"DIVWCC", | ||||
| 	"DIVWVCC", | ||||
| 	"DIVWV", | ||||
| 	"DIVWU", | ||||
| 	"DIVWUCC", | ||||
| 	"DIVWUVCC", | ||||
| 	"DIVWUV", | ||||
| 	"EQV", | ||||
| 	"EQVCC", | ||||
| 	"EXTSB", | ||||
| 	"EXTSBCC", | ||||
| 	"EXTSH", | ||||
| 	"EXTSHCC", | ||||
| 	"FABS", | ||||
| 	"FABSCC", | ||||
| 	"FADD", | ||||
| 	"FADDCC", | ||||
| 	"FADDS", | ||||
| 	"FADDSCC", | ||||
| 	"FCMPO", | ||||
| 	"FCMPU", | ||||
| 	"FCTIW", | ||||
| 	"FCTIWCC", | ||||
| 	"FCTIWZ", | ||||
| 	"FCTIWZCC", | ||||
| 	"FDIV", | ||||
| 	"FDIVCC", | ||||
| 	"FDIVS", | ||||
| 	"FDIVSCC", | ||||
| 	"FMADD", | ||||
| 	"FMADDCC", | ||||
| 	"FMADDS", | ||||
| 	"FMADDSCC", | ||||
| 	"FMOVD", | ||||
| 	"FMOVDCC", | ||||
| 	"FMOVDU", | ||||
| 	"FMOVS", | ||||
| 	"FMOVSU", | ||||
| 	"FMOVSX", | ||||
| 	"FMOVSZ", | ||||
| 	"FMSUB", | ||||
| 	"FMSUBCC", | ||||
| 	"FMSUBS", | ||||
| 	"FMSUBSCC", | ||||
| 	"FMUL", | ||||
| 	"FMULCC", | ||||
| 	"FMULS", | ||||
| 	"FMULSCC", | ||||
| 	"FNABS", | ||||
| 	"FNABSCC", | ||||
| 	"FNEG", | ||||
| 	"FNEGCC", | ||||
| 	"FNMADD", | ||||
| 	"FNMADDCC", | ||||
| 	"FNMADDS", | ||||
| 	"FNMADDSCC", | ||||
| 	"FNMSUB", | ||||
| 	"FNMSUBCC", | ||||
| 	"FNMSUBS", | ||||
| 	"FNMSUBSCC", | ||||
| 	"FRSP", | ||||
| 	"FRSPCC", | ||||
| 	"FSUB", | ||||
| 	"FSUBCC", | ||||
| 	"FSUBS", | ||||
| 	"FSUBSCC", | ||||
| 	"ISEL", | ||||
| 	"MOVMW", | ||||
| 	"LBAR", | ||||
| 	"LSW", | ||||
| 	"LWAR", | ||||
| 	"LWSYNC", | ||||
| 	"MOVDBR", | ||||
| 	"MOVWBR", | ||||
| 	"MOVB", | ||||
| 	"MOVBU", | ||||
| 	"MOVBZ", | ||||
| 	"MOVBZU", | ||||
| 	"MOVH", | ||||
| 	"MOVHBR", | ||||
| 	"MOVHU", | ||||
| 	"MOVHZ", | ||||
| 	"MOVHZU", | ||||
| 	"MOVW", | ||||
| 	"MOVWU", | ||||
| 	"MOVFL", | ||||
| 	"MOVCRFS", | ||||
| 	"MTFSB0", | ||||
| 	"MTFSB0CC", | ||||
| 	"MTFSB1", | ||||
| 	"MTFSB1CC", | ||||
| 	"MULHW", | ||||
| 	"MULHWCC", | ||||
| 	"MULHWU", | ||||
| 	"MULHWUCC", | ||||
| 	"MULLW", | ||||
| 	"MULLWCC", | ||||
| 	"MULLWVCC", | ||||
| 	"MULLWV", | ||||
| 	"NAND", | ||||
| 	"NANDCC", | ||||
| 	"NEG", | ||||
| 	"NEGCC", | ||||
| 	"NEGVCC", | ||||
| 	"NEGV", | ||||
| 	"NOR", | ||||
| 	"NORCC", | ||||
| 	"OR", | ||||
| 	"ORCC", | ||||
| 	"ORN", | ||||
| 	"ORNCC", | ||||
| 	"REM", | ||||
| 	"REMCC", | ||||
| 	"REMV", | ||||
| 	"REMVCC", | ||||
| 	"REMU", | ||||
| 	"REMUCC", | ||||
| 	"REMUV", | ||||
| 	"REMUVCC", | ||||
| 	"RFI", | ||||
| 	"RLWMI", | ||||
| 	"RLWMICC", | ||||
| 	"RLWNM", | ||||
| 	"RLWNMCC", | ||||
| 	"SLW", | ||||
| 	"SLWCC", | ||||
| 	"SRW", | ||||
| 	"SRAW", | ||||
| 	"SRAWCC", | ||||
| 	"SRWCC", | ||||
| 	"STBCCC", | ||||
| 	"STSW", | ||||
| 	"STWCCC", | ||||
| 	"SUB", | ||||
| 	"SUBCC", | ||||
| 	"SUBVCC", | ||||
| 	"SUBC", | ||||
| 	"SUBCCC", | ||||
| 	"SUBCV", | ||||
| 	"SUBCVCC", | ||||
| 	"SUBME", | ||||
| 	"SUBMECC", | ||||
| 	"SUBMEVCC", | ||||
| 	"SUBMEV", | ||||
| 	"SUBV", | ||||
| 	"SUBE", | ||||
| 	"SUBECC", | ||||
| 	"SUBEV", | ||||
| 	"SUBEVCC", | ||||
| 	"SUBZE", | ||||
| 	"SUBZECC", | ||||
| 	"SUBZEVCC", | ||||
| 	"SUBZEV", | ||||
| 	"SYNC", | ||||
| 	"XOR", | ||||
| 	"XORCC", | ||||
| 	"DCBF", | ||||
| 	"DCBI", | ||||
| 	"DCBST", | ||||
| 	"DCBT", | ||||
| 	"DCBTST", | ||||
| 	"DCBZ", | ||||
| 	"ECIWX", | ||||
| 	"ECOWX", | ||||
| 	"EIEIO", | ||||
| 	"ICBI", | ||||
| 	"ISYNC", | ||||
| 	"PTESYNC", | ||||
| 	"TLBIE", | ||||
| 	"TLBIEL", | ||||
| 	"TLBSYNC", | ||||
| 	"TW", | ||||
| 	"SYSCALL", | ||||
| 	"WORD", | ||||
| 	"RFCI", | ||||
| 	"FRES", | ||||
| 	"FRESCC", | ||||
| 	"FRIM", | ||||
| 	"FRIMCC", | ||||
| 	"FRIP", | ||||
| 	"FRIPCC", | ||||
| 	"FRIZ", | ||||
| 	"FRIZCC", | ||||
| 	"FRSQRTE", | ||||
| 	"FRSQRTECC", | ||||
| 	"FSEL", | ||||
| 	"FSELCC", | ||||
| 	"FSQRT", | ||||
| 	"FSQRTCC", | ||||
| 	"FSQRTS", | ||||
| 	"FSQRTSCC", | ||||
| 	"CNTLZD", | ||||
| 	"CNTLZDCC", | ||||
| 	"CMPW", | ||||
| 	"CMPWU", | ||||
| 	"DIVD", | ||||
| 	"DIVDCC", | ||||
| 	"DIVDE", | ||||
| 	"DIVDECC", | ||||
| 	"DIVDEU", | ||||
| 	"DIVDEUCC", | ||||
| 	"DIVDVCC", | ||||
| 	"DIVDV", | ||||
| 	"DIVDU", | ||||
| 	"DIVDUCC", | ||||
| 	"DIVDUVCC", | ||||
| 	"DIVDUV", | ||||
| 	"EXTSW", | ||||
| 	"EXTSWCC", | ||||
| 	"FCFID", | ||||
| 	"FCFIDCC", | ||||
| 	"FCFIDU", | ||||
| 	"FCFIDUCC", | ||||
| 	"FCTID", | ||||
| 	"FCTIDCC", | ||||
| 	"FCTIDZ", | ||||
| 	"FCTIDZCC", | ||||
| 	"LDAR", | ||||
| 	"MOVD", | ||||
| 	"MOVDU", | ||||
| 	"MOVWZ", | ||||
| 	"MOVWZU", | ||||
| 	"MULHD", | ||||
| 	"MULHDCC", | ||||
| 	"MULHDU", | ||||
| 	"MULHDUCC", | ||||
| 	"MULLD", | ||||
| 	"MULLDCC", | ||||
| 	"MULLDVCC", | ||||
| 	"MULLDV", | ||||
| 	"RFID", | ||||
| 	"RLDMI", | ||||
| 	"RLDMICC", | ||||
| 	"RLDIMI", | ||||
| 	"RLDIMICC", | ||||
| 	"RLDC", | ||||
| 	"RLDCCC", | ||||
| 	"RLDCR", | ||||
| 	"RLDCRCC", | ||||
| 	"RLDICR", | ||||
| 	"RLDICRCC", | ||||
| 	"RLDCL", | ||||
| 	"RLDCLCC", | ||||
| 	"RLDICL", | ||||
| 	"RLDICLCC", | ||||
| 	"SLBIA", | ||||
| 	"SLBIE", | ||||
| 	"SLBMFEE", | ||||
| 	"SLBMFEV", | ||||
| 	"SLBMTE", | ||||
| 	"SLD", | ||||
| 	"SLDCC", | ||||
| 	"SRD", | ||||
| 	"SRAD", | ||||
| 	"SRADCC", | ||||
| 	"SRDCC", | ||||
| 	"STDCCC", | ||||
| 	"TD", | ||||
| 	"DWORD", | ||||
| 	"REMD", | ||||
| 	"REMDCC", | ||||
| 	"REMDV", | ||||
| 	"REMDVCC", | ||||
| 	"REMDU", | ||||
| 	"REMDUCC", | ||||
| 	"REMDUV", | ||||
| 	"REMDUVCC", | ||||
| 	"HRFID", | ||||
| 	"LV", | ||||
| 	"LVEBX", | ||||
| 	"LVEHX", | ||||
| 	"LVEWX", | ||||
| 	"LVX", | ||||
| 	"LVXL", | ||||
| 	"LVSL", | ||||
| 	"LVSR", | ||||
| 	"STV", | ||||
| 	"STVEBX", | ||||
| 	"STVEHX", | ||||
| 	"STVEWX", | ||||
| 	"STVX", | ||||
| 	"STVXL", | ||||
| 	"VAND", | ||||
| 	"VANDL", | ||||
| 	"VANDC", | ||||
| 	"VNAND", | ||||
| 	"VOR", | ||||
| 	"VORL", | ||||
| 	"VORC", | ||||
| 	"VNOR", | ||||
| 	"VXOR", | ||||
| 	"VEQV", | ||||
| 	"VADDUM", | ||||
| 	"VADDUBM", | ||||
| 	"VADDUHM", | ||||
| 	"VADDUWM", | ||||
| 	"VADDUDM", | ||||
| 	"VADDUQM", | ||||
| 	"VADDCU", | ||||
| 	"VADDCUQ", | ||||
| 	"VADDCUW", | ||||
| 	"VADDUS", | ||||
| 	"VADDUBS", | ||||
| 	"VADDUHS", | ||||
| 	"VADDUWS", | ||||
| 	"VADDSS", | ||||
| 	"VADDSBS", | ||||
| 	"VADDSHS", | ||||
| 	"VADDSWS", | ||||
| 	"VADDE", | ||||
| 	"VADDEUQM", | ||||
| 	"VADDECUQ", | ||||
| 	"VSUBUM", | ||||
| 	"VSUBUBM", | ||||
| 	"VSUBUHM", | ||||
| 	"VSUBUWM", | ||||
| 	"VSUBUDM", | ||||
| 	"VSUBUQM", | ||||
| 	"VSUBCU", | ||||
| 	"VSUBCUQ", | ||||
| 	"VSUBCUW", | ||||
| 	"VSUBUS", | ||||
| 	"VSUBUBS", | ||||
| 	"VSUBUHS", | ||||
| 	"VSUBUWS", | ||||
| 	"VSUBSS", | ||||
| 	"VSUBSBS", | ||||
| 	"VSUBSHS", | ||||
| 	"VSUBSWS", | ||||
| 	"VSUBE", | ||||
| 	"VSUBEUQM", | ||||
| 	"VSUBECUQ", | ||||
| 	"VR", | ||||
| 	"VRLB", | ||||
| 	"VRLH", | ||||
| 	"VRLW", | ||||
| 	"VRLD", | ||||
| 	"VS", | ||||
| 	"VSLB", | ||||
| 	"VSLH", | ||||
| 	"VSLW", | ||||
| 	"VSL", | ||||
| 	"VSLO", | ||||
| 	"VSRB", | ||||
| 	"VSRH", | ||||
| 	"VSRW", | ||||
| 	"VSR", | ||||
| 	"VSRO", | ||||
| 	"VSLD", | ||||
| 	"VSRD", | ||||
| 	"VSA", | ||||
| 	"VSRAB", | ||||
| 	"VSRAH", | ||||
| 	"VSRAW", | ||||
| 	"VSRAD", | ||||
| 	"VSOI", | ||||
| 	"VSLDOI", | ||||
| 	"VCLZ", | ||||
| 	"VCLZB", | ||||
| 	"VCLZH", | ||||
| 	"VCLZW", | ||||
| 	"VCLZD", | ||||
| 	"VPOPCNT", | ||||
| 	"VPOPCNTB", | ||||
| 	"VPOPCNTH", | ||||
| 	"VPOPCNTW", | ||||
| 	"VPOPCNTD", | ||||
| 	"VCMPEQ", | ||||
| 	"VCMPEQUB", | ||||
| 	"VCMPEQUBCC", | ||||
| 	"VCMPEQUH", | ||||
| 	"VCMPEQUHCC", | ||||
| 	"VCMPEQUW", | ||||
| 	"VCMPEQUWCC", | ||||
| 	"VCMPEQUD", | ||||
| 	"VCMPEQUDCC", | ||||
| 	"VCMPGT", | ||||
| 	"VCMPGTUB", | ||||
| 	"VCMPGTUBCC", | ||||
| 	"VCMPGTUH", | ||||
| 	"VCMPGTUHCC", | ||||
| 	"VCMPGTUW", | ||||
| 	"VCMPGTUWCC", | ||||
| 	"VCMPGTUD", | ||||
| 	"VCMPGTUDCC", | ||||
| 	"VCMPGTSB", | ||||
| 	"VCMPGTSBCC", | ||||
| 	"VCMPGTSH", | ||||
| 	"VCMPGTSHCC", | ||||
| 	"VCMPGTSW", | ||||
| 	"VCMPGTSWCC", | ||||
| 	"VCMPGTSD", | ||||
| 	"VCMPGTSDCC", | ||||
| 	"VPERM", | ||||
| 	"VSEL", | ||||
| 	"VSPLT", | ||||
| 	"VSPLTB", | ||||
| 	"VSPLTH", | ||||
| 	"VSPLTW", | ||||
| 	"VSPLTI", | ||||
| 	"VSPLTISB", | ||||
| 	"VSPLTISH", | ||||
| 	"VSPLTISW", | ||||
| 	"VCIPH", | ||||
| 	"VCIPHER", | ||||
| 	"VCIPHERLAST", | ||||
| 	"VNCIPH", | ||||
| 	"VNCIPHER", | ||||
| 	"VNCIPHERLAST", | ||||
| 	"VSBOX", | ||||
| 	"VSHASIGMA", | ||||
| 	"VSHASIGMAW", | ||||
| 	"VSHASIGMAD", | ||||
| 	"LXV", | ||||
| 	"LXVD2X", | ||||
| 	"LXVDSX", | ||||
| 	"LXVW4X", | ||||
| 	"STXV", | ||||
| 	"STXVD2X", | ||||
| 	"STXVW4X", | ||||
| 	"LXS", | ||||
| 	"LXSDX", | ||||
| 	"STXS", | ||||
| 	"STXSDX", | ||||
| 	"LXSI", | ||||
| 	"LXSIWAX", | ||||
| 	"LXSIWZX", | ||||
| 	"STXSI", | ||||
| 	"STXSIWX", | ||||
| 	"MFVSR", | ||||
| 	"MFVSRD", | ||||
| 	"MFVSRWZ", | ||||
| 	"MTVSR", | ||||
| 	"MTVSRD", | ||||
| 	"MTVSRWA", | ||||
| 	"MTVSRWZ", | ||||
| 	"XXLAND", | ||||
| 	"XXLANDQ", | ||||
| 	"XXLANDC", | ||||
| 	"XXLEQV", | ||||
| 	"XXLNAND", | ||||
| 	"XXLOR", | ||||
| 	"XXLORC", | ||||
| 	"XXLNOR", | ||||
| 	"XXLORQ", | ||||
| 	"XXLXOR", | ||||
| 	"XXSEL", | ||||
| 	"XXMRG", | ||||
| 	"XXMRGHW", | ||||
| 	"XXMRGLW", | ||||
| 	"XXSPLT", | ||||
| 	"XXSPLTW", | ||||
| 	"XXPERM", | ||||
| 	"XXPERMDI", | ||||
| 	"XXSI", | ||||
| 	"XXSLDWI", | ||||
| 	"XSCV", | ||||
| 	"XSCVDPSP", | ||||
| 	"XSCVSPDP", | ||||
| 	"XSCVDPSPN", | ||||
| 	"XSCVSPDPN", | ||||
| 	"XVCV", | ||||
| 	"XVCVDPSP", | ||||
| 	"XVCVSPDP", | ||||
| 	"XSCVX", | ||||
| 	"XSCVDPSXDS", | ||||
| 	"XSCVDPSXWS", | ||||
| 	"XSCVDPUXDS", | ||||
| 	"XSCVDPUXWS", | ||||
| 	"XSCVXP", | ||||
| 	"XSCVSXDDP", | ||||
| 	"XSCVUXDDP", | ||||
| 	"XSCVSXDSP", | ||||
| 	"XSCVUXDSP", | ||||
| 	"XVCVX", | ||||
| 	"XVCVDPSXDS", | ||||
| 	"XVCVDPSXWS", | ||||
| 	"XVCVDPUXDS", | ||||
| 	"XVCVDPUXWS", | ||||
| 	"XVCVSPSXDS", | ||||
| 	"XVCVSPSXWS", | ||||
| 	"XVCVSPUXDS", | ||||
| 	"XVCVSPUXWS", | ||||
| 	"XVCVXP", | ||||
| 	"XVCVSXDDP", | ||||
| 	"XVCVSXWDP", | ||||
| 	"XVCVUXDDP", | ||||
| 	"XVCVUXWDP", | ||||
| 	"XVCVSXDSP", | ||||
| 	"XVCVSXWSP", | ||||
| 	"XVCVUXDSP", | ||||
| 	"XVCVUXWSP", | ||||
| 	"LAST", | ||||
| } | ||||
							
								
								
									
										49
									
								
								vendor/github.com/google/gops/internal/obj/ppc64/anames9.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								vendor/github.com/google/gops/internal/obj/ppc64/anames9.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| // Copyright 2015 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package ppc64 | ||||
|  | ||||
| var cnames9 = []string{ | ||||
| 	"NONE", | ||||
| 	"REG", | ||||
| 	"FREG", | ||||
| 	"VREG", | ||||
| 	"VSREG", | ||||
| 	"CREG", | ||||
| 	"SPR", | ||||
| 	"ZCON", | ||||
| 	"SCON", | ||||
| 	"UCON", | ||||
| 	"ADDCON", | ||||
| 	"ANDCON", | ||||
| 	"LCON", | ||||
| 	"DCON", | ||||
| 	"SACON", | ||||
| 	"SECON", | ||||
| 	"LACON", | ||||
| 	"LECON", | ||||
| 	"DACON", | ||||
| 	"SBRA", | ||||
| 	"LBRA", | ||||
| 	"SAUTO", | ||||
| 	"LAUTO", | ||||
| 	"SEXT", | ||||
| 	"LEXT", | ||||
| 	"ZOREG", | ||||
| 	"SOREG", | ||||
| 	"LOREG", | ||||
| 	"FPSCR", | ||||
| 	"MSR", | ||||
| 	"XER", | ||||
| 	"LR", | ||||
| 	"CTR", | ||||
| 	"ANY", | ||||
| 	"GOK", | ||||
| 	"ADDR", | ||||
| 	"GOTADDR", | ||||
| 	"TLS_LE", | ||||
| 	"TLS_IE", | ||||
| 	"TEXTSIZE", | ||||
| 	"NCLASS", | ||||
| } | ||||
							
								
								
									
										4552
									
								
								vendor/github.com/google/gops/internal/obj/ppc64/asm9.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4552
									
								
								vendor/github.com/google/gops/internal/obj/ppc64/asm9.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										105
									
								
								vendor/github.com/google/gops/internal/obj/ppc64/list9.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								vendor/github.com/google/gops/internal/obj/ppc64/list9.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| // cmd/9l/list.c from Vita Nuova. | ||||
| // | ||||
| //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | ||||
| //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| //	Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| //	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others | ||||
| //	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package ppc64 | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/google/gops/internal/obj" | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	obj.RegisterRegister(obj.RBasePPC64, REG_DCR0+1024, Rconv) | ||||
| 	obj.RegisterOpcode(obj.ABasePPC64, Anames) | ||||
| } | ||||
|  | ||||
| func Rconv(r int) string { | ||||
| 	if r == 0 { | ||||
| 		return "NONE" | ||||
| 	} | ||||
| 	if r == REGG { | ||||
| 		// Special case. | ||||
| 		return "g" | ||||
| 	} | ||||
| 	if REG_R0 <= r && r <= REG_R31 { | ||||
| 		return fmt.Sprintf("R%d", r-REG_R0) | ||||
| 	} | ||||
| 	if REG_F0 <= r && r <= REG_F31 { | ||||
| 		return fmt.Sprintf("F%d", r-REG_F0) | ||||
| 	} | ||||
| 	if REG_V0 <= r && r <= REG_V31 { | ||||
| 		return fmt.Sprintf("V%d", r-REG_V0) | ||||
| 	} | ||||
| 	if REG_VS0 <= r && r <= REG_VS63 { | ||||
| 		return fmt.Sprintf("VS%d", r-REG_VS0) | ||||
| 	} | ||||
| 	if REG_CR0 <= r && r <= REG_CR7 { | ||||
| 		return fmt.Sprintf("CR%d", r-REG_CR0) | ||||
| 	} | ||||
| 	if r == REG_CR { | ||||
| 		return "CR" | ||||
| 	} | ||||
| 	if REG_SPR0 <= r && r <= REG_SPR0+1023 { | ||||
| 		switch r { | ||||
| 		case REG_XER: | ||||
| 			return "XER" | ||||
|  | ||||
| 		case REG_LR: | ||||
| 			return "LR" | ||||
|  | ||||
| 		case REG_CTR: | ||||
| 			return "CTR" | ||||
| 		} | ||||
|  | ||||
| 		return fmt.Sprintf("SPR(%d)", r-REG_SPR0) | ||||
| 	} | ||||
|  | ||||
| 	if REG_DCR0 <= r && r <= REG_DCR0+1023 { | ||||
| 		return fmt.Sprintf("DCR(%d)", r-REG_DCR0) | ||||
| 	} | ||||
| 	if r == REG_FPSCR { | ||||
| 		return "FPSCR" | ||||
| 	} | ||||
| 	if r == REG_MSR { | ||||
| 		return "MSR" | ||||
| 	} | ||||
|  | ||||
| 	return fmt.Sprintf("Rgok(%d)", r-obj.RBasePPC64) | ||||
| } | ||||
|  | ||||
| func DRconv(a int) string { | ||||
| 	s := "C_??" | ||||
| 	if a >= C_NONE && a <= C_NCLASS { | ||||
| 		s = cnames9[a] | ||||
| 	} | ||||
| 	var fp string | ||||
| 	fp += s | ||||
| 	return fp | ||||
| } | ||||
							
								
								
									
										1251
									
								
								vendor/github.com/google/gops/internal/obj/ppc64/obj9.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1251
									
								
								vendor/github.com/google/gops/internal/obj/ppc64/obj9.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										17
									
								
								vendor/github.com/google/gops/internal/obj/reloctype_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/google/gops/internal/obj/reloctype_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| // Code generated by "stringer -type=RelocType"; DO NOT EDIT | ||||
|  | ||||
| package obj | ||||
|  | ||||
| import "fmt" | ||||
|  | ||||
| const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLS" | ||||
|  | ||||
| var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 195, 206, 216, 225, 235, 249, 263, 279, 293, 307, 318, 332, 347, 364, 382, 403, 413, 424, 437} | ||||
|  | ||||
| func (i RelocType) String() string { | ||||
| 	i -= 1 | ||||
| 	if i < 0 || i >= RelocType(len(_RelocType_index)-1) { | ||||
| 		return fmt.Sprintf("RelocType(%d)", i+1) | ||||
| 	} | ||||
| 	return _RelocType_name[_RelocType_index[i]:_RelocType_index[i+1]] | ||||
| } | ||||
							
								
								
									
										926
									
								
								vendor/github.com/google/gops/internal/obj/s390x/a.out.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										926
									
								
								vendor/github.com/google/gops/internal/obj/s390x/a.out.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,926 @@ | ||||
| // Based on cmd/internal/obj/ppc64/a.out.go. | ||||
| // | ||||
| //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | ||||
| //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| //	Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| //	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others | ||||
| //	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package s390x | ||||
|  | ||||
| import "github.com/google/gops/internal/obj" | ||||
|  | ||||
| //go:generate go run ../stringer.go -i $GOFILE -o anames.go -p s390x | ||||
|  | ||||
| const ( | ||||
| 	NSNAME = 8 | ||||
| 	NSYM   = 50 | ||||
| 	NREG   = 16 // number of general purpose registers | ||||
| 	NFREG  = 16 // number of floating point registers | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// General purpose registers (GPRs). | ||||
| 	REG_R0 = obj.RBaseS390X + iota | ||||
| 	REG_R1 | ||||
| 	REG_R2 | ||||
| 	REG_R3 | ||||
| 	REG_R4 | ||||
| 	REG_R5 | ||||
| 	REG_R6 | ||||
| 	REG_R7 | ||||
| 	REG_R8 | ||||
| 	REG_R9 | ||||
| 	REG_R10 | ||||
| 	REG_R11 | ||||
| 	REG_R12 | ||||
| 	REG_R13 | ||||
| 	REG_R14 | ||||
| 	REG_R15 | ||||
|  | ||||
| 	// Floating point registers (FPRs). | ||||
| 	REG_F0 | ||||
| 	REG_F1 | ||||
| 	REG_F2 | ||||
| 	REG_F3 | ||||
| 	REG_F4 | ||||
| 	REG_F5 | ||||
| 	REG_F6 | ||||
| 	REG_F7 | ||||
| 	REG_F8 | ||||
| 	REG_F9 | ||||
| 	REG_F10 | ||||
| 	REG_F11 | ||||
| 	REG_F12 | ||||
| 	REG_F13 | ||||
| 	REG_F14 | ||||
| 	REG_F15 | ||||
|  | ||||
| 	// Vector registers (VRs) - only available when the vector | ||||
| 	// facility is installed. | ||||
| 	// V0-V15 are aliases for F0-F15. | ||||
| 	// We keep them in a separate space to make printing etc. easier | ||||
| 	// If the code generator ever emits vector instructions it will | ||||
| 	// need to take into account the aliasing. | ||||
| 	REG_V0 | ||||
| 	REG_V1 | ||||
| 	REG_V2 | ||||
| 	REG_V3 | ||||
| 	REG_V4 | ||||
| 	REG_V5 | ||||
| 	REG_V6 | ||||
| 	REG_V7 | ||||
| 	REG_V8 | ||||
| 	REG_V9 | ||||
| 	REG_V10 | ||||
| 	REG_V11 | ||||
| 	REG_V12 | ||||
| 	REG_V13 | ||||
| 	REG_V14 | ||||
| 	REG_V15 | ||||
| 	REG_V16 | ||||
| 	REG_V17 | ||||
| 	REG_V18 | ||||
| 	REG_V19 | ||||
| 	REG_V20 | ||||
| 	REG_V21 | ||||
| 	REG_V22 | ||||
| 	REG_V23 | ||||
| 	REG_V24 | ||||
| 	REG_V25 | ||||
| 	REG_V26 | ||||
| 	REG_V27 | ||||
| 	REG_V28 | ||||
| 	REG_V29 | ||||
| 	REG_V30 | ||||
| 	REG_V31 | ||||
|  | ||||
| 	// Access registers (ARs). | ||||
| 	// The thread pointer is typically stored in the register pair | ||||
| 	// AR0 and AR1. | ||||
| 	REG_AR0 | ||||
| 	REG_AR1 | ||||
| 	REG_AR2 | ||||
| 	REG_AR3 | ||||
| 	REG_AR4 | ||||
| 	REG_AR5 | ||||
| 	REG_AR6 | ||||
| 	REG_AR7 | ||||
| 	REG_AR8 | ||||
| 	REG_AR9 | ||||
| 	REG_AR10 | ||||
| 	REG_AR11 | ||||
| 	REG_AR12 | ||||
| 	REG_AR13 | ||||
| 	REG_AR14 | ||||
| 	REG_AR15 | ||||
|  | ||||
| 	REG_RESERVED // end of allocated registers | ||||
|  | ||||
| 	REGZERO = REG_R0  // set to zero | ||||
| 	REGARG  = -1      // -1 disables passing the first argument in register | ||||
| 	REGRT1  = REG_R3  // used during zeroing of the stack - not reserved | ||||
| 	REGRT2  = REG_R4  // used during zeroing of the stack - not reserved | ||||
| 	REGTMP  = REG_R10 // scratch register used in the assembler and linker | ||||
| 	REGTMP2 = REG_R11 // scratch register used in the assembler and linker | ||||
| 	REGCTXT = REG_R12 // context for closures | ||||
| 	REGG    = REG_R13 // G | ||||
| 	REG_LR  = REG_R14 // link register | ||||
| 	REGSP   = REG_R15 // stack pointer | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	BIG    = 32768 - 8 | ||||
| 	DISP12 = 4096 | ||||
| 	DISP16 = 65536 | ||||
| 	DISP20 = 1048576 | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// mark flags | ||||
| 	LABEL   = 1 << 0 | ||||
| 	LEAF    = 1 << 1 | ||||
| 	FLOAT   = 1 << 2 | ||||
| 	BRANCH  = 1 << 3 | ||||
| 	LOAD    = 1 << 4 | ||||
| 	FCMP    = 1 << 5 | ||||
| 	SYNC    = 1 << 6 | ||||
| 	LIST    = 1 << 7 | ||||
| 	FOLL    = 1 << 8 | ||||
| 	NOSCHED = 1 << 9 | ||||
| ) | ||||
|  | ||||
| const ( // comments from func aclass in asmz.go | ||||
| 	C_NONE     = iota | ||||
| 	C_REG      // general-purpose register (64-bit) | ||||
| 	C_FREG     // floating-point register (64-bit) | ||||
| 	C_VREG     // vector register (128-bit) | ||||
| 	C_AREG     // access register (32-bit) | ||||
| 	C_ZCON     // constant == 0 | ||||
| 	C_SCON     // 0 <= constant <= 0x7fff (positive int16) | ||||
| 	C_UCON     // constant & 0xffff == 0 (int16 or uint16) | ||||
| 	C_ADDCON   // 0 > constant >= -0x8000 (negative int16) | ||||
| 	C_ANDCON   // constant <= 0xffff | ||||
| 	C_LCON     // constant (int32 or uint32) | ||||
| 	C_DCON     // constant (int64 or uint64) | ||||
| 	C_SACON    // computed address, 16-bit displacement, possibly SP-relative | ||||
| 	C_LACON    // computed address, 32-bit displacement, possibly SP-relative | ||||
| 	C_DACON    // computed address, 64-bit displacment? | ||||
| 	C_SBRA     // short branch | ||||
| 	C_LBRA     // long branch | ||||
| 	C_SAUTO    // short auto | ||||
| 	C_LAUTO    // long auto | ||||
| 	C_ZOREG    // heap address, register-based, displacement == 0 | ||||
| 	C_SOREG    // heap address, register-based, int16 displacement | ||||
| 	C_LOREG    // heap address, register-based, int32 displacement | ||||
| 	C_TLS_LE   // TLS - local exec model (for executables) | ||||
| 	C_TLS_IE   // TLS - initial exec model (for shared libraries loaded at program startup) | ||||
| 	C_GOK      // general address | ||||
| 	C_ADDR     // relocation for extern or static symbols (loads and stores) | ||||
| 	C_SYMADDR  // relocation for extern or static symbols (address taking) | ||||
| 	C_GOTADDR  // GOT slot for a symbol in -dynlink mode | ||||
| 	C_TEXTSIZE // text size | ||||
| 	C_ANY | ||||
| 	C_NCLASS // must be the last | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// integer arithmetic | ||||
| 	AADD = obj.ABaseS390X + obj.A_ARCHSPECIFIC + iota | ||||
| 	AADDC | ||||
| 	AADDE | ||||
| 	AADDW | ||||
| 	ADIVW | ||||
| 	ADIVWU | ||||
| 	ADIVD | ||||
| 	ADIVDU | ||||
| 	AMODW | ||||
| 	AMODWU | ||||
| 	AMODD | ||||
| 	AMODDU | ||||
| 	AMULLW | ||||
| 	AMULLD | ||||
| 	AMULHD | ||||
| 	AMULHDU | ||||
| 	ASUB | ||||
| 	ASUBC | ||||
| 	ASUBV | ||||
| 	ASUBE | ||||
| 	ASUBW | ||||
| 	ANEG | ||||
| 	ANEGW | ||||
|  | ||||
| 	// integer moves | ||||
| 	AMOVWBR | ||||
| 	AMOVB | ||||
| 	AMOVBZ | ||||
| 	AMOVH | ||||
| 	AMOVHBR | ||||
| 	AMOVHZ | ||||
| 	AMOVW | ||||
| 	AMOVWZ | ||||
| 	AMOVD | ||||
| 	AMOVDBR | ||||
|  | ||||
| 	// conditional moves | ||||
| 	AMOVDEQ | ||||
| 	AMOVDGE | ||||
| 	AMOVDGT | ||||
| 	AMOVDLE | ||||
| 	AMOVDLT | ||||
| 	AMOVDNE | ||||
|  | ||||
| 	// find leftmost one | ||||
| 	AFLOGR | ||||
|  | ||||
| 	// integer bitwise | ||||
| 	AAND | ||||
| 	AANDW | ||||
| 	AOR | ||||
| 	AORW | ||||
| 	AXOR | ||||
| 	AXORW | ||||
| 	ASLW | ||||
| 	ASLD | ||||
| 	ASRW | ||||
| 	ASRAW | ||||
| 	ASRD | ||||
| 	ASRAD | ||||
| 	ARLL | ||||
| 	ARLLG | ||||
|  | ||||
| 	// floating point | ||||
| 	AFABS | ||||
| 	AFADD | ||||
| 	AFADDS | ||||
| 	AFCMPO | ||||
| 	AFCMPU | ||||
| 	ACEBR | ||||
| 	AFDIV | ||||
| 	AFDIVS | ||||
| 	AFMADD | ||||
| 	AFMADDS | ||||
| 	AFMOVD | ||||
| 	AFMOVS | ||||
| 	AFMSUB | ||||
| 	AFMSUBS | ||||
| 	AFMUL | ||||
| 	AFMULS | ||||
| 	AFNABS | ||||
| 	AFNEG | ||||
| 	AFNEGS | ||||
| 	AFNMADD | ||||
| 	AFNMADDS | ||||
| 	AFNMSUB | ||||
| 	AFNMSUBS | ||||
| 	ALEDBR | ||||
| 	ALDEBR | ||||
| 	AFSUB | ||||
| 	AFSUBS | ||||
| 	AFSQRT | ||||
| 	AFSQRTS | ||||
| 	AFIEBR | ||||
| 	AFIDBR | ||||
|  | ||||
| 	// convert from int32/int64 to float/float64 | ||||
| 	ACEFBRA | ||||
| 	ACDFBRA | ||||
| 	ACEGBRA | ||||
| 	ACDGBRA | ||||
|  | ||||
| 	// convert from float/float64 to int32/int64 | ||||
| 	ACFEBRA | ||||
| 	ACFDBRA | ||||
| 	ACGEBRA | ||||
| 	ACGDBRA | ||||
|  | ||||
| 	// convert from uint32/uint64 to float/float64 | ||||
| 	ACELFBR | ||||
| 	ACDLFBR | ||||
| 	ACELGBR | ||||
| 	ACDLGBR | ||||
|  | ||||
| 	// convert from float/float64 to uint32/uint64 | ||||
| 	ACLFEBR | ||||
| 	ACLFDBR | ||||
| 	ACLGEBR | ||||
| 	ACLGDBR | ||||
|  | ||||
| 	// compare | ||||
| 	ACMP | ||||
| 	ACMPU | ||||
| 	ACMPW | ||||
| 	ACMPWU | ||||
|  | ||||
| 	// compare and swap | ||||
| 	ACS | ||||
| 	ACSG | ||||
|  | ||||
| 	// serialize | ||||
| 	ASYNC | ||||
|  | ||||
| 	// branch | ||||
| 	ABC | ||||
| 	ABCL | ||||
| 	ABEQ | ||||
| 	ABGE | ||||
| 	ABGT | ||||
| 	ABLE | ||||
| 	ABLT | ||||
| 	ABLEU | ||||
| 	ABLTU | ||||
| 	ABNE | ||||
| 	ABVC | ||||
| 	ABVS | ||||
| 	ASYSCALL | ||||
|  | ||||
| 	// compare and branch | ||||
| 	ACMPBEQ | ||||
| 	ACMPBGE | ||||
| 	ACMPBGT | ||||
| 	ACMPBLE | ||||
| 	ACMPBLT | ||||
| 	ACMPBNE | ||||
| 	ACMPUBEQ | ||||
| 	ACMPUBGE | ||||
| 	ACMPUBGT | ||||
| 	ACMPUBLE | ||||
| 	ACMPUBLT | ||||
| 	ACMPUBNE | ||||
|  | ||||
| 	// storage-and-storage | ||||
| 	AMVC | ||||
| 	ACLC | ||||
| 	AXC | ||||
| 	AOC | ||||
| 	ANC | ||||
|  | ||||
| 	// load | ||||
| 	AEXRL | ||||
| 	ALARL | ||||
| 	ALA | ||||
| 	ALAY | ||||
|  | ||||
| 	// interlocked load and op | ||||
| 	ALAA | ||||
| 	ALAAG | ||||
| 	ALAAL | ||||
| 	ALAALG | ||||
| 	ALAN | ||||
| 	ALANG | ||||
| 	ALAX | ||||
| 	ALAXG | ||||
| 	ALAO | ||||
| 	ALAOG | ||||
|  | ||||
| 	// load/store multiple | ||||
| 	ALMY | ||||
| 	ALMG | ||||
| 	ASTMY | ||||
| 	ASTMG | ||||
|  | ||||
| 	// store clock | ||||
| 	ASTCK | ||||
| 	ASTCKC | ||||
| 	ASTCKE | ||||
| 	ASTCKF | ||||
|  | ||||
| 	// macros | ||||
| 	ACLEAR | ||||
|  | ||||
| 	// vector | ||||
| 	AVA | ||||
| 	AVAB | ||||
| 	AVAH | ||||
| 	AVAF | ||||
| 	AVAG | ||||
| 	AVAQ | ||||
| 	AVACC | ||||
| 	AVACCB | ||||
| 	AVACCH | ||||
| 	AVACCF | ||||
| 	AVACCG | ||||
| 	AVACCQ | ||||
| 	AVAC | ||||
| 	AVACQ | ||||
| 	AVACCC | ||||
| 	AVACCCQ | ||||
| 	AVN | ||||
| 	AVNC | ||||
| 	AVAVG | ||||
| 	AVAVGB | ||||
| 	AVAVGH | ||||
| 	AVAVGF | ||||
| 	AVAVGG | ||||
| 	AVAVGL | ||||
| 	AVAVGLB | ||||
| 	AVAVGLH | ||||
| 	AVAVGLF | ||||
| 	AVAVGLG | ||||
| 	AVCKSM | ||||
| 	AVCEQ | ||||
| 	AVCEQB | ||||
| 	AVCEQH | ||||
| 	AVCEQF | ||||
| 	AVCEQG | ||||
| 	AVCEQBS | ||||
| 	AVCEQHS | ||||
| 	AVCEQFS | ||||
| 	AVCEQGS | ||||
| 	AVCH | ||||
| 	AVCHB | ||||
| 	AVCHH | ||||
| 	AVCHF | ||||
| 	AVCHG | ||||
| 	AVCHBS | ||||
| 	AVCHHS | ||||
| 	AVCHFS | ||||
| 	AVCHGS | ||||
| 	AVCHL | ||||
| 	AVCHLB | ||||
| 	AVCHLH | ||||
| 	AVCHLF | ||||
| 	AVCHLG | ||||
| 	AVCHLBS | ||||
| 	AVCHLHS | ||||
| 	AVCHLFS | ||||
| 	AVCHLGS | ||||
| 	AVCLZ | ||||
| 	AVCLZB | ||||
| 	AVCLZH | ||||
| 	AVCLZF | ||||
| 	AVCLZG | ||||
| 	AVCTZ | ||||
| 	AVCTZB | ||||
| 	AVCTZH | ||||
| 	AVCTZF | ||||
| 	AVCTZG | ||||
| 	AVEC | ||||
| 	AVECB | ||||
| 	AVECH | ||||
| 	AVECF | ||||
| 	AVECG | ||||
| 	AVECL | ||||
| 	AVECLB | ||||
| 	AVECLH | ||||
| 	AVECLF | ||||
| 	AVECLG | ||||
| 	AVERIM | ||||
| 	AVERIMB | ||||
| 	AVERIMH | ||||
| 	AVERIMF | ||||
| 	AVERIMG | ||||
| 	AVERLL | ||||
| 	AVERLLB | ||||
| 	AVERLLH | ||||
| 	AVERLLF | ||||
| 	AVERLLG | ||||
| 	AVERLLV | ||||
| 	AVERLLVB | ||||
| 	AVERLLVH | ||||
| 	AVERLLVF | ||||
| 	AVERLLVG | ||||
| 	AVESLV | ||||
| 	AVESLVB | ||||
| 	AVESLVH | ||||
| 	AVESLVF | ||||
| 	AVESLVG | ||||
| 	AVESL | ||||
| 	AVESLB | ||||
| 	AVESLH | ||||
| 	AVESLF | ||||
| 	AVESLG | ||||
| 	AVESRA | ||||
| 	AVESRAB | ||||
| 	AVESRAH | ||||
| 	AVESRAF | ||||
| 	AVESRAG | ||||
| 	AVESRAV | ||||
| 	AVESRAVB | ||||
| 	AVESRAVH | ||||
| 	AVESRAVF | ||||
| 	AVESRAVG | ||||
| 	AVESRL | ||||
| 	AVESRLB | ||||
| 	AVESRLH | ||||
| 	AVESRLF | ||||
| 	AVESRLG | ||||
| 	AVESRLV | ||||
| 	AVESRLVB | ||||
| 	AVESRLVH | ||||
| 	AVESRLVF | ||||
| 	AVESRLVG | ||||
| 	AVX | ||||
| 	AVFAE | ||||
| 	AVFAEB | ||||
| 	AVFAEH | ||||
| 	AVFAEF | ||||
| 	AVFAEBS | ||||
| 	AVFAEHS | ||||
| 	AVFAEFS | ||||
| 	AVFAEZB | ||||
| 	AVFAEZH | ||||
| 	AVFAEZF | ||||
| 	AVFAEZBS | ||||
| 	AVFAEZHS | ||||
| 	AVFAEZFS | ||||
| 	AVFEE | ||||
| 	AVFEEB | ||||
| 	AVFEEH | ||||
| 	AVFEEF | ||||
| 	AVFEEBS | ||||
| 	AVFEEHS | ||||
| 	AVFEEFS | ||||
| 	AVFEEZB | ||||
| 	AVFEEZH | ||||
| 	AVFEEZF | ||||
| 	AVFEEZBS | ||||
| 	AVFEEZHS | ||||
| 	AVFEEZFS | ||||
| 	AVFENE | ||||
| 	AVFENEB | ||||
| 	AVFENEH | ||||
| 	AVFENEF | ||||
| 	AVFENEBS | ||||
| 	AVFENEHS | ||||
| 	AVFENEFS | ||||
| 	AVFENEZB | ||||
| 	AVFENEZH | ||||
| 	AVFENEZF | ||||
| 	AVFENEZBS | ||||
| 	AVFENEZHS | ||||
| 	AVFENEZFS | ||||
| 	AVFA | ||||
| 	AVFADB | ||||
| 	AWFADB | ||||
| 	AWFK | ||||
| 	AWFKDB | ||||
| 	AVFCE | ||||
| 	AVFCEDB | ||||
| 	AVFCEDBS | ||||
| 	AWFCEDB | ||||
| 	AWFCEDBS | ||||
| 	AVFCH | ||||
| 	AVFCHDB | ||||
| 	AVFCHDBS | ||||
| 	AWFCHDB | ||||
| 	AWFCHDBS | ||||
| 	AVFCHE | ||||
| 	AVFCHEDB | ||||
| 	AVFCHEDBS | ||||
| 	AWFCHEDB | ||||
| 	AWFCHEDBS | ||||
| 	AWFC | ||||
| 	AWFCDB | ||||
| 	AVCDG | ||||
| 	AVCDGB | ||||
| 	AWCDGB | ||||
| 	AVCDLG | ||||
| 	AVCDLGB | ||||
| 	AWCDLGB | ||||
| 	AVCGD | ||||
| 	AVCGDB | ||||
| 	AWCGDB | ||||
| 	AVCLGD | ||||
| 	AVCLGDB | ||||
| 	AWCLGDB | ||||
| 	AVFD | ||||
| 	AVFDDB | ||||
| 	AWFDDB | ||||
| 	AVLDE | ||||
| 	AVLDEB | ||||
| 	AWLDEB | ||||
| 	AVLED | ||||
| 	AVLEDB | ||||
| 	AWLEDB | ||||
| 	AVFM | ||||
| 	AVFMDB | ||||
| 	AWFMDB | ||||
| 	AVFMA | ||||
| 	AVFMADB | ||||
| 	AWFMADB | ||||
| 	AVFMS | ||||
| 	AVFMSDB | ||||
| 	AWFMSDB | ||||
| 	AVFPSO | ||||
| 	AVFPSODB | ||||
| 	AWFPSODB | ||||
| 	AVFLCDB | ||||
| 	AWFLCDB | ||||
| 	AVFLNDB | ||||
| 	AWFLNDB | ||||
| 	AVFLPDB | ||||
| 	AWFLPDB | ||||
| 	AVFSQ | ||||
| 	AVFSQDB | ||||
| 	AWFSQDB | ||||
| 	AVFS | ||||
| 	AVFSDB | ||||
| 	AWFSDB | ||||
| 	AVFTCI | ||||
| 	AVFTCIDB | ||||
| 	AWFTCIDB | ||||
| 	AVGFM | ||||
| 	AVGFMB | ||||
| 	AVGFMH | ||||
| 	AVGFMF | ||||
| 	AVGFMG | ||||
| 	AVGFMA | ||||
| 	AVGFMAB | ||||
| 	AVGFMAH | ||||
| 	AVGFMAF | ||||
| 	AVGFMAG | ||||
| 	AVGEF | ||||
| 	AVGEG | ||||
| 	AVGBM | ||||
| 	AVZERO | ||||
| 	AVONE | ||||
| 	AVGM | ||||
| 	AVGMB | ||||
| 	AVGMH | ||||
| 	AVGMF | ||||
| 	AVGMG | ||||
| 	AVISTR | ||||
| 	AVISTRB | ||||
| 	AVISTRH | ||||
| 	AVISTRF | ||||
| 	AVISTRBS | ||||
| 	AVISTRHS | ||||
| 	AVISTRFS | ||||
| 	AVL | ||||
| 	AVLR | ||||
| 	AVLREP | ||||
| 	AVLREPB | ||||
| 	AVLREPH | ||||
| 	AVLREPF | ||||
| 	AVLREPG | ||||
| 	AVLC | ||||
| 	AVLCB | ||||
| 	AVLCH | ||||
| 	AVLCF | ||||
| 	AVLCG | ||||
| 	AVLEH | ||||
| 	AVLEF | ||||
| 	AVLEG | ||||
| 	AVLEB | ||||
| 	AVLEIH | ||||
| 	AVLEIF | ||||
| 	AVLEIG | ||||
| 	AVLEIB | ||||
| 	AVFI | ||||
| 	AVFIDB | ||||
| 	AWFIDB | ||||
| 	AVLGV | ||||
| 	AVLGVB | ||||
| 	AVLGVH | ||||
| 	AVLGVF | ||||
| 	AVLGVG | ||||
| 	AVLLEZ | ||||
| 	AVLLEZB | ||||
| 	AVLLEZH | ||||
| 	AVLLEZF | ||||
| 	AVLLEZG | ||||
| 	AVLM | ||||
| 	AVLP | ||||
| 	AVLPB | ||||
| 	AVLPH | ||||
| 	AVLPF | ||||
| 	AVLPG | ||||
| 	AVLBB | ||||
| 	AVLVG | ||||
| 	AVLVGB | ||||
| 	AVLVGH | ||||
| 	AVLVGF | ||||
| 	AVLVGG | ||||
| 	AVLVGP | ||||
| 	AVLL | ||||
| 	AVMX | ||||
| 	AVMXB | ||||
| 	AVMXH | ||||
| 	AVMXF | ||||
| 	AVMXG | ||||
| 	AVMXL | ||||
| 	AVMXLB | ||||
| 	AVMXLH | ||||
| 	AVMXLF | ||||
| 	AVMXLG | ||||
| 	AVMRH | ||||
| 	AVMRHB | ||||
| 	AVMRHH | ||||
| 	AVMRHF | ||||
| 	AVMRHG | ||||
| 	AVMRL | ||||
| 	AVMRLB | ||||
| 	AVMRLH | ||||
| 	AVMRLF | ||||
| 	AVMRLG | ||||
| 	AVMN | ||||
| 	AVMNB | ||||
| 	AVMNH | ||||
| 	AVMNF | ||||
| 	AVMNG | ||||
| 	AVMNL | ||||
| 	AVMNLB | ||||
| 	AVMNLH | ||||
| 	AVMNLF | ||||
| 	AVMNLG | ||||
| 	AVMAE | ||||
| 	AVMAEB | ||||
| 	AVMAEH | ||||
| 	AVMAEF | ||||
| 	AVMAH | ||||
| 	AVMAHB | ||||
| 	AVMAHH | ||||
| 	AVMAHF | ||||
| 	AVMALE | ||||
| 	AVMALEB | ||||
| 	AVMALEH | ||||
| 	AVMALEF | ||||
| 	AVMALH | ||||
| 	AVMALHB | ||||
| 	AVMALHH | ||||
| 	AVMALHF | ||||
| 	AVMALO | ||||
| 	AVMALOB | ||||
| 	AVMALOH | ||||
| 	AVMALOF | ||||
| 	AVMAL | ||||
| 	AVMALB | ||||
| 	AVMALHW | ||||
| 	AVMALF | ||||
| 	AVMAO | ||||
| 	AVMAOB | ||||
| 	AVMAOH | ||||
| 	AVMAOF | ||||
| 	AVME | ||||
| 	AVMEB | ||||
| 	AVMEH | ||||
| 	AVMEF | ||||
| 	AVMH | ||||
| 	AVMHB | ||||
| 	AVMHH | ||||
| 	AVMHF | ||||
| 	AVMLE | ||||
| 	AVMLEB | ||||
| 	AVMLEH | ||||
| 	AVMLEF | ||||
| 	AVMLH | ||||
| 	AVMLHB | ||||
| 	AVMLHH | ||||
| 	AVMLHF | ||||
| 	AVMLO | ||||
| 	AVMLOB | ||||
| 	AVMLOH | ||||
| 	AVMLOF | ||||
| 	AVML | ||||
| 	AVMLB | ||||
| 	AVMLHW | ||||
| 	AVMLF | ||||
| 	AVMO | ||||
| 	AVMOB | ||||
| 	AVMOH | ||||
| 	AVMOF | ||||
| 	AVNO | ||||
| 	AVNOT | ||||
| 	AVO | ||||
| 	AVPK | ||||
| 	AVPKH | ||||
| 	AVPKF | ||||
| 	AVPKG | ||||
| 	AVPKLS | ||||
| 	AVPKLSH | ||||
| 	AVPKLSF | ||||
| 	AVPKLSG | ||||
| 	AVPKLSHS | ||||
| 	AVPKLSFS | ||||
| 	AVPKLSGS | ||||
| 	AVPKS | ||||
| 	AVPKSH | ||||
| 	AVPKSF | ||||
| 	AVPKSG | ||||
| 	AVPKSHS | ||||
| 	AVPKSFS | ||||
| 	AVPKSGS | ||||
| 	AVPERM | ||||
| 	AVPDI | ||||
| 	AVPOPCT | ||||
| 	AVREP | ||||
| 	AVREPB | ||||
| 	AVREPH | ||||
| 	AVREPF | ||||
| 	AVREPG | ||||
| 	AVREPI | ||||
| 	AVREPIB | ||||
| 	AVREPIH | ||||
| 	AVREPIF | ||||
| 	AVREPIG | ||||
| 	AVSCEF | ||||
| 	AVSCEG | ||||
| 	AVSEL | ||||
| 	AVSL | ||||
| 	AVSLB | ||||
| 	AVSLDB | ||||
| 	AVSRA | ||||
| 	AVSRAB | ||||
| 	AVSRL | ||||
| 	AVSRLB | ||||
| 	AVSEG | ||||
| 	AVSEGB | ||||
| 	AVSEGH | ||||
| 	AVSEGF | ||||
| 	AVST | ||||
| 	AVSTEH | ||||
| 	AVSTEF | ||||
| 	AVSTEG | ||||
| 	AVSTEB | ||||
| 	AVSTM | ||||
| 	AVSTL | ||||
| 	AVSTRC | ||||
| 	AVSTRCB | ||||
| 	AVSTRCH | ||||
| 	AVSTRCF | ||||
| 	AVSTRCBS | ||||
| 	AVSTRCHS | ||||
| 	AVSTRCFS | ||||
| 	AVSTRCZB | ||||
| 	AVSTRCZH | ||||
| 	AVSTRCZF | ||||
| 	AVSTRCZBS | ||||
| 	AVSTRCZHS | ||||
| 	AVSTRCZFS | ||||
| 	AVS | ||||
| 	AVSB | ||||
| 	AVSH | ||||
| 	AVSF | ||||
| 	AVSG | ||||
| 	AVSQ | ||||
| 	AVSCBI | ||||
| 	AVSCBIB | ||||
| 	AVSCBIH | ||||
| 	AVSCBIF | ||||
| 	AVSCBIG | ||||
| 	AVSCBIQ | ||||
| 	AVSBCBI | ||||
| 	AVSBCBIQ | ||||
| 	AVSBI | ||||
| 	AVSBIQ | ||||
| 	AVSUMG | ||||
| 	AVSUMGH | ||||
| 	AVSUMGF | ||||
| 	AVSUMQ | ||||
| 	AVSUMQF | ||||
| 	AVSUMQG | ||||
| 	AVSUM | ||||
| 	AVSUMB | ||||
| 	AVSUMH | ||||
| 	AVTM | ||||
| 	AVUPH | ||||
| 	AVUPHB | ||||
| 	AVUPHH | ||||
| 	AVUPHF | ||||
| 	AVUPLH | ||||
| 	AVUPLHB | ||||
| 	AVUPLHH | ||||
| 	AVUPLHF | ||||
| 	AVUPLL | ||||
| 	AVUPLLB | ||||
| 	AVUPLLH | ||||
| 	AVUPLLF | ||||
| 	AVUPL | ||||
| 	AVUPLB | ||||
| 	AVUPLHW | ||||
| 	AVUPLF | ||||
|  | ||||
| 	// binary | ||||
| 	ABYTE | ||||
| 	AWORD | ||||
| 	ADWORD | ||||
|  | ||||
| 	// end marker | ||||
| 	ALAST | ||||
|  | ||||
| 	// aliases | ||||
| 	ABR = obj.AJMP | ||||
| 	ABL = obj.ACALL | ||||
| ) | ||||
							
								
								
									
										675
									
								
								vendor/github.com/google/gops/internal/obj/s390x/anames.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										675
									
								
								vendor/github.com/google/gops/internal/obj/s390x/anames.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,675 @@ | ||||
| // Generated by stringer -i a.out.go -o anames.go -p s390x | ||||
| // Do not edit. | ||||
|  | ||||
| package s390x | ||||
|  | ||||
| import "github.com/google/gops/internal/obj" | ||||
|  | ||||
| var Anames = []string{ | ||||
| 	obj.A_ARCHSPECIFIC: "ADD", | ||||
| 	"ADDC", | ||||
| 	"ADDE", | ||||
| 	"ADDW", | ||||
| 	"DIVW", | ||||
| 	"DIVWU", | ||||
| 	"DIVD", | ||||
| 	"DIVDU", | ||||
| 	"MODW", | ||||
| 	"MODWU", | ||||
| 	"MODD", | ||||
| 	"MODDU", | ||||
| 	"MULLW", | ||||
| 	"MULLD", | ||||
| 	"MULHD", | ||||
| 	"MULHDU", | ||||
| 	"SUB", | ||||
| 	"SUBC", | ||||
| 	"SUBV", | ||||
| 	"SUBE", | ||||
| 	"SUBW", | ||||
| 	"NEG", | ||||
| 	"NEGW", | ||||
| 	"MOVWBR", | ||||
| 	"MOVB", | ||||
| 	"MOVBZ", | ||||
| 	"MOVH", | ||||
| 	"MOVHBR", | ||||
| 	"MOVHZ", | ||||
| 	"MOVW", | ||||
| 	"MOVWZ", | ||||
| 	"MOVD", | ||||
| 	"MOVDBR", | ||||
| 	"MOVDEQ", | ||||
| 	"MOVDGE", | ||||
| 	"MOVDGT", | ||||
| 	"MOVDLE", | ||||
| 	"MOVDLT", | ||||
| 	"MOVDNE", | ||||
| 	"FLOGR", | ||||
| 	"AND", | ||||
| 	"ANDW", | ||||
| 	"OR", | ||||
| 	"ORW", | ||||
| 	"XOR", | ||||
| 	"XORW", | ||||
| 	"SLW", | ||||
| 	"SLD", | ||||
| 	"SRW", | ||||
| 	"SRAW", | ||||
| 	"SRD", | ||||
| 	"SRAD", | ||||
| 	"RLL", | ||||
| 	"RLLG", | ||||
| 	"FABS", | ||||
| 	"FADD", | ||||
| 	"FADDS", | ||||
| 	"FCMPO", | ||||
| 	"FCMPU", | ||||
| 	"CEBR", | ||||
| 	"FDIV", | ||||
| 	"FDIVS", | ||||
| 	"FMADD", | ||||
| 	"FMADDS", | ||||
| 	"FMOVD", | ||||
| 	"FMOVS", | ||||
| 	"FMSUB", | ||||
| 	"FMSUBS", | ||||
| 	"FMUL", | ||||
| 	"FMULS", | ||||
| 	"FNABS", | ||||
| 	"FNEG", | ||||
| 	"FNEGS", | ||||
| 	"FNMADD", | ||||
| 	"FNMADDS", | ||||
| 	"FNMSUB", | ||||
| 	"FNMSUBS", | ||||
| 	"LEDBR", | ||||
| 	"LDEBR", | ||||
| 	"FSUB", | ||||
| 	"FSUBS", | ||||
| 	"FSQRT", | ||||
| 	"FSQRTS", | ||||
| 	"FIEBR", | ||||
| 	"FIDBR", | ||||
| 	"CEFBRA", | ||||
| 	"CDFBRA", | ||||
| 	"CEGBRA", | ||||
| 	"CDGBRA", | ||||
| 	"CFEBRA", | ||||
| 	"CFDBRA", | ||||
| 	"CGEBRA", | ||||
| 	"CGDBRA", | ||||
| 	"CELFBR", | ||||
| 	"CDLFBR", | ||||
| 	"CELGBR", | ||||
| 	"CDLGBR", | ||||
| 	"CLFEBR", | ||||
| 	"CLFDBR", | ||||
| 	"CLGEBR", | ||||
| 	"CLGDBR", | ||||
| 	"CMP", | ||||
| 	"CMPU", | ||||
| 	"CMPW", | ||||
| 	"CMPWU", | ||||
| 	"CS", | ||||
| 	"CSG", | ||||
| 	"SYNC", | ||||
| 	"BC", | ||||
| 	"BCL", | ||||
| 	"BEQ", | ||||
| 	"BGE", | ||||
| 	"BGT", | ||||
| 	"BLE", | ||||
| 	"BLT", | ||||
| 	"BLEU", | ||||
| 	"BLTU", | ||||
| 	"BNE", | ||||
| 	"BVC", | ||||
| 	"BVS", | ||||
| 	"SYSCALL", | ||||
| 	"CMPBEQ", | ||||
| 	"CMPBGE", | ||||
| 	"CMPBGT", | ||||
| 	"CMPBLE", | ||||
| 	"CMPBLT", | ||||
| 	"CMPBNE", | ||||
| 	"CMPUBEQ", | ||||
| 	"CMPUBGE", | ||||
| 	"CMPUBGT", | ||||
| 	"CMPUBLE", | ||||
| 	"CMPUBLT", | ||||
| 	"CMPUBNE", | ||||
| 	"MVC", | ||||
| 	"CLC", | ||||
| 	"XC", | ||||
| 	"OC", | ||||
| 	"NC", | ||||
| 	"EXRL", | ||||
| 	"LARL", | ||||
| 	"LA", | ||||
| 	"LAY", | ||||
| 	"LAA", | ||||
| 	"LAAG", | ||||
| 	"LAAL", | ||||
| 	"LAALG", | ||||
| 	"LAN", | ||||
| 	"LANG", | ||||
| 	"LAX", | ||||
| 	"LAXG", | ||||
| 	"LAO", | ||||
| 	"LAOG", | ||||
| 	"LMY", | ||||
| 	"LMG", | ||||
| 	"STMY", | ||||
| 	"STMG", | ||||
| 	"STCK", | ||||
| 	"STCKC", | ||||
| 	"STCKE", | ||||
| 	"STCKF", | ||||
| 	"CLEAR", | ||||
| 	"VA", | ||||
| 	"VAB", | ||||
| 	"VAH", | ||||
| 	"VAF", | ||||
| 	"VAG", | ||||
| 	"VAQ", | ||||
| 	"VACC", | ||||
| 	"VACCB", | ||||
| 	"VACCH", | ||||
| 	"VACCF", | ||||
| 	"VACCG", | ||||
| 	"VACCQ", | ||||
| 	"VAC", | ||||
| 	"VACQ", | ||||
| 	"VACCC", | ||||
| 	"VACCCQ", | ||||
| 	"VN", | ||||
| 	"VNC", | ||||
| 	"VAVG", | ||||
| 	"VAVGB", | ||||
| 	"VAVGH", | ||||
| 	"VAVGF", | ||||
| 	"VAVGG", | ||||
| 	"VAVGL", | ||||
| 	"VAVGLB", | ||||
| 	"VAVGLH", | ||||
| 	"VAVGLF", | ||||
| 	"VAVGLG", | ||||
| 	"VCKSM", | ||||
| 	"VCEQ", | ||||
| 	"VCEQB", | ||||
| 	"VCEQH", | ||||
| 	"VCEQF", | ||||
| 	"VCEQG", | ||||
| 	"VCEQBS", | ||||
| 	"VCEQHS", | ||||
| 	"VCEQFS", | ||||
| 	"VCEQGS", | ||||
| 	"VCH", | ||||
| 	"VCHB", | ||||
| 	"VCHH", | ||||
| 	"VCHF", | ||||
| 	"VCHG", | ||||
| 	"VCHBS", | ||||
| 	"VCHHS", | ||||
| 	"VCHFS", | ||||
| 	"VCHGS", | ||||
| 	"VCHL", | ||||
| 	"VCHLB", | ||||
| 	"VCHLH", | ||||
| 	"VCHLF", | ||||
| 	"VCHLG", | ||||
| 	"VCHLBS", | ||||
| 	"VCHLHS", | ||||
| 	"VCHLFS", | ||||
| 	"VCHLGS", | ||||
| 	"VCLZ", | ||||
| 	"VCLZB", | ||||
| 	"VCLZH", | ||||
| 	"VCLZF", | ||||
| 	"VCLZG", | ||||
| 	"VCTZ", | ||||
| 	"VCTZB", | ||||
| 	"VCTZH", | ||||
| 	"VCTZF", | ||||
| 	"VCTZG", | ||||
| 	"VEC", | ||||
| 	"VECB", | ||||
| 	"VECH", | ||||
| 	"VECF", | ||||
| 	"VECG", | ||||
| 	"VECL", | ||||
| 	"VECLB", | ||||
| 	"VECLH", | ||||
| 	"VECLF", | ||||
| 	"VECLG", | ||||
| 	"VERIM", | ||||
| 	"VERIMB", | ||||
| 	"VERIMH", | ||||
| 	"VERIMF", | ||||
| 	"VERIMG", | ||||
| 	"VERLL", | ||||
| 	"VERLLB", | ||||
| 	"VERLLH", | ||||
| 	"VERLLF", | ||||
| 	"VERLLG", | ||||
| 	"VERLLV", | ||||
| 	"VERLLVB", | ||||
| 	"VERLLVH", | ||||
| 	"VERLLVF", | ||||
| 	"VERLLVG", | ||||
| 	"VESLV", | ||||
| 	"VESLVB", | ||||
| 	"VESLVH", | ||||
| 	"VESLVF", | ||||
| 	"VESLVG", | ||||
| 	"VESL", | ||||
| 	"VESLB", | ||||
| 	"VESLH", | ||||
| 	"VESLF", | ||||
| 	"VESLG", | ||||
| 	"VESRA", | ||||
| 	"VESRAB", | ||||
| 	"VESRAH", | ||||
| 	"VESRAF", | ||||
| 	"VESRAG", | ||||
| 	"VESRAV", | ||||
| 	"VESRAVB", | ||||
| 	"VESRAVH", | ||||
| 	"VESRAVF", | ||||
| 	"VESRAVG", | ||||
| 	"VESRL", | ||||
| 	"VESRLB", | ||||
| 	"VESRLH", | ||||
| 	"VESRLF", | ||||
| 	"VESRLG", | ||||
| 	"VESRLV", | ||||
| 	"VESRLVB", | ||||
| 	"VESRLVH", | ||||
| 	"VESRLVF", | ||||
| 	"VESRLVG", | ||||
| 	"VX", | ||||
| 	"VFAE", | ||||
| 	"VFAEB", | ||||
| 	"VFAEH", | ||||
| 	"VFAEF", | ||||
| 	"VFAEBS", | ||||
| 	"VFAEHS", | ||||
| 	"VFAEFS", | ||||
| 	"VFAEZB", | ||||
| 	"VFAEZH", | ||||
| 	"VFAEZF", | ||||
| 	"VFAEZBS", | ||||
| 	"VFAEZHS", | ||||
| 	"VFAEZFS", | ||||
| 	"VFEE", | ||||
| 	"VFEEB", | ||||
| 	"VFEEH", | ||||
| 	"VFEEF", | ||||
| 	"VFEEBS", | ||||
| 	"VFEEHS", | ||||
| 	"VFEEFS", | ||||
| 	"VFEEZB", | ||||
| 	"VFEEZH", | ||||
| 	"VFEEZF", | ||||
| 	"VFEEZBS", | ||||
| 	"VFEEZHS", | ||||
| 	"VFEEZFS", | ||||
| 	"VFENE", | ||||
| 	"VFENEB", | ||||
| 	"VFENEH", | ||||
| 	"VFENEF", | ||||
| 	"VFENEBS", | ||||
| 	"VFENEHS", | ||||
| 	"VFENEFS", | ||||
| 	"VFENEZB", | ||||
| 	"VFENEZH", | ||||
| 	"VFENEZF", | ||||
| 	"VFENEZBS", | ||||
| 	"VFENEZHS", | ||||
| 	"VFENEZFS", | ||||
| 	"VFA", | ||||
| 	"VFADB", | ||||
| 	"WFADB", | ||||
| 	"WFK", | ||||
| 	"WFKDB", | ||||
| 	"VFCE", | ||||
| 	"VFCEDB", | ||||
| 	"VFCEDBS", | ||||
| 	"WFCEDB", | ||||
| 	"WFCEDBS", | ||||
| 	"VFCH", | ||||
| 	"VFCHDB", | ||||
| 	"VFCHDBS", | ||||
| 	"WFCHDB", | ||||
| 	"WFCHDBS", | ||||
| 	"VFCHE", | ||||
| 	"VFCHEDB", | ||||
| 	"VFCHEDBS", | ||||
| 	"WFCHEDB", | ||||
| 	"WFCHEDBS", | ||||
| 	"WFC", | ||||
| 	"WFCDB", | ||||
| 	"VCDG", | ||||
| 	"VCDGB", | ||||
| 	"WCDGB", | ||||
| 	"VCDLG", | ||||
| 	"VCDLGB", | ||||
| 	"WCDLGB", | ||||
| 	"VCGD", | ||||
| 	"VCGDB", | ||||
| 	"WCGDB", | ||||
| 	"VCLGD", | ||||
| 	"VCLGDB", | ||||
| 	"WCLGDB", | ||||
| 	"VFD", | ||||
| 	"VFDDB", | ||||
| 	"WFDDB", | ||||
| 	"VLDE", | ||||
| 	"VLDEB", | ||||
| 	"WLDEB", | ||||
| 	"VLED", | ||||
| 	"VLEDB", | ||||
| 	"WLEDB", | ||||
| 	"VFM", | ||||
| 	"VFMDB", | ||||
| 	"WFMDB", | ||||
| 	"VFMA", | ||||
| 	"VFMADB", | ||||
| 	"WFMADB", | ||||
| 	"VFMS", | ||||
| 	"VFMSDB", | ||||
| 	"WFMSDB", | ||||
| 	"VFPSO", | ||||
| 	"VFPSODB", | ||||
| 	"WFPSODB", | ||||
| 	"VFLCDB", | ||||
| 	"WFLCDB", | ||||
| 	"VFLNDB", | ||||
| 	"WFLNDB", | ||||
| 	"VFLPDB", | ||||
| 	"WFLPDB", | ||||
| 	"VFSQ", | ||||
| 	"VFSQDB", | ||||
| 	"WFSQDB", | ||||
| 	"VFS", | ||||
| 	"VFSDB", | ||||
| 	"WFSDB", | ||||
| 	"VFTCI", | ||||
| 	"VFTCIDB", | ||||
| 	"WFTCIDB", | ||||
| 	"VGFM", | ||||
| 	"VGFMB", | ||||
| 	"VGFMH", | ||||
| 	"VGFMF", | ||||
| 	"VGFMG", | ||||
| 	"VGFMA", | ||||
| 	"VGFMAB", | ||||
| 	"VGFMAH", | ||||
| 	"VGFMAF", | ||||
| 	"VGFMAG", | ||||
| 	"VGEF", | ||||
| 	"VGEG", | ||||
| 	"VGBM", | ||||
| 	"VZERO", | ||||
| 	"VONE", | ||||
| 	"VGM", | ||||
| 	"VGMB", | ||||
| 	"VGMH", | ||||
| 	"VGMF", | ||||
| 	"VGMG", | ||||
| 	"VISTR", | ||||
| 	"VISTRB", | ||||
| 	"VISTRH", | ||||
| 	"VISTRF", | ||||
| 	"VISTRBS", | ||||
| 	"VISTRHS", | ||||
| 	"VISTRFS", | ||||
| 	"VL", | ||||
| 	"VLR", | ||||
| 	"VLREP", | ||||
| 	"VLREPB", | ||||
| 	"VLREPH", | ||||
| 	"VLREPF", | ||||
| 	"VLREPG", | ||||
| 	"VLC", | ||||
| 	"VLCB", | ||||
| 	"VLCH", | ||||
| 	"VLCF", | ||||
| 	"VLCG", | ||||
| 	"VLEH", | ||||
| 	"VLEF", | ||||
| 	"VLEG", | ||||
| 	"VLEB", | ||||
| 	"VLEIH", | ||||
| 	"VLEIF", | ||||
| 	"VLEIG", | ||||
| 	"VLEIB", | ||||
| 	"VFI", | ||||
| 	"VFIDB", | ||||
| 	"WFIDB", | ||||
| 	"VLGV", | ||||
| 	"VLGVB", | ||||
| 	"VLGVH", | ||||
| 	"VLGVF", | ||||
| 	"VLGVG", | ||||
| 	"VLLEZ", | ||||
| 	"VLLEZB", | ||||
| 	"VLLEZH", | ||||
| 	"VLLEZF", | ||||
| 	"VLLEZG", | ||||
| 	"VLM", | ||||
| 	"VLP", | ||||
| 	"VLPB", | ||||
| 	"VLPH", | ||||
| 	"VLPF", | ||||
| 	"VLPG", | ||||
| 	"VLBB", | ||||
| 	"VLVG", | ||||
| 	"VLVGB", | ||||
| 	"VLVGH", | ||||
| 	"VLVGF", | ||||
| 	"VLVGG", | ||||
| 	"VLVGP", | ||||
| 	"VLL", | ||||
| 	"VMX", | ||||
| 	"VMXB", | ||||
| 	"VMXH", | ||||
| 	"VMXF", | ||||
| 	"VMXG", | ||||
| 	"VMXL", | ||||
| 	"VMXLB", | ||||
| 	"VMXLH", | ||||
| 	"VMXLF", | ||||
| 	"VMXLG", | ||||
| 	"VMRH", | ||||
| 	"VMRHB", | ||||
| 	"VMRHH", | ||||
| 	"VMRHF", | ||||
| 	"VMRHG", | ||||
| 	"VMRL", | ||||
| 	"VMRLB", | ||||
| 	"VMRLH", | ||||
| 	"VMRLF", | ||||
| 	"VMRLG", | ||||
| 	"VMN", | ||||
| 	"VMNB", | ||||
| 	"VMNH", | ||||
| 	"VMNF", | ||||
| 	"VMNG", | ||||
| 	"VMNL", | ||||
| 	"VMNLB", | ||||
| 	"VMNLH", | ||||
| 	"VMNLF", | ||||
| 	"VMNLG", | ||||
| 	"VMAE", | ||||
| 	"VMAEB", | ||||
| 	"VMAEH", | ||||
| 	"VMAEF", | ||||
| 	"VMAH", | ||||
| 	"VMAHB", | ||||
| 	"VMAHH", | ||||
| 	"VMAHF", | ||||
| 	"VMALE", | ||||
| 	"VMALEB", | ||||
| 	"VMALEH", | ||||
| 	"VMALEF", | ||||
| 	"VMALH", | ||||
| 	"VMALHB", | ||||
| 	"VMALHH", | ||||
| 	"VMALHF", | ||||
| 	"VMALO", | ||||
| 	"VMALOB", | ||||
| 	"VMALOH", | ||||
| 	"VMALOF", | ||||
| 	"VMAL", | ||||
| 	"VMALB", | ||||
| 	"VMALHW", | ||||
| 	"VMALF", | ||||
| 	"VMAO", | ||||
| 	"VMAOB", | ||||
| 	"VMAOH", | ||||
| 	"VMAOF", | ||||
| 	"VME", | ||||
| 	"VMEB", | ||||
| 	"VMEH", | ||||
| 	"VMEF", | ||||
| 	"VMH", | ||||
| 	"VMHB", | ||||
| 	"VMHH", | ||||
| 	"VMHF", | ||||
| 	"VMLE", | ||||
| 	"VMLEB", | ||||
| 	"VMLEH", | ||||
| 	"VMLEF", | ||||
| 	"VMLH", | ||||
| 	"VMLHB", | ||||
| 	"VMLHH", | ||||
| 	"VMLHF", | ||||
| 	"VMLO", | ||||
| 	"VMLOB", | ||||
| 	"VMLOH", | ||||
| 	"VMLOF", | ||||
| 	"VML", | ||||
| 	"VMLB", | ||||
| 	"VMLHW", | ||||
| 	"VMLF", | ||||
| 	"VMO", | ||||
| 	"VMOB", | ||||
| 	"VMOH", | ||||
| 	"VMOF", | ||||
| 	"VNO", | ||||
| 	"VNOT", | ||||
| 	"VO", | ||||
| 	"VPK", | ||||
| 	"VPKH", | ||||
| 	"VPKF", | ||||
| 	"VPKG", | ||||
| 	"VPKLS", | ||||
| 	"VPKLSH", | ||||
| 	"VPKLSF", | ||||
| 	"VPKLSG", | ||||
| 	"VPKLSHS", | ||||
| 	"VPKLSFS", | ||||
| 	"VPKLSGS", | ||||
| 	"VPKS", | ||||
| 	"VPKSH", | ||||
| 	"VPKSF", | ||||
| 	"VPKSG", | ||||
| 	"VPKSHS", | ||||
| 	"VPKSFS", | ||||
| 	"VPKSGS", | ||||
| 	"VPERM", | ||||
| 	"VPDI", | ||||
| 	"VPOPCT", | ||||
| 	"VREP", | ||||
| 	"VREPB", | ||||
| 	"VREPH", | ||||
| 	"VREPF", | ||||
| 	"VREPG", | ||||
| 	"VREPI", | ||||
| 	"VREPIB", | ||||
| 	"VREPIH", | ||||
| 	"VREPIF", | ||||
| 	"VREPIG", | ||||
| 	"VSCEF", | ||||
| 	"VSCEG", | ||||
| 	"VSEL", | ||||
| 	"VSL", | ||||
| 	"VSLB", | ||||
| 	"VSLDB", | ||||
| 	"VSRA", | ||||
| 	"VSRAB", | ||||
| 	"VSRL", | ||||
| 	"VSRLB", | ||||
| 	"VSEG", | ||||
| 	"VSEGB", | ||||
| 	"VSEGH", | ||||
| 	"VSEGF", | ||||
| 	"VST", | ||||
| 	"VSTEH", | ||||
| 	"VSTEF", | ||||
| 	"VSTEG", | ||||
| 	"VSTEB", | ||||
| 	"VSTM", | ||||
| 	"VSTL", | ||||
| 	"VSTRC", | ||||
| 	"VSTRCB", | ||||
| 	"VSTRCH", | ||||
| 	"VSTRCF", | ||||
| 	"VSTRCBS", | ||||
| 	"VSTRCHS", | ||||
| 	"VSTRCFS", | ||||
| 	"VSTRCZB", | ||||
| 	"VSTRCZH", | ||||
| 	"VSTRCZF", | ||||
| 	"VSTRCZBS", | ||||
| 	"VSTRCZHS", | ||||
| 	"VSTRCZFS", | ||||
| 	"VS", | ||||
| 	"VSB", | ||||
| 	"VSH", | ||||
| 	"VSF", | ||||
| 	"VSG", | ||||
| 	"VSQ", | ||||
| 	"VSCBI", | ||||
| 	"VSCBIB", | ||||
| 	"VSCBIH", | ||||
| 	"VSCBIF", | ||||
| 	"VSCBIG", | ||||
| 	"VSCBIQ", | ||||
| 	"VSBCBI", | ||||
| 	"VSBCBIQ", | ||||
| 	"VSBI", | ||||
| 	"VSBIQ", | ||||
| 	"VSUMG", | ||||
| 	"VSUMGH", | ||||
| 	"VSUMGF", | ||||
| 	"VSUMQ", | ||||
| 	"VSUMQF", | ||||
| 	"VSUMQG", | ||||
| 	"VSUM", | ||||
| 	"VSUMB", | ||||
| 	"VSUMH", | ||||
| 	"VTM", | ||||
| 	"VUPH", | ||||
| 	"VUPHB", | ||||
| 	"VUPHH", | ||||
| 	"VUPHF", | ||||
| 	"VUPLH", | ||||
| 	"VUPLHB", | ||||
| 	"VUPLHH", | ||||
| 	"VUPLHF", | ||||
| 	"VUPLL", | ||||
| 	"VUPLLB", | ||||
| 	"VUPLLH", | ||||
| 	"VUPLLF", | ||||
| 	"VUPL", | ||||
| 	"VUPLB", | ||||
| 	"VUPLHW", | ||||
| 	"VUPLF", | ||||
| 	"BYTE", | ||||
| 	"WORD", | ||||
| 	"DWORD", | ||||
| 	"LAST", | ||||
| } | ||||
							
								
								
									
										39
									
								
								vendor/github.com/google/gops/internal/obj/s390x/anamesz.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								vendor/github.com/google/gops/internal/obj/s390x/anamesz.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| // Copyright 2016 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package s390x | ||||
|  | ||||
| var cnamesz = []string{ | ||||
| 	"NONE", | ||||
| 	"REG", | ||||
| 	"FREG", | ||||
| 	"VREG", | ||||
| 	"AREG", | ||||
| 	"ZCON", | ||||
| 	"SCON", | ||||
| 	"UCON", | ||||
| 	"ADDCON", | ||||
| 	"ANDCON", | ||||
| 	"LCON", | ||||
| 	"DCON", | ||||
| 	"SACON", | ||||
| 	"LACON", | ||||
| 	"DACON", | ||||
| 	"SBRA", | ||||
| 	"LBRA", | ||||
| 	"SAUTO", | ||||
| 	"LAUTO", | ||||
| 	"ZOREG", | ||||
| 	"SOREG", | ||||
| 	"LOREG", | ||||
| 	"TLS_LE", | ||||
| 	"TLS_IE", | ||||
| 	"GOK", | ||||
| 	"ADDR", | ||||
| 	"SYMADDR", | ||||
| 	"GOTADDR", | ||||
| 	"TEXTSIZE", | ||||
| 	"ANY", | ||||
| 	"NCLASS", | ||||
| } | ||||
							
								
								
									
										4766
									
								
								vendor/github.com/google/gops/internal/obj/s390x/asmz.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4766
									
								
								vendor/github.com/google/gops/internal/obj/s390x/asmz.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										74
									
								
								vendor/github.com/google/gops/internal/obj/s390x/listz.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								vendor/github.com/google/gops/internal/obj/s390x/listz.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| // Based on cmd/internal/obj/ppc64/list9.go. | ||||
| // | ||||
| //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | ||||
| //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| //	Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| //	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others | ||||
| //	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package s390x | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/google/gops/internal/obj" | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	obj.RegisterRegister(obj.RBaseS390X, REG_R0+1024, Rconv) | ||||
| 	obj.RegisterOpcode(obj.ABaseS390X, Anames) | ||||
| } | ||||
|  | ||||
| func Rconv(r int) string { | ||||
| 	if r == 0 { | ||||
| 		return "NONE" | ||||
| 	} | ||||
| 	if r == REGG { | ||||
| 		// Special case. | ||||
| 		return "g" | ||||
| 	} | ||||
| 	if REG_R0 <= r && r <= REG_R15 { | ||||
| 		return fmt.Sprintf("R%d", r-REG_R0) | ||||
| 	} | ||||
| 	if REG_F0 <= r && r <= REG_F15 { | ||||
| 		return fmt.Sprintf("F%d", r-REG_F0) | ||||
| 	} | ||||
| 	if REG_AR0 <= r && r <= REG_AR15 { | ||||
| 		return fmt.Sprintf("AR%d", r-REG_AR0) | ||||
| 	} | ||||
| 	if REG_V0 <= r && r <= REG_V31 { | ||||
| 		return fmt.Sprintf("V%d", r-REG_V0) | ||||
| 	} | ||||
| 	return fmt.Sprintf("Rgok(%d)", r-obj.RBaseS390X) | ||||
| } | ||||
|  | ||||
| func DRconv(a int) string { | ||||
| 	s := "C_??" | ||||
| 	if a >= C_NONE && a <= C_NCLASS { | ||||
| 		s = cnamesz[a] | ||||
| 	} | ||||
| 	var fp string | ||||
| 	fp += s | ||||
| 	return fp | ||||
| } | ||||
							
								
								
									
										1029
									
								
								vendor/github.com/google/gops/internal/obj/s390x/objz.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1029
									
								
								vendor/github.com/google/gops/internal/obj/s390x/objz.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1061
									
								
								vendor/github.com/google/gops/internal/obj/s390x/vector.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1061
									
								
								vendor/github.com/google/gops/internal/obj/s390x/vector.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										21
									
								
								vendor/github.com/google/gops/internal/obj/stack.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/google/gops/internal/obj/stack.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| // Copyright 2011 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| // For the linkers. Must match Go definitions. | ||||
| // TODO(rsc): Share Go definitions with linkers directly. | ||||
|  | ||||
| const ( | ||||
| 	STACKSYSTEM = 0 | ||||
| 	StackSystem = STACKSYSTEM | ||||
| 	StackBig    = 4096 | ||||
| 	StackGuard  = 880*stackGuardMultiplier + StackSystem | ||||
| 	StackSmall  = 128 | ||||
| 	StackLimit  = StackGuard - StackSystem - StackSmall | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	StackPreempt = -1314 // 0xfff...fade | ||||
| ) | ||||
							
								
								
									
										104
									
								
								vendor/github.com/google/gops/internal/obj/stringer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								vendor/github.com/google/gops/internal/obj/stringer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| // Copyright 2015 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // +build ignore | ||||
|  | ||||
| // This is a mini version of the stringer tool customized for the Anames table | ||||
| // in the architecture support for obj. | ||||
| // This version just generates the slice of strings, not the String method. | ||||
|  | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"flag" | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	input  = flag.String("i", "", "input file name") | ||||
| 	output = flag.String("o", "", "output file name") | ||||
| 	pkg    = flag.String("p", "", "package name") | ||||
| ) | ||||
|  | ||||
| var Are = regexp.MustCompile(`^\tA([A-Z0-9]+)`) | ||||
|  | ||||
| func main() { | ||||
| 	flag.Parse() | ||||
| 	if *input == "" || *output == "" || *pkg == "" { | ||||
| 		flag.Usage() | ||||
| 		os.Exit(2) | ||||
| 	} | ||||
| 	in, err := os.Open(*input) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	fd, err := os.Create(*output) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	out := bufio.NewWriter(fd) | ||||
| 	defer out.Flush() | ||||
| 	var on = false | ||||
| 	s := bufio.NewScanner(in) | ||||
| 	first := true | ||||
| 	for s.Scan() { | ||||
| 		line := s.Text() | ||||
| 		if !on { | ||||
| 			// First relevant line contains "= obj.ABase". | ||||
| 			// If we find it, delete the = so we don't stop immediately. | ||||
| 			const prefix = "= obj.ABase" | ||||
| 			index := strings.Index(line, prefix) | ||||
| 			if index < 0 { | ||||
| 				continue | ||||
| 			} | ||||
| 			// It's on. Start with the header. | ||||
| 			fmt.Fprintf(out, header, *input, *output, *pkg, *pkg) | ||||
| 			on = true | ||||
| 			line = line[:index] | ||||
| 		} | ||||
| 		// Strip comments so their text won't defeat our heuristic. | ||||
| 		index := strings.Index(line, "//") | ||||
| 		if index > 0 { | ||||
| 			line = line[:index] | ||||
| 		} | ||||
| 		index = strings.Index(line, "/*") | ||||
| 		if index > 0 { | ||||
| 			line = line[:index] | ||||
| 		} | ||||
| 		// Termination condition: Any line with an = changes the sequence, | ||||
| 		// so stop there, and stop at a closing brace. | ||||
| 		if strings.HasPrefix(line, "}") || strings.ContainsRune(line, '=') { | ||||
| 			break | ||||
| 		} | ||||
| 		sub := Are.FindStringSubmatch(line) | ||||
| 		if len(sub) < 2 { | ||||
| 			continue | ||||
| 		} | ||||
| 		if first { | ||||
| 			fmt.Fprintf(out, "\tobj.A_ARCHSPECIFIC: %q,\n", sub[1]) | ||||
| 			first = false | ||||
| 		} else { | ||||
| 			fmt.Fprintf(out, "\t%q,\n", sub[1]) | ||||
| 		} | ||||
| 	} | ||||
| 	fmt.Fprintln(out, "}") | ||||
| 	if s.Err() != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| const header = `// Generated by stringer -i %s -o %s -p %s | ||||
| // Do not edit. | ||||
|  | ||||
| package %s | ||||
|  | ||||
| import "github.com/google/gops/internal/obj" | ||||
|  | ||||
| var Anames = []string{ | ||||
| ` | ||||
							
								
								
									
										88
									
								
								vendor/github.com/google/gops/internal/obj/sym.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								vendor/github.com/google/gops/internal/obj/sym.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| // Derived from Inferno utils/6l/obj.c and utils/6l/span.c | ||||
| // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/obj.c | ||||
| // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/span.c | ||||
| // | ||||
| //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | ||||
| //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| //	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others | ||||
| //	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| import ( | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| ) | ||||
|  | ||||
| func Linknew(arch *LinkArch) *Link { | ||||
| 	ctxt := new(Link) | ||||
| 	ctxt.Hash = make(map[SymVer]*LSym) | ||||
| 	ctxt.Arch = arch | ||||
| 	ctxt.Version = HistVersion | ||||
|  | ||||
| 	var buf string | ||||
| 	buf, _ = os.Getwd() | ||||
| 	if buf == "" { | ||||
| 		buf = "/???" | ||||
| 	} | ||||
| 	buf = filepath.ToSlash(buf) | ||||
| 	ctxt.Pathname = buf | ||||
|  | ||||
| 	ctxt.LineHist.GOROOT = GOROOT | ||||
| 	ctxt.LineHist.Dir = ctxt.Pathname | ||||
|  | ||||
| 	ctxt.Headtype.Set(GOOS) | ||||
| 	if ctxt.Headtype < 0 { | ||||
| 		log.Fatalf("unknown goos %s", GOOS) | ||||
| 	} | ||||
|  | ||||
| 	ctxt.Flag_optimize = true | ||||
| 	ctxt.Framepointer_enabled = Framepointer_enabled(GOOS, arch.Name) | ||||
| 	return ctxt | ||||
| } | ||||
|  | ||||
| func Linklookup(ctxt *Link, name string, v int) *LSym { | ||||
| 	s := ctxt.Hash[SymVer{name, v}] | ||||
| 	if s != nil { | ||||
| 		return s | ||||
| 	} | ||||
|  | ||||
| 	s = &LSym{ | ||||
| 		Name:    name, | ||||
| 		Type:    0, | ||||
| 		Version: int16(v), | ||||
| 		Size:    0, | ||||
| 	} | ||||
| 	ctxt.Hash[SymVer{name, v}] = s | ||||
| 	return s | ||||
| } | ||||
|  | ||||
| func Linksymfmt(s *LSym) string { | ||||
| 	if s == nil { | ||||
| 		return "<nil>" | ||||
| 	} | ||||
| 	return s.Name | ||||
| } | ||||
							
								
								
									
										16
									
								
								vendor/github.com/google/gops/internal/obj/symkind_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/google/gops/internal/obj/symkind_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| // Code generated by "stringer -type=SymKind"; DO NOT EDIT | ||||
|  | ||||
| package obj | ||||
|  | ||||
| import "fmt" | ||||
|  | ||||
| const _SymKind_name = "SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASBSSSNOPTRBSSSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILESFILEPATHSCONSTSDYNIMPORTSHOSTOBJSDWARFSECTSDWARFINFO" | ||||
|  | ||||
| var _SymKind_index = [...]uint16{0, 4, 9, 19, 24, 31, 40, 47, 54, 61, 69, 79, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 214, 220, 229, 237, 244, 254, 262, 267, 271, 280, 287, 292, 304, 316, 333, 350, 355, 364, 370, 380, 388, 398, 408} | ||||
|  | ||||
| func (i SymKind) String() string { | ||||
| 	if i < 0 || i >= SymKind(len(_SymKind_index)-1) { | ||||
| 		return fmt.Sprintf("SymKind(%d)", i) | ||||
| 	} | ||||
| 	return _SymKind_name[_SymKind_index[i]:_SymKind_index[i+1]] | ||||
| } | ||||
							
								
								
									
										50
									
								
								vendor/github.com/google/gops/internal/obj/textflag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								vendor/github.com/google/gops/internal/obj/textflag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| // Copyright 2013 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // This file defines flags attached to various functions | ||||
| // and data objects. The compilers, assemblers, and linker must | ||||
| // all agree on these values. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| const ( | ||||
| 	// Don't profile the marked routine. | ||||
| 	// | ||||
| 	// Deprecated: Not implemented, do not use. | ||||
| 	NOPROF = 1 | ||||
|  | ||||
| 	// It is ok for the linker to get multiple of these symbols. It will | ||||
| 	// pick one of the duplicates to use. | ||||
| 	DUPOK = 2 | ||||
|  | ||||
| 	// Don't insert stack check preamble. | ||||
| 	NOSPLIT = 4 | ||||
|  | ||||
| 	// Put this data in a read-only section. | ||||
| 	RODATA = 8 | ||||
|  | ||||
| 	// This data contains no pointers. | ||||
| 	NOPTR = 16 | ||||
|  | ||||
| 	// This is a wrapper function and should not count as disabling 'recover'. | ||||
| 	WRAPPER = 32 | ||||
|  | ||||
| 	// This function uses its incoming context register. | ||||
| 	NEEDCTXT = 64 | ||||
|  | ||||
| 	// When passed to ggloblsym, causes Local to be set to true on the LSym it creates. | ||||
| 	LOCAL = 128 | ||||
|  | ||||
| 	// Allocate a word of thread local storage and store the offset from the | ||||
| 	// thread local base to the thread local storage in this variable. | ||||
| 	TLSBSS = 256 | ||||
|  | ||||
| 	// Do not insert instructions to allocate a stack frame for this function. | ||||
| 	// Only valid on functions that declare a frame size of 0. | ||||
| 	// TODO(mwhudson): only implemented for ppc64x at present. | ||||
| 	NOFRAME = 512 | ||||
|  | ||||
| 	// Function can call reflect.Type.Method or reflect.Type.MethodByName. | ||||
| 	REFLECTMETHOD = 1024 | ||||
| ) | ||||
							
								
								
									
										41
									
								
								vendor/github.com/google/gops/internal/obj/typekind.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								vendor/github.com/google/gops/internal/obj/typekind.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| // Copyright 2012 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| // Must match runtime and reflect. | ||||
| // Included by cmd/gc. | ||||
|  | ||||
| const ( | ||||
| 	KindBool = 1 + iota | ||||
| 	KindInt | ||||
| 	KindInt8 | ||||
| 	KindInt16 | ||||
| 	KindInt32 | ||||
| 	KindInt64 | ||||
| 	KindUint | ||||
| 	KindUint8 | ||||
| 	KindUint16 | ||||
| 	KindUint32 | ||||
| 	KindUint64 | ||||
| 	KindUintptr | ||||
| 	KindFloat32 | ||||
| 	KindFloat64 | ||||
| 	KindComplex64 | ||||
| 	KindComplex128 | ||||
| 	KindArray | ||||
| 	KindChan | ||||
| 	KindFunc | ||||
| 	KindInterface | ||||
| 	KindMap | ||||
| 	KindPtr | ||||
| 	KindSlice | ||||
| 	KindString | ||||
| 	KindStruct | ||||
| 	KindUnsafePointer | ||||
| 	KindDirectIface = 1 << 5 | ||||
| 	KindGCProg      = 1 << 6 | ||||
| 	KindNoPointers  = 1 << 7 | ||||
| 	KindMask        = (1 << 5) - 1 | ||||
| ) | ||||
							
								
								
									
										499
									
								
								vendor/github.com/google/gops/internal/obj/util.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										499
									
								
								vendor/github.com/google/gops/internal/obj/util.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,499 @@ | ||||
| // Copyright 2015 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package obj | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| const REG_NONE = 0 | ||||
|  | ||||
| var start time.Time | ||||
|  | ||||
| func Cputime() float64 { | ||||
| 	if start.IsZero() { | ||||
| 		start = time.Now() | ||||
| 	} | ||||
| 	return time.Since(start).Seconds() | ||||
| } | ||||
|  | ||||
| func envOr(key, value string) string { | ||||
| 	if x := os.Getenv(key); x != "" { | ||||
| 		return x | ||||
| 	} | ||||
| 	return value | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	GOROOT  = envOr("GOROOT", defaultGOROOT) | ||||
| 	GOARCH  = envOr("GOARCH", defaultGOARCH) | ||||
| 	GOOS    = envOr("GOOS", defaultGOOS) | ||||
| 	GO386   = envOr("GO386", defaultGO386) | ||||
| 	GOARM   = goarm() | ||||
| 	Version = version | ||||
| ) | ||||
|  | ||||
| func goarm() int { | ||||
| 	switch v := envOr("GOARM", defaultGOARM); v { | ||||
| 	case "5": | ||||
| 		return 5 | ||||
| 	case "6": | ||||
| 		return 6 | ||||
| 	case "7": | ||||
| 		return 7 | ||||
| 	} | ||||
| 	// Fail here, rather than validate at multiple call sites. | ||||
| 	log.Fatalf("Invalid GOARM value. Must be 5, 6, or 7.") | ||||
| 	panic("unreachable") | ||||
| } | ||||
|  | ||||
| func Getgoextlinkenabled() string { | ||||
| 	return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED) | ||||
| } | ||||
|  | ||||
| func (p *Prog) Line() string { | ||||
| 	return p.Ctxt.LineHist.LineString(int(p.Lineno)) | ||||
| } | ||||
|  | ||||
| var armCondCode = []string{ | ||||
| 	".EQ", | ||||
| 	".NE", | ||||
| 	".CS", | ||||
| 	".CC", | ||||
| 	".MI", | ||||
| 	".PL", | ||||
| 	".VS", | ||||
| 	".VC", | ||||
| 	".HI", | ||||
| 	".LS", | ||||
| 	".GE", | ||||
| 	".LT", | ||||
| 	".GT", | ||||
| 	".LE", | ||||
| 	"", | ||||
| 	".NV", | ||||
| } | ||||
|  | ||||
| /* ARM scond byte */ | ||||
| const ( | ||||
| 	C_SCOND     = (1 << 4) - 1 | ||||
| 	C_SBIT      = 1 << 4 | ||||
| 	C_PBIT      = 1 << 5 | ||||
| 	C_WBIT      = 1 << 6 | ||||
| 	C_FBIT      = 1 << 7 | ||||
| 	C_UBIT      = 1 << 7 | ||||
| 	C_SCOND_XOR = 14 | ||||
| ) | ||||
|  | ||||
| // CConv formats ARM condition codes. | ||||
| func CConv(s uint8) string { | ||||
| 	if s == 0 { | ||||
| 		return "" | ||||
| 	} | ||||
| 	sc := armCondCode[(s&C_SCOND)^C_SCOND_XOR] | ||||
| 	if s&C_SBIT != 0 { | ||||
| 		sc += ".S" | ||||
| 	} | ||||
| 	if s&C_PBIT != 0 { | ||||
| 		sc += ".P" | ||||
| 	} | ||||
| 	if s&C_WBIT != 0 { | ||||
| 		sc += ".W" | ||||
| 	} | ||||
| 	if s&C_UBIT != 0 { /* ambiguous with FBIT */ | ||||
| 		sc += ".U" | ||||
| 	} | ||||
| 	return sc | ||||
| } | ||||
|  | ||||
| func (p *Prog) String() string { | ||||
| 	if p == nil { | ||||
| 		return "<nil Prog>" | ||||
| 	} | ||||
|  | ||||
| 	if p.Ctxt == nil { | ||||
| 		return "<Prog without ctxt>" | ||||
| 	} | ||||
|  | ||||
| 	sc := CConv(p.Scond) | ||||
|  | ||||
| 	var buf bytes.Buffer | ||||
|  | ||||
| 	fmt.Fprintf(&buf, "%.5d (%v)\t%v%s", p.Pc, p.Line(), p.As, sc) | ||||
| 	sep := "\t" | ||||
| 	quadOpAmd64 := p.RegTo2 == -1 | ||||
| 	if quadOpAmd64 { | ||||
| 		fmt.Fprintf(&buf, "%s$%d", sep, p.From3.Offset) | ||||
| 		sep = ", " | ||||
| 	} | ||||
| 	if p.From.Type != TYPE_NONE { | ||||
| 		fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.From)) | ||||
| 		sep = ", " | ||||
| 	} | ||||
| 	if p.Reg != REG_NONE { | ||||
| 		// Should not happen but might as well show it if it does. | ||||
| 		fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.Reg))) | ||||
| 		sep = ", " | ||||
| 	} | ||||
| 	if p.From3Type() != TYPE_NONE { | ||||
| 		if p.From3.Type == TYPE_CONST && p.As == ATEXT { | ||||
| 			// Special case - omit $. | ||||
| 			fmt.Fprintf(&buf, "%s%d", sep, p.From3.Offset) | ||||
| 		} else if quadOpAmd64 { | ||||
| 			fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.From3.Reg))) | ||||
| 		} else { | ||||
| 			fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, p.From3)) | ||||
| 		} | ||||
| 		sep = ", " | ||||
| 	} | ||||
| 	if p.To.Type != TYPE_NONE { | ||||
| 		fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.To)) | ||||
| 	} | ||||
| 	if p.RegTo2 != REG_NONE && !quadOpAmd64 { | ||||
| 		fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.RegTo2))) | ||||
| 	} | ||||
| 	return buf.String() | ||||
| } | ||||
|  | ||||
| func (ctxt *Link) NewProg() *Prog { | ||||
| 	var p *Prog | ||||
| 	if i := ctxt.allocIdx; i < len(ctxt.progs) { | ||||
| 		p = &ctxt.progs[i] | ||||
| 		ctxt.allocIdx = i + 1 | ||||
| 	} else { | ||||
| 		p = new(Prog) // should be the only call to this; all others should use ctxt.NewProg | ||||
| 	} | ||||
| 	p.Ctxt = ctxt | ||||
| 	return p | ||||
| } | ||||
| func (ctxt *Link) freeProgs() { | ||||
| 	s := ctxt.progs[:ctxt.allocIdx] | ||||
| 	for i := range s { | ||||
| 		s[i] = Prog{} | ||||
| 	} | ||||
| 	ctxt.allocIdx = 0 | ||||
| } | ||||
|  | ||||
| func (ctxt *Link) Line(n int) string { | ||||
| 	return ctxt.LineHist.LineString(n) | ||||
| } | ||||
|  | ||||
| func Getcallerpc(interface{}) uintptr { | ||||
| 	return 1 | ||||
| } | ||||
|  | ||||
| func (ctxt *Link) Dconv(a *Addr) string { | ||||
| 	return Dconv(nil, a) | ||||
| } | ||||
|  | ||||
| func Dconv(p *Prog, a *Addr) string { | ||||
| 	var str string | ||||
|  | ||||
| 	switch a.Type { | ||||
| 	default: | ||||
| 		str = fmt.Sprintf("type=%d", a.Type) | ||||
|  | ||||
| 	case TYPE_NONE: | ||||
| 		str = "" | ||||
| 		if a.Name != NAME_NONE || a.Reg != 0 || a.Sym != nil { | ||||
| 			str = fmt.Sprintf("%v(%v)(NONE)", Mconv(a), Rconv(int(a.Reg))) | ||||
| 		} | ||||
|  | ||||
| 	case TYPE_REG: | ||||
| 		// TODO(rsc): This special case is for x86 instructions like | ||||
| 		//	PINSRQ	CX,$1,X6 | ||||
| 		// where the $1 is included in the p->to Addr. | ||||
| 		// Move into a new field. | ||||
| 		if a.Offset != 0 { | ||||
| 			str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(int(a.Reg))) | ||||
| 			break | ||||
| 		} | ||||
|  | ||||
| 		str = Rconv(int(a.Reg)) | ||||
| 		if a.Name != NAME_NONE || a.Sym != nil { | ||||
| 			str = fmt.Sprintf("%v(%v)(REG)", Mconv(a), Rconv(int(a.Reg))) | ||||
| 		} | ||||
|  | ||||
| 	case TYPE_BRANCH: | ||||
| 		if a.Sym != nil { | ||||
| 			str = fmt.Sprintf("%s(SB)", a.Sym.Name) | ||||
| 		} else if p != nil && p.Pcond != nil { | ||||
| 			str = fmt.Sprint(p.Pcond.Pc) | ||||
| 		} else if a.Val != nil { | ||||
| 			str = fmt.Sprint(a.Val.(*Prog).Pc) | ||||
| 		} else { | ||||
| 			str = fmt.Sprintf("%d(PC)", a.Offset) | ||||
| 		} | ||||
|  | ||||
| 	case TYPE_INDIR: | ||||
| 		str = fmt.Sprintf("*%s", Mconv(a)) | ||||
|  | ||||
| 	case TYPE_MEM: | ||||
| 		str = Mconv(a) | ||||
| 		if a.Index != REG_NONE { | ||||
| 			str += fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale)) | ||||
| 		} | ||||
|  | ||||
| 	case TYPE_CONST: | ||||
| 		if a.Reg != 0 { | ||||
| 			str = fmt.Sprintf("$%v(%v)", Mconv(a), Rconv(int(a.Reg))) | ||||
| 		} else { | ||||
| 			str = fmt.Sprintf("$%v", Mconv(a)) | ||||
| 		} | ||||
|  | ||||
| 	case TYPE_TEXTSIZE: | ||||
| 		if a.Val.(int32) == ArgsSizeUnknown { | ||||
| 			str = fmt.Sprintf("$%d", a.Offset) | ||||
| 		} else { | ||||
| 			str = fmt.Sprintf("$%d-%d", a.Offset, a.Val.(int32)) | ||||
| 		} | ||||
|  | ||||
| 	case TYPE_FCONST: | ||||
| 		str = fmt.Sprintf("%.17g", a.Val.(float64)) | ||||
| 		// Make sure 1 prints as 1.0 | ||||
| 		if !strings.ContainsAny(str, ".e") { | ||||
| 			str += ".0" | ||||
| 		} | ||||
| 		str = fmt.Sprintf("$(%s)", str) | ||||
|  | ||||
| 	case TYPE_SCONST: | ||||
| 		str = fmt.Sprintf("$%q", a.Val.(string)) | ||||
|  | ||||
| 	case TYPE_ADDR: | ||||
| 		str = fmt.Sprintf("$%s", Mconv(a)) | ||||
|  | ||||
| 	case TYPE_SHIFT: | ||||
| 		v := int(a.Offset) | ||||
| 		ops := "<<>>->@>" | ||||
| 		switch GOARCH { | ||||
| 		case "arm": | ||||
| 			op := ops[((v>>5)&3)<<1:] | ||||
| 			if v&(1<<4) != 0 { | ||||
| 				str = fmt.Sprintf("R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15) | ||||
| 			} else { | ||||
| 				str = fmt.Sprintf("R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31) | ||||
| 			} | ||||
| 			if a.Reg != 0 { | ||||
| 				str += fmt.Sprintf("(%v)", Rconv(int(a.Reg))) | ||||
| 			} | ||||
| 		case "arm64": | ||||
| 			op := ops[((v>>22)&3)<<1:] | ||||
| 			str = fmt.Sprintf("R%d%c%c%d", (v>>16)&31, op[0], op[1], (v>>10)&63) | ||||
| 		default: | ||||
| 			panic("TYPE_SHIFT is not supported on " + GOARCH) | ||||
| 		} | ||||
|  | ||||
| 	case TYPE_REGREG: | ||||
| 		str = fmt.Sprintf("(%v, %v)", Rconv(int(a.Reg)), Rconv(int(a.Offset))) | ||||
|  | ||||
| 	case TYPE_REGREG2: | ||||
| 		str = fmt.Sprintf("%v, %v", Rconv(int(a.Reg)), Rconv(int(a.Offset))) | ||||
|  | ||||
| 	case TYPE_REGLIST: | ||||
| 		str = regListConv(int(a.Offset)) | ||||
| 	} | ||||
|  | ||||
| 	return str | ||||
| } | ||||
|  | ||||
| func Mconv(a *Addr) string { | ||||
| 	var str string | ||||
|  | ||||
| 	switch a.Name { | ||||
| 	default: | ||||
| 		str = fmt.Sprintf("name=%d", a.Name) | ||||
|  | ||||
| 	case NAME_NONE: | ||||
| 		switch { | ||||
| 		case a.Reg == REG_NONE: | ||||
| 			str = fmt.Sprint(a.Offset) | ||||
| 		case a.Offset == 0: | ||||
| 			str = fmt.Sprintf("(%v)", Rconv(int(a.Reg))) | ||||
| 		case a.Offset != 0: | ||||
| 			str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(int(a.Reg))) | ||||
| 		} | ||||
|  | ||||
| 	case NAME_EXTERN: | ||||
| 		if a.Sym != nil { | ||||
| 			str = fmt.Sprintf("%s%s(SB)", a.Sym.Name, offConv(a.Offset)) | ||||
| 		} else { | ||||
| 			str = fmt.Sprintf("%s(SB)", offConv(a.Offset)) | ||||
| 		} | ||||
|  | ||||
| 	case NAME_GOTREF: | ||||
| 		if a.Sym != nil { | ||||
| 			str = fmt.Sprintf("%s%s@GOT(SB)", a.Sym.Name, offConv(a.Offset)) | ||||
| 		} else { | ||||
| 			str = fmt.Sprintf("%s@GOT(SB)", offConv(a.Offset)) | ||||
| 		} | ||||
|  | ||||
| 	case NAME_STATIC: | ||||
| 		if a.Sym != nil { | ||||
| 			str = fmt.Sprintf("%s<>%s(SB)", a.Sym.Name, offConv(a.Offset)) | ||||
| 		} else { | ||||
| 			str = fmt.Sprintf("<>%s(SB)", offConv(a.Offset)) | ||||
| 		} | ||||
|  | ||||
| 	case NAME_AUTO: | ||||
| 		if a.Sym != nil { | ||||
| 			str = fmt.Sprintf("%s%s(SP)", a.Sym.Name, offConv(a.Offset)) | ||||
| 		} else { | ||||
| 			str = fmt.Sprintf("%s(SP)", offConv(a.Offset)) | ||||
| 		} | ||||
|  | ||||
| 	case NAME_PARAM: | ||||
| 		if a.Sym != nil { | ||||
| 			str = fmt.Sprintf("%s%s(FP)", a.Sym.Name, offConv(a.Offset)) | ||||
| 		} else { | ||||
| 			str = fmt.Sprintf("%s(FP)", offConv(a.Offset)) | ||||
| 		} | ||||
| 	} | ||||
| 	return str | ||||
| } | ||||
|  | ||||
| func offConv(off int64) string { | ||||
| 	if off == 0 { | ||||
| 		return "" | ||||
| 	} | ||||
| 	return fmt.Sprintf("%+d", off) | ||||
| } | ||||
|  | ||||
| type regSet struct { | ||||
| 	lo    int | ||||
| 	hi    int | ||||
| 	Rconv func(int) string | ||||
| } | ||||
|  | ||||
| // Few enough architectures that a linear scan is fastest. | ||||
| // Not even worth sorting. | ||||
| var regSpace []regSet | ||||
|  | ||||
| /* | ||||
| 	Each architecture defines a register space as a unique | ||||
| 	integer range. | ||||
| 	Here is the list of architectures and the base of their register spaces. | ||||
| */ | ||||
|  | ||||
| const ( | ||||
| 	// Because of masking operations in the encodings, each register | ||||
| 	// space should start at 0 modulo some power of 2. | ||||
| 	RBase386    = 1 * 1024 | ||||
| 	RBaseAMD64  = 2 * 1024 | ||||
| 	RBaseARM    = 3 * 1024 | ||||
| 	RBasePPC64  = 4 * 1024  // range [4k, 8k) | ||||
| 	RBaseARM64  = 8 * 1024  // range [8k, 13k) | ||||
| 	RBaseMIPS64 = 13 * 1024 // range [13k, 14k) | ||||
| 	RBaseS390X  = 14 * 1024 // range [14k, 15k) | ||||
| ) | ||||
|  | ||||
| // RegisterRegister binds a pretty-printer (Rconv) for register | ||||
| // numbers to a given register number range. Lo is inclusive, | ||||
| // hi exclusive (valid registers are lo through hi-1). | ||||
| func RegisterRegister(lo, hi int, Rconv func(int) string) { | ||||
| 	regSpace = append(regSpace, regSet{lo, hi, Rconv}) | ||||
| } | ||||
|  | ||||
| func Rconv(reg int) string { | ||||
| 	if reg == REG_NONE { | ||||
| 		return "NONE" | ||||
| 	} | ||||
| 	for i := range regSpace { | ||||
| 		rs := ®Space[i] | ||||
| 		if rs.lo <= reg && reg < rs.hi { | ||||
| 			return rs.Rconv(reg) | ||||
| 		} | ||||
| 	} | ||||
| 	return fmt.Sprintf("R???%d", reg) | ||||
| } | ||||
|  | ||||
| func regListConv(list int) string { | ||||
| 	str := "" | ||||
|  | ||||
| 	for i := 0; i < 16; i++ { // TODO: 16 is ARM-specific. | ||||
| 		if list&(1<<uint(i)) != 0 { | ||||
| 			if str == "" { | ||||
| 				str += "[" | ||||
| 			} else { | ||||
| 				str += "," | ||||
| 			} | ||||
| 			// This is ARM-specific; R10 is g. | ||||
| 			if i == 10 { | ||||
| 				str += "g" | ||||
| 			} else { | ||||
| 				str += fmt.Sprintf("R%d", i) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	str += "]" | ||||
| 	return str | ||||
| } | ||||
|  | ||||
| type opSet struct { | ||||
| 	lo    As | ||||
| 	names []string | ||||
| } | ||||
|  | ||||
| // Not even worth sorting | ||||
| var aSpace []opSet | ||||
|  | ||||
| // RegisterOpcode binds a list of instruction names | ||||
| // to a given instruction number range. | ||||
| func RegisterOpcode(lo As, Anames []string) { | ||||
| 	if len(Anames) > AllowedOpCodes { | ||||
| 		panic(fmt.Sprintf("too many instructions, have %d max %d", len(Anames), AllowedOpCodes)) | ||||
| 	} | ||||
| 	aSpace = append(aSpace, opSet{lo, Anames}) | ||||
| } | ||||
|  | ||||
| func (a As) String() string { | ||||
| 	if 0 <= a && int(a) < len(Anames) { | ||||
| 		return Anames[a] | ||||
| 	} | ||||
| 	for i := range aSpace { | ||||
| 		as := &aSpace[i] | ||||
| 		if as.lo <= a && int(a-as.lo) < len(as.names) { | ||||
| 			return as.names[a-as.lo] | ||||
| 		} | ||||
| 	} | ||||
| 	return fmt.Sprintf("A???%d", a) | ||||
| } | ||||
|  | ||||
| var Anames = []string{ | ||||
| 	"XXX", | ||||
| 	"CALL", | ||||
| 	"DUFFCOPY", | ||||
| 	"DUFFZERO", | ||||
| 	"END", | ||||
| 	"FUNCDATA", | ||||
| 	"JMP", | ||||
| 	"NOP", | ||||
| 	"PCDATA", | ||||
| 	"RET", | ||||
| 	"TEXT", | ||||
| 	"TYPE", | ||||
| 	"UNDEF", | ||||
| 	"USEFIELD", | ||||
| 	"VARDEF", | ||||
| 	"VARKILL", | ||||
| 	"VARLIVE", | ||||
| } | ||||
|  | ||||
| func Bool2int(b bool) int { | ||||
| 	// The compiler currently only optimizes this form. | ||||
| 	// See issue 6011. | ||||
| 	var i int | ||||
| 	if b { | ||||
| 		i = 1 | ||||
| 	} else { | ||||
| 		i = 0 | ||||
| 	} | ||||
| 	return i | ||||
| } | ||||
							
								
								
									
										1009
									
								
								vendor/github.com/google/gops/internal/obj/x86/a.out.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1009
									
								
								vendor/github.com/google/gops/internal/obj/x86/a.out.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										769
									
								
								vendor/github.com/google/gops/internal/obj/x86/anames.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										769
									
								
								vendor/github.com/google/gops/internal/obj/x86/anames.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,769 @@ | ||||
| // Generated by stringer -i a.out.go -o anames.go -p x86 | ||||
| // Do not edit. | ||||
|  | ||||
| package x86 | ||||
|  | ||||
| import "github.com/google/gops/internal/obj" | ||||
|  | ||||
| var Anames = []string{ | ||||
| 	obj.A_ARCHSPECIFIC: "AAA", | ||||
| 	"AAD", | ||||
| 	"AAM", | ||||
| 	"AAS", | ||||
| 	"ADCB", | ||||
| 	"ADCL", | ||||
| 	"ADCW", | ||||
| 	"ADDB", | ||||
| 	"ADDL", | ||||
| 	"ADDW", | ||||
| 	"ADJSP", | ||||
| 	"ANDB", | ||||
| 	"ANDL", | ||||
| 	"ANDW", | ||||
| 	"ARPL", | ||||
| 	"BOUNDL", | ||||
| 	"BOUNDW", | ||||
| 	"BSFL", | ||||
| 	"BSFW", | ||||
| 	"BSRL", | ||||
| 	"BSRW", | ||||
| 	"BTL", | ||||
| 	"BTW", | ||||
| 	"BTCL", | ||||
| 	"BTCW", | ||||
| 	"BTRL", | ||||
| 	"BTRW", | ||||
| 	"BTSL", | ||||
| 	"BTSW", | ||||
| 	"BYTE", | ||||
| 	"CLC", | ||||
| 	"CLD", | ||||
| 	"CLI", | ||||
| 	"CLTS", | ||||
| 	"CMC", | ||||
| 	"CMPB", | ||||
| 	"CMPL", | ||||
| 	"CMPW", | ||||
| 	"CMPSB", | ||||
| 	"CMPSL", | ||||
| 	"CMPSW", | ||||
| 	"DAA", | ||||
| 	"DAS", | ||||
| 	"DECB", | ||||
| 	"DECL", | ||||
| 	"DECQ", | ||||
| 	"DECW", | ||||
| 	"DIVB", | ||||
| 	"DIVL", | ||||
| 	"DIVW", | ||||
| 	"ENTER", | ||||
| 	"HADDPD", | ||||
| 	"HADDPS", | ||||
| 	"HLT", | ||||
| 	"HSUBPD", | ||||
| 	"HSUBPS", | ||||
| 	"IDIVB", | ||||
| 	"IDIVL", | ||||
| 	"IDIVW", | ||||
| 	"IMULB", | ||||
| 	"IMULL", | ||||
| 	"IMULW", | ||||
| 	"INB", | ||||
| 	"INL", | ||||
| 	"INW", | ||||
| 	"INCB", | ||||
| 	"INCL", | ||||
| 	"INCQ", | ||||
| 	"INCW", | ||||
| 	"INSB", | ||||
| 	"INSL", | ||||
| 	"INSW", | ||||
| 	"INT", | ||||
| 	"INTO", | ||||
| 	"IRETL", | ||||
| 	"IRETW", | ||||
| 	"JCC", | ||||
| 	"JCS", | ||||
| 	"JCXZL", | ||||
| 	"JEQ", | ||||
| 	"JGE", | ||||
| 	"JGT", | ||||
| 	"JHI", | ||||
| 	"JLE", | ||||
| 	"JLS", | ||||
| 	"JLT", | ||||
| 	"JMI", | ||||
| 	"JNE", | ||||
| 	"JOC", | ||||
| 	"JOS", | ||||
| 	"JPC", | ||||
| 	"JPL", | ||||
| 	"JPS", | ||||
| 	"LAHF", | ||||
| 	"LARL", | ||||
| 	"LARW", | ||||
| 	"LEAL", | ||||
| 	"LEAW", | ||||
| 	"LEAVEL", | ||||
| 	"LEAVEW", | ||||
| 	"LOCK", | ||||
| 	"LODSB", | ||||
| 	"LODSL", | ||||
| 	"LODSW", | ||||
| 	"LONG", | ||||
| 	"LOOP", | ||||
| 	"LOOPEQ", | ||||
| 	"LOOPNE", | ||||
| 	"LSLL", | ||||
| 	"LSLW", | ||||
| 	"MOVB", | ||||
| 	"MOVL", | ||||
| 	"MOVW", | ||||
| 	"MOVBLSX", | ||||
| 	"MOVBLZX", | ||||
| 	"MOVBQSX", | ||||
| 	"MOVBQZX", | ||||
| 	"MOVBWSX", | ||||
| 	"MOVBWZX", | ||||
| 	"MOVWLSX", | ||||
| 	"MOVWLZX", | ||||
| 	"MOVWQSX", | ||||
| 	"MOVWQZX", | ||||
| 	"MOVSB", | ||||
| 	"MOVSL", | ||||
| 	"MOVSW", | ||||
| 	"MULB", | ||||
| 	"MULL", | ||||
| 	"MULW", | ||||
| 	"NEGB", | ||||
| 	"NEGL", | ||||
| 	"NEGW", | ||||
| 	"NOTB", | ||||
| 	"NOTL", | ||||
| 	"NOTW", | ||||
| 	"ORB", | ||||
| 	"ORL", | ||||
| 	"ORW", | ||||
| 	"OUTB", | ||||
| 	"OUTL", | ||||
| 	"OUTW", | ||||
| 	"OUTSB", | ||||
| 	"OUTSL", | ||||
| 	"OUTSW", | ||||
| 	"PAUSE", | ||||
| 	"POPAL", | ||||
| 	"POPAW", | ||||
| 	"POPCNTW", | ||||
| 	"POPCNTL", | ||||
| 	"POPCNTQ", | ||||
| 	"POPFL", | ||||
| 	"POPFW", | ||||
| 	"POPL", | ||||
| 	"POPW", | ||||
| 	"PUSHAL", | ||||
| 	"PUSHAW", | ||||
| 	"PUSHFL", | ||||
| 	"PUSHFW", | ||||
| 	"PUSHL", | ||||
| 	"PUSHW", | ||||
| 	"RCLB", | ||||
| 	"RCLL", | ||||
| 	"RCLW", | ||||
| 	"RCRB", | ||||
| 	"RCRL", | ||||
| 	"RCRW", | ||||
| 	"REP", | ||||
| 	"REPN", | ||||
| 	"ROLB", | ||||
| 	"ROLL", | ||||
| 	"ROLW", | ||||
| 	"RORB", | ||||
| 	"RORL", | ||||
| 	"RORW", | ||||
| 	"SAHF", | ||||
| 	"SALB", | ||||
| 	"SALL", | ||||
| 	"SALW", | ||||
| 	"SARB", | ||||
| 	"SARL", | ||||
| 	"SARW", | ||||
| 	"SBBB", | ||||
| 	"SBBL", | ||||
| 	"SBBW", | ||||
| 	"SCASB", | ||||
| 	"SCASL", | ||||
| 	"SCASW", | ||||
| 	"SETCC", | ||||
| 	"SETCS", | ||||
| 	"SETEQ", | ||||
| 	"SETGE", | ||||
| 	"SETGT", | ||||
| 	"SETHI", | ||||
| 	"SETLE", | ||||
| 	"SETLS", | ||||
| 	"SETLT", | ||||
| 	"SETMI", | ||||
| 	"SETNE", | ||||
| 	"SETOC", | ||||
| 	"SETOS", | ||||
| 	"SETPC", | ||||
| 	"SETPL", | ||||
| 	"SETPS", | ||||
| 	"CDQ", | ||||
| 	"CWD", | ||||
| 	"SHLB", | ||||
| 	"SHLL", | ||||
| 	"SHLW", | ||||
| 	"SHRB", | ||||
| 	"SHRL", | ||||
| 	"SHRW", | ||||
| 	"STC", | ||||
| 	"STD", | ||||
| 	"STI", | ||||
| 	"STOSB", | ||||
| 	"STOSL", | ||||
| 	"STOSW", | ||||
| 	"SUBB", | ||||
| 	"SUBL", | ||||
| 	"SUBW", | ||||
| 	"SYSCALL", | ||||
| 	"TESTB", | ||||
| 	"TESTL", | ||||
| 	"TESTW", | ||||
| 	"VERR", | ||||
| 	"VERW", | ||||
| 	"WAIT", | ||||
| 	"WORD", | ||||
| 	"XCHGB", | ||||
| 	"XCHGL", | ||||
| 	"XCHGW", | ||||
| 	"XLAT", | ||||
| 	"XORB", | ||||
| 	"XORL", | ||||
| 	"XORW", | ||||
| 	"FMOVB", | ||||
| 	"FMOVBP", | ||||
| 	"FMOVD", | ||||
| 	"FMOVDP", | ||||
| 	"FMOVF", | ||||
| 	"FMOVFP", | ||||
| 	"FMOVL", | ||||
| 	"FMOVLP", | ||||
| 	"FMOVV", | ||||
| 	"FMOVVP", | ||||
| 	"FMOVW", | ||||
| 	"FMOVWP", | ||||
| 	"FMOVX", | ||||
| 	"FMOVXP", | ||||
| 	"FCOMD", | ||||
| 	"FCOMDP", | ||||
| 	"FCOMDPP", | ||||
| 	"FCOMF", | ||||
| 	"FCOMFP", | ||||
| 	"FCOML", | ||||
| 	"FCOMLP", | ||||
| 	"FCOMW", | ||||
| 	"FCOMWP", | ||||
| 	"FUCOM", | ||||
| 	"FUCOMP", | ||||
| 	"FUCOMPP", | ||||
| 	"FADDDP", | ||||
| 	"FADDW", | ||||
| 	"FADDL", | ||||
| 	"FADDF", | ||||
| 	"FADDD", | ||||
| 	"FMULDP", | ||||
| 	"FMULW", | ||||
| 	"FMULL", | ||||
| 	"FMULF", | ||||
| 	"FMULD", | ||||
| 	"FSUBDP", | ||||
| 	"FSUBW", | ||||
| 	"FSUBL", | ||||
| 	"FSUBF", | ||||
| 	"FSUBD", | ||||
| 	"FSUBRDP", | ||||
| 	"FSUBRW", | ||||
| 	"FSUBRL", | ||||
| 	"FSUBRF", | ||||
| 	"FSUBRD", | ||||
| 	"FDIVDP", | ||||
| 	"FDIVW", | ||||
| 	"FDIVL", | ||||
| 	"FDIVF", | ||||
| 	"FDIVD", | ||||
| 	"FDIVRDP", | ||||
| 	"FDIVRW", | ||||
| 	"FDIVRL", | ||||
| 	"FDIVRF", | ||||
| 	"FDIVRD", | ||||
| 	"FXCHD", | ||||
| 	"FFREE", | ||||
| 	"FLDCW", | ||||
| 	"FLDENV", | ||||
| 	"FRSTOR", | ||||
| 	"FSAVE", | ||||
| 	"FSTCW", | ||||
| 	"FSTENV", | ||||
| 	"FSTSW", | ||||
| 	"F2XM1", | ||||
| 	"FABS", | ||||
| 	"FCHS", | ||||
| 	"FCLEX", | ||||
| 	"FCOS", | ||||
| 	"FDECSTP", | ||||
| 	"FINCSTP", | ||||
| 	"FINIT", | ||||
| 	"FLD1", | ||||
| 	"FLDL2E", | ||||
| 	"FLDL2T", | ||||
| 	"FLDLG2", | ||||
| 	"FLDLN2", | ||||
| 	"FLDPI", | ||||
| 	"FLDZ", | ||||
| 	"FNOP", | ||||
| 	"FPATAN", | ||||
| 	"FPREM", | ||||
| 	"FPREM1", | ||||
| 	"FPTAN", | ||||
| 	"FRNDINT", | ||||
| 	"FSCALE", | ||||
| 	"FSIN", | ||||
| 	"FSINCOS", | ||||
| 	"FSQRT", | ||||
| 	"FTST", | ||||
| 	"FXAM", | ||||
| 	"FXTRACT", | ||||
| 	"FYL2X", | ||||
| 	"FYL2XP1", | ||||
| 	"CMPXCHGB", | ||||
| 	"CMPXCHGL", | ||||
| 	"CMPXCHGW", | ||||
| 	"CMPXCHG8B", | ||||
| 	"CPUID", | ||||
| 	"INVD", | ||||
| 	"INVLPG", | ||||
| 	"LFENCE", | ||||
| 	"MFENCE", | ||||
| 	"MOVNTIL", | ||||
| 	"RDMSR", | ||||
| 	"RDPMC", | ||||
| 	"RDTSC", | ||||
| 	"RSM", | ||||
| 	"SFENCE", | ||||
| 	"SYSRET", | ||||
| 	"WBINVD", | ||||
| 	"WRMSR", | ||||
| 	"XADDB", | ||||
| 	"XADDL", | ||||
| 	"XADDW", | ||||
| 	"CMOVLCC", | ||||
| 	"CMOVLCS", | ||||
| 	"CMOVLEQ", | ||||
| 	"CMOVLGE", | ||||
| 	"CMOVLGT", | ||||
| 	"CMOVLHI", | ||||
| 	"CMOVLLE", | ||||
| 	"CMOVLLS", | ||||
| 	"CMOVLLT", | ||||
| 	"CMOVLMI", | ||||
| 	"CMOVLNE", | ||||
| 	"CMOVLOC", | ||||
| 	"CMOVLOS", | ||||
| 	"CMOVLPC", | ||||
| 	"CMOVLPL", | ||||
| 	"CMOVLPS", | ||||
| 	"CMOVQCC", | ||||
| 	"CMOVQCS", | ||||
| 	"CMOVQEQ", | ||||
| 	"CMOVQGE", | ||||
| 	"CMOVQGT", | ||||
| 	"CMOVQHI", | ||||
| 	"CMOVQLE", | ||||
| 	"CMOVQLS", | ||||
| 	"CMOVQLT", | ||||
| 	"CMOVQMI", | ||||
| 	"CMOVQNE", | ||||
| 	"CMOVQOC", | ||||
| 	"CMOVQOS", | ||||
| 	"CMOVQPC", | ||||
| 	"CMOVQPL", | ||||
| 	"CMOVQPS", | ||||
| 	"CMOVWCC", | ||||
| 	"CMOVWCS", | ||||
| 	"CMOVWEQ", | ||||
| 	"CMOVWGE", | ||||
| 	"CMOVWGT", | ||||
| 	"CMOVWHI", | ||||
| 	"CMOVWLE", | ||||
| 	"CMOVWLS", | ||||
| 	"CMOVWLT", | ||||
| 	"CMOVWMI", | ||||
| 	"CMOVWNE", | ||||
| 	"CMOVWOC", | ||||
| 	"CMOVWOS", | ||||
| 	"CMOVWPC", | ||||
| 	"CMOVWPL", | ||||
| 	"CMOVWPS", | ||||
| 	"ADCQ", | ||||
| 	"ADDQ", | ||||
| 	"ANDQ", | ||||
| 	"BSFQ", | ||||
| 	"BSRQ", | ||||
| 	"BTCQ", | ||||
| 	"BTQ", | ||||
| 	"BTRQ", | ||||
| 	"BTSQ", | ||||
| 	"CMPQ", | ||||
| 	"CMPSQ", | ||||
| 	"CMPXCHGQ", | ||||
| 	"CQO", | ||||
| 	"DIVQ", | ||||
| 	"IDIVQ", | ||||
| 	"IMULQ", | ||||
| 	"IRETQ", | ||||
| 	"JCXZQ", | ||||
| 	"LEAQ", | ||||
| 	"LEAVEQ", | ||||
| 	"LODSQ", | ||||
| 	"MOVQ", | ||||
| 	"MOVLQSX", | ||||
| 	"MOVLQZX", | ||||
| 	"MOVNTIQ", | ||||
| 	"MOVSQ", | ||||
| 	"MULQ", | ||||
| 	"NEGQ", | ||||
| 	"NOTQ", | ||||
| 	"ORQ", | ||||
| 	"POPFQ", | ||||
| 	"POPQ", | ||||
| 	"PUSHFQ", | ||||
| 	"PUSHQ", | ||||
| 	"RCLQ", | ||||
| 	"RCRQ", | ||||
| 	"ROLQ", | ||||
| 	"RORQ", | ||||
| 	"QUAD", | ||||
| 	"SALQ", | ||||
| 	"SARQ", | ||||
| 	"SBBQ", | ||||
| 	"SCASQ", | ||||
| 	"SHLQ", | ||||
| 	"SHRQ", | ||||
| 	"STOSQ", | ||||
| 	"SUBQ", | ||||
| 	"TESTQ", | ||||
| 	"XADDQ", | ||||
| 	"XCHGQ", | ||||
| 	"XORQ", | ||||
| 	"XGETBV", | ||||
| 	"ADDPD", | ||||
| 	"ADDPS", | ||||
| 	"ADDSD", | ||||
| 	"ADDSS", | ||||
| 	"ANDNL", | ||||
| 	"ANDNQ", | ||||
| 	"ANDNPD", | ||||
| 	"ANDNPS", | ||||
| 	"ANDPD", | ||||
| 	"ANDPS", | ||||
| 	"BEXTRL", | ||||
| 	"BEXTRQ", | ||||
| 	"BLSIL", | ||||
| 	"BLSIQ", | ||||
| 	"BLSMSKL", | ||||
| 	"BLSMSKQ", | ||||
| 	"BLSRL", | ||||
| 	"BLSRQ", | ||||
| 	"BZHIL", | ||||
| 	"BZHIQ", | ||||
| 	"CMPPD", | ||||
| 	"CMPPS", | ||||
| 	"CMPSD", | ||||
| 	"CMPSS", | ||||
| 	"COMISD", | ||||
| 	"COMISS", | ||||
| 	"CVTPD2PL", | ||||
| 	"CVTPD2PS", | ||||
| 	"CVTPL2PD", | ||||
| 	"CVTPL2PS", | ||||
| 	"CVTPS2PD", | ||||
| 	"CVTPS2PL", | ||||
| 	"CVTSD2SL", | ||||
| 	"CVTSD2SQ", | ||||
| 	"CVTSD2SS", | ||||
| 	"CVTSL2SD", | ||||
| 	"CVTSL2SS", | ||||
| 	"CVTSQ2SD", | ||||
| 	"CVTSQ2SS", | ||||
| 	"CVTSS2SD", | ||||
| 	"CVTSS2SL", | ||||
| 	"CVTSS2SQ", | ||||
| 	"CVTTPD2PL", | ||||
| 	"CVTTPS2PL", | ||||
| 	"CVTTSD2SL", | ||||
| 	"CVTTSD2SQ", | ||||
| 	"CVTTSS2SL", | ||||
| 	"CVTTSS2SQ", | ||||
| 	"DIVPD", | ||||
| 	"DIVPS", | ||||
| 	"DIVSD", | ||||
| 	"DIVSS", | ||||
| 	"EMMS", | ||||
| 	"FXRSTOR", | ||||
| 	"FXRSTOR64", | ||||
| 	"FXSAVE", | ||||
| 	"FXSAVE64", | ||||
| 	"LDDQU", | ||||
| 	"LDMXCSR", | ||||
| 	"MASKMOVOU", | ||||
| 	"MASKMOVQ", | ||||
| 	"MAXPD", | ||||
| 	"MAXPS", | ||||
| 	"MAXSD", | ||||
| 	"MAXSS", | ||||
| 	"MINPD", | ||||
| 	"MINPS", | ||||
| 	"MINSD", | ||||
| 	"MINSS", | ||||
| 	"MOVAPD", | ||||
| 	"MOVAPS", | ||||
| 	"MOVOU", | ||||
| 	"MOVHLPS", | ||||
| 	"MOVHPD", | ||||
| 	"MOVHPS", | ||||
| 	"MOVLHPS", | ||||
| 	"MOVLPD", | ||||
| 	"MOVLPS", | ||||
| 	"MOVMSKPD", | ||||
| 	"MOVMSKPS", | ||||
| 	"MOVNTO", | ||||
| 	"MOVNTPD", | ||||
| 	"MOVNTPS", | ||||
| 	"MOVNTQ", | ||||
| 	"MOVO", | ||||
| 	"MOVQOZX", | ||||
| 	"MOVSD", | ||||
| 	"MOVSS", | ||||
| 	"MOVUPD", | ||||
| 	"MOVUPS", | ||||
| 	"MULPD", | ||||
| 	"MULPS", | ||||
| 	"MULSD", | ||||
| 	"MULSS", | ||||
| 	"MULXL", | ||||
| 	"MULXQ", | ||||
| 	"ORPD", | ||||
| 	"ORPS", | ||||
| 	"PACKSSLW", | ||||
| 	"PACKSSWB", | ||||
| 	"PACKUSWB", | ||||
| 	"PADDB", | ||||
| 	"PADDL", | ||||
| 	"PADDQ", | ||||
| 	"PADDSB", | ||||
| 	"PADDSW", | ||||
| 	"PADDUSB", | ||||
| 	"PADDUSW", | ||||
| 	"PADDW", | ||||
| 	"PAND", | ||||
| 	"PANDN", | ||||
| 	"PAVGB", | ||||
| 	"PAVGW", | ||||
| 	"PCMPEQB", | ||||
| 	"PCMPEQL", | ||||
| 	"PCMPEQW", | ||||
| 	"PCMPGTB", | ||||
| 	"PCMPGTL", | ||||
| 	"PCMPGTW", | ||||
| 	"PDEPL", | ||||
| 	"PDEPQ", | ||||
| 	"PEXTL", | ||||
| 	"PEXTQ", | ||||
| 	"PEXTRB", | ||||
| 	"PEXTRD", | ||||
| 	"PEXTRQ", | ||||
| 	"PEXTRW", | ||||
| 	"PHADDD", | ||||
| 	"PHADDSW", | ||||
| 	"PHADDW", | ||||
| 	"PHMINPOSUW", | ||||
| 	"PHSUBD", | ||||
| 	"PHSUBSW", | ||||
| 	"PHSUBW", | ||||
| 	"PINSRB", | ||||
| 	"PINSRD", | ||||
| 	"PINSRQ", | ||||
| 	"PINSRW", | ||||
| 	"PMADDWL", | ||||
| 	"PMAXSW", | ||||
| 	"PMAXUB", | ||||
| 	"PMINSW", | ||||
| 	"PMINUB", | ||||
| 	"PMOVMSKB", | ||||
| 	"PMOVSXBD", | ||||
| 	"PMOVSXBQ", | ||||
| 	"PMOVSXBW", | ||||
| 	"PMOVSXDQ", | ||||
| 	"PMOVSXWD", | ||||
| 	"PMOVSXWQ", | ||||
| 	"PMOVZXBD", | ||||
| 	"PMOVZXBQ", | ||||
| 	"PMOVZXBW", | ||||
| 	"PMOVZXDQ", | ||||
| 	"PMOVZXWD", | ||||
| 	"PMOVZXWQ", | ||||
| 	"PMULDQ", | ||||
| 	"PMULHUW", | ||||
| 	"PMULHW", | ||||
| 	"PMULLD", | ||||
| 	"PMULLW", | ||||
| 	"PMULULQ", | ||||
| 	"POR", | ||||
| 	"PSADBW", | ||||
| 	"PSHUFB", | ||||
| 	"PSHUFHW", | ||||
| 	"PSHUFL", | ||||
| 	"PSHUFLW", | ||||
| 	"PSHUFW", | ||||
| 	"PSLLL", | ||||
| 	"PSLLO", | ||||
| 	"PSLLQ", | ||||
| 	"PSLLW", | ||||
| 	"PSRAL", | ||||
| 	"PSRAW", | ||||
| 	"PSRLL", | ||||
| 	"PSRLO", | ||||
| 	"PSRLQ", | ||||
| 	"PSRLW", | ||||
| 	"PSUBB", | ||||
| 	"PSUBL", | ||||
| 	"PSUBQ", | ||||
| 	"PSUBSB", | ||||
| 	"PSUBSW", | ||||
| 	"PSUBUSB", | ||||
| 	"PSUBUSW", | ||||
| 	"PSUBW", | ||||
| 	"PUNPCKHBW", | ||||
| 	"PUNPCKHLQ", | ||||
| 	"PUNPCKHQDQ", | ||||
| 	"PUNPCKHWL", | ||||
| 	"PUNPCKLBW", | ||||
| 	"PUNPCKLLQ", | ||||
| 	"PUNPCKLQDQ", | ||||
| 	"PUNPCKLWL", | ||||
| 	"PXOR", | ||||
| 	"RCPPS", | ||||
| 	"RCPSS", | ||||
| 	"RSQRTPS", | ||||
| 	"RSQRTSS", | ||||
| 	"SARXL", | ||||
| 	"SARXQ", | ||||
| 	"SHLXL", | ||||
| 	"SHLXQ", | ||||
| 	"SHRXL", | ||||
| 	"SHRXQ", | ||||
| 	"SHUFPD", | ||||
| 	"SHUFPS", | ||||
| 	"SQRTPD", | ||||
| 	"SQRTPS", | ||||
| 	"SQRTSD", | ||||
| 	"SQRTSS", | ||||
| 	"STMXCSR", | ||||
| 	"SUBPD", | ||||
| 	"SUBPS", | ||||
| 	"SUBSD", | ||||
| 	"SUBSS", | ||||
| 	"UCOMISD", | ||||
| 	"UCOMISS", | ||||
| 	"UNPCKHPD", | ||||
| 	"UNPCKHPS", | ||||
| 	"UNPCKLPD", | ||||
| 	"UNPCKLPS", | ||||
| 	"XORPD", | ||||
| 	"XORPS", | ||||
| 	"PCMPESTRI", | ||||
| 	"RETFW", | ||||
| 	"RETFL", | ||||
| 	"RETFQ", | ||||
| 	"SWAPGS", | ||||
| 	"MODE", | ||||
| 	"CRC32B", | ||||
| 	"CRC32Q", | ||||
| 	"IMUL3Q", | ||||
| 	"PREFETCHT0", | ||||
| 	"PREFETCHT1", | ||||
| 	"PREFETCHT2", | ||||
| 	"PREFETCHNTA", | ||||
| 	"MOVQL", | ||||
| 	"BSWAPL", | ||||
| 	"BSWAPQ", | ||||
| 	"AESENC", | ||||
| 	"AESENCLAST", | ||||
| 	"AESDEC", | ||||
| 	"AESDECLAST", | ||||
| 	"AESIMC", | ||||
| 	"AESKEYGENASSIST", | ||||
| 	"ROUNDPS", | ||||
| 	"ROUNDSS", | ||||
| 	"ROUNDPD", | ||||
| 	"ROUNDSD", | ||||
| 	"MOVDDUP", | ||||
| 	"MOVSHDUP", | ||||
| 	"MOVSLDUP", | ||||
| 	"PSHUFD", | ||||
| 	"PCLMULQDQ", | ||||
| 	"VZEROUPPER", | ||||
| 	"VMOVDQU", | ||||
| 	"VMOVNTDQ", | ||||
| 	"VMOVDQA", | ||||
| 	"VPCMPEQB", | ||||
| 	"VPXOR", | ||||
| 	"VPMOVMSKB", | ||||
| 	"VPAND", | ||||
| 	"VPTEST", | ||||
| 	"VPBROADCASTB", | ||||
| 	"VPSHUFB", | ||||
| 	"VPSHUFD", | ||||
| 	"VPERM2F128", | ||||
| 	"VPALIGNR", | ||||
| 	"VPADDQ", | ||||
| 	"VPADDD", | ||||
| 	"VPSRLDQ", | ||||
| 	"VPSLLDQ", | ||||
| 	"VPSRLQ", | ||||
| 	"VPSLLQ", | ||||
| 	"VPSRLD", | ||||
| 	"VPSLLD", | ||||
| 	"VPOR", | ||||
| 	"VPBLENDD", | ||||
| 	"VINSERTI128", | ||||
| 	"VPERM2I128", | ||||
| 	"RORXL", | ||||
| 	"RORXQ", | ||||
| 	"VBROADCASTSS", | ||||
| 	"VBROADCASTSD", | ||||
| 	"VMOVDDUP", | ||||
| 	"VMOVSHDUP", | ||||
| 	"VMOVSLDUP", | ||||
| 	"JCXZW", | ||||
| 	"FCMOVCC", | ||||
| 	"FCMOVCS", | ||||
| 	"FCMOVEQ", | ||||
| 	"FCMOVHI", | ||||
| 	"FCMOVLS", | ||||
| 	"FCMOVNE", | ||||
| 	"FCMOVNU", | ||||
| 	"FCMOVUN", | ||||
| 	"FCOMI", | ||||
| 	"FCOMIP", | ||||
| 	"FUCOMI", | ||||
| 	"FUCOMIP", | ||||
| 	"XACQUIRE", | ||||
| 	"XRELEASE", | ||||
| 	"XBEGIN", | ||||
| 	"XEND", | ||||
| 	"XABORT", | ||||
| 	"XTEST", | ||||
| 	"LAST", | ||||
| } | ||||
							
								
								
									
										4536
									
								
								vendor/github.com/google/gops/internal/obj/x86/asm6.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4536
									
								
								vendor/github.com/google/gops/internal/obj/x86/asm6.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										181
									
								
								vendor/github.com/google/gops/internal/obj/x86/list6.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								vendor/github.com/google/gops/internal/obj/x86/list6.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,181 @@ | ||||
| // Inferno utils/6c/list.c | ||||
| // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6c/list.c | ||||
| // | ||||
| //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | ||||
| //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Portions Copyright © 1997-1999 Vita Nuova Limited | ||||
| //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) | ||||
| //	Portions Copyright © 2004,2006 Bruce Ellis | ||||
| //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | ||||
| //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others | ||||
| //	Portions Copyright © 2009 The Go Authors. All rights reserved. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| // of this software and associated documentation files (the "Software"), to deal | ||||
| // in the Software without restriction, including without limitation the rights | ||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| // copies of the Software, and to permit persons to whom the Software is | ||||
| // furnished to do so, subject to the following conditions: | ||||
| // | ||||
| // The above copyright notice and this permission notice shall be included in | ||||
| // all copies or substantial portions of the Software. | ||||
| // | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| // THE SOFTWARE. | ||||
|  | ||||
| package x86 | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/google/gops/internal/obj" | ||||
| ) | ||||
|  | ||||
| var Register = []string{ | ||||
| 	"AL", /* [D_AL] */ | ||||
| 	"CL", | ||||
| 	"DL", | ||||
| 	"BL", | ||||
| 	"SPB", | ||||
| 	"BPB", | ||||
| 	"SIB", | ||||
| 	"DIB", | ||||
| 	"R8B", | ||||
| 	"R9B", | ||||
| 	"R10B", | ||||
| 	"R11B", | ||||
| 	"R12B", | ||||
| 	"R13B", | ||||
| 	"R14B", | ||||
| 	"R15B", | ||||
| 	"AX", /* [D_AX] */ | ||||
| 	"CX", | ||||
| 	"DX", | ||||
| 	"BX", | ||||
| 	"SP", | ||||
| 	"BP", | ||||
| 	"SI", | ||||
| 	"DI", | ||||
| 	"R8", | ||||
| 	"R9", | ||||
| 	"R10", | ||||
| 	"R11", | ||||
| 	"R12", | ||||
| 	"R13", | ||||
| 	"R14", | ||||
| 	"R15", | ||||
| 	"AH", | ||||
| 	"CH", | ||||
| 	"DH", | ||||
| 	"BH", | ||||
| 	"F0", /* [D_F0] */ | ||||
| 	"F1", | ||||
| 	"F2", | ||||
| 	"F3", | ||||
| 	"F4", | ||||
| 	"F5", | ||||
| 	"F6", | ||||
| 	"F7", | ||||
| 	"M0", | ||||
| 	"M1", | ||||
| 	"M2", | ||||
| 	"M3", | ||||
| 	"M4", | ||||
| 	"M5", | ||||
| 	"M6", | ||||
| 	"M7", | ||||
| 	"X0", | ||||
| 	"X1", | ||||
| 	"X2", | ||||
| 	"X3", | ||||
| 	"X4", | ||||
| 	"X5", | ||||
| 	"X6", | ||||
| 	"X7", | ||||
| 	"X8", | ||||
| 	"X9", | ||||
| 	"X10", | ||||
| 	"X11", | ||||
| 	"X12", | ||||
| 	"X13", | ||||
| 	"X14", | ||||
| 	"X15", | ||||
| 	"Y0", | ||||
| 	"Y1", | ||||
| 	"Y2", | ||||
| 	"Y3", | ||||
| 	"Y4", | ||||
| 	"Y5", | ||||
| 	"Y6", | ||||
| 	"Y7", | ||||
| 	"Y8", | ||||
| 	"Y9", | ||||
| 	"Y10", | ||||
| 	"Y11", | ||||
| 	"Y12", | ||||
| 	"Y13", | ||||
| 	"Y14", | ||||
| 	"Y15", | ||||
| 	"CS", /* [D_CS] */ | ||||
| 	"SS", | ||||
| 	"DS", | ||||
| 	"ES", | ||||
| 	"FS", | ||||
| 	"GS", | ||||
| 	"GDTR", /* [D_GDTR] */ | ||||
| 	"IDTR", /* [D_IDTR] */ | ||||
| 	"LDTR", /* [D_LDTR] */ | ||||
| 	"MSW",  /* [D_MSW] */ | ||||
| 	"TASK", /* [D_TASK] */ | ||||
| 	"CR0",  /* [D_CR] */ | ||||
| 	"CR1", | ||||
| 	"CR2", | ||||
| 	"CR3", | ||||
| 	"CR4", | ||||
| 	"CR5", | ||||
| 	"CR6", | ||||
| 	"CR7", | ||||
| 	"CR8", | ||||
| 	"CR9", | ||||
| 	"CR10", | ||||
| 	"CR11", | ||||
| 	"CR12", | ||||
| 	"CR13", | ||||
| 	"CR14", | ||||
| 	"CR15", | ||||
| 	"DR0", /* [D_DR] */ | ||||
| 	"DR1", | ||||
| 	"DR2", | ||||
| 	"DR3", | ||||
| 	"DR4", | ||||
| 	"DR5", | ||||
| 	"DR6", | ||||
| 	"DR7", | ||||
| 	"TR0", /* [D_TR] */ | ||||
| 	"TR1", | ||||
| 	"TR2", | ||||
| 	"TR3", | ||||
| 	"TR4", | ||||
| 	"TR5", | ||||
| 	"TR6", | ||||
| 	"TR7", | ||||
| 	"TLS",    /* [D_TLS] */ | ||||
| 	"MAXREG", /* [MAXREG] */ | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	obj.RegisterRegister(REG_AL, REG_AL+len(Register), Rconv) | ||||
| 	obj.RegisterOpcode(obj.ABaseAMD64, Anames) | ||||
| } | ||||
|  | ||||
| func Rconv(r int) string { | ||||
| 	if REG_AL <= r && r-REG_AL < len(Register) { | ||||
| 		return Register[r-REG_AL] | ||||
| 	} | ||||
| 	return fmt.Sprintf("Rgok(%d)", r-obj.RBaseAMD64) | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user