@isopodlabs/binary_libs 0.0.1 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/mach.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as binary from '@isopodlabs/binary';
2
2
 
3
- class mach_stream extends binary.stream_endian {
4
- constructor(public base: Uint8Array, data: Uint8Array, be: boolean, public mem?: binary.utils.memory) { super(data, be); }
3
+ class mach_stream extends binary.endianStream {
4
+ constructor(public base: Uint8Array, data: Uint8Array, be: boolean, public mem?: binary.memory) { super(data, be); }
5
5
  subdata(offset: number, size?: number) {
6
6
  return this.base.subarray(offset, size && offset + size);
7
7
  }
@@ -17,8 +17,8 @@ const uint16 = binary.UINT16;
17
17
  const uint32 = binary.UINT32;
18
18
  const uint64 = binary.UINT64;
19
19
  const int32 = binary.INT32;
20
- const xint32 = binary.XINT32;
21
- const xint64 = binary.XINT64;
20
+ const xint32 = binary.asHex(uint32);
21
+ const xint64 = binary.asHex(uint64);
22
22
 
23
23
  const FILETYPE = {
24
24
  OBJECT: 1, // Relocatable object file
@@ -33,7 +33,7 @@ const FILETYPE = {
33
33
  DSYM: 10, // Companion file with only debug sections
34
34
  KEXT_BUNDLE: 11, // x86_64 kexts
35
35
  FILESET: 12
36
- }
36
+ } as const;
37
37
 
38
38
  // Machine types known by all
39
39
  enum CPU_TYPE {
@@ -57,7 +57,7 @@ enum CPU_TYPE {
57
57
  X86_64 = X86 | ARCH_64,
58
58
  POWERPC_64 = POWERPC | ARCH_64,
59
59
  ARM_64 = ARM | ARCH_64,
60
- }
60
+ };
61
61
 
62
62
  const CPU_SUBTYPES: {[K in CPU_TYPE]?: any} = {
63
63
  [CPU_TYPE.VAX] : {
@@ -185,7 +185,7 @@ const CPU_SUBTYPES: {[K in CPU_TYPE]?: any} = {
185
185
  ARM64_V8: 1,
186
186
  ARM64E: 2,
187
187
  },
188
- }
188
+ };
189
189
 
190
190
  // Constants for the flags field of the header
191
191
  const HEADER_FLAGS = {
@@ -214,7 +214,7 @@ const HEADER_FLAGS = {
214
214
  DEAD_STRIPPABLE_DYLIB: 0x400000, // Only for use on dylibs. When linking against a dylib that has this bit set, the static linker will automatically not create a LC_LOAD_DYLIBload command to the dylib if no symbols are being referenced from the dylib.
215
215
  HAS_TLV_DESCRIPTORS: 0x800000, // Contains a section of type S_THREAD_LOCAL_VARIABLES
216
216
  NO_HEAP_EXECUTION: 0x1000000, // When this bit is set, the OS will run the main executable with a non-executable heap even on platforms (e.g. i386) that don't require it.Only used in MH_EXECUTE filetypes.
217
- }
217
+ } as const;
218
218
 
219
219
  const header = {
220
220
  magic: uint32, // mach magic number identifier
@@ -241,62 +241,61 @@ const fat_header = {
241
241
  };
242
242
 
243
243
  const REQ_DYLD = 0x80000000;
244
- export const CMD = {
245
- SEGMENT: 0x01, // segment of this file to be mapped
246
- SYMTAB: 0x02, // link-edit stab symbol table info
247
- SYMSEG: 0x03, // link-edit gdb symbol table info (obsolete)
248
- THREAD: 0x04, // thread
249
- UNIXTHREAD: 0x05, // unix thread (includes a stack)
250
- LOADFVMLIB: 0x06, // load a specified fixed VM shared library
251
- IDFVMLIB: 0x07, // fixed VM shared library identification
252
- IDENT: 0x08, // object identification info (obsolete)
253
- FVMFILE: 0x09, // fixed VM file inclusion (internal use)
254
- PREPAGE: 0x0a, // prepage command (internal use)
255
- DYSYMTAB: 0x0b, // dynamic link-edit symbol table info
256
- LOAD_DYLIB: 0x0c, // load a dynamically linked shared library
257
- ID_DYLIB: 0x0d, // dynamically linked shared lib ident
258
- LOAD_DYLINKER: 0x0e, // load a dynamic linker
259
- ID_DYLINKER: 0x0f, // dynamic linker identification
260
- PREBOUND_DYLIB: 0x10, // modules prebound for a dynamically linked shared library
261
- ROUTINES: 0x11, // image routines
262
- SUB_FRAMEWORK: 0x12, // sub framework
263
- SUB_UMBRELLA: 0x13, // sub umbrella
264
- SUB_CLIENT: 0x14, // sub client
265
- SUB_LIBRARY: 0x15, // sub library
266
- TWOLEVEL_HINTS: 0x16, // two-level namespace lookup hints
267
- PREBIND_CKSUM: 0x17, // prebind checksum
268
- LOAD_WEAK_DYLIB: 0x18 + REQ_DYLD, // load a dynamically linked shared library that is allowed to be missing (all symbols are weak imported).
269
- SEGMENT_64: 0x19, // 64-bit segment of this file to be mapped
270
- ROUTINES_64: 0x1a, // 64-bit image routines
271
- UUID: 0x1b, // the uuid
272
- RPATH: 0x1c + REQ_DYLD, // runpath additions
273
- CODE_SIGNATURE: 0x1d, // local of code signature
274
- SEGMENT_SPLIT_INFO: 0x1e, // local of info to split segments
275
- REEXPORT_DYLIB: 0x1f + REQ_DYLD, // load and re-export dylib
276
- LAZY_LOAD_DYLIB: 0x20, // delay load of dylib until first use
277
- ENCRYPTION_INFO: 0x21, // encrypted segment information
278
- DYLD_INFO: 0x22, // compressed dyld information
279
- DYLD_INFO_ONLY: 0x22 + REQ_DYLD, // compressed dyld information only
280
- LOAD_UPWARD_DYLIB: 0x23 + REQ_DYLD, // load upward dylib
281
- VERSION_MIN_MACOSX: 0x24, // build for MacOSX min OS version
282
- VERSION_MIN_IPHONEOS: 0x25, // build for iPhoneOS min OS version
283
- FUNCTION_STARTS: 0x26, // compressed table of function start addresses
284
- DYLD_ENVIRONMENT: 0x27, // string for dyld to treat like environment variable
285
- MAIN: 0x28 + REQ_DYLD, // replacement for LC_UNIXTHREAD
286
- DATA_IN_CODE: 0x29, // table of non-instructions in __text
287
- SOURCE_VERSION: 0x2A, // source version used to build binary
288
- DYLIB_CODE_SIGN_DRS: 0x2B, // Code signing DRs copied from linked dylibs
289
- ENCRYPTION_INFO_64: 0x2C, // 64-bit encrypted segment information
290
- LINKER_OPTION: 0x2D, // linker options in MH_OBJECT files
291
- LINKER_OPTIMIZATION_HINT: 0x2E, // optimization hints in MH_OBJECT files
292
- VERSION_MIN_TVOS: 0x2F, // build for AppleTV min OS version
293
- VERSION_MIN_WATCHOS: 0x30, // build for Watch min OS version
294
- NOTE: 0x31, // arbitrary data included within a Mach-O file
295
- BUILD_VERSION: 0x32, // build for platform min OS version
296
- DYLD_EXPORTS_TRIE: 0x33 + REQ_DYLD, // used with linkedit_data_command, payload is trie
297
- DYLD_CHAINED_FIXUPS: 0x34 + REQ_DYLD, // used with linkedit_data_command
298
- } as const;
299
- export type CMD = typeof CMD[keyof typeof CMD];
244
+ const enum CMD {
245
+ SEGMENT = 0x01, // segment of this file to be mapped
246
+ SYMTAB = 0x02, // link-edit stab symbol table info
247
+ SYMSEG = 0x03, // link-edit gdb symbol table info (obsolete)
248
+ THREAD = 0x04, // thread
249
+ UNIXTHREAD = 0x05, // unix thread (includes a stack)
250
+ LOADFVMLIB = 0x06, // load a specified fixed VM shared library
251
+ IDFVMLIB = 0x07, // fixed VM shared library identification
252
+ // IDENT = 0x08, // object identification info (obsolete)
253
+ FVMFILE = 0x09, // fixed VM file inclusion (internal use)
254
+ // PREPAGE = 0x0a, // prepage command (internal use)
255
+ DYSYMTAB = 0x0b, // dynamic link-edit symbol table info
256
+ LOAD_DYLIB = 0x0c, // load a dynamically linked shared library
257
+ ID_DYLIB = 0x0d, // dynamically linked shared lib ident
258
+ LOAD_DYLINKER = 0x0e, // load a dynamic linker
259
+ ID_DYLINKER = 0x0f, // dynamic linker identification
260
+ PREBOUND_DYLIB = 0x10, // modules prebound for a dynamically linked shared library
261
+ ROUTINES = 0x11, // image routines
262
+ SUB_FRAMEWORK = 0x12, // sub framework
263
+ SUB_UMBRELLA = 0x13, // sub umbrella
264
+ SUB_CLIENT = 0x14, // sub client
265
+ SUB_LIBRARY = 0x15, // sub library
266
+ TWOLEVEL_HINTS = 0x16, // two-level namespace lookup hints
267
+ PREBIND_CKSUM = 0x17, // prebind checksum
268
+ LOAD_WEAK_DYLIB = REQ_DYLD+0x18, // load a dynamically linked shared library that is allowed to be missing (all symbols are weak imported).
269
+ SEGMENT_64 = 0x19, // 64-bit segment of this file to be mapped
270
+ ROUTINES_64 = 0x1a, // 64-bit image routines
271
+ UUID = 0x1b, // the uuid
272
+ RPATH = REQ_DYLD+0x1c, // runpath additions
273
+ CODE_SIGNATURE = 0x1d, // local of code signature
274
+ SEGMENT_SPLIT_INFO = 0x1e, // local of info to split segments
275
+ REEXPORT_DYLIB = REQ_DYLD+0x1f, // load and re-export dylib
276
+ LAZY_LOAD_DYLIB = 0x20, // delay load of dylib until first use
277
+ ENCRYPTION_INFO = 0x21, // encrypted segment information
278
+ DYLD_INFO = 0x22, // compressed dyld information
279
+ DYLD_INFO_ONLY = REQ_DYLD+0x22, // compressed dyld information only
280
+ LOAD_UPWARD_DYLIB = REQ_DYLD+0x23, // load upward dylib
281
+ VERSION_MIN_MACOSX = 0x24, // build for MacOSX min OS version
282
+ VERSION_MIN_IPHONEOS = 0x25, // build for iPhoneOS min OS version
283
+ FUNCTION_STARTS = 0x26, // compressed table of function start addresses
284
+ DYLD_ENVIRONMENT = 0x27, // string for dyld to treat like environment variable
285
+ MAIN = REQ_DYLD+0x28, // replacement for LC_UNIXTHREAD
286
+ DATA_IN_CODE = 0x29, // table of non-instructions in __text
287
+ SOURCE_VERSION = 0x2A, // source version used to build binary
288
+ DYLIB_CODE_SIGN_DRS = 0x2B, // Code signing DRs copied from linked dylibs
289
+ ENCRYPTION_INFO_64 = 0x2C, // 64-bit encrypted segment information
290
+ LINKER_OPTION = 0x2D, // linker options in MH_OBJECT files
291
+ LINKER_OPTIMIZATION_HINT = 0x2E, // optimization hints in MH_OBJECT files
292
+ VERSION_MIN_TVOS = 0x2F, // build for AppleTV min OS version
293
+ VERSION_MIN_WATCHOS = 0x30, // build for Watch min OS version
294
+ NOTE = 0x31, // arbitrary data included within a Mach-O file
295
+ BUILD_VERSION = 0x32, // build for platform min OS version
296
+ DYLD_EXPORTS_TRIE = REQ_DYLD+0x33, // used with linkedit_data_command, payload is trie
297
+ DYLD_CHAINED_FIXUPS = REQ_DYLD+0x34, // used with linkedit_data_command
298
+ };
300
299
 
301
300
  const str = {
302
301
  get(s: binary.stream) {
@@ -308,7 +307,7 @@ const str = {
308
307
  const index_table = {
309
308
  first: uint32,
310
309
  count: uint32,
311
- }
310
+ };
312
311
 
313
312
  const blob = {
314
313
  get(s: mach_stream) {
@@ -327,11 +326,16 @@ function blobT<T extends binary.TypeReader>(type: T) {
327
326
  return {
328
327
  data: s.subdata(offset, size),
329
328
  contents: binary.read(s.substream(offset, size), type)
330
- }
329
+ };
331
330
  }
332
331
  };
333
332
  }
334
333
 
334
+ function blobArray<T extends binary.Type>(type: T) {
335
+ return blobT(binary.RemainingArrayType(type));
336
+ }
337
+
338
+
335
339
  function count_table<T extends binary.TypeReader>(type: T) {
336
340
  return {
337
341
  get(s: mach_stream) {
@@ -347,9 +351,9 @@ const fixed_string16 = binary.StringType(16);
347
351
  const version = binary.asFlags(uint32, {major: 0xffff0000, minor: 0xff00, patch: 0xff}, false);
348
352
 
349
353
  const command = {
350
- cmd: binary.as(uint32, binary.EnumV(CMD)),
354
+ cmd: binary.as(uint32, v => v as CMD),
351
355
  cmdsize: uint32,
352
- }
356
+ };
353
357
 
354
358
  const SECTION_FLAGS = binary.BitFields({
355
359
  TYPE: [8, binary.Enum({
@@ -398,7 +402,7 @@ const SECTION_FLAGS = binary.BitFields({
398
402
  function section(bits: 32|64) {
399
403
  const type = binary.UINT(bits);
400
404
 
401
- class Section extends binary.ReadWriteStruct({
405
+ class Section extends binary.Class({
402
406
  //data: binary.DontRead<binary.utils.MappedMemory>(),
403
407
  sectname: fixed_string16,
404
408
  segname: fixed_string16,
@@ -413,14 +417,14 @@ function section(bits: 32|64) {
413
417
  reserved2: uint32, // reserved (for count or sizeof)
414
418
  _: binary.AlignType(bits / 8)
415
419
  }) {
416
- data: Promise<binary.utils.MappedMemory>;
420
+ data: Promise<binary.MappedMemory>;
417
421
  constructor(s: mach_stream) {
418
422
  super(s);
419
- const prot = this.flags.ATTRIBUTES.SYS.SOME_INSTRUCTIONS ? binary.utils.MEM.EXECUTE : binary.utils.MEM.NONE;
420
- this.data = (async () => {
421
- //return new binary.utils.MappedMemory(await s.file.get(BigInt(this.addr), Number(this.size)), Number(this.addr), prot)
422
- return new binary.utils.MappedMemory(s.subdata(+this.offset, Number(this.size)), Number(this.addr), prot)
423
- })();
423
+ const prot = this.flags.ATTRIBUTES.SYS.SOME_INSTRUCTIONS ? binary.MEM.EXECUTE : binary.MEM.NONE;
424
+ this.data = (async () =>
425
+ //new binary.utils.MappedMemory(await s.file.get(BigInt(this.addr), Number(this.size)), Number(this.addr), prot)
426
+ new binary.MappedMemory(s.subdata(+this.offset, Number(this.size)), Number(this.addr), prot)
427
+ )();
424
428
  }
425
429
  }
426
430
  return Section;
@@ -431,12 +435,12 @@ const SEGMENT_FLAGS = {
431
435
  FVMLIB: 0x2, // this segment is the VM that is allocated by a fixed VM library, for overlap checking in the link editor
432
436
  NORELOC: 0x4, // this segment has nothing that was relocated in it and nothing relocated to it, that is it maybe safely replaced without relocation
433
437
  PROTECTED_VERSION_1: 0x8, // This segment is protected. If the segment starts at file offset 0, the first page of the segment is not protected. All other pages of the segment are protected.
434
- }
438
+ };
435
439
 
436
- function segment(bits: 32|64) {
440
+ function segment<T extends 32|64>(bits: T) {
437
441
  const type = binary.UINT(bits);
438
442
  const fields = {
439
- data: binary.DontRead<binary.utils.MappedMemory>(),
443
+ data: binary.DontRead<binary.MappedMemory>(),
440
444
  segname: fixed_string16, // segment name
441
445
  vmaddr: type, // memory address of this segment
442
446
  vmsize: type, // memory size of this segment
@@ -449,21 +453,62 @@ function segment(bits: 32|64) {
449
453
  sections: binary.DontRead<Record<string, any>>(),//binary.ReadType<typeof section(bits)>)),
450
454
  };
451
455
  return {
452
- async get(s: mach_stream) {
456
+ get(s: mach_stream) {
453
457
  const o = binary.read(s, fields);
454
- const data = await s.getmem(BigInt(o.vmaddr), Number(o.filesize)) ?? s.subdata(Number(o.fileoff), Number(o.filesize));
455
- o.data = new binary.utils.MappedMemory(data, Number(o.vmaddr), o.initprot);
456
458
 
457
- const sect = section(bits);
458
- if (o.nsects) {
459
- o.sections = binary.objectWithNames(binary.ArrayType(o.nsects, section(bits)), binary.field('sectname')).get(s);
460
- //o.sections = Object.fromEntries(Array.from({length: o.nsects}, (_,i)=>new sect(s)).map(s => [s.sectname, s]));
459
+ async function load() {
460
+ const data = await s.getmem(BigInt(Number(o.vmaddr)), Number(o.filesize)) ?? s.subdata(Number(o.fileoff), Number(o.filesize));
461
+ o.data = new binary.MappedMemory(data, Number(o.vmaddr), o.initprot);
462
+
463
+ //const sect = section(bits);
464
+ if (o.nsects) {
465
+ o.sections = binary.objectWithNames(binary.ArrayType(o.nsects, section(bits)), binary.field('sectname')).get(s);
466
+ //o.sections = Object.fromEntries(Array.from({length: o.nsects}, (_,i)=>new sect(s)).map(s => [s.sectname, s]));
467
+ }
461
468
  }
469
+
470
+ load();
462
471
  return o;
463
472
  }
464
473
  };
465
474
  }
466
475
 
476
+ /*
477
+ function segment(bits: 32|64) {
478
+ const type = binary.UINT(bits);
479
+ return class extends binary.ReadWriteStruct({
480
+ segname: fixed_string16, // segment name
481
+ vmaddr: type, // memory address of this segment
482
+ vmsize: type, // memory size of this segment
483
+ fileoff: type, // file offset of this segment
484
+ filesize: type, // amount to map from the file
485
+ maxprot: uint32, // maximum VM protection
486
+ initprot: uint32, // initial VM protection
487
+ nsects: uint32, // number of sections in segment
488
+ flags: binary.as(uint32, binary.Flags(SEGMENT_FLAGS,true)), // flags
489
+ }) {
490
+ data?: binary.MappedMemory;
491
+ sections: Record<string, any> = {};
492
+
493
+ constructor(s: mach_stream) {
494
+ super(s);
495
+ this.load(s);
496
+ }
497
+ async load(s: mach_stream) {
498
+ const data = await s.getmem(BigInt(this.vmaddr), Number(this.filesize)) ?? s.subdata(Number(this.fileoff), Number(this.filesize));
499
+ this.data = new binary.MappedMemory(data, Number(this.vmaddr), this.initprot);
500
+
501
+ //const sect = section(bits);
502
+ if (this.nsects) {
503
+ this.sections = binary.objectWithNames(binary.ArrayType(this.nsects, section(bits)), binary.field('sectname')).get(s);
504
+ //o.sections = Object.fromEntries(Array.from({length: o.nsects}, (_,i)=>new sect(s)).map(s => [s.sectname, s]));
505
+ }
506
+
507
+ }
508
+ };
509
+ }
510
+ */
511
+
467
512
  const fvmlib = {
468
513
  name: str, // library's target pathname
469
514
  minor_version: xint32, // library's minor version number
@@ -478,8 +523,8 @@ const dylib = {
478
523
  };
479
524
 
480
525
  const thread_command = {
481
- // uint32 flavor flavor of thread state
482
- // uint32 count count of longs in thread state
526
+ flavor: uint32, // flavor of thread state
527
+ count: uint32, // count of longs in thread state
483
528
  // struct XXX_thread_state state thread state for this flavor
484
529
  // ...
485
530
  };
@@ -594,7 +639,7 @@ const symtab = {
594
639
  const INDIRECT = {
595
640
  INDIRECT_SYMBOL_LOCAL: 0x80000000, // non-lazy symbol pointer section for a defined symbol which strip(1) has removed
596
641
  INDIRECT_SYMBOL_ABS: 0x40000000,
597
- }
642
+ } as const;
598
643
 
599
644
  const toc_entry = {
600
645
  symbol_index: uint32, // the defined external symbol (index into the symbol table)
@@ -687,7 +732,7 @@ const dyld_kind = {
687
732
  WEAK_DEFINITION: 0x04,
688
733
  REEXPORT: 0x08,
689
734
  STUB_AND_RESOLVER: 0x10,
690
- }
735
+ } as const;
691
736
 
692
737
  const dyldinfo = {
693
738
  rebase: blob,
@@ -703,7 +748,8 @@ const TOOL = {
703
748
  SWIFT: 2,
704
749
  LD: 3,
705
750
  LLD: 4,
706
- }
751
+ } as const;
752
+
707
753
  const PLATFORM = {
708
754
  MACOS: 1,
709
755
  IOS: 2,
@@ -715,7 +761,7 @@ const PLATFORM = {
715
761
  TVOSSIMULATOR: 8,
716
762
  WATCHOSSIMULATOR: 9,
717
763
  DRIVERKIT: 10,
718
- }
764
+ } as const;
719
765
 
720
766
  //DYLD_CHAINED_FIXUPS
721
767
 
@@ -768,7 +814,7 @@ const dyld_chained_import_addend64 = {
768
814
  addend: uint64,
769
815
  };
770
816
 
771
- class dyld_chained_fixups extends binary.ReadStruct({
817
+ class dyld_chained_fixups extends binary.ReadClass({
772
818
  fixups_version: uint32, // currently 0
773
819
  starts: binary.OffsetType(uint32, dyld_chained_starts_in_image),
774
820
  imports: binary.OffsetType(uint32, binary.Remainder), // offset of imports table in chain_data
@@ -784,18 +830,20 @@ class dyld_chained_fixups extends binary.ReadStruct({
784
830
  ZLIB: 1,
785
831
  }),
786
832
  }) {
787
- constructor(s: binary.stream_endian) {
833
+ imports2;
834
+ constructor(s: binary.endianStream) {
788
835
  super(s);
789
- const imports = new binary.stream_endian(this.imports, s.be);
836
+ const imports = new binary.endianStream(this.imports, s.be);
790
837
  switch (this.imports_format) {
791
- case 'IMPORT':
792
- this.imports = binary.withNames(binary.readn(imports, dyld_chained_import, this.imports_count), imp => binary.utils.decodeTextTo0(this.symbols.subarray(imp.name_offset)));
838
+ case 'IMPORT': {
839
+ this.imports2 = binary.withNames(binary.readn(imports, dyld_chained_import, this.imports_count), imp => binary.utils.decodeTextTo0(this.symbols.subarray(Number(imp.name_offset))));
793
840
  break;
841
+ }
794
842
  case 'IMPORT_ADDEND':
795
- this.imports = binary.withNames(binary.readn(imports, dyld_chained_import_addend, this.imports_count), imp => binary.utils.decodeTextTo0(this.symbols.subarray(imp.import.name_offset)));
843
+ this.imports2 = binary.withNames(binary.readn(imports, dyld_chained_import_addend, this.imports_count), imp => binary.utils.decodeTextTo0(this.symbols.subarray(Number(imp.import.name_offset))));
796
844
  break;
797
845
  case 'IMPORT_ADDEND64':
798
- this.imports = binary.withNames(binary.readn(imports, dyld_chained_import_addend64, this.imports_count), imp => binary.utils.decodeTextTo0(this.symbols.subarray(imp.import.name_offset)));
846
+ this.imports2 = binary.withNames(binary.readn(imports, dyld_chained_import_addend64, this.imports_count), imp => binary.utils.decodeTextTo0(this.symbols.subarray(Number(imp.import.name_offset))));
799
847
  break;
800
848
  }
801
849
  }
@@ -858,7 +906,6 @@ function routines(bits:32|64) {
858
906
 
859
907
  //const cmd_table : {[K in CMD]?: binary.TypeReader2} = {
860
908
  const cmd_table = {//: Record<CMD, binary.TypeReader2> = {
861
- //const cmd_table = {
862
909
  [CMD.SEGMENT]: segment(32),
863
910
  [CMD.SEGMENT_64]: segment(64),
864
911
  [CMD.LOADFVMLIB]: fvmlib,
@@ -906,8 +953,8 @@ const cmd_table = {//: Record<CMD, binary.TypeReader2> = {
906
953
 
907
954
  [CMD.CODE_SIGNATURE]: blob,
908
955
  [CMD.SEGMENT_SPLIT_INFO]: blob,
909
- [CMD.FUNCTION_STARTS]: blobT(binary.RemainingArrayType(binary.ULEB128)),
910
- [CMD.DATA_IN_CODE]: blobT(binary.RemainingArrayType(data_in_code_entry)),
956
+ [CMD.FUNCTION_STARTS]: blobArray(binary.ULEB128),
957
+ [CMD.DATA_IN_CODE]: blobArray(data_in_code_entry),
911
958
  [CMD.DYLIB_CODE_SIGN_DRS]: blob,
912
959
  [CMD.LINKER_OPTIMIZATION_HINT]: blob,
913
960
  [CMD.DYLD_EXPORTS_TRIE]: blob,
@@ -935,7 +982,7 @@ const cmd_table = {//: Record<CMD, binary.TypeReader2> = {
935
982
 
936
983
  [CMD.SYMSEG]: blob,//OBSOLETE
937
984
 
938
- [CMD.IDENT]: {},//OBSOLETE
985
+ // [CMD.IDENT]: {},//OBSOLETE
939
986
 
940
987
  [CMD.FVMFILE]: {//OBSOLETE
941
988
  name: str,
@@ -963,7 +1010,7 @@ const cmd_table = {//: Record<CMD, binary.TypeReader2> = {
963
1010
  data_owner: fixed_string16, // owner name for this LC_NOTE
964
1011
  data: blob
965
1012
  },
966
- [CMD.PREPAGE]: {},
1013
+ // [CMD.PREPAGE]: {},
967
1014
  [CMD.DYSYMTAB]: {
968
1015
  localsym: index_table, // local symbols
969
1016
  extdefsym: index_table, // externally defined symbols
@@ -994,7 +1041,7 @@ export class MachFile {
994
1041
  }
995
1042
  }
996
1043
 
997
- constructor(data: Uint8Array, mem?: binary.utils.memory) {
1044
+ constructor(data: Uint8Array, mem?: binary.memory) {
998
1045
  const magic = binary.UINT32_LE.get(new binary.stream(data));
999
1046
  switch (magic) {
1000
1047
  case 0xfeedface: this.ready = this.load(data, false, 32, mem); break;
@@ -1005,8 +1052,8 @@ export class MachFile {
1005
1052
  }
1006
1053
  }
1007
1054
 
1008
- async load(data: Uint8Array, be: boolean, bits: 32|64, mem?: binary.utils.memory) {
1009
- const file = new binary.stream_endian(data, be);
1055
+ async load(data: Uint8Array, be: boolean, bits: 32|64, mem?: binary.memory) {
1056
+ const file = new binary.endianStream(data, be);
1010
1057
  const h = binary.read(file, header);
1011
1058
  const cpu = CPU_TYPE[h.cputype as keyof typeof CPU_TYPE];
1012
1059
  h.cpusubtype = binary.Enum(CPU_SUBTYPES[cpu])(+h.cpusubtype);
@@ -1021,7 +1068,7 @@ export class MachFile {
1021
1068
  }
1022
1069
  this.header = h;
1023
1070
 
1024
- const funcs = this.getCommandT(CMD.FUNCTION_STARTS);
1071
+ const funcs = this.getCommand(CMD.FUNCTION_STARTS);
1025
1072
  if (funcs) {
1026
1073
  const array = funcs.contents;
1027
1074
  const text = await this.getSegment('__TEXT');
@@ -1030,7 +1077,8 @@ export class MachFile {
1030
1077
  array[i] = (acc += BigInt(array[i]));
1031
1078
  }
1032
1079
  }
1033
-
1080
+
1081
+ getCommand<T extends CMD>(cmd: T) : binary.ReadType<typeof cmd_table[T]>;
1034
1082
  getCommand(cmd: CMD) {
1035
1083
  for (const i of this.commands) {
1036
1084
  if (i.cmd === cmd)
@@ -1038,14 +1086,12 @@ export class MachFile {
1038
1086
  }
1039
1087
  }
1040
1088
 
1041
- getCommandT<T extends CMD>(cmd: T) {
1042
- const c = this.getCommand(cmd);
1043
- return c as binary.ReadType<typeof cmd_table[T]>;
1044
- }
1045
- getSegment(name: string) : binary.ReadType<ReturnType<typeof segment>> | undefined {
1089
+ getSegment(name: string) {
1046
1090
  for (const i of this.commands) {
1047
- if ((i.cmd === CMD.SEGMENT || i.cmd === CMD.SEGMENT_64) && i.data.segname === name)
1048
- return i.data;
1091
+ if (i.cmd === CMD.SEGMENT && i.data.segname === name)
1092
+ return i.data as binary.ReadType<typeof cmd_table[CMD.SEGMENT]>;
1093
+ if (i.cmd === CMD.SEGMENT_64 && i.data.segname === name)
1094
+ return i.data as binary.ReadType<typeof cmd_table[CMD.SEGMENT_64]>;;
1049
1095
  }
1050
1096
  }
1051
1097
  }
@@ -1066,24 +1112,29 @@ export class FATMachFile {
1066
1112
  }
1067
1113
  }
1068
1114
 
1069
- constructor(data: Uint8Array, mem?: binary.utils.memory) {
1115
+ constructor(data: Uint8Array, mem?: binary.memory) {
1070
1116
  switch (binary.UINT32_BE.get(new binary.stream(data))) {
1071
- case FAT_MAGIC: this.load(new binary.stream_endian(data, false), mem); break;
1072
- case FAT_CIGAM: this.load(new binary.stream_endian(data, true), mem); break;
1117
+ case FAT_MAGIC: this.load(new binary.endianStream(data, false), mem); break;
1118
+ case FAT_CIGAM: this.load(new binary.endianStream(data, true), mem); break;
1073
1119
  default:
1074
1120
  throw new Error('not a fat mach file');
1075
1121
  }
1076
1122
  }
1077
1123
 
1078
- load(file: binary.stream_endian, mem?: binary.utils.memory) {
1124
+ load(file: binary.endianStream, mem?: binary.memory) {
1079
1125
  const header = binary.read(file, fat_header);
1080
1126
  this.archs = header.archs;
1081
1127
  for (const arch of header.archs) {
1082
1128
  const cpu = CPU_TYPE[arch.cputype as keyof typeof CPU_TYPE];
1083
1129
  const data = file.buffer_at(arch.offset, arch. size);
1084
1130
  arch.cpusubtype = binary.Enum(CPU_SUBTYPES[cpu])(+arch.cpusubtype);
1085
- arch.contents = new MachFile(data);
1131
+ arch.contents = new MachFile(data, mem);
1086
1132
  }
1087
1133
  }
1088
1134
  }
1089
-
1135
+ /*
1136
+ export function freestanding<T extends CMD>(s: binary.stream, cmd: T) : binary.ReadType<typeof cmd_table[T]>;
1137
+ export function freestanding(s: binary.stream, cmd: CMD) {
1138
+ return binary.read(s, cmd_table[cmd]);
1139
+ }
1140
+ */