| // Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'dart:io'; |
| |
| /// Compute the difference between virtual address and the file offset of the |
| /// TEXT section. It can be used to convert virtual addresses into |
| /// file offsets. |
| int loadingBiasOf(String path) { |
| final data = Process.runSync('llvm-readelf', ['-l', path]).stdout.split("\n"); |
| for (var line in data) { |
| line = line.trim(); |
| if (line.startsWith("LOAD") && line.contains("R E")) { |
| final components = line.split(RegExp(r"\s+")); |
| final fileOffset = int.parse(components[1]); |
| final virtAddr = int.parse(components[2]); |
| return virtAddr - fileOffset; |
| } |
| } |
| throw StateError('Unable to determine loading bias for $path'); |
| } |
| |
| /// Iterate over all symbols in TEXT section of the given binary. |
| Iterable<({int addr, String name})> textSymbolsOf(String path) { |
| // Run `nm -C` on a binary to extract demangled (-C) symbols. |
| final output = Process.runSync('/usr/bin/nm', ['-C', path]); |
| final result = (output.stdout as String).split('\n'); |
| if (output.exitCode != 0) throw 'failed to run nm'; |
| |
| // Parse `nm` output looking for `t` (TEXT) symbols. Each line |
| // has the following format: |
| final lineRe = RegExp(r"^(?<addr>[0-9a-f]+)\s+(?<typ>\w+)\s+(?<name>.*)$"); |
| // final symbols = <(int, String)>[]; |
| return result.map((line) { |
| final m = lineRe.firstMatch(line); |
| if (m != null && m.namedGroup('typ') == 't') { |
| final addr = int.parse(m.namedGroup('addr')!, radix: 16); |
| final name = m.namedGroup('name')!; |
| return (addr: addr, name: name); |
| } |
| return null; |
| }).nonNulls; |
| } |