mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[linux] swift-inspect support for Linux
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import Foundation
|
||||
import LinuxSystemHeaders
|
||||
|
||||
public class SymbolCache {
|
||||
public typealias SymbolRange = (start: UInt64, end: UInt64)
|
||||
public typealias SymbolInfo = (start: UInt64, end: UInt64, module: String, name: String)
|
||||
public typealias SymbolLookup = [String: [String: SymbolRange]]
|
||||
|
||||
public let symbolLookup: SymbolLookup
|
||||
let linkMap: LinkMap
|
||||
|
||||
// an array of all symbols sorted by their start address
|
||||
lazy var sortedAddressLookup: [SymbolInfo] = {
|
||||
var addressLookup: [SymbolInfo] = []
|
||||
for (module, symbols) in self.symbolLookup {
|
||||
for (name, (start, end)) in symbols {
|
||||
addressLookup.append((start: start, end: end, module: module, name: name))
|
||||
}
|
||||
}
|
||||
addressLookup.sort { $0.start < $1.start }
|
||||
return addressLookup
|
||||
}()
|
||||
|
||||
public init(for process: Process) throws {
|
||||
self.linkMap = try LinkMap(for: process)
|
||||
var symbolLookup: SymbolLookup = [:]
|
||||
for linkMapEntry in linkMap.entries {
|
||||
guard FileManager.default.fileExists(atPath: linkMapEntry.moduleName) else { continue }
|
||||
|
||||
let elfFile = try ElfFile(filePath: linkMapEntry.moduleName)
|
||||
let symbolMap = try elfFile.loadSymbols(baseAddress: linkMapEntry.baseAddress)
|
||||
symbolLookup[linkMapEntry.moduleName] = symbolMap
|
||||
}
|
||||
self.symbolLookup = symbolLookup
|
||||
}
|
||||
|
||||
// find the address range for the requetsed symbol
|
||||
public func address(of symbol: String) -> SymbolRange? {
|
||||
for (_, symbols) in symbolLookup { if let range = symbols[symbol] { return range } }
|
||||
return nil
|
||||
}
|
||||
|
||||
// find and return symbol that contains the specified address
|
||||
public func symbol(for address: UInt64) -> SymbolInfo? {
|
||||
var lowerBound = 0
|
||||
var upperBound = self.sortedAddressLookup.count
|
||||
while lowerBound < upperBound {
|
||||
let currentIndex = (lowerBound + upperBound) / 2
|
||||
let entry = self.sortedAddressLookup[currentIndex]
|
||||
if entry.start > address {
|
||||
upperBound = currentIndex
|
||||
} else if entry.end <= address {
|
||||
lowerBound = currentIndex + 1
|
||||
} else {
|
||||
assert(address >= entry.start)
|
||||
assert(address < entry.end)
|
||||
return entry
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user