blob: 82fdff8cf8f3e2232607194a2f1a76938428954d [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/pe"
19 "fmt"
20 "io"
21 "sort"
22)
23
24func findPESymbol(r io.ReaderAt, symbolName string) (uint64, uint64, error) {
25 peFile, err := pe.NewFile(r)
26 if err != nil {
27 return maxUint64, maxUint64, cantParseError{err}
28 }
29
Colin Cross64c6d4b2018-02-23 17:10:34 -080030 if peFile.FileHeader.Machine == pe.IMAGE_FILE_MACHINE_I386 {
31 // symbols in win32 exes seem to be prefixed with an underscore
32 symbolName = "_" + symbolName
33 }
34
Colin Crossdfce7642018-02-28 13:05:39 -080035 symbols := peFile.Symbols
36 sort.Slice(symbols, func(i, j int) bool {
37 if symbols[i].SectionNumber != symbols[j].SectionNumber {
38 return symbols[i].SectionNumber < symbols[j].SectionNumber
Colin Cross5498f852018-01-03 23:39:54 -080039 }
Colin Crossdfce7642018-02-28 13:05:39 -080040 return symbols[i].Value < symbols[j].Value
Colin Cross5498f852018-01-03 23:39:54 -080041 })
42
Colin Crossdfce7642018-02-28 13:05:39 -080043 for _, symbol := range symbols {
Colin Cross5498f852018-01-03 23:39:54 -080044 if symbol.Name == symbolName {
Colin Crossdfce7642018-02-28 13:05:39 -080045 // Find the next symbol (n the same section with a higher address
46 n := sort.Search(len(symbols), func(i int) bool {
47 return symbols[i].SectionNumber == symbol.SectionNumber &&
48 symbols[i].Value > symbol.Value
49 })
50
51 section := peFile.Sections[symbol.SectionNumber-1]
52
53 var end uint32
54 if n < len(symbols) {
55 end = symbols[n].Value
56 } else {
57 end = section.Size
Colin Cross5498f852018-01-03 23:39:54 -080058 }
Colin Crossdfce7642018-02-28 13:05:39 -080059
60 if end <= symbol.Value && end > symbol.Value+4096 {
61 return maxUint64, maxUint64, fmt.Errorf("symbol end address does not seem valid, %x:%x", symbol.Value, end)
62 }
63
64 size := end - symbol.Value - 1
65 offset := section.Offset + symbol.Value
66
67 return uint64(offset), uint64(size), nil
Colin Cross5498f852018-01-03 23:39:54 -080068 }
69 }
70
71 return maxUint64, maxUint64, fmt.Errorf("symbol not found")
72}