Chameleon

Chameleon Commit Details

Date:2014-11-14 02:27:20 (5 years 11 months ago)
Author:ErmaC
Commit:2476
Parents: 2475
Message:Typo, indent and blank space.
Changes:
M/trunk/i386/boot0/boot0.s
M/trunk/i386/boot0/boot0hfs.s
M/trunk/i386/boot2/boot.c
M/trunk/i386/modules/KernelPatcher/Makefile
M/trunk/i386/modules/AcpiCodec/acpi_codec.c
M/trunk/i386/libsaio/dram_controllers.c
M/trunk/i386/libsaio/ntfs.c
M/trunk/i386/boot2/modules.c
M/trunk/i386/libsa/string.c
M/trunk/i386/libsaio/convert.c
M/trunk/i386/libsaio/allocate.c
M/trunk/i386/libsaio/bootargs.h
M/trunk/i386/libsaio/msdos.c
M/trunk/i386/boot2/bmdecompress.c
M/trunk/i386/boot2/gui.c
M/trunk/i386/modules/MakeInc.dir
M/trunk/i386/libsaio/disk.c
M/trunk/i386/libsaio/smbios.c
M/trunk/i386/libsaio/saio_internal.h
M/trunk/i386/boot2/appleboot.h
M/trunk/i386/boot2/options.c
M/trunk/i386/boot2/graphic_utils.c
M/trunk/i386/modules/FileNVRAM/Cconfig
M/trunk/i386/config/confdata.c
M/trunk/i386/boot2/graphics.c
M/trunk/i386/modules/Sata/Sata.c
M/trunk/i386/util/machOconv.c
M/trunk/i386/libsaio/vbe.c
M/trunk/i386/libsaio/sys.c
M/trunk/i386/include/mach-o/loader.h
M/trunk/i386/libsaio/hfs.c
M/trunk/i386/libsaio/cpu.c
M/trunk/i386/libsaio/smbios_getters.c
M/trunk/i386/libsaio/fake_efi.c
M/trunk/i386/libsa/zalloc.c
M/trunk/i386/boot2/Makefile
M/trunk/i386/libsaio/smbios_decode.c
M/trunk/i386/libsa/prf.c

File differences

trunk/i386/libsaio/vbe.c
3333
3434
3535
36
37
3836
3937
4038
......
7169
7270
7371
74
75
7672
7773
7874
static biosBuf_t bb;
#if UNUSED
//==============================================================================
#if UNUSED
static inline void
#endif /* UNUSED */
//==============================================================================
#endif /* UNUSED */
int getVBEInfo( void * infoBlock )
{
bb.intno = 0x10;
trunk/i386/libsaio/hfs.c
22
33
44
5
5
66
77
88
......
1616
1717
1818
19
19
2020
21
22
21
22
2323
2424
2525
......
119119
120120
121121
122
123122
124123
125124
126125
127
126
127
128128
129129
130130
131131
132132
133
134133
135134
136135
......
150149
151150
152151
153
154152
155153
156154
......
284282
285283
286284
287
288285
289286
290287
......
352349
353350
354351
355
356
357352
353
354
358355
359356
360357
......
365362
366363
367364
368
365
366
367
368
369369
370
370
371
372
373
371374
372
373
374
375
376
377
378
379
380
381
382
375
383376
384
385
386
387
388
377
378
379
380
381
382
383
384
385
386
387
388
389
389390
390
391
392
391
392
393
394
393395
394
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
395430
396431
397
398
432
433
434
399435
400436
401437
......
404440
405441
406442
407
443
444
445
446
408447
409448
410449
411450
412451
413
414
415
452
453
454
416455
417
456
418457
419
458
420459
421
422
460
461
423462
424463
464
425465
426466
427467
......
431471
432472
433473
434
474
475
476
477
435478
436
437
438
439
440
441
442
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
443508
444
445
446
447
448
509
449510
450
451
452
453
454
511
512
513
514
515
455516
456
457
458
459
460
461
462517
463518
464519
......
468523
469524
470525
526
527
528
471529
472530
473
474
531
532
533
534
475535
476
536
537
538
539
540
541
477542
478543
544
479545
480546
481547
......
486552
487553
488554
489
490
491
492
493
494
495
496
497
555
556
557
558
559
560
561
562
563
564
565
566
498567
499
500
501
502
568
569
570
503571
504
505
506
572
573
507574
508
509
510
511
575
576
577
578
512579
513
514
580
581
582
583
584
585
586
515587
516
588
589
590
517591
518592
519593
......
522596
523597
524598
525
599
526600
527
528
529
530
531
532
601
602
603
604
605
606
533607
534
535
536
537
538
539
540
608
609
610
611
612
613
614
615
541616
542
543
544
545
546
547
548
549
617
618
619
620
621
622
623
624
625
550626
551
552
553
554
555
556
557
558
559
560
561
627
628
629
630
631
632
633
634
635
636
637
638
639
562640
563
564
565
566
567
568
569
570
641
642
643
644
645
646
647
648
571649
572
573
574
575
576
650
651
652
653
654
577655
578
656
657
658
659
660
661
579662
580663
581664
......
586669
587670
588671
589
590
591
592
672
673
674
675
676
677
593678
594
595
596
679
597680
598
599
681
682
683
684
685
600686
601
602
603
604
687
605688
606
689
690
607691
608
609
610
611
612
613
692
614693
615
616
617
694
695
696
697
618698
619
620
621
622
623
624
625
626
627
628
699
629700
630
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
631730
632731
633732
......
639738
640739
641740
642
643
644
645
646
647
648
741
742
743
744
745
746
747
748
749
750
649751
650
651
652
752
753
754
653755
654756
655757
656758
657
658
659
660
759
760
661761
662
762
663763
664
665
666
764
765
766
767
768
769
667770
668771
669
670
671
672
673
674
675
772
773
774
775
676776
677
678
679
680
681
682
683
777
778
779
684780
685
781
782
686783
687
784
785
786
787
788
789
790
791
792
793
688794
689795
690796
......
711817
712818
713819
714
820
715821
716822
717823
718824
719
720
721
825
826
827
722828
723
724
725
726
727
728
729
730
731
732
829
830
831
832
833
834
835
836
837
838
839
840
841
733842
734
843
735844
736845
846
847
737848
738849
739850
......
745856
746857
747858
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
768888
769
770
771
772
773
774
775
776
777
778
779
889
890
891
892
893
780894
781
782
783
784
895
896
897
898
899
785900
786
787
788
789
790
791
792
793
794
795
901
902
903
904
796905
797
906
907
908
909
798910
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
817963
818
819
820
821
822
823
824
825
826
827
828
829
830
964
965
966
967
968
969
970
971
972
973
831974
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
975
976
977
978
979
980
849981
850
851
852
853
854
855
856
857
858
859
860
861
862
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
8631033
8641034
8651035
......
8911061
8921062
8931063
894
1064
1065
1066
1067
8951068
896
897
898
899
900
901
902
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
9031079
904
905
906
1080
9071081
908
909
910
911
912
913
914
1082
1083
1084
9151085
916
917
918
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
9191096
920
921
922
923
1097
1098
1099
9241100
925
926
927
928
929
1101
1102
1103
9301104
931
1105
1106
1107
1108
1109
9321110
933
934
935
936
937
938
939
1111
9401112
941
942
943
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
9441132
945
946
1133
9471134
948
949
950
951
1135
1136
1137
1138
9521139
953
954
955
956
1140
9571141
958
1142
9591143
960
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
9611155
9621156
9631157
......
9661160
9671161
9681162
969
970
1163
1164
1165
1166
1167
1168
1169
1170
9711171
972
1172
9731173
9741174
9751175
......
9841184
9851185
9861186
1187
1188
9871189
9881190
989
990
1191
1192
9911193
992
993
1194
1195
9941196
995
996
1197
1198
9971199
998
999
1000
1001
1002
1003
1004
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
10051214
1006
1215
10071216
10081217
1218
1219
10091220
10101221
1011
1012
1013
1014
1015
1016
1017
1018
1222
1223
10191224
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
10301250
10311251
10321252
1033
1034
1253
1254
1255
1256
10351257
10361258
10371259
1038
1039
1260
1261
10401262
1041
1263
10421264
10431265
1266
1267
10441268
10451269
1046
1047
1048
1049
1050
1051
1052
1053
1270
1271
10541272
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1273
1274
10761275
1077
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
10781318
10791319
1320
1321
1322
10801323
10811324
1082
1083
1325
10841326
1085
1086
1327
10871328
1088
1089
1329
1330
10901331
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1332
1333
11121334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
11131373
11141374
11151375
* Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
*
* The contents of this file constitute Original Code as defined in and
* are subject to the Apple Public Source License Version 2.0 (the
* "License"). You may not use this file except in compliance with the
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
*
*
* hfs.c - File System Module for HFS and HFS+.
*
* Copyright (c) 1999-2002 Apple Computer, Inc.
// Don't bother with location
}
//==============================================================================
void HFSFree(CICell ih)
{
if(gCurrentIH == ih) {
if(gCurrentIH == ih)
{
gCurrentIH = 0;
}
free(ih);
}
//==============================================================================
bool HFSProbe (const void *buf)
return true;
}
//==============================================================================
long HFSInitPartition(CICell ih)
return 0;
}
//==============================================================================
long HFSLoadFile(CICell ih, char * filePath)
}
getDeviceDescription(ih, devStr);
verbose("Read HFS%s file: [%s/%s] %d bytes.\n",
(gIsHFSPlus ? "+" : ""), devStr, filePath, (uint32_t)length);
verbose("Read HFS%s file: [%s/%s] %d bytes.\n",(gIsHFSPlus ? "+" : ""), devStr, filePath, (uint32_t)length);
return length;
}
char entry[512];
long dirID, dirFlags;
if (HFSInitPartition(ih) == -1) return -1;
if (HFSInitPartition(ih) == -1)
{
return -1;
}
if (*dirIndex == -1) return -1;
if (*dirIndex == -1)
{
return -1;
}
dirID = kHFSRootFolderID;
// Skip a lead '/'. Start in the system folder if there are two.
if (dirPath[0] == '/') {
if (dirPath[1] == '/') {
if (gIsHFSPlus) dirID = SWAP_BE32(((long *)gHFSPlus->finderInfo)[5]);
else dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]);
if (dirID == 0) return -1;
dirPath++;
}
dirPath++;
}
dirID = kHFSRootFolderID;
if (*dirIndex == 0) {
ResolvePathToCatalogEntry(dirPath, &dirFlags, entry, dirID, dirIndex);
if (*dirIndex == 0) *dirIndex = -1;
if ((dirFlags & kFileTypeMask) != kFileTypeUnknown) return -1;
}
// Skip a lead '/'. Start in the system folder if there are two.
if (dirPath[0] == '/')
{
if (dirPath[1] == '/')
{
if (gIsHFSPlus)
{
dirID = SWAP_BE32(((long *)gHFSPlus->finderInfo)[5]);
}
else
{
dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]);
}
GetCatalogEntry(dirIndex, name, flags, time, finderInfo, infoValid);
if (*dirIndex == 0) *dirIndex = -1;
if ((*flags & kFileTypeMask) == kFileTypeUnknown) return -1;
if (dirID == 0)
{
return -1;
}
return 0;
dirPath++;
}
dirPath++;
}
if (*dirIndex == 0)
{
ResolvePathToCatalogEntry(dirPath, &dirFlags, entry, dirID, dirIndex);
if (*dirIndex == 0)
{
*dirIndex = -1;
}
if ((dirFlags & kFileTypeMask) != kFileTypeUnknown)
{
return -1;
}
}
GetCatalogEntry(dirIndex, name, flags, time, finderInfo, infoValid);
if (*dirIndex == 0)
{
*dirIndex = -1;
}
if ((*flags & kFileTypeMask) == kFileTypeUnknown)
{
return -1;
}
return 0;
}
void
HFSGetDescription(CICell ih, char *str, long strMaxLen)
//==============================================================================
void HFSGetDescription(CICell ih, char *str, long strMaxLen)
{
UInt16 nodeSize;
char *name;
long flags, time;
if (HFSInitPartition(ih) == -1) { return; }
if (HFSInitPartition(ih) == -1)
{
return;
}
/* Fill some crucial data structures by side effect. */
dirIndex = 0;
HFSGetDirEntry(ih, "/", &dirIndex, &name, &flags, &time, 0, 0);
/* Now we can loook up the volume name node. */
nodeSize = SWAP_BE16(gBTHeaders[kBTreeCatalog]->nodeSize);
firstLeafNode = SWAP_BE32(gBTHeaders[kBTreeCatalog]->firstLeafNode);
/* Now we can loook up the volume name node. */
nodeSize = SWAP_BE16(gBTHeaders[kBTreeCatalog]->nodeSize);
firstLeafNode = SWAP_BE32(gBTHeaders[kBTreeCatalog]->firstLeafNode);
dirIndex = (long long) firstLeafNode * nodeSize;
dirIndex = (long long) firstLeafNode * nodeSize;
GetCatalogEntry(&dirIndex, &name, &flags, &time, 0, 0);
GetCatalogEntry(&dirIndex, &name, &flags, &time, 0, 0);
strncpy(str, name, strMaxLen);
str[strMaxLen] = '\0';
strncpy(str, name, strMaxLen);
str[strMaxLen] = '\0';
}
//==============================================================================
long HFSGetFileBlock(CICell ih, char *filePath, unsigned long long *firstBlock)
{
HFSCatalogFile *hfsFile = (void *)entry;
HFSPlusCatalogFile *hfsPlusFile = (void *)entry;
if (HFSInitPartition(ih) == -1) return -1;
if (HFSInitPartition(ih) == -1)
{
return -1;
}
dirID = kHFSRootFolderID;
// Skip a lead '/'. Start in the system folder if there are two.
if (filePath[0] == '/') {
if (filePath[1] == '/') {
if (gIsHFSPlus) dirID = SWAP_BE32(((long *)gHFSPlus->finderInfo)[5]);
else dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]);
if (dirID == 0) {
dirID = kHFSRootFolderID;
// Skip a lead '/'. Start in the system folder if there are two.
if (filePath[0] == '/')
{
if (filePath[1] == '/')
{
if (gIsHFSPlus)
{
dirID = SWAP_BE32(((long *) gHFSPlus->finderInfo)[5]);
}
else
{
dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]);
}
if (dirID == 0)
{
return -1;
}
filePath++;
}
filePath++;
}
result = ResolvePathToCatalogEntry(filePath, &flags, entry, dirID, 0);
if ((result == -1) || ((flags & kFileTypeMask) != kFileTypeFlat))
{
printf("HFS: Resolve path %s failed\n", filePath);
return -1;
}
filePath++;
}
filePath++;
}
}
result = ResolvePathToCatalogEntry(filePath, &flags, entry, dirID, 0);
if ((result == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) {
printf("HFS: Resolve path %s failed\n", filePath);
return -1;
}
if (gIsHFSPlus) {
extents = &hfsPlusFile->dataFork.extents;
} else {
extents = &hfsFile->dataExtents;
}
if (gIsHFSPlus) {
extents = &hfsPlusFile->dataFork.extents;
} else {
extents = &hfsFile->dataExtents;
}
#if DEBUG
printf("extent start 0x%x\n", (unsigned long)GetExtentStart(extents, 0));
printf("block size 0x%x\n", (unsigned long)gBlockSize);
return 0;
}
//==============================================================================
long HFSGetUUID(CICell ih, char *uuidStr)
{
if (HFSInitPartition(ih) == -1) return -1;
if (gVolID == 0LL) return -1;
if (HFSInitPartition(ih) == -1)
{
return -1;
}
return CreateUUIDString((uint8_t*)(&gVolID), sizeof(gVolID), uuidStr);
if (gVolID == 0LL)
{
return -1;
}
return CreateUUIDString((uint8_t*)(&gVolID), sizeof(gVolID), uuidStr);
}
//==============================================================================
// Private Functions
static long ReadFile(void * file, uint64_t * length, void * base, uint64_t offset)
HFSCatalogFile *hfsFile = file;
HFSPlusCatalogFile *hfsPlusFile = file;
if (gIsHFSPlus) {
fileID = SWAP_BE32(hfsPlusFile->fileID);
fileLength = (uint64_t)SWAP_BE64(hfsPlusFile->dataFork.logicalSize);
extents = &hfsPlusFile->dataFork.extents;
} else {
fileID = SWAP_BE32(hfsFile->fileID);
fileLength = SWAP_BE32(hfsFile->dataLogicalSize);
extents = &hfsFile->dataExtents;
}
if (gIsHFSPlus)
{
fileID = SWAP_BE32(hfsPlusFile->fileID);
fileLength = (uint64_t)SWAP_BE64(hfsPlusFile->dataFork.logicalSize);
extents = &hfsPlusFile->dataFork.extents;
}
else
{
fileID = SWAP_BE32(hfsFile->fileID);
fileLength = SWAP_BE32(hfsFile->dataLogicalSize);
extents = &hfsFile->dataExtents;
}
if (offset > fileLength) {
printf("Offset is too large.\n");
return -1;
}
if (offset > fileLength)
{
printf("Offset is too large.\n");
if ((*length == 0) || ((offset + *length) > fileLength)) {
*length = fileLength - offset;
}
return -1;
}
/* if (*length > kLoadSize) {
printf("File is too large.\n");
return -1;
}*/
if ((*length == 0) || ((offset + *length) > fileLength))
{
*length = fileLength - offset;
}
*length = ReadExtent((char *)extents, fileLength, fileID,
offset, *length, (char *)base, 0);
/*
if (*length > kLoadSize)
{
printf("File is too large.\n");
return -1;
}
*/
return 0;
*length = ReadExtent((char *)extents, fileLength, fileID, offset, *length, (char *)base, 0);
return 0;
}
static long GetCatalogEntryInfo(void * entry, long * flags, long * time,
long tmpTime = 0;
long valid = 0;
// Get information about the file.
// Get information about the file.
switch ( SWAP_BE16(*(short *)entry) )
{
case kHFSFolderRecord :
*flags = kFileTypeDirectory;
tmpTime = SWAP_BE32(((HFSCatalogFolder *)entry)->modifyDate);
break;
switch ( SWAP_BE16(*(short *)entry) )
{
case kHFSFolderRecord :
*flags = kFileTypeDirectory;
tmpTime = SWAP_BE32(((HFSCatalogFolder *)entry)->modifyDate);
break;
case kHFSPlusFolderRecord :
*flags = kFileTypeDirectory |
(SWAP_BE16(((HFSPlusCatalogFolder *)entry)->bsdInfo.fileMode) & kPermMask);
if (SWAP_BE32(((HFSPlusCatalogFolder *)entry)->bsdInfo.ownerID) != 0)
*flags |= kOwnerNotRoot;
tmpTime = SWAP_BE32(((HFSPlusCatalogFolder *)entry)->contentModDate);
break;
case kHFSPlusFolderRecord :
*flags = kFileTypeDirectory | (SWAP_BE16(((HFSPlusCatalogFolder *)entry)->bsdInfo.fileMode) & kPermMask);
if (SWAP_BE32(((HFSPlusCatalogFolder *)entry)->bsdInfo.ownerID) != 0)
{
*flags |= kOwnerNotRoot;
}
tmpTime = SWAP_BE32(((HFSPlusCatalogFolder *)entry)->contentModDate);
break;
case kHFSFileRecord :
*flags = kFileTypeFlat;
tmpTime = SWAP_BE32(((HFSCatalogFile *)entry)->modifyDate);
if (finderInfo) {
SwapFinderInfo((FndrFileInfo *)finderInfo, &((HFSCatalogFile *)entry)->userInfo);
valid = 1;
}
break;
case kHFSFileRecord :
*flags = kFileTypeFlat;
tmpTime = SWAP_BE32(((HFSCatalogFile *)entry)->modifyDate);
if (finderInfo)
{
SwapFinderInfo((FndrFileInfo *)finderInfo, &((HFSCatalogFile *)entry)->userInfo);
valid = 1;
}
break;
case kHFSPlusFileRecord :
*flags = kFileTypeFlat |
(SWAP_BE16(((HFSPlusCatalogFile *)entry)->bsdInfo.fileMode) & kPermMask);
if (SWAP_BE32(((HFSPlusCatalogFile *)entry)->bsdInfo.ownerID) != 0)
*flags |= kOwnerNotRoot;
tmpTime = SWAP_BE32(((HFSPlusCatalogFile *)entry)->contentModDate);
if (finderInfo) {
SwapFinderInfo((FndrFileInfo *)finderInfo, &((HFSPlusCatalogFile *)entry)->userInfo);
valid = 1;
}
break;
case kHFSPlusFileRecord :
*flags = kFileTypeFlat | (SWAP_BE16(((HFSPlusCatalogFile *)entry)->bsdInfo.fileMode) & kPermMask);
if (SWAP_BE32(((HFSPlusCatalogFile *)entry)->bsdInfo.ownerID) != 0)
{
*flags |= kOwnerNotRoot;
}
tmpTime = SWAP_BE32(((HFSPlusCatalogFile *)entry)->contentModDate);
if (finderInfo)
{
SwapFinderInfo((FndrFileInfo *)finderInfo, &((HFSPlusCatalogFile *)entry)->userInfo);
valid = 1;
}
break;
case kHFSFileThreadRecord :
case kHFSPlusFileThreadRecord :
case kHFSFolderThreadRecord :
case kHFSPlusFolderThreadRecord :
*flags = kFileTypeUnknown;
tmpTime = 0;
break;
}
case kHFSFileThreadRecord :
case kHFSPlusFileThreadRecord :
case kHFSFolderThreadRecord :
case kHFSPlusFolderThreadRecord :
*flags = kFileTypeUnknown;
tmpTime = 0;
break;
}
if (time != 0) {
// Convert base time from 1904 to 1970.
*time = tmpTime - 2082844800;
}
if (infoValid) *infoValid = valid;
if (time != 0)
{
// Convert base time from 1904 to 1970.
*time = tmpTime - 2082844800;
}
return 0;
if (infoValid)
{
*infoValid = valid;
}
return 0;
}
static long ResolvePathToCatalogEntry(char * filePath, long * flags,
long long tmpDirIndex;
HFSPlusCatalogFile *hfsPlusFile;
// Copy the file name to gTempStr
cnt = 0;
while ((filePath[cnt] != '/') && (filePath[cnt] != '\0')) cnt++;
strlcpy(gTempStr, filePath, cnt+1);
// Copy the file name to gTempStr
cnt = 0;
while ((filePath[cnt] != '/') && (filePath[cnt] != '\0'))
{
cnt++;
}
// Move restPath to the right place.
if (filePath[cnt] != '\0') cnt++;
restPath = filePath + cnt;
strlcpy(gTempStr, filePath, cnt+1);
// gTempStr is a name in the current Dir.
// restPath is the rest of the path if any.
// Move restPath to the right place.
if (filePath[cnt] != '\0')
{
cnt++;
}
result = ReadCatalogEntry(gTempStr, dirID, entry, dirIndex);
if (result == -1) {
return -1;
}
restPath = filePath + cnt;
GetCatalogEntryInfo(entry, flags, 0, 0, 0);
// gTempStr is a name in the current Dir.
// restPath is the rest of the path if any.
if ((*flags & kFileTypeMask) == kFileTypeDirectory) {
if (gIsHFSPlus)
subFolderID = SWAP_BE32(((HFSPlusCatalogFolder *)entry)->folderID);
else
subFolderID = SWAP_BE32(((HFSCatalogFolder *)entry)->folderID);
}
result = ReadCatalogEntry(gTempStr, dirID, entry, dirIndex);
if ((*flags & kFileTypeMask) == kFileTypeDirectory)
result = ResolvePathToCatalogEntry(restPath, flags, entry,
subFolderID, dirIndex);
if (result == -1)
{
return -1;
}
if (gIsHFSPlus && ((*flags & kFileTypeMask) == kFileTypeFlat)) {
hfsPlusFile = (HFSPlusCatalogFile *)entry;
if ((SWAP_BE32(hfsPlusFile->userInfo.fdType) == kHardLinkFileType) &&
(SWAP_BE32(hfsPlusFile->userInfo.fdCreator) == kHFSPlusCreator)) {
sprintf(gLinkTemp, "%s/%s%ld", HFSPLUSMETADATAFOLDER,
HFS_INODE_PREFIX, SWAP_BE32(hfsPlusFile->bsdInfo.special.iNodeNum));
result = ResolvePathToCatalogEntry(gLinkTemp, flags, entry,
kHFSRootFolderID, &tmpDirIndex);
}
}
GetCatalogEntryInfo(entry, flags, 0, 0, 0);
return result;
if ((*flags & kFileTypeMask) == kFileTypeDirectory)
{
if (gIsHFSPlus)
{
subFolderID = SWAP_BE32(((HFSPlusCatalogFolder *)entry)->folderID);
}
else
{
subFolderID = SWAP_BE32(((HFSCatalogFolder *)entry)->folderID);
}
}
if ((*flags & kFileTypeMask) == kFileTypeDirectory)
{
result = ResolvePathToCatalogEntry(restPath, flags, entry, subFolderID, dirIndex);
}
if (gIsHFSPlus && ((*flags & kFileTypeMask) == kFileTypeFlat))
{
hfsPlusFile = (HFSPlusCatalogFile *)entry;
if ((SWAP_BE32(hfsPlusFile->userInfo.fdType) == kHardLinkFileType) && (SWAP_BE32(hfsPlusFile->userInfo.fdCreator) == kHFSPlusCreator))
{
sprintf(gLinkTemp, "%s/%s%ld", HFSPLUSMETADATAFOLDER, HFS_INODE_PREFIX, SWAP_BE32(hfsPlusFile->bsdInfo.special.iNodeNum));
result = ResolvePathToCatalogEntry(gLinkTemp, flags, entry, kHFSRootFolderID, &tmpDirIndex);
}
}
return result;
}
static long GetCatalogEntry(long long * dirIndex, char ** name,
char *nodeBuf, *testKey, *entry;
BTNodeDescriptor *node;
if (gIsHFSPlus) {
extent = &gHFSPlus->catalogFile.extents;
extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize);
} else {
extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
}
if (gIsHFSPlus)
{
extent = &gHFSPlus->catalogFile.extents;
extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize);
}
else
{
extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
}
nodeSize = SWAP_BE16(gBTHeaders[kBTreeCatalog]->nodeSize);
nodeBuf = (char *)malloc(nodeSize);
node = (BTNodeDescriptor *)nodeBuf;
nodeSize = SWAP_BE16(gBTHeaders[kBTreeCatalog]->nodeSize);
nodeBuf = (char *)malloc(nodeSize);
node = (BTNodeDescriptor *)nodeBuf;
index = (long) (*dirIndex % nodeSize);
curNode = (long) (*dirIndex / nodeSize);
// Read the BTree node and get the record for index.
ReadExtent(extent, extentSize, kHFSCatalogFileID,
(long long) curNode * nodeSize, nodeSize, nodeBuf, 1);
GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &entry);
// Read the BTree node and get the record for index.
ReadExtent(extent, extentSize, kHFSCatalogFileID, (long long) curNode * nodeSize, nodeSize, nodeBuf, 1);
GetCatalogEntryInfo(entry, flags, time, finderInfo, infoValid);
GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &entry);
// Get the file name.
if (gIsHFSPlus) {
utf_encodestr(((HFSPlusCatalogKey *)testKey)->nodeName.unicode,
GetCatalogEntryInfo(entry, flags, time, finderInfo, infoValid);
// Get the file name.
if (gIsHFSPlus)
{
utf_encodestr(((HFSPlusCatalogKey *)testKey)->nodeName.unicode,
SWAP_BE16(((HFSPlusCatalogKey *)testKey)->nodeName.length),
(u_int8_t *)gTempStr, 256, OSBigEndian);
} else {
strncpy(gTempStr,
(const char *)&((HFSCatalogKey *)testKey)->nodeName[1],
((HFSCatalogKey *)testKey)->nodeName[0]);
gTempStr[((HFSCatalogKey *)testKey)->nodeName[0]] = '\0';
}
*name = gTempStr;
}
else
{
strncpy(gTempStr, (const char *)&((HFSCatalogKey *)testKey)->nodeName[1], ((HFSCatalogKey *)testKey)->nodeName[0]);
// Update dirIndex.
index++;
if (index == SWAP_BE16(node->numRecords)) {
index = 0;
curNode = SWAP_BE32(node->fLink);
}
*dirIndex = (long long) curNode * nodeSize + index;
gTempStr[((HFSCatalogKey *)testKey)->nodeName[0]] = '\0';
}
*name = gTempStr;
free(nodeBuf);
// Update dirIndex.
index++;
return 0;
if (index == SWAP_BE16(node->numRecords))
{
index = 0;
curNode = SWAP_BE32(node->fLink);
}
*dirIndex = (long long) curNode * nodeSize + index;
free(nodeBuf);
return 0;
}
static long ReadCatalogEntry(char * fileName, long dirID,
strncpy((char *)(hfsKey->nodeName + 1), fileName, length);
}
return ReadBTreeEntry(kBTreeCatalog, &key, entry, dirIndex);
return ReadBTreeEntry(kBTreeCatalog, &key, entry, dirIndex);
}
static long ReadExtentsEntry(long fileID, long startBlock, void * entry)
{
char key[sizeof(HFSPlusExtentKey)];
HFSExtentKey *hfsKey = (HFSExtentKey *)key;
HFSPlusExtentKey *hfsPlusKey = (HFSPlusExtentKey *)key;
char key[sizeof(HFSPlusExtentKey)];
HFSExtentKey *hfsKey = (HFSExtentKey *)key;
HFSPlusExtentKey *hfsPlusKey = (HFSPlusExtentKey *)key;
// Make the extents key.
if (gIsHFSPlus) {
hfsPlusKey->forkType = 0;
hfsPlusKey->fileID = SWAP_BE32(fileID);
hfsPlusKey->startBlock = SWAP_BE32(startBlock);
} else {
hfsKey->forkType = 0;
hfsKey->fileID = SWAP_BE32(fileID);
hfsKey->startBlock = SWAP_BE16(startBlock);
}
// Make the extents key.
if (gIsHFSPlus)
{
hfsPlusKey->forkType = 0;
hfsPlusKey->fileID = SWAP_BE32(fileID);
hfsPlusKey->startBlock = SWAP_BE32(startBlock);
}
else
{
hfsKey->forkType = 0;
hfsKey->fileID = SWAP_BE32(fileID);
hfsKey->startBlock = SWAP_BE16(startBlock);
}
return ReadBTreeEntry(kBTreeExtents, &key, entry, 0);
return ReadBTreeEntry(kBTreeExtents, &key, entry, 0);
}
//==============================================================================
static long ReadBTreeEntry(long btree, void * key, char * entry, long long * dirIndex)
{
long extentSize;
long curNode, index = 0, lowerBound, upperBound;
char *testKey, *recordData;
// Figure out which tree is being looked at.
if (btree == kBTreeCatalog) {
if (gIsHFSPlus) {
extent = &gHFSPlus->catalogFile.extents;
extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize);
} else {
extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
}
extentFile = kHFSCatalogFileID;
} else {
if (gIsHFSPlus) {
extent = &gHFSPlus->extentsFile.extents;
extentSize = SWAP_BE64(gHFSPlus->extentsFile.logicalSize);
} else {
extent = (HFSExtentDescriptor *)&gHFSMDB->drXTExtRec;
extentSize = SWAP_BE32(gHFSMDB->drXTFlSize);
}
extentFile = kHFSExtentsFileID;
}
// Figure out which tree is being looked at.
if (btree == kBTreeCatalog)
{
if (gIsHFSPlus)
{
extent = &gHFSPlus->catalogFile.extents;
extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize);
}
else
{
extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
}
extentFile = kHFSCatalogFileID;
}
else
{
if (gIsHFSPlus)
{
extent = &gHFSPlus->extentsFile.extents;
extentSize = SWAP_BE64(gHFSPlus->extentsFile.logicalSize);
}
else
{
extent = (HFSExtentDescriptor *)&gHFSMDB->drXTExtRec;
extentSize = SWAP_BE32(gHFSMDB->drXTFlSize);
}
extentFile = kHFSExtentsFileID;
}
// Read the BTree Header if needed.
if (gBTHeaders[btree] == 0) {
ReadExtent(extent, extentSize, extentFile, 0, 256,
gBTreeHeaderBuffer + btree * 256, 0);
gBTHeaders[btree] = (BTHeaderRec *)(gBTreeHeaderBuffer + btree * 256 +
sizeof(BTNodeDescriptor));
if ((gIsHFSPlus && btree == kBTreeCatalog) &&
(gBTHeaders[btree]->keyCompareType == kHFSBinaryCompare)) {
gCaseSensitive = 1;
}
}
// Read the BTree Header if needed.
if (gBTHeaders[btree] == 0)
{
ReadExtent(extent, extentSize, extentFile, 0, 256, gBTreeHeaderBuffer + btree * 256, 0);
gBTHeaders[btree] = (BTHeaderRec *)(gBTreeHeaderBuffer + btree * 256 + sizeof(BTNodeDescriptor));
curNode = SWAP_BE32(gBTHeaders[btree]->rootNode);
nodeSize = SWAP_BE16(gBTHeaders[btree]->nodeSize);
nodeBuf = (char *)malloc(nodeSize);
node = (BTNodeDescriptor *)nodeBuf;
if ((gIsHFSPlus && btree == kBTreeCatalog) && (gBTHeaders[btree]->keyCompareType == kHFSBinaryCompare))
{
gCaseSensitive = 1;
}
}
while (1) {
// Read the current node.
ReadExtent(extent, extentSize, extentFile,
(long long) curNode * nodeSize, nodeSize, nodeBuf, 1);
// Find the matching key.
lowerBound = 0;
upperBound = SWAP_BE16(node->numRecords) - 1;
while (lowerBound <= upperBound) {
index = (lowerBound + upperBound) / 2;
curNode = SWAP_BE32(gBTHeaders[btree]->rootNode);
nodeSize = SWAP_BE16(gBTHeaders[btree]->nodeSize);
nodeBuf = (char *)malloc(nodeSize);
node = (BTNodeDescriptor *)nodeBuf;
GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &recordData);
while (1)
{
// Read the current node.
ReadExtent(extent, extentSize, extentFile, (long long) curNode * nodeSize, nodeSize, nodeBuf, 1);
if (gIsHFSPlus) {
if (btree == kBTreeCatalog) {
result = CompareHFSPlusCatalogKeys(key, testKey);
} else {
result = CompareHFSPlusExtentsKeys(key, testKey);
}
} else {
if (btree == kBTreeCatalog) {
result = CompareHFSCatalogKeys(key, testKey);
} else {
result = CompareHFSExtentsKeys(key, testKey);
}
}
if (result < 0) upperBound = index - 1; // search < trial
else if (result > 0) lowerBound = index + 1; // search > trial
else break; // search = trial
}
// Find the matching key.
lowerBound = 0;
upperBound = SWAP_BE16(node->numRecords) - 1;
while (lowerBound <= upperBound)
{
index = (lowerBound + upperBound) / 2;
GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &recordData);
if (gIsHFSPlus)
{
if (btree == kBTreeCatalog)
{
result = CompareHFSPlusCatalogKeys(key, testKey);
}
else
{
result = CompareHFSPlusExtentsKeys(key, testKey);
}
}
else
{
if (btree == kBTreeCatalog)
{
result = CompareHFSCatalogKeys(key, testKey);
}
else
{
result = CompareHFSExtentsKeys(key, testKey);
}
}
if (result < 0)
{
upperBound = index - 1;// search < trial
}
else if (result > 0)
{
lowerBound = index + 1;// search > trial
}
else
{
break;// search = trial
}
}
if (result < 0)
{
index = upperBound;
GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &recordData);
}
if (result < 0) {
index = upperBound;
GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &recordData);
}
// Found the closest key... Recurse on it if this is an index node.
if (node->kind == kBTIndexNode) {
curNode = SWAP_BE32( *((long *)recordData) );
} else break;
}
// Return error if the file was not found.
if (result != 0) { free(nodeBuf); return -1; }
// Found the closest key... Recurse on it if this is an index node.
if (node->kind == kBTIndexNode)
{
curNode = SWAP_BE32( *((long *)recordData) );
}
else
{
break;
}
}
if (btree == kBTreeCatalog) {
switch (SWAP_BE16(*(short *)recordData)) {
case kHFSFolderRecord : entrySize = 70; break;
case kHFSFileRecord : entrySize = 102; break;
case kHFSFolderThreadRecord : entrySize = 46; break;
case kHFSFileThreadRecord : entrySize = 46; break;
case kHFSPlusFolderRecord : entrySize = 88; break;
case kHFSPlusFileRecord : entrySize = 248; break;
case kHFSPlusFolderThreadRecord : entrySize = 264; break;
case kHFSPlusFileThreadRecord : entrySize = 264; break;
}
} else {
if (gIsHFSPlus) entrySize = sizeof(HFSPlusExtentRecord);
else entrySize = sizeof(HFSExtentRecord);
}
bcopy(recordData, entry, entrySize);
// Return error if the file was not found.
if (result != 0)
{
free(nodeBuf);
return -1;
}
// Update dirIndex.
if (dirIndex != 0) {
index++;
if (index == SWAP_BE16(node->numRecords)) {
index = 0;
curNode = SWAP_BE32(node->fLink);
}
*dirIndex = (long long) curNode * nodeSize + index;
}
free(nodeBuf);
return 0;
if (btree == kBTreeCatalog)
{
switch (SWAP_BE16(*(short *)recordData))
{
case kHFSFolderRecord : entrySize = 70;
break;
case kHFSFileRecord : entrySize = 102;
break;
case kHFSFolderThreadRecord : entrySize = 46;
break;
case kHFSFileThreadRecord : entrySize = 46;
break;
case kHFSPlusFolderRecord : entrySize = 88;
break;
case kHFSPlusFileRecord : entrySize = 248;
break;
case kHFSPlusFolderThreadRecord : entrySize = 264;
break;
case kHFSPlusFileThreadRecord : entrySize = 264;
break;
}
}
else
{
if (gIsHFSPlus)
{
entrySize = sizeof(HFSPlusExtentRecord);
}
else
{
entrySize = sizeof(HFSExtentRecord);
}
}
bcopy(recordData, entry, entrySize);
// Update dirIndex.
if (dirIndex != 0)
{
index++;
if (index == SWAP_BE16(node->numRecords))
{
index = 0;
curNode = SWAP_BE32(node->fLink);
}
*dirIndex = (long long) curNode * nodeSize + index;
}
free(nodeBuf);
return 0;
}
static void GetBTreeRecord(long index, char * nodeBuffer, long nodeSize,
long long extentDensity, sizeofExtent, currentExtentSize;
char *currentExtent, *extentBuffer = 0, *bufferPos = buffer;
if (offset >= extentSize) return 0;
if (offset >= extentSize)
{
return 0;
}
if (gIsHFSPlus) {
extentDensity = kHFSPlusExtentDensity;
sizeofExtent = sizeof(HFSPlusExtentDescriptor);
} else {
extentDensity = kHFSExtentDensity;
sizeofExtent = sizeof(HFSExtentDescriptor);
}
if (gIsHFSPlus)
{
extentDensity = kHFSPlusExtentDensity;
sizeofExtent = sizeof(HFSPlusExtentDescriptor);
}
else
{
extentDensity = kHFSExtentDensity;
sizeofExtent = sizeof(HFSExtentDescriptor);
}
lastOffset = offset + size;
while (offset < lastOffset) {
blockNumber = offset / gBlockSize;
lastOffset = offset + size;
// Find the extent for the offset.
for (; ; nextExtent++) {
if (nextExtent < extentDensity) {
if ((countedBlocks + GetExtentSize(extent, nextExtent) - 1) < blockNumber) {
countedBlocks += GetExtentSize(extent, nextExtent);
continue;
}
while (offset < lastOffset)
{
blockNumber = offset / gBlockSize;
currentExtent = extent + nextExtent * sizeofExtent;
break;
}
// Find the extent for the offset.
for (; ; nextExtent++)
{
if (nextExtent < extentDensity)
{
if ((countedBlocks + GetExtentSize(extent, nextExtent) -1) < blockNumber)
{
countedBlocks += GetExtentSize(extent, nextExtent);
continue;
}
if (extentBuffer == 0) {
extentBuffer = malloc(sizeofExtent * extentDensity);
if (extentBuffer == 0) return -1;
}
currentExtent = extent + nextExtent * sizeofExtent;
break;
}
nextExtentBlock = nextExtent / extentDensity;
if (currentExtentBlock != nextExtentBlock) {
ReadExtentsEntry(extentFile, countedBlocks, extentBuffer);
currentExtentBlock = nextExtentBlock;
}
if (extentBuffer == 0)
{
extentBuffer = malloc(sizeofExtent * extentDensity);
currentExtentSize = GetExtentSize(extentBuffer, nextExtent % extentDensity);
if (extentBuffer == 0)
{
return -1;
}
}
if ((countedBlocks + currentExtentSize - 1) >= blockNumber) {
currentExtent = extentBuffer + sizeofExtent * (nextExtent % extentDensity);
break;
}
countedBlocks += currentExtentSize;
}
nextExtentBlock = nextExtent / extentDensity;
readOffset = ((blockNumber - countedBlocks) * gBlockSize) +
(offset % gBlockSize);
if (currentExtentBlock != nextExtentBlock)
{
ReadExtentsEntry(extentFile, countedBlocks, extentBuffer);
currentExtentBlock = nextExtentBlock;
}
currentExtentSize = GetExtentSize(extentBuffer, nextExtent % extentDensity);
if ((countedBlocks + currentExtentSize - 1) >= blockNumber)
{
currentExtent = extentBuffer + sizeofExtent * (nextExtent % extentDensity);
break;
}
countedBlocks += currentExtentSize;
}
readOffset = ((blockNumber - countedBlocks) * gBlockSize) + (offset % gBlockSize);
// MacWen: fix overflow in multiplication by forcing 64bit multiplication
readSize = (long long)GetExtentSize(currentExtent, 0) * gBlockSize - readOffset;
if (readSize > (size - sizeRead)) readSize = size - sizeRead;
readSize = (long long)GetExtentSize(currentExtent, 0) * gBlockSize - readOffset;
readOffset += (long long)GetExtentStart(currentExtent, 0) * gBlockSize;
CacheRead(gCurrentIH, bufferPos, gAllocationOffset + readOffset,
readSize, cache);
if (readSize > (size - sizeRead))
{
readSize = size - sizeRead;
}
sizeRead += readSize;
offset += readSize;
bufferPos += readSize;
}
readOffset += (long long)GetExtentStart(currentExtent, 0) * gBlockSize;
if (extentBuffer) free(extentBuffer);
CacheRead(gCurrentIH, bufferPos, gAllocationOffset + readOffset, readSize, cache);
return sizeRead;
sizeRead += readSize;
offset += readSize;
bufferPos += readSize;
}
if (extentBuffer)
{
free(extentBuffer);
}
return sizeRead;
}
static long GetExtentStart(void * extents, long index)
HFSExtentDescriptor *hfsExtents = extents;
HFSPlusExtentDescriptor *hfsPlusExtents = extents;
if (gIsHFSPlus) start = SWAP_BE32(hfsPlusExtents[index].startBlock);
else start = SWAP_BE16(hfsExtents[index].startBlock);
if (gIsHFSPlus)
{
start = SWAP_BE32(hfsPlusExtents[index].startBlock);
}
else
{
start = SWAP_BE16(hfsExtents[index].startBlock);
}
return start;
return start;
}
static long GetExtentSize(void * extents, long index)
return size;
}
//==============================================================================
static long CompareHFSCatalogKeys(void * key, void * testKey)
{
HFSCatalogKey *searchKey, *trialKey;
long result, searchParentID, trialParentID;
HFSCatalogKey *searchKey, *trialKey;
long result, searchParentID, trialParentID;
searchKey = key;
trialKey = testKey;
searchKey = key;
trialKey = testKey;
searchParentID = SWAP_BE32(searchKey->parentID);
trialParentID = SWAP_BE32(trialKey->parentID);
searchParentID = SWAP_BE32(searchKey->parentID);
trialParentID = SWAP_BE32(trialKey->parentID);
// parent dirID is unsigned
if (searchParentID > trialParentID) result = 1;
else if (searchParentID < trialParentID) result = -1;
else {
// parent dirID's are equal, compare names
result = FastRelString(searchKey->nodeName, trialKey->nodeName);
}
// parent dirID is unsigned
if (searchParentID > trialParentID)
{
result = 1;
}
else if (searchParentID < trialParentID)
{
result = -1;
}
else
{
// parent dirID's are equal, compare names
result = FastRelString(searchKey->nodeName, trialKey->nodeName);
}
return result;
return result;
}
//==============================================================================
static long CompareHFSPlusCatalogKeys(void * key, void * testKey)
{
HFSPlusCatalogKey *searchKey, *trialKey;
long result, searchParentID, trialParentID;
searchKey = key;
trialKey = testKey;
searchParentID = SWAP_BE32(searchKey->parentID);
trialParentID = SWAP_BE32(trialKey->parentID);
HFSPlusCatalogKey *searchKey, *trialKey;
long result, searchParentID, trialParentID;
// parent dirID is unsigned
if (searchParentID > trialParentID) result = 1;
else if (searchParentID < trialParentID) result = -1;
else {
// parent dirID's are equal, compare names
if ((searchKey->nodeName.length == 0) || (trialKey->nodeName.length == 0))
result = searchKey->nodeName.length - trialKey->nodeName.length;
else
if (gCaseSensitive) {
result = BinaryUnicodeCompare(&searchKey->nodeName.unicode[0],
searchKey = key;
trialKey = testKey;
searchParentID = SWAP_BE32(searchKey->parentID);
trialParentID = SWAP_BE32(trialKey->parentID);
// parent dirID is unsigned
if (searchParentID > trialParentID)
{
result = 1;
}
else if (searchParentID < trialParentID)
{
result = -1;
}
else
{
// parent dirID's are equal, compare names
if ((searchKey->nodeName.length == 0) || (trialKey->nodeName.length == 0))
{
result = searchKey->nodeName.length - trialKey->nodeName.length;
}
else if (gCaseSensitive)
{
result = BinaryUnicodeCompare(&searchKey->nodeName.unicode[0],
SWAP_BE16(searchKey->nodeName.length),
&trialKey->nodeName.unicode[0],
SWAP_BE16(trialKey->nodeName.length));
} else {
result = FastUnicodeCompare(&searchKey->nodeName.unicode[0],
}
else
{
result = FastUnicodeCompare(&searchKey->nodeName.unicode[0],
SWAP_BE16(searchKey->nodeName.length),
&trialKey->nodeName.unicode[0],
SWAP_BE16(trialKey->nodeName.length), OSBigEndian);
}
}
}
}
return result;
return result;
}
//==============================================================================
static long CompareHFSExtentsKeys(void * key, void * testKey)
{
HFSExtentKey *searchKey, *trialKey;
long result;
searchKey = key;
trialKey = testKey;
// assume searchKey < trialKey
result = -1;
HFSExtentKey *searchKey, *trialKey;
long result;
if (searchKey->fileID == trialKey->fileID) {
// FileNum's are equal; compare fork types
if (searchKey->forkType == trialKey->forkType) {
// Fork types are equal; compare allocation block number
if (searchKey->startBlock == trialKey->startBlock) {
// Everything is equal
result = 0;
} else {
// Allocation block numbers differ; determine sign
if (SWAP_BE16(searchKey->startBlock) > SWAP_BE16(trialKey->startBlock))
result = 1;
}
} else {
// Fork types differ; determine sign
if (searchKey->forkType > trialKey->forkType) result = 1;
}
} else {
// FileNums differ; determine sign
if (SWAP_BE32(searchKey->fileID) > SWAP_BE32(trialKey->fileID))
result = 1;
}
searchKey = key;
trialKey = testKey;
return result;
// assume searchKey < trialKey
result = -1;
if (searchKey->fileID == trialKey->fileID)
{
// FileNum's are equal; compare fork types
if (searchKey->forkType == trialKey->forkType)
{
// Fork types are equal; compare allocation block number
if (searchKey->startBlock == trialKey->startBlock)
{
// Everything is equal
result = 0;
}
else
{
// Allocation block numbers differ; determine sign
if (SWAP_BE16(searchKey->startBlock) > SWAP_BE16(trialKey->startBlock))
{
result = 1;
}
}
}
else
{
// Fork types differ; determine sign
if (searchKey->forkType > trialKey->forkType)
{
result = 1;
}
}
}
else
{
// FileNums differ; determine sign
if (SWAP_BE32(searchKey->fileID) > SWAP_BE32(trialKey->fileID))
{
result = 1;
}
}
return result;
}
//==============================================================================
static long CompareHFSPlusExtentsKeys(void * key, void * testKey)
{
HFSPlusExtentKey *searchKey, *trialKey;
long result;
HFSPlusExtentKey*searchKey, *trialKey;
searchKey = key;
trialKey = testKey;
longresult;
// assume searchKey < trialKey
result = -1;
searchKey = key;
trialKey = testKey;
if (searchKey->fileID == trialKey->fileID) {
// FileNum's are equal; compare fork types
if (searchKey->forkType == trialKey->forkType) {
// Fork types are equal; compare allocation block number
if (searchKey->startBlock == trialKey->startBlock) {
// Everything is equal
result = 0;
} else {
// Allocation block numbers differ; determine sign
if (SWAP_BE32(searchKey->startBlock) > SWAP_BE32(trialKey->startBlock))
result = 1;
}
} else {
// Fork types differ; determine sign
if (searchKey->forkType > trialKey->forkType) result = 1;
}
} else {
// FileNums differ; determine sign
if (SWAP_BE32(searchKey->fileID) > SWAP_BE32(trialKey->fileID))
result = 1;
}
// assume searchKey < trialKey
result = -1;
if (searchKey->fileID == trialKey->fileID)
{
// FileNum's are equal; compare fork types
if (searchKey->forkType == trialKey->forkType)
{
// Fork types are equal; compare allocation block number
if (searchKey->startBlock == trialKey->startBlock)
{
// Everything is equal
result = 0;
}
else
{
// Allocation block numbers differ; determine sign
if (SWAP_BE32(searchKey->startBlock) > SWAP_BE32(trialKey->startBlock))
{
result = 1;
}
}
}
else
{
// Fork types differ; determine sign
if (searchKey->forkType > trialKey->forkType)
{
result = 1;
}
}
}
else
{
// FileNums differ; determine sign
if (SWAP_BE32(searchKey->fileID) > SWAP_BE32(trialKey->fileID))
{
result = 1;
}
}
return result;
}
trunk/i386/libsaio/allocate.c
4949
5050
5151
52
52
53
5354
5455
5556
......
7172
7273
7374
74
75
76
7577
7678
7779
7880
7981
80
82
83
8184
8285
8386
buffer = malloc(2 * sizeof(uint32_t));
if (buffer == 0) {
if (buffer == 0)
{
free(nameBuf);
return -1;
}
{
long addr;
if (gImageLastKernelAddr == 0) {
if (gImageLastKernelAddr == 0)
{
gImageLastKernelAddr = RoundPage(bootArgs->kaddr + bootArgs->ksize);
}
addr = gImageLastKernelAddr;
gImageLastKernelAddr += RoundPage(inSize);
if ( gImageLastKernelAddr >= (KERNEL_ADDR + KERNEL_LEN) ) {
if ( gImageLastKernelAddr >= (KERNEL_ADDR + KERNEL_LEN) )
{
stop ("AllocateKernelMemory error");
}
trunk/i386/libsaio/bootargs.h
131131
132132
133133
134
135
136
137
138
134139
135
140
141
136142
137143
138144
139145
140146
141
147
142148
143149
144150
......
159165
160166
161167
162
163
168
169
164170
165
171
166172
167173
168
174
169175
170
176
171177
172178
173179
174
180
175181
176182
177183
178
179
180
184
185
186
181187
182188
183189
184
190
191
185192
186193
187194
......
202209
203210
204211
212
205213
206214
207215
#define kBootArgsFlagRebootOnPanic(1 << 0)
#define kBootArgsFlagHiDPI(1 << 1)
#define kBootArgsFlagBlack(1 << 2)
#define kBootArgsFlagCSRActiveConfig(1 << 3)
#define kBootArgsFlagCSRPendingConfig(1 << 4)
#define kBootArgsFlagCSRBoot(1 << 5)
#define kBootArgsFlagBlackBg(1 << 6)
#define kBootArgsFlagLoginUI(1 << 7)
typedef struct boot_args {
typedef struct boot_args
{
uint16_t Revision;/* Revision of boot_args structure */
uint16_t Version;/* Version of boot_args structure */
uint8_t efiMode; /* 32 means 32-bit mode, 64 means 64-bit mode */
uint8_t debugMode; /* Bit field with behavior changes */
uint16_t flags; // uint8_t __reserved1[2];
uint16_t flags;
char CommandLine[BOOT_LINE_LENGTH];/* Passed in command line */
uint32_t efiRuntimeServicesPageCount;
uint64_t efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */
uint32_t efiSystemTable;/* physical address of system table in runtime area */
uint32_t kslide;// uint32_t __reserved2;
uint32_t efiSystemTable; /* physical address of system table in runtime area */
uint32_t kslide;
uint32_t performanceDataStart;/* physical address of log */
uint32_t performanceDataStart; /* physical address of log */
uint32_t performanceDataSize;
uint32_t keyStoreDataStart;/* physical address of key store data */
uint32_t keyStoreDataStart; /* physical address of key store data */
uint32_t keyStoreDataSize;
uint64_tbootMemStart;/* physical address of interpreter boot memory */
uint64_tbootMemStart;
uint64_tbootMemSize;
uint64_t PhysicalMemorySize;
uint64_t FSBFrequency;
//
uint64_t pciConfigSpaceBaseAddress;
uint32_t pciConfigSpaceStartBusNumber;
uint32_t pciConfigSpaceEndBusNumber;
uint32_t __reserved4[730];
//
// uint32_t __reserved4[734];
uint32_tcsrActiveConfig;
uint32_tcsrPendingConfig;
uint32_t __reserved4[728];
} boot_args;
typedef struct boot_args_pre_lion {
typedef struct boot_args_pre_lion
{
uint16_t Revision;/* Revision of boot_args structure */
uint16_t Version;/* Version of boot_args structure */
uint32_t efiRuntimeServicesPageStart; /* physical address of defragmented runtime pages */
uint32_t efiRuntimeServicesPageCount;
uint32_t efiSystemTable; /* physical address of system table in runtime area */
uint8_t efiMode; /* 32 means 32-bit mode, 64 means 64-bit mode */
trunk/i386/libsaio/dram_controllers.c
222222
223223
224224
225
225226
226227
227228
......
236237
237238
238239
240
239241
240242
241243
// Compute RAM Frequency
Platform.RAM.Frequency = (Platform.CPU.FSBFrequency * mch_ratio) / 100000;
// DBG("ram_fsb %d\n", Platform.RAM.Frequency);
}
// Compute RAM Frequency
Platform.RAM.Frequency = Platform.CPU.FSBFrequency * mch_ratio / 2;
// DBG("ram_fsb %d\n", Platform.RAM.Frequency);
}
/*
trunk/i386/libsaio/ntfs.c
106106
107107
108108
109
110
109
111110
112111
113112
......
148147
149148
150149
151
152
150
153151
154
155
156
157
158
159
160
161
162
163
152
153
154
155
156
157
158
159
160
161
164162
165
166
167
168
163
164
165
166
167
169168
170
171
172
173
174
175
176
177
169
170
171
172
173
174
175
176
178177
179
180
181
182
183
184
185
186
187
188
189
190
191
192
178
193179
194
195
196
197
198
199
200
201
202
203
204
205
180
181
182
183
184
185
186
187
188
189
190
206191
207
208
209
210
211
212
213
214
215
216
192
193
194
195
196
197
198
199
200
201
202
203
217204
218
219
220
221
222
223
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
224222
225223
226224
......
284282
285283
286284
287
288
289
290
291
292
293
285
286
287
288
289
294290
295
291
296292
297
298
293
299294
295
296
297
300298
301
302
299
300
301
302
303
303304
304305
305306
......
308309
309310
310311
311
312
313
312314
313315
314316
......
324326
325327
326328
327
329
330
328331
329332
330333
331334
332335
333
336
337
334338
335339
336340
337341
338
339
342
340343
341344
342345
......
349352
350353
351354
355
352356
357
353358
354359
355360
361
356362
363
357364
358365
359366
* Find a resident attribute of a given type. Returns a pointer to the
* attribute data, and its size in bytes.
*/
static int
ntfs_find_attr(
static int ntfs_find_attr(
char *buf,
u_int32_t attrType,
void **attrData,
/*
* Examine a volume to see if we recognize it as a mountable.
*/
void
NTFSGetDescription(CICell ih, char *str, long strMaxLen)
void NTFSGetDescription(CICell ih, char *str, long strMaxLen)
{
struct bootfile *boot;
unsigned bytesPerSector;
unsigned sectorsPerCluster;
int mftRecordSize;
u_int64_t totalClusters;
u_int64_t cluster, mftCluster;
size_t mftOffset;
void *nameAttr;
size_t nameSize;
char *buf;
struct bootfile *boot;
unsigned bytesPerSector;
unsigned sectorsPerCluster;
int mftRecordSize;
u_int64_t totalClusters;
u_int64_t cluster, mftCluster;
size_t mftOffset;
void *nameAttr;
size_t nameSize;
char *buf;
buf = (char *)malloc(MAX_CLUSTER_SIZE);
if (buf == 0) {
goto error;
}
buf = (char *)malloc(MAX_CLUSTER_SIZE);
if (buf == 0)
{
goto error;
}
/*
* Read the boot sector, check signatures, and do some minimal
* sanity checking. NOTE: the size of the read below is intended
* to be a multiple of all supported block sizes, so we don't
* have to determine or change the device's block size.
*/
Seek(ih, 0);
Read(ih, (long)buf, MAX_BLOCK_SIZE);
/*
* Read the boot sector, check signatures, and do some minimal
* sanity checking. NOTE: the size of the read below is intended
* to be a multiple of all supported block sizes, so we don't
* have to determine or change the device's block size.
*/
Seek(ih, 0);
Read(ih, (long)buf, MAX_BLOCK_SIZE);
boot = (struct bootfile *) buf;
/*
* The first three bytes are an Intel x86 jump instruction. I assume it
* can be the same forms as DOS FAT:
* 0xE9 0x?? 0x??
* 0xEC 0x?? 0x90
* where 0x?? means any byte value is OK.
*/
if (boot->reserved1[0] != 0xE9
&& (boot->reserved1[0] != 0xEB || boot->reserved1[2] != 0x90))
{
goto error;
}
boot = (struct bootfile *) buf;
/*
* Check the "NTFS " signature.
*/
if (memcmp((const char *)boot->bf_sysid, "NTFS ", 8) != 0)
{
/*
* Check for EXFAT. Finish by jumping to error to free buf,
* although if it is EXFAT then it's no an error.
*/
EXFATGetDescription(ih, str, strMaxLen);
goto error;
}
/*
* The first three bytes are an Intel x86 jump instruction. I assume it
* can be the same forms as DOS FAT:
* 0xE9 0x?? 0x??
* 0xEC 0x?? 0x90
* where 0x?? means any byte value is OK.
*/
if (boot->reserved1[0] != 0xE9 && (boot->reserved1[0] != 0xEB || boot->reserved1[2] != 0x90))
{
goto error;
}
/*
* Make sure the bytes per sector and sectors per cluster are
* powers of two, and within reasonable ranges.
*/
bytesPerSector = OSReadLittleInt16(&boot->bf_bps,0);
if ((bytesPerSector & (bytesPerSector-1)) || bytesPerSector < 512 || bytesPerSector > 32768)
{
//verbose("NTFS: invalid bytes per sector (%d)\n", bytesPerSector);
goto error;
}
/*
* Check the "NTFS " signature.
*/
if (memcmp((const char *)boot->bf_sysid, "NTFS ", 8) != 0)
{
/*
* Check for EXFAT. Finish by jumping to error to free buf,
* although if it is EXFAT then it's no an error.
*/
EXFATGetDescription(ih, str, strMaxLen);
goto error;
}
sectorsPerCluster = boot->bf_spc;/* Just one byte; no swapping needed */
if ((sectorsPerCluster & (sectorsPerCluster-1)) || sectorsPerCluster > 128)
{
//verbose("NTFS: invalid sectors per cluster (%d)\n", bytesPerSector);
goto error;
}
/*
* Make sure the bytes per sector and sectors per cluster are
* powers of two, and within reasonable ranges.
*/
bytesPerSector = OSReadLittleInt16(&boot->bf_bps,0);
if ((bytesPerSector & (bytesPerSector-1)) || bytesPerSector < 512 || bytesPerSector > 32768)
{
//verbose("NTFS: invalid bytes per sector (%d)\n", bytesPerSector);
goto error;
}
sectorsPerCluster = boot->bf_spc;/* Just one byte; no swapping needed */
if ((sectorsPerCluster & (sectorsPerCluster-1)) || sectorsPerCluster > 128)
{
//verbose("NTFS: invalid sectors per cluster (%d)\n", bytesPerSector);
goto error;
}
/*
* Calculate the number of clusters from the number of sectors.
/*
* Loop over the attributes, looking for $VOLUME_NAME (0x60).
*/
if(ntfs_find_attr(buf, NTFS_A_VOLUMENAME, &nameAttr, &nameSize) != 0)
{
//verbose("NTFS: $VOLUME_NAME attribute not found\n");
goto error;
}
str[0] = '\0';
if(ntfs_find_attr(buf, NTFS_A_VOLUMENAME, &nameAttr, &nameSize) != 0)
{
//verbose("NTFS: $VOLUME_NAME attribute not found\n");
goto error;
}
utf_encodestr( nameAttr, nameSize / 2, (u_int8_t *)str, strMaxLen, OSLittleEndian );
str[0] = '\0';
free(buf);
return;
utf_encodestr( nameAttr, nameSize / 2, (u_int8_t *)str, strMaxLen, OSLittleEndian );
free(buf);
return;
error:
if (buf) free(buf);
return;
if (buf)
{
free(buf);
}
return;
}
long NTFSGetUUID(CICell ih, char *uuidStr)
struct bootfile *boot;
void *buf = malloc(MAX_BLOCK_SIZE);
if ( !buf ) {
if ( !buf )
{
return -1;
}
boot = (struct bootfile *) buf;
// Check for NTFS signature
if ( memcmp((void*)boot->bf_sysid, NTFS_BBID, NTFS_BBIDLEN) != 0 ) {
if ( memcmp((void*)boot->bf_sysid, NTFS_BBID, NTFS_BBIDLEN) != 0 )
{
// If not NTFS, maybe it is EXFAT
return EXFATGetUUID(ih, uuidStr);
}
// Check for non-null volume serial number
if( !boot->bf_volsn ) {
if( !boot->bf_volsn )
{
return -1;
}
// Use UUID like the one you get on Windows
sprintf(uuidStr, "%04X-%04X",(unsigned short)(boot->bf_volsn >> 16) & 0xFFFF,
(unsigned short)boot->bf_volsn & 0xFFFF);
sprintf(uuidStr, "%04X-%04X",(unsigned short)(boot->bf_volsn >> 16) & 0xFFFF, (unsigned short)boot->bf_volsn & 0xFFFF);
return 0;
}
// Looking for NTFS signature.
if (strncmp((const char *)part_bootfile->bf_sysid, NTFS_BBID, NTFS_BBIDLEN) == 0)
{
result = true;
}
// If not NTFS, maybe it is EXFAT
if (!result)
{
result = EXFATProbe(buffer);
}
return result;
}
trunk/i386/libsaio/sys.c
161161
162162
163163
164
164
165
165166
166167
167168
......
175176
176177
177178
178
179
180
179181
180182
181183
182
184
185
183186
184187
185188
......
197200
198201
199202
200
203
204
201205
202206
203207
......
228232
229233
230234
231
235
236
237
232238
233239
234240
235241
236
242
243
237244
238245
239246
240247
241248
242249
243
250
251
252
244253
245254
246255
......
248257
249258
250259
251
260
252261
253262
254263
......
301310
302311
303312
304
305
313
314
315
316
306317
307318
308319
309320
310
321
322
311323
312324
313325
......
316328
317329
318330
319
331
332
320333
321334
322335
......
325338
326339
327340
328
341
342
329343
330344
331345
......
350364
351365
352366
353
367
368
354369
355370
356371
357
372
358373
359
374
360375
361376
362377
......
374389
375390
376391
377
392
393
378394
379395
380396
......
401417
402418
403419
404
420
421
405422
406423
407424
......
434451
435452
436453
437
438
454
455
456
457
439458
440
459
441460
442461
443462
......
454473
455474
456475
457
476
477
458478
459
479
480
481
460482
461483
462484
......
466488
467489
468490
469
470
491
492
471493
472
473
474
494
495
496
475497
476
477
498
499
478500
479
480
481
501
502
503
482504
483
505
484506
485507
486508
......
528550
529551
530552
531
553
554
532555
533556
534557
......
536559
537560
538561
539
562
540563
541564
542565
......
544567
545568
546569
547
570
571
548572
549573
550574
551
575
576
552577
553578
554579
555
556
580
581
582
583
557584
558585
559586
560587
561588
562589
563
590
591
564592
565593
566594
567
595
596
568597
569
598
599
570600
571601
572602
573603
574604
575605
606
576607
577608
578
609
579610
580611
581612
......
586617
587618
588619
589
620
621
590622
591623
592624
......
603635
604636
605637
606
638
639
607640
608641
609642
......
619652
620653
621654
622
655
656
623657
624658
625659
......
820854
821855
822856
823
857
858
824859
825860
826861
......
835870
836871
837872
838
873
874
839875
840
876
877
841878
842879
843
880
881
882
844883
845884
846885
......
854893
855894
856895
857
896
897
858898
859899
860900
861901
862902
863903
864
904
905
865906
866907
867908
......
875916
876917
877918
878
919
920
879921
880922
881923
882
883
884
924
925
926
927
928
929
885930
886931
887932
......
893938
894939
895940
896
897
898
941
942
943
944
945
946
899947
900948
901949
......
909957
910958
911959
912
913
960
961
962
963
914964
915965
916
966
967
917968
918969
919970
......
922973
923974
924975
925
976
977
926978
927979
928980
......
930982
931983
932984
933
985
986
934987
935988
936989
......
942995
943996
944997
945
998
999
9461000
9471001
948
1002
1003
9491004
9501005
9511006
......
9751030
9761031
9771032
978
1033
1034
9791035
9801036
9811037
......
9841040
9851041
9861042
987
1043
9881044
989
1045
1046
9901047
9911048
9921049
......
10101067
10111068
10121069
1013
1070
1071
10141072
10151073
10161074
......
10191077
10201078
10211079
1022
1080
1081
10231082
10241083
10251084
......
10341093
10351094
10361095
1037
1038
1096
1097
1098
1099
10391100
10401101
10411102
10421103
1043
1104
1105
10441106
10451107
10461108
......
10501112
10511113
10521114
1053
1115
1116
10541117
10551118
10561119
10571120
1058
1059
1060
1061
1062
1063
1121
1122
1123
1124
1125
1126
1127
10641128
10651129
10661130
10671131
10681132
1069
1133
1134
10701135
10711136
10721137
......
10781143
10791144
10801145
1081
1146
1147
10821148
10831149
1084
1150
10851151
10861152
10871153
10881154
1089
1155
1156
10901157
10911158
1092
1159
1160
1161
10931162
10941163
10951164
1096
1165
1166
10971167
10981168
10991169
......
11191189
11201190
11211191
1122
1123
1192
1193
1194
1195
11241196
11251197
1126
1127
1198
1199
1200
1201
1202
11281203
1129
1204
1205
1206
11301207
11311208
1132
1209
1210
1211
11331212
11341213
11351214
......
11371216
11381217
11391218
1140
1141
1219
1220
1221
1222
11421223
11431224
11441225
11451226
1146
1227
1228
11471229
11481230
11491231
......
11581240
11591241
11601242
1161
1243
1244
11621245
11631246
11641247
11651248
11661249
1167
1250
1251
11681252
1169
1253
1254
11701255
11711256
11721257
1173
1258
1259
11741260
11751261
11761262
// Resolve the boot volume from the file spec.
if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL) {
if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL)
{
return -1;
}
const char *filePath;
BVRef bvr;
if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL) {
if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL)
{
return -1;
}
if (bvr->fs_readfile == NULL) {
if (bvr->fs_readfile == NULL)
{
return -1;
}
// Resolve the boot volume from the file spec.
if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL) {
if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL)
{
return -1;
}
DBG("Fat Binary found. Reading thin part only...\n");
length = readFile(bvr, (char *)filePath, (void *)kLoadAddr, (unsigned long)(*binary) - kLoadAddr, length);
*binary = (void *)kLoadAddr;
} else {
}
else
{
// Not a fat binary; read the rest of the file
DBG("Thin Binary found. Reading rest of the file...\n");
length2 = readFile(bvr, (char *)filePath, (void *)(kLoadAddr + length), length, 0);
if (length2 == -1) {
if (length2 == -1)
{
return -1;
}
length += length2;
}
}
} else {
}
else
{
length = bvr->fs_loadfile(bvr, (char *)filePath);
if (length > 0)
ThinFatFile(binary, &length);
}
}
return length;
}
i = 0;
fmtbase = 0;
for(fmtidx = 0; fmtidx < sizeof(uuidfmt); fmtidx++) {
for (i = 0; i < uuidfmt[fmtidx]; i++) {
for(fmtidx = 0; fmtidx < sizeof(uuidfmt); fmtidx++)
{
for (i = 0; i < uuidfmt[fmtidx]; i++)
{
uint8_t byte = mdresult[fmtbase + i];
char nib = byte >> 4;
*p = nib + '0'; // 0x4 -> '4'
if (*p > '9') {
if (*p > '9')
{
*p = (nib - 9 + ('A'-1)); // 0xB -> 'B'
}
nib = byte & 0xf;
*p = nib + '0'; // 0x4 -> '4'
if (*p > '9') {
if (*p > '9')
{
*p = (nib - 9 + ('A'-1)); // 0xB -> 'B'
}
fmtbase += i;
if (fmtidx < sizeof(uuidfmt) - 1) {
if (fmtidx < sizeof(uuidfmt) - 1)
{
*(p++) = '-';
}
else
// Resolve the boot volume from the dir spec.
if ((bvr = getBootVolumeRef(dirSpec, &dirPath)) == NULL) {
if ((bvr = getBootVolumeRef(dirSpec, &dirPath)) == NULL)
{
return -1;
}
// Returns 0 on success or -1 when there are no additional entries.
// Return 0 on success, or -1 if there are no additional entries.
return bvr->fs_getdirentry( bvr,
return bvr->fs_getdirentry( bvr,
/* dirPath */ (char *)dirPath,
/* dirIndex */ dirIndex,
/* dirEntry */ (char **)name, flags, time, 0, 0 );
long long index = 0;
const char * entryName;
if (gMakeDirSpec == 0) {
if (gMakeDirSpec == 0)
{
gMakeDirSpec = (char *)malloc(1024);
}
while (GetDirEntry(dirSpec, &index, &entryName, flags, time) == 0)
{
if (strcmp(entryName, name) == 0) {
if (strcmp(entryName, name) == 0)
{
return 0; // success
}
}
intfd;
// Locate a free descriptor slot.
for (fd = 0; fd < NFILES; fd++) {
if (iob[fd].i_flgs == 0) {
for (fd = 0; fd < NFILES; fd++)
{
if (iob[fd].i_flgs == 0)
{
return fd;
}
}
}
stop("Out of file descriptors");
// not reached
{
register struct iob * io;
if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0)
{
return NULL;
} else {
}
else
{
return io;
}
}
int openmem(char * buf, int len)
{
int fdesc;
struct iob * io;
int fdesc;
struct iob * io;
fdesc = GetFreeFd();
io = &iob[fdesc];
bzero(io, sizeof(*io));
fdesc = GetFreeFd();
io = &iob[fdesc];
bzero(io, sizeof(*io));
// Mark the descriptor as taken. Set the F_MEM flag to indicate
// that the file buffer is provided by the caller.
// Mark the descriptor as taken. Set the F_MEM flag to indicate
// that the file buffer is provided by the caller.
io->i_flgs = F_ALLOC | F_MEM;
io->i_buf = buf;
io->i_filesize = len;
io->i_flgs = F_ALLOC | F_MEM;
io->i_buf = buf;
io->i_filesize = len;
return fdesc;
return fdesc;
}
//==========================================================================
BVRefbvr;
// Resolve the boot volume from the file spec.
if ((bvr = getBootVolumeRef(path, &filepath)) != NULL) {
if ((bvr = getBootVolumeRef(path, &filepath)) != NULL)
{
return open_bvr(bvr, filepath, flags);
}
return -1;
int open_bvdev(const char *bvd, const char *path, int flags)
{
const struct devsw*dp;
const struct devsw*dp;
const char*cp;
BVRefbvr;
inti;
intunit;
intpartition;
if ((i = open(path, flags)) >= 0) {
if ((i = open(path, flags)) >= 0)
{
return i;
}
if (bvd == NULL || (len = strlen(bvd)) < 2) {
if (bvd == NULL || (len = strlen(bvd)) < 2)
{
return -1;
}
for (dp=devsw; dp->name; dp++) {
if (bvd[0] == dp->name[0] && bvd[1] == dp->name[1]) {
for (dp=devsw; dp->name; dp++)
{
if (bvd[0] == dp->name[0] && bvd[1] == dp->name[1])
{
unit = 0;
partition = 0;
/* get optional unit and partition */
if (len >= 5 && bvd[2] == '(') { /* min must be present xx(0) */
cp = &bvd[3];
i = 0;
while ((cp - path) < len && isdigit(*cp)) {
while ((cp - path) < len && isdigit(*cp))
{
i = i * 10 + *cp++ - '0';
unit = i;
}
if (*cp++ == ',') {
if (*cp++ == ',')
{
i = 0;
while ((cp - path) < len && isdigit(*cp)) {
while ((cp - path) < len && isdigit(*cp))
{
i = i * 10 + *cp++ - '0';
partition = i;
}
}
}
bvr = newBootVolumeRef(dp->biosdev + unit, partition);
return open_bvr(bvr, path, flags);
}
}
}
return -1;
}
{
struct iob * io;
if ((io = iob_from_fdesc(fdesc)) == NULL) {
if ((io = iob_from_fdesc(fdesc)) == NULL)
{
return (-1);
}
{
struct iob * io;
if ((io = iob_from_fdesc(fdesc)) == NULL) {
if ((io = iob_from_fdesc(fdesc)) == NULL)
{
return (-1);
}
{
struct iob * io;
if ((io = iob_from_fdesc(fdesc)) == NULL) {
if ((io = iob_from_fdesc(fdesc)) == NULL)
{
return 0;
}
const char * systemConfigDir()
{
if (gBootFileType == kNetworkDeviceType) {
if (gBootFileType == kNetworkDeviceType)
{
return "";
}
return "/Library/Preferences/SystemConfiguration";
BVRef bvr = 0;
bvr = diskScanBootVolumes(biosdev, count);
if (bvr == NULL) {
if (bvr == NULL)
{
bvr = nbpScanBootVolumes(biosdev, count);
if (bvr != NULL) {
if (bvr != NULL)
{
gBootFileType = kNetworkDeviceType;
}
} else {
}
else
{
gBootFileType = kBlockDeviceType;
}
}
int hd = 0;
// Testing up to MAX_HDD_COUNT hard drives.
while(!testBiosread(0x80 + hd, 0) && hd < MAX_HDD_COUNT) {
while(!testBiosread(0x80 + hd, 0) && hd < MAX_HDD_COUNT)
{
bvCount = 0;
scanBootVolumes(0x80 + hd, &bvCount);
hd++;
}
// Also scanning CD/DVD drive.
if (biosDevIsCDROM(gBIOSDev)) {
if (biosDevIsCDROM(gBIOSDev))
{
bvCount = 0;
scanBootVolumes(gBIOSDev, &bvCount);
}
bool foundPrimary = false;
BVRef bvr, bvr1 = 0, bvr2 = 0;
if (chain->filtered) {
if (chain->filtered)
{
filteredChain = true;
}
if (multiboot_partition_set) {
for ( bvr = chain; bvr; bvr = bvr->next ) {
if ( bvr->part_no == multiboot_partition && bvr->biosdev == gBIOSDev ) {
if (multiboot_partition_set)
{
for ( bvr = chain; bvr; bvr = bvr->next )
{
if ( bvr->part_no == multiboot_partition && bvr->biosdev == gBIOSDev )
{
return bvr;
}
}
* We accept only kBVFlagSystemVolume or kBVFlagForeignBoot volumes.
*/
char *val = XMLDecode(getStringForKey(kDefaultPartition, &bootInfo->chameleonConfig));
if (val) {
for ( bvr = chain; bvr; bvr = bvr->next ) {
if (matchVolumeToString(bvr, val, false)) {
if (val)
{
for ( bvr = chain; bvr; bvr = bvr->next )
{
if (matchVolumeToString(bvr, val, false))
{
free(val);
return bvr;
}
* If not found any active partition then we will
* select this volume as the boot volume.
*/
for ( bvr = chain; bvr; bvr = bvr->next ) {
if (multiboot_skip_partition_set) {
for ( bvr = chain; bvr; bvr = bvr->next )
{
if (multiboot_skip_partition_set)
{
if (bvr->part_no == multiboot_skip_partition) continue;
}
if ( bvr->flags & kBVFlagPrimary && bvr->biosdev == gBIOSDev ) {
if ( bvr->flags & kBVFlagPrimary && bvr->biosdev == gBIOSDev )
{
foundPrimary = true;
}
if ( bvr->flags & (kBVFlagBootable|kBVFlagSystemVolume)
&& gBIOSBootVolume
&& (!filteredChain || (filteredChain && bvr->visible))
&& bvr->biosdev == gBIOSDev ) {
&& bvr->biosdev == gBIOSDev )
{
bvr2 = bvr;
}
// from r491,
if ( bvr->flags & kBVFlagBootable
&& ! gBIOSBootVolume
&& bvr->biosdev == gBIOSDev ) {
&& bvr->biosdev == gBIOSDev )
{
bvr2 = bvr;
}
}
{
for ( bvr = chain; bvr; bvr = bvr->next )
{
if ( bvr->flags & kBVFlagNativeBoot && bvr->biosdev == gBIOSDev ) {
if ( bvr->flags & kBVFlagNativeBoot && bvr->biosdev == gBIOSDev )
{
bvr1 = bvr;
}
if ( bvr->flags & kBVFlagPrimary && bvr->biosdev == gBIOSDev ) {
if ( bvr->flags & kBVFlagPrimary && bvr->biosdev == gBIOSDev )
{
bvr2 = bvr;
}
}
gRootVolume = volume;
// Veto non-native FS. Basically that means don't allow the root volume to
// be set to a volume we can't read files from.
if(gRootVolume != NULL && ((gRootVolume->flags & kBVFlagNativeBoot) == 0)) {
if(gRootVolume != NULL && ((gRootVolume->flags & kBVFlagNativeBoot) == 0))
{
gRootVolume = NULL;
}
}
{
// Record default boot device.
gBootVolume = selectBootVolume(chain);
// turbo - Save the ORIGINAL boot volume too for loading our mkext
if (!gBIOSBootVolume) {
if (!gBIOSBootVolume)
{
gBIOSBootVolume = gBootVolume;
}
// Search for left parenthesis in the path specification.
for (cp = path; *cp; cp++) {
if (*cp == LP || *cp == '/') {
if (*cp == LP || *cp == '/')
{
break;
}
}
cp = path;
// Path is using the implicit current device so if there is
// no current device, then we must fail.
if (gRootVolume == NULL) {
if (gRootVolume == NULL)
{
return NULL;
}
} else if ((cp - path) == 2) { // found "xx("
// Check the 2 character device name pointed by 'xp'.
for (dp = devsw; dp->name; dp++) {
if ((xp[0] == dp->name[0]) && (xp[1] == dp->name[1])) {
for (dp = devsw; dp->name; dp++)
{
if ((xp[0] == dp->name[0]) && (xp[1] == dp->name[1]))
{
break;// Found matching entry.
}
}
if (dp->name == NULL) {
if (dp->name == NULL)
{
error("Unknown device '%c%c'\n", xp[0], xp[1]);
return NULL;
}
i = 0;
while (*cp >= '0' && *cp <= '9') {
while (*cp >= '0' && *cp <= '9')
{
i = i * 10 + *cp++ - '0';
unit = i;
}
// Unit is no longer optional and never really was.
// If the user failed to specify it then the unit number from the previous kernDev
// would have been used which makes little sense anyway.
// For example, if the user did fd()/foobar and the current root device was the
// second hard disk (i.e. unit 1) then fd() would select the second floppy drive!
if (unit == -1) {
// Unit is no longer optional and never really was.
// If the user failed to specify it then the unit number from the previous kernDev
// would have been used which makes little sense anyway.
// For example, if the user did fd()/foobar and the current root device was the
// second hard disk (i.e. unit 1) then fd() would select the second floppy drive!
if (unit == -1)
{
return NULL;
}
// Extract the optional partition number from the specification.
if (*cp == ',') {
if (*cp == ',')
{
part = atoi(++cp);
}
for ( ; *cp && *cp != RP; cp++) /* LOOP */;
if (*cp == RP) {
if (*cp == RP)
{
cp++;
}
biosdev = dp->biosdev + unit;
bvr = newBootVolumeRef(biosdev, part);
if (bvr == NULL) {
if (bvr == NULL)
{
return NULL;
}
} else {
}
else
{
// Bad device specifier, skip past the right paren.
for (cp++; *cp && *cp != RP; cp++) /* LOOP */;
if (*cp == RP) {
if (*cp == RP)
{
cp++;
}
bvr = bvr1 = NULL;
// Try resolving "rd" and "bt" devices first.
if (biosdev == kPseudoBIOSDevRAMDisk) {
if (gRAMDiskVolume) {
if (biosdev == kPseudoBIOSDevRAMDisk)
{
if (gRAMDiskVolume)
{
bvr1 = gRAMDiskVolume;
}
} else if (biosdev == kPseudoBIOSDevBooter) {
if (gRAMDiskVolume != NULL && gRAMDiskBTAliased) {
}
else if (biosdev == kPseudoBIOSDevBooter)
{
if (gRAMDiskVolume != NULL && gRAMDiskBTAliased)
{
bvr1 = gRAMDiskVolume;
} else {
}
else
{
bvr1 = gBIOSBootVolume;
}
} else {
}
else
{
// Fetch the volume list from the device.
scanBootVolumes( biosdev, NULL );
// Look for a perfect match based on device and partition number.
for ( bvr1 = NULL, bvr = bvrChain; bvr; bvr = bvr->next ) {
if ( ( bvr->flags & kBVFlagNativeBoot ) == 0 ) {
for ( bvr1 = NULL, bvr = bvrChain; bvr; bvr = bvr->next )
{
if ( ( bvr->flags & kBVFlagNativeBoot ) == 0 )
{
continue;
}
bvr1 = bvr;
if ( bvr->part_no == partno ) {
if ( bvr->part_no == partno )
{
break;
}
}
// Returns length of the out string
int getDeviceDescription(BVRef bvr, char *str)
{
if(!str) {
if(!str)
{
return 0;
}
*str = '\0';
if (bvr) {
if (bvr)
{
const struct devsw *dp = devsw;
while(dp->name && bvr->biosdev >= dp->biosdev) {
while(dp->name && bvr->biosdev >= dp->biosdev)
{
dp++;
}
dp--;
if (dp->name) {
if (dp->name)
{
return sprintf(str, "%s(%d,%d)", dp->name, bvr->biosdev - dp->biosdev, bvr->part_no);
}
}
trunk/i386/libsaio/cpu.c
192192
193193
194194
195
195
196
196197
197198
198199
199200
200201
201202
202
203
204
203205
204206
205207
206
208
209
207210
208211
209212
......
211214
212215
213216
214
217
218
215219
216
220
221
222
217223
218224
219225
......
258264
259265
260266
261
267
268
262269
263270
264
271
272
265273
266274
267
275
276
268277
269278
270
279
280
281
271282
272283
273284
......
601612
602613
603614
615
616
617
618
619
604620
605621
606622
......
745761
746762
747763
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
766782
767783
768784
pollCount = poll_PIT2_gate();
aperfEnd = rdmsr64(MSR_AMD_APERF);
/* The poll loop must have run at least a few times for accuracy */
if (pollCount <= 1) {
if (pollCount <= 1)
{
continue;
}
/* The TSC must increment at LEAST once every millisecond.
* We should have waited exactly 30 msec so the APERF delta should
* be >= 30. Anything less and the processor is way too slow.
*/
if ((aperfEnd - aperfStart) <= CALIBRATE_TIME_MSEC) {
if ((aperfEnd - aperfStart) <= CALIBRATE_TIME_MSEC)
{
continue;
}
// tscDelta = MIN(tscDelta, (tscEnd - tscStart))
if ( (aperfEnd - aperfStart) < aperfDelta ) {
if ( (aperfEnd - aperfStart) < aperfDelta )
{
aperfDelta = aperfEnd - aperfStart;
}
}
* a timespan of 0.03 s (e.g. 30 milliseconds)
*/
if (aperfDelta > (1ULL<<32)) {
if (aperfDelta > (1ULL<<32))
{
retval = 0;
} else {
}
else
{
retval = aperfDelta * 1000 / 30;
}
disable_PIT2();
do_cpuid2(0x00000004, 0, p->CPU.CPUID[CPUID_4]);
do_cpuid(0x80000000, p->CPU.CPUID[CPUID_80]);
if (p->CPU.CPUID[CPUID_0][0] >= 0x5) {
if (p->CPU.CPUID[CPUID_0][0] >= 0x5)
{
do_cpuid(5, p->CPU.CPUID[CPUID_5]);
}
if (p->CPU.CPUID[CPUID_0][0] >= 6) {
if (p->CPU.CPUID[CPUID_0][0] >= 6)
{
do_cpuid(6, p->CPU.CPUID[CPUID_6]);
}
if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 8) {
if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 8)
{
do_cpuid(0x80000008, p->CPU.CPUID[CPUID_88]);
do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]);
} else if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 1) {
}
else if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 1)
{
do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]);
}
maxcoef = currcoef;
}
if (!currcoef)
{
currcoef = maxcoef;
}
if (maxcoef)
{
if (maxdiv)
DBG("\n---------------------------------------------\n");
DBG("------------------ CPU INFO -----------------\n");
DBG("---------------------------------------------\n");
DBG("Brand String: %s\n", p->CPU.BrandString); // Processor name (BIOS)
DBG("Vendor: 0x%x\n", p->CPU.Vendor); // Vendor ex: GenuineIntel
DBG("Family: 0x%x\n", p->CPU.Family); // Family ex: 6 (06h)
DBG("ExtFamily: 0x%x\n", p->CPU.ExtFamily);
DBG("Signature: %x\n", p->CPU.Signature); // CPUID signature
DBG("Model: 0x%x\n", p->CPU.Model); // Model ex: 37 (025h)
DBG("ExtModel: 0x%x\n", p->CPU.ExtModel);
DBG("Stepping: 0x%x\n", p->CPU.Stepping); // Stepping ex: 5 (05h)
DBG("MaxCoef: 0x%x\n", p->CPU.MaxCoef);
DBG("CurrCoef: 0x%x\n", p->CPU.CurrCoef);
DBG("MaxDiv: 0x%x\n", p->CPU.MaxDiv);
DBG("CurrDiv: 0x%x\n", p->CPU.CurrDiv);
DBG("TSCFreq: %dMHz\n", p->CPU.TSCFrequency / 1000000);
DBG("FSBFreq: %dMHz\n", p->CPU.FSBFrequency / 1000000);
DBG("CPUFreq: %dMHz\n", p->CPU.CPUFrequency / 1000000);
DBG("Cores: %d\n", p->CPU.NoCores); // Cores
DBG("Logical processor: %d\n", p->CPU.NoThreads); // Logical procesor
DBG("Features: 0x%08x\n", p->CPU.Features);
DBG("Brand String: %s\n",p->CPU.BrandString); // Processor name (BIOS)
DBG("Vendor: 0x%x\n",p->CPU.Vendor); // Vendor ex: GenuineIntel
DBG("Family: 0x%x\n",p->CPU.Family); // Family ex: 6 (06h)
DBG("ExtFamily: 0x%x\n",p->CPU.ExtFamily);
DBG("Signature: %x\n",p->CPU.Signature); // CPUID signature
DBG("Model: 0x%x\n",p->CPU.Model); // Model ex: 37 (025h)
DBG("ExtModel: 0x%x\n",p->CPU.ExtModel);
DBG("Stepping: 0x%x\n",p->CPU.Stepping); // Stepping ex: 5 (05h)
DBG("MaxCoef: 0x%x\n",p->CPU.MaxCoef);
DBG("CurrCoef: 0x%x\n",p->CPU.CurrCoef);
DBG("MaxDiv: 0x%x\n",p->CPU.MaxDiv);
DBG("CurrDiv: 0x%x\n",p->CPU.CurrDiv);
DBG("TSCFreq: %dMHz\n",p->CPU.TSCFrequency / 1000000);
DBG("FSBFreq: %dMHz\n",p->CPU.FSBFrequency / 1000000);
DBG("CPUFreq: %dMHz\n",p->CPU.CPUFrequency / 1000000);
DBG("Cores: %d\n",p->CPU.NoCores); // Cores
DBG("Logical processor: %d\n",p->CPU.NoThreads); // Logical procesor
DBG("Features: 0x%08x\n",p->CPU.Features);
DBG("\n---------------------------------------------\n");
#if DEBUG_CPU
trunk/i386/libsaio/disk.c
717717
718718
719719
720
720
721
721722
722723
723724
......
733734
734735
735736
736
737
738
737739
738
740
741
742
739743
740744
741745
742746
743
747
748
744749
745750
746751
......
820825
821826
822827
823
824
828
829
825830
826
827
831
832
828833
829
830
831
832
833
834
835
836
837
838
834839
835
840
836841
837
838
839
840
841
842
843
844
845
846
842847
843
844
848
849
845850
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
862867
863868
864869
......
898903
899904
900905
901
902
906
907
903908
904909
905910
......
913918
914919
915920
916
921
917922
918923
919924
......
16501655
16511656
16521657
1653
1658
1659
16541660
16551661
16561662
16571663
16581664
16591665
1660
1666
1667
16611668
16621669
16631670
1664
1671
1672
16651673
16661674
1667
1668
1675
1676
1677
1678
16691679
16701680
1671
1681
1682
1683
16721684
16731685
16741686
......
16911703
16921704
16931705
1706
16941707
16951708
16961709
......
17211734
17221735
17231736
1724
1737
1738
17251739
1726
1740
1741
1742
17271743
1728
1744
1745
1746
17291747
17301748
17311749
......
18731891
18741892
18751893
1876
1894
1895
18771896
18781897
18791898
......
18821901
18831902
18841903
1885
1904
1905
18861906
18871907
18881908
......
18991919
19001920
19011921
1902
1922
1923
19031924
19041925
19051926
19061927
19071928
19081929
1909
1930
1931
19101932
19111933
19121934
1913
1935
1936
19141937
19151938
19161939
int probe, int type, unsigned int bvrFlags )
{
BVRef bvr = (BVRef) malloc( sizeof(*bvr) );
if ( bvr ) {
if ( bvr )
{
bzero(bvr, sizeof(*bvr));
bvr->biosdev = biosdev;
bvr->bv_free = bvFreeFunc;
// FIXME: UCS-2 -> UTF-8 the name
strlcpy(bvr->name, "----", DPISTRLEN);
if ( (efi_guid_compare(&GPT_BOOT_GUID, (EFI_GUID const*)part->ent_type) == 0) || (efi_guid_compare(&GPT_HFS_GUID, (EFI_GUID const*)part->ent_type) == 0) ) {
if ( (efi_guid_compare(&GPT_BOOT_GUID, (EFI_GUID const*)part->ent_type) == 0) || (efi_guid_compare(&GPT_HFS_GUID, (EFI_GUID const*)part->ent_type) == 0) )
{
strlcpy(bvr->type_name, "GPT HFS+", DPISTRLEN);
} else {
}
else
{
strlcpy(bvr->type_name, "GPT Unknown", DPISTRLEN);
}
/*
if ( part->bootid & FDISK_ACTIVE ) {
if ( part->bootid & FDISK_ACTIVE )
{
bvr->flags |= kBVFlagPrimary;
}
*/
spc = 1;
}
do {
// Create a new mapping.
do {
// Create a new mapping.
map = (struct DiskBVMap *) malloc( sizeof(*map) );
if ( map )
map = (struct DiskBVMap *) malloc( sizeof(*map) );
if ( map )
{
map->biosdev = biosdev;
map->bvr = NULL;
map->bvrcnt = 0;
map->next = gDiskBVMap;
gDiskBVMap = map;
map->biosdev = biosdev;
map->bvr = NULL;
map->bvrcnt = 0;
map->next = gDiskBVMap;
gDiskBVMap = map;
// Create a record for each partition found on the disk.
// Create a record for each partition found on the disk.
while ( getNextFDiskPartition( biosdev, &partno, &part ) )
{
DEBUG_DISK(("%s: part %d [%x]\n", __FUNCTION__,
partno, part->systid));
bvr = 0;
while ( getNextFDiskPartition( biosdev, &partno, &part ) )
{
DEBUG_DISK(("%s: part %d [%x]\n", __FUNCTION__,
partno, part->systid));
bvr = 0;
switch ( part->systid )
{
switch ( part->systid )
{
#if UFS_SUPPORT
case FDISK_UFS:
bvr = newFDiskBVRef(
biosdev, partno,
part->relsect + UFS_FRONT_PORCH/BPS,
part,
UFSInitPartition,
UFSLoadFile,
UFSReadFile,
UFSGetDirEntry,
UFSGetFileBlock,
UFSGetUUID,
UFSGetDescription,
UFSFree,
0,
kBIOSDevTypeHardDrive, 0);
break;
case FDISK_UFS:
bvr = newFDiskBVRef(
biosdev, partno,
part->relsect + UFS_FRONT_PORCH/BPS,
part,
UFSInitPartition,
UFSLoadFile,
UFSReadFile,
UFSGetDirEntry,
UFSGetFileBlock,
UFSGetUUID,
UFSGetDescription,
UFSFree,
0,
kBIOSDevTypeHardDrive, 0);
break;
#endif
case FDISK_HFS:
break;
#if UFS_SUPPORT
case FDISK_BOOTER:
booterUFS = newFDiskBVRef(
case FDISK_BOOTER:
booterUFS = newFDiskBVRef(
biosdev, partno,
((part->relsect + spc - 1) / spc) * spc,
part,
UFSFree,
0,
kBIOSDevTypeHardDrive, 0);
break;
break;
#endif
case FDISK_FAT32:
long flags, time;
int fh, fileSize, error;
for (bvr = chain; bvr; bvr = bvr->next) {
for (bvr = chain; bvr; bvr = bvr->next)
{
ret = -1;
error = 0;
//
// Check for alternate volume label on boot helper partitions.
//
if (bvr->flags & kBVFlagBooter) {
if (bvr->flags & kBVFlagBooter)
{
sprintf(dirSpec, "hd(%d,%d)/System/Library/CoreServices/", BIOS_DEV_UNIT(bvr), bvr->part_no);
strcpy(fileSpec, ".disk_label.contentDetails");
ret = GetFileInfo(dirSpec, fileSpec, &flags, &time);
if (!ret) {
if (!ret)
{
fh = open(strcat(dirSpec, fileSpec), 0);
fileSize = file_size(fh);
if (fileSize > 0 && fileSize < BVSTRLEN) {
if (read(fh, label, fileSize) != fileSize) {
if (fileSize > 0 && fileSize < BVSTRLEN)
{
if (read(fh, label, fileSize) != fileSize)
{
error = -1;
}
} else {
}
else
{
error = -1;
}
bvr->flags |= kBVFlagSystemVolume;
}
}
}
}
verbose("Resetting BIOS device %xh\n", biosdev);
// Reset the biosbuf cache
cache_valid = false;
if(map == gDiskBVMap) {
if(map == gDiskBVMap)
{
gDiskBVMap = map->next;
} else if(prevMap != NULL) {
}
else if(prevMap != NULL)
{
prevMap->next = map->next;
} else {
}
else
{
stop("");
}
}
if ( (!allowFlags || newBVR->flags & allowFlags)
&& (!denyFlags || !(newBVR->flags & denyFlags) )
&& (newBVR->biosdev >= minBIOSDev && newBVR->biosdev <= maxBIOSDev)
) {
)
{
newBVR->visible = true;
}
* to be able to hide foreign partitions from the boot menu.
*
*/
if ( (newBVR->flags & kBVFlagForeignBoot) ) {
if ( (newBVR->flags & kBVFlagForeignBoot) )
{
char *start, *next = val;
long len = 0;
do
/*
* Use the first bvr entry as the starting chain pointer.
*/
if (!chain) {
if (!chain)
{
chain = newBVR;
}
/*
* Update the previous bvr's link pointer to use the new memory area.
*/
if (prevBVR) {
if (prevBVR)
{
prevBVR->next = newBVR;
}
if (newBVR->visible) {
if (newBVR->visible)
{
bvCount++;
}
}
trunk/i386/libsaio/smbios.c
652652
653653
654654
655
655
656
657
656658
657659
658660
......
661663
662664
663665
664
666
667
668
665669
666670
667671
defaultBaseBoard.product = kDefaultMacBookProBoardProduct;
defaultBaseBoard.boardType = kSMBBaseBoardMotherboard;
defaultChassis.chassisType = kSMBchassisUnknown;
} else {
}
else
{
defaultSystemInfo.productName = kDefaultMacBook;
defaultBIOSInfo.version = kDefaultMacBookBIOSVersion;
defaultBIOSInfo.releaseDate = kDefaultMacBookBIOSReleaseDate;
defaultBaseBoard.boardType = kSMBBaseBoardMotherboard;
defaultChassis.chassisType = kSMBchassisUnknown;
}
} else {
}
else
{
switch (Platform.CPU.NoCores)
{
case 1:
trunk/i386/libsaio/smbios_decode.c
471471
472472
473473
474
474
475
475476
476
477
478
479
477480
478481
479482
480483
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
496501
497
498
499
502
503
504
505
506
500507
501508
502509
503
510
511
504512
505
513
514
515
506516
507517
508518
......
651661
652662
653663
654
664
665
655666
656667
657668
printHeader(structHeader);
DBG("Memory Device\n");
// Aray Handle
if (((SMBMemoryDevice *)structHeader)->errorHandle == 0xFFFF) {
if (((SMBMemoryDevice *)structHeader)->errorHandle == 0xFFFF)
{
DBG("\tError Information Handle: No Error\n");
} else {
}
else
{
DBG("\tError Information Handle: 0x%x\n", ((SMBMemoryDevice *)structHeader)->errorHandle);
}
// Total Width:
// Data Width:
switch (((SMBMemoryDevice *)structHeader)->memorySize) {
case 0:
DBG("\tSize: No Module Installed\n");
break;
case 0x7FFF:
DBG("\tSize: 32GB or more\n");
break;
case 0xFFFF:
DBG("\tSize: Unknown\n");
break;
default:
DBG("\tSize: %d %s\n", ((SMBMemoryDevice *)structHeader)->memorySize & 0x7FFF, ((((SMBMemoryDevice *)structHeader)->memorySize & 0x8000) == 0x8000) ? "kB" : "MB");
break;
}
if ((((SMBMemoryDevice *)structHeader)->formFactor < 0x01) || (((SMBMemoryDevice *)structHeader)->formFactor > 0x0F)) {
switch (((SMBMemoryDevice *)structHeader)->memorySize)
{
case 0:
DBG("\tSize: No Module Installed\n");
break;
case 0x7FFF:
DBG("\tSize: 32GB or more\n");
break;
case 0xFFFF:
DBG("\tSize: Unknown\n");
break;
default:
DBG("\tSize: %d %s\n", ((SMBMemoryDevice *)structHeader)->memorySize & 0x7FFF, ((((SMBMemoryDevice *)structHeader)->memorySize & 0x8000) == 0x8000) ? "kB" : "MB");
break;
}
if ((((SMBMemoryDevice *)structHeader)->formFactor < 0x01) || (((SMBMemoryDevice *)structHeader)->formFactor > 0x0F))
{
DBG("\tForm Factor: %s\n", OutOfSpecStr);
} else {
DBG("\tForm Factor: %s\n", SMBMemoryDeviceFormFactors[((SMBMemoryDevice *)structHeader)->formFactor - 1]);
}
}
else
{
DBG("\tForm Factor: %s\n", SMBMemoryDeviceFormFactors[((SMBMemoryDevice *)structHeader)->formFactor - 1]);
}
// Set:
DBG("\tLocator: %s\n", SMBStringForField(structHeader, ((SMBMemoryDevice *)structHeader)->deviceLocator, neverMask));
DBG("\tBank Locator: %s\n", SMBStringForField(structHeader, ((SMBMemoryDevice *)structHeader)->bankLocator, neverMask));
if (((SMBMemoryDevice *)structHeader)->memoryType > kSMBMemoryDeviceTypeCount) {
if (((SMBMemoryDevice *)structHeader)->memoryType > kSMBMemoryDeviceTypeCount)
{
DBG("\tMemory Type: %s\n", OutOfSpecStr);
} else {
}
else
{
DBG("\tMemory Type: %s\n", SMBMemoryDeviceTypes[((SMBMemoryDevice *)structHeader)->memoryType]);
}
// Type Detail:
ptr = (uint8_t *)((uint32_t)structHeader + structHeader->length);
for (; ((uint16_t *)ptr)[0] != 0; ptr++);
if (((uint16_t *)ptr)[0] == 0) {
if (((uint16_t *)ptr)[0] == 0)
{
ptr += 2;
}
trunk/i386/libsaio/convert.c
1010
1111
1212
13
14
15
16
13
14
15
16
1717
1818
1919
2020
21
21
2222
2323
2424
2525
2626
27
27
2828
2929
3030
......
3232
3333
3434
35
36
35
36
37
38
3739
3840
3941
4042
4143
4244
43
45
46
4447
4548
4649
4750
4851
49
52
53
5054
5155
5256
......
5963
6064
6165
62
63
66
67
6468
6569
6670
6771
6872
6973
70
74
7175
7276
7377
......
7579
7680
7781
78
79
80
81
82
83
82
83
84
85
86
87
8488
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
106124
107
108
109
125
126
127
128
110129
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
130138
131139
132140
/** Transform a 16 bytes hexadecimal value UUID to a string */
const char * getStringFromUUID(const EFI_CHAR8* eUUID)
{
static char msg[UUID_LEN*2 + 8] = "";
if (!eUUID) return "";
const unsigned char * uuid = (unsigned char*) eUUID;
sprintf(msg, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
static char msg[UUID_LEN*2 + 8] = "";
if (!eUUID) return "";
const unsigned char * uuid = (unsigned char*) eUUID;
sprintf(msg, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
uuid[0], uuid[1], uuid[2], uuid[3],
uuid[4], uuid[5], uuid[6], uuid[7],
uuid[8], uuid[9], uuid[10],uuid[11],
uuid[12],uuid[13],uuid[14],uuid[15]);
return msg ;
return msg ;
}
/** Parse an UUID string into an (EFI_CHAR8*) buffer */
EFI_CHAR8* getUUIDFromString(const char *source)
{
if (!source) return 0;
if (!source) return 0;
char*p = (char *)source;
inti;
static EFI_CHAR8 uuid[UUID_LEN+1]="";
buf[2] = '\0';
for (i=0; i<UUID_LEN; i++) {
if (p[0] == '\0' || p[1] == '\0' || !isxdigit(p[0]) || !isxdigit(p[1])) {
for (i=0; i<UUID_LEN; i++)
{
if (p[0] == '\0' || p[1] == '\0' || !isxdigit(p[0]) || !isxdigit(p[1]))
{
verbose("[ERROR] UUID='%s' syntax error\n", source);
return 0;
}
buf[0] = *p++;
buf[1] = *p++;
uuid[i] = (unsigned char) strtoul(buf, NULL, 16);
if (*p == '-' && (i % 2) == 1 && i < UUID_LEN - 1) {
if (*p == '-' && (i % 2) == 1 && i < UUID_LEN - 1)
{
p++;
}
}
uuid[UUID_LEN]='\0';
if (*p != '\0') {
if (*p != '\0')
{
verbose("[ERROR] UUID='%s' syntax error\n", source);
return 0;
}
uint32_tvalue = 0, i, digit;
for(i = 0; i < strlen(buff); i++)
{
if (buff[i] >= 48 && buff[i] <= 57)// '0' through '9'
digit = buff[i] - 48;
if (buff[i] >= 48 && buff[i] <= 57)// '0' through '9'
digit = buff[i] - 48;
else if (buff[i] >= 65 && buff[i] <= 70)// 'A' through 'F'
digit = buff[i] - 55;
else if (buff[i] >= 97 && buff[i] <= 102)// 'a' through 'f'
digit = buff[i] - 87;
else
return value;
value = digit + 16 * value;
}
returnvalue;
void *convertHexStr2Binary(const char *hexStr, int *outLength)
{
int len;
char hexNibble;
char hexByte[2];
uint8_t binChar;
uint8_t *binStr;
int hexStrIdx, binStrIdx, hexNibbleIdx;
int len;
char hexNibble;
char hexByte[2];
uint8_t binChar;
uint8_t *binStr;
int hexStrIdx, binStrIdx, hexNibbleIdx;
len = strlen(hexStr);
if (len > 1)
{
// the resulting binary will be the half size of the input hex string
binStr = malloc(len / 2);
binStrIdx = 0;
hexNibbleIdx = 0;
for (hexStrIdx = 0; hexStrIdx < len; hexStrIdx++)
{
hexNibble = hexStr[hexStrIdx];
// ignore all chars except valid hex numbers
if ( (hexNibble >= '0' && hexNibble <= '9') ||
(hexNibble >= 'A' && hexNibble <= 'F') ||
(hexNibble >= 'a' && hexNibble <= 'f') ) {
hexByte[hexNibbleIdx++] = hexNibble;
// found both two nibbles, convert to binary
if (hexNibbleIdx == 2)
{
binChar = 0;
len = strlen(hexStr);
if (len > 1)
{
// the resulting binary will be the half size of the input hex string
binStr = malloc(len / 2);
binStrIdx = 0;
hexNibbleIdx = 0;
for (hexStrIdx = 0; hexStrIdx < len; hexStrIdx++)
{
hexNibble = hexStr[hexStrIdx];
// ignore all chars except valid hex numbers
if ( (hexNibble >= '0' && hexNibble <= '9') ||
(hexNibble >= 'A' && hexNibble <= 'F') ||
(hexNibble >= 'a' && hexNibble <= 'f') )
{
hexByte[hexNibbleIdx++] = hexNibble;
// found both two nibbles, convert to binary
if (hexNibbleIdx == 2)
{
binChar = 0;
for (hexNibbleIdx = 0; hexNibbleIdx < sizeof(hexByte); hexNibbleIdx++)
{
if (hexNibbleIdx > 0)
{
binChar = binChar << 4;
}
if (hexByte[hexNibbleIdx] <= '9') binChar += hexByte[hexNibbleIdx] - '0';
else if (hexByte[hexNibbleIdx] <= 'F') binChar += hexByte[hexNibbleIdx] - ('A' - 10);
else if (hexByte[hexNibbleIdx] <= 'f') binChar += hexByte[hexNibbleIdx] - ('a' - 10);
}
for (hexNibbleIdx = 0; hexNibbleIdx < sizeof(hexByte); hexNibbleIdx++) {
if (hexNibbleIdx > 0) {
binChar = binChar << 4;
binStr[binStrIdx++] = binChar;
hexNibbleIdx = 0;
}
}
}
if (hexByte[hexNibbleIdx] <= '9') binChar += hexByte[hexNibbleIdx] - '0';
else if (hexByte[hexNibbleIdx] <= 'F') binChar += hexByte[hexNibbleIdx] - ('A' - 10);
else if (hexByte[hexNibbleIdx] <= 'f') binChar += hexByte[hexNibbleIdx] - ('a' - 10);
}
binStr[binStrIdx++] = binChar;
hexNibbleIdx = 0;
}
}
}
*outLength = binStrIdx;
return binStr;
}
else
{
*outLength = 0;
return NULL;
}
*outLength = binStrIdx;
return binStr;
}
else
{
*outLength = 0;
return NULL;
}
}
// FIXME: can't use my original code here,
trunk/i386/libsaio/msdos.c
7171
7272
7373
74
75
76
77
78
79
80
81
82
83
7484
7585
7686
7787
78
79
88
89
90
8091
8192
8293
83
84
85
86
87
88
94
95
96
97
98
99
100
101
102
89103
90104
91105
......
167181
168182
169183
170
171
172
173
184
185
186
187
174188
175189
176190
......
188202
189203
190204
191
205
206
207
192208
193209
194210
......
201217
202218
203219
204
220
221
205222
223
206224
225
207226
227
208228
229
209230
210231
211232
......
325346
326347
327348
328
329
330
331
332
333
334
335
336
337
338349
339350
340351
......
427438
428439
429440
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
558569
559570
560571
......
780791
781792
782793
783
794
795
784796
785797
786798
......
794806
795807
796808
797
809
810
798811
799812
800813
......
816829
817830
818831
819
820
832
821833
822834
823835
......
836848
837849
838850
839
851
852
840853
841854
842855
......
931944
932945
933946
934
947
948
935949
936950
937951
......
963977
964978
965979
966
980
981
982
967983
968984
969985
......
981997
982998
983999
984
1000
1001
9851002
9861003
9871004
988
1005
9891006
9901007
9911008
static int msdosrootcluster = 0;
static int msdosfatbits = 0;
struct msdosdirstate
{
struct direntry *buf;
uint8_t vfatchecksum;
int root16;
off_t cluster;
int nument;
int vfatnumber;
};
#if UNUSED
/*
* Check a volume label.
*/
static int
oklabel(const char *src)
static int oklabel(const char *src);
static int oklabel(const char *src)
{
int c, i;
for (i = 0, c = 0; i <= 11; i++) {
c = (u_char)*src++;
if (c < ' ' + !i || strchr("\"*+,./:;<=>?[\\]|", c))
break;
}
return i && !c;
for (i = 0, c = 0; i <= 11; i++)
{
c = (u_char)*src++;
if (c < ' ' + !i || strchr("\"*+,./:;<=>?[\\]|", c))
{
break;
}
}
return i && !c;
}
#endif /* UNUSED */
Seek(ih, 0);
Read(ih, (long)buf, 512);
bsp = (union bootsector *)buf;
b33 = (struct bpb33 *)bsp->bs33.bsBPB;
b50 = (struct bpb50 *)bsp->bs50.bsBPB;
b710 = (struct bpb710 *)bsp->bs710.bsBPB;
bsp = (union bootsector *)buf;
b33 = (struct bpb33 *)bsp->bs33.bsBPB;
b50 = (struct bpb50 *)bsp->bs50.bsBPB;
b710 = (struct bpb710 *)bsp->bs710.bsBPB;
/* We only work with 512, 1024, and 2048 byte sectors */
free (buf);
return -1;
}
if (OSSwapLittleToHostInt16(b50->bpbRootDirEnts) == 0) { /* It's FAT32 */
if (OSSwapLittleToHostInt16(b50->bpbRootDirEnts) == 0)
{
/* It's FAT32 */
if (memcmp(((struct extboot *)bsp->bs710.bsExt)->exFileSysType, "FAT32 ", 8))
{
free (buf);
msdosrootDirSectors = 0;
msdosfatbits = 32;
}
else if (((struct extboot *)bsp->bs50.bsExt)->exBootSignature == EXBOOTSIG) {
else if (((struct extboot *)bsp->bs50.bsExt)->exBootSignature == EXBOOTSIG)
{
if (!memcmp((char *)((struct extboot *)bsp->bs50.bsExt)->exFileSysType, "FAT16 ", 8))
{
msdosfatbits = 16;
}
else if (!memcmp((char *)((struct extboot *)bsp->bs50.bsExt)->exFileSysType, "FAT12 ", 8))
{
msdosfatbits = 12;
}
else
{
free (buf);
}
}
struct msdosdirstate
{
struct direntry *buf;
uint8_t vfatchecksum;
int root16;
off_t cluster;
int nument;
int vfatnumber;
};
static struct direntry *
getnextdirent (CICell ih, uint16_t *longname, struct msdosdirstate *st)
{
/* First comes lowercase, then uppercase*/
static uint16_t cp850[128][2]=
{
{0x00E7,0x00C7},
{0x00FC,0x00DC},
{0x00E9,0x00C9},
{0x00E2,0x00C2},
{0x00E4,0x00C4},
{0x00E0,0x00C0},
{0x00E5,0x00C5},
{0x00E7,0x00C7},
{0x00EA,0x00CA},
{0x00EB,0x00CB},
{0x00E8,0x00C8},
{0x00EF,0x00CF},
{0x00EE,0x00CE},
{0x00EC,0x00CC},
{0x00E4,0x00C4},
{0x00E5,0x00C5},
{0x00E9,0x00C9},
{0x00E6,0x00C6},
{0x00E6,0x00C6},
{0x00F4,0x00D4},
{0x00F6,0x00D6},
{0x00F2,0x00D2},
{0x00FB,0x00DB},
{0x00F9,0x00D9},
{0x00FF,0x0178},
{0x00F6,0x00D6},
{0x00FC,0x00DC},
{0x00F8,0x00D8},
{0x00A3,0x00A3},
{0x00F8,0x00D8},
{0x00D7,0x00D7},
{0x0192,0x0191},
{0x00E1,0x00C1},
{0x00ED,0x00CD},
{0x00F3,0x00D3},
{0x00FA,0x00DA},
{0x00F1,0x00D1},
{0x00F1,0x00D1},
{0x00AA,0x00AA},
{0x00BA,0x00BA},
{0x00BF,0x00BF},
{0x00AE,0x00AE},
{0x00AC,0x00AC},
{0x00BD,0x00BD},
{0x00BC,0x00BC},
{0x00A1,0x00A1},
{0x00AB,0x00AB},
{0x00BB,0x00BB},
{0x2591,0x2591},
{0x2592,0x2592},
{0x2593,0x2593},
{0x2502,0x2502},
{0x2524,0x2524},
{0x00E1,0x00C1},
{0x00E2,0x00C2},
{0x00E0,0x00C0},
{0x00A9,0x00A9},
{0x2563,0x2563},
{0x2551,0x2551},
{0x2557,0x2557},
{0x255D,0x255D},
{0x00A2,0x00A2},
{0x00A5,0x00A5},
{0x2510,0x2510},
{0x2514,0x2514},
{0x2534,0x2534},
{0x252C,0x252C},
{0x251C,0x251C},
{0x2500,0x2500},
{0x253C,0x253C},
{0x00E3,0x00C3},
{0x00E3,0x00C3},
{0x255A,0x255A},
{0x2554,0x2554},
{0x2569,0x2569},
{0x2566,0x2566},
{0x2560,0x2560},
{0x2550,0x2550},
{0x256C,0x256C},
{0x00A4,0x00A4},
{0x00F0,0x00D0},
{0x00F0,0x00D0},
{0x00EA,0x00CA},
{0x00EB,0x00CB},
{0x00E8,0x00C8},
{0x0131,0x0049},
{0x00ED,0x00CD},
{0x00EE,0x00CE},
{0x00EF,0x00CF},
{0x2518,0x2518},
{0x250C,0x250C},
{0x2588,0x2588},
{0x2584,0x2584},
{0x00A6,0x00A6},
{0x00EC,0x00CC},
{0x2580,0x2580},
{0x00F3,0x00D3},
{0x00DF,0x00DF},
{0x00F4,0x00D4},
{0x00F2,0x00D2},
{0x00F5,0x00D5},
{0x00F5,0x00D5},
{0x00B5,0x00B5},
{0x00FE,0x00DE},
{0x00FE,0x00DE},
{0x00FA,0x00DA},
{0x00FB,0x00DB},
{0x00F9,0x00D9},
{0x00FD,0x00DD},
{0x00FD,0x00DD},
{0x00AF,0x00AF},
{0x00B4,0x00B4},
{0x00AD,0x00AD},
{0x00B1,0x00B1},
{0x2017,0x2017},
{0x00BE,0x00BE},
{0x00B6,0x00B6},
{0x00A7,0x00A7},
{0x00F7,0x00F7},
{0x00B8,0x00B8},
{0x00B0,0x00B0},
{0x00A8,0x00A8},
{0x00B7,0x00B7},
{0x00B9,0x00B9},
{0x00B3,0x00B3},
{0x00B2,0x00B2},
{0x25A0,0x25A0},
{0x00A0,0x00A0}
{0x00E7,0x00C7},
{0x00FC,0x00DC},
{0x00E9,0x00C9},
{0x00E2,0x00C2},
{0x00E4,0x00C4},
{0x00E0,0x00C0},
{0x00E5,0x00C5},
{0x00E7,0x00C7},
{0x00EA,0x00CA},
{0x00EB,0x00CB},
{0x00E8,0x00C8},
{0x00EF,0x00CF},
{0x00EE,0x00CE},
{0x00EC,0x00CC},
{0x00E4,0x00C4},
{0x00E5,0x00C5},
{0x00E9,0x00C9},
{0x00E6,0x00C6},
{0x00E6,0x00C6},
{0x00F4,0x00D4},
{0x00F6,0x00D6},
{0x00F2,0x00D2},
{0x00FB,0x00DB},
{0x00F9,0x00D9},
{0x00FF,0x0178},
{0x00F6,0x00D6},
{0x00FC,0x00DC},
{0x00F8,0x00D8},
{0x00A3,0x00A3},
{0x00F8,0x00D8},
{0x00D7,0x00D7},
{0x0192,0x0191},
{0x00E1,0x00C1},
{0x00ED,0x00CD},
{0x00F3,0x00D3},
{0x00FA,0x00DA},
{0x00F1,0x00D1},
{0x00F1,0x00D1},
{0x00AA,0x00AA},
{0x00BA,0x00BA},
{0x00BF,0x00BF},
{0x00AE,0x00AE},
{0x00AC,0x00AC},
{0x00BD,0x00BD},
{0x00BC,0x00BC},
{0x00A1,0x00A1},
{0x00AB,0x00AB},
{0x00BB,0x00BB},
{0x2591,0x2591},
{0x2592,0x2592},
{0x2593,0x2593},
{0x2502,0x2502},
{0x2524,0x2524},
{0x00E1,0x00C1},
{0x00E2,0x00C2},
{0x00E0,0x00C0},
{0x00A9,0x00A9},
{0x2563,0x2563},
{0x2551,0x2551},
{0x2557,0x2557},
{0x255D,0x255D},
{0x00A2,0x00A2},
{0x00A5,0x00A5},
{0x2510,0x2510},
{0x2514,0x2514},
{0x2534,0x2534},
{0x252C,0x252C},
{0x251C,0x251C},
{0x2500,0x2500},
{0x253C,0x253C},
{0x00E3,0x00C3},
{0x00E3,0x00C3},
{0x255A,0x255A},
{0x2554,0x2554},
{0x2569,0x2569},
{0x2566,0x2566},
{0x2560,0x2560},
{0x2550,0x2550},
{0x256C,0x256C},
{0x00A4,0x00A4},
{0x00F0,0x00D0},
{0x00F0,0x00D0},
{0x00EA,0x00CA},
{0x00EB,0x00CB},
{0x00E8,0x00C8},
{0x0131,0x0049},
{0x00ED,0x00CD},
{0x00EE,0x00CE},
{0x00EF,0x00CF},
{0x2518,0x2518},
{0x250C,0x250C},
{0x2588,0x2588},
{0x2584,0x2584},
{0x00A6,0x00A6},
{0x00EC,0x00CC},
{0x2580,0x2580},
{0x00F3,0x00D3},
{0x00DF,0x00DF},
{0x00F4,0x00D4},
{0x00F2,0x00D2},
{0x00F5,0x00D5},
{0x00F5,0x00D5},
{0x00B5,0x00B5},
{0x00FE,0x00DE},
{0x00FE,0x00DE},
{0x00FA,0x00DA},
{0x00FB,0x00DB},
{0x00F9,0x00D9},
{0x00FD,0x00DD},
{0x00FD,0x00DD},
{0x00AF,0x00AF},
{0x00B4,0x00B4},
{0x00AD,0x00AD},
{0x00B1,0x00B1},
{0x2017,0x2017},
{0x00BE,0x00BE},
{0x00B6,0x00B6},
{0x00A7,0x00A7},
{0x00F7,0x00F7},
{0x00B8,0x00B8},
{0x00B0,0x00B0},
{0x00A8,0x00A8},
{0x00B7,0x00B7},
{0x00B9,0x00B9},
{0x00B3,0x00B3},
{0x00B2,0x00B2},
{0x25A0,0x25A0},
{0x00A0,0x00A0}
};
static int
if (filePath[0] == '/')
filePath++;
buf = malloc(msdosclustersize);
if (!buf) {
if (!buf)
{
return -1;
}
dirp = getdirpfrompath (ih, filePath, buf);
if (msdosfatbits == 32)
cluster |= ((uint32_t)OSReadLittleInt16 ((dirp->deHighClust),0)) <<16;
size = (uint32_t)OSReadLittleInt32 ((dirp->deFileSize),0);
if (size<=offset) {
if (size<=offset)
{
free (buf);
return -1;
}
}
getDeviceDescription(ih, devStr);
verbose("Read FAT%d file: [%s/%s] %d bytes.\n",
msdosfatbits, devStr, filePath, (uint32_t)( toread<0 ) ? wastoread : wastoread-toread);
verbose("Read FAT%d file: [%s/%s] %d bytes.\n", msdosfatbits, devStr, filePath, (uint32_t)( toread<0 ) ? wastoread : wastoread-toread);
free (buf);
if (toread<0)
return wastoread;
if (filePath[0] == '/')
filePath++;
buf = malloc(msdosclustersize);
if (!buf) {
if (!buf)
{
return -1;
}
dirp = getdirpfrompath (ih, filePath, buf);
initRoot (&st);
st.buf = malloc(msdosclustersize);
if (!st.buf) {
if (!st.buf)
{
return;
}
while ((dirp = getnextdirent (ih, vfatlabel, &st)))
union bootsector *bsp = (union bootsector *)buf;
Seek(ih, 0);
Read(ih, (long)buf, 512);
if (msdosfatbits == 32) { /* It's FAT32 */
if (msdosfatbits == 32)
{
/* It's FAT32 */
strncpy((char *)label, (char *)((struct extboot *)bsp->bs710.bsExt)->exVolumeLabel, LABEL_LENGTH);
}
else if (msdosfatbits == 16)
MSDOSGetUUID(CICell ih, char *uuidStr)
{
char *buf = malloc (512);
if (!buf) {
if (!buf)
{
return -1;
}
union bootsector *bsp = (union bootsector *)buf;
if (MSDOSInitPartition (ih)<0)
{
free (buf);
trunk/i386/libsaio/fake_efi.c
717717
718718
719719
720
721720
722721
723722
......
772771
773772
774773
774
775775
776776
777777
DT__AddProperty(chosenNode, "machine-signature", sizeof(EFI_UINT32), (EFI_UINT32 *)&MachineSig);
if(YOSEMITE)
{
//
}
cpuTick = getCPUTick();// callq0x121a7
//printf("value: 0x%llx\n", getCPUTick());
rcx = (cpuTick >> 8);// mov%rax,%rcx
// shr$0x8,%rcx
rdx = (cpuTick >> 10);// mov%rax,%rdx
trunk/i386/libsaio/smbios_getters.c
2121
2222
2323
24
25
24
25
26
27
2628
2729
2830
......
4951
5052
5153
52
54
55
56
5357
5458
5559
......
7074
7175
7276
73
77
78
7479
7580
7681
......
101106
102107
103108
104
109
110
105111
106112
107113
108114
109115
110
116
117
111118
112119
113120
......
118125
119126
120127
121
128
129
122130
123131
124132
......
138146
139147
140148
141
149
150
142151
143
152
153
154
144155
145156
146157
......
153164
154165
155166
156
157
167
168
169
170
158171
159172
160173
161174
162
175
176
163177
164178
165179
166
180
181
167182
168183
169184
170185
171
186
187
172188
173189
174190
......
182198
183199
184200
185
201
202
186203
187204
188205
189
206
207
190208
191209
192210
......
345363
346364
347365
348
366
367
349368
350369
351370
352371
353
372
373
354374
355
375
376
356377
357378
358379
......
406427
407428
408429
409
430
431
410432
411
433
434
412435
413436
414437
......
432455
433456
434457
435
458
459
436460
437
461
462
438463
439464
440465
......
455480
456481
457482
458
483
484
459485
460
486
487
461488
462489
463490
......
482509
483510
484511
485
512
513
486514
487515
488516
489
517
518
490519
491520
492521
bool getProcessorInformationExternalClock(returnType *value)
{
if (Platform.CPU.Vendor == CPUID_VENDOR_INTEL) { // Intel
switch (Platform.CPU.Family) {
if (Platform.CPU.Vendor == CPUID_VENDOR_INTEL) // Intel
{
switch (Platform.CPU.Family)
{
case 0x06:
{
switch (Platform.CPU.Model)
default:
value->word = (uint16_t)(Platform.CPU.FSBFrequency/1000000LL);
}
} else {
}
else
{
value->word = (uint16_t)(Platform.CPU.FSBFrequency/1000000LL);
}
{
case 0x06:
{
switch (Platform.CPU.Model) {
switch (Platform.CPU.Model)
{
case CPU_MODEL_PENTIUM_M:
case CPU_MODEL_DOTHAN:// Intel Pentium M
case CPU_MODEL_YONAH:// Intel Mobile Core Solo, Duo
// Nehalem supports Scrubbing
// First, locate the PCI bus where the MCH is located
for(i = 0; i < (sizeof(possible_nhm_bus)/sizeof(possible_nhm_bus[0])); i++) {
for(i = 0; i < (sizeof(possible_nhm_bus)/sizeof(possible_nhm_bus[0])); i++)
{
vid = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x00);
did = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x02);
vid &= 0xFFFF;
did &= 0xFF00;
if(vid == 0x8086 && did >= 0x2C00) {
if(vid == 0x8086 && did >= 0x2C00)
{
nhm_bus = possible_nhm_bus[i];
}
}
DBG("qpimult %d\n", qpimult);
qpibusspeed = (qpimult * 2 * (Platform.CPU.FSBFrequency/1000000LL));
// Rek: rounding decimals to match original mac profile info
if (qpibusspeed%100 != 0) {
if (qpibusspeed%100 != 0)
{
qpibusspeed = ((qpibusspeed+50)/100)*100;
}
DBG("qpibusspeed %d\n", qpibusspeed);
uint16_t simpleGetSMBOemProcessorType(void)
{
if (Platform.CPU.NoCores >= 4) {
if (Platform.CPU.NoCores >= 4)
{
return 0x501;// 1281 - Quad-Core Xeon
} else if (Platform.CPU.NoCores == 1) {
}
else if (Platform.CPU.NoCores == 1)
{
return 0x201;// 513 - Core Duo
};
value->word = simpleGetSMBOemProcessorType();
if (Platform.CPU.Vendor == CPUID_VENDOR_INTEL) { // Intel
if (!done) {
if (Platform.CPU.Vendor == CPUID_VENDOR_INTEL) // Intel
{
if (!done)
{
verbose("CPU is %s, family 0x%x, model 0x%x\n", Platform.CPU.BrandString, (uint32_t)Platform.CPU.Family, (uint32_t)Platform.CPU.Model);
done = true;
}
// Bungo: fixes Oem Processor Type - better matching IMHO, needs testing
switch (Platform.CPU.Family) {
switch (Platform.CPU.Family)
{
case 0x0F:
case 0x06:
{
switch (Platform.CPU.Model) {
switch (Platform.CPU.Model)
{
case CPU_MODEL_PENTIUM_M:
case CPU_MODEL_DOTHAN:// 0x0D - Intel Pentium M model D
case CPU_MODEL_PRESCOTT:
case CPU_MODEL_NOCONA:
if (strstr(Platform.CPU.BrandString, "Xeon")) {
if (strstr(Platform.CPU.BrandString, "Xeon"))
{
value->word = 0x402;// 1026 - Xeon
}
return true;
case CPU_MODEL_MEROM:// 0x0F - Intel Mobile Core 2 Solo, Duo, Xeon 30xx, Xeon 51xx, Xeon X53xx, Xeon E53xx, Xeon X32xx
case CPU_MODEL_XEON_MP:// 0x1D - Six-Core Xeon 7400, "Dunnington", 45nm
case CPU_MODEL_PENRYN:// 0x17 - Intel Core 2 Solo, Duo, Quad, Extreme, Xeon X54xx, Xeon X33xx
if (strstr(Platform.CPU.BrandString, "Xeon")) {
if (strstr(Platform.CPU.BrandString, "Xeon"))
{
value->word = 0x402;// 1026 - Xeon
return true;
}
if (Platform.CPU.NoCores <= 2) {
if (Platform.CPU.NoCores <= 2)
{
value->word = 0x301;// 769 - Core 2 Duo
} else {
value->word = 0x402;// 1026 - Core 2 Quad as Xeon
static int idx = -1;
intmap;
if (!bootInfo->memDetect) {
if (!bootInfo->memDetect)
{
return false;
}
idx++;
if (idx < MAX_RAM_SLOTS) {
if (idx < MAX_RAM_SLOTS)
{
map = Platform.DMI.DIMM[idx];
if (Platform.RAM.DIMM[map].InUse && Platform.RAM.DIMM[map].Type != 0) {
if (Platform.RAM.DIMM[map].InUse && Platform.RAM.DIMM[map].Type != 0)
{
DBG("RAM Detected Type = %d\n", Platform.RAM.DIMM[map].Type);
value->byte = Platform.RAM.DIMM[map].Type;
return true;
}
idx++;
if (idx < MAX_RAM_SLOTS) {
if (idx < MAX_RAM_SLOTS)
{
map = Platform.DMI.DIMM[idx];
if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].Vendor) > 0) {
if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].Vendor) > 0)
{
DBG("RAM Detected Vendor[%d]='%s'\n", idx, Platform.RAM.DIMM[map].Vendor);
value->string = Platform.RAM.DIMM[map].Vendor;
return true;
//DBG("getSMBMemoryDeviceSerialNumber index: %d, MAX_RAM_SLOTS: %d\n",idx,MAX_RAM_SLOTS);
if (idx < MAX_RAM_SLOTS) {
if (idx < MAX_RAM_SLOTS)
{
map = Platform.DMI.DIMM[idx];
if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].SerialNo) > 0) {
if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].SerialNo) > 0)
{
DBG("map=%d, RAM Detected SerialNo[%d]='%s'\n", map, idx, Platform.RAM.DIMM[map].SerialNo);
value->string = Platform.RAM.DIMM[map].SerialNo;
return true;
}
idx++;
if (idx < MAX_RAM_SLOTS) {
if (idx < MAX_RAM_SLOTS)
{
map = Platform.DMI.DIMM[idx];
if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].PartNo) > 0) {
if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].PartNo) > 0)
{
DBG("map=%d, RAM Detected PartNo[%d]='%s'\n", map, idx, Platform.RAM.DIMM[map].PartNo);
value->string = Platform.RAM.DIMM[map].PartNo;
return true;
* for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").
*/
smbios = (SMBEntryPoint*)SMBIOS_RANGE_START;
while (smbios <= (SMBEntryPoint *)SMBIOS_RANGE_END) {
while (smbios <= (SMBEntryPoint *)SMBIOS_RANGE_END)
{
if (COMPARE_DWORD(smbios->anchor, SMTAG) &&
COMPARE_DWORD(smbios->dmi.anchor, DMITAG) &&
smbios->dmi.anchor[4] == DMITAG[4] &&
checksum8(smbios, sizeof(SMBEntryPoint)) == 0) {
checksum8(smbios, sizeof(SMBEntryPoint)) == 0)
{
return smbios;
}
smbios = (SMBEntryPoint*)(((char*)smbios) + 16);
trunk/i386/libsaio/saio_internal.h
22
33
44
5
5
66
77
88
......
1010
1111
1212
13
13
1414
1515
1616
......
1818
1919
2020
21
21
2222
2323
2424
* Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
*
* Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
*
* The Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
*
* @APPLE_LICENSE_HEADER_END@
*/
trunk/i386/boot0/boot0.s
328328
329329
330330
331
331
332332
333333
334334
......
350350
351351
352352
353
353
354354
355355
356356
......
372372
373373
374374
375
375
376376
377377
378378
......
382382
383383
384384
385
386385
387386
388387
......
463462
464463
465464
466
467
465
466
468467
469
468
470469
471
472
470
471
473472
474
475
473
474
476475
477476
478477
......
506505
507506
508507
509
508
510509
511510
512511
......
611610
612611
613612
614
613
615614
616615
617616
......
621620
622621
623622
624
623
625624
626625
627626
......
782781
783782
784783
785
784
786785
787786
788787
; equipped with boot1h in its boot record
; regardless if it's active or not.
jne .continue
mov dh, 1 ; Argument for loadBootSector to check HFS+ partition signature.
mov dh, 1 ; Argument for loadBootSector to check HFS+ partition signature.
DebugChar('*')
; Scanned all partitions but not found any with active flag enabled
; Anyway if we found a protective MBR before we still have a chance
; for a possible GPT Header at LBA 1
;
;
dec bl
jnz .switchPass2; didn't find Protective MBR before
call checkGPT
; Jump to partition booter. The drive number is already in register DL.
; SI is pointing to the modified partition entry.
;
initBootLoader:
initBootLoader:
DebugChar('J')
jmp kBoot0LoadAddr
;
; Found Protective MBR Partition Type: 0xEE
; Check for 'EFI PART' string at the beginning
;
mov eax, [si + gpta.StartingLBA]; load boot sector from StartingLBA
mov [my_lba], eax
movdh, 1; Argument for loadBootSector to check HFS+ partition signature.
mov [my_lba], eax
mov dh, 1; Argument for loadBootSector to check HFS+ partition signature.
call loadBootSector
jne .gpt_continue; no boot loader signature
jne .gpt_continue; no boot loader signature
mov si, kMBRPartTable; fake the current GUID Partition
mov [si + part.lba], eax; as MBR style partition for boot1h
mov si, kMBRPartTable; fake the current GUID Partition
mov [si + part.lba], eax; as MBR style partition for boot1h
mov BYTE [si + part.type], kPartTypeHFS; with HFS+ filesystem type (0xAF)
jmp SHORT initBootLoader
jmp SHORT initBootLoader
.gpt_continue:
add si, bx; advance SI to next partition entry
ordh, dh
jz.checkBootSignature
.checkHFSSignature:
%if VERBOSE
mov eax, ecx
call print_hex
%endif
;
; INT13 Func 42 - Extended Read Sectors
;
; DS:SI = pointer to Disk Address Packet
;
; Returns:
; AH = return status (sucess is 0)
; AH = return status (success is 0)
; carry = 0 success
; 1 error
;
; that the 'times' argument is negative.
;
; According to EFI specification, maximum boot code size is 440 bytes
; According to EFI specification, maximum boot code size is 440 bytes
;
;
trunk/i386/boot0/boot0hfs.s
620620
621621
622622
623
623
624624
625625
626626
; DS:SI = pointer to Disk Address Packet
;
; Returns:
; AH = return status (sucess is 0)
; AH = return status (success is 0)
; carry = 0 success
; 1 error
;
trunk/i386/include/mach-o/loader.h
22
33
44
5
5
66
77
88
99
1010
1111
12
12
1313
1414
1515
......
1717
1818
1919
20
20
2121
2222
2323
......
3535
3636
3737
38
38
3939
4040
4141
......
9090
9191
9292
93
93
9494
9595
96
96
9797
9898
9999
......
159159
160160
161161
162
162
163163
164164
165165
......
170170
171171
172172
173
173
174174
175175
176176
177
177
178178
179179
180
181
180
181
182182
183183
184184
185
185
186186
187187
188188
......
197197
198198
199199
200
200
201201
202202
203203
......
303303
304304
305305
306
306
307307
308308
309309
......
474474
475475
476476
477
477
478478
479479
480480
......
482482
483483
484484
485
485
486486
487
487
488488
489489
490
490
491491
492492
493493
......
520520
521521
522522
523
523
524524
525525
526526
......
681681
682682
683683
684
684
685685
686686
687687
......
700700
701701
702702
703
703
704704
705705
706706
......
780780
781781
782782
783
783
784784
785785
786786
......
986986
987987
988988
989
989
990990
991991
992
992
993993
994
994
995995
996996
997997
......
10051005
10061006
10071007
1008
1008
10091009
10101010
10111011
......
10321032
10331033
10341034
1035
1035
10361036
10371037
10381038
......
10611061
10621062
10631063
1064
1064
10651065
10661066
10671067
......
11021102
11031103
11041104
1105
1105
11061106
11071107
11081108
......
11451145
11461146
11471147
1148
1148
11491149
11501150
11511151
......
11811181
11821182
11831183
1184
1185
1184
1185
11861186
11871187
11881188
1189
1189
11901190
11911191
11921192
......
12051205
12061206
12071207
1208
1208
12091209
12101210
1211
1212
1211
1212
12131213
12141214
12151215
12161216
12171217
1218
1218
12191219
12201220
12211221
12221222
1223
1223
12241224
12251225
12261226
12271227
12281228
1229
1229
12301230
12311231
12321232
......
12381238
12391239
12401240
1241
1241
12421242
12431243
12441244
12451245
12461246
12471247
1248
1248
12491249
12501250
1251
1252
1251
1252
12531253
12541254
12551255
1256
1256
12571257
12581258
12591259
1260
1260
12611261
12621262
1263
1263
12641264
12651265
12661266
1267
1268
1269
1270
1267
1268
1269
1270
1271
12711272
12721273
12731274
......
12751276
12761277
12771278
1278
1279
12791280
12801281
12811282
12821283
1283
1284
12841285
12851286
12861287
......
13891390
13901391
13911392
1392
1393
13931394
13941395
13951396
* Copyright (c) 1999-2010 Apple Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef _MACHO_LOADER_H_
#include <mach/machine.h>
/*
* <mach/vm_prot.h> is needed here for the vm_prot_t type and contains the
* <mach/vm_prot.h> is needed here for the vm_prot_t type and contains the
* constants that are or'ed together for the possible values of this type.
*/
#include <mach/vm_prot.h>
* boundary for efficient demand pageing. The MH_EXECUTE, MH_FVMLIB, MH_DYLIB,
* MH_DYLINKER and MH_BUNDLE file types also have the headers included as part
* of their first segment.
*
*
* The file type MH_OBJECT is a compact format intended as output of the
* assembler and input (and possibly output) of the link editor (the .o
* format). All sections are in one unnamed segment with no segment padding.
* format). All sections are in one unnamed segment with no segment padding.
* This format is used as an executable format when the file is so small the
* segment padding greatly increases its size.
*
all two-level namespace modules of
its dependent libraries. only used
when MH_PREBINDABLE and MH_TWOLEVEL
are both set. */
are both set. */
#define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000/* safe to divide up the sections into
sub-sections via symbols for dead
code stripping */
#define MH_BINDS_TO_WEAK 0x10000/* the final linked image uses
weak symbols */
#define MH_ALLOW_STACK_EXECUTION 0x20000/* When this bit is set, all stacks
#define MH_ALLOW_STACK_EXECUTION 0x20000/* When this bit is set, all stacks
in the task will be given stack
execution privilege. Only used in
MH_EXECUTE filetypes. */
#define MH_ROOT_SAFE 0x40000 /* When this bit is set, the binary
#define MH_ROOT_SAFE 0x40000 /* When this bit is set, the binary
declares it is safe for use in
processes with uid zero */
#define MH_SETUID_SAFE 0x80000 /* When this bit is set, the binary
#define MH_SETUID_SAFE 0x80000 /* When this bit is set, the binary
declares it is safe for use in
processes when issetugid() is true */
#define MH_NO_REEXPORTED_DYLIBS 0x100000 /* When this bit is set on a dylib,
#define MH_NO_REEXPORTED_DYLIBS 0x100000 /* When this bit is set on a dylib,
the static linker does not need to
examine dependent dylibs to see
if any are re-exported */
LC_LOAD_DYLIB load command to the
dylib if no symbols are being
referenced from the dylib. */
#define MH_HAS_TLV_DESCRIPTORS 0x800000 /* Contains a section of type
#define MH_HAS_TLV_DESCRIPTORS 0x800000 /* Contains a section of type
S_THREAD_LOCAL_VARIABLES */
#define MH_NO_HEAP_EXECUTION 0x1000000/* When this bit is set, the OS will
uint32_toffset;/* offset to the string */
#ifndef __LP64__
char*ptr;/* pointer to the string */
#endif
#endif
};
/*
interposing */
#defineS_16BYTE_LITERALS0xe/* section with only 16 byte
literals */
#defineS_DTRACE_DOF0xf/* section contains
#defineS_DTRACE_DOF0xf/* section contains
DTrace Object Format */
#defineS_LAZY_DYLIB_SYMBOL_POINTERS0x10/* section with only lazy
symbol pointers to lazy
/*
* Section types to support thread local variables
*/
#define S_THREAD_LOCAL_REGULAR 0x11 /* template of initial
#define S_THREAD_LOCAL_REGULAR 0x11 /* template of initial
values for TLVs */
#define S_THREAD_LOCAL_ZEROFILL 0x12 /* template of initial
#define S_THREAD_LOCAL_ZEROFILL 0x12 /* template of initial
values for TLVs */
#define S_THREAD_LOCAL_VARIABLES 0x13 /* TLV descriptors */
#define S_THREAD_LOCAL_VARIABLE_POINTERS 0x14 /* pointers to TLV
#define S_THREAD_LOCAL_VARIABLE_POINTERS 0x14 /* pointers to TLV
descriptors */
#define S_THREAD_LOCAL_INIT_FUNCTION_POINTERS 0x15 /* functions to call
to initialize TLV
* a section type S_REGULAR. The static linker will not copy section contents
* from sections with this attribute into its output file. These sections
* generally contain DWARF debugging info.
*/
*/
#defineS_ATTR_DEBUG 0x02000000/* a debug section */
#define SECTION_ATTRIBUTES_SYS 0x00ffff00/* system setable attributes */
#define S_ATTR_SOME_INSTRUCTIONS 0x00000400/* section contains some
* A dynamically linked shared library may be a sub_umbrella of an umbrella
* framework. If so it will be linked with "-sub_umbrella umbrella_name" where
* Where "umbrella_name" is the name of the sub_umbrella framework. When
* staticly linking when -twolevel_namespace is in effect a twolevel namespace
* staticly linking when -twolevel_namespace is in effect a twolevel namespace
* umbrella framework will only cause its subframeworks and those frameworks
* listed as sub_umbrella frameworks to be implicited linked in. Any other
* dependent dynamic libraries will not be linked it when -twolevel_namespace
* A dynamically linked shared library may be a sub_library of another shared
* library. If so it will be linked with "-sub_library library_name" where
* Where "library_name" is the name of the sub_library shared library. When
* staticly linking when -twolevel_namespace is in effect a twolevel namespace
* staticly linking when -twolevel_namespace is in effect a twolevel namespace
* shared library will only cause its subframeworks and those frameworks
* listed as sub_umbrella frameworks and libraries listed as sub_libraries to
* be implicited linked in. Any other dependent dynamic libraries will not be
};
/*
* The routines command contains the address of the dynamic shared library
* The routines command contains the address of the dynamic shared library
* initialization routine and an index into the module table for the module
* that defines the routine. Before any modules are used from the library the
* dynamic linker fully binds the module that defines the initialization routine
uint32_t locreloff;/* offset to local relocation entries */
uint32_t nlocrel;/* number of local relocation entries */
};
};
/*
* An indirect symbol table entry is simply a 32bit index into the symbol table
* An indirect symbol table entry is simply a 32bit index into the symbol table
* to the symbol that the pointer or stub is refering to. Unless it is for a
* non-lazy symbol pointer section for a defined symbol which strip(1) as
* non-lazy symbol pointer section for a defined symbol which strip(1) as
* removed. In which case it has the value INDIRECT_SYMBOL_LOCAL. If the
* symbol was also absolute INDIRECT_SYMBOL_ABS is or'ed with that.
*/
(index into the symbol table) */
uint32_t module_index;/* index into the module table this symbol
is defined in */
};
};
/* a module table entry */
struct dylib_module {
objc_module_info_addr; /* the (__OBJC,__module_info) section */
uint32_t/* for this module size of */
objc_module_info_size;/* the (__OBJC,__module_info) section */
};
};
/* a 64-bit module table entry */
struct dylib_module_64 {
objc_module_info_addr;/* the (__OBJC,__module_info) section */
};
/*
/*
* The entries in the reference symbol table are used when loading the module
* (both by the static and dynamic link editors) and if the module is unloaded
* or replaced. Therefore all external symbols (defined and undefined) are
* binary search or a directed linear search.
*/
struct twolevel_hint {
uint32_t
uint32_t
isub_image:8,/* index into the sub images */
itoc:24;/* index into the table of contents */
};
/*
* The linkedit_data_command contains the offsets and sizes of a blob
* of data in the __LINKEDIT segment.
* of data in the __LINKEDIT segment.
*/
struct linkedit_data_command {
uint32_tcmd;/* LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO,
};
/*
* The