Source code of Windows XP (NT5)
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.

562 lines
13 KiB

  1. #include <windows.h>
  2. #include <insignia.h>
  3. #include <host_def.h>
  4. /* Forced manually here for standalone variant of LCIF generator */
  5. #define WITHSIZE
  6. #define STAND_ALONE
  7. /*[
  8. * Name: dat2obj.c
  9. * Author: Jerry Sexton (based on William Roberts' version for RS6000)
  10. * SCCS ID:
  11. *
  12. * Created: 7/12/93
  13. *
  14. * Purpose:
  15. * Convert thread.dat and online.dat into object files.
  16. * Called from onGen.
  17. *
  18. * The input & output files will be found in SRC_OUT_DIR, which may be
  19. * overridden using the GENERATOR_OUTPUT_DIRECTORY mechansim.
  20. *
  21. * (C) Copyright Insignia Solutions Ltd., 1993.
  22. ]*/
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. //#include "gen_file.h"
  27. //#include "host_clo.h"
  28. /* Local defines. */
  29. #define SYMSIZE sizeof(syms[0])
  30. #define AUXSIZE sizeof(aux[0])
  31. #define SECNAME ".data\0\0\0"
  32. #ifdef STAND_ALONE
  33. /* Variables needed for stand-alone version. */
  34. LOCAL FILE *out_file;
  35. #endif /* STAND_ALONE */
  36. /*
  37. * machineStrings and machineIds - valid environment strings and corresponding
  38. * machine ID's. The two arrays must be edited in tandem.
  39. */
  40. LOCAL CHAR *machineStrings[] =
  41. {
  42. "I860",
  43. "I386",
  44. "R3000",
  45. "R4000",
  46. "ALPHA",
  47. "POWERPC",
  48. "HPPA"
  49. };
  50. LOCAL IU16 machineIds[] =
  51. {
  52. #ifdef IMAGE_FILE_MACHINE_I860
  53. IMAGE_FILE_MACHINE_I860,
  54. #else
  55. 0xAAA,
  56. #endif
  57. IMAGE_FILE_MACHINE_I386,
  58. IMAGE_FILE_MACHINE_R3000,
  59. IMAGE_FILE_MACHINE_R4000,
  60. IMAGE_FILE_MACHINE_ALPHA,
  61. #ifdef IMAGE_FILE_MACHINE_POWERPC
  62. IMAGE_FILE_MACHINE_POWERPC,
  63. #else
  64. 0x1F0,
  65. #endif
  66. 0x290 /* HPPA currently has no define in ntimage.h */
  67. };
  68. #define MC_TAB_SIZE (sizeof(machineIds) / sizeof(machineIds[0]))
  69. LOCAL IBOOL cUnderscore; /* Does target precede symbols with '_'. */
  70. #ifdef STAND_ALONE
  71. /*(
  72. =============================== open_gen_file ==============================
  73. PURPOSE:
  74. Open output file if running stand alone.
  75. INPUT:
  76. file - output file path.
  77. OUTPUT:
  78. None.
  79. ============================================================================
  80. )*/
  81. LOCAL void open_gen_file IFN1(CHAR *, file)
  82. {
  83. out_file = fopen(file, "wb");
  84. if (out_file == NULL)
  85. {
  86. printf("Could not open %s for writing.\n", out_file);
  87. exit(-1);
  88. }
  89. }
  90. /*(
  91. ============================== close_gen_file ==============================
  92. PURPOSE:
  93. Closes the output file if runnong stand-alone.
  94. INPUT:
  95. None.
  96. OUTPUT:
  97. None.
  98. ============================================================================
  99. )*/
  100. LOCAL void close_gen_file IFN0()
  101. {
  102. fclose(out_file);
  103. }
  104. /*(
  105. ============================== abort_gen_file ==============================
  106. PURPOSE:
  107. Aborts output if running stand-alone.
  108. INPUT:
  109. None.
  110. OUTPUT:
  111. None.
  112. ============================================================================
  113. )*/
  114. LOCAL void abort_gen_file IFN0()
  115. {
  116. printf("Output aborted.\n");
  117. fclose(out_file);
  118. exit(-1);
  119. }
  120. #endif /* STAND_ALONE */
  121. /*(
  122. =============================== getMachineId ===============================
  123. PURPOSE:
  124. Get the machine ID field either from the environment or compiler
  125. defines.
  126. INPUT:
  127. None.
  128. OUTPUT:
  129. A 16-bit machine ID.
  130. ============================================================================
  131. )*/
  132. LOCAL IU16 getMachineId IFN0()
  133. {
  134. CHAR *mcstr,
  135. *end;
  136. IU32 i,
  137. val;
  138. IU16 machineId = IMAGE_FILE_MACHINE_UNKNOWN;
  139. IBOOL gotMachineId = FALSE;
  140. /*
  141. * Order of priority is (highest priority first):
  142. *
  143. * COFF_MACHINE_ID environment variable, which can be a machine
  144. * string (see machineStrings for valid strings) or a hex number.
  145. *
  146. * Machine type defined by compiler.
  147. *
  148. * Unknown machine type.
  149. */
  150. /* See if an environmenet variable is set. */
  151. mcstr = getenv("COFF_MACHINE_ID");
  152. if (mcstr != NULL)
  153. {
  154. /* Check for a valid machine string. */
  155. for (i = 0; i < MC_TAB_SIZE; i++)
  156. {
  157. if (strcmp(mcstr, machineStrings[i]) == 0)
  158. break;
  159. }
  160. if (i < MC_TAB_SIZE)
  161. {
  162. /* Got a valid string. */
  163. machineId = machineIds[i];
  164. gotMachineId = TRUE;
  165. }
  166. else
  167. {
  168. /* Is environment variable a 16-bit hex number? */
  169. val = strtoul(mcstr, &end, 16);
  170. if ((*end == '\0') && (val < 0x10000))
  171. {
  172. machineId = (IU16) val;
  173. gotMachineId = TRUE;
  174. }
  175. }
  176. /* If environment variable not valid print possibilities. */
  177. if (!gotMachineId)
  178. {
  179. printf("\n=========================================\n");
  180. printf("COFF_MACHINE_ID=%s invalid\n", mcstr);
  181. printf("Valid strings are -\n");
  182. for (i = 0; i < MC_TAB_SIZE; i++)
  183. printf("\t%s\n", machineStrings[i]);
  184. printf("\n\tOR\n");
  185. printf("\n\tA 16-bit hexadecimal number\n");
  186. printf("=========================================\n\n");
  187. }
  188. }
  189. /*
  190. * Get the default machine type according to predefined compiler
  191. * defines.
  192. */
  193. if (!gotMachineId)
  194. {
  195. #ifdef _X86_
  196. machineId = IMAGE_FILE_MACHINE_I386;
  197. #endif /* _X86_ */
  198. #ifdef _MIPS_
  199. machineId = IMAGE_FILE_MACHINE_R4000;
  200. #endif /* _MIPS_ */
  201. #ifdef _PPC_
  202. machineId = IMAGE_FILE_MACHINE_POWERPC;
  203. #endif /* _PPC_ */
  204. #ifdef ALPHA
  205. machineId = IMAGE_FILE_MACHINE_ALPHA;
  206. #endif /* ALPHA */
  207. /* Empty brace if none of the above are defined. */
  208. }
  209. #ifndef PROD
  210. printf("machineId = %#x\n", machineId);
  211. #endif /* PROD */
  212. return(machineId);
  213. }
  214. /*(
  215. ============================== getDatFileSize ==============================
  216. PURPOSE:
  217. Get the size of a data file.
  218. INPUT:
  219. infilepath - path to input file
  220. len - address of variable to hold length
  221. OUTPUT:
  222. TRUE if length was successfully found,
  223. FALSE otherwise.
  224. ============================================================================
  225. )*/
  226. LOCAL IBOOL getDatFileSize IFN2(CHAR *, infilepath, IU32 *, len)
  227. {
  228. HANDLE hInFile;
  229. DWORD fileLen;
  230. /* Get file size. */
  231. hInFile = CreateFile(infilepath,
  232. GENERIC_READ,
  233. (DWORD) 0,
  234. (LPSECURITY_ATTRIBUTES) NULL,
  235. OPEN_EXISTING,
  236. (DWORD) 0,
  237. (HANDLE) NULL);
  238. if (hInFile != INVALID_HANDLE_VALUE)
  239. fileLen = GetFileSize(hInFile, (LPDWORD) NULL);
  240. if ((hInFile == INVALID_HANDLE_VALUE) || (fileLen == 0xffffffff))
  241. {
  242. printf("Cannot get size of %s\n", infilepath);
  243. return(FALSE);
  244. }
  245. if (CloseHandle(hInFile) == FALSE)
  246. {
  247. printf("CloseHandle on %s failed.\n", infilepath);
  248. return(FALSE);
  249. }
  250. *len = (IU32) fileLen;
  251. return(TRUE);
  252. }
  253. /*(
  254. ================================= dat2obj ==================================
  255. PURPOSE:
  256. Produce a COFF object file from an input data file.
  257. INPUT:
  258. label - data label name
  259. datfile - data file name
  260. machineId - 16-bit machine ID stamp
  261. OUTPUT:
  262. None.
  263. ============================================================================
  264. )*/
  265. LOCAL void dat2obj IFN3(char *, label, char *, datfile, IU16, machineId)
  266. {
  267. IMAGE_FILE_HEADER fhdr;
  268. IMAGE_SECTION_HEADER shdr;
  269. IMAGE_SYMBOL syms[2];
  270. IMAGE_AUX_SYMBOL aux[2];
  271. IU32 padding = 4;
  272. CHAR labname[9]; /* 8 chars+terminator */
  273. CHAR outfilename[11]; /* 8 chars+".o"+terminator */
  274. CHAR infilepath[256];
  275. CHAR buffer[BUFSIZ];
  276. IU32 len,
  277. count;
  278. IS32 i;
  279. FILE *infile;
  280. if (cUnderscore)
  281. {
  282. labname[0] = '_';
  283. strncpy(&labname[1], label, 7); /* will be padded with zeros */
  284. }
  285. else
  286. {
  287. strncpy(labname, label, 8); /* will be padded with zeros */
  288. }
  289. labname[8] = '\0';
  290. sprintf(outfilename, "%s.obj", label);
  291. sprintf(infilepath, "%s", datfile);
  292. /* Get file size. */
  293. if (getDatFileSize(infilepath, &len) == FALSE)
  294. return;
  295. /* construct the various headers */
  296. fhdr.Machine = machineId;
  297. fhdr.NumberOfSections = 1; /* .text */
  298. fhdr.TimeDateStamp = 0; /* no timestamps here */
  299. #ifdef WITHSIZE
  300. /* We add the length of the input file for test purposes. */
  301. fhdr.PointerToSymbolTable = sizeof(fhdr) + sizeof(shdr) + sizeof(len) +
  302. len;
  303. #else
  304. fhdr.PointerToSymbolTable = sizeof(fhdr) + sizeof(shdr) + len;
  305. #endif /* WITHSIZE */
  306. fhdr.NumberOfSymbols = 3; /* Section + Aux. + Label */
  307. fhdr.SizeOfOptionalHeader = 0; /* no optional headers */
  308. fhdr.Characteristics =
  309. IMAGE_FILE_LINE_NUMS_STRIPPED | /* No line numbers. */
  310. IMAGE_FILE_32BIT_MACHINE; /* 32 bit word. */
  311. /* no optional header */
  312. memcpy(shdr.Name, SECNAME, 8);
  313. shdr.Misc.PhysicalAddress = 0;
  314. shdr.VirtualAddress = 0;
  315. #ifdef WITHSIZE
  316. /* We add the length of the input file for test purposes. */
  317. shdr.SizeOfRawData = sizeof(len) + len;
  318. #else
  319. shdr.SizeOfRawData = len; /* assumed a multiple of 4 */
  320. #endif /* WITHSIZE */
  321. shdr.PointerToRawData = sizeof(fhdr) + sizeof(shdr);
  322. shdr.PointerToRelocations = 0; /* no relocation information */
  323. shdr.PointerToLinenumbers = 0; /* no line number information */
  324. shdr.NumberOfRelocations = 0;
  325. shdr.NumberOfLinenumbers = 0;
  326. shdr.Characteristics =
  327. IMAGE_SCN_CNT_INITIALIZED_DATA | /* Initialized data. */
  328. IMAGE_SCN_ALIGN_4BYTES | /* Align4. */
  329. IMAGE_SCN_MEM_READ | /* Read. */
  330. IMAGE_SCN_MEM_WRITE; /* Write. */
  331. /* 1st symbol. */
  332. memcpy(syms[0].N.ShortName, SECNAME, 8);
  333. syms[0].Value = 0;
  334. syms[0].SectionNumber = 1; /* first section */
  335. syms[0].Type = 0; /* notype */
  336. syms[0].StorageClass = IMAGE_SYM_CLASS_STATIC; /* static */
  337. syms[0].NumberOfAuxSymbols = 1;
  338. /* 1st symbol auxiliary. */
  339. #ifdef WITHSIZE
  340. /* We add the length of the input file for test purposes. */
  341. aux[0].Section.Length = sizeof(len) + len;
  342. #else
  343. aux[0].Section.Length = len;
  344. #endif /* WITHSIZE */
  345. aux[0].Section.NumberOfRelocations = 0;
  346. aux[0].Section.NumberOfLinenumbers = 0;
  347. aux[0].Section.CheckSum = 0;
  348. aux[0].Section.Number = 0;
  349. aux[0].Section.Selection = 0;
  350. /* 2nd symbol. */
  351. memcpy(syms[1].N.ShortName, labname, 8);
  352. syms[1].Value = 0;
  353. syms[1].SectionNumber = 1;
  354. syms[1].Type = 0;
  355. syms[1].StorageClass = IMAGE_SYM_CLASS_EXTERNAL;
  356. syms[1].NumberOfAuxSymbols = 0;
  357. infile = fopen(infilepath, "rb");
  358. if (infile == NULL) {
  359. printf("Unable to open %s for reading\n", infilepath);
  360. perror(infilepath);
  361. return;
  362. }
  363. open_gen_file(outfilename);
  364. if (out_file == stderr) {
  365. return;
  366. }
  367. /* Write file header. */
  368. fwrite(&fhdr, sizeof(fhdr), 1, out_file);
  369. /* Write section header. */
  370. fwrite(&shdr, sizeof(shdr), 1, out_file);
  371. #ifdef WITHSIZE
  372. /* Write size of file for test purposes. */
  373. fwrite(&len, sizeof(len), 1, out_file);
  374. #endif /* WITHSIZE */
  375. /* Write data. */
  376. count = 0;
  377. do {
  378. i = fread(buffer, 1, sizeof(buffer), infile);
  379. if (i < 0) {
  380. fprintf(stderr, "problem reading %s\n", infilepath);
  381. perror(infilepath);
  382. abort_gen_file();
  383. }
  384. fwrite(buffer, i, 1, out_file);
  385. count += i;
  386. } while (i > 0 && count < len);
  387. /* Write first symbol. */
  388. fwrite(&syms[0], SYMSIZE, 1, out_file);
  389. fwrite(&aux[0], AUXSIZE, 1, out_file);
  390. /* Write second symbol. */
  391. fwrite(&syms[1], SYMSIZE, 1, out_file);
  392. /* Write 04 00 00 00 to the end of the file. Don't know why this */
  393. /* is necessary, but the linker complains on MIPS and Alpha if */
  394. /* isn't there. */
  395. fwrite(&padding, 4, 1, out_file);
  396. fclose(infile);
  397. close_gen_file();
  398. }
  399. #ifdef TEST_CASE
  400. #ifndef PROD
  401. LOCAL IU32 testdata[] = {
  402. 0x31415926,
  403. 0x11223344, 0x55667788, 0x99aabbcc, 0xddeeff00,
  404. 0x14142135 };
  405. #endif
  406. #endif
  407. /*(
  408. ========================== host_convert_dat_files ==========================
  409. PURPOSE:
  410. Convert thread.dat and online.dat to COFF format.
  411. INPUT:
  412. None.
  413. OUTPUT:
  414. None.
  415. ============================================================================
  416. )*/
  417. #ifdef STAND_ALONE
  418. LOCAL void
  419. #else
  420. GLOBAL void
  421. #endif /* STAND_ALONE */
  422. host_convert_dat_files IFN2(char *,src,char *,dest)
  423. {
  424. IU16 machineId;
  425. /* Set underscore flag here if we are part of onGen. */
  426. #ifndef STAND_ALONE
  427. #ifdef C_NO_UL
  428. cUnderscore = FALSE;
  429. #else
  430. cUnderscore = TRUE;
  431. #endif /* C_NO_UL */
  432. #endif /* !STAND_ALONE */
  433. machineId = getMachineId();
  434. dat2obj(dest, src, machineId);
  435. //dat2obj("onsub", "online.dat", machineId);
  436. #ifdef TEST_CASE
  437. #ifndef PROD
  438. /* Generate a specimen .dat file which we could write as
  439. * a .s file and compile directly: helpful for debugging.
  440. */
  441. open_gen_file("test.dat");
  442. if (out_file == stderr) {
  443. return;
  444. }
  445. fwrite(&testdata, sizeof(testdata), 1, out_file);
  446. close_gen_file();
  447. dat2obj("testd", "test.dat", machineId);
  448. #endif
  449. #endif
  450. }
  451. #ifdef STAND_ALONE
  452. /*(
  453. =================================== main ===================================
  454. PURPOSE:
  455. Wrapper for host_convert_dat_files if running stand-alone
  456. ============================================================================
  457. )*/
  458. __cdecl main(int argc, char *argv[])
  459. {
  460. IBOOL argerr = FALSE;
  461. /*
  462. * Source file is the full filename of the lcif file
  463. * dest file/name is the name for the .obj and the symbol name within it
  464. * one optional argument, -u, which specifies that 'C' symbols should
  465. * be preceded by '_'.
  466. */
  467. switch (argc)
  468. {
  469. case 3:
  470. cUnderscore = FALSE;
  471. break;
  472. case 4:
  473. if (strcmp(argv[argc-1], "-u") == 0)
  474. cUnderscore = TRUE;
  475. else
  476. argerr = TRUE;
  477. break;
  478. default:
  479. argerr = TRUE;
  480. break;
  481. }
  482. if (argerr)
  483. {
  484. printf("Usage - dat2obj <sourcefile> <dest file/name> [-u]\n");
  485. printf("\t-u - precede symbols with '_'\n");
  486. printf("\t<sourcefile> is the full pathname for the input lcif\n");
  487. printf("\t<dest file/name> is the dest name without the .obj and\n");
  488. printf("\t\t\tis the name of the symbol within the .obj file\n");
  489. return(-1);
  490. }
  491. host_convert_dat_files(argv[1],argv[2]);
  492. return(0);
  493. }
  494. #endif /* STAND_ALONE */