cvdisasm.c revision 1.1 1 /******************************************************************************
2 *
3 * Module Name: cvcompiler - ASL-/ASL+ converter functions
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2017, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44 #include "aslcompiler.h"
45 #include "acparser.h"
46 #include "amlcode.h"
47 #include "acdebug.h"
48 #include "acconvert.h"
49
50
51 static void
52 CvPrintInclude(
53 ACPI_FILE_NODE *FNode,
54 UINT32 Level);
55
56 static BOOLEAN
57 CvListIsSingleton (
58 ACPI_COMMENT_NODE *CommentList);
59
60
61 /*******************************************************************************
62 *
63 * FUNCTION: CvPrintOneCommentList
64 *
65 * PARAMETERS: CommentList
66 * Level
67 *
68 * RETURN: None
69 *
70 * DESCRIPTION: Prints all comments within the given list.
71 * This is referred as ASL_CV_PRINT_ONE_COMMENT_LIST.
72 *
73 ******************************************************************************/
74
75 void
76 CvPrintOneCommentList (
77 ACPI_COMMENT_NODE *CommentList,
78 UINT32 Level)
79 {
80 ACPI_COMMENT_NODE *Current = CommentList;
81 ACPI_COMMENT_NODE *Previous;
82
83
84 while (Current)
85 {
86 Previous = Current;
87 if (Current->Comment)
88 {
89 AcpiDmIndent(Level);
90 AcpiOsPrintf("%s\n", Current->Comment);
91 Current->Comment = NULL;
92 }
93 Current = Current->Next;
94 AcpiOsReleaseObject(AcpiGbl_RegCommentCache, Previous);
95 }
96 }
97
98
99 /*******************************************************************************
100 *
101 * FUNCTION: CvListIsSingleton
102 *
103 * PARAMETERS: CommentList -- check to see if this is a single item list.
104 *
105 * RETURN: BOOLEAN
106 *
107 * DESCRIPTION: Returns TRUE if CommentList only contains 1 node.
108 *
109 ******************************************************************************/
110
111 static BOOLEAN
112 CvListIsSingleton (
113 ACPI_COMMENT_NODE *CommentList)
114
115 {
116 if (!CommentList)
117 {
118 return FALSE;
119 }
120 else if (CommentList->Next)
121 {
122 return FALSE;
123 }
124
125 return TRUE;
126 }
127
128
129 /*******************************************************************************
130 *
131 * FUNCTION: CvPrintOneCommentType
132 *
133 * PARAMETERS: Op
134 * CommentType
135 * EndStr - String to print after printing the comment
136 * Level - indentation level for comment lists.
137 *
138 * RETURN: None
139 *
140 * DESCRIPTION: Prints all comments of CommentType within the given Op and
141 * clears the printed comment from the Op.
142 * This is referred as ASL_CV_PRINT_ONE_COMMENT.
143 *
144 ******************************************************************************/
145
146 void
147 CvPrintOneCommentType (
148 ACPI_PARSE_OBJECT *Op,
149 UINT8 CommentType,
150 char* EndStr,
151 UINT32 Level)
152 {
153 BOOLEAN CommentExists = FALSE;
154 char **CommentToPrint = NULL;
155
156
157 switch (CommentType)
158 {
159 case AML_COMMENT_STANDARD:
160
161 if (CvListIsSingleton (Op->Common.CommentList))
162 {
163 CvPrintOneCommentList (Op->Common.CommentList, Level);
164 AcpiOsPrintf ("\n");
165 }
166 else
167 {
168 CvPrintOneCommentList (Op->Common.CommentList, Level);
169 }
170 Op->Common.CommentList = NULL;
171 return;
172
173 case AML_COMMENT_ENDBLK:
174
175 if (Op->Common.EndBlkComment)
176 {
177 CvPrintOneCommentList (Op->Common.EndBlkComment, Level);
178 Op->Common.EndBlkComment = NULL;
179 AcpiDmIndent(Level);
180 }
181 return;
182
183 case AMLCOMMENT_INLINE:
184
185 CommentToPrint = &Op->Common.InlineComment;
186 break;
187
188 case AML_COMMENT_END_NODE:
189
190 CommentToPrint = &Op->Common.EndNodeComment;
191 break;
192
193 case AML_NAMECOMMENT:
194
195 CommentToPrint = &Op->Common.NameComment;
196 break;
197
198 case AML_COMMENT_CLOSE_BRACE:
199
200 CommentToPrint = &Op->Common.CloseBraceComment;
201 break;
202
203 default:
204 return;
205 }
206
207 if (*CommentToPrint)
208 {
209 AcpiOsPrintf ("%s", *CommentToPrint);
210 *CommentToPrint = NULL;
211 }
212
213 if (CommentExists && EndStr)
214 {
215 AcpiOsPrintf ("%s", EndStr);
216 }
217 }
218
219
220 /*******************************************************************************
221 *
222 * FUNCTION: CvCloseBraceWriteComment
223 *
224 * PARAMETERS: Op
225 * Level
226 *
227 * RETURN: none
228 *
229 * DESCRIPTION: Print a close brace } and any open brace comments associated
230 * with this parse object.
231 * This is referred as ASL_CV_CLOSE_BRACE.
232 *
233 ******************************************************************************/
234
235 void
236 CvCloseBraceWriteComment(
237 ACPI_PARSE_OBJECT *Op,
238 UINT32 Level)
239 {
240 if (!Gbl_CaptureComments)
241 {
242 AcpiOsPrintf ("}");
243 return;
244 }
245
246 CvPrintOneCommentType (Op, AML_COMMENT_ENDBLK, NULL, Level);
247 AcpiOsPrintf ("}");
248 CvPrintOneCommentType (Op, AML_COMMENT_CLOSE_BRACE, NULL, Level);
249 }
250
251
252 /*******************************************************************************
253 *
254 * FUNCTION: CvCloseParenWriteComment
255 *
256 * PARAMETERS: Op
257 * Level
258 *
259 * RETURN: none
260 *
261 * DESCRIPTION: Print a closing paren ) and any end node comments associated
262 * with this parse object.
263 * This is referred as ASL_CV_CLOSE_PAREN.
264 *
265 ******************************************************************************/
266
267 void
268 CvCloseParenWriteComment(
269 ACPI_PARSE_OBJECT *Op,
270 UINT32 Level)
271 {
272 if (!Gbl_CaptureComments)
273 {
274 AcpiOsPrintf (")");
275 return;
276 }
277
278 /*
279 * If this op has a BLOCK_BRACE, then output the comment when the
280 * disassembler calls CvCloseBraceWriteComment
281 */
282 if (AcpiDmBlockType (Op) == BLOCK_PAREN)
283 {
284 CvPrintOneCommentType (Op, AML_COMMENT_ENDBLK, NULL, Level);
285 }
286
287 AcpiOsPrintf (")");
288
289 if (Op->Common.EndNodeComment)
290 {
291 CvPrintOneCommentType (Op, AML_COMMENT_END_NODE, NULL, Level);
292 }
293 else if ((Op->Common.Parent->Common.AmlOpcode == AML_IF_OP) &&
294 Op->Common.Parent->Common.EndNodeComment)
295 {
296 CvPrintOneCommentType (Op->Common.Parent,
297 AML_COMMENT_END_NODE, NULL, Level);
298 }
299 }
300
301
302 /*******************************************************************************
303 *
304 * FUNCTION: CvFileHasSwitched
305 *
306 * PARAMETERS: Op
307 *
308 * RETURN: BOOLEAN
309 *
310 * DESCRIPTION: Determine whether if a file has switched.
311 * TRUE - file has switched.
312 * FALSE - file has not switched.
313 * This is referred as ASL_CV_FILE_HAS_SWITCHED.
314 *
315 ******************************************************************************/
316
317 BOOLEAN
318 CvFileHasSwitched(
319 ACPI_PARSE_OBJECT *Op)
320 {
321 if (Op->Common.CvFilename &&
322 AcpiGbl_CurrentFilename &&
323 AcpiUtStricmp(Op->Common.CvFilename, AcpiGbl_CurrentFilename))
324 {
325 return TRUE;
326 }
327 return FALSE;
328 }
329
330
331 /*******************************************************************************
332 *
333 * FUNCTION: CvPrintInclude
334 *
335 * PARAMETERS: FNode - Write an Include statement for the file that is pointed
336 * by FNode->File.
337 * Level - indentation level
338 *
339 * RETURN: None
340 *
341 * DESCRIPTION: Write the ASL Include statement for FNode->File in the file
342 * indicated by FNode->Parent->File. Note this function emits
343 * actual ASL code rather than comments. This switches the output
344 * file to FNode->Parent->File.
345 *
346 ******************************************************************************/
347
348 static void
349 CvPrintInclude(
350 ACPI_FILE_NODE *FNode,
351 UINT32 Level)
352 {
353 if (!FNode || FNode->IncludeWritten)
354 {
355 return;
356 }
357
358 CvDbgPrint ("Writing include for %s within %s\n", FNode->Filename, FNode->Parent->Filename);
359 AcpiOsRedirectOutput (FNode->Parent->File);
360 CvPrintOneCommentList (FNode->IncludeComment, Level);
361 AcpiDmIndent (Level);
362 AcpiOsPrintf ("Include (\"%s\")\n", FNode->Filename);
363 CvDbgPrint ("emitted the following: Include (\"%s\")\n", FNode->Filename);
364 FNode->IncludeWritten = TRUE;
365 }
366
367
368 /*******************************************************************************
369 *
370 * FUNCTION: CvSwitchFiles
371 *
372 * PARAMETERS: Level - indentation level
373 * Op
374 *
375 * RETURN: None
376 *
377 * DESCRIPTION: Switch the outputfile and write ASL Include statement. Note,
378 * this function emits actual ASL code rather than comments.
379 * This is referred as ASL_CV_SWITCH_FILES.
380 *
381 ******************************************************************************/
382
383 void
384 CvSwitchFiles(
385 UINT32 Level,
386 ACPI_PARSE_OBJECT *Op)
387 {
388 char *Filename = Op->Common.CvFilename;
389 ACPI_FILE_NODE *FNode;
390
391 CvDbgPrint ("Switching from %s to %s\n", AcpiGbl_CurrentFilename, Filename);
392 FNode = CvFilenameExists (Filename, AcpiGbl_FileTreeRoot);
393 if (!FNode)
394 {
395 /*
396 * At this point, each Filename should exist in AcpiGbl_FileTreeRoot
397 * if it does not exist, then abort.
398 */
399 FlDeleteFile (ASL_FILE_AML_OUTPUT);
400 sprintf (MsgBuffer, "\"Cannot find %s\" - %s", Filename, strerror (errno));
401 AslCommonError (ASL_ERROR, ASL_MSG_OPEN, 0, 0, 0, 0, NULL, MsgBuffer);
402 AslAbort ();
403 }
404
405 /*
406 * If the previous file is a descendent of the current file,
407 * make sure that Include statements from the current file
408 * to the previous have been emitted.
409 */
410 while (FNode &&
411 FNode->Parent &&
412 AcpiUtStricmp (FNode->Filename, AcpiGbl_CurrentFilename))
413 {
414 CvPrintInclude (FNode, Level);
415 FNode = FNode->Parent;
416 }
417
418 /* Redirect output to the Op->Common.CvFilename */
419
420 FNode = CvFilenameExists (Filename, AcpiGbl_FileTreeRoot);
421 AcpiOsRedirectOutput (FNode->File);
422 AcpiGbl_CurrentFilename = FNode->Filename;
423 }
424