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.

491 lines
14 KiB

  1. /*** asl.c - Main module of the ASL assembler
  2. *
  3. * This program compiles the ASL language into AML (p-code).
  4. *
  5. * Copyright (c) 1996 Microsoft Corporation
  6. * Author: Michael Tsang (MikeTs)
  7. * Created 07/23/96
  8. *
  9. * MODIFICATION HISTORY
  10. */
  11. #include "aslp.h"
  12. /***EP main - main program
  13. *
  14. * ENTRY
  15. * icArg - command line arguments count
  16. * apszArg - command line arguments array
  17. *
  18. * EXIT-SUCCESS
  19. * program terminates with return code ASLERR_NONE
  20. * EXIT-FAILURE
  21. * program terminates with negative error code
  22. */
  23. int EXPORT main(int icArg, char **apszArg)
  24. {
  25. int rc = ASLERR_NONE;
  26. ParseProgInfo(apszArg[0], &ProgInfo);
  27. icArg--;
  28. apszArg++;
  29. if ((ParseSwitches(&icArg, &apszArg, ArgTypes, &ProgInfo) != ARGERR_NONE) ||
  30. (gpszTabSig == NULL) && ((icArg != 1) || (gdwfASL & ASLF_CREAT_BIN)) ||
  31. (gpszTabSig != NULL) && ((icArg != 0) || (gdwfASL & ASLF_UNASM)))
  32. {
  33. MSG(("invalid command line options"));
  34. PrintUsage();
  35. rc = ASLERR_INVALID_PARAM;
  36. }
  37. else
  38. {
  39. #ifdef __UNASM
  40. PBYTE pbTable = NULL;
  41. DWORD dwTableSig = 0;
  42. PSZ psz;
  43. #endif
  44. OPENTRACE(gpszTraceFile);
  45. PrintLogo();
  46. if ((rc = InitNameSpace()) == ASLERR_NONE)
  47. {
  48. #ifdef __UNASM
  49. if (gdwfASL & ASLF_DUMP_BIN)
  50. {
  51. if (((rc = ReadBinFile(*apszArg, &pbTable, &dwTableSig)) ==
  52. ASLERR_NONE) &&
  53. (gpszLSTFile == NULL))
  54. {
  55. strncpy(gszLSTName, (PSZ)&dwTableSig, sizeof(DWORD));
  56. strcpy(&gszLSTName[sizeof(DWORD)], ".TXT");
  57. gpszLSTFile = gszLSTName;
  58. gdwfASL |= ASLF_DUMP_NONASL | ASLF_UNASM;
  59. }
  60. }
  61. else if (gdwfASL & ASLF_UNASM)
  62. {
  63. gpszAMLFile = *apszArg;
  64. if (gpszLSTFile == NULL)
  65. {
  66. strncpy(gszLSTName, gpszAMLFile, _MAX_FNAME - 1);
  67. if ((psz = strchr(gszLSTName, '.')) != NULL)
  68. {
  69. *psz = '\0';
  70. }
  71. strcpy(&gszLSTName[strlen(gszLSTName)], ".ASL");
  72. gpszLSTFile = gszLSTName;
  73. gdwfASL |= ASLF_GENSRC;
  74. }
  75. }
  76. else if (gpszTabSig != NULL)
  77. {
  78. gdwfASL |= ASLF_UNASM;
  79. if (IsWinNT())
  80. {
  81. gdwfASL |= ASLF_NT;
  82. }
  83. _strupr(gpszTabSig);
  84. if ((strcmp(gpszTabSig, "DSDT") != 0) &&
  85. (strcmp(gpszTabSig, "SSDT") != 0) &&
  86. (strcmp(gpszTabSig, "PSDT") != 0))
  87. {
  88. gdwfASL |= ASLF_DUMP_NONASL;
  89. }
  90. if (gpszLSTFile == NULL)
  91. {
  92. gpszLSTFile = gszLSTName;
  93. if (gdwfASL & ASLF_DUMP_NONASL)
  94. {
  95. if (strcmp(gpszTabSig, "*") == 0)
  96. {
  97. strcpy(gszLSTName, "ACPI");
  98. }
  99. else
  100. {
  101. strcpy(gszLSTName, gpszTabSig);
  102. }
  103. strcpy(&gszLSTName[strlen(gszLSTName)], ".TXT");
  104. }
  105. else
  106. {
  107. strcpy(gszLSTName, gpszTabSig);
  108. strcpy(&gszLSTName[strlen(gszLSTName)], ".ASL");
  109. gdwfASL |= ASLF_GENSRC;
  110. }
  111. }
  112. #ifndef WINNT
  113. if (!(gdwfASL & ASLF_NT) && ((ghVxD = OpenVxD()) == NULL))
  114. {
  115. ERROR(("option is not available"));
  116. rc = ASLERR_OPEN_VXD;
  117. }
  118. #endif
  119. }
  120. else
  121. {
  122. #endif
  123. rc = ParseASLFile(*apszArg);
  124. #ifdef __UNASM
  125. }
  126. #endif
  127. }
  128. if (rc == ASLERR_NONE)
  129. {
  130. FILE *pfileOut;
  131. if (!(gdwfASL & ASLF_DUMP_NONASL))
  132. {
  133. if (gpszAMLFile == NULL)
  134. {
  135. if (gpszTabSig == NULL)
  136. {
  137. ERROR(("%s has no DefinitionBlock", *apszArg));
  138. }
  139. else
  140. {
  141. strcpy(gszAMLName, gpszTabSig);
  142. strcat(gszAMLName, ".AML");
  143. }
  144. }
  145. if (gpszASMFile != NULL)
  146. {
  147. if ((pfileOut = fopen(gpszASMFile, "w")) == NULL)
  148. {
  149. ERROR(("failed to open ASM file - %s", gpszASMFile));
  150. }
  151. else
  152. {
  153. gdwfASL |= ASLF_GENASM;
  154. UnAsmFile(gpszAMLFile? gpszAMLFile: gszAMLName,
  155. pfileOut);
  156. gdwfASL &= ~ASLF_GENASM;
  157. fclose(pfileOut);
  158. }
  159. }
  160. }
  161. if (gpszLSTFile != NULL)
  162. {
  163. #ifdef __UNASM
  164. if (gdwfASL & ASLF_CREAT_BIN)
  165. {
  166. rc = DumpTableBySig(NULL, *((PDWORD)gpszTabSig));
  167. }
  168. else if ((pfileOut = fopen(gpszLSTFile, "w")) == NULL)
  169. {
  170. ERROR(("failed to open LST file - %s", gpszLSTFile));
  171. }
  172. else
  173. {
  174. if (gdwfASL & ASLF_DUMP_BIN)
  175. {
  176. ASSERT(pbTable != NULL);
  177. ASSERT(dwTableSig != 0);
  178. rc = DumpTable(pfileOut, pbTable, 0, dwTableSig);
  179. MEMFREE(pbTable);
  180. }
  181. else if (gdwfASL & ASLF_DUMP_NONASL)
  182. {
  183. DWORD dwAddr;
  184. if (((dwAddr = strtoul(gpszTabSig, &psz, 16)) != 0) &&
  185. (*psz == 0))
  186. {
  187. rc = DumpTableByAddr(pfileOut, dwAddr);
  188. }
  189. else
  190. {
  191. rc = DumpTableBySig(pfileOut, *((PDWORD)gpszTabSig));
  192. }
  193. }
  194. else
  195. {
  196. rc = UnAsmFile(gpszAMLFile? gpszAMLFile: gszAMLName,
  197. pfileOut);
  198. }
  199. fclose(pfileOut);
  200. }
  201. #else
  202. if ((pfileOut = fopen(gpszLSTFile, "w")) != NULL)
  203. {
  204. rc = UnAsmFile(gpszAMLFile? gpszAMLFile: gszAMLName,
  205. pfileOut);
  206. fclose(pfileOut);
  207. }
  208. else
  209. {
  210. ERROR(("failed to open LST file - %s", gpszLSTFile));
  211. }
  212. #endif
  213. }
  214. if (gpszNSDFile != NULL)
  215. {
  216. if ((pfileOut = fopen(gpszNSDFile, "w")) == NULL)
  217. {
  218. ERROR(("failed to open NameSpace dump file - %s",
  219. gpszNSDFile));
  220. }
  221. else
  222. {
  223. fprintf(pfileOut, "Name Space Objects:\n");
  224. DumpNameSpacePaths(gpnsNameSpaceRoot, pfileOut);
  225. fclose(pfileOut);
  226. }
  227. }
  228. }
  229. #ifdef __UNASM
  230. #ifndef WINNT
  231. if (ghVxD != NULL)
  232. {
  233. CloseVxD(ghVxD);
  234. ghVxD = NULL;
  235. }
  236. #endif
  237. #endif
  238. CLOSETRACE();
  239. }
  240. return rc;
  241. } //main
  242. #ifdef __UNASM
  243. /***LP ReadBinFile - Read table from binary file
  244. *
  245. * ENTRY
  246. * pszFile -> binary file name
  247. * ppb -> to hold the binary buffer pointer
  248. * pdwTableSig -> to hold the table signature
  249. *
  250. * EXIT-SUCCESS
  251. * returns ASLERR_NONE
  252. * EXIT-FAILURE
  253. * returns negative error code
  254. */
  255. int LOCAL ReadBinFile(PSZ pszFile, PBYTE *ppb, PDWORD pdwTableSig)
  256. {
  257. int rc = ASLERR_NONE;
  258. FILE *pfileBin;
  259. DESCRIPTION_HEADER dh;
  260. ENTER((1, "ReadBinFile(File=%s,ppb=%p,pdwTableSig=%p)\n",
  261. pszFile, ppb, pdwTableSig));
  262. if ((pfileBin = fopen(pszFile, "rb")) == NULL)
  263. {
  264. ERROR(("ReadBinFile: failed to open file %s", pszFile));
  265. rc = ASLERR_OPEN_FILE;
  266. }
  267. else if (fread(&dh, 1, sizeof(dh), pfileBin) < 2*sizeof(DWORD))
  268. {
  269. ERROR(("ReadBinFile: failed to read file %s", pszFile));
  270. rc = ASLERR_READ_FILE;
  271. }
  272. else if (fseek(pfileBin, 0, SEEK_SET) != 0)
  273. {
  274. ERROR(("ReadBinFile: failed to reset file %s", pszFile));
  275. rc = ASLERR_SEEK_FILE;
  276. }
  277. else
  278. {
  279. DWORD dwLen = (dh.Signature == SIG_LOW_RSDP)? sizeof(RSDP): dh.Length;
  280. if ((*ppb = MEMALLOC(dwLen)) == NULL)
  281. {
  282. ERROR(("ReadBinFile: failed to allocate table buffer for %s",
  283. pszFile));
  284. rc = ASLERR_OUT_OF_MEM;
  285. }
  286. else if (fread(*ppb, dwLen, 1, pfileBin) != 1)
  287. {
  288. MEMFREE(*ppb);
  289. *ppb = NULL;
  290. ERROR(("ReadBinFile: failed to read file %s", pszFile));
  291. rc = ASLERR_READ_FILE;
  292. }
  293. else if (dh.Signature == SIG_LOW_RSDP)
  294. {
  295. *pdwTableSig = SIG_RSDP;
  296. }
  297. else
  298. {
  299. *pdwTableSig = dh.Signature;
  300. }
  301. }
  302. if (pfileBin != NULL)
  303. {
  304. fclose(pfileBin);
  305. }
  306. EXIT((1, "ReadBinFile=%d (pbTable=%p,TableSig=%s)\n",
  307. rc, *ppb, GetTableSigStr(*pdwTableSig)));
  308. return rc;
  309. } //ReadBinFile
  310. #endif
  311. /***LP InitNameSpace - Initialize NameSpace
  312. *
  313. * ENTRY
  314. * None
  315. *
  316. * EXIT-SUCCESS
  317. * returns ASLERR_NONE
  318. * EXIT-FAILURE
  319. * returns negative error code
  320. */
  321. int LOCAL InitNameSpace(VOID)
  322. {
  323. int rc = ASLERR_NONE;
  324. ENTER((1, "InitNameSpace()\n"));
  325. if ((rc = CreateNameSpaceObj(NULL, "\\", NULL, NULL, NULL, NSF_EXIST_ERR))
  326. == ASLERR_NONE)
  327. {
  328. static struct _defobj {
  329. PSZ pszName;
  330. ULONG dwObjType;
  331. } DefinedRootObjs[] = {
  332. "_GPE", OBJTYPE_UNKNOWN,
  333. "_PR", OBJTYPE_UNKNOWN,
  334. "_SB", OBJTYPE_UNKNOWN,
  335. "_SI", OBJTYPE_UNKNOWN,
  336. "_TZ", OBJTYPE_UNKNOWN,
  337. "_REV", OBJTYPE_INTDATA,
  338. "_OS", OBJTYPE_STRDATA,
  339. "_GL", OBJTYPE_MUTEX,
  340. NULL, 0
  341. };
  342. int i;
  343. PNSOBJ pns;
  344. gpnsCurrentScope = gpnsNameSpaceRoot;
  345. for (i = 0; DefinedRootObjs[i].pszName != NULL; ++i)
  346. {
  347. if ((rc = CreateNameSpaceObj(NULL, DefinedRootObjs[i].pszName, NULL,
  348. NULL, &pns, NSF_EXIST_ERR)) ==
  349. ASLERR_NONE)
  350. {
  351. pns->ObjData.dwDataType = DefinedRootObjs[i].dwObjType;
  352. }
  353. else
  354. {
  355. break;
  356. }
  357. }
  358. }
  359. EXIT((1, "InitNameSpace=%d\n", rc));
  360. return rc;
  361. } //InitNameSpace
  362. /***LP PrintLogo - Print logo message
  363. *
  364. * ENTRY
  365. * None
  366. *
  367. * EXIT
  368. * None
  369. */
  370. VOID LOCAL PrintLogo(VOID)
  371. {
  372. if ((gdwfASL & ASLF_NOLOGO) == 0)
  373. {
  374. printf("%s Version %d.%d.%d%s [%s, %s]\n%s\n",
  375. STR_PROGDESC, VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE,
  376. #ifdef WINNT
  377. "NT",
  378. #else
  379. "",
  380. #endif
  381. __DATE__, __TIME__, STR_COPYRIGHT);
  382. printf("Compliant with ACPI 1.0 specification\n\n");
  383. }
  384. } //PrintLogo
  385. /***LP PrintHelp - Print help messages
  386. *
  387. * ENTRY
  388. * ppszArg -> pointer to argument (not used)
  389. * pAT -> argument type structure (not used)
  390. *
  391. * EXIT
  392. * program terminated with exit code 0
  393. */
  394. int LOCAL PrintHelp(char **ppszArg, PARGTYPE pAT)
  395. {
  396. DEREF(ppszArg);
  397. DEREF(pAT);
  398. PrintLogo();
  399. PrintUsage();
  400. printf("\t? - Print this help message.\n");
  401. printf("\tnologo - Supress logo banner.\n");
  402. printf("\tFo=<AMLFile> - Override the AML file name in the DefinitionBlock.\n");
  403. printf("\tFa=<ASMFile> - Generate .ASM file with the name <ASMFile>.\n");
  404. printf("\tFl=<LSTFile> - Generate .LST file with the name <LSTFile>.\n");
  405. printf("\tFn=<NSDFile> - Generate NameSpace Dump file with the name <NSDFile>.\n");
  406. #ifdef __UNASM
  407. printf("\td - Dump the binary file in text form.\n");
  408. printf("\tu - Unassemble AML file to an .ASL file (default)\n"
  409. "\t or a .LST file.\n");
  410. printf("\ttab=<TabSig> - Unassemble ASL table to an .ASL file (default)\n"
  411. "\t or a .LST file.\n");
  412. printf("\t Dump non ASL table to an .TXT file.\n");
  413. printf("\t If <TabSig> is '*', all tables are dump to ACPI.TXT.\n");
  414. printf("\t <TabSig> can also be the physical address of the table.\n");
  415. printf("\tc - Create binary files from tables.\n");
  416. #endif
  417. #ifdef TRACING
  418. printf("\tt=<n> - Enable tracing at trace level n.\n");
  419. printf("\tl=<LogFile> - Overriding the default trace log file name.\n");
  420. #endif
  421. exit(0);
  422. return ASLERR_NONE;
  423. } //PrintHelp
  424. /***LP PrintUsage - Print program usage syntax
  425. *
  426. * ENTRY
  427. * None
  428. *
  429. * EXIT
  430. * None
  431. */
  432. VOID LOCAL PrintUsage(VOID)
  433. {
  434. printf("Usage:\n%s /?\n", MODNAME);
  435. #ifdef __UNASM
  436. printf("%s [/nologo] /d <BinFile>\n", MODNAME);
  437. printf("%s [/nologo] /u [/Fa=<ASMFile>] [/Fl=<LSTFile>] [/Fn=<NSDFile>] <AMLFile>\n",
  438. MODNAME);
  439. printf("%s [/nologo] /tab=<TabSig> [/c] [/Fa=<ASMfile>] [/Fl=<LSTFile>] [/Fn=<NSDFile>]\n",
  440. MODNAME);
  441. #endif
  442. #ifdef TRACING
  443. printf("%s [/nologo] [/Fo=<AMLFile>] [/Fa=<ASMFile>] [/Fl=<LSTFile>] [/Fn=<NSDFile>] [/t=<n>] [/l=<LogFile>] <ASLFile>\n",
  444. MODNAME);
  445. #else
  446. printf("%s [/nologo] [/Fo=<AMLFile>] [/Fa=<ASMFile>] [/Fl=<LSTFile>] [/Fn=<NSDFile>] <ASLFile>\n",
  447. MODNAME);
  448. #endif
  449. printf("\n");
  450. } //PrintUsage