blob: 478e6de8fa2ac49d9216a162104a37a9406bf470 [file] [log] [blame]
Colin Cross5498f852018-01-03 23:39:54 -08001// Copyright 2018 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package main
16
17import (
18 "debug/macho"
19 "fmt"
20 "io"
Colin Crossc4a18e02018-02-23 22:43:24 -080021 "sort"
Colin Cross5498f852018-01-03 23:39:54 -080022)
23
24func findMachoSymbol(r io.ReaderAt, symbolName string) (uint64, uint64, error) {
25 machoFile, err := macho.NewFile(r)
26 if err != nil {
27 return maxUint64, maxUint64, cantParseError{err}
28 }
29
Colin Cross64c6d4b2018-02-23 17:10:34 -080030 // symbols in macho files seem to be prefixed with an underscore
Colin Cross5498f852018-01-03 23:39:54 -080031 symbolName = "_" + symbolName
32
Colin Crossc4a18e02018-02-23 22:43:24 -080033 symbols := machoFile.Symtab.Syms
34 sort.Slice(symbols, func(i, j int) bool {
35 if symbols[i].Sect != symbols[j].Sect {
36 return symbols[i].Sect < symbols[j].Sect
37 }
38 return symbols[i].Value < symbols[j].Value
39 })
40
Colin Crossdfce7642018-02-28 13:05:39 -080041 for _, symbol := range symbols {
42 if symbol.Name == symbolName && symbol.Sect != 0 {
43 // Find the next symbol in the same section with a higher address
44 n := sort.Search(len(symbols), func(i int) bool {
45 return symbols[i].Sect == symbol.Sect &&
46 symbols[i].Value > symbol.Value
47 })
48
49 section := machoFile.Sections[symbol.Sect-1]
50
51 var end uint64
52 if n < len(symbols) {
53 end = symbols[n].Value
54 } else {
55 end = section.Addr + section.Size
Colin Cross5498f852018-01-03 23:39:54 -080056 }
Colin Crossdfce7642018-02-28 13:05:39 -080057
58 if end <= symbol.Value && end > symbol.Value+4096 {
59 return maxUint64, maxUint64, fmt.Errorf("symbol end address does not seem valid, %x:%x", symbol.Value, end)
60 }
61
62 size := end - symbol.Value - 1
63 offset := uint64(section.Offset) + (symbol.Value - section.Addr)
64
65 return offset, size, nil
Colin Cross5498f852018-01-03 23:39:54 -080066 }
67 }
68
69 return maxUint64, maxUint64, fmt.Errorf("symbol not found")
70}