source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPSVCPlugin.rb@ 374

Last change on this file since 374 was 374, checked in by coas-nagasima, 5 years ago

mbed関連を更新
シリアルドライバをmbedのHALを使うよう変更
ファイルディスクリプタの処理を更新

  • Property charset set to UTF-8
  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby
File size: 33.6 KB
Line 
1# coding: utf-8
2#
3# TECS Generator
4# Generator for TOPPERS Embedded Component System
5#
6# Copyright (C) 2008-2018 by TOPPERS Project
7#--
8# 上記著作権者
9は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
10# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
11# 変・再é…
12å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
13# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
14# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
15# スコード中に含まれていること.
16# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
17# 用できる形で再é…
18å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
19å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
20# 者
21マニュアルなど)に,上記の著作権表示,この利用条件および下記
22# の無保証規定を掲載すること.
23# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
24# 用できない形で再é…
25å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
26# と.
27# (a) 再é…
28å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
29マニュアルなど)に,上記の著
30# 作権表示,この利用条件および下記の無保証規定を掲載すること.
31# (b) 再é…
32å¸ƒã®å½¢æ…
33‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
34# 報告すること.
35# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
36# 害からも,上記著作権者
37およびTOPPERSプロジェクトをå…
38è²¬ã™ã‚‹ã“と.
39# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
40# 由に基づく請求からも,上記著作権者
41およびTOPPERSプロジェクトを
42# å…
43è²¬ã™ã‚‹ã“と.
44#
45# 本ソフトウェアは,無保証で提供されているものである.上記著作権者
46お
47# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
48# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
49# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
50# の責任を負わない.
51#
52# $Id$
53#++
54
55# mikan through plugin: namespace が考æ…
56®ã•ã‚Œã¦ã„ない
57# これを利用する場合、以下のように toppers_jsp.cdl sChannel.cdl を指定する必
58要がある
59# tecsgen toppers_jsp.cdl sChannel.cdl your_description.cdl
60
61# 以下を仮定(制限事項
62)
63# 呼びå…
64ƒã€å‘¼ã³å…
65ˆã®ã‚¨ãƒ³ãƒ‡ã‚£ã‚¢ãƒ³ã€char, short, int_t, long_t, intptr_t のサイズが同じ
66# 有符号、無符号でサイズが同じ
67
68class SVCManage
69 #
70 # @@id: TECSのプラグインで生成した拡張サービスコールに割り当てるid
71 # 実際の拡張サービスコールIDは,TFN_TECSGEN_ORIGINで下駄を
72 # 履かせた値となる
73 # TFN_TECSGEN_ORIGINは,hrp3/include/extsvc_fncode.h で定義
74 # される
75 # @@func_ids: 拡張サービスコールの関数名と拡張サービスコールIDを
76 #    対応づけるハッシュ
77 #
78 @@id = 0
79 @@func_ids = {}
80 def initialize()
81 #
82 # 本クラスはインスタンスを持たない仮想的なクラスである
83 #
84 raise "class #{self.class.name} shall not have instances"
85 end
86 def self.get_func_id func_name
87 return @@func_ids[ func_name ]
88 end
89 def self.set_func_id func_name
90 @@func_ids[ func_name ] = self.assign_id
91 # puts @@func_ids[ func_name ]
92 end
93 def self.get_id
94 return @@id
95 end
96 def self.set_id id
97 @@id = id
98 end
99 def self.assign_id
100 assignedId = @@id
101 @@id += 1
102 return assignedId
103 end
104end
105
106#
107# 拡張サービスコールを用いたドメイン間通信の
108# throughプラグイン
109# HRPドメインプラグインによって挿å…
110¥ã•ã‚Œã‚‹
111# 前提条件: 呼出しå…
112ˆãŒã‚«ãƒ¼ãƒãƒ«ã‚ªãƒ–ジェクトかどうかの判定はHRPドメインプラグイン
113#      で実施されるため,ここでは判定しないこととした
114#
115class HRPSVCPlugin < ThroughPlugin
116
117 NUM_SVC_ARG_MAX = 5 # HRP3 の拡張サービスコールで扱うことのできる引数の最大個数
118
119 @@generated_celltype ={} # セルタイプの重複排除用
120 @@generated_cell = {} # セルの重複排除用
121
122 def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
123 super
124
125 # 受け口é…
126åˆ—の場合、é…
127åˆ—添数ごとに別のセルタイプとする
128 # セルタイプをシングルトン化したいため。
129 # さもないと、セルを識別する引数を渡す必
130要があり、NUM_SVC_ARG_MAX(5) つしか渡せない引数の一つを消費することになるため。
131 if @next_cell_port_subscript then
132 subscript = "__" + @next_cell_port_subscript.to_s
133 else
134 subscript = ""
135 end
136 @ct_name_body = "#{@ct_name}SVCBody_#{@next_cell.get_name}_#{@next_cell_port_name}#{subscript}".to_sym
137 @ct_name = "#{@ct_name}SVCCaller_#{@next_cell.get_name}_#{@next_cell_port_name}#{subscript}".to_sym
138 @cell_name_body = "#{@cell_name}SVCBody".to_sym
139 @cell_name = "#{@cell_name}SVCCaller".to_sym
140 # puts "%%%% "
141 # p @next_cell.get_name
142 # p @caller_cell.get_name
143 @b_printed_include_stdint = false
144 check_signature signature
145 end
146
147 #=== NamespacePath を得る
148 # 生成するセルの namespace path を生成する
149 def get_cell_namespace_path
150# nsp = @region.get_namespace.get_namespace_path
151 nsp = @start_region.get_namespace_path
152 return nsp.append( @cell_name )
153 end
154
155 def gen_plugin_decl_code( file )
156
157 # このセルタイプ(同じシグニチャ)は既に生成されているか?
158 if @@generated_celltype[ @ct_name_body ] == nil then
159 @@generated_celltype[ @ct_name_body ] = [ self ]
160 file2 = CFile.open( "#{$gen}/#{@ct_name_body}.cdl", "w" )
161 file2.print <<EOT
162import_C( "t_stdlib.h" );
163
164/* HRPSVC0001 */
165[active,singleton]
166celltype #{@ct_name_body} {
167 call #{@signature.get_name} #{@call_port_name};
168 FACTORY {
169 write("$ct$_tecsgen.h", "#include \\"kernel_cfg.h\\"");
170 };
171};
172EOT
173 file2.close
174 else
175 @@generated_celltype[ @ct_name_body ] << self
176 end
177 file.print "import( \"#{$gen}/#{@ct_name_body}.cdl\" );\n"
178
179 # このセルタイプ(同じシグニチャ)は既に生成されているか?
180 if @@generated_celltype[ @ct_name ] == nil then
181 @@generated_celltype[ @ct_name ] = [ self ]
182 file2 = CFile.open( "#{$gen}/#{@ct_name}.cdl", "w" )
183 file2.print <<EOT
184/* HRPSVC0002 */
185celltype #{@ct_name} {
186 entry #{@signature.get_name} #{@entry_port_name};
187 FACTORY {
188 write("$ct$_tecsgen.h", "#include \\"extsvc_fncode.h\\"");
189 };
190};
191EOT
192 file2.close
193 else
194 @@generated_celltype[ @ct_name ] << self
195 end
196 file.print "import( \"#{$gen}/#{@ct_name}.cdl\" );\n"
197
198=begin
199 # TODO: send. receive 対応
200 send_receive = []
201 if @signature != nil then
202 @signature.each_param{ |fd,param|
203 dir =param.get_direction
204 case dir
205 when :SEND, :RECEIVE
206 send_receive << [ dir, fd, param ]
207 end
208 }
209 end
210=end
211
212=begin
213composite #{@ct_name} {
214 entry #{@signature.get_name} #{@entry_port_name};
215 call #{@signature.get_name} #{@call_port_name};
216
217 cell #{@ct_name}Client #{@cell_name}Client{
218 };
219
220 [active]
221 cell #{@ct_name}Server #{@cell_name}Server{
222 #{@call_port_name} => composite.#{@call_port_name};
223 };
224
225 composite.#{@entry_port_name} => #{@cell_name}.#{@entry_port_name};
226};
227=end
228
229 end
230
231 #=== through cell コードを生成
232 #
233 #
234 def gen_through_cell_code( file )
235
236 # gen_plugin_decl_code( file ) this is called from super.
237
238 # セルを探す
239 # path =["::",@next_cell.get_name] # mikan namespace
240 # cell = Namespace.find( path )
241 # cell = Namespace.find( @next_cell.get_namespace_path )
242
243 ##### クライアント側のセルの生成 #####
244 # file.print "[domain(HRP, \"kernel\")]"
245 nest = @start_region.gen_region_str_pre file
246 nest_str = " " * nest
247
248 # クライアント側チャンネルの生成
249 # 拡張サービスコール呼出し
250 file.print <<EOT
251/* HRPSVC0003 */
252#{nest_str} // Client Side Channel
253#{nest_str} cell #{@ct_name} #{@cell_name}{
254#{nest_str} };
255
256EOT
257
258 @start_region.gen_region_str_post file
259 file.print "\n\n"
260
261 ##### サーバー側のセルの生成 #####
262 # print "###### #{@cell_name_body} ... #{@ct_name_body} #{@@generated_cell[ @ct_name_body ].class} #####\n"
263
264 if @@generated_cell[ @ct_name_body ] then
265 file.print "/* cell #{@ct_name_body} #{@@generated_cell[ @ct_name_body ]}: already generated. */\n"
266 else
267 @@generated_cell[ @ct_name_body ] = @cell_name_body
268 nest = @end_region.gen_region_str_pre file
269 nest_str = " " * nest
270 if @next_cell_port_subscript then
271 subscript = '[' + @next_cell_port_subscript.to_s + ']'
272 else
273 subscript = ""
274 end
275
276 # サーバー側チャンネルの生成
277 # 拡張サービスコール本体
278 file.print <<EOT
279
280/* HRPSVC0004 */
281#{nest_str} // Server Side Channel
282#{nest_str} cell #{@ct_name_body} #{@cell_name_body}{
283#{nest_str} #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name}#{subscript};
284#{nest_str} };
285EOT
286
287 @end_region.gen_region_str_post file
288
289 file2 = AppFile.open( "#{$gen}/tecsgen.cfg" )
290 file2.print "\n/* Generated by HRPSVCPlugin */\n\n"
291 file2.print <<EOT
292/* HRPSVC0005 */
293#include "#{@ct_name_body}_factory.h"
294EOT
295 file2.close
296
297 # callee_cell のget_restricted_regions を呼び出しておく
298 # restrict が参ç…
299§ã•ã‚ŒãŸå°ã‚’つけるため
300 @callee_cell.get_restricted_regions( :dummy_entry_name, :dummy_func_name )
301 end
302 end
303
304 #=== 受け口関数の本体(C言語)を生成する
305 # 通常であれば、ジェネレータは受け口関数のテンプレートを生成する
306 # プラグインの場合、変更する必
307要のないセルタイプコードを生成する
308 #file:: FILE 出力å…
309ˆãƒ•ã‚¡ã‚¤ãƒ«
310 #b_singleton:: bool true if singleton
311 #ct_name:: Symbol
312 #global_ct_name:: string
313 #sig_name:: string
314 #ep_name:: string
315 #func_name:: string
316 #func_global_name:: string
317 #func_type:: class derived from Type
318 def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
319 # puts "generate ep_func for #{ct_name}"
320
321 #
322 # 拡張サービスコール呼出し側の関数生成
323 #
324 # 完成形のイメージ
325 #
326 # ER_UINT
327 # eThroughEntry_write(CELLIDX idx, const char* buffer, uint_t length)
328 # {
329 # ER_UINT retval;
330 # tHRPSVCPlugin_<Sig>SVCCaller_<Cell>_<Entry>_CB *p_cellcb;
331 # if( VALID_IDX( idx ) ){
332 # p_cellcb = tHRPSVCPlugin_<Sig>SVCBody_<Cell>_<Entry>_GET_CELLCB(idx);
333 # }else{
334 # /* エラー処理コードをここに記述 */
335 # }
336 #
337 # retval = (ER_UINT)cal_svc( TFN_TECSGEN_ORIGIN + svcid,
338 # (intptr_t)par1, (intptr_t)par2, 0, 0, 0 );
339 #
340 # return retval;
341 # }
342
343 if ! func_type.get_type.kind_of?( VoidType ) then
344 file.print( " #{func_type.get_type_str} retval;\n" )
345 end
346
347 # p "celltype_name, sig_name, func_name, func_global_name"
348 # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
349
350 delim = ""
351 if ! func_type.get_type.kind_of?( VoidType ) then
352 file.print( " retval = (#{func_type.get_type_str})" )
353 else
354 file.print( " " )
355 end
356
357 #file.print( "#{@call_port_name}_#{func_name}(" )
358 SVCManage.set_func_id( "#{@ct_name_body}_#{func_name}" )
359 svcid = SVCManage.get_func_id( "#{@ct_name_body}_#{func_name}" )
360 #file.print( "cal_svc( #{@ct_name_body}_#{func_name}" )
361 file.print( "cal_svc( TFN_TECSGEN_ORIGIN + #{svcid.to_s}" )
362
363 # if ( ! b_singleton ) then
364 # file.print( " tecs_this" )
365 # delim = ","
366 # end
367
368 i = 0
369 passed_param = {}
370 params.each{ |param|
371 delim = ","
372 file.printf( "#{delim} (intptr_t)#{param.get_name}" )
373 passed_param[i] = param.get_name
374 i += 1
375 }
376
377 while(i < NUM_SVC_ARG_MAX) do
378 delim = ","
379 file.printf( "#{delim} 0" )
380 passed_param[i] = "par#{i+1}"
381 i += 1
382 end
383
384 file.print( " );\n\n" )
385
386 if ! func_type.get_type.kind_of?( VoidType ) then
387 file.print( " return retval;\n" )
388 end
389
390 #
391 # 拡張サービスコール本体側の関数生成
392 #
393 # 完成形のイメージ
394 #
395 # ER_UINT
396 # eThroughEntry_write(CELLIDX idx, const char* buffer, uint_t length)
397 # {
398 # ER_UINT retval;
399 # tHRPSVCPlugin_<Sig>SVCBody_<Cell>_<Entry>_CB *p_cellcb;
400 # if( VALID_IDX( idx ) ){
401 # p_cellcb = tHRPSVCPlugin_<Sig>SVCBody_<Cell>_<Entry>_GET_CELLCB(idx);
402 # }else{
403 # /* エラー処理コードをここに記述 */
404 # }
405 #
406 # retval = (ER_UINT)cal_svc( TFN_TECSGEN_ORIGIN + svcid,
407 # (intptr_t)par1, (intptr_t)par2, 0, 0, 0 );
408 #
409 # return retval;
410 # }
411 file2 = AppFile.open( "#{$gen}/#{@ct_name_body}.c" )
412 if @b_printed_include_stdint == false then
413 file2.print <<EOT
414#ifndef SIZE_MAX
415#define SIZE_MAX (~0UL)
416#endif
417
418EOT
419 @b_printed_include_stdint = true
420 end
421
422 if func_type.get_type.kind_of?( VoidType ) then
423 retval_assign = ""
424 else
425 retval_assign = "retval = (ER_UINT)"
426 end
427
428 file2.print <<EOT
429/* HRPSVC0006 */
430ER_UINT
431#{@ct_name_body}_#{func_name}(intptr_t #{passed_param[0]}, intptr_t #{passed_param[1]}, intptr_t #{passed_param[2]}, intptr_t #{passed_param[3]}, intptr_t #{passed_param[4]}, ID cdmid)
432{
433 ER_UINT retval = E_OK;
434
435EOT
436
437 #
438 # エラーチェック処理の生成
439 #
440
441 #
442 # 呼出しå…
443ƒãƒ‰ãƒ¡ã‚¤ãƒ³ã®ãƒã‚§ãƒƒã‚¯
444 # * private method: gen_caller_check_code参ç…
445§
446 #
447 generated_check_code = gen_caller_check_code(func_name)
448 check_code = generated_check_code["check_code"]
449 user_cannot_callable = generated_check_code["user_cannot_callable"]
450
451 #
452 # パラメータにポインタが存在する場合,呼出しå…
453ƒã‚¿ã‚¹ã‚¯ã«å¯¾ã™ã‚‹
454 # アクセス権のチェック処理を出力する
455 # ※ cdmidがカーネルドメイン(拡張サービスコール呼出し中のユーザ
456 # ドメインを含む)であればprb_memの処理をスキップし,初段の
457 # 拡張サービスコールのみprb_memを呼出しå…
458ƒã‚¿ã‚¹ã‚¯ã«ç™ºè¡Œã™ã‚‹
459 #
460 num = 0
461 params.each{ |param|
462 if param.get_declarator.get_ptr_level > 0 then
463 align_check_str = "!ALIGN_TYPE(#{passed_param[num]}, #{param.get_type.get_referto.get_type_str}) || "
464
465 if param.get_type.get_referto.kind_of?(IntType) then
466 case param.get_type.get_referto.get_bit_size
467 when -11, -1, 8 # char, char_t, int8_t (無符号含む)
468 #
469 # charデータの場合,ALIGN_TYPEは必
470ずTRUE
471 # となるので,エラーチェックを省略
472 # char型の@bit_sizeは-11
473 # tecsgen/tecslib/core/types.rbを参ç…
474§
475 #
476 align_check_str = ""
477 end
478 end
479 if param.get_direction == :IN then
480 #
481 # å…
482¥åŠ›([in])のポインタパラメータは,呼出しå…
483ƒã‚¿ã‚¹ã‚¯ã«
484 # TPM_READ(読出し可能)のアクセス権が必
485要
486 #
487 # 二重ポインタが不可のため、size_is と string が同時に設定されることはない
488 prb_func = "prb_mem"
489 if param.get_size then
490 size_str = param.get_size.to_s
491 elsif param.get_string == -1 then
492 size_str = "SIZE_MAX"
493 prb_func = "prb_str"
494 elsif param.get_string then
495 size_str = param.get_string.to_s
496 prb_func = "prb_str"
497 else
498 size_str = "1"
499 end
500 check_code.concat <<EOT
501 /* HRPSVC0007 */
502 if (#{align_check_str}#{prb_func}((void *)#{passed_param[num]}, sizeof(#{param.get_type.get_referto.get_type_str}) * (#{size_str}), TSK_SELF, TPM_READ) != E_OK) {
503 return E_MACV;
504 }
505EOT
506
507 elsif param.get_direction == :OUT || param.get_direction == :INOUT then
508 #
509 # 出力([out])のポインタパラメータは,呼出しå…
510ƒã‚¿ã‚¹ã‚¯ã«
511 # TPM_WRITE(書込み可能)のアクセス権が必
512要
513 #
514 prb_func = "prb_mem"
515 if param.get_size then
516 size_str = param.get_size.to_s
517 elsif param.get_string then # 引数なしの string はない
518 size_str = param.get_string.to_s
519 # prb_func = "prb_str" # out, inout の場合、必
520ず領域を確保する. prb_mem を用いる
521 else
522 size_str = "1"
523 end
524 check_code.concat <<EOT
525 /* HRPSVC0008 */
526 if (#{align_check_str}#{prb_func}((void *)#{passed_param[num]}, sizeof(#{param.get_type.get_referto.get_type_str}) * (#{size_str}), TSK_SELF, TPM_WRITE) != E_OK) {
527 return E_MACV;
528 }
529EOT
530
531 end
532 end
533 num += 1
534 }
535
536 #
537 # 呼出しå…
538ƒãŒã‚«ãƒ¼ãƒãƒ«ãƒ‰ãƒ¡ã‚¤ãƒ³ã®ã¿è¨±å¯ã•ã‚Œã¦ã„る場合,
539 # すべてのユーザドメインからの呼出しに対し,E_OACVを返す
540 #
541 if user_cannot_callable
542 check_code = "\t\treturn E_OACV;"
543 end
544
545 if check_code != ""
546 #
547 # 呼出しå…
548ƒãŒã‚«ãƒ¼ãƒãƒ«ãƒ‰ãƒ¡ã‚¤ãƒ³ã®å ´åˆï¼Œã‚¢ã‚¯ã‚»ã‚¹æ¨©ã®ãƒã‚§ãƒƒã‚¯
549 # 処理をスキップさせる
550 #
551 file2.print <<eot
552 if (cdmid != TDOM_KERNEL) {
553#{check_code}
554 }
555eot
556 end
557
558 #
559 # 拡張サービスコール本体(本来の受け口関数)を呼び出す
560 #
561 file2.print" #{retval_assign}#{@call_port_name}_#{func_name}("
562
563 delim = ""
564 num = 0
565 params.each{ |param|
566 file2.print "#{delim}"
567 delim = ", "
568 file2.print "(#{param.get_type.get_type_str})"
569 file2.print passed_param[num]
570 file2.print param.get_type.get_type_str_post
571 num += 1
572 }
573
574 file2.print ");\n"
575
576 file2.print "\n return retval;\n"
577 file2.print "}\n\n"
578
579 file2.close
580
581 #
582 # 拡張サービスコールの登録
583 #
584 file2 = AppFile.open( "#{$gen}/tecsgen.cfg" )
585 file2.print "\n/* Generated by HRPSVCPlugin */\n\n"
586 file2.print <<EOT
587/* HRPSVC0009 */
588KERNEL_DOMAIN{
589 DEF_SVC( TFN_TECSGEN_ORIGIN + #{svcid.to_s}, { TA_NULL, #{@ct_name_body}_#{func_name}, SSZ_#{func_global_name} } );
590}
591EOT
592 file2.close
593
594 #
595 # 拡張サービスコール登録に必
596要な情
597報をヘッダに出力
598 # - 拡張サービスコール呼出し時のチェックで使用するスタックサイズを出力
599 # - 拡張サービスコールとして登録する関数名のextern宣言を出力
600 #
601 file2 = AppFile.open( "#{$gen}/#{@ct_name_body}_factory.h" )
602 file2.print "\n/* Generated by HRPSVCPlugin */\n\n"
603 file2.print <<EOT
604/* HRPSVC0010 */
605#ifndef SSZ_#{func_global_name}
606#define SSZ_#{func_global_name} DefaultExtsvcStackSize
607#endif /* SSZ_#{func_global_name} */
608
609/* HRPSVC0011 */
610extern ER_UINT #{@ct_name_body}_#{func_name}(intptr_t par1, intptr_t par2, intptr_t par3, intptr_t par4, intptr_t par5, ID cdmid);
611EOT
612 file2.close
613 end
614
615 def get_callee_cell
616 return @callee_cell
617 end
618
619 def get_caller_cell
620 return @caller_cell
621 end
622
623 def get_callee_ep_name
624 return @join.get_port_name
625 end
626
627 private
628 #
629 # 拡張サービスコール本体における,呼出しå…
630ƒãƒã‚§ãƒƒã‚¯ã®ã‚³ãƒ¼ãƒ‰ã‚’
631 # 出力する
632 # gen_ep_func_body からのみ呼び出される
633 # 引数: 対象の関数名
634 # 返り値: 下記のハッシュ
635 # {"check_code"=>出力するエラーチェックコード,
636 # "user_cannot_callable"=>ユーザドメインが呼出し不可能かどうかのフラグ}
637 #
638 def gen_caller_check_code(func_name)
639 dbgPrint "gen_caller_check_code(func_name): #{@callee_cell.get_name}\n"
640 #
641 # エラーチェック処理
642 #
643 check_code = ""
644 user_cannot_callable = false
645 all_domain_callable = false
646 caller_unrestricted = false
647
648 #
649 # 呼出しå…
650ƒãƒ‰ãƒ¡ã‚¤ãƒ³ã®ãƒã‚§ãƒƒã‚¯å‡¦ç†
651 # callable_domains: 拡張サービスコールを呼出し可能なドメインのリスト
652 # - 無所属のセルから結合されている場合,すべてのセルに対して,
653 #  callable?をチェックし,呼出し可能なすべてのドメインを返す
654 # - 無所属以外のセルから結合されている場合,そのセルに対して
655 # callable?をチェックし,呼出し可能であれば,そのドメインを返す
656 #
657 callable_domains = []
658 @@generated_celltype[ @ct_name_body ].each { |svcplugin|
659 if svcplugin.get_caller_cell.get_region.get_domain_root.get_domain_type.get_option == "OutOfDomain"
660 # 無所属かつ active な場合も、restrict に従う
661 # if svcplugin.get_caller_cell.get_celltype.is_active?
662 # #
663 # # 無所属かつactiveなセルは、TECSから存在が認識されていないのを
664 # # 含む任意のドメインから呼び出される可能性も存在する
665 # #
666 # caller_unrestricted = true
667 # else
668 # #
669 # # 無所属から接続されている場合は,すべてのセルの
670 # # restrictをチェック
671 # #
672 # Cell.get_cell_list2.each { |cell|
673 # if cell.callable?(svcplugin.get_callee_cell, svcplugin.get_callee_ep_name, func_name)
674 # callable_domains << cell.get_region.get_domain_root
675 # end
676 # }
677 # print "callable_domains: "
678 # callable_domains.each{ |dm| print dm.get_name, " " }
679 # print "\n"
680 # end
681
682 # restrict 指定がある場合には、それに従う。さもなければ、チェックしない
683 callable_domains = @callee_cell.get_restricted_regions( get_callee_ep_name, func_name )
684 if callable_domains == nil then
685 caller_unrestricted = true
686 end
687 # print "restrict_list: "
688 # delim = ""
689 # callable_domains.each{ |domain|
690 # print delim, domain
691 # delim = ", "
692 # }
693 # print "\n"
694
695 elsif svcplugin.get_caller_cell.callable?( svcplugin.get_callee_cell, svcplugin.get_callee_ep_name, func_name )
696 #
697 # 特定のドメインから接続されている場合は,呼出しå…
698ƒã‚»ãƒ«ã®
699 # restrictをチェック
700 #
701 callable_domains << svcplugin.get_caller_cell.get_region.get_domain_root
702 else
703 #
704 # 無所属から結合されておらず,特定の呼出しå…
705ƒãƒ‰ãƒ¡ã‚¤ãƒ³ã«ã‚¢ã‚¯ã‚»ã‚¹æ¨©
706 # がない場合,callable_domainsは空となる
707 #
708 # pp "#{svcplugin.get_caller_cell.get_name} cannot call #{svcplugin.get_callee_cell.get_name}_#{svcplugin.get_callee_ep_name}_#{func_name}"
709 end
710 }
711
712 if caller_unrestricted
713 # pp "caller_unrestricted: #{@ct_name_body}"
714 return {"check_code"=>"", "user_cannot_callable"=>false}
715 end
716
717 #
718 # 重複を削除
719 #
720 callable_domains.uniq!
721 #
722 # 無所属に対するドメインチェックは実施しない
723 # カーネルドメインに対するドメインチェックは実施しない
724 #
725 callable_domains = callable_domains.select { |domain|
726 ((domain.get_domain_type.get_option != "OutOfDomain") && \
727 (domain.get_domain_type.get_option != "kernel"))
728 }
729 # pp "callable_domains"
730 # pp callable_domains.map{|domain| domain.get_name }
731 #
732 # すべてのユーザドメインから呼出し可能な場合,ドメインチェックは
733 # 実施しない
734 #
735 all_domain_regions = DomainType.get_domain_regions[:HRP].select { |reg|
736 ((reg.get_domain_type.get_option != "OutOfDomain") && \
737 (reg.get_domain_type.get_option != "kernel"))
738
739 }
740 # pp "all domains"
741 # pp all_domain_regions.map {|reg| reg.get_name}
742 if all_domain_regions.all? {|reg| callable_domains.include?(reg)}
743 all_domain_callable = true
744 end
745
746 #
747 # 呼出しå…
748ƒãƒ‰ãƒ¡ã‚¤ãƒ³ã®ãƒã‚§ãƒƒã‚¯å‡¦ç†æœ¬ä½“の生成
749 #
750 if callable_domains.length == 0
751 dbgPrint "callable_domain.length = 0\n"
752 #
753 # ユーザドメインから呼出し不可能な場合は
754 # 個別のエラーチェックはせず,問答無用でE_OACVを返す
755 #
756 user_cannot_callable = true
757 elsif callable_domains.length == 1
758 dbgPrint "callable_domain.length = 1\n"
759 #
760 # 呼出し可能なユーザドメインが単一の場合は
761 # cdmid != <domain名> の形式でチェックする
762 #
763 check_code += "\t/* HRPSVC0012.1 */\n"
764 check_code += "\tif (cdmid != #{callable_domains[0].get_name}) {\n"
765 elsif callable_domains.length > 1 && !all_domain_callable
766 dbgPrint "callable_domain.length > 1 && not all_domains \n"
767 #
768 # 呼出し可能なユーザドメインが複数の場合は
769 # TACP(cdmid) & (TACP(<domain名>) | ...) != 0U
770 # の形式でチェックする
771 #
772 check_code += "\t/* HRPSVC0012.2 */\n"
773 check_code += "\tif((TACP(cdmid) & ("
774 check_code += (callable_domains.map { |domain| "TACP(#{domain.get_name})"}).join("|")
775 check_code += ")) != 0U) {\n"
776 else
777 dbgPrint "callable_all_domains\n"
778 end
779 if check_code != ""
780 #
781 # 呼出し可能なユーザドメインのチェックがある場合は
782 # エラーコードを返すためのコードを出力する
783 #
784 check_code += <<EOS
785 /* HRPSVC0013 */
786 return E_OACV;
787 }
788EOS
789 end
790
791 return {"check_code"=>check_code, "user_cannot_callable"=>user_cannot_callable}
792 end
793
794 #---------------------------------------------------------#
795 #=== シグニチャのチェック
796 def check_signature signature
797 signature.get_function_head_array.each{ |fh|
798 type = fh.get_return_type
799 check_return_type signature, fh, type
800 if fh.get_paramlist.get_items.length > NUM_SVC_ARG_MAX then
801 cdl_error( "HSV0005 $1.$2: # of parameter more than #{NUM_SVC_ARG_MAX}", signature.get_name, fh.get_name )
802 end
803 fh.get_paramlist.get_items.each{ |param|
804 check_param signature, fh, param
805 }
806 }
807 end
808 #=== 戻り値の型のチェック
809 # ER, ER_UINT は推奨される型
810 # 整数、ブール、void は可能、他は不可
811 def check_return_type signature, fh, type
812 ot = type.get_original_type
813 if( type.get_type_str == "ER" || type.get_type_str == "ER_UINT" ) then
814 # OK!
815 elsif ot.kind_of?( IntType ) || ot.kind_of?( VoidType ) || ot.kind_of?( BoolType ) then
816 cdl_warning( "HSW0001 $1.$2: $3 return type cannot get access violation error", signature.get_name, fh.get_name, type.get_type_str.downcase )
817 check_intptr "#{signature.get_name}.#{fh.get_name} return type", type
818 else
819 cdl_error( "HSV0001 $1.$2 return type $3 cannot be used", signature.get_name, fh.get_name, type.get_type_str.to_s+type.get_type_str_post.to_s )
820 end
821 end
822 #=== 引数の型のチェック
823 def check_param signature, fh, param
824 type = param.get_type
825 ot = type.get_original_type
826 dir = param.get_direction
827 case dir
828 when :IN
829 if ot.kind_of?( IntType ) || ot.kind_of?( BoolType ) then
830 # OK!
831 check_intptr "#{signature.get_name}.#{fh.get_name}.#{param.get_name}", type
832 elsif ot.kind_of? PtrType then
833 check_ptr signature, fh, param, dir
834 else
835 cdl_error( "HSV0002 $1.$2.$3 $4 param type cannot be used", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s+type.get_type_str_post.to_s )
836 end
837 when :OUT, :INOUT
838 if ot.kind_of? PtrType then
839 check_ptr signature, fh, param, dir
840 else
841 # error
842 end
843 when :SEND, :RECEIVE
844 cdl_error( "HSV0008 $1.$2.$3 param direction '$4' cannot be used", signature.get_name, fh.get_name, param.get_name, param.get_direction.to_s.downcase )
845 end
846 end
847 def check_ptr signature, fh, param, dir
848 type = param.get_type.get_referto
849 ot = type.get_original_type
850 if ot.kind_of?( IntType ) || ot.kind_of?( BoolType ) || ot.kind_of?( FloatType ) then
851 # OK!
852 check_intptr "#{signature.get_name}.#{fh.get_name}.#{param.get_name}", type
853 elsif ot.kind_of? PtrType then
854 cdl_error( "HSV0003 $1.$2.$3 multi-pointer type cannot be used", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s+type.get_type_str_post.to_s )
855 elsif ot.kind_of? StructType then
856 check_struct signature, fh, param
857 else
858 cdl_error( "HSV0004 $1.$2.$3 $4 type cannot be used", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s+type.get_type_str_post.to_s )
859 end
860 if ( dir == :OUT || dir == :INOUT) && param.get_string == -1 then
861 cdl_error( "HSV0009 $1.$2.$3 string argment is necessary for out/inout parameter", signature.get_name, fh.get_name, param.get_name )
862 end
863 end
864 def check_struct signature, fh, param
865 type = param.get_type.get_referto
866 ot = type.get_original_type
867 ot.get_members_decl.get_items.each{ |decl|
868 type = decl.get_type
869 ot = type.get_original_type
870 if ot.kind_of?( IntType ) || ot.kind_of?( BoolType ) || ot.kind_of?( FloatType ) then
871 # OK!
872 check_intptr "#{signature.get_name}.#{fh.get_name}.#{param.get_name}.#{decl.get_name} member", type
873 else
874 dbgPrint "struct member #{decl.get_name} #{type} #{decl.get_type} #{decl.get_type.get_original_type}\n"
875 if( decl.get_type.get_original_type.kind_of? ArrayType ) then
876 dbgPrint "member array type #{decl.get_type.get_original_type.get_type} #{decl.get_type.get_original_type.get_type.get_original_type}\n"
877 check_struct_member_array signature, fh, param, decl
878 else
879 cdl_error( "HSV0006 $1.$2.$3 $4 type cannot be used as struct member", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s+type.get_type_str_post.to_s )
880 end
881 end
882 }
883 end
884 def check_struct_member_array signature, fh, param, member_decl
885 # p "check_struct_member_array: #{member_decl.get_type.get_type_str}"
886 type = member_decl.get_type.get_type
887 ot = type.get_original_type
888 if ot.kind_of?( IntType ) || ot.kind_of?( BoolType ) || ot.kind_of?( FloatType ) then
889 # OK!
890 check_intptr "#{signature.get_name}.#{fh.get_name}.#{param.get_name}.#{member_decl.get_name} member", type
891 else
892 cdl_error( "HSV0007 $1.$2.$3 $4 type cannot be used as struct member", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s+type.get_type_str_post )
893 end
894 end
895 def check_intptr msg, type
896 dbgPrint "check_intptr IN\n"
897 t = type
898 while( t.kind_of? DefinedType )
899 dbgPrint "check_intptr #{msg} #{t.get_type_str} #{t.get_original_type.get_type_str}\n"
900 tstr = t.get_type_str
901 tstr.sub!( /const /, "" )
902 tstr.sub!( /volatile /, "" )
903 if tstr == "intptr_t" || tstr == "uintptr_t" then
904 cdl_info( "HSI0001 $1 type '$2' not checked by plugin", msg, type.get_type_str )
905 end
906 t = t.get_type
907 end
908 end
909end
910
Note: See TracBrowser for help on using the repository browser.