Chameleon

Chameleon Commit Details

Date:2014-11-13 00:11:03 (5 years 6 months ago)
Author:ErmaC
Commit:2471
Parents: 2470
Message:Typo, indent and blank space.
Changes:
M/branches/ErmaC/Enoch/i386/libsaio/smbios.c
M/branches/ErmaC/Enoch/i386/boot2/options.c
M/branches/ErmaC/Enoch/i386/libsaio/sys.c
M/branches/ErmaC/Enoch/i386/libsaio/smbios_decode.c
M/branches/ErmaC/Enoch/i386/include/mach-o/loader.h
M/branches/ErmaC/Enoch/i386/libsaio/convert.c
M/branches/ErmaC/Enoch/i386/libsaio/acpi_patcher.c
M/branches/ErmaC/Enoch/i386/libsaio/bootargs.h
M/branches/ErmaC/Enoch/i386/libsaio/msdos.c
M/branches/ErmaC/Enoch/i386/libsaio/cpu.c
M/branches/ErmaC/Enoch/i386/libsaio/smbios_getters.c
M/branches/ErmaC/Enoch/i386/libsaio/disk.c
M/branches/ErmaC/Enoch/i386/libsaio/ntfs.c
M/branches/ErmaC/Enoch/i386/boot2/boot.h
M/branches/ErmaC/Enoch/i386/boot2/modules.c

File differences

branches/ErmaC/Enoch/i386/libsaio/acpi_patcher.c
796796
797797
798798
799
799800
800801
801802
{
rsdt_entries[i-dropoffset+j]=(uint32_t)new_ssdt[j];
}
DBG("RSDT: Added %d SSDT table(s)\n", ssdt_count);
}
branches/ErmaC/Enoch/i386/libsaio/bootargs.h
137137
138138
139139
140
140
141141
142142
143143
144144
145
146
147
148
145149
146150
147151
......
159163
160164
161165
166
162167
163168
169
164170
165
166
167
168171
169172
170
171
172173
173
174
175
176
177
178
179
174180
175
181
182
183
184
185
186
187
188
189
190
176191
177192
178193
179194
180
181
182
183
184195
185196
186197
......
198209
199210
200211
201
202212
203213
204
205214
215
216
217
206218
207219
220
221
208222
209
210
211
212
213
214
223
215224
216
217
218
219
220
221
222
223
224
225225
226226
227227
#define kBootArgsFlagBlackBg(1 << 6)
#define kBootArgsFlagLoginUI(1 << 7)
typedef struct boot_args_pre_lion
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;
char CommandLine[BOOT_LINE_LENGTH];/* Passed in command line */
uint32_t MemoryMap; /* Physical address of memory map */
uint32_t efiRuntimeServicesPageStart; /* physical address of defragmented runtime pages */
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;
uint8_t efiMode; /* 32 means 32-bit mode, 64 means 64-bit mode */
uint8_t __reserved1[3];
uint32_t __reserved2[1];
uint32_t performanceDataStart; /* physical address of log */
uint32_t performanceDataSize;
uint64_t efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */
uint32_t __reserved3[2];
} boot_args_pre_lion;
uint32_t keyStoreDataStart; /* physical address of key store data */
uint32_t keyStoreDataSize;
uint64_tbootMemStart;
uint64_tbootMemSize;
uint64_t PhysicalMemorySize;
uint64_t FSBFrequency;
typedef struct boot_args
uint64_t pciConfigSpaceBaseAddress;
uint32_t pciConfigSpaceStartBusNumber;
uint32_t pciConfigSpaceEndBusNumber;
uint32_tcsrActiveConfig;
uint32_tcsrPendingConfig;
uint32_t __reserved4[728];
} boot_args;
typedef struct boot_args_pre_lion
{
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;
char CommandLine[BOOT_LINE_LENGTH];/* Passed in command line */
uint32_t MemoryMap; /* Physical address of memory map */
uint32_t efiRuntimeServicesPageStart; /* physical address of defragmented runtime pages */
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;
uint8_t efiMode; /* 32 means 32-bit mode, 64 means 64-bit mode */
uint8_t __reserved1[3];
uint32_t __reserved2[1];
uint32_t performanceDataStart; /* physical address of log */
uint32_t performanceDataSize;
uint64_t efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */
uint32_t __reserved3[2];
uint32_t keyStoreDataStart; /* physical address of key store data */
uint32_t keyStoreDataSize;
uint64_tbootMemStart;
uint64_tbootMemSize;
uint64_t PhysicalMemorySize;
uint64_t FSBFrequency;
} boot_args_pre_lion;
uint64_t pciConfigSpaceBaseAddress;
uint32_t pciConfigSpaceStartBusNumber;
uint32_t pciConfigSpaceEndBusNumber;
uint32_tcsrActiveConfig;
uint32_tcsrPendingConfig;
uint32_t __reserved4[728];
} boot_args;
extern char gMacOSVersion[8];
#endif /* _PEXPERT_I386_BOOT_H */
branches/ErmaC/Enoch/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;
}
branches/ErmaC/Enoch/i386/libsaio/sys.c
162162
163163
164164
165
165
166
166167
167168
168169
......
176177
177178
178179
179
180
181
180182
181183
182184
183
185
186
184187
185188
186189
......
198201
199202
200203
201
204
205
202206
203207
204208
......
229233
230234
231235
232
236
237
238
233239
234240
235241
236242
237
243
244
238245
239246
240247
241248
242249
243250
244
251
252
253
245254
246255
247256
......
249258
250259
251260
252
261
253262
254263
255264
......
302311
303312
304313
305
306
314
315
316
317
307318
308319
309320
310321
311
322
323
312324
313325
314326
......
317329
318330
319331
320
332
333
321334
322335
323336
......
326339
327340
328341
329
342
343
330344
331345
332346
......
351365
352366
353367
354
368
369
355370
356371
357372
358
373
359374
360
375
361376
362377
363378
......
375390
376391
377392
378
393
394
379395
380396
381397
......
402418
403419
404420
405
421
422
406423
407424
408425
......
435452
436453
437454
438
439
455
456
457
458
440459
441
460
442461
443462
444463
......
455474
456475
457476
458
477
478
459479
460
480
481
482
461483
462484
463485
......
467489
468490
469491
470
471
492
493
472494
473
474
475
495
496
497
476498
477
478
499
500
479501
480
481
482
502
503
504
483505
484
506
485507
486508
487509
......
529551
530552
531553
532
554
555
533556
534557
535558
......
537560
538561
539562
540
563
541564
542565
543566
......
545568
546569
547570
548
571
572
549573
550574
551575
552
576
577
553578
554579
555580
556
557
581
582
583
584
558585
559586
560587
561588
562589
563590
564
591
592
565593
566594
567595
568
596
597
569598
570
599
600
571601
572602
573603
574604
575605
576606
607
577608
578609
579
610
580611
581612
582613
......
587618
588619
589620
590
621
622
591623
592624
593625
......
604636
605637
606638
607
639
640
608641
609642
610643
......
620653
621654
622655
623
656
657
624658
625659
626660
......
821855
822856
823857
824
858
859
825860
826861
827862
......
836871
837872
838873
839
874
875
840876
841
877
878
842879
843880
844
881
882
883
845884
846885
847886
......
855894
856895
857896
858
897
898
859899
860900
861901
862902
863903
864904
865
905
906
866907
867908
868909
......
876917
877918
878919
879
920
921
880922
881923
882924
883
884
885
925
926
927
928
929
930
886931
887932
888933
......
894939
895940
896941
897
898
899
942
943
944
945
946
947
900948
901949
902950
......
910958
911959
912960
913
914
915
961
962
963
964
965
966
967
968
916969
917
970
971
918972
919973
920974
......
923977
924978
925979
926
980
981
927982
928983
929984
......
931986
932987
933988
934
989
990
935991
936992
937993
......
943999
9441000
9451001
946
1002
1003
9471004
9481005
949
1006
1007
9501008
9511009
9521010
......
9761034
9771035
9781036
979
1037
1038
9801039
9811040
9821041
......
9851044
9861045
9871046
988
1047
9891048
990
1049
1050
9911051
9921052
9931053
......
10111071
10121072
10131073
1014
1074
1075
10151076
10161077
10171078
......
10201081
10211082
10221083
1023
1084
1085
10241086
10251087
10261088
......
10351097
10361098
10371099
1038
1039
1100
1101
1102
1103
10401104
10411105
10421106
10431107
1044
1108
1109
10451110
10461111
10471112
......
10511116
10521117
10531118
1054
1119
1120
10551121
10561122
10571123
10581124
1059
1060
1061
1062
1063
1064
1125
1126
1127
1128
1129
1130
1131
10651132
10661133
10671134
10681135
10691136
1070
1137
1138
10711139
10721140
10731141
......
10791147
10801148
10811149
1082
1150
1151
10831152
10841153
1085
1154
10861155
10871156
10881157
10891158
1090
1159
1160
10911161
10921162
1093
1163
1164
1165
10941166
10951167
10961168
1097
1169
1170
10981171
10991172
11001173
......
11201193
11211194
11221195
1123
1124
1196
1197
1198
1199
11251200
11261201
1127
1128
1202
1203
1204
1205
1206
11291207
1130
1208
1209
1210
11311211
11321212
1133
1213
1214
1215
11341216
11351217
11361218
......
11381220
11391221
11401222
1141
1142
1223
1224
1225
1226
11431227
11441228
11451229
11461230
1147
1231
1232
11481233
11491234
11501235
......
11591244
11601245
11611246
1162
1247
1248
11631249
11641250
11651251
11661252
11671253
1168
1254
1255
11691256
1170
1257
1258
11711259
11721260
11731261
1174
1262
1263
11751264
11761265
11771266
// 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) {
if (bvr->part_no == multiboot_skip_partition) continue;
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);
}
}
branches/ErmaC/Enoch/i386/libsaio/cpu.c
2020
2121
2222
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
2395
2496
2597
......
96168
97169
98170
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165171
166172
167173
......
192198
193199
194200
195
201
202
196203
197204
198205
199206
200207
201208
202
209
210
203211
204212
205213
206
214
215
207216
208217
209218
......
211220
212221
213222
214
223
224
215225
216
226
227
228
217229
218230
219231
......
256268
257269
258270
259
271
272
260273
261274
262
275
276
263277
264278
265
279
280
266281
267282
268
283
284
285
269286
270287
271288
......
365382
366383
367384
368
385
386
369387
370388
371389
......
378396
379397
380398
381
382
399
400
401
402
383403
384404
385405
......
735755
736756
737757
738
739
740
741
742
758
759
760
761
762
743763
744764
745765
......
756776
757777
758778
759
760
761
762
763
764
765
766
767
768
769
770
771
772
779
780
781
782
783
784
785
786
787
788
789
790
791
792
773793
774794
775795
#endif
/*
* DFE: Measures the TSC frequency in Hz (64-bit) using the ACPI PM timer
*/
static uint64_t measure_tsc_frequency(void)
{
uint64_t tscStart;
uint64_t tscEnd;
uint64_t tscDelta = 0xffffffffffffffffULL;
unsigned long pollCount;
uint64_t retval = 0;
int i;
/* Time how many TSC ticks elapse in 30 msec using the 8254 PIT
* counter 2. We run this loop 3 times to make sure the cache
* is hot and we take the minimum delta from all of the runs.
* That is to say that we're biased towards measuring the minimum
* number of TSC ticks that occur while waiting for the timer to
* expire. That theoretically helps avoid inconsistencies when
* running under a VM if the TSC is not virtualized and the host
* steals time. The TSC is normally virtualized for VMware.
*/
for(i = 0; i < 10; ++i)
{
enable_PIT2();
set_PIT2_mode0(CALIBRATE_LATCH);
tscStart = rdtsc64();
pollCount = poll_PIT2_gate();
tscEnd = rdtsc64();
/* The poll loop must have run at least a few times for accuracy */
if (pollCount <= 1)
{
continue;
}
/* The TSC must increment at LEAST once every millisecond.
* We should have waited exactly 30 msec so the TSC delta should
* be >= 30. Anything less and the processor is way too slow.
*/
if ((tscEnd - tscStart) <= CALIBRATE_TIME_MSEC)
{
continue;
}
// tscDelta = MIN(tscDelta, (tscEnd - tscStart))
if ( (tscEnd - tscStart) < tscDelta )
{
tscDelta = tscEnd - tscStart;
}
}
/* tscDelta is now the least number of TSC ticks the processor made in
* a timespan of 0.03 s (e.g. 30 milliseconds)
* Linux thus divides by 30 which gives the answer in kiloHertz because
* 1 / ms = kHz. But we're xnu and most of the rest of the code uses
* Hz so we need to convert our milliseconds to seconds. Since we're
* dividing by the milliseconds, we simply multiply by 1000.
*/
/* Unlike linux, we're not limited to 32-bit, but we do need to take care
* that we're going to multiply by 1000 first so we do need at least some
* arithmetic headroom. For now, 32-bit should be enough.
* Also unlike Linux, our compiler can do 64-bit integer arithmetic.
*/
if (tscDelta > (1ULL<<32))
{
retval = 0;
}
else
{
retval = tscDelta * 1000 / 30;
}
disable_PIT2();
return retval;
}
/*
* timeRDTSC()
* This routine sets up PIT counter 2 to count down 1/20 of a second.
* It pauses until the value is latched in the counter
}
/*
* DFE: Measures the TSC frequency in Hz (64-bit) using the ACPI PM timer
*/
static uint64_t measure_tsc_frequency(void)
{
uint64_t tscStart;
uint64_t tscEnd;
uint64_t tscDelta = 0xffffffffffffffffULL;
unsigned long pollCount;
uint64_t retval = 0;
int i;
/* Time how many TSC ticks elapse in 30 msec using the 8254 PIT
* counter 2. We run this loop 3 times to make sure the cache
* is hot and we take the minimum delta from all of the runs.
* That is to say that we're biased towards measuring the minimum
* number of TSC ticks that occur while waiting for the timer to
* expire. That theoretically helps avoid inconsistencies when
* running under a VM if the TSC is not virtualized and the host
* steals time. The TSC is normally virtualized for VMware.
*/
for(i = 0; i < 10; ++i)
{
enable_PIT2();
set_PIT2_mode0(CALIBRATE_LATCH);
tscStart = rdtsc64();
pollCount = poll_PIT2_gate();
tscEnd = rdtsc64();
/* The poll loop must have run at least a few times for accuracy */
if (pollCount <= 1) {
continue;
}
/* The TSC must increment at LEAST once every millisecond.
* We should have waited exactly 30 msec so the TSC delta should
* be >= 30. Anything less and the processor is way too slow.
*/
if ((tscEnd - tscStart) <= CALIBRATE_TIME_MSEC) {
continue;
}
// tscDelta = MIN(tscDelta, (tscEnd - tscStart))
if ( (tscEnd - tscStart) < tscDelta ) {
tscDelta = tscEnd - tscStart;
}
}
/* tscDelta is now the least number of TSC ticks the processor made in
* a timespan of 0.03 s (e.g. 30 milliseconds)
* Linux thus divides by 30 which gives the answer in kiloHertz because
* 1 / ms = kHz. But we're xnu and most of the rest of the code uses
* Hz so we need to convert our milliseconds to seconds. Since we're
* dividing by the milliseconds, we simply multiply by 1000.
*/
/* Unlike linux, we're not limited to 32-bit, but we do need to take care
* that we're going to multiply by 1000 first so we do need at least some
* arithmetic headroom. For now, 32-bit should be enough.
* Also unlike Linux, our compiler can do 64-bit integer arithmetic.
*/
if (tscDelta > (1ULL<<32)) {
retval = 0;
} else {
retval = tscDelta * 1000 / 30;
}
disable_PIT2();
return retval;
}
/*
* Original comment/code:
* "DFE: Measures the Max Performance Frequency in Hz (64-bit)"
*
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]);
}
/* get BrandString (if supported) */
/* Copyright: from Apple's XNU cpuid.c */
if (p->CPU.CPUID[CPUID_80][0] > 0x80000004) {
if (p->CPU.CPUID[CPUID_80][0] > 0x80000004)
{
uint32_treg[4];
charstr[128], *s;
/*
bcopy((char *)reg, &str[16], 16);
do_cpuid(0x80000004, reg);
bcopy((char *)reg, &str[32], 16);
for (s = str; *s != '\0'; s++) {
if (*s != ' ') {
for (s = str; *s != '\0'; s++)
{
if (*s != ' ')
{
break;
}
}
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("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
/*switch (p->CPU.Type) {
case PT_OEM:
DBG("Processor type: Intel Original OEM Processor\n");
default:
break;
}*/
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 + 500000) / 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("Microcode version: %d\n", p->CPU.MCodeVersion); // CPU microcode version
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 + 500000) / 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("Microcode version: %d\n",p->CPU.MCodeVersion); // CPU microcode version
DBG("\n---------------------------------------------\n");
#if DEBUG_CPU
pause();
branches/ErmaC/Enoch/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
......
16861691
16871692
16881693
1689
1694
1695
16901696
16911697
16921698
16931699
16941700
16951701
1696
1702
1703
16971704
16981705
16991706
1700
1707
1708
17011709
17021710
1703
1704
1711
1712
1713
1714
17051715
17061716
1707
1717
1718
1719
17081720
17091721
17101722
......
17271739
17281740
17291741
1742
17301743
17311744
17321745
......
17571770
17581771
17591772
1760
1773
1774
17611775
1762
1776
1777
1778
17631779
1764
1780
1781
1782
17651783
17661784
17671785
......
19091927
19101928
19111929
1912
1930
1931
19131932
19141933
19151934
......
19181937
19191938
19201939
1921
1940
1941
19221942
19231943
19241944
......
19351955
19361956
19371957
1938
1958
1959
19391960
19401961
19411962
19421963
19431964
19441965
1945
1966
1967
19461968
19471969
19481970
1949
1971
1972
19501973
19511974
19521975
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:
u_int32_t 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++;
}
}
branches/ErmaC/Enoch/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:
branches/ErmaC/Enoch/i386/libsaio/smbios_decode.c
471471
472472
473473
474
474
475
475476
476
477
478
479
477480
478481
479482
480483
481
484
485
482486
483487
484488
......
492496
493497
494498
495
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) {
switch (((SMBMemoryDevice *)structHeader)->memorySize)
{
case 0:
DBG("\tSize: No Module Installed\n");
break;
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)) {
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;
}
branches/ErmaC/Enoch/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,
branches/ErmaC/Enoch/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
......
838851
839852
840853
841
854
855
842856
843857
844858
......
933947
934948
935949
936
950
951
937952
938953
939954
......
965980
966981
967982
968
983
984
985
969986
970987
971988
......
9831000
9841001
9851002
986
1003
1004
9871005
9881006
9891007
990
1008
9911009
9921010
9931011
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;
}
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);
branches/ErmaC/Enoch/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
......
102106
103107
104108
105
109
110
106111
107112
108113
109114
110115
111
116
117
112118
113119
114120
......
119125
120126
121127
122
128
129
123130
124131
125132
......
139146
140147
141148
142
149
150
143151
144
152
153
154
145155
146156
147157
......
154164
155165
156166
157
158
167
168
169
170
159171
160172
161173
162174
163
175
176
164177
165178
166179
......
188201
189202
190203
191
204
192205
193
206
207
194208
195
209
210
211
196212
197213
198214
......
210226
211227
212228
213
229
230
214231
215232
216233
217
234
235
218236
219237
220238
221
239
240
222241
223242
224243
225
244
245
226246
227247
228248
......
235255
236256
237257
238
258
259
239260
240261
241262
242
263
264
243265
244266
245267
246
268
269
247270
248271
249272
250
273
274
251275
252276
253277
......
259283
260284
261285
262
286
287
263288
264289
265290
266
291
292
267293
268294
269295
270
296
297
271298
272299
273300
274
301
302
275303
276304
277305
......
282310
283311
284312
285
313
314
286315
287316
288317
289
318
319
290320
291321
292322
293
323
324
294325
295326
296327
297
328
329
298330
299331
300332
......
312344
313345
314346
315
347
348
316349
317350
318351
319
352
353
320354
321355
322356
323
357
358
324359
325360
326361
327
362
363
328364
329365
330366
......
338374
339375
340376
341
377
342378
343379
344380
......
354390
355391
356392
357
393
394
358395
359396
360397
361398
362
399
400
363401
364
402
403
365404
366405
367406
......
415454
416455
417456
418
457
458
419459
420
460
461
421462
422463
423464
......
441482
442483
443484
444
485
486
445487
446
488
489
447490
448491
449492
......
464507
465508
466509
467
510
511
468512
469
513
514
470515
471516
472517
......
491536
492537
493538
494
539
540
495541
496542
497543
498
544
545
499546
500547
501548
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);
}
// 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:
{
if (strstr(Platform.CPU.BrandString, "Xeon"))
{
value->word = 0x402;// 1026 - Xeon
return true;
return true;
}
if (Platform.CPU.NoCores <= 2) {
if (Platform.CPU.NoCores <= 2)
{
value->word = 0x301;// 769 - Core 2 Duo
} else {
}
else
{
value->word = 0x402;// 1026 - Core 2 Quad as Xeon
}
return true;
value->word = 0x501;// 1281 - Lynnfiled Quad-Core Xeon
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i3")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i3"))
{
value->word = 0x901;// 2305 - Core i3
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i5")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))
{
value->word = 0x601;// Core i5
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i7")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i7"))
{
value->word = 0x701;// 1793 - Core i7
return true;
}
if (Platform.CPU.NoCores <= 2) {
if (Platform.CPU.NoCores <= 2)
{
value->word = 0x901;// - Core i3
}
return true;
value->word = 0x501;// 1281 - Xeon
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i3")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i3"))
{
value->word = 0x901;// 2305 - Core i3
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i5")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))
{
value->word = 0x602;// 1538 - Core i5
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i7")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i7"))
{
value->word = 0x702;// 1794 -Core i7
return true;
}
if (Platform.CPU.NoCores <= 2) {
if (Platform.CPU.NoCores <= 2)
{
value->word = 0x901;// - Core i3
}
return true;
value->word = 0x501;// 1281 - Xeon
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i3")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i3"))
{
value->word = 0x902;// 2306 -Core i3
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i5")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))
{
value->word = 0x603;// 1539 - Core i5
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i7")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i7"))
{
value->word = 0x703;// 1795 - Core i7
return true;
}
if (Platform.CPU.NoCores <= 2) {
if (Platform.CPU.NoCores <= 2)
{
value->word = 0x902;// - Core i5
}
return true;
value->word = 0xA01;// 2561 - Xeon
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i3")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i3"))
{
value->word = 0x903;// 2307 - Core i3 - Apple doesn't use it
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i5")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))
{
value->word = 0x604;// 1540 - Core i5
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i7")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i7"))
{
value->word = 0x704;// 1796 - Core i7
return true;
}
if (Platform.CPU.NoCores <= 2) {
if (Platform.CPU.NoCores <= 2)
{
value->word = 0x903;// - Core i5
}
return true;
value->word = 0xA01;// 2561 - Xeon
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i3")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i3"))
{
value->word = 0x904;// 2308 - Core i3 - Apple doesn't use it - but we yes:-)
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i5")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))
{
value->word = 0x605;// 1541 - Core i5
return true;
}
if (strstr(Platform.CPU.BrandString, "Core(TM) i7")) {
if (strstr(Platform.CPU.BrandString, "Core(TM) i7"))
{
value->word = 0x705;// 1797 - Core i7
return true;
}
if (Platform.CPU.NoCores <= 2) {
if (Platform.CPU.NoCores <= 2)
{
value->word = 0x904;// - Core i3
}
return true;
value->word = 0x601;// 1537 - Core i5
return true;
default:
break; //Unsupported CPU type
break; // Unsupported CPU type
}
}
default:
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);
branches/ErmaC/Enoch/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 dyld_info_command contains the file offsets and sizes of
* the new compressed form of the information dyld needs to
* The dyld_info_command contains the file offsets and sizes of
* the new compressed form of the information dyld needs to
* load the image. This information is used by dyld on Mac OS X
* 10.6 and later. All information pointed to by this command
* is encoded using byte streams, so no endian swapping is needed
* to interpret it.
* to interpret it.
*/
struct dyld_info_command {
uint32_t cmd;/* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */
*/
uint32_t rebase_off;/* file offset to rebase info */
uint32_t rebase_size;/* size of rebase info */
/*
* Dyld binds an image during the loading process, if the image
* requires any pointers to be initialized to symbols in other images.
* The bind information is a stream of byte sized
* requires any pointers to be initialized to symbols in other images.
* The bind information is a stream of byte sized
* opcodes whose symbolic names start with BIND_OPCODE_.
* Conceptually the bind information is a table of tuples:
* <seg-index, seg-offset, type, symbol-library-ordinal, symbol-name, addend>
* The opcodes are a compressed way to encode the table by only
* encoding when a column changes. In addition simple patterns
* like for runs of pointers initialzed to the same value can be
* like for runs of pointers initialzed to the same value can be
* encoded in a few bytes.
*/
uint32_t bind_off;/* file offset to binding info */
uint32_t bind_size;/* size of binding info */
/*
* Some C++ programs require dyld to unique symbols so that all
* images in the process use the same copy of some code/data.
* This step is done after binding. The content of the weak_bind
* info is an opcode stream like the bind_info. But it is sorted
* alphabetically by symbol name. This enable dyld to walk
* alphabetically by symbol name. This enable dyld to walk
* all images with weak binding information in order and look
* for collisions. If there are no collisions, dyld does
* no updating. That means that some fixups are also encoded
*/
uint32_t weak_bind_off;/* file offset to weak binding info */
uint32_t weak_bind_size; /* size of weak binding info */
/*
* Some uses of external symbols do not need to be bound immediately.
* Instead they can be lazily bound on first use. The lazy_bind
* are contains a stream of BIND opcodes to bind all lazy symbols.
* Normal use is that dyld ignores the lazy_bind section when
* loading an image. Instead the static linker arranged for the
* lazy pointer to initially point to a helper function which
* lazy pointer to initially point to a helper function which
* pushes the offset into the lazy_bind area for the symbol
* needing to be bound, then jumps to dyld which simply adds
* the offset to lazy_bind_off to get the information on what
* to bind.
* the offset to lazy_bind_off to get the information on what
* to bind.
*/
uint32_t lazy_bind_off;/* file offset to lazy binding info */
uint32_t lazy_bind_size; /* size of lazy binding infs */
/*
* The symbols exported by a dylib are encoded in a trie. This
* is a compact representation that factors out common prefixes.
* It also reduces LINKEDIT pages in RAM because it encodes all
* It also reduces LINKEDIT pages in RAM because it encodes all
* information (name, address, flags) in one small, contiguous range.
* The export area is a stream of nodes. The first node sequentially
* is the start node for the trie.
* is the start node for the trie.
*
* Nodes for a symbol start with a uleb128 that is the length of
* the exported symbol information for the string so far.
* If there is no exported symbol, the node starts with a zero byte.
* If there is exported info, it follows the length. First is
* a uleb128 containing flags. Normally, it is followed by a
* uleb128 encoded offset which is location of the content named
* If there is no exported symbol, the node starts with a zero byte.
* If there is exported info, it follows the length.
*
* First is a uleb128 containing flags. Normally, it is followed by
* a uleb128 encoded offset which is location of the content named
* by the symbol from the mach_header for the image. If the flags
* is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is
* a uleb128 encoded library ordinal, then a zero terminated
* is re-export from the specified dylib with the same name.
*
* After the optional exported symbol information is a byte of
* how many edges (0-255) that this node has leaving it,
* how many edges (0-255) that this node has leaving it,
* followed by each edge.
* Each edge is a zero terminated UTF8 of the addition chars
* in the symbol, followed by a uleb128 offset for the node that
* edge points to.
*
*
*/
uint32_t export_off;/* file offset to lazy binding info */
uint32_t export_size;/* size of lazy binding infs */
};
/*
* Sections of type S_THREAD_LOCAL_VARIABLES contain an array
* Sections of type S_THREAD_LOCAL_VARIABLES contain an array
* of tlv_descriptor structures.
*/
struct tlv_descriptor
branches/ErmaC/Enoch/i386/boot2/boot.h
337337
338338
339339
340
340
341
341342
342343
343344
size_t dst_size,
const void * src,
size_t src_size);
/*extern size_t lzvn_encode(void * dst,
/*
extern size_t lzvn_encode(void * dst,
size_t dst_size,
const void * src,
size_t src_size,
branches/ErmaC/Enoch/i386/boot2/modules.c
7878
7979
8080
81
82
81
82
8383
8484
8585
......
9595
9696
9797
98
98
9999
100100
101101
......
107107
108108
109109
110
110
111111
112112
113113
......
146146
147147
148148
149
149
150150
151151
152152
......
197197
198198
199199
200
200
201201
202202
203203
204204
205205
206206
207
207
208208
209209
210
210
211211
212212
213213
......
235235
236236
237237
238
238
239239
240240
241241
......
269269
270270
271271
272
272
273273
274274
275275
......
298298
299299
300300
301
301
302302
303303
304304
......
307307
308308
309309
310
310
311311
312312
313313
......
322322
323323
324324
325
326
325
326
327327
328328
329329
330
330
331331
332332
333
333
334334
335335
336336
......
340340
341341
342342
343
343
344344
345345
346346
......
348348
349349
350350
351
351
352352
353353
354354
......
376376
377377
378378
379
379
380380
381381
382382
383
383
384384
385385
386
387
386
387
388388
389389
390390
391391
392392
393
393
394394
395395
396396
......
414414
415415
416416
417
417
418418
419419
420420
......
440440
441441
442442
443
443
444444
445445
446446
447
448447
448
449449
450450
451451
......
458458
459459
460460
461
461
462462
463463
464464
......
481481
482482
483483
484
484
485485
486486
487487
488488
489489
490490
491
491
492492
493493
494494
495
495
496496
497
497
498498
499499
500500
......
505505
506506
507507
508
508
509509
510510
511511
512512
513
513
514514
515515
516516
......
535535
536536
537537
538
538
539539
540540
541541
......
547547
548548
549549
550
550
551551
552552
553553
......
572572
573573
574574
575
575
576576
577577
578578
579579
580580
581
582
581
582
583583
584584
585585
586586
587587
588
588
589589
590590
591591
592592
593
594
593
594
595595
596596
597597
......
601601
602602
603603
604
605
604
605
606606
607607
608608
609
610
609
610
611611
612612
613613
......
624624
625625
626626
627
627
628628
629629
630630
......
632632
633633
634634
635
635
636636
637637
638638
......
645645
646646
647647
648
649
648
649
650650
651
651
652652
653653
654654
......
661661
662662
663663
664
664
665665
666666
667667
......
677677
678678
679679
680
680
681681
682682
683683
......
685685
686686
687687
688
688
689689
690
690
691691
692692
693
693
694694
695695
696696
......
698698
699699
700700
701
702
701
702
703703
704704
705705
......
709709
710710
711711
712
712
713713
714
714
715715
716716
717717
......
741741
742742
743743
744
744
745745
746746
747747
748
748
749749
750
750
751751
752752
753753
754
754
755755
756
756
757757
758
758
759759
760760
761
761
762762
763763
764764
765
765
766766
767767
768768
769769
770770
771771
772
772
773773
774774
775775
776776
777
778
777
778
779779
780780
781781
......
787787
788788
789789
790
790
791791
792792
793793
794
794
795795
796796
797797
798
798
799799
800
800
801801
802
802
803803
804804
805805
......
811811
812812
813813
814
814
815815
816816
817817
818818
819
819
820820
821821
822822
......
837837
838838
839839
840
840
841841
842842
843843
844
844
845845
846846
847847
......
854854
855855
856856
857
857
858858
859859
860
860
861861
862862
863863
......
865865
866866
867867
868
868
869869
870870
871871
......
875875
876876
877877
878
879
878
879
880880
881
881
882882
883883
884884
885885
886
886
887887
888888
889889
......
892892
893893
894894
895
896895
896
897897
898
898
899899
900900
901
902
903901
902
903
904904
905905
906906
907907
908
908
909909
910910
911911
......
926926
927927
928928
929
929
930930
931931
932932
933933
934934
935935
936
936
937937
938938
939939
......
941941
942942
943943
944
944
945945
946946
947
947
948948
949949
950950
951951
952
952
953953
954954
955
955
956956
957957
958958
......
981981
982982
983983
984
984
985985
986986
987987
......
10351035
10361036
10371037
1038
1038
10391039
1040
1040
10411041
10421042
10431043
......
10921092
10931093
10941094
1095
1095
10961096
10971097
10981098
......
11221122
11231123
11241124
1125
1125
11261126
11271127
11281128
......
11431143
11441144
11451145
1146
1147
1146
1147
11481148
11491149
11501150
return retVal;
}
void start_built_in_module(const char* name,
const char* author,
void start_built_in_module(const char* name,
const char* author,
const char* description,
UInt32 version,
UInt32 compat,
* Module depencdies will be loaded first
* Modules will only be loaded once. When loaded a module must
* setup apropriete function calls and hooks as required.
* NOTE: To ensure a module loads after another you may
* NOTE: To ensure a module loads after another you may
* link one module with the other. For dyld to allow this, you must
* reference at least one symbol within the module.
*/
struct dirstuff* moduleDir = opendir("/Extra/modules/");
if(!moduleDir)
{
verbose("Warning: Unable to open modules folder at '/Extra/modules/'. Ingoring modules.\n");
verbose("Warning: Unable to open modules folder at '/Extra/modules/'. Ignoring modules.\n");
return;
}
while (readdir(moduleDir, (const char**)&name, &flags, &time) >= 0) {
{
return 1;
}
snprintf(modString, sizeof(modString), MODULE_PATH "%s", module);
fh = open(modString, 0);
if(fh < 0)
/*
* add_symbol
* This function adds a symbol from a module to the list of known symbols
* This function adds a symbol from a module to the list of known symbols
* possibly change to a pointer and add this to the Symbol module so that it can
* adjust it's internal symbol list (sort) to optimize locating new symbols
* NOTE: returns the address if the symbol is "start", else returns 0xFFFFFFFF
*/
long long add_symbol(char* symbol, long long addr, char is64)
{
// This only can handle 32bit symbols
// This only can handle 32bit symbols
symbolList_t* entry;
//DBG("Adding symbol %s at 0x%X\n", symbol, addr);
entry = malloc(sizeof(symbolList_t));
entry->next = moduleSymbols;
moduleSymbols = entry;
new_entry->next = loadedModules;
loadedModules = new_entry;
if(!name) name = "Unknown";
if(!author) author = "Unknown";
if(!description) description = "";
}
}
DBG("Module %s not loaded\n", name); DBGPAUSE();
return 0;
}
entry = entry->next;
}
}
#if CONFIG_MODULE_DEBUG
printf("Unable to locate symbol %s\n", name);
getchar();
if(strcmp(name, VOID_SYMBOL) == 0) return 0xFFFFFFFF;
// In the event that a symbol does not exist
// Return a pointer to a void function.
else return lookup_all_symbols(VOID_SYMBOL);
else return lookup_all_symbols(VOID_SYMBOL);
}
/********************************************************************************/
* NOTE: If the module is unable to load ot completeion, the modules
* symbols will still be available.
*/
void* parse_mach(void* binary,
int(*dylib_loader)(char*),
void* parse_mach(void* binary,
int(*dylib_loader)(char*),
long long(*symbol_handler)(char*, long long, char),
void (*section_handler)(char* section, char* segment, void* cmd, UInt64 offset, UInt64 address)
)
{
{
char is64 = false;
void (*module_start)(void) = NULL;
// Module info
/*char* moduleName = NULL;
UInt32 moduleVersion = 0;
struct load_command *loadCommand = NULL;
struct dylib_command* dylibCommand = NULL;
struct dyld_info_command* dyldInfoCommand = NULL;
struct symtab_command* symtabCommand = NULL;
struct segment_command *segCommand = NULL;
struct segment_command_64 *segCommand64 = NULL;
//struct dysymtab_command* dysymtabCommand = NULL;
UInt32 binaryIndex = 0;
UInt16 cmd = 0;
textSection = 0;
textAddress = 0;// reinitialize text location in case it doesn't exist;
getchar();
return NULL; // Module is in the incorrect format
}*/
while(cmd < ((struct mach_header*)binary)->ncmds)
{
cmd++;
loadCommand = binary + binaryIndex;
UInt32 cmdSize = loadCommand->cmdsize;
switch ((loadCommand->cmd & 0x7FFFFFFF))
{
case LC_SYMTAB:
symtabCommand = binary + binaryIndex;
break;
case LC_SEGMENT: // 32bit macho
{
segCommand = binary + binaryIndex;
// __TEXT,__text found, save the offset and address for when looking for the calls.
textSection = sect->offset;
textAddress = sect->addr;
}
}
}
}
break;
// __TEXT,__text found, save the offset and address for when looking for the calls.
textSection = sect->offset;
textAddress = sect->addr;
}
}
}
}
break;
case LC_LOAD_DYLIB:
case LC_LOAD_WEAK_DYLIB ^ LC_REQ_DYLD:
// Required modules
{
char* name = malloc(strlen(module) + strlen(".dylib") + 1);
sprintf(name, "%s.dylib", module);
if (!dylib_loader(name))
{
// NOTE: any symbols exported by dep will be replace with the void function
// Bind and rebase info is stored here
dyldInfoCommand = binary + binaryIndex;
break;
case LC_DYSYMTAB:
case LC_UUID:
break;
case LC_UNIXTHREAD:
break;
default:
DBG("Unhandled loadcommand 0x%X\n", loadCommand->cmd & 0x7FFFFFFF);
break;
}
binaryIndex += cmdSize;
}
{
// Rebase the module before binding it.
if(dyldInfoCommand->rebase_off)rebase_macho(binary, (char*)dyldInfoCommand->rebase_off,dyldInfoCommand->rebase_size);
// Bind all symbols.
// Bind all symbols.
if(dyldInfoCommand->bind_off)bind_macho(binary, (UInt8*)dyldInfoCommand->bind_off,dyldInfoCommand->bind_size);
if(dyldInfoCommand->weak_bind_off)bind_macho(binary, (UInt8*)dyldInfoCommand->weak_bind_off,dyldInfoCommand->weak_bind_size);
if(dyldInfoCommand->lazy_bind_off)bind_macho(binary, (UInt8*)dyldInfoCommand->lazy_bind_off,dyldInfoCommand->lazy_bind_size);
}
return module_start;
}
if(symbolEntry->n_value &&
symbol_handler(symbolString + symbolEntry->n_un.n_strx, textAddress ? (long long)base + symbolEntry->n_value : symbolEntry->n_value, is64) != 0xFFFFFFFF)
{
// Module start located. Start is an alias so don't register it
module_start = textAddress ? base + symbolEntry->n_value : symbolEntry->n_value;
}
else
{
struct nlist_64* symbolEntry = (void*)base + symtabCommand->symoff;
// NOTE First entry is *not* correct, but we can ignore it (i'm getting radar:// right now, verify later)
// NOTE First entry is *not* correct, but we can ignore it (i'm getting radar:// right now, verify later)
while(symbolIndex < symtabCommand->nsyms)
{
void rebase_macho(void* base, char* rebase_stream, UInt32 size)
{
rebase_stream += (UInt32)base;
UInt8 immediate = 0;
UInt8 opcode = 0;
UInt8 type = 0;
UInt32 segmentAddress = 0;
UInt32 tmp = 0;
UInt32 tmp2 = 0;
UInt8 bits = 0;
int index = 0;
unsigned int i = 0;
while(i < size)
{
immediate = rebase_stream[i] & REBASE_IMMEDIATE_MASK;
opcode = rebase_stream[i] & REBASE_OPCODE_MASK;
switch(opcode)
{
case REBASE_OPCODE_DONE:
type = 0;
segmentAddress = 0;
break;
case REBASE_OPCODE_SET_TYPE_IMM:
type = immediate;
break;
case REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
// Locate address to begin rebasing
} while(index <= immediate);
segmentAddress = segCommand->fileoff;
tmp = 0;
bits = 0;
do {
bits += 7;
}
while(rebase_stream[i] & 0x80);
segmentAddress += tmp;
break;
tmp |= rebase_stream[++i] & 0x7f;
bits += 7;
} while(rebase_stream[i] & 0x80);
segmentAddress +=tmp;
segmentAddress +=tmp;
break;
case REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
segmentAddress += immediate * sizeof(void*);
break;
segmentAddress += sizeof(void*);
}
break;
case REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
tmp = 0;
bits = 0;
segmentAddress += sizeof(void*);
}
break;
case REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
tmp = 0;
bits = 0;
tmp |= (rebase_stream[++i] & 0x7f) << bits;
bits += 7;
} while(rebase_stream[i] & 0x80);
rebase_location(base + segmentAddress, (char*)base, type);
segmentAddress += tmp + sizeof(void*);
break;
case REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
tmp = 0;
bits = 0;
tmp |= (rebase_stream[++i] & 0x7f) << bits;
bits += 7;
} while(rebase_stream[i] & 0x80);
tmp2 = 0;
bits = 0;
do {
index = 0;
for (index = 0; index < tmp; ++index) {
rebase_location(base + segmentAddress, (char*)base, type);
segmentAddress += tmp2 + sizeof(void*);
}
break;
// Based on code from dylibinfo.cpp and ImageLoaderMachOCompressed.cpp
// NOTE: this uses 32bit values, and not 64bit values.
// NOTE: this uses 32bit values, and not 64bit values.
// There is a possibility that this could cause issues,
// however the modules are 32 bits, so it shouldn't matter too much
void bind_macho(void* base, UInt8* bind_stream, UInt32 size)
{
{
bind_stream += (UInt32)base;
UInt8 immediate = 0;
UInt8 opcode = 0;
UInt8 type = BIND_TYPE_POINTER;
UInt32 segmentAddress = 0;
UInt32 address = 0;
SInt32 addend = 0;
SInt32 libraryOrdinal = 0;
const char* symbolName = NULL;
UInt8 symboFlags = 0;
UInt32 symbolAddr = 0xFFFFFFFF;
// Temperary variables
UInt32 tmp = 0;
UInt32 tmp2 = 0;
UInt32 index = 0;
unsigned int i = 0;
while(i < size)
{
immediate = bind_stream[i] & BIND_IMMEDIATE_MASK;
opcode = bind_stream[i] & BIND_OPCODE_MASK;
switch(opcode)
{
case BIND_OPCODE_DONE:
libraryOrdinal = 0;
symbolAddr = 0xFFFFFFFF;
break;
case BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
libraryOrdinal = immediate;
break;
case BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
libraryOrdinal = read_uleb(bind_stream, &i);
break;
case BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
libraryOrdinal = immediate ? (SInt8)(BIND_OPCODE_MASK | immediate) : immediate;
libraryOrdinal = immediate ? (SInt8)(BIND_OPCODE_MASK | immediate) : immediate;
break;
case BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
symboFlags = immediate;
symbolName = (char*)&bind_stream[++i];
case BIND_OPCODE_SET_TYPE_IMM:
type = immediate;
break;
case BIND_OPCODE_SET_ADDEND_SLEB:
addend = read_uleb(bind_stream, &i);
if(!(bind_stream[i-1] & 0x40)) addend *= -1;
break;
case BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
segmentAddress = 0;
segmentAddress += read_uleb(bind_stream, &i);
break;
case BIND_OPCODE_ADD_ADDR_ULEB:
segmentAddress += read_uleb(bind_stream, &i);
break;
case BIND_OPCODE_DO_BIND:
if(symbolAddr != 0xFFFFFFFF)
{
printf("Unable to bind symbol %s\n", symbolName);
getchar();
}
segmentAddress += sizeof(void*);
break;
case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
// Read in offset
tmp = read_uleb(bind_stream, &i);
if(symbolAddr != 0xFFFFFFFF)
{
address = segmentAddress + (UInt32)base;
bind_location((UInt32*)address, (char*)symbolAddr, addend, type);
}
else
}
segmentAddress += tmp + sizeof(void*);
break;
case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
if(symbolAddr != 0xFFFFFFFF)
{
address = segmentAddress + (UInt32)base;
bind_location((UInt32*)address, (char*)symbolAddr, addend, type);
}
else
getchar();
}
segmentAddress += (immediate * sizeof(void*)) + sizeof(void*);
break;
case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
tmp = read_uleb(bind_stream, &i);
tmp2 = read_uleb(bind_stream, &i);
tmp2 = read_uleb(bind_stream, &i);
if(symbolAddr != 0xFFFFFFFF)
{
for(index = 0; index < tmp; index++)
{
address = segmentAddress + (UInt32)base;
bind_location((UInt32*)address, (char*)symbolAddr, addend, type);
segmentAddress += tmp2 + sizeof(void*);
}
static inline void rebase_location(UInt32* location, char* base, int type)
{
{
switch(type)
{
case REBASE_TYPE_POINTER:
case REBASE_TYPE_TEXT_ABSOLUTE32:
*location += (UInt32)base;
break;
default:
break;
}
static inline void bind_location(UInt32* location, char* value, UInt32 addend, int type)
{
{
// do actual update
char* newValue = value + addend;
switch (type) {
case BIND_TYPE_POINTER:
case BIND_TYPE_TEXT_ABSOLUTE32:
break;
case BIND_TYPE_TEXT_PCREL32:
newValue -= ((UInt32)location + 4);
break;
default:
return;
*binary++ = 0xFF;// Jump
*binary++ = 0x25;// Long Jump
*((UInt32*)binary) = (UInt32)jumpPointer;
*jumpPointer = (UInt32)newAddress;
return 1;
}
void register_hook_callback(const char* name, void(*callback)(void*, void*, void*, void*))
{
DBG("Adding callback for '%s' hook.\n", name); DBGPAUSE();
moduleHook_t* hook = hook_exists(name);
if(hook)
{
// append
void print_hook_list()
{
printf("---Hook Table---\n");
moduleHook_t* hooks = moduleCallbacks;
while(hooks)
{
void load_all_modules()
{
}
int execute_hook(const char* name, void* arg1, void* arg2, void* arg3, void* arg4)
return 0;
}
void start_built_in_module(const char* name,
const char* author,
void start_built_in_module(const char* name,
const char* author,
const char* description,
UInt32 version,
UInt32 compat,
branches/ErmaC/Enoch/i386/boot2/options.c
611611
612612
613613
614
615
614
616615
617616
618617
//==========================================================================
static void
printMemoryInfo(void)
static void printMemoryInfo(void)
{
int line;
int i;

Archive Download the corresponding diff file

Revision: 2471