diff options
author | 2018-10-15 00:35:59 -0700 | |
---|---|---|
committer | 2018-10-22 15:46:03 -0700 | |
commit | 2249dc892d8fb95ad2b0ce0eb4278110534f31e4 (patch) | |
tree | aa7a90e6145c35f5e9d9bcba52b5fd337940a45a /symbol_inject/macho.go | |
parent | 4f644da0ad7c2ff648733b43d59b19b8593195a4 (diff) |
Turn symbol_inject into a reusable package
Bug: 31559095
Test: m blueprint_tools
Change-Id: I0f7a9f14111af26d753db547c6de313a7079658a
Diffstat (limited to 'symbol_inject/macho.go')
-rw-r--r-- | symbol_inject/macho.go | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/symbol_inject/macho.go b/symbol_inject/macho.go new file mode 100644 index 000000000..6ee3f4fbd --- /dev/null +++ b/symbol_inject/macho.go @@ -0,0 +1,97 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package symbol_inject + +import ( + "debug/macho" + "fmt" + "io" + "sort" + "strings" +) + +func machoSymbolsFromFile(r io.ReaderAt) (*File, error) { + machoFile, err := macho.NewFile(r) + if err != nil { + return nil, cantParseError{err} + } + + return extractMachoSymbols(machoFile) +} + +func extractMachoSymbols(machoFile *macho.File) (*File, error) { + symbols := machoFile.Symtab.Syms + sort.SliceStable(symbols, func(i, j int) bool { + if symbols[i].Sect != symbols[j].Sect { + return symbols[i].Sect < symbols[j].Sect + } + return symbols[i].Value < symbols[j].Value + }) + + file := &File{} + + for _, section := range machoFile.Sections { + file.Sections = append(file.Sections, &Section{ + Name: section.Name, + Addr: section.Addr, + Offset: uint64(section.Offset), + Size: section.Size, + }) + } + + for _, symbol := range symbols { + if symbol.Sect > 0 { + section := file.Sections[symbol.Sect-1] + file.Symbols = append(file.Symbols, &Symbol{ + // symbols in macho files seem to be prefixed with an underscore + Name: strings.TrimPrefix(symbol.Name, "_"), + // MachO symbol value is virtual address of the symbol, convert it to offset into the section. + Addr: symbol.Value - section.Addr, + // MachO symbols don't have size information. + Size: 0, + Section: section, + }) + } + } + + return file, nil +} + +func dumpMachoSymbols(r io.ReaderAt) error { + machoFile, err := macho.NewFile(r) + if err != nil { + return cantParseError{err} + } + + fmt.Println("&macho.File{") + + fmt.Println("\tSections: []*macho.Section{") + for _, section := range machoFile.Sections { + fmt.Printf("\t\t&macho.Section{SectionHeader: %#v},\n", section.SectionHeader) + } + fmt.Println("\t},") + + fmt.Println("\tSymtab: &macho.Symtab{") + fmt.Println("\t\tSyms: []macho.Symbol{") + for _, symbol := range machoFile.Symtab.Syms { + fmt.Printf("\t\t\t%#v,\n", symbol) + } + fmt.Println("\t\t},") + fmt.Println("\t},") + + fmt.Println("}") + + return nil +} |