[vm] Additional Mach-O related command line options for gen_snapshot.
Adds the following command line options to gen_snapshot: * --macho-install-name: The name to use as the install name for the dynamic library (used in the LC_ID_DYLIB and LC_CODE_SIGNATURE load commands). If not provided, the output filename is used. * --[no-]macho-linker-signature: Whether or not gen_snapshot should generate an ad-hoc linker-signed signature. Defaults to true. The following command line option is macOS/iOS-specific: * --macho-rpath: Comma-delimited run paths that should be added at runtime to the current run path used for finding @rpath-prefixed dynamic libraries. Adds support to parsing rpath and dylib load commands to pkg/native_stack_traces's Mach-O parser in order to test the command line options appropriately. TEST=vm/dart/use_macho_options Issue: https://github.com/dart-lang/sdk/issues/60307 Change-Id: I17618578a7bff7851a88cdaf27f299f058f98dd3 Cq-Include-Trybots: luci.dart.try:vm-aot-mac-debug-x64-try,vm-aot-mac-debug-arm64-try,vm-aot-linux-debug-arm64-try,vm-aot-linux-debug-x64-try,pkg-mac-release-try,pkg-mac-release-arm64-try,pkg-linux-release-arm64-try,vm-aot-win-release-arm64-try,vm-aot-win-debug-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/441920 Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Tess Strickland <sstrickl@google.com>
This commit is contained in:
committed by
Commit Queue
parent
20f773724a
commit
83e9bd72ea
@@ -121,10 +121,15 @@ class LoadCommand {
|
||||
|
||||
LoadCommand._(this.cmd, this.cmdsize);
|
||||
|
||||
static const LC_REQ_DYLD = 0x80000000;
|
||||
|
||||
static const LC_SEGMENT = 0x1;
|
||||
static const LC_SYMTAB = 0x2;
|
||||
static const LC_ID_DYLIB = 0xd;
|
||||
static const LC_SEGMENT_64 = 0x19;
|
||||
static const LC_UUID = 0x1b;
|
||||
static const LC_RPATH = 0x1c | LC_REQ_DYLD;
|
||||
static const LC_CODE_SIGNATURE = 0x1d; // Only used in vm/dart tests.
|
||||
static const LC_BUILD_VERSION = 0x32;
|
||||
|
||||
static LoadCommand fromReader(Reader reader) {
|
||||
@@ -147,6 +152,10 @@ class LoadCommand {
|
||||
case LC_BUILD_VERSION:
|
||||
command = BuildVersionCommand.fromReader(reader, cmd, cmdsize);
|
||||
break;
|
||||
case LC_ID_DYLIB:
|
||||
command = DylibCommand.fromReader(reader, cmd, cmdsize);
|
||||
case LC_RPATH:
|
||||
command = RunPathCommand.fromReader(reader, cmd, cmdsize);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -355,6 +364,86 @@ class UuidCommand extends LoadCommand {
|
||||
}
|
||||
}
|
||||
|
||||
class DylibInfo {
|
||||
final String name;
|
||||
final int timestamp;
|
||||
final int currentVersion;
|
||||
final int compatibilityVersion;
|
||||
|
||||
const DylibInfo._(this.name, this.timestamp, this.currentVersion,
|
||||
this.compatibilityVersion);
|
||||
|
||||
static DylibInfo fromReader(Reader reader, int cmdsize) {
|
||||
final start = reader.offset - 8; // cmd + cmdsize
|
||||
final offset = _readMachOUint32(reader);
|
||||
final timestamp = _readMachOUint32(reader);
|
||||
final currentVersion = _readMachOUint32(reader);
|
||||
final compatibilityVersion = _readMachOUint32(reader);
|
||||
reader.seek(start + offset, absolute: true);
|
||||
final name = reader.readNullTerminatedString(maxSize: cmdsize - offset);
|
||||
return DylibInfo._(name, timestamp, currentVersion, compatibilityVersion);
|
||||
}
|
||||
|
||||
void writeToStringBuffer(StringBuffer buffer) {
|
||||
buffer
|
||||
..write(' Name: ')
|
||||
..writeln(name)
|
||||
..write(' Timestamp: ')
|
||||
..writeln(timestamp)
|
||||
..write(' Current version: ')
|
||||
..writeln(currentVersion)
|
||||
..write(' Compatibility version: ')
|
||||
..writeln(compatibilityVersion);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
final buffer = StringBuffer();
|
||||
writeToStringBuffer(buffer);
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class DylibCommand extends LoadCommand {
|
||||
final DylibInfo info;
|
||||
|
||||
DylibCommand._(super.cmd, super.cmdsize, this.info) : super._();
|
||||
|
||||
static DylibCommand fromReader(Reader reader, int cmd, int cmdsize) =>
|
||||
DylibCommand._(cmd, cmdsize, DylibInfo.fromReader(reader, cmdsize));
|
||||
|
||||
@override
|
||||
void writeToStringBuffer(StringBuffer buffer) {
|
||||
if (cmd == LoadCommand.LC_ID_DYLIB) {
|
||||
buffer.writeln('LC_ID_DYLIB:');
|
||||
info.writeToStringBuffer(buffer);
|
||||
} else {
|
||||
throw StateError("Unexpected command code $cmd");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RunPathCommand extends LoadCommand {
|
||||
String path;
|
||||
|
||||
RunPathCommand._(super.cmd, super.cmdsize, this.path) : super._();
|
||||
|
||||
static RunPathCommand fromReader(Reader reader, int cmd, int cmdsize) {
|
||||
final start = reader.offset - 8; // cmd + cmdsize
|
||||
final offset = _readMachOUint32(reader);
|
||||
reader.seek(start + offset, absolute: true);
|
||||
final path = reader.readNullTerminatedString(maxSize: cmdsize - offset);
|
||||
return RunPathCommand._(cmd, cmdsize, path);
|
||||
}
|
||||
|
||||
@override
|
||||
void writeToStringBuffer(StringBuffer buffer) {
|
||||
buffer
|
||||
..write('Run path: ')
|
||||
..write(path);
|
||||
}
|
||||
}
|
||||
|
||||
class Version {
|
||||
final int x;
|
||||
final int y;
|
||||
@@ -688,6 +777,7 @@ class MachO extends DwarfContainer {
|
||||
Reader.fromTypedData(reader.bdata,
|
||||
wordSize: _header.wordSize, endian: _header.endian);
|
||||
|
||||
Iterable<LoadCommand> get commands => _commands;
|
||||
Iterable<T> commandsWhereType<T extends LoadCommand>() =>
|
||||
_commands.whereType<T>();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user