|
3 | 3 | // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
|
5 | 5 | import 'dart:async'; |
| 6 | +import 'dart:convert'; |
6 | 7 | import 'dart:ffi'; |
7 | 8 | import 'dart:io'; |
8 | 9 |
|
@@ -248,48 +249,26 @@ Future<RunProcessResult?> _runDumpbin( |
248 | 249 | ); |
249 | 250 | } |
250 | 251 |
|
251 | | -Future<int> textSectionAddress(Uri dylib) async { |
252 | | - if (Platform.isMacOS) { |
253 | | - // Find the line in the objdump output that looks like: |
254 | | - // 11 .text 00000046 00000000000045a0 TEXT |
255 | | - final result = await runProcess( |
256 | | - executable: Uri.file('objdump'), |
257 | | - arguments: ['--headers', dylib.toFilePath()], |
258 | | - logger: logger, |
259 | | - ); |
260 | | - expect(result.exitCode, 0); |
261 | | - final textSection = result.stdout |
262 | | - .split('\n') |
263 | | - .firstWhere((e) => e.contains('.text')); |
264 | | - final parsed = textSection.split(' ').where((e) => e.isNotEmpty).toList(); |
265 | | - expect(parsed[1], '.text'); |
266 | | - expect(parsed[4], 'TEXT'); |
267 | | - final vma = int.parse(parsed[3], radix: 16); |
268 | | - return vma; |
269 | | - } |
270 | | - if (Platform.isLinux) { |
271 | | - // Find the line in the readelf output that looks like: |
272 | | - // [11] .text PROGBITS 00004328 000328 000064 00 AX 0 0 4 |
273 | | - final result = await readelf(dylib.toFilePath(), 'S'); |
274 | | - final textSection = result |
275 | | - .split('\n') |
276 | | - .firstWhere((e) => e.contains('.text')); |
277 | | - final parsed = textSection.split(' ').where((e) => e.isNotEmpty).toList(); |
278 | | - expect(parsed[1], '.text'); |
279 | | - expect(parsed[2], 'PROGBITS'); |
280 | | - final addr = int.parse(parsed[3], radix: 16); |
281 | | - return addr; |
282 | | - } |
283 | | - throw UnimplementedError(); |
284 | | -} |
| 252 | +Future<List<int>> loadAlignments(Uri dylib) async { |
| 253 | + // https://cs.android.com/android/platform/superproject/main/+/main:system/extras/tools/check_elf_alignment.sh;l=99 |
| 254 | + final result = await runProcess( |
| 255 | + executable: Uri.file('objdump'), |
| 256 | + arguments: ['-p', dylib.toFilePath()], |
| 257 | + logger: logger, |
| 258 | + ); |
| 259 | + expect(result.exitCode, 0); |
285 | 260 |
|
286 | | -Future<void> expectPageSize(Uri dylib, int pageSize) async { |
287 | | - if (Platform.isMacOS || Platform.isLinux) { |
288 | | - // If page size is 16kb, the `.text` section address should be |
289 | | - // above 0x4000. With smaller page sizes it's above 0x1000. |
290 | | - final vma = await textSectionAddress(dylib); |
291 | | - expect(vma, greaterThanOrEqualTo(pageSize)); |
292 | | - } |
| 261 | + // Parse alignment from lines that look like this: |
| 262 | + // LOAD off <...> vaddr <...> paddr <...> align 2**12 |
| 263 | + final alignmentRegex = RegExp(r'align 2\*\*(\d+)'); |
| 264 | + return const LineSplitter() |
| 265 | + .convert(result.stdout) |
| 266 | + .where((e) => e.contains('LOAD')) |
| 267 | + .map((line) { |
| 268 | + final exponent = int.parse(alignmentRegex.firstMatch(line)!.group(1)!); |
| 269 | + return 1 << exponent; |
| 270 | + }) |
| 271 | + .toList(); |
293 | 272 | } |
294 | 273 |
|
295 | 274 | int defaultMacOSVersion = 13; |
|
0 commit comments