diff options
author | Colin Cross <ccross@android.com> | 2018-02-28 13:05:39 -0800 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2018-02-28 15:04:59 -0800 |
commit | dfce764476b6be22907d555097b7346cfa16f0ca (patch) | |
tree | 0a35c3dd22cefeb0068f341b5739857872860a86 /cmd | |
parent | 0c74ad9381e33545e77596dd0e9208e5e215eae8 (diff) | |
download | build_soong-dfce764476b6be22907d555097b7346cfa16f0ca.tar.gz build_soong-dfce764476b6be22907d555097b7346cfa16f0ca.tar.bz2 build_soong-dfce764476b6be22907d555097b7346cfa16f0ca.zip |
Fix finding next symbol when multiple symbols have the same address
Some exe files have a .data symbol at the same address as the
soong_build_number symbol. If the .data symbol is after
soong_build_number in the symbol list, symbol_inject would think
the end address was the same as the start address, and use
uint32(-1) as the size.
Use sort.Search to find the first symbol whose section number is
the same as the target symbol, but whose address is higher than
the target symbol.
Test: manual
Change-Id: I51d6e53c6b906222ba68c5cf93be944843e23550
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/symbol_inject/macho.go | 50 | ||||
-rw-r--r-- | cmd/symbol_inject/pe.go | 54 |
2 files changed, 50 insertions, 54 deletions
diff --git a/cmd/symbol_inject/macho.go b/cmd/symbol_inject/macho.go index 4a3ecc74..478e6de8 100644 --- a/cmd/symbol_inject/macho.go +++ b/cmd/symbol_inject/macho.go @@ -38,37 +38,33 @@ func findMachoSymbol(r io.ReaderAt, symbolName string) (uint64, uint64, error) { return symbols[i].Value < symbols[j].Value }) - for i, symbol := range symbols { - if symbol.Sect == 0 { - continue - } - if symbol.Name == symbolName { - var nextSymbol *macho.Symbol - if i+1 < len(symbols) { - nextSymbol = &symbols[i+1] + for _, symbol := range symbols { + if symbol.Name == symbolName && symbol.Sect != 0 { + // Find the next symbol in the same section with a higher address + n := sort.Search(len(symbols), func(i int) bool { + return symbols[i].Sect == symbol.Sect && + symbols[i].Value > symbol.Value + }) + + section := machoFile.Sections[symbol.Sect-1] + + var end uint64 + if n < len(symbols) { + end = symbols[n].Value + } else { + end = section.Addr + section.Size } - return calculateMachoSymbolOffset(machoFile, symbol, nextSymbol) - } - } - return maxUint64, maxUint64, fmt.Errorf("symbol not found") -} + if end <= symbol.Value && end > symbol.Value+4096 { + return maxUint64, maxUint64, fmt.Errorf("symbol end address does not seem valid, %x:%x", symbol.Value, end) + } -func calculateMachoSymbolOffset(file *macho.File, symbol macho.Symbol, nextSymbol *macho.Symbol) (uint64, uint64, error) { - section := file.Sections[symbol.Sect-1] + size := end - symbol.Value - 1 + offset := uint64(section.Offset) + (symbol.Value - section.Addr) - var end uint64 - if nextSymbol != nil && nextSymbol.Sect != symbol.Sect { - nextSymbol = nil - } - if nextSymbol != nil { - end = nextSymbol.Value - } else { - end = section.Addr + section.Size + return offset, size, nil + } } - size := end - symbol.Value - 1 - offset := uint64(section.Offset) + (symbol.Value - section.Addr) - - return offset, size, nil + return maxUint64, maxUint64, fmt.Errorf("symbol not found") } diff --git a/cmd/symbol_inject/pe.go b/cmd/symbol_inject/pe.go index dad530d4..82fdff8c 100644 --- a/cmd/symbol_inject/pe.go +++ b/cmd/symbol_inject/pe.go @@ -32,41 +32,41 @@ func findPESymbol(r io.ReaderAt, symbolName string) (uint64, uint64, error) { symbolName = "_" + symbolName } - sort.Slice(peFile.Symbols, func(i, j int) bool { - if peFile.Symbols[i].SectionNumber != peFile.Symbols[j].SectionNumber { - return peFile.Symbols[i].SectionNumber < peFile.Symbols[j].SectionNumber + symbols := peFile.Symbols + sort.Slice(symbols, func(i, j int) bool { + if symbols[i].SectionNumber != symbols[j].SectionNumber { + return symbols[i].SectionNumber < symbols[j].SectionNumber } - return peFile.Symbols[i].Value < peFile.Symbols[j].Value + return symbols[i].Value < symbols[j].Value }) - for i, symbol := range peFile.Symbols { + for _, symbol := range symbols { if symbol.Name == symbolName { - var nextSymbol *pe.Symbol - if i+1 < len(peFile.Symbols) { - nextSymbol = peFile.Symbols[i+1] + // Find the next symbol (n the same section with a higher address + n := sort.Search(len(symbols), func(i int) bool { + return symbols[i].SectionNumber == symbol.SectionNumber && + symbols[i].Value > symbol.Value + }) + + section := peFile.Sections[symbol.SectionNumber-1] + + var end uint32 + if n < len(symbols) { + end = symbols[n].Value + } else { + end = section.Size } - return calculatePESymbolOffset(peFile, symbol, nextSymbol) - } - } - return maxUint64, maxUint64, fmt.Errorf("symbol not found") -} + if end <= symbol.Value && end > symbol.Value+4096 { + return maxUint64, maxUint64, fmt.Errorf("symbol end address does not seem valid, %x:%x", symbol.Value, end) + } -func calculatePESymbolOffset(file *pe.File, symbol *pe.Symbol, nextSymbol *pe.Symbol) (uint64, uint64, error) { - section := file.Sections[symbol.SectionNumber-1] + size := end - symbol.Value - 1 + offset := section.Offset + symbol.Value - var end uint32 - if nextSymbol != nil && nextSymbol.SectionNumber != symbol.SectionNumber { - nextSymbol = nil - } - if nextSymbol != nil { - end = nextSymbol.Value - } else { - end = section.Size + return uint64(offset), uint64(size), nil + } } - size := end - symbol.Value - 1 - offset := section.Offset + symbol.Value - - return uint64(offset), uint64(size), nil + return maxUint64, maxUint64, fmt.Errorf("symbol not found") } |