Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1401 lines
30 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. bldrthnk.c
  5. Abstract:
  6. This module implements a program which generates code to thunk from
  7. 32-bit to 64-bit structures.
  8. This code is generated as an aid to the AMD64 boot loader, which
  9. must generate 64-bit structures from 32-bit structures.
  10. Author:
  11. Forrest C. Foltz (forrestf) 15-May-2000
  12. To use:
  13. Revision History:
  14. --*/
  15. #include <windows.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include "bldrthnk.h"
  19. //
  20. // Internal type definitions follow
  21. //
  22. typedef struct _OBJ {
  23. PCHAR Image;
  24. LONG ImageSize;
  25. PDEFINITIONS Definitions;
  26. } OBJ, *POBJ;
  27. typedef struct _TYPE_REC *PTYPE_REC;
  28. typedef struct _FIELD_REC *PFIELD_REC;
  29. typedef struct _TYPE_REC {
  30. PTYPE_REC Next;
  31. PCHAR Name;
  32. ULONG Size32;
  33. ULONG Size64;
  34. PFIELD_REC FieldList;
  35. BOOL SignExtend;
  36. BOOL Fabricated;
  37. BOOL Only64;
  38. } TYPE_REC;
  39. typedef struct _FIELD_REC {
  40. PFIELD_REC Next;
  41. PCHAR Name;
  42. PCHAR TypeName;
  43. PCHAR SizeFormula;
  44. ULONG TypeSize32;
  45. ULONG TypeSize64;
  46. ULONG Offset32;
  47. ULONG Offset64;
  48. ULONG Size32;
  49. ULONG Size64;
  50. PTYPE_REC TypeRec;
  51. } FIELD_REC;
  52. //
  53. // Static TYPE_REC describing a 64-bit pointer type
  54. //
  55. TYPE_REC pointer64_typerec = {
  56. NULL,
  57. "POINTER64",
  58. 4,
  59. 8,
  60. NULL,
  61. TRUE,
  62. TRUE };
  63. //
  64. // Inline routine to generate a 32-bit pointer value from a ULONGLONG
  65. // value found in an .obj file.
  66. //
  67. __inline
  68. PVOID
  69. CalcPtr(
  70. IN ULONGLONG Address
  71. )
  72. {
  73. return (PVOID)((ULONG)Address);
  74. }
  75. //
  76. // Forward declarations follow
  77. //
  78. VOID
  79. ApplyFixupsToImage(
  80. IN PCHAR ObjImage
  81. );
  82. VOID
  83. __cdecl
  84. CheckCondition(
  85. int Condition,
  86. const char *FormatString,
  87. ...
  88. );
  89. VOID
  90. FabricateMissingTypes(
  91. VOID
  92. );
  93. PTYPE_REC
  94. FindTypeRec(
  95. IN PCHAR Name
  96. );
  97. PVOID
  98. GetMem(
  99. IN ULONG Size
  100. );
  101. VOID
  102. NewGlobalType(
  103. IN PTYPE_REC TypeRec
  104. );
  105. BOOL
  106. ProcessStructure(
  107. IN ULONG StrucIndex
  108. );
  109. void
  110. ReadObj(
  111. IN PCHAR Path,
  112. OUT POBJ Obj
  113. );
  114. int
  115. Usage(
  116. void
  117. );
  118. VOID
  119. WriteCopyList(
  120. IN PTYPE_REC TypeRec
  121. );
  122. VOID
  123. WriteCopyListWorker(
  124. IN PTYPE_REC TypeRec,
  125. IN ULONG Offset32,
  126. IN ULONG Offset64,
  127. IN PCHAR ParentName
  128. );
  129. VOID
  130. WriteCopyRoutine(
  131. IN PTYPE_REC TypeRec
  132. );
  133. VOID
  134. WriteThunkSource(
  135. VOID
  136. );
  137. //
  138. // Global data follows.
  139. //
  140. OBJ Obj32;
  141. OBJ Obj64;
  142. PTYPE_REC TypeRecList = NULL;
  143. int
  144. __cdecl
  145. main(
  146. IN int argc,
  147. IN char *argv[]
  148. )
  149. /*++
  150. Routine Description:
  151. This is the main entrypoint of bldrthnk.exe. Two command-line arguments
  152. are expected: first the path to the 32-bit .obj module, the second to
  153. the path to the 64-bit .obj module. The .objs are expected to be the
  154. result of compiling m4-generated structure definition code.
  155. Arguments:
  156. Return value:
  157. 0 for success, non-zero otherwise.
  158. --*/
  159. {
  160. ULONG strucIndex;
  161. //
  162. // argv[1] is the name of the 32-bit obj, argv[2] is the name of the
  163. // 64-bit obj
  164. //
  165. if (argc != 3) {
  166. return Usage();
  167. }
  168. //
  169. // Usage:
  170. //
  171. // bldrthnk <32-bit.obj> <64-bit.obj>
  172. //
  173. ReadObj( argv[1], &Obj32 );
  174. ReadObj( argv[2], &Obj64 );
  175. //
  176. // Process each STRUC_DEF structure
  177. //
  178. strucIndex = 0;
  179. while (ProcessStructure( strucIndex )) {
  180. strucIndex += 1;
  181. }
  182. FabricateMissingTypes();
  183. //
  184. // Write out the file
  185. //
  186. WriteThunkSource();
  187. return 0;
  188. }
  189. int
  190. Usage(
  191. VOID
  192. )
  193. /*++
  194. Routine Description:
  195. Displays program usage.
  196. Arguments:
  197. Return value:
  198. --*/
  199. {
  200. fprintf(stderr, "Usage: bldrthnk.exe <32-bit obj> <64-bit obj>\n");
  201. return -1;
  202. }
  203. void
  204. ReadObj(
  205. IN PCHAR Path,
  206. OUT POBJ Obj
  207. )
  208. /*++
  209. Routine Description:
  210. Allocates an appropriate buffer, and reads into it the supplied object
  211. image in its entirety.
  212. Arguments:
  213. Path - Supplies the path of the object image to process.
  214. Obj - Supplies a pointer to an OBJ structure which upon return will
  215. updated with the appropriate data.
  216. Return value:
  217. None.
  218. --*/
  219. {
  220. FILE *objFile;
  221. int result;
  222. long objImageSize;
  223. PCHAR objImage;
  224. PULONG sigPtr;
  225. PULONG srchEnd;
  226. PDEFINITIONS definitions;
  227. LONGLONG imageBias;
  228. //
  229. // Open the file
  230. //
  231. objFile = fopen( Path, "rb" );
  232. CheckCondition( objFile != NULL,
  233. "Cannot open %s for reading.\n",
  234. Path );
  235. //
  236. // Get the file size, allocate a buffer, read it in, and close.
  237. //
  238. result = fseek( objFile, 0, SEEK_END );
  239. CheckCondition( result == 0,
  240. "fseek() failed, error %d\n",
  241. errno );
  242. objImageSize = ftell( objFile );
  243. CheckCondition( objImageSize != -1L,
  244. "ftell() failed, error %d\n",
  245. errno );
  246. CheckCondition( objImageSize > 0,
  247. "%s appears to be corrupt\n",
  248. Path );
  249. objImage = GetMem( objImageSize );
  250. result = fseek( objFile, 0, SEEK_SET );
  251. CheckCondition( result == 0,
  252. "fseek() failed, error %d\n",
  253. errno );
  254. result = fread( objImage, 1, objImageSize, objFile );
  255. CheckCondition( result == objImageSize,
  256. "Error reading from %s\n",
  257. Path );
  258. fclose( objFile );
  259. //
  260. // Find the start of the "definitions" array by looking for
  261. // SIG_1 followed by SIG_2
  262. //
  263. srchEnd = (PULONG)(objImage + objImageSize - 2 * sizeof(SIG_1));
  264. sigPtr = (PULONG)objImage;
  265. definitions = NULL;
  266. while (sigPtr < srchEnd) {
  267. if (sigPtr[0] == SIG_1 && sigPtr[1] == SIG_2) {
  268. definitions = (PDEFINITIONS)sigPtr;
  269. break;
  270. }
  271. sigPtr = (PULONG)((PCHAR)sigPtr + 1);
  272. }
  273. CheckCondition( definitions != NULL,
  274. "Error: could not find signature in %s\n",
  275. Path );
  276. //
  277. // Perform fixups on the image
  278. //
  279. ApplyFixupsToImage( objImage );
  280. //
  281. // Fill in the output structure and return
  282. //
  283. Obj->Image = objImage;
  284. Obj->ImageSize = objImageSize;
  285. Obj->Definitions = definitions;
  286. }
  287. VOID
  288. __cdecl
  289. CheckCondition(
  290. int Condition,
  291. const char *FormatString,
  292. ...
  293. )
  294. /*++
  295. Routine Description:
  296. Asserts that Condition is non-zero. If Condition is zero, FormatString
  297. is processed and displayed, and the program is terminated.
  298. Arguments:
  299. Condition - Supplies the boolean value to evaluate.
  300. FormatString, ... - Supplies the format string and optional parameters
  301. to display in the event of a zero Condition.
  302. Return value:
  303. None.
  304. --*/
  305. {
  306. va_list(arglist);
  307. va_start(arglist, FormatString);
  308. if( Condition == 0 ){
  309. //
  310. // A fatal error was encountered. Bail.
  311. //
  312. vprintf( FormatString, arglist );
  313. perror( "genxx" );
  314. exit(-1);
  315. }
  316. }
  317. BOOL
  318. ProcessStructure(
  319. IN ULONG StrucIndex
  320. )
  321. /*++
  322. Routine Description:
  323. Processes a single pair of structure definitions, 32-bit and 64-bit,
  324. respectively.
  325. Processing includes generating a TYPE_REC and associated FIELD_RECs for
  326. the definition pair.
  327. Arguments:
  328. StrucIndex - Supplies the index into the array of STRUC_DEF structures
  329. found within each of the object images.
  330. Return value:
  331. TRUE if the processing was successful, FALSE otherwise (e.g. a terminating
  332. record was located).
  333. --*/
  334. {
  335. PSTRUC_DEF Struc32, Struc64;
  336. PFIELD_DEF Field32, Field64;
  337. ULONG strLen;
  338. ULONG strLen2;
  339. ULONG strLen3;
  340. PTYPE_REC typeRec;
  341. PFIELD_REC fieldRec;
  342. PFIELD_REC insertNode;
  343. BOOL only64;
  344. ULONG index;
  345. Struc32 = CalcPtr( Obj32.Definitions->Structures[ StrucIndex ] );
  346. Struc64 = CalcPtr( Obj64.Definitions->Structures[ StrucIndex ] );
  347. if (Struc64 == NULL) {
  348. return FALSE;
  349. }
  350. if (Struc32 == NULL) {
  351. only64 = TRUE;
  352. } else {
  353. only64 = FALSE;
  354. }
  355. CheckCondition( Struc64 != NULL &&
  356. ((only64 != FALSE) ||
  357. strcmp( Struc32->Name, Struc64->Name ) == 0),
  358. "Mismatched structure definitions found.\n" );
  359. //
  360. // Allocate and build a TYPE_REC for this STRUC_DEF
  361. //
  362. strLen = strlen( Struc64->Name ) + sizeof(char);
  363. typeRec = GetMem( sizeof(TYPE_REC) + strLen );
  364. typeRec->Name = (PCHAR)(typeRec + 1);
  365. typeRec->Only64 = only64;
  366. memcpy( typeRec->Name, Struc64->Name, strLen );
  367. if (only64 == FALSE) {
  368. typeRec->Size32 = Struc32->Size;
  369. }
  370. typeRec->Size64 = Struc64->Size;
  371. typeRec->FieldList = NULL;
  372. typeRec->SignExtend = FALSE;
  373. typeRec->Fabricated = FALSE;
  374. //
  375. // Create the FIELD_RECs hanging off of this type
  376. //
  377. index = 0;
  378. while (TRUE) {
  379. if (only64 == FALSE) {
  380. Field32 = CalcPtr( Struc32->Fields[index] );
  381. }
  382. Field64 = CalcPtr( Struc64->Fields[index] );
  383. if (Field64 == NULL) {
  384. break;
  385. }
  386. if (only64 == FALSE) {
  387. CheckCondition( strcmp( Field32->Name, Field64->Name ) == 0 &&
  388. strcmp( Field32->TypeName, Field64->TypeName ) == 0,
  389. "Mismatched structure definitions found.\n" );
  390. }
  391. strLen = strlen( Field64->Name ) + sizeof(CHAR);
  392. strLen2 = strlen( Field64->TypeName ) + sizeof(CHAR);
  393. strLen3 = strlen( Field64->SizeFormula );
  394. if (strLen3 > 0) {
  395. strLen3 += sizeof(CHAR);
  396. }
  397. fieldRec = GetMem( sizeof(FIELD_REC) + strLen + strLen2 + strLen3 );
  398. fieldRec->Name = (PCHAR)(fieldRec + 1);
  399. fieldRec->TypeName = fieldRec->Name + strLen;
  400. memcpy( fieldRec->Name, Field64->Name, strLen );
  401. memcpy( fieldRec->TypeName, Field64->TypeName, strLen2 );
  402. if (strLen3 > 0) {
  403. fieldRec->SizeFormula = fieldRec->TypeName + strLen2;
  404. memcpy( fieldRec->SizeFormula, Field64->SizeFormula, strLen3 );
  405. } else {
  406. fieldRec->SizeFormula = NULL;
  407. }
  408. if (only64 == FALSE) {
  409. fieldRec->Offset32 = Field32->Offset;
  410. fieldRec->Size32 = Field32->Size;
  411. fieldRec->TypeSize32 = Field32->TypeSize;
  412. }
  413. fieldRec->Offset64 = Field64->Offset;
  414. fieldRec->TypeSize64 = Field64->TypeSize;
  415. fieldRec->Size64 = Field64->Size;
  416. fieldRec->Next = NULL;
  417. fieldRec->TypeRec = NULL;
  418. //
  419. // Insert at the end of the list
  420. //
  421. insertNode = CONTAINING_RECORD( &typeRec->FieldList,
  422. FIELD_REC,
  423. Next );
  424. while (insertNode->Next != NULL) {
  425. insertNode = insertNode->Next;
  426. }
  427. insertNode->Next = fieldRec;
  428. index += 1;
  429. }
  430. //
  431. // Insert it into the global list
  432. //
  433. CheckCondition( FindTypeRec( typeRec->Name ) == NULL,
  434. "Duplicate definition for structure %s\n",
  435. typeRec->Name );
  436. NewGlobalType( typeRec );
  437. return TRUE;
  438. }
  439. PTYPE_REC
  440. FindTypeRec(
  441. IN PCHAR Name
  442. )
  443. /*++
  444. Routine Description:
  445. Searches the global list of TYPE_REC structures for one with a name
  446. that matches the supplied name.
  447. Arguments:
  448. Name - pointer to a null-terminated string representing the name of
  449. the sought type.
  450. Return value:
  451. A pointer to the matching TYPE_REC, or NULL if a match was not found.
  452. --*/
  453. {
  454. PTYPE_REC typeRec;
  455. typeRec = TypeRecList;
  456. while (typeRec != NULL) {
  457. if (strcmp( Name, typeRec->Name ) == 0) {
  458. return typeRec;
  459. }
  460. typeRec = typeRec->Next;
  461. }
  462. return NULL;
  463. }
  464. PVOID
  465. GetMem(
  466. IN ULONG Size
  467. )
  468. /*++
  469. Routine Description:
  470. Memory allocator. Works just like malloc() except that triggers a
  471. fatal error in the event of an out-of-memory condition.
  472. Arguments:
  473. Size - number of bytes to allocate.
  474. Return value:
  475. Returns a pointer to a block of memory of the specified size.
  476. --*/
  477. {
  478. PVOID mem;
  479. mem = malloc( Size );
  480. CheckCondition( mem != NULL,
  481. "Out of memory.\n" );
  482. return mem;
  483. }
  484. VOID
  485. FabricateMissingTypes(
  486. VOID
  487. )
  488. /*++
  489. Routine Description:
  490. Routine to generate TYPE_REC records for simple types referenced, but
  491. not defined, by a structure layout file.
  492. Arguments:
  493. None.
  494. Return value:
  495. None.
  496. --*/
  497. {
  498. PTYPE_REC typeRec;
  499. PTYPE_REC fieldTypeRec;
  500. PFIELD_REC fieldRec;
  501. PCHAR fieldTypeName;
  502. ULONG strLen;
  503. typeRec = TypeRecList;
  504. while (typeRec != NULL) {
  505. fieldRec = typeRec->FieldList;
  506. while (fieldRec != NULL) {
  507. fieldTypeRec = FindTypeRec( fieldRec->TypeName );
  508. if (fieldTypeRec == NULL) {
  509. if (typeRec->Only64 == FALSE) {
  510. CheckCondition( (fieldRec->Size32 == fieldRec->Size64) ||
  511. ((fieldRec->Size32 == 1 ||
  512. fieldRec->Size32 == 2 ||
  513. fieldRec->Size32 == 4 ||
  514. fieldRec->Size32 == 8) &&
  515. (fieldRec->Size64 > fieldRec->Size32) &&
  516. (fieldRec->Size64 % fieldRec->Size32 == 0)),
  517. "Must specify type %s (%s)\n",
  518. fieldRec->TypeName,
  519. typeRec->Name );
  520. }
  521. //
  522. // No typerec exists for this type. Assume it is a simple
  523. // type.
  524. //
  525. if ((typeRec->Only64 != FALSE &&
  526. fieldRec->Size64 == sizeof(ULONGLONG) &&
  527. *fieldRec->TypeName == 'P') ||
  528. (fieldRec->Size32 == sizeof(PVOID) &&
  529. fieldRec->Size64 == sizeof(ULONGLONG))) {
  530. //
  531. // Either a pointer or [U]LONG_PTR type. Make
  532. // it longlong.
  533. //
  534. fieldTypeRec = &pointer64_typerec;
  535. } else {
  536. //
  537. // Some other type.
  538. //
  539. strLen = strlen( fieldRec->TypeName ) + sizeof(CHAR);
  540. fieldTypeRec = GetMem( sizeof(TYPE_REC) + strLen );
  541. fieldTypeRec->Name = (PCHAR)(fieldTypeRec + 1);
  542. memcpy( fieldTypeRec->Name, fieldRec->TypeName, strLen );
  543. fieldTypeRec->Size32 = fieldRec->Size32;
  544. fieldTypeRec->Size64 = fieldRec->Size64;
  545. fieldTypeRec->FieldList = NULL;
  546. fieldTypeRec->SignExtend = TRUE;
  547. fieldTypeRec->Fabricated = TRUE;
  548. NewGlobalType( fieldTypeRec );
  549. }
  550. }
  551. fieldRec->TypeRec = fieldTypeRec;
  552. fieldRec = fieldRec->Next;
  553. }
  554. typeRec = typeRec->Next;
  555. }
  556. }
  557. VOID
  558. WriteCopyRecord(
  559. IN ULONG Offset32,
  560. IN ULONG Offset64,
  561. IN PCHAR TypeName,
  562. IN ULONG Size32,
  563. IN ULONG Size64,
  564. IN BOOL SignExtend,
  565. IN PCHAR FieldName,
  566. IN BOOL Last
  567. )
  568. /*++
  569. Routine Description:
  570. Support routine to generate the text of a copy record.
  571. Arguments:
  572. Offset32 - Offset of this field within a 32-bit structure layout
  573. Offset64 - Offset of this field within a 64-bit structure layout
  574. Size32 - Size of this field within a 32-bit structure layout
  575. Size64 - Size of this field within a 64-bit structure layout
  576. SignExtend - Indicates whether this type should be sign extended or not
  577. FieldName - Name of the field
  578. Last - Whether this is the last copy record in a zero-terminated list
  579. Return value:
  580. None
  581. --*/
  582. {
  583. CHAR buf[ 255 ];
  584. buf[sizeof(buf) - 1] = 0;
  585. if (SignExtend) {
  586. _snprintf(buf, sizeof(buf) - 1, "IS_SIGNED_TYPE(%s)", TypeName);
  587. } else {
  588. _snprintf(buf, sizeof(buf) - 1, "FALSE");
  589. }
  590. printf(" { \t0x%x, \t0x%x, \t0x%x, \t0x%x, \t%5s }%s\n",
  591. Offset32,
  592. Offset64,
  593. Size32,
  594. Size64,
  595. buf,
  596. Last ? "" : "," );
  597. }
  598. VOID
  599. WriteDefinition64(
  600. IN PTYPE_REC TypeRec
  601. )
  602. /*++
  603. Routine Description:
  604. Generates a structure definition that represents, to a 32-bit compiler,
  605. the layout of a 64-bit structure.
  606. Arguments:
  607. TypeRec - Pointer to the TYPE_REC structure defining this type.
  608. Return value:
  609. None.
  610. --*/
  611. {
  612. PFIELD_REC fieldRec;
  613. ULONG currentOffset;
  614. PTYPE_REC fieldTypeRec;
  615. ULONG padBytes;
  616. ULONG reservedCount;
  617. currentOffset = 0;
  618. reservedCount = 0;
  619. printf("typedef struct _%s_64 {\n", TypeRec->Name );
  620. fieldRec = TypeRec->FieldList;
  621. while (fieldRec != NULL) {
  622. fieldTypeRec = fieldRec->TypeRec;
  623. padBytes = fieldRec->Offset64 - currentOffset;
  624. if (padBytes > 0) {
  625. printf(" UCHAR Reserved%d[ 0x%x ];\n",
  626. reservedCount,
  627. padBytes );
  628. currentOffset += padBytes;
  629. reservedCount += 1;
  630. }
  631. printf(" %s%s %s",
  632. fieldTypeRec->Name,
  633. fieldTypeRec->Fabricated ? "" : "_64",
  634. fieldRec->Name );
  635. if (fieldRec->Size64 > fieldRec->TypeSize64) {
  636. CheckCondition( fieldRec->Size64 % fieldRec->TypeSize64 == 0,
  637. "Internal error type %s.%s\n",
  638. TypeRec->Name, fieldRec->Name );
  639. //
  640. // This field must be an array
  641. //
  642. printf("[%d]", fieldRec->Size64 / fieldRec->TypeSize64);
  643. }
  644. printf(";\n");
  645. currentOffset += fieldRec->Size64;
  646. fieldRec = fieldRec->Next;
  647. }
  648. padBytes = TypeRec->Size64 - currentOffset;
  649. if (padBytes > 0) {
  650. printf(" UCHAR Reserved%d[ 0x%x ];\n", reservedCount, padBytes );
  651. currentOffset += padBytes;
  652. reservedCount += 1;
  653. }
  654. printf("} %s_64, *P%s_64;\n\n", TypeRec->Name, TypeRec->Name );
  655. fieldRec = TypeRec->FieldList;
  656. while (fieldRec != NULL) {
  657. fieldTypeRec = fieldRec->TypeRec;
  658. printf("C_ASSERT( FIELD_OFFSET(%s_64,%s) == 0x%x);\n",
  659. TypeRec->Name,
  660. fieldRec->Name,
  661. fieldRec->Offset64);
  662. fieldRec = fieldRec->Next;
  663. }
  664. printf("\n");
  665. }
  666. VOID
  667. WriteCopyList(
  668. IN PTYPE_REC TypeRec
  669. )
  670. /*++
  671. Routine Description:
  672. Generates the list of copy records necessary to copy the contents of
  673. each of the fields with TypeRec from their 32-bit layout to their
  674. 64-bit layout.
  675. Arguments:
  676. TypeRec - Pointer to the TYPE_REC structure that defines this type.
  677. Return value:
  678. None.
  679. --*/
  680. {
  681. PFIELD_REC fieldRec;
  682. printf("COPY_REC cr3264_%s[] = {\n", TypeRec->Name);
  683. WriteCopyListWorker( TypeRec, 0, 0, NULL );
  684. WriteCopyRecord( 0,0,NULL,0,0,FALSE,NULL,TRUE );
  685. printf("};\n\n");
  686. }
  687. VOID
  688. WriteCopyListWorker(
  689. IN PTYPE_REC TypeRec,
  690. IN ULONG Offset32,
  691. IN ULONG Offset64,
  692. IN PCHAR ParentName
  693. )
  694. /*++
  695. Routine Description:
  696. Recursively-called support routine for WriteCopyList. This routine
  697. generates a copy record if this type is not composed of child types,
  698. otherwise it calls itself recursively for each child type.
  699. Arguments:
  700. TypeRec - Pointer to the definition of the type to process.
  701. Offset32 - Current offset within the master structure being defined.
  702. Offset64 - Current offset within the master structure being defined.
  703. ParentName - Not currently used.
  704. Return value:
  705. None.
  706. --*/
  707. {
  708. PFIELD_REC fieldRec;
  709. PTYPE_REC typeRec;
  710. CHAR fieldName[ 255 ];
  711. PCHAR fieldStart;
  712. int result = 0;
  713. fieldName[sizeof(fieldName) - 1] = 0;
  714. fieldRec = TypeRec->FieldList;
  715. if (fieldRec == NULL) {
  716. WriteCopyRecord( Offset32,
  717. Offset64,
  718. TypeRec->Name,
  719. TypeRec->Size32,
  720. TypeRec->Size64,
  721. TypeRec->SignExtend,
  722. ParentName,
  723. FALSE );
  724. } else {
  725. //
  726. // Build the field name
  727. //
  728. if (ParentName != NULL) {
  729. //strcpy( fieldName, ParentName);
  730. //strcat( fieldName, "." );
  731. result = _snprintf(fieldName, sizeof(fieldName) - 1,
  732. "%s.", ParentName);
  733. if (result < 0) {
  734. //
  735. // Not much we can do
  736. //
  737. return;
  738. }
  739. } else {
  740. fieldName[0] = '\0';
  741. }
  742. fieldStart = &fieldName[ strlen(fieldName) ];
  743. do {
  744. strncpy( fieldStart, fieldRec->Name, sizeof(fieldName) - 1 - result );
  745. // typeRec = FindTypeRec( fieldRec->TypeName );
  746. typeRec = fieldRec->TypeRec;
  747. WriteCopyListWorker( typeRec,
  748. fieldRec->Offset32 + Offset32,
  749. fieldRec->Offset64 + Offset64,
  750. fieldName );
  751. fieldRec = fieldRec->Next;
  752. } while (fieldRec != NULL);
  753. }
  754. }
  755. VOID
  756. WriteBufferCopies(
  757. IN PTYPE_REC TypeRec,
  758. IN PCHAR StrucName
  759. )
  760. {
  761. PFIELD_REC fieldRec;
  762. PTYPE_REC typeRec;
  763. CHAR strucName[ 255 ];
  764. CHAR sizeFormula[ 255 ];
  765. PCHAR fieldPos;
  766. PCHAR src;
  767. PCHAR dst;
  768. int result;
  769. ULONG remainingLength;
  770. if (TypeRec == NULL) {
  771. return;
  772. }
  773. strucName[sizeof(strucName) - 1] = 0;
  774. sizeFormula[sizeof(sizeFormula) - 1] = 0;
  775. strncpy(strucName,StrucName,sizeof(strucName) - 2 );
  776. if (*StrucName != '\0') {
  777. strcat(strucName,".");
  778. }
  779. fieldPos = &strucName[ strlen(strucName) ];
  780. fieldRec = TypeRec->FieldList;
  781. while (fieldRec != NULL) {
  782. strncpy(fieldPos,fieldRec->Name,sizeof(strucName) - 1 - strlen(strucName));
  783. if (fieldRec->SizeFormula != NULL) {
  784. //
  785. // Perform substitution on the size formula
  786. //
  787. dst = sizeFormula;
  788. src = fieldRec->SizeFormula;
  789. remainingLength = sizeof(sizeFormula) - 1;
  790. do {
  791. if (*src == '%' &&
  792. *(src+1) == '1') {
  793. result = _snprintf(dst,
  794. remainingLength,
  795. "Source->%s%s",
  796. StrucName,
  797. *StrucName == '\0' ? "" : ".");
  798. if (result < 0) {
  799. //
  800. // Not much we can do here...
  801. //
  802. break;
  803. } else {
  804. dst += result;
  805. remainingLength -= result;
  806. }
  807. src += 2;
  808. } else {
  809. *dst++ = *src++;
  810. }
  811. } while (*src != '\0');
  812. *dst = '\0';
  813. printf("\n"
  814. " status = \n"
  815. " CopyBuf( Source->%s,\n"
  816. " &Destination->%s,\n"
  817. " %s );\n"
  818. " if (status != ESUCCESS) {\n"
  819. " return status;\n"
  820. " }\n",
  821. strucName,
  822. strucName,
  823. sizeFormula);
  824. }
  825. typeRec = fieldRec->TypeRec;
  826. WriteBufferCopies( typeRec, strucName );
  827. fieldRec = fieldRec->Next;
  828. }
  829. }
  830. VOID
  831. WriteThunkSource(
  832. VOID
  833. )
  834. /*++
  835. Routine Description:
  836. Generates the source code and supporting definitions necessary to
  837. copy all or portions of the contents of 32-bit structures to the
  838. equivalent 64-bit layout.
  839. Arguments:
  840. None.
  841. Return value:
  842. None.
  843. --*/
  844. {
  845. PTYPE_REC typeRec;
  846. printf("//\n");
  847. printf("// Autogenerated file, do not edit\n");
  848. printf("//\n\n");
  849. printf("#include <bldrthnk.h>\n\n");
  850. printf("#pragma warning(disable:4296)\n\n");
  851. //
  852. // Output the 64-bit type definitions
  853. //
  854. printf("#pragma pack(push,1)\n\n");
  855. typeRec = TypeRecList;
  856. while (typeRec != NULL) {
  857. if (typeRec->Fabricated == FALSE) {
  858. WriteDefinition64( typeRec );
  859. }
  860. typeRec = typeRec->Next;
  861. }
  862. printf("#pragma pack(pop)\n\n");
  863. //
  864. // Output the copy records
  865. //
  866. typeRec = TypeRecList;
  867. while (typeRec != NULL) {
  868. if (typeRec->Only64 == FALSE &&
  869. typeRec->Fabricated == FALSE) {
  870. WriteCopyList( typeRec );
  871. }
  872. typeRec = typeRec->Next;
  873. }
  874. //
  875. // Generate the copy routines
  876. //
  877. typeRec = TypeRecList;
  878. while (typeRec != NULL) {
  879. if (typeRec->Only64 == FALSE &&
  880. typeRec->Fabricated == FALSE) {
  881. WriteCopyRoutine( typeRec );
  882. }
  883. typeRec = typeRec->Next;
  884. }
  885. printf("\n");
  886. }
  887. VOID
  888. WriteCopyRoutine(
  889. IN PTYPE_REC TypeRec
  890. )
  891. /*++
  892. Routine Description:
  893. Generates text that implements a function to copy the contents of a
  894. structure of the specified type from a 32-bit layout to a 64-bit
  895. layout.
  896. Arguments:
  897. TypeRec - Pointer to the type for which the function should be generated.
  898. Return value:
  899. None.
  900. --*/
  901. {
  902. PCHAR typeName;
  903. typeName = TypeRec->Name;
  904. printf("\n"
  905. "ARC_STATUS\n"
  906. "__inline\n"
  907. "static\n"
  908. "Copy_%s(\n"
  909. " IN %s *Source,\n"
  910. " OUT %s_64 *Destination\n"
  911. " )\n"
  912. "{\n"
  913. " ARC_STATUS status = ESUCCESS;"
  914. "\n"
  915. " DbgPrint(\"BLAMD64: Copy %s->%s_64 (0x%%08x->0x%%08x)\\n\",\n"
  916. " (ULONG)Source, (ULONG)Destination );\n"
  917. "\n"
  918. " CopyRec( Source, Destination, cr3264_%s );\n",
  919. typeName,
  920. typeName,
  921. typeName,
  922. typeName,
  923. typeName,
  924. typeName );
  925. WriteBufferCopies( TypeRec, "" );
  926. printf(" return status;\n");
  927. printf("}\n\n");
  928. }
  929. VOID
  930. ApplyFixupsToImage(
  931. IN PCHAR ObjImage
  932. )
  933. /*++
  934. Routine Description:
  935. Processes fixup records found within an object image.
  936. Arguments:
  937. Pointer to a buffer containing the entire image.
  938. Return value:
  939. None.
  940. --*/
  941. {
  942. //
  943. // Applies fixups to the OBJ image loaded at ObjImage
  944. //
  945. PIMAGE_FILE_HEADER fileHeader;
  946. PIMAGE_SECTION_HEADER sectionHeader;
  947. PIMAGE_SECTION_HEADER sectionHeaderArray;
  948. PIMAGE_SYMBOL symbolTable;
  949. PIMAGE_SYMBOL symbol;
  950. PIMAGE_RELOCATION reloc;
  951. PIMAGE_RELOCATION relocArray;
  952. ULONG sectionNum;
  953. ULONG relocNum;
  954. ULONG_PTR targetVa;
  955. PULONG_PTR fixupVa;
  956. fileHeader = (PIMAGE_FILE_HEADER)ObjImage;
  957. //
  958. // We need the symbol table to apply the fixups
  959. //
  960. symbolTable = (PIMAGE_SYMBOL)(ObjImage +
  961. fileHeader->PointerToSymbolTable);
  962. //
  963. // Get a pointer to the first element in the section header
  964. //
  965. sectionHeaderArray = (PIMAGE_SECTION_HEADER)(ObjImage +
  966. sizeof( IMAGE_FILE_HEADER ) +
  967. fileHeader->SizeOfOptionalHeader);
  968. //
  969. // Apply the fixups for each section
  970. //
  971. for( sectionNum = 0;
  972. sectionNum < fileHeader->NumberOfSections;
  973. sectionNum++ ){
  974. sectionHeader = &sectionHeaderArray[ sectionNum ];
  975. //
  976. // Apply each fixup in this section
  977. //
  978. relocArray = (PIMAGE_RELOCATION)(ObjImage +
  979. sectionHeader->PointerToRelocations);
  980. for( relocNum = 0;
  981. relocNum < sectionHeader->NumberOfRelocations;
  982. relocNum++ ){
  983. reloc = &relocArray[ relocNum ];
  984. //
  985. // The relocation gives us the position in the image of the
  986. // relocation modification (VirtualAddress). To find out what
  987. // to put there, we have to look the symbol up in the symbol index.
  988. //
  989. symbol = &symbolTable[ reloc->SymbolTableIndex ];
  990. targetVa =
  991. sectionHeaderArray[ symbol->SectionNumber-1 ].PointerToRawData;
  992. targetVa += symbol->Value;
  993. targetVa += (ULONG_PTR)ObjImage;
  994. fixupVa = (PULONG_PTR)(ObjImage +
  995. reloc->VirtualAddress +
  996. sectionHeader->PointerToRawData );
  997. *fixupVa = targetVa;
  998. }
  999. }
  1000. }
  1001. VOID
  1002. NewGlobalType(
  1003. IN PTYPE_REC TypeRec
  1004. )
  1005. /*++
  1006. Routine Description:
  1007. Inserts a new TYPE_REC structure at the end of the global TYPE_REC
  1008. list.
  1009. Arguments:
  1010. TypeRec - Pointer to the TYPE_REC structure to insert.
  1011. Return value:
  1012. None.
  1013. --*/
  1014. {
  1015. PTYPE_REC insertNode;
  1016. insertNode = CONTAINING_RECORD( &TypeRecList,
  1017. TYPE_REC,
  1018. Next );
  1019. while (insertNode->Next != NULL) {
  1020. insertNode = insertNode->Next;
  1021. }
  1022. insertNode->Next = TypeRec;
  1023. TypeRec->Next = NULL;
  1024. }