source: svn/newcon3bcm2_21bu/nexus/build/tools/ipcthunk/bapi_ipc_server.pm

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 21.8 KB
Line 
1#!/usr/bin/perl
2#     (c)2004-2011 Broadcom Corporation
3#
4#  This program is the proprietary software of Broadcom Corporation and/or its licensors,
5#  and may only be used, duplicated, modified or distributed pursuant to the terms and
6#  conditions of a separate, written license agreement executed between you and Broadcom
7#  (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8#  no license (express or implied), right to use, or waiver of any kind with respect to the
9#  Software, and Broadcom expressly reserves all rights in and to the Software and all
10#  intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11#  HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12#  NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
13#
14#  Except as expressly set forth in the Authorized License,
15#
16#  1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17#  secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18#  and to use this information only in connection with your use of Broadcom integrated circuit products.
19#
20#  2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21#  AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22#  WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23#  THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24#  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25#  LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26#  OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27#  USE OR PERFORMANCE OF THE SOFTWARE.
28#
29#  3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30#  LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31#  EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32#  USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33#  THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34#  ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35#  LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36#  ANY LIMITED REMEDY.
37#
38# $brcm_Workfile: bapi_ipc_server.pm $
39# $brcm_Revision: 28 $
40# $brcm_Date: 12/7/11 10:41a $
41#
42# File Description:
43#
44# Revision History:
45#
46# $brcm_Log: /nexus/build/tools/ipcthunk/bapi_ipc_server.pm $
47#
48# 28   12/7/11 10:41a erickson
49# SW7420-2141: merge as much duplicated kernelmode proxy/usermode ipc
50#  perl code as possible
51#
52# 27   11/7/11 3:59p bandrews
53# SW7231-446: merge to main
54#
55# SW7231-446/3   11/4/11 10:15p bandrews
56# SW7231-446: compile error
57#
58# SW7231-446/2   11/4/11 9:44p bandrews
59# SW7231-446: fix based on review
60#
61# SW7231-446/1   11/3/11 7:55p bandrews
62# SW7231-446: implemented
63#
64# 26   10/31/11 6:13p bandrews
65# SW7231-391: casts to support parser band and timebase as enums
66#
67# SW7420-2078/3   10/18/11 7:00p bandrews
68# SW7231-391: remove global_handle attribute, add comment about cross-
69#  module handle verification
70#
71# SW7420-2078/2   10/11/11 8:21p bandrews
72# SW7231-391: added casts to support parser band and timebase dual
73#  variants
74#
75# SW7420-2078/1   9/30/11 8:35p bandrews
76# SW7420-2078: added global_handle attribute
77#
78# 24   9/29/11 1:57p erickson
79# SW7420-1148: nexus_unregister cannot call NEXUS_ASSERT_MODULE
80#
81# 23   9/20/11 11:02a erickson
82# SW7420-1148: check attr{null_allowed} for NEXUS_HeapHandle function
83#  param
84#
85# 22   9/13/11 1:23p erickson
86# SW7420-1148: change client modes to unprotected/protected/untrusted
87#
88# 21   9/2/11 12:39p erickson
89# SW7420-1148: refactor class_list.pl to generate per-module "get current
90#  client" functions
91#
92# 20   9/2/11 10:03a erickson
93# SW7420-1148: allow nexus_register/unregister to objdb from nexus
94#  module. enables more complex resource management.
95#
96# 19   8/31/11 12:18p erickson
97# SW7231-357: don't generate server-side code for attr{local=true}
98#  functions
99#
100# 18   8/23/11 4:13p erickson
101# SW7420-1992: rename to surface_compositor
102#
103# 17   8/22/11 1:01p erickson
104# SW7420-1689: NEXUS_HeapHandle is validated, even though it is not a
105#  class
106#
107# 16   8/11/11 11:29a erickson
108# SW7420-1689: clarify comment
109#
110# 15   8/8/11 5:10p erickson
111# SW7420-1689: add untrusted client api enforcement
112#
113# 14   8/3/11 9:57a erickson
114# SW7420-1992: add per-display framebuffer heap to
115#  NEXUS_SurfaceCmpSettings
116#
117# 13   7/29/11 12:10p erickson
118# SW7420-1991: fix nelem,nelem_out attribute support, reorganize to be
119#  closer to kernelproxy/bapi_common.pm layout
120#
121# 12   7/25/11 2:46p erickson
122# SW7420-1992: allow class with secondary_destructor and release, no
123#  destructor
124#
125# 11   5/17/11 12:25p erickson
126# SW7420-1679: NEXUS_Memory_Free must check pointer with objdb before
127#  freeing
128#
129# 10   5/13/11 12:18p erickson
130# SW7420-1873: remove shutdown attribute
131#
132# 9   4/18/11 1:48p erickson
133# SW7420-1123: use void* for intermediate device offset to avoid strict
134#  aliasing warnings
135#
136# 8   4/14/11 11:59a erickson
137# SW7420-1679: clean up NEXUS_Memory_Allocate using
138#  attr{dealloc=NEXUS_Memory_Free}
139#
140# 7   4/1/11 9:59a erickson
141# SW7420-1671: refactor object database for multiprocess stress
142#
143# 6   2/16/11 2:17p erickson
144# SW7420-1123: implement nelem/nelem_out for IPC thunk
145#
146# 5   2/15/11 2:28p erickson
147# SW7420-1123: refactor IPC thunk to separate in/out params
148#
149# 4   1/28/11 9:04a erickson
150# SW7420-1440: refactor secondary_destructor
151#
152# 3   1/21/11 4:03p erickson
153# SW7420-1123: verify NEXUS_HeapHandle as function param
154#
155# 2   1/19/11 2:03p erickson
156# SW7420-1123: socket-based usermode IPC
157#
158# 1   9/29/10 9:34a erickson
159# SW7420-1123: add linux usermode IPC
160#
161#############################################################################
162use strict;
163
164package bapi_ipc_server;
165
166sub generate_class_code
167{
168    my ($classes, $func, $in_args, $out_args) = @_;
169    my $id=0;
170    CLASS: for (@$classes) {
171        my $class = $_;
172        for (@{$class->{CONSTRUCTORS}}) {
173            if($_ == $func) {
174                if($class->{DESTRUCTOR_TYPE} eq 'destructor') {
175                    return ["NEXUS_DRIVER_CREATE_OBJECT($id, (void *)$out_args.__retval);"];
176                }
177                elsif($class->{DESTRUCTOR_TYPE} eq 'dealloc') {
178                    # find param based on param dealloc attr
179                    my $param;
180                    for $param (@{$func->{PARAMS}}) {
181                        if (defined $param->{ATTR}->{'dealloc'}) {
182                            return ["NEXUS_DRIVER_CREATE_OBJECT($id, NEXUS_OffsetToCachedAddr((uint32_t)$out_args.$param->{NAME}));"];
183                        }
184                    }
185                }
186                last CLASS;
187            }
188        }
189        if($class->{DESTRUCTOR} == $func) {
190            my $param = @{$func->{PARAMS}}[0];
191            if($class->{DESTRUCTOR_TYPE} eq 'dealloc') {
192                return ["/* coverity[pass_freed_arg] */ ", "NEXUS_DRIVER_DESTROY_OBJECT($id, NEXUS_OffsetToCachedAddr((uint32_t)$in_args.$param->{NAME}));"];
193            }
194            else {
195                return ["/* coverity[pass_freed_arg] */ ", "NEXUS_DRIVER_DESTROY_OBJECT($id, (void *)$in_args.$param->{NAME});"];
196            }
197        }
198        for (@{$class->{SECONDARY_DESTRUCTORS}}) {
199            if($_ == $func) {
200                my $param = @{$func->{PARAMS}}[1];
201                return ["/* coverity[pass_freed_arg] */ ", "NEXUS_DRIVER_DESTROY_OBJECT($id, (void *)$in_args.$param->{NAME});"];
202            }
203        }
204        if($class->{ACQUIRE} == $func) {
205            my $param = @{$func->{PARAMS}}[0];
206            return ["NEXUS_DRIVER_ACQUIRE_OBJECT($id, (void *)$out_args.__retval);"];
207        }
208        if($class->{RELEASE} == $func) {
209            my $param = @{$func->{PARAMS}}[0];
210            return ["NEXUS_DRIVER_RELEASE_OBJECT($id, (void *)$in_args.$param->{NAME});"];
211        }
212        $id++;
213    }
214    return undef;
215}
216
217# check if any function parameter or struct member is a class handle.
218# if so, generate code to verify the handle matches the instance and client.
219# also, check NEXUS_HeapHandle as a special case
220sub generate_class_verification
221{
222    my ($classes, $structs, $func, $args, $class_handles, $untrusted_api) = @_;
223    my @verify_lines;
224
225    # TODO: requires >2 levels of nested struct parsing in bapi_parse_c.pm. not required for now.
226    if ($func->{FUNCNAME} eq "NEXUS_SurfaceCompositor_SetSettings" ||
227        $func->{FUNCNAME} eq "NEXUS_SimpleAudioDecoder_Start")
228    {
229        return \@verify_lines;
230    }
231
232    # if untrusted, verify that this function can be called
233    if (!bapi_classes::callable_by_untrusted($func, $classes, $untrusted_api)) {
234        push @verify_lines, "if ((CLIENT_ID)->limited_api) {BERR_TRACE(-1); goto err_fault;}";
235    }
236
237    for (@{$func->{PARAMS}}) {
238        my $param = $_;
239        my $handletype;
240        my $param_field = "$args.$param->{NAME}";
241
242        # check each class that was defined in this module
243        for (@$classes) {
244            my $class = $_;
245            $handletype = $class->{CLASS_TYPE};
246
247            # check if param is class handle
248            if ($param->{TYPE} eq $handletype) {
249                push @verify_lines, "if (nexus_driver_verify_$handletype(CLIENT_ID, (void *)${param_field})) {BERR_TRACE(-1); goto err_fault;}";
250            }
251            elsif ($param == @{$func->{PARAMS}}[0] &&
252                   $class->{DESTRUCTOR_TYPE} eq 'dealloc' &&
253                   $class->{DESTRUCTOR} == $func) {
254                push @verify_lines, "if (nexus_driver_verify_$handletype(CLIENT_ID, NEXUS_OffsetToCachedAddr((uint32_t)${param_field}))) {BERR_TRACE(-1); goto err_fault;}";
255            }
256        }
257
258        foreach $handletype (@$class_handles) {
259            # this generates cross-module verification, but only if inside a struct param
260            # TODO: do we need to do cross-module handle verification for non-struct params?
261            #print "generate_class_verification $handletype\n";
262            # check is param is a struct which has a class handle field
263            if ($param->{ISREF} && $param->{INPARAM} && exists $structs->{$param->{BASETYPE}}) {
264                my $struct_field;
265                for $struct_field (@{$structs->{$param->{BASETYPE}}}) {
266                    if ($struct_field->{TYPE} eq $handletype) {
267                        my $struct_param = "${param_field}.$struct_field->{NAME}";
268                        # verify non-NULL params
269                        push @verify_lines, "if(!${param_field}_isnull && $struct_param) {";
270                        push @verify_lines, "  if (nexus_driver_verify_$handletype(CLIENT_ID, (void*)$struct_param)) {BERR_TRACE(-1); goto err_fault;}";
271                        push @verify_lines, "}";
272                    }
273                }
274            }
275        }
276
277        # check for timebase or parser band as struct member
278        # this code only checks input params
279        # output params post call are checked in bapi_common.pm
280        # TODO: doesn't support members as pointers
281        if ($param->{ISREF} && $param->{INPARAM} && exists $structs->{$param->{BASETYPE}}) {
282            my $struct_field;
283            for $struct_field (@{$structs->{$param->{BASETYPE}}}) {
284                if ($struct_field->{TYPE} eq 'NEXUS_Timebase' || $struct_field->{TYPE} eq 'NEXUS_ParserBand') {
285                    my $struct_param = "${param_field}.$struct_field->{NAME}";
286                    push @verify_lines, "if (client_module_state->client->config.mode != NEXUS_ClientMode_eUnprotected) {";
287                    push @verify_lines, "  if (!${param_field}_isnull) {"; #_isnull check replaces ioctl pointer check
288                    push @verify_lines, "    if ((void *)$struct_param == NULL) {";
289                    push @verify_lines, "      $struct_param = $struct_field->{TYPE}_eInvalid;";
290                    push @verify_lines, "    }";
291                    push @verify_lines, "  }";
292                    push @verify_lines, "}";
293                }
294            }
295        }
296
297        # check for timebase or parser band as function param
298        # this code only checks input params
299        # output params post call are checked in bapi_common.pm
300        if ($param->{ISREF})
301        {
302            if ($param->{BASETYPE} eq 'NEXUS_Timebase' || $param->{BASETYPE} eq 'NEXUS_ParserBand')
303            {
304                if ($param->{INPARAM}) 
305                {
306                    push @verify_lines, "if (nexus_driver_client_id(context)->config.mode != NEXUS_ClientMode_eUnprotected) {";
307                    push @verify_lines, "  if (${param_field} != NULL) {"; # check pointer
308                    push @verify_lines, "    if ((void *)*${param_field} == NULL) {"; # check pointed to value
309                    push @verify_lines, "      *${param_field} = $param->{TYPE}_eInvalid;";
310                    push @verify_lines, "    }";
311                    push @verify_lines, "  }";
312                    push @verify_lines, "}";
313                }
314            }
315        }
316        else # pass by value is input implicitly
317        {
318            if ($param->{TYPE} eq 'NEXUS_Timebase' || $param->{TYPE} eq 'NEXUS_ParserBand') {
319                push @verify_lines, "if (client_module_state->client->config.mode != NEXUS_ClientMode_eUnprotected) {";
320                push @verify_lines, "  if ((void *)${param_field} == NULL) {";
321                push @verify_lines, "    ${param_field} = $param->{TYPE}_eInvalid;";
322                push @verify_lines, "  }";
323                push @verify_lines, "}";
324            }
325        }
326
327        # check for heap handle as struct member
328        if ($param->{ISREF} && $param->{INPARAM} && exists $structs->{$param->{BASETYPE}}) {
329            my $struct_field;
330            for $struct_field (@{$structs->{$param->{BASETYPE}}}) {
331                if ($struct_field->{TYPE} eq 'NEXUS_HeapHandle') {
332                    my $struct_param = "${param_field}.$struct_field->{NAME}";
333                    # verify all heap handles, even if NULL
334                    push @verify_lines, "if(!${param_field}_isnull) {";
335                    push @verify_lines, "  if (NEXUS_DRIVER_VERIFY_HEAP($struct_param)) {BERR_TRACE(-1); goto err_fault;}";
336                    push @verify_lines, "}";
337                }
338            }
339        }
340
341        # check for heap handle as function param
342        if ($param->{TYPE} eq 'NEXUS_HeapHandle') {
343            # verify all heap handles, but honor null_allowed
344            my $null_allowed = $param->{ATTR}->{'null_allowed'};
345            if (!defined $null_allowed || $null_allowed eq "unprotected" || $null_allowed eq "trusted") {
346                if ($null_allowed eq "unprotected" || $null_allowed eq "trusted") {
347                    # allowed for unprotected code
348                    push @verify_lines, "if (!${param_field} && (CLIENT_ID)->verify != b_objdb_verify_none) {";
349                }
350                else {
351                    # never allowed
352                    push @verify_lines, "if (!${param_field}) {";
353                }
354                push @verify_lines, "  BDBG_ERR((\"NULL not allowed for $param->{NAME} param in $func->{FUNCNAME}: %d\", __LINE__));";
355                push @verify_lines, "  goto err_fault;";
356                push @verify_lines, "}";
357            }
358            push @verify_lines, "if (NEXUS_DRIVER_VERIFY_HEAP(${param_field})) {BERR_TRACE(-1); goto err_fault;}";
359        }
360    }
361
362    # for destructors with shutdown attributes, we must call the auto-generated shutdown_close function
363    # instead of directly calling the normal close function.
364    my $class;
365    my $bypass;
366    for $class (@$classes) {
367        if ($class->{DESTRUCTOR} == $func && exists $class->{SHUTDOWN}) {
368            my $classtype = $class->{CLASS_TYPE};
369            my $params = $func->{PARAMS};
370            my $handle = "$args.$$params[0]->{NAME}";
371            push @verify_lines, "nexus_driver_shutdown_close_$classtype($handle);";
372            $bypass = 1;
373        }
374    }
375
376    return (\@verify_lines, $bypass);
377}
378
379sub generate_ipc
380{
381    my ($file, $module, $version, $structs, $classes, $funcs, $class_handles, $untrusted_api) = @_;
382    my $func;
383    my $ipc = bapi_common::version_ipc $module;
384    my $name;
385
386    for $func (@$funcs) {
387        my $params = $func->{PARAMS};
388        my $param;
389        my $ipc = bapi_common::ipc_name $module, $func;
390        my $in_args = "in_data->data.$func->{FUNCNAME}.in";
391        my $out_args = "out_data->data.$func->{FUNCNAME}.out";
392                my $retval = "$out_args.__retval";
393        my $attr = bapi_common::process_function_attributes $func, $structs, $funcs;
394        my $class_code = generate_class_code $classes, $func, $in_args, $out_args;
395        my ($class_verification,$bypass) = generate_class_verification $classes, $structs, $func, $in_args, $class_handles, $untrusted_api;
396       
397        next if(exists $func->{ATTR}->{'local'});
398
399        print $file "case $ipc:\n";
400        print $file "   NEXUS_IPC_ENTER($func->{FUNCNAME});\n";
401
402        # verify in size for fixed params. auto-gen code also verifies each variable param.
403        print $file "   if (in_data_size < sizeof(in_data->header)+sizeof($in_args)) {\n";
404        print $file "     BDBG_ERR((\"short in data %d < %d+%d: %d\", in_data_size, sizeof(in_data->header),sizeof($in_args), __LINE__));\n";
405        print $file "     goto err_fault;\n";
406        print $file "   }\n";
407        # verify out size for fixed params. auto-gen code also verifies each variable param.
408        print $file "   *p_out_data_size = sizeof(out_data->header)+sizeof($out_args);\n";
409        print $file "   if (out_mem_size < *p_out_data_size) {\n";
410        print $file "     BDBG_ERR((\"short out size %d < %d+%d: %d\", out_mem_size, sizeof(out_data->header), *p_out_data_size, __LINE__));\n";
411        print $file "     goto err_fault;\n";
412        print $file "   }\n";
413
414        # must do class_verification before driver_pre_call to avoid leaks if not verified
415        bapi_util::print_code $file, $class_verification, "   ";
416
417        bapi_util::print_code $file, $attr->{driver_pre_call}, "   ";
418
419                if (!defined $bypass) {
420                # make a function call
421       
422                if ($func->{RETTYPE} ne "void") {
423                    print $file "   $retval = \n"
424                }
425       
426       
427                my @args;
428                for $param (@$params) {
429                    my $info = bapi_common::process_function_param $func, $param;
430                    push @args, "\n        " . $info->{'driver_arg'};
431       
432       
433       
434       
435       
436       
437       
438                }
439       
440                print $file "   " . bapi_util::call($func->{FUNCNAME} , @args) . ";\n\n";
441                }
442
443        if (defined $attr->{driver_post_success} || defined $attr->{driver_post_error} || defined $class_code) {
444            if ($func->{RETTYPE} eq "NEXUS_Error") {
445                print $file "  if ($retval == NEXUS_SUCCESS) {\n";
446            } elsif ($func->{RETTYPE} ne "void") {
447                if ($func->{RETTYPE} eq "NEXUS_Timebase" || $func->{RETTYPE} eq "NEXUS_ParserBand")
448                {
449                    print $file "  if ($retval == $func->{RETTYPE}_eInvalid) {\n";
450                    print $file "    $retval = ($func->{RETTYPE})NULL;\n";
451                    print $file "  }\n";
452                }
453                print $file "  if ((void *)$retval != NULL) {\n";
454            } else {
455                print $file "  {\n";
456            }
457            bapi_util::print_code $file, $attr->{driver_post_success}, "     ";
458            if (defined $class_code) {
459                bapi_util::print_code $file, $class_code, "     ";
460            }
461            if (($func->{RETTYPE} ne "void") && (defined $attr->{driver_post_error}) ) {
462                print $file "  } else { \n";
463                bapi_util::print_code $file, $attr->{driver_post_error}, "     ";
464            }
465            print $file "  }\n";
466        }
467        bapi_util::print_code  $file, $attr->{driver_post_always}, "  ";
468        print $file "  NEXUS_IPC_LEAVE($func->{FUNCNAME});\n";
469        print $file "  break;\n\n";
470    }
471
472}
473
474
475sub generate
476{
477    my ($filename, $module, $version, $structs, $funcs, $class_handles, $untrusted_api) = @_;
478    my $module_lc = lc $module;
479    open FILE, ">$filename";
480    my $file = \*FILE;
481
482    my $destructors = bapi_classes::get_destructors $funcs;
483    my $classes = bapi_classes::get_classes $funcs, $destructors;
484    print $file bapi_util::header $module;
485    print $file "#define NEXUS_SERVER_MODULE_NAME \"$module\"\n";
486    print $file "#include \"nexus_${module_lc}_module.h\"\n";
487    print $file "BDBG_MODULE(nexus_${module_lc}_ipc_server);\n";
488    print $file "#include \"nexus_core_utils.h\"\n";
489    print $file "#include \"nexus_class_verification.h\"\n";
490    print $file "\n\n";
491    print $file "/* defines to make all module symbols uniques */\n";
492    print $file "#define nexus_server_module_open nexus_server_${module_lc}_open\n";
493    print $file "#define nexus_server_module_close nexus_server_${module_lc}_close\n";
494    print $file "#define nexus_server_process nexus_server_${module_lc}_process\n";
495    print $file "#define nexus_server_args " . (bapi_common::ipc_block $module) ."\n";
496    print $file "#define nexus_server_data_size nexus_server_${module_lc}_data_size\n";
497    print $file "\n\n";
498    if(scalar @$classes) {
499        print $file "#define NEXUS_DRIVER_MODULE_CLASS_TABLE    nexus_server_$module\_class_table\n";
500    }
501    print $file "\n\n";
502
503    print $file "#include \"server/nexus_server_prologue.h\"\n";
504
505    print $file "#include \"" . (bapi_common::ipc_header $module) . "\"\n";
506    print $file "#define NEXUS_IPC_HEADER_VERSION   " . (bapi_common::version_define $module) . "\n";
507    print $file "\n\n\n";
508    bapi_classes::generate_class_table $file, $classes;
509    print $file "\n\n\n";
510    print $file "#include \"server/nexus_server_body.h\"\n";
511    print $file "\n\n\n";
512    generate_ipc $file, $module, $version, $structs, $classes, $funcs, $class_handles, $untrusted_api;
513    print $file "\n\n\n";
514    print $file "#include \"server/nexus_server_epilogue.h\"\n";
515    print $file "\n\n\n";
516    bapi_classes::generate_class_verify_functions $file, $classes, $module;
517    print $file "\n\n\n";
518    close FILE;
519}
520
5211;
522
Note: See TracBrowser for help on using the repository browser.