Home | History | Annotate | Download | only in generator
      1 # Copyright 2014 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """A code generator for TPM 2.0 commands.
      6 
      7 The command generator takes as input a list of command objects generated by
      8 parsing the TCG specification and outputs valid C code to marshal command
      9 input and output structures, and also generates functions ParseHandleBuffer
     10 and CommandDispatcher defined by the TCG TPM2.0 Library Specification.
     11 
     12 """
     13 
     14 from __future__ import print_function
     15 
     16 import re
     17 from subprocess import call
     18 
     19 from structure_generator import COPYRIGHT_HEADER
     20 from structure_generator import Field
     21 
     22 _HEADER_FILE_GUARD_HEADER = """
     23 #ifndef TPM2_%(name)s_FP_H_
     24 #define TPM2_%(name)s_FP_H_
     25 """
     26 _HEADER_FILE_GUARD_FOOTER = """
     27 #endif  // TPM2_%(name)s_FP_H
     28 """
     29 _HEADER_FILE_INCLUDES = """
     30 #include "tpm_generated.h"
     31 """
     32 _IMPLEMENTATION_FILE_INCLUDES = """
     33 #include "MemoryLib_fp.h"
     34 #include "%(command_name)s_fp.h"
     35 """
     36 _COMMAND_DISPATCHER_INCLUDES = '#include "%(command_name)s_fp.h"\n'
     37 _COMMAND_DISPATCHER_START = """
     38 #include "Implementation.h"
     39 #include "CommandDispatcher_fp.h"
     40 
     41 TPM_RC CommandDispatcher(
     42     TPMI_ST_COMMAND_TAG tag,
     43     TPM_CC command_code,
     44     INT32 *request_parameter_buffer_size,
     45     BYTE *request_parameter_buffer_start,
     46     TPM_HANDLE request_handles[],
     47     UINT32 *response_handle_buffer_size,
     48     UINT32 *response_parameter_buffer_size) {
     49   BYTE *request_parameter_buffer = request_parameter_buffer_start;
     50   switch(command_code) {"""
     51 _COMMAND_DISPATCHER_CASE = """
     52 #ifdef %(command_code)s
     53     case %(command_code)s:
     54       return Exec_%(command_name)s(tag, &request_parameter_buffer,
     55           request_parameter_buffer_size, request_handles,
     56           response_handle_buffer_size, response_parameter_buffer_size);
     57 #endif"""
     58 _COMMAND_DISPATCHER_END = """
     59     default:
     60       return TPM_RC_COMMAND_CODE;
     61   }
     62 }"""
     63 _HANDLE_PROCESS_START = """
     64 #include "tpm_generated.h"
     65 #include "HandleProcess_fp.h"
     66 #include "Implementation.h"
     67 #include "TPM_Types.h"
     68 
     69 TPM_RC ParseHandleBuffer(
     70     TPM_CC command_code,
     71     BYTE **request_handle_buffer_start,
     72     INT32 *request_buffer_remaining_size,
     73     TPM_HANDLE request_handles[],
     74     UINT32 *num_request_handles) {
     75   TPM_RC result = TPM_RC_SUCCESS;
     76   *num_request_handles = 0;
     77   switch(command_code) {
     78 """
     79 _HANDLE_PROCESS_CASE_START = """
     80 #ifdef %(command_code)s
     81     case %(command_code)s:"""
     82 _HANDLE_PROCESS_CASE_UNMARSHAL = """
     83       result = %(handle_type)s_Unmarshal(
     84           (%(handle_type)s*)&request_handles[*num_request_handles],
     85           request_handle_buffer_start,
     86           request_buffer_remaining_size);"""
     87 _HANDLE_PROCESS_CASE_UNMARSHAL_FLAG = """
     88       result = %(handle_type)s_Unmarshal(
     89           (%(handle_type)s*)&request_handles[*num_request_handles],
     90           request_handle_buffer_start,
     91           request_buffer_remaining_size,
     92           %(flag_val)s);"""
     93 _HANDLE_PROCESS_CASE_CHECK = """
     94       if (result != TPM_RC_SUCCESS) {
     95         return result;
     96       }
     97       ++(*num_request_handles);"""
     98 _HANDLE_PROCESS_CASE_END = """
     99       return TPM_RC_SUCCESS;
    100 #endif"""
    101 _HANDLE_PROCESS_END = """
    102     default:
    103       return TPM_RC_COMMAND_CODE;
    104   }
    105 }"""
    106 _GET_COMMAND_CODE_STRING_HEADER = """
    107 #ifndef TPM2_GET_COMMAND_CODE_STRING_FP_H_
    108 #define TPM2_GET_COMMAND_CODE_STRING_FP_H_
    109 
    110 #include "TPM_Types.h"
    111 
    112 const char* GetCommandCodeString(TPM_CC command_code);
    113 
    114 #endif  // TPM2_GET_COMMAND_CODE_STRING_FP_H_"""
    115 _GET_COMMAND_CODE_STRING_START = """
    116 #include "GetCommandCodeString_fp.h"
    117 
    118 const char* GetCommandCodeString(TPM_CC command_code) {
    119   switch(command_code) {"""
    120 _GET_COMMAND_CODE_STRING_CASE = """
    121 #ifdef TPM_CC_%(command_name)s
    122   case TPM_CC_%(command_name)s:
    123       return "%(command_name)s";
    124 #endif"""
    125 _GET_COMMAND_CODE_STRING_END = """
    126     default:
    127       return "Unknown command";
    128   }
    129 }"""
    130 
    131 
    132 class Command(object):
    133   """Represents a TPM command.
    134 
    135   Attributes:
    136     name: The command name (e.g. 'TPM2_Startup').
    137     command_code: The name of the command code constant (e.g. TPM2_CC_Startup).
    138     request_args: A list to hold command input arguments. Each element is a dict
    139         and has these keys:
    140             'type': The argument type.
    141             'name': The argument name.
    142             'command_code': The optional value of the command code constant.
    143             'description': Optional descriptive text for the argument.
    144             'has_conditional': String literal 'TRUE' or 'FALSE' indicating
    145                 whether 'type' is allowed to have a conditional value.
    146     response_args: A list identical in form to request_args but to hold command
    147         output arguments.
    148   """
    149 
    150   _HANDLE_RE = re.compile(r'TPMI_.H_.*')
    151   _STRUCT_DECL_START = """
    152 typedef struct {"""
    153   _STRUCT_DECL_FIELD = """
    154   %(type)s %(name)s;"""
    155   _STRUCT_DECL_END = """
    156 } %(command_name)s_%(direction)s;
    157 """
    158   _FUNCTION_DECL_IN_OUT = """
    159 // Executes %(command_name)s with request handles and parameters from
    160 // |in| and computes response handles and parameters to |out|.
    161 TPM_RC TPM2_%(command_name)s(
    162     %(command_name)s_In *in,
    163     %(command_name)s_Out *out);
    164 
    165 // Initializes handle fields in |target| from |request_handles|. Unmarshals
    166 // parameter fields in |target| from |buffer|.
    167 TPM_RC %(command_name)s_In_Unmarshal(
    168     %(command_name)s_In *target,
    169     TPM_HANDLE request_handles[],
    170     BYTE **buffer,
    171     INT32 *size);
    172 
    173 // Marshals response handles and parameters from |source| to |buffer|. Computes
    174 // and marshals the size of the parameter area (parameter_size) if |tag| ==
    175 // TPM_ST_SESSIONS. Returns size of (parameter area + handle area) in bytes.
    176 // Return value does not include parameter_size field.
    177 UINT16 %(command_name)s_Out_Marshal(
    178     %(command_name)s_Out *source,
    179     TPMI_ST_COMMAND_TAG tag,
    180     BYTE **buffer,
    181     INT32 *size);
    182 """
    183   _FUNCTION_DECL_IN = """
    184 // Executes %(command_name)s with request handles and parameters from |in|.
    185 TPM_RC TPM2_%(command_name)s(
    186     %(command_name)s_In *in);
    187 
    188 // Initializes handle fields in |target| from |request_handles|. Unmarshals
    189 // parameter fields in |target| from |buffer|.
    190 TPM_RC %(command_name)s_In_Unmarshal(
    191     %(command_name)s_In *target,
    192     TPM_HANDLE request_handles[],
    193     BYTE **buffer,
    194     INT32 *size);
    195 """
    196   _FUNCTION_DECL_OUT = """
    197 // Executes %(command_name)s and computes response handles and parameters
    198 // to |out|.
    199 TPM_RC TPM2_%(command_name)s(
    200     %(command_name)s_Out *out);
    201 
    202 // Marshals response handles and parameters from |source| to |buffer|. Computes
    203 // and marshals the size of the parameter area (parameter_size) if |tag| ==
    204 // TPM_ST_SESSIONS. Returns size of (parameter area + handle area) in bytes.
    205 // Does not include parameter_size field.
    206 UINT16 %(command_name)s_Out_Marshal(
    207     %(command_name)s_Out *source,
    208     TPMI_ST_COMMAND_TAG tag,
    209     BYTE **buffer,
    210     INT32 *size);
    211 """
    212   _EXEC_DECL = """
    213 // Unmarshals any request parameters starting at |request_parameter_buffer|.
    214 // Executes command. Marshals any response handles and parameters to the
    215 // global response buffer and computes |*response_handle_buffer_size| and
    216 // |*response_parameter_buffer_size|. If |tag| == TPM_ST_SESSIONS, marshals
    217 // parameter_size indicating the size of the parameter area. parameter_size
    218 // field is located between the handle area and parameter area.
    219 TPM_RC Exec_%(command_name)s(
    220     TPMI_ST_COMMAND_TAG tag,
    221     BYTE **request_parameter_buffer,
    222     INT32 *request_parameter_buffer_size,
    223     TPM_HANDLE request_handles[],
    224     UINT32 *response_handle_buffer_size,
    225     UINT32 *response_parameter_buffer_size);
    226 """
    227   _EXEC_COMMAND_IMPL_START = """
    228 TPM_RC Exec_%(command_name)s(
    229     TPMI_ST_COMMAND_TAG tag,
    230     BYTE **request_parameter_buffer,
    231     INT32 *request_parameter_buffer_size,
    232     TPM_HANDLE request_handles[],
    233     UINT32 *response_handle_buffer_size,
    234     UINT32 *response_parameter_buffer_size) {
    235   TPM_RC result = TPM_RC_SUCCESS;"""
    236   _EXEC_COMMAND_IMPL_IN_OUT = """
    237   %(command_name)s_In in;
    238   %(command_name)s_Out out;
    239 #ifdef %(command_code)s
    240   BYTE *response_buffer;
    241   INT32 response_buffer_size;
    242   UINT16 bytes_marshalled;
    243   UINT16 num_response_handles = %(num_response_handles)s;
    244 #endif
    245   *response_handle_buffer_size = 0;
    246   *response_parameter_buffer_size = 0;
    247   // Unmarshal request parameters to input structure.
    248   result = %(command_name)s_In_Unmarshal(&in, request_handles,
    249       request_parameter_buffer, request_parameter_buffer_size);
    250   if (result != TPM_RC_SUCCESS) {
    251     return result;
    252   }
    253   // Execute command.
    254   result = TPM2_%(command_name)s(&in, &out);
    255   if (result != TPM_RC_SUCCESS) {
    256     return result;
    257   }
    258   // Marshal output structure to global response buffer.
    259 #ifdef %(command_code)s
    260   response_buffer = MemoryGetResponseBuffer(%(command_code)s) + 10;
    261   response_buffer_size = MAX_RESPONSE_SIZE - 10;
    262   bytes_marshalled = %(command_name)s_Out_Marshal(
    263       &out, tag, &response_buffer, &response_buffer_size);
    264   *response_handle_buffer_size = num_response_handles*sizeof(TPM_HANDLE);
    265   *response_parameter_buffer_size =
    266       bytes_marshalled - *response_handle_buffer_size;
    267   return TPM_RC_SUCCESS;
    268 #endif
    269   return TPM_RC_COMMAND_CODE;
    270 }
    271 """
    272   _EXEC_COMMAND_IMPL_IN = """
    273   %(command_name)s_In in;
    274 #ifdef %(command_code)s
    275   BYTE *response_buffer;
    276   INT32 response_buffer_size;
    277 #endif
    278   *response_handle_buffer_size = 0;
    279   *response_parameter_buffer_size = 0;
    280   // Unmarshal request parameters to input structure.
    281   result = %(command_name)s_In_Unmarshal(&in, request_handles,
    282       request_parameter_buffer, request_parameter_buffer_size);
    283   if (result != TPM_RC_SUCCESS) {
    284     return result;
    285   }
    286   // Execute command.
    287   result = TPM2_%(command_name)s(&in);
    288   if (result != TPM_RC_SUCCESS) {
    289     return result;
    290   }
    291 #ifdef %(command_code)s
    292   response_buffer = MemoryGetResponseBuffer(%(command_code)s) + 10;
    293   response_buffer_size = MAX_RESPONSE_SIZE - 10;
    294   // Add parameter_size field, always equal to 0 here.
    295   if (tag == TPM_ST_SESSIONS) {
    296     UINT32_Marshal(response_parameter_buffer_size, &response_buffer,
    297         &response_buffer_size);
    298   }
    299   return TPM_RC_SUCCESS;
    300 #endif
    301   return TPM_RC_COMMAND_CODE;
    302 }
    303 """
    304   _EXEC_COMMAND_IMPL_OUT = """
    305   %(command_name)s_Out out;
    306 #ifdef %(command_code)s
    307   BYTE *response_buffer;
    308   INT32 response_buffer_size;
    309   UINT16 bytes_marshalled;
    310   UINT16 num_response_handles = %(num_response_handles)s;
    311 #endif
    312   *response_handle_buffer_size = 0;
    313   *response_parameter_buffer_size = 0;
    314   // Execute command.
    315   result = TPM2_%(command_name)s(&out);
    316   if (result != TPM_RC_SUCCESS) {
    317     return result;
    318   }
    319   // Marshal output structure containing response handles and parameters to
    320   // response buffer.
    321 #ifdef %(command_code)s
    322   response_buffer = MemoryGetResponseBuffer(%(command_code)s) + 10;
    323   response_buffer_size = MAX_RESPONSE_SIZE - 10;
    324   bytes_marshalled = %(command_name)s_Out_Marshal(
    325       &out, tag, &response_buffer, &response_buffer_size);
    326   *response_handle_buffer_size = num_response_handles*sizeof(TPM_HANDLE);
    327   *response_parameter_buffer_size =
    328       bytes_marshalled - *response_handle_buffer_size;
    329   return TPM_RC_SUCCESS;
    330 #endif
    331   return TPM_RC_COMMAND_CODE;
    332 }
    333 """
    334   _UNMARSHAL_COMMAND_START = """
    335 TPM_RC %(command_name)s_In_Unmarshal(
    336     %(command_name)s_In *target,
    337     TPM_HANDLE request_handles[],
    338     BYTE **buffer,
    339     INT32 *size) {
    340   TPM_RC result = TPM_RC_SUCCESS;"""
    341   _MARSHAL_COMMAND_START = """
    342 UINT16 %(command_name)s_Out_Marshal(
    343     %(command_name)s_Out *source,
    344     TPMI_ST_COMMAND_TAG tag,
    345     BYTE **buffer,
    346     INT32 *size) {
    347   UINT16 total_size = 0;
    348   UINT32 parameter_size = 0;
    349   BYTE *parameter_size_location;
    350   INT32 parameter_size_size = sizeof(UINT32);
    351   UINT32 num_response_handles = %(num_response_handles)s;"""
    352   _UNMARSHAL_END = """
    353   if ((result == TPM_RC_SUCCESS) && *size) {
    354     result = TPM_RC_SIZE;
    355   }
    356   return result;
    357 }
    358 """
    359   _MARSHAL_END = """
    360   // Compute actual parameter_size. Don't add result to total_size.
    361   if (tag == TPM_ST_SESSIONS) {
    362     parameter_size = total_size - num_response_handles*sizeof(TPM_HANDLE);
    363     UINT32_Marshal(
    364         &parameter_size, &parameter_size_location, &parameter_size_size);
    365   }
    366   return total_size;
    367 }
    368 """
    369   _SET_COMMAND_HANDLE = """
    370   target->%(field_name)s = request_handles[%(num)s];"""
    371   _PARAMETERSIZE_CHECK = """
    372   // Add parameter_size=0 to indicate size of the parameter area. Will be
    373   // replaced later by computed parameter_size.
    374   if (tag == TPM_ST_SESSIONS) {
    375     parameter_size_location = *buffer;
    376     // Don't add to total_size, but increment *buffer and decrement *size.
    377     UINT32_Marshal(&parameter_size, buffer, size);
    378   }"""
    379 
    380   def __init__(self, name):
    381     """Initializes a Command instance.
    382 
    383     Initially the request_args and response_args attributes are not set.
    384 
    385     Args:
    386       name: The command name (e.g. 'TPM2_Startup').
    387     """
    388     self.name = name
    389     self.request_args = None
    390     self.response_args = None
    391     if name.startswith('TPM2_'):
    392       self.command_code = name.replace('TPM2_', 'TPM_CC_')
    393     else:
    394       self.command_code = ''
    395 
    396   def __str__(self):
    397     s = ['%s:' % self.name,]
    398     if self.request_args:
    399       s.append(' req:')
    400       for r in self.request_args:
    401         s.append('  %s: %s' % (r['type'], r['name']))
    402     if self.response_args:
    403       s.append(' resp:')
    404       for r in self.response_args:
    405         s.append('  %s: %s' % (r['type'], r['name']))
    406     s.append('')
    407     return '\n'.join(s)
    408 
    409   def OutputMarshalFunction(self, out_file, typemap):
    410     """Generates a marshal function for the command output structure.
    411 
    412     Args:
    413       out_file: File to be written to opened by the caller.
    414       typemap: A dict mapping type names to the corresponding object.
    415           Generated by structure_generator.
    416     """
    417     if not self.response_args:
    418       return
    419     # Categorize arguments as either handles or parameters.
    420     handles, parameters = self._SplitArgs(self.response_args)
    421     out_file.write(self._MARSHAL_COMMAND_START % {
    422         'command_name': self.MethodName(),
    423         'num_response_handles': self._GetNumberOfResponseHandles()})
    424     if handles:
    425       out_file.write('\n  // Marshal response handles.')
    426     for handle in handles:
    427       typemap[handle['type']].OutputMarshalCall(
    428           out_file, Field(handle['type'],
    429                           handle['name'],
    430                           conditional_value=handle['has_conditional']))
    431     out_file.write(self._PARAMETERSIZE_CHECK)
    432     if parameters:
    433       out_file.write('\n  // Marshal response parameters.')
    434     for parameter in parameters:
    435       typemap[parameter['type']].OutputMarshalCall(
    436           out_file, Field(parameter['type'], parameter['name'],
    437                           conditional_value=parameter['has_conditional']))
    438     out_file.write(self._MARSHAL_END)
    439 
    440   def OutputUnmarshalFunction(self, out_file, typemap):
    441     """Generates a unmarshal function for the command input structure.
    442 
    443     Args:
    444       out_file: File to be written to opened by the caller.
    445       typemap: A dict mapping type names to the corresponding object.
    446           Generated by structure_generator.
    447     """
    448     if not self.request_args:
    449       return
    450     # Categorize arguments as either handles or parameters.
    451     handles, parameters = self._SplitArgs(self.request_args)
    452     out_file.write(self._UNMARSHAL_COMMAND_START % {
    453         'command_name': self.MethodName()})
    454     if handles:
    455       out_file.write('\n  // Get request handles from request_handles array.')
    456     for index, handle in enumerate(handles):
    457       out_file.write(self._SET_COMMAND_HANDLE % {'field_name': handle['name'],
    458                                                  'num': index})
    459     if parameters:
    460       out_file.write('\n  // Unmarshal request parameters.')
    461     for parameter in parameters:
    462       typemap[parameter['type']].OutputUnmarshalCall(
    463           out_file, Field(parameter['type'],
    464                           parameter['name'],
    465                           conditional_value=parameter['has_conditional']))
    466     out_file.write(self._UNMARSHAL_END)
    467 
    468   def OutputExecFunction(self, out_file):
    469     """Generates an exec function for the command.
    470 
    471     Args:
    472       out_file: File to be written to opened by the caller.
    473     """
    474     out_file.write(
    475         self._EXEC_COMMAND_IMPL_START % {'command_name': self.MethodName()})
    476     if self.request_args and self.response_args:
    477       out_file.write(self._EXEC_COMMAND_IMPL_IN_OUT % {
    478           'command_name': self.MethodName(),
    479           'command_code': self.command_code,
    480           'num_response_handles': self._GetNumberOfResponseHandles()})
    481     elif self.request_args:
    482       out_file.write(self._EXEC_COMMAND_IMPL_IN % {
    483           'command_name': self.MethodName(),
    484           'command_code': self.command_code})
    485     elif self.response_args:
    486       out_file.write(self._EXEC_COMMAND_IMPL_OUT % {
    487           'command_name': self.MethodName(),
    488           'command_code': self.command_code,
    489           'num_response_handles': self._GetNumberOfResponseHandles()})
    490 
    491   def OutputDecl(self, out_file):
    492     """Generates a TPM object declaration."""
    493     if self.request_args:
    494       out_file.write(self._STRUCT_DECL_START)
    495       for arg in self.request_args:
    496         out_file.write(self._STRUCT_DECL_FIELD % {'type': arg['type'],
    497                                                   'name': arg['name']})
    498       out_file.write(self._STRUCT_DECL_END % {'command_name': self.MethodName(),
    499                                               'direction': 'In'})
    500     if self.response_args:
    501       out_file.write(self._STRUCT_DECL_START)
    502       for arg in self.response_args:
    503         out_file.write(self._STRUCT_DECL_FIELD % {'type': arg['type'],
    504                                                   'name': arg['name']})
    505       out_file.write(self._STRUCT_DECL_END % {'command_name': self.MethodName(),
    506                                               'direction': 'Out'})
    507     if len(self.response_args) and len(self.request_args):
    508       out_file.write(
    509           self._FUNCTION_DECL_IN_OUT % {'command_name': self.MethodName()})
    510     elif self.response_args:
    511       out_file.write(
    512           self._FUNCTION_DECL_OUT % {'command_name': self.MethodName()})
    513     elif self.request_args:
    514       out_file.write(
    515           self._FUNCTION_DECL_IN % {'command_name': self.MethodName()})
    516     out_file.write(self._EXEC_DECL % {'command_name': self.MethodName()})
    517 
    518   def _GetNumberOfRequestHandles(self):
    519     """Returns the number of input handles for this command."""
    520     return len(self._SplitArgs(self.request_args)[0])
    521 
    522   def _GetNumberOfResponseHandles(self):
    523     """Returns the number of output handles for this command."""
    524     return len(self._SplitArgs(self.response_args)[0])
    525 
    526   def MethodName(self):
    527     """Creates an appropriate generated method name for the command.
    528 
    529     We use the command name without the TPM2_ prefix.
    530 
    531     Returns:
    532       The method name.
    533     """
    534     if not self.name.startswith('TPM2_'):
    535       return self.name
    536     return self.name[5:]
    537 
    538   def GetRequestHandles(self):
    539     """Returns a list of input handles for this command."""
    540     return self._SplitArgs(self.request_args)[0]
    541 
    542   def _SplitArgs(self, args):
    543     """Splits a list of args into handles and parameters."""
    544     always_params = {
    545         'TPM_CC_FlushContext': 'TPMI_DH_CONTEXT',
    546         'TPM_CC_Hash': 'TPMI_RH_HIERARCHY',
    547         'TPM_CC_LoadExternal': 'TPMI_RH_HIERARCHY',
    548         'TPM_CC_SequenceComplete': 'TPMI_RH_HIERARCHY',
    549     }
    550     handles = []
    551     parameters = []
    552     always_handle = set(['TPM_HANDLE'])
    553     # Handle types that appear as command parameters.
    554     always_parameter = set(['TPMI_RH_ENABLES', 'TPMI_DH_PERSISTENT'])
    555     if self.command_code in always_params:
    556       always_parameter.add(always_params[self.command_code])
    557     for arg in args:
    558       if (arg['type'] in always_handle or
    559           (self._HANDLE_RE.search(arg['type']) and
    560            arg['type'] not in always_parameter)):
    561         handles.append(arg)
    562       else:
    563         parameters.append(arg)
    564     return handles, parameters
    565 
    566 
    567 def _OutputCommandDispatcher(commands):
    568   """Generates implementation file for CommandDispatcher function.
    569 
    570   Args:
    571     commands: A list of Command objects.
    572   """
    573   with open('CommandDispatcher.c', 'w') as out_file:
    574     out_file.write(COPYRIGHT_HEADER)
    575     for command in commands:
    576       out_file.write(_COMMAND_DISPATCHER_INCLUDES %
    577                      {'command_name': command.MethodName()})
    578     out_file.write(_COMMAND_DISPATCHER_START)
    579     for command in commands:
    580       command_code = 'TPM_CC_' + command.MethodName()
    581       out_file.write(_COMMAND_DISPATCHER_CASE %
    582                      {'command_code': command_code,
    583                       'command_name': command.MethodName()})
    584     out_file.write(_COMMAND_DISPATCHER_END)
    585   call(['clang-format', '-i', '-style=Chromium', 'CommandDispatcher.c'])
    586 
    587 
    588 def _OutputHandleProcess(commands, typemap):
    589   """Generates implementation file for ParseHandleBuffer function.
    590 
    591   Args:
    592     commands: A list of Command objects.
    593     typemap: A dict mapping type names to the corresponding object.
    594         Generated by structure_generator.
    595   """
    596   with open('HandleProcess.c', 'w') as out_file:
    597     out_file.write(COPYRIGHT_HEADER)
    598     out_file.write(_HANDLE_PROCESS_START)
    599     for command in commands:
    600       command_code = 'TPM_CC_' + command.MethodName()
    601       out_file.write(_HANDLE_PROCESS_CASE_START %
    602                      {'command_code': command_code})
    603       for handle in command.GetRequestHandles():
    604         if typemap[handle['type']].HasConditional():
    605           out_file.write(_HANDLE_PROCESS_CASE_UNMARSHAL_FLAG %
    606                          {'handle_type': handle['type'],
    607                           'flag_val': handle['has_conditional']})
    608         else:
    609           out_file.write(_HANDLE_PROCESS_CASE_UNMARSHAL %
    610                          {'handle_type': handle['type']})
    611         out_file.write(_HANDLE_PROCESS_CASE_CHECK)
    612       out_file.write(_HANDLE_PROCESS_CASE_END)
    613     out_file.write(_HANDLE_PROCESS_END)
    614   call(['clang-format', '-i', '-style=Chromium', 'HandleProcess.c'])
    615 
    616 
    617 def _OutputGetCommandCodeString(commands):
    618   """Generates header and implementation files for GetCommandCodeString.
    619 
    620   Args:
    621     commands: A list of Command objects.
    622   """
    623   with open('GetCommandCodeString_fp.h', 'w') as out_file:
    624     out_file.write(COPYRIGHT_HEADER)
    625     out_file.write(_GET_COMMAND_CODE_STRING_HEADER)
    626   call(['clang-format', '-i', '-style=Chromium', 'GetCommandCodeString_fp.h'])
    627   with open('GetCommandCodeString.c', 'w') as out_file:
    628     out_file.write(COPYRIGHT_HEADER)
    629     out_file.write(_GET_COMMAND_CODE_STRING_START)
    630     for command in commands:
    631       out_file.write(_GET_COMMAND_CODE_STRING_CASE %
    632                      {'command_name': command.MethodName()})
    633     out_file.write(_GET_COMMAND_CODE_STRING_END)
    634   call(['clang-format', '-i', '-style=Chromium', 'GetCommandCodeString.c'])
    635 
    636 
    637 def GenerateHeader(commands):
    638   """Generates a header file with declarations for all given generator objects.
    639 
    640   Args:
    641     commands: A list of Command objects.
    642   """
    643   for command in commands:
    644     command_header_file = command.MethodName()+'_fp.h'
    645     with open(command_header_file, 'w') as out_file:
    646       out_file.write(COPYRIGHT_HEADER)
    647       out_file.write(
    648           _HEADER_FILE_GUARD_HEADER % {'name': command.MethodName().upper()})
    649       out_file.write(_HEADER_FILE_INCLUDES)
    650       command.OutputDecl(out_file)
    651       out_file.write(
    652           _HEADER_FILE_GUARD_FOOTER % {'name': command.MethodName().upper()})
    653     call(['clang-format', '-i', '-style=Chromium', command_header_file])
    654 
    655 
    656 def GenerateImplementation(commands, typemap):
    657   """Generates implementation code for each command.
    658 
    659   Args:
    660     commands: A list of Command objects.
    661     typemap: A dict mapping type names to the corresponding object.
    662         Generated by structure_generator.
    663   """
    664   for command in commands:
    665     marshal_command_file = 'Marshal_'+command.MethodName()+'.c'
    666     with open(marshal_command_file, 'w') as out_file:
    667       out_file.write(COPYRIGHT_HEADER)
    668       out_file.write(_IMPLEMENTATION_FILE_INCLUDES %
    669                      {'command_name': command.MethodName()})
    670       command.OutputMarshalFunction(out_file, typemap)
    671       command.OutputUnmarshalFunction(out_file, typemap)
    672       command.OutputExecFunction(out_file)
    673     call(['clang-format', '-i', '-style=Chromium', marshal_command_file])
    674   _OutputHandleProcess(commands, typemap)
    675   _OutputCommandDispatcher(commands)
    676   _OutputGetCommandCodeString(commands)
    677