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
diff --git a/cmd/symbol_inject/macho.go b/cmd/symbol_inject/macho.go
index 4a3ecc7..478e6de 100644
--- a/cmd/symbol_inject/macho.go
+++ b/cmd/symbol_inject/macho.go
@@ -38,37 +38,33 @@
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)
+
+ 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)
+ }
+
+ 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")
}
-
-func calculateMachoSymbolOffset(file *macho.File, symbol macho.Symbol, nextSymbol *macho.Symbol) (uint64, uint64, error) {
- section := file.Sections[symbol.Sect-1]
-
- var end uint64
- if nextSymbol != nil && nextSymbol.Sect != symbol.Sect {
- nextSymbol = nil
- }
- if nextSymbol != nil {
- end = nextSymbol.Value
- } else {
- end = section.Addr + section.Size
- }
-
- size := end - symbol.Value - 1
- offset := uint64(section.Offset) + (symbol.Value - section.Addr)
-
- return offset, size, nil
-}