Skip to content

Instantly share code, notes, and snippets.

@mmcloughlin
Created September 30, 2018 22:14
Show Gist options
  • Save mmcloughlin/6167deb9591994183e96210d612c88a0 to your computer and use it in GitHub Desktop.
Save mmcloughlin/6167deb9591994183e96210d612c88a0 to your computer and use it in GitHub Desktop.
package main
import (
"flag"
"io/ioutil"
"log"
"objfile"
"os"
"path/filepath"
"regexp"
)
func SymbolText(filename string) (map[string][]byte, error) {
f, err := objfile.Open(filename)
if err != nil {
return nil, err
}
textStart, text, err := f.Text()
if err != nil {
return nil, err
}
syms, err := f.Symbols()
if err != nil {
return nil, err
}
code := map[string][]byte{}
for _, s := range syms {
if s.Code != 'T' && s.Code != 't' {
continue
}
if s.Name == "runtime.etext" {
break
}
symStart := s.Addr - textStart
symEnd := symStart + uint64(s.Size)
code[s.Name] = text[symStart:symEnd]
}
return code, nil
}
func WriteSymbolData(directory, name string, b []byte, perm os.FileMode) error {
path := filepath.Join(directory, name+".bin")
if err := os.MkdirAll(filepath.Dir(path), perm|0111); err != nil {
return err
}
return ioutil.WriteFile(path, b, perm)
}
var (
dir = flag.String("output", ".", "output directory")
filter = flag.String("s", ".", "output symbols matching this regular expression")
)
func main() {
flag.Parse()
objectFilename := flag.Arg(0)
re, err := regexp.Compile(*filter)
if err != nil {
log.Fatal(err)
}
s, err := SymbolText(objectFilename)
if err != nil {
log.Fatal(err)
}
for name, b := range s {
if !re.MatchString(name) {
log.Printf("skip symbol %s", name)
continue
}
if err := WriteSymbolData(*dir, name, b, 0660); err != nil {
log.Fatal(err)
}
}
}
#!/bin/bash -ex
# Extract some internal packages from go standard library for our own use.
eval $(go env)
prefix=cmd/internal
pkgs=(objfile src goobj objabi sys)
rm -rf vendor
cp -r ${GOROOT}/src/cmd/vendor .
for pkg in ${pkgs[@]}; do
from=${GOROOT}/src/${prefix}/${pkg}
to=vendor/${pkg}
mkdir -p ${to}
cp -r ${from}/* ${to}
sed -e 's/cmd\/internal\///' -i '' ${to}/*.go
done
find vendor -type f -name '*_test.go' -exec rm {} \;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment