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
This commit is contained in:
parent
0c74ad9381
commit
dfce764476
|
@ -38,37 +38,33 @@ func findMachoSymbol(r io.ReaderAt, symbolName string) (uint64, uint64, error) {
|
||||||
return symbols[i].Value < symbols[j].Value
|
return symbols[i].Value < symbols[j].Value
|
||||||
})
|
})
|
||||||
|
|
||||||
for i, symbol := range symbols {
|
for _, symbol := range symbols {
|
||||||
if symbol.Sect == 0 {
|
if symbol.Name == symbolName && symbol.Sect != 0 {
|
||||||
continue
|
// Find the next symbol in the same section with a higher address
|
||||||
}
|
n := sort.Search(len(symbols), func(i int) bool {
|
||||||
if symbol.Name == symbolName {
|
return symbols[i].Sect == symbol.Sect &&
|
||||||
var nextSymbol *macho.Symbol
|
symbols[i].Value > symbol.Value
|
||||||
if i+1 < len(symbols) {
|
})
|
||||||
nextSymbol = &symbols[i+1]
|
|
||||||
}
|
|
||||||
return calculateMachoSymbolOffset(machoFile, symbol, nextSymbol)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return maxUint64, maxUint64, fmt.Errorf("symbol not found")
|
section := machoFile.Sections[symbol.Sect-1]
|
||||||
}
|
|
||||||
|
|
||||||
func calculateMachoSymbolOffset(file *macho.File, symbol macho.Symbol, nextSymbol *macho.Symbol) (uint64, uint64, error) {
|
|
||||||
section := file.Sections[symbol.Sect-1]
|
|
||||||
|
|
||||||
var end uint64
|
var end uint64
|
||||||
if nextSymbol != nil && nextSymbol.Sect != symbol.Sect {
|
if n < len(symbols) {
|
||||||
nextSymbol = nil
|
end = symbols[n].Value
|
||||||
}
|
|
||||||
if nextSymbol != nil {
|
|
||||||
end = nextSymbol.Value
|
|
||||||
} else {
|
} else {
|
||||||
end = section.Addr + section.Size
|
end = section.Addr + section.Size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
size := end - symbol.Value - 1
|
||||||
offset := uint64(section.Offset) + (symbol.Value - section.Addr)
|
offset := uint64(section.Offset) + (symbol.Value - section.Addr)
|
||||||
|
|
||||||
return offset, size, nil
|
return offset, size, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxUint64, maxUint64, fmt.Errorf("symbol not found")
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,41 +32,41 @@ func findPESymbol(r io.ReaderAt, symbolName string) (uint64, uint64, error) {
|
||||||
symbolName = "_" + symbolName
|
symbolName = "_" + symbolName
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Slice(peFile.Symbols, func(i, j int) bool {
|
symbols := peFile.Symbols
|
||||||
if peFile.Symbols[i].SectionNumber != peFile.Symbols[j].SectionNumber {
|
sort.Slice(symbols, func(i, j int) bool {
|
||||||
return peFile.Symbols[i].SectionNumber < peFile.Symbols[j].SectionNumber
|
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 {
|
if symbol.Name == symbolName {
|
||||||
var nextSymbol *pe.Symbol
|
// Find the next symbol (n the same section with a higher address
|
||||||
if i+1 < len(peFile.Symbols) {
|
n := sort.Search(len(symbols), func(i int) bool {
|
||||||
nextSymbol = peFile.Symbols[i+1]
|
return symbols[i].SectionNumber == symbol.SectionNumber &&
|
||||||
}
|
symbols[i].Value > symbol.Value
|
||||||
return calculatePESymbolOffset(peFile, symbol, nextSymbol)
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return maxUint64, maxUint64, fmt.Errorf("symbol not found")
|
section := peFile.Sections[symbol.SectionNumber-1]
|
||||||
}
|
|
||||||
|
|
||||||
func calculatePESymbolOffset(file *pe.File, symbol *pe.Symbol, nextSymbol *pe.Symbol) (uint64, uint64, error) {
|
|
||||||
section := file.Sections[symbol.SectionNumber-1]
|
|
||||||
|
|
||||||
var end uint32
|
var end uint32
|
||||||
if nextSymbol != nil && nextSymbol.SectionNumber != symbol.SectionNumber {
|
if n < len(symbols) {
|
||||||
nextSymbol = nil
|
end = symbols[n].Value
|
||||||
}
|
|
||||||
if nextSymbol != nil {
|
|
||||||
end = nextSymbol.Value
|
|
||||||
} else {
|
} else {
|
||||||
end = section.Size
|
end = section.Size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
size := end - symbol.Value - 1
|
||||||
offset := section.Offset + symbol.Value
|
offset := section.Offset + symbol.Value
|
||||||
|
|
||||||
return uint64(offset), uint64(size), nil
|
return uint64(offset), uint64(size), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxUint64, maxUint64, fmt.Errorf("symbol not found")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue