Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dfce7644 authored by Colin Cross's avatar Colin Cross
Browse files

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
parent 0c74ad93
Loading
Loading
Loading
Loading
+23 −27
Original line number Diff line number Diff line
@@ -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]
			}
			return calculateMachoSymbolOffset(machoFile, symbol, nextSymbol)
		}
	}

	return maxUint64, maxUint64, fmt.Errorf("symbol not found")
}
	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
			})

func calculateMachoSymbolOffset(file *macho.File, symbol macho.Symbol, nextSymbol *macho.Symbol) (uint64, uint64, error) {
	section := file.Sections[symbol.Sect-1]
			section := machoFile.Sections[symbol.Sect-1]

			var end uint64
	if nextSymbol != nil && nextSymbol.Sect != symbol.Sect {
		nextSymbol = nil
	}
	if nextSymbol != nil {
		end = nextSymbol.Value
			if n < len(symbols) {
				end = symbols[n].Value
			} else {
				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
			offset := uint64(section.Offset) + (symbol.Value - section.Addr)

			return offset, size, nil
		}
	}

	return maxUint64, maxUint64, fmt.Errorf("symbol not found")
}
+27 −27
Original line number Diff line number Diff line
@@ -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]
			}
			return calculatePESymbolOffset(peFile, symbol, nextSymbol)
		}
	}

	return maxUint64, maxUint64, fmt.Errorf("symbol not found")
}
			// 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
			})

func calculatePESymbolOffset(file *pe.File, symbol *pe.Symbol, nextSymbol *pe.Symbol) (uint64, uint64, error) {
	section := file.Sections[symbol.SectionNumber-1]
			section := peFile.Sections[symbol.SectionNumber-1]

			var end uint32
	if nextSymbol != nil && nextSymbol.SectionNumber != symbol.SectionNumber {
		nextSymbol = nil
	}
	if nextSymbol != nil {
		end = nextSymbol.Value
			if n < len(symbols) {
				end = symbols[n].Value
			} else {
				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
			offset := section.Offset + symbol.Value

			return uint64(offset), uint64(size), nil
		}
	}

	return maxUint64, maxUint64, fmt.Errorf("symbol not found")
}