dmextern.c 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424
  1. /******************************************************************************
  2. *
  3. * Module Name: dmextern - Support for External() ASL statements
  4. *
  5. *****************************************************************************/
  6. /******************************************************************************
  7. *
  8. * 1. Copyright Notice
  9. *
  10. * Some or all of this work - Copyright (c) 1999 - 2016, Intel Corp.
  11. * All rights reserved.
  12. *
  13. * 2. License
  14. *
  15. * 2.1. This is your license from Intel Corp. under its intellectual property
  16. * rights. You may have additional license terms from the party that provided
  17. * you this software, covering your right to use that party's intellectual
  18. * property rights.
  19. *
  20. * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  21. * copy of the source code appearing in this file ("Covered Code") an
  22. * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  23. * base code distributed originally by Intel ("Original Intel Code") to copy,
  24. * make derivatives, distribute, use and display any portion of the Covered
  25. * Code in any form, with the right to sublicense such rights; and
  26. *
  27. * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  28. * license (with the right to sublicense), under only those claims of Intel
  29. * patents that are infringed by the Original Intel Code, to make, use, sell,
  30. * offer to sell, and import the Covered Code and derivative works thereof
  31. * solely to the minimum extent necessary to exercise the above copyright
  32. * license, and in no event shall the patent license extend to any additions
  33. * to or modifications of the Original Intel Code. No other license or right
  34. * is granted directly or by implication, estoppel or otherwise;
  35. *
  36. * The above copyright and patent license is granted only if the following
  37. * conditions are met:
  38. *
  39. * 3. Conditions
  40. *
  41. * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  42. * Redistribution of source code of any substantial portion of the Covered
  43. * Code or modification with rights to further distribute source must include
  44. * the above Copyright Notice, the above License, this list of Conditions,
  45. * and the following Disclaimer and Export Compliance provision. In addition,
  46. * Licensee must cause all Covered Code to which Licensee contributes to
  47. * contain a file documenting the changes Licensee made to create that Covered
  48. * Code and the date of any change. Licensee must include in that file the
  49. * documentation of any changes made by any predecessor Licensee. Licensee
  50. * must include a prominent statement that the modification is derived,
  51. * directly or indirectly, from Original Intel Code.
  52. *
  53. * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  54. * Redistribution of source code of any substantial portion of the Covered
  55. * Code or modification without rights to further distribute source must
  56. * include the following Disclaimer and Export Compliance provision in the
  57. * documentation and/or other materials provided with distribution. In
  58. * addition, Licensee may not authorize further sublicense of source of any
  59. * portion of the Covered Code, and must include terms to the effect that the
  60. * license from Licensee to its licensee is limited to the intellectual
  61. * property embodied in the software Licensee provides to its licensee, and
  62. * not to intellectual property embodied in modifications its licensee may
  63. * make.
  64. *
  65. * 3.3. Redistribution of Executable. Redistribution in executable form of any
  66. * substantial portion of the Covered Code or modification must reproduce the
  67. * above Copyright Notice, and the following Disclaimer and Export Compliance
  68. * provision in the documentation and/or other materials provided with the
  69. * distribution.
  70. *
  71. * 3.4. Intel retains all right, title, and interest in and to the Original
  72. * Intel Code.
  73. *
  74. * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  75. * Intel shall be used in advertising or otherwise to promote the sale, use or
  76. * other dealings in products derived from or relating to the Covered Code
  77. * without prior written authorization from Intel.
  78. *
  79. * 4. Disclaimer and Export Compliance
  80. *
  81. * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  82. * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  83. * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
  84. * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
  85. * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
  86. * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  87. * PARTICULAR PURPOSE.
  88. *
  89. * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  90. * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  91. * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  92. * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  93. * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  94. * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
  95. * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  96. * LIMITED REMEDY.
  97. *
  98. * 4.3. Licensee shall not export, either directly or indirectly, any of this
  99. * software or system incorporating such software without first obtaining any
  100. * required license or other approval from the U. S. Department of Commerce or
  101. * any other agency or department of the United States Government. In the
  102. * event Licensee exports any such software from the United States or
  103. * re-exports any such software from a foreign destination, Licensee shall
  104. * ensure that the distribution and export/re-export of the software is in
  105. * compliance with all laws, regulations, orders, or other restrictions of the
  106. * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  107. * any of its subsidiaries will export/re-export any technical data, process,
  108. * software, or service, directly or indirectly, to any country for which the
  109. * United States government or any agency thereof requires an export license,
  110. * other governmental approval, or letter of assurance, without first obtaining
  111. * such license, approval or letter.
  112. *
  113. *****************************************************************************/
  114. #include "acpi.h"
  115. #include "accommon.h"
  116. #include "amlcode.h"
  117. #include "acnamesp.h"
  118. #include "acdisasm.h"
  119. #include "aslcompiler.h"
  120. #include <stdio.h>
  121. #include <errno.h>
  122. /*
  123. * This module is used for application-level code (iASL disassembler) only.
  124. *
  125. * It contains the code to create and emit any necessary External() ASL
  126. * statements for the module being disassembled.
  127. */
  128. #define _COMPONENT ACPI_CA_DISASSEMBLER
  129. ACPI_MODULE_NAME ("dmextern")
  130. /*
  131. * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL
  132. * ObjectTypeKeyword. Used to generate typed external declarations
  133. */
  134. static const char *AcpiGbl_DmTypeNames[] =
  135. {
  136. /* 00 */ ", UnknownObj", /* Type ANY */
  137. /* 01 */ ", IntObj",
  138. /* 02 */ ", StrObj",
  139. /* 03 */ ", BuffObj",
  140. /* 04 */ ", PkgObj",
  141. /* 05 */ ", FieldUnitObj",
  142. /* 06 */ ", DeviceObj",
  143. /* 07 */ ", EventObj",
  144. /* 08 */ ", MethodObj",
  145. /* 09 */ ", MutexObj",
  146. /* 10 */ ", OpRegionObj",
  147. /* 11 */ ", PowerResObj",
  148. /* 12 */ ", ProcessorObj",
  149. /* 13 */ ", ThermalZoneObj",
  150. /* 14 */ ", BuffFieldObj",
  151. /* 15 */ ", DDBHandleObj",
  152. /* 16 */ "", /* Debug object */
  153. /* 17 */ ", FieldUnitObj",
  154. /* 18 */ ", FieldUnitObj",
  155. /* 19 */ ", FieldUnitObj"
  156. };
  157. #define METHOD_SEPARATORS " \t,()\n"
  158. /* Local prototypes */
  159. static const char *
  160. AcpiDmGetObjectTypeName (
  161. ACPI_OBJECT_TYPE Type);
  162. static char *
  163. AcpiDmNormalizeParentPrefix (
  164. ACPI_PARSE_OBJECT *Op,
  165. char *Path);
  166. static void
  167. AcpiDmAddPathToExternalList (
  168. char *Path,
  169. UINT8 Type,
  170. UINT32 Value,
  171. UINT16 Flags);
  172. static ACPI_STATUS
  173. AcpiDmCreateNewExternal (
  174. char *ExternalPath,
  175. char *InternalPath,
  176. UINT8 Type,
  177. UINT32 Value,
  178. UINT16 Flags);
  179. /*******************************************************************************
  180. *
  181. * FUNCTION: AcpiDmGetObjectTypeName
  182. *
  183. * PARAMETERS: Type - An ACPI_OBJECT_TYPE
  184. *
  185. * RETURN: Pointer to a string
  186. *
  187. * DESCRIPTION: Map an object type to the ASL object type string.
  188. *
  189. ******************************************************************************/
  190. static const char *
  191. AcpiDmGetObjectTypeName (
  192. ACPI_OBJECT_TYPE Type)
  193. {
  194. if (Type == ACPI_TYPE_LOCAL_SCOPE)
  195. {
  196. Type = ACPI_TYPE_DEVICE;
  197. }
  198. else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD)
  199. {
  200. return ("");
  201. }
  202. return (AcpiGbl_DmTypeNames[Type]);
  203. }
  204. /*******************************************************************************
  205. *
  206. * FUNCTION: AcpiDmNormalizeParentPrefix
  207. *
  208. * PARAMETERS: Op - Parse op
  209. * Path - Path with parent prefix
  210. *
  211. * RETURN: The full pathname to the object (from the namespace root)
  212. *
  213. * DESCRIPTION: Returns the full pathname of a path with parent prefix
  214. * The caller must free the fullpath returned.
  215. *
  216. ******************************************************************************/
  217. static char *
  218. AcpiDmNormalizeParentPrefix (
  219. ACPI_PARSE_OBJECT *Op,
  220. char *Path)
  221. {
  222. ACPI_NAMESPACE_NODE *Node;
  223. char *Fullpath;
  224. char *ParentPath;
  225. ACPI_SIZE Length;
  226. UINT32 Index = 0;
  227. if (!Op)
  228. {
  229. return (NULL);
  230. }
  231. /* Search upwards in the parse tree until we reach the next namespace node */
  232. Op = Op->Common.Parent;
  233. while (Op)
  234. {
  235. if (Op->Common.Node)
  236. {
  237. break;
  238. }
  239. Op = Op->Common.Parent;
  240. }
  241. if (!Op)
  242. {
  243. return (NULL);
  244. }
  245. /*
  246. * Find the actual parent node for the reference:
  247. * Remove all carat prefixes from the input path.
  248. * There may be multiple parent prefixes (For example, ^^^M000)
  249. */
  250. Node = Op->Common.Node;
  251. while (Node && (*Path == (UINT8) AML_PARENT_PREFIX))
  252. {
  253. Node = Node->Parent;
  254. Path++;
  255. }
  256. if (!Node)
  257. {
  258. return (NULL);
  259. }
  260. /* Get the full pathname for the parent node */
  261. ParentPath = AcpiNsGetExternalPathname (Node);
  262. if (!ParentPath)
  263. {
  264. return (NULL);
  265. }
  266. Length = (strlen (ParentPath) + strlen (Path) + 1);
  267. if (ParentPath[1])
  268. {
  269. /*
  270. * If ParentPath is not just a simple '\', increment the length
  271. * for the required dot separator (ParentPath.Path)
  272. */
  273. Length++;
  274. /* For External() statements, we do not want a leading '\' */
  275. if (*ParentPath == AML_ROOT_PREFIX)
  276. {
  277. Index = 1;
  278. }
  279. }
  280. Fullpath = ACPI_ALLOCATE_ZEROED (Length);
  281. if (!Fullpath)
  282. {
  283. goto Cleanup;
  284. }
  285. /*
  286. * Concatenate parent fullpath and path. For example,
  287. * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT"
  288. *
  289. * Copy the parent path
  290. */
  291. strcpy (Fullpath, &ParentPath[Index]);
  292. /*
  293. * Add dot separator
  294. * (don't need dot if parent fullpath is a single backslash)
  295. */
  296. if (ParentPath[1])
  297. {
  298. strcat (Fullpath, ".");
  299. }
  300. /* Copy child path (carat parent prefix(es) were skipped above) */
  301. strcat (Fullpath, Path);
  302. Cleanup:
  303. ACPI_FREE (ParentPath);
  304. return (Fullpath);
  305. }
  306. /*******************************************************************************
  307. *
  308. * FUNCTION: AcpiDmAddToExternalFileList
  309. *
  310. * PARAMETERS: PathList - Single path or list separated by comma
  311. *
  312. * RETURN: None
  313. *
  314. * DESCRIPTION: Add external files to global list
  315. *
  316. ******************************************************************************/
  317. ACPI_STATUS
  318. AcpiDmAddToExternalFileList (
  319. char *Pathname)
  320. {
  321. ACPI_EXTERNAL_FILE *ExternalFile;
  322. char *LocalPathname;
  323. if (!Pathname)
  324. {
  325. return (AE_OK);
  326. }
  327. LocalPathname = ACPI_ALLOCATE (strlen (Pathname) + 1);
  328. if (!LocalPathname)
  329. {
  330. return (AE_NO_MEMORY);
  331. }
  332. ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
  333. if (!ExternalFile)
  334. {
  335. ACPI_FREE (LocalPathname);
  336. return (AE_NO_MEMORY);
  337. }
  338. /* Take a copy of the file pathname */
  339. strcpy (LocalPathname, Pathname);
  340. ExternalFile->Path = LocalPathname;
  341. if (AcpiGbl_ExternalFileList)
  342. {
  343. ExternalFile->Next = AcpiGbl_ExternalFileList;
  344. }
  345. AcpiGbl_ExternalFileList = ExternalFile;
  346. return (AE_OK);
  347. }
  348. /*******************************************************************************
  349. *
  350. * FUNCTION: AcpiDmClearExternalFileList
  351. *
  352. * PARAMETERS: None
  353. *
  354. * RETURN: None
  355. *
  356. * DESCRIPTION: Clear the external file list
  357. *
  358. ******************************************************************************/
  359. void
  360. AcpiDmClearExternalFileList (
  361. void)
  362. {
  363. ACPI_EXTERNAL_FILE *NextExternal;
  364. while (AcpiGbl_ExternalFileList)
  365. {
  366. NextExternal = AcpiGbl_ExternalFileList->Next;
  367. ACPI_FREE (AcpiGbl_ExternalFileList->Path);
  368. ACPI_FREE (AcpiGbl_ExternalFileList);
  369. AcpiGbl_ExternalFileList = NextExternal;
  370. }
  371. }
  372. /*******************************************************************************
  373. *
  374. * FUNCTION: AcpiDmGetExternalsFromFile
  375. *
  376. * PARAMETERS: None
  377. *
  378. * RETURN: None
  379. *
  380. * DESCRIPTION: Process the optional external reference file.
  381. *
  382. * Each line in the file should be of the form:
  383. * External (<Method namepath>, MethodObj, <ArgCount>)
  384. *
  385. * Example:
  386. * External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
  387. *
  388. ******************************************************************************/
  389. void
  390. AcpiDmGetExternalsFromFile (
  391. void)
  392. {
  393. FILE *ExternalRefFile;
  394. char *Token;
  395. char *MethodName;
  396. UINT32 ArgCount;
  397. UINT32 ImportCount = 0;
  398. if (!Gbl_ExternalRefFilename)
  399. {
  400. return;
  401. }
  402. /* Open the file */
  403. ExternalRefFile = fopen (Gbl_ExternalRefFilename, "r");
  404. if (!ExternalRefFile)
  405. {
  406. fprintf (stderr, "Could not open external reference file \"%s\"\n",
  407. Gbl_ExternalRefFilename);
  408. AslAbort ();
  409. return;
  410. }
  411. /* Each line defines a method */
  412. while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ExternalRefFile))
  413. {
  414. Token = strtok (StringBuffer, METHOD_SEPARATORS); /* "External" */
  415. if (!Token)
  416. {
  417. continue;
  418. }
  419. if (strcmp (Token, "External"))
  420. {
  421. continue;
  422. }
  423. MethodName = strtok (NULL, METHOD_SEPARATORS); /* Method namepath */
  424. if (!MethodName)
  425. {
  426. continue;
  427. }
  428. Token = strtok (NULL, METHOD_SEPARATORS); /* "MethodObj" */
  429. if (!Token)
  430. {
  431. continue;
  432. }
  433. if (strcmp (Token, "MethodObj"))
  434. {
  435. continue;
  436. }
  437. Token = strtok (NULL, METHOD_SEPARATORS); /* Arg count */
  438. if (!Token)
  439. {
  440. continue;
  441. }
  442. /* Convert arg count string to an integer */
  443. errno = 0;
  444. ArgCount = strtoul (Token, NULL, 0);
  445. if (errno)
  446. {
  447. fprintf (stderr, "Invalid argument count (%s)\n", Token);
  448. continue;
  449. }
  450. if (ArgCount > 7)
  451. {
  452. fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
  453. continue;
  454. }
  455. /* Add this external to the global list */
  456. AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
  457. Gbl_ExternalRefFilename, ArgCount, MethodName);
  458. AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD,
  459. ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE));
  460. ImportCount++;
  461. }
  462. if (!ImportCount)
  463. {
  464. fprintf (stderr,
  465. "Did not find any external methods in reference file \"%s\"\n",
  466. Gbl_ExternalRefFilename);
  467. }
  468. else
  469. {
  470. /* Add the external(s) to the namespace */
  471. AcpiDmAddExternalsToNamespace ();
  472. AcpiOsPrintf ("%s: Imported %u external method definitions\n",
  473. Gbl_ExternalRefFilename, ImportCount);
  474. }
  475. fclose (ExternalRefFile);
  476. }
  477. /*******************************************************************************
  478. *
  479. * FUNCTION: AcpiDmAddOpToExternalList
  480. *
  481. * PARAMETERS: Op - Current parser Op
  482. * Path - Internal (AML) path to the object
  483. * Type - ACPI object type to be added
  484. * Value - Arg count if adding a Method object
  485. * Flags - To be passed to the external object
  486. *
  487. * RETURN: None
  488. *
  489. * DESCRIPTION: Insert a new name into the global list of Externals which
  490. * will in turn be later emitted as an External() declaration
  491. * in the disassembled output.
  492. *
  493. * This function handles the most common case where the referenced
  494. * name is simply not found in the constructed namespace.
  495. *
  496. ******************************************************************************/
  497. void
  498. AcpiDmAddOpToExternalList (
  499. ACPI_PARSE_OBJECT *Op,
  500. char *Path,
  501. UINT8 Type,
  502. UINT32 Value,
  503. UINT16 Flags)
  504. {
  505. char *ExternalPath;
  506. char *InternalPath = Path;
  507. char *Temp;
  508. ACPI_STATUS Status;
  509. ACPI_FUNCTION_TRACE (DmAddOpToExternalList);
  510. if (!Path)
  511. {
  512. return_VOID;
  513. }
  514. /* Remove a root backslash if present */
  515. if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
  516. {
  517. Path++;
  518. }
  519. /* Externalize the pathname */
  520. Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path,
  521. NULL, &ExternalPath);
  522. if (ACPI_FAILURE (Status))
  523. {
  524. return_VOID;
  525. }
  526. /*
  527. * Get the full pathname from the root if "Path" has one or more
  528. * parent prefixes (^). Note: path will not contain a leading '\'.
  529. */
  530. if (*Path == (UINT8) AML_PARENT_PREFIX)
  531. {
  532. Temp = AcpiDmNormalizeParentPrefix (Op, ExternalPath);
  533. /* Set new external path */
  534. ACPI_FREE (ExternalPath);
  535. ExternalPath = Temp;
  536. if (!Temp)
  537. {
  538. return_VOID;
  539. }
  540. /* Create the new internal pathname */
  541. Flags |= ACPI_EXT_INTERNAL_PATH_ALLOCATED;
  542. Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
  543. if (ACPI_FAILURE (Status))
  544. {
  545. ACPI_FREE (ExternalPath);
  546. return_VOID;
  547. }
  548. }
  549. /* Create the new External() declaration node */
  550. Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
  551. Type, Value, Flags);
  552. if (ACPI_FAILURE (Status))
  553. {
  554. ACPI_FREE (ExternalPath);
  555. if (Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
  556. {
  557. ACPI_FREE (InternalPath);
  558. }
  559. }
  560. return_VOID;
  561. }
  562. /*******************************************************************************
  563. *
  564. * FUNCTION: AcpiDmAddNodeToExternalList
  565. *
  566. * PARAMETERS: Node - Namespace node for object to be added
  567. * Type - ACPI object type to be added
  568. * Value - Arg count if adding a Method object
  569. * Flags - To be passed to the external object
  570. *
  571. * RETURN: None
  572. *
  573. * DESCRIPTION: Insert a new name into the global list of Externals which
  574. * will in turn be later emitted as an External() declaration
  575. * in the disassembled output.
  576. *
  577. * This function handles the case where the referenced name has
  578. * been found in the namespace, but the name originated in a
  579. * table other than the one that is being disassembled (such
  580. * as a table that is added via the iASL -e option).
  581. *
  582. ******************************************************************************/
  583. void
  584. AcpiDmAddNodeToExternalList (
  585. ACPI_NAMESPACE_NODE *Node,
  586. UINT8 Type,
  587. UINT32 Value,
  588. UINT16 Flags)
  589. {
  590. char *ExternalPath;
  591. char *InternalPath;
  592. char *Temp;
  593. ACPI_STATUS Status;
  594. ACPI_FUNCTION_TRACE (DmAddNodeToExternalList);
  595. if (!Node)
  596. {
  597. return_VOID;
  598. }
  599. /* Get the full external and internal pathnames to the node */
  600. ExternalPath = AcpiNsGetExternalPathname (Node);
  601. if (!ExternalPath)
  602. {
  603. return_VOID;
  604. }
  605. Status = AcpiNsInternalizeName (ExternalPath, &InternalPath);
  606. if (ACPI_FAILURE (Status))
  607. {
  608. ACPI_FREE (ExternalPath);
  609. return_VOID;
  610. }
  611. /* Remove the root backslash */
  612. if ((*ExternalPath == AML_ROOT_PREFIX) && (ExternalPath[1]))
  613. {
  614. Temp = ACPI_ALLOCATE_ZEROED (strlen (ExternalPath) + 1);
  615. if (!Temp)
  616. {
  617. return_VOID;
  618. }
  619. strcpy (Temp, &ExternalPath[1]);
  620. ACPI_FREE (ExternalPath);
  621. ExternalPath = Temp;
  622. }
  623. /* Create the new External() declaration node */
  624. Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type,
  625. Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
  626. if (ACPI_FAILURE (Status))
  627. {
  628. ACPI_FREE (ExternalPath);
  629. ACPI_FREE (InternalPath);
  630. }
  631. return_VOID;
  632. }
  633. /*******************************************************************************
  634. *
  635. * FUNCTION: AcpiDmAddPathToExternalList
  636. *
  637. * PARAMETERS: Path - External name of the object to be added
  638. * Type - ACPI object type to be added
  639. * Value - Arg count if adding a Method object
  640. * Flags - To be passed to the external object
  641. *
  642. * RETURN: None
  643. *
  644. * DESCRIPTION: Insert a new name into the global list of Externals which
  645. * will in turn be later emitted as an External() declaration
  646. * in the disassembled output.
  647. *
  648. * This function currently is used to add externals via a
  649. * reference file (via the -fe iASL option).
  650. *
  651. ******************************************************************************/
  652. static void
  653. AcpiDmAddPathToExternalList (
  654. char *Path,
  655. UINT8 Type,
  656. UINT32 Value,
  657. UINT16 Flags)
  658. {
  659. char *InternalPath;
  660. char *ExternalPath;
  661. ACPI_STATUS Status;
  662. ACPI_FUNCTION_TRACE (DmAddPathToExternalList);
  663. if (!Path)
  664. {
  665. return_VOID;
  666. }
  667. /* Remove a root backslash if present */
  668. if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
  669. {
  670. Path++;
  671. }
  672. /* Create the internal and external pathnames */
  673. Status = AcpiNsInternalizeName (Path, &InternalPath);
  674. if (ACPI_FAILURE (Status))
  675. {
  676. return_VOID;
  677. }
  678. Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
  679. NULL, &ExternalPath);
  680. if (ACPI_FAILURE (Status))
  681. {
  682. ACPI_FREE (InternalPath);
  683. return_VOID;
  684. }
  685. /* Create the new External() declaration node */
  686. Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath,
  687. Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED));
  688. if (ACPI_FAILURE (Status))
  689. {
  690. ACPI_FREE (ExternalPath);
  691. ACPI_FREE (InternalPath);
  692. }
  693. return_VOID;
  694. }
  695. /*******************************************************************************
  696. *
  697. * FUNCTION: AcpiDmCreateNewExternal
  698. *
  699. * PARAMETERS: ExternalPath - External path to the object
  700. * InternalPath - Internal (AML) path to the object
  701. * Type - ACPI object type to be added
  702. * Value - Arg count if adding a Method object
  703. * Flags - To be passed to the external object
  704. *
  705. * RETURN: Status
  706. *
  707. * DESCRIPTION: Common low-level function to insert a new name into the global
  708. * list of Externals which will in turn be later emitted as
  709. * External() declarations in the disassembled output.
  710. *
  711. * Note: The external name should not include a root prefix
  712. * (backslash). We do not want External() statements to contain
  713. * a leading '\', as this prevents duplicate external statements
  714. * of the form:
  715. *
  716. * External (\ABCD)
  717. * External (ABCD)
  718. *
  719. * This would cause a compile time error when the disassembled
  720. * output file is recompiled.
  721. *
  722. * There are two cases that are handled here. For both, we emit
  723. * an External() statement:
  724. * 1) The name was simply not found in the namespace.
  725. * 2) The name was found, but it originated in a table other than
  726. * the table that is being disassembled.
  727. *
  728. ******************************************************************************/
  729. static ACPI_STATUS
  730. AcpiDmCreateNewExternal (
  731. char *ExternalPath,
  732. char *InternalPath,
  733. UINT8 Type,
  734. UINT32 Value,
  735. UINT16 Flags)
  736. {
  737. ACPI_EXTERNAL_LIST *NewExternal;
  738. ACPI_EXTERNAL_LIST *NextExternal;
  739. ACPI_EXTERNAL_LIST *PrevExternal = NULL;
  740. ACPI_FUNCTION_TRACE (DmCreateNewExternal);
  741. /* Check all existing externals to ensure no duplicates */
  742. NextExternal = AcpiGbl_ExternalList;
  743. while (NextExternal)
  744. {
  745. /* Check for duplicates */
  746. if (!strcmp (ExternalPath, NextExternal->Path))
  747. {
  748. /*
  749. * If this external came from an External() opcode, we are
  750. * finished with this one. (No need to check any further).
  751. */
  752. if (NextExternal->Flags & ACPI_EXT_ORIGIN_FROM_OPCODE)
  753. {
  754. return_ACPI_STATUS (AE_ALREADY_EXISTS);
  755. }
  756. /* Allow upgrade of type from ANY */
  757. else if ((NextExternal->Type == ACPI_TYPE_ANY) &&
  758. (Type != ACPI_TYPE_ANY))
  759. {
  760. NextExternal->Type = Type;
  761. }
  762. /* Update the argument count as necessary */
  763. if (Value < NextExternal->Value)
  764. {
  765. NextExternal->Value = Value;
  766. }
  767. /* Update flags. */
  768. NextExternal->Flags |= Flags;
  769. NextExternal->Flags &= ~ACPI_EXT_INTERNAL_PATH_ALLOCATED;
  770. return_ACPI_STATUS (AE_ALREADY_EXISTS);
  771. }
  772. NextExternal = NextExternal->Next;
  773. }
  774. /* Allocate and init a new External() descriptor */
  775. NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
  776. if (!NewExternal)
  777. {
  778. return_ACPI_STATUS (AE_NO_MEMORY);
  779. }
  780. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  781. "Adding external reference node (%s) type [%s]\n",
  782. ExternalPath, AcpiUtGetTypeName (Type)));
  783. NewExternal->Flags = Flags;
  784. NewExternal->Value = Value;
  785. NewExternal->Path = ExternalPath;
  786. NewExternal->Type = Type;
  787. NewExternal->Length = (UINT16) strlen (ExternalPath);
  788. NewExternal->InternalPath = InternalPath;
  789. /* Link the new descriptor into the global list, alphabetically ordered */
  790. NextExternal = AcpiGbl_ExternalList;
  791. while (NextExternal)
  792. {
  793. if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
  794. {
  795. if (PrevExternal)
  796. {
  797. PrevExternal->Next = NewExternal;
  798. }
  799. else
  800. {
  801. AcpiGbl_ExternalList = NewExternal;
  802. }
  803. NewExternal->Next = NextExternal;
  804. return_ACPI_STATUS (AE_OK);
  805. }
  806. PrevExternal = NextExternal;
  807. NextExternal = NextExternal->Next;
  808. }
  809. if (PrevExternal)
  810. {
  811. PrevExternal->Next = NewExternal;
  812. }
  813. else
  814. {
  815. AcpiGbl_ExternalList = NewExternal;
  816. }
  817. return_ACPI_STATUS (AE_OK);
  818. }
  819. /*******************************************************************************
  820. *
  821. * FUNCTION: AcpiDmAddExternalsToNamespace
  822. *
  823. * PARAMETERS: None
  824. *
  825. * RETURN: None
  826. *
  827. * DESCRIPTION: Add all externals to the namespace. Allows externals to be
  828. * "resolved".
  829. *
  830. ******************************************************************************/
  831. void
  832. AcpiDmAddExternalsToNamespace (
  833. void)
  834. {
  835. ACPI_STATUS Status;
  836. ACPI_NAMESPACE_NODE *Node;
  837. ACPI_OPERAND_OBJECT *ObjDesc;
  838. ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
  839. while (External)
  840. {
  841. /* Add the external name (object) into the namespace */
  842. Status = AcpiNsLookup (NULL, External->InternalPath, External->Type,
  843. ACPI_IMODE_LOAD_PASS1,
  844. ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
  845. NULL, &Node);
  846. if (ACPI_FAILURE (Status))
  847. {
  848. ACPI_EXCEPTION ((AE_INFO, Status,
  849. "while adding external to namespace [%s]",
  850. External->Path));
  851. }
  852. else switch (External->Type)
  853. {
  854. case ACPI_TYPE_METHOD:
  855. /* For methods, we need to save the argument count */
  856. ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
  857. ObjDesc->Method.ParamCount = (UINT8) External->Value;
  858. Node->Object = ObjDesc;
  859. break;
  860. case ACPI_TYPE_REGION:
  861. /* Regions require a region sub-object */
  862. ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
  863. ObjDesc->Region.Node = Node;
  864. Node->Object = ObjDesc;
  865. break;
  866. default:
  867. break;
  868. }
  869. External = External->Next;
  870. }
  871. }
  872. /*******************************************************************************
  873. *
  874. * FUNCTION: AcpiDmGetExternalMethodCount
  875. *
  876. * PARAMETERS: None
  877. *
  878. * RETURN: The number of control method externals in the external list
  879. *
  880. * DESCRIPTION: Return the number of method externals that have been generated.
  881. * If any control method externals have been found, we must
  882. * re-parse the entire definition block with the new information
  883. * (number of arguments for the methods.) This is limitation of
  884. * AML, we don't know the number of arguments from the control
  885. * method invocation itself.
  886. *
  887. ******************************************************************************/
  888. UINT32
  889. AcpiDmGetExternalMethodCount (
  890. void)
  891. {
  892. ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList;
  893. UINT32 Count = 0;
  894. while (External)
  895. {
  896. if (External->Type == ACPI_TYPE_METHOD)
  897. {
  898. Count++;
  899. }
  900. External = External->Next;
  901. }
  902. return (Count);
  903. }
  904. /*******************************************************************************
  905. *
  906. * FUNCTION: AcpiDmClearExternalList
  907. *
  908. * PARAMETERS: None
  909. *
  910. * RETURN: None
  911. *
  912. * DESCRIPTION: Free the entire External info list
  913. *
  914. ******************************************************************************/
  915. void
  916. AcpiDmClearExternalList (
  917. void)
  918. {
  919. ACPI_EXTERNAL_LIST *NextExternal;
  920. while (AcpiGbl_ExternalList)
  921. {
  922. NextExternal = AcpiGbl_ExternalList->Next;
  923. ACPI_FREE (AcpiGbl_ExternalList->Path);
  924. ACPI_FREE (AcpiGbl_ExternalList);
  925. AcpiGbl_ExternalList = NextExternal;
  926. }
  927. }
  928. /*******************************************************************************
  929. *
  930. * FUNCTION: AcpiDmEmitExternals
  931. *
  932. * PARAMETERS: None
  933. *
  934. * RETURN: None
  935. *
  936. * DESCRIPTION: Emit an External() ASL statement for each of the externals in
  937. * the global external info list.
  938. *
  939. ******************************************************************************/
  940. void
  941. AcpiDmEmitExternals (
  942. void)
  943. {
  944. ACPI_EXTERNAL_LIST *NextExternal;
  945. if (!AcpiGbl_ExternalList)
  946. {
  947. return;
  948. }
  949. /*
  950. * Determine the number of control methods in the external list, and
  951. * also how many of those externals were resolved via the namespace.
  952. */
  953. NextExternal = AcpiGbl_ExternalList;
  954. while (NextExternal)
  955. {
  956. if (NextExternal->Type == ACPI_TYPE_METHOD)
  957. {
  958. AcpiGbl_NumExternalMethods++;
  959. if (NextExternal->Flags & ACPI_EXT_RESOLVED_REFERENCE)
  960. {
  961. AcpiGbl_ResolvedExternalMethods++;
  962. }
  963. }
  964. NextExternal = NextExternal->Next;
  965. }
  966. /* Check if any control methods were unresolved */
  967. AcpiDmUnresolvedWarning (1);
  968. if (Gbl_ExternalRefFilename)
  969. {
  970. AcpiOsPrintf (
  971. " /*\n * External declarations were imported from\n"
  972. " * a reference file -- %s\n */\n\n",
  973. Gbl_ExternalRefFilename);
  974. }
  975. /*
  976. * Walk and emit the list of externals found during the AML parsing
  977. */
  978. while (AcpiGbl_ExternalList)
  979. {
  980. if (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_EXTERNAL_EMITTED))
  981. {
  982. AcpiOsPrintf (" External (%s%s)",
  983. AcpiGbl_ExternalList->Path,
  984. AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type));
  985. /* Check for "unresolved" method reference */
  986. if ((AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) &&
  987. (!(AcpiGbl_ExternalList->Flags & ACPI_EXT_RESOLVED_REFERENCE)))
  988. {
  989. AcpiOsPrintf (" // Warning: Unknown method, "
  990. "guessing %u arguments",
  991. AcpiGbl_ExternalList->Value);
  992. }
  993. /* Check for external from a external references file */
  994. else if (AcpiGbl_ExternalList->Flags & ACPI_EXT_ORIGIN_FROM_FILE)
  995. {
  996. if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
  997. {
  998. AcpiOsPrintf (" // %u Arguments",
  999. AcpiGbl_ExternalList->Value);
  1000. }
  1001. AcpiOsPrintf (" // From external reference file");
  1002. }
  1003. /* This is the normal external case */
  1004. else
  1005. {
  1006. /* For methods, add a comment with the number of arguments */
  1007. if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD)
  1008. {
  1009. AcpiOsPrintf (" // %u Arguments",
  1010. AcpiGbl_ExternalList->Value);
  1011. }
  1012. }
  1013. AcpiOsPrintf ("\n");
  1014. }
  1015. /* Free this external info block and move on to next external */
  1016. NextExternal = AcpiGbl_ExternalList->Next;
  1017. if (AcpiGbl_ExternalList->Flags & ACPI_EXT_INTERNAL_PATH_ALLOCATED)
  1018. {
  1019. ACPI_FREE (AcpiGbl_ExternalList->InternalPath);
  1020. }
  1021. ACPI_FREE (AcpiGbl_ExternalList->Path);
  1022. ACPI_FREE (AcpiGbl_ExternalList);
  1023. AcpiGbl_ExternalList = NextExternal;
  1024. }
  1025. AcpiOsPrintf ("\n");
  1026. }
  1027. /*******************************************************************************
  1028. *
  1029. * FUNCTION: AcpiDmUnresolvedWarning
  1030. *
  1031. * PARAMETERS: Type - Where to output the warning.
  1032. * 0 means write to stderr
  1033. * 1 means write to AcpiOsPrintf
  1034. *
  1035. * RETURN: None
  1036. *
  1037. * DESCRIPTION: Issue warning message if there are unresolved external control
  1038. * methods within the disassembly.
  1039. *
  1040. ******************************************************************************/
  1041. #if 0
  1042. Summary of the external control method problem:
  1043. When the -e option is used with disassembly, the various SSDTs are simply
  1044. loaded into a global namespace for the disassembler to use in order to
  1045. resolve control method references (invocations).
  1046. The disassembler tracks any such references, and will emit an External()
  1047. statement for these types of methods, with the proper number of arguments .
  1048. Without the SSDTs, the AML does not contain enough information to properly
  1049. disassemble the control method invocation -- because the disassembler does
  1050. not know how many arguments to parse.
  1051. An example: Assume we have two control methods. ABCD has one argument, and
  1052. EFGH has zero arguments. Further, we have two additional control methods
  1053. that invoke ABCD and EFGH, named T1 and T2:
  1054. Method (ABCD, 1)
  1055. {
  1056. }
  1057. Method (EFGH, 0)
  1058. {
  1059. }
  1060. Method (T1)
  1061. {
  1062. ABCD (Add (2, 7, Local0))
  1063. }
  1064. Method (T2)
  1065. {
  1066. EFGH ()
  1067. Add (2, 7, Local0)
  1068. }
  1069. Here is the AML code that is generated for T1 and T2:
  1070. 185: Method (T1)
  1071. 0000034C: 14 10 54 31 5F 5F 00 ... "..T1__."
  1072. 186: {
  1073. 187: ABCD (Add (2, 7, Local0))
  1074. 00000353: 41 42 43 44 ............ "ABCD"
  1075. 00000357: 72 0A 02 0A 07 60 ...... "r....`"
  1076. 188: }
  1077. 190: Method (T2)
  1078. 0000035D: 14 10 54 32 5F 5F 00 ... "..T2__."
  1079. 191: {
  1080. 192: EFGH ()
  1081. 00000364: 45 46 47 48 ............ "EFGH"
  1082. 193: Add (2, 7, Local0)
  1083. 00000368: 72 0A 02 0A 07 60 ...... "r....`"
  1084. 194: }
  1085. Note that the AML code for T1 and T2 is essentially identical. When
  1086. disassembling this code, the methods ABCD and EFGH must be known to the
  1087. disassembler, otherwise it does not know how to handle the method invocations.
  1088. In other words, if ABCD and EFGH are actually external control methods
  1089. appearing in an SSDT, the disassembler does not know what to do unless
  1090. the owning SSDT has been loaded via the -e option.
  1091. #endif
  1092. static char ExternalWarningPart1[600];
  1093. static char ExternalWarningPart2[400];
  1094. static char ExternalWarningPart3[400];
  1095. static char ExternalWarningPart4[200];
  1096. void
  1097. AcpiDmUnresolvedWarning (
  1098. UINT8 Type)
  1099. {
  1100. char *Format;
  1101. char Pad[] = " *";
  1102. char NoPad[] = "";
  1103. if (!AcpiGbl_NumExternalMethods)
  1104. {
  1105. return;
  1106. }
  1107. if (AcpiGbl_NumExternalMethods == AcpiGbl_ResolvedExternalMethods)
  1108. {
  1109. return;
  1110. }
  1111. Format = Type ? Pad : NoPad;
  1112. sprintf (ExternalWarningPart1,
  1113. "%s iASL Warning: There %s %u external control method%s found during\n"
  1114. "%s disassembly, but only %u %s resolved (%u unresolved). Additional\n"
  1115. "%s ACPI tables may be required to properly disassemble the code. This\n"
  1116. "%s resulting disassembler output file may not compile because the\n"
  1117. "%s disassembler did not know how many arguments to assign to the\n"
  1118. "%s unresolved methods. Note: SSDTs can be dynamically loaded at\n"
  1119. "%s runtime and may or may not be available via the host OS.\n",
  1120. Format, (AcpiGbl_NumExternalMethods != 1 ? "were" : "was"),
  1121. AcpiGbl_NumExternalMethods, (AcpiGbl_NumExternalMethods != 1 ? "s" : ""),
  1122. Format, AcpiGbl_ResolvedExternalMethods,
  1123. (AcpiGbl_ResolvedExternalMethods != 1 ? "were" : "was"),
  1124. (AcpiGbl_NumExternalMethods - AcpiGbl_ResolvedExternalMethods),
  1125. Format, Format, Format, Format, Format);
  1126. sprintf (ExternalWarningPart2,
  1127. "%s To specify the tables needed to resolve external control method\n"
  1128. "%s references, the -e option can be used to specify the filenames.\n"
  1129. "%s Example iASL invocations:\n"
  1130. "%s iasl -e ssdt1.aml ssdt2.aml ssdt3.aml -d dsdt.aml\n"
  1131. "%s iasl -e dsdt.aml ssdt2.aml -d ssdt1.aml\n"
  1132. "%s iasl -e ssdt*.aml -d dsdt.aml\n",
  1133. Format, Format, Format, Format, Format, Format);
  1134. sprintf (ExternalWarningPart3,
  1135. "%s In addition, the -fe option can be used to specify a file containing\n"
  1136. "%s control method external declarations with the associated method\n"
  1137. "%s argument counts. Each line of the file must be of the form:\n"
  1138. "%s External (<method pathname>, MethodObj, <argument count>)\n"
  1139. "%s Invocation:\n"
  1140. "%s iasl -fe refs.txt -d dsdt.aml\n",
  1141. Format, Format, Format, Format, Format, Format);
  1142. sprintf (ExternalWarningPart4,
  1143. "%s The following methods were unresolved and many not compile properly\n"
  1144. "%s because the disassembler had to guess at the number of arguments\n"
  1145. "%s required for each:\n",
  1146. Format, Format, Format);
  1147. if (Type)
  1148. {
  1149. if (!AcpiGbl_ExternalFileList)
  1150. {
  1151. /* The -e option was not specified */
  1152. AcpiOsPrintf (" /*\n%s *\n%s *\n%s *\n%s */\n",
  1153. ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3,
  1154. ExternalWarningPart4);
  1155. }
  1156. else
  1157. {
  1158. /* The -e option was specified, but there are still some unresolved externals */
  1159. AcpiOsPrintf (" /*\n%s *\n%s *\n%s */\n",
  1160. ExternalWarningPart1, ExternalWarningPart3, ExternalWarningPart4);
  1161. }
  1162. }
  1163. else
  1164. {
  1165. if (!AcpiGbl_ExternalFileList)
  1166. {
  1167. /* The -e option was not specified */
  1168. fprintf (stderr, "\n%s\n%s\n%s\n",
  1169. ExternalWarningPart1, ExternalWarningPart2, ExternalWarningPart3);
  1170. }
  1171. else
  1172. {
  1173. /* The -e option was specified, but there are still some unresolved externals */
  1174. fprintf (stderr, "\n%s\n%s\n",
  1175. ExternalWarningPart1, ExternalWarningPart3);
  1176. }
  1177. }
  1178. }