Skip to content

Instantly share code, notes, and snippets.

@mraleph
Created May 20, 2020 08:15
Show Gist options
  • Save mraleph/c11e9aa9ec76f04429cf8021e0b58ea7 to your computer and use it in GitHub Desktop.
Save mraleph/c11e9aa9ec76f04429cf8021e0b58ea7 to your computer and use it in GitHub Desktop.
// Copyright (c) 2020, the Dart project authors.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import 'dart:io';
class Symbol implements Comparable<Symbol> {
final int address;
final String name;
Symbol(this.address, this.name);
@override
int compareTo(Symbol other) => this.address.compareTo(other.address);
@override
String toString() => 'sym(${name} at ${address.toRadixString(16)})';
}
void main(List<String> args) async {
if (args.length != 3) {
print('Usage: locate-symbol.dart <path-to-nm> <path-to-symbols-info> <pc>');
exit(1);
}
final nmBinary = args[0];
final debugInfo = args[1];
final pc = int.tryParse(args[2], radix: 16);
if (!File(nmBinary).existsSync()) {
print('nm binary does not exist at ${nmBinary} path');
exit(1);
}
if (!File(debugInfo).existsSync()) {
print('symbols file does not exist at ${debugInfo} path');
exit(1);
}
final result = await Process.run(nmBinary, [debugInfo]);
if (result.exitCode != 0) {
print(
'Running ${nmBinary} ${debugInfo} failed with exit code ${result.exitCode}');
print('STDOUT: ${result.stdout}\nSTDERR: ${result.stderr}\n');
exit(1);
}
var symbols = (result.stdout as String)
.split('\n')
.map((s) => s.trim())
.where((s) => s.isNotEmpty)
.map((line) {
final fields = line.split(' ');
final addr = int.parse(fields[0], radix: 16);
final name = fields[2];
return Symbol(addr, name);
}).toList(growable: false)
..sort();
print('${pc.toRadixString(16)} belongs to ${binarySearch(symbols, pc)}');
}
Symbol binarySearch(List<Symbol> symbols, int pc) {
var left = 0;
var right = symbols.length;
while (left < right) {
var mid = (left + right) >> 1;
var addr = symbols[mid].address;
if (addr <= pc && pc < symbols[mid + 1].address) {
return symbols[mid];
}
if (addr < pc) {
left = mid;
} else if (addr > pc) {
right = mid;
}
}
return null;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment