📄 module.hhf
字号:
#if( ! @defined( module_hhf ))?module_hhf := true;#includeonce( "os/atomic.hhf" )namespace linux; @fast;const // Bits of module.flags: mod_uninitialized := 0; mod_running := 1; mod_deleted := 2; mod_autoclean := 4; mod_visited := 8; mod_used_once := $10; mod_just_freed := $20; mod_initializing := $40; // Values for query module's which: qm_modules := 1; qm_deps := 2; qm_refs := 3; qm_symbols := 4; qm_info := 5; type kernel_sym: record value :dword; theName :char[60]; endrecord; module_persist :dword; // Really an empty structure, // But HLA doesn't allow this. module_symbol: record value :dword; theName :pointer to char; endrecord; module_ref: record dep :pointer to module_t; ref :pointer to module_t; next_ref :pointer to module_ref; endrecord; module_info: record addr :dword; size :dword; flags :dword; usecount:uns32; endrecord; module_t: record size_of_struct :uns32; next :pointer to module_t; _name :pointer to char; size :uns32; uc: union usecount :atomic_t; pad :dword; endunion; flags :dword; nsyms :uns32; ndeps :uns32; syms :pointer to module_symbol; deps :pointer to module_ref; refs :pointer to module_ref; init :procedure; @returns( "eax" ); cleanup :procedure; // The following members are all optional. // At run-time, compare their offsets against // the size_of_struct field to see if they are // actually present (use mod_member_present for this). ex_table_start :pointer to exception_table_entry; ex_table_end :pointer to exception_table_entry; persist_start :pointer to module_persist; persist_end :pointer to module_persist; can_unload :procedure; @returns( "eax" ); runsize :dword; kallsyms_start :pointer to char; kallsyms_end :pointer to char; archdata_start :pointer to char; archdata_end :pointer to char; kernel_data :pointer to char; endrecord; // mod_member_present- passed a module_t object and // a field. Checks to see if the field is present in // the particular instance of the module object. // returns an "above" (@a) condition code if the field is present. // Generally, you'd invoke this macro where a (run-time) // boolean expression is expected (e.g., in an IF stmt). #macro mod_member_present(__mod,__member):__fn; ?__fn := "linux.module_t." + @string:__member; returns({ cmp ( __mod.size_of_struct, @offset( @text(__fn) ) ); },"@a") #endmacro; // mod_can_query - returns true in EAX if we can query the // module. We can query it if it's running or initializing, // but not deleted. Note that this macros *know* the values // of mod_running, mod_initializing, and mod_deleted and // you must rewrite this macros if their values change. #macro mod_can_query(__mod); returns ({ mov( (type byte __mod.flags), al ); and ( linux.mod_running // Bit 0 | linux.mod_initializing // Bit 6 | linux.mod_deleted, // Bit 1 eax ); ror( 1, al ); // r0i0_000d shr( 1, al ); // 0r0i_0000 d (in carry) setnbe( al ); // carry = @b so fail if @be. },"eax" ) #endmacro; static __this_module :module_t; @external( "__this_module" ); #macro mod_inc_use_count; push( eax ); mov( linux.__this_module.uc.usecount.counter, eax ); lock.inc( (type dword [eax]) ); or ( linux.mod_visited | linux.mod_used_once, linux.__this_module.flags ); pop( eax ); #endmacro; #macro mod_dec_use_count; push( eax ); mov( linux.__this_module.uc.usecount.counter, eax ); lock.dec( (type dword [eax]) ); or( linux.mod_visited, linux.__this_module.flags ); pop( eax ); #endmacro; #macro mod_in_use; returns ( { if ( linux.mod_member_present( can_unload ) && linux.__this_module <> 0 ) then call( linux.__this_module.can_unload ); else mov ( linux.__this_module.uc.usecount.counter, eax ); mov( [eax], eax ); endif; }, "eax" ) #endmacro; // module_parm( sym, typ) - // sym must be the name of a global variable. // typ must be a string constant. // Creates a parameter definition record in the object file. #macro module_parm( sym, typ):modname,modstr; ?modname :string := "__module_parm_" + @string:sym; ?modstr :string := "parm_" + @string:sym + "=" + typ; #emit( " .globl " + modname ) #emit( " .section .modinfo" ) #emit( " .type " + modname + ",@object" ) #emit ( " .size " + modname + "," + string(@length(modstr)+1) ) #emit( modname + ":" ) #emit( " .string """ + modstr + """" ) #endmacro; // module_parm_desc( sym, typ) - // sym must be the name of a global variable. // cmnt must be a string constant. // Creates a parameter description record in the object file. #macro module_parm_desc( sym, cmnt):modname,modstr; ?modname :string := "__module_parm_desc_" + @string:sym; ?modstr :string := "parm_desc_" + @string:sym + "=" + cmnt; #emit( " .globl " + modname ) #emit( " .align 32" ) #emit( " .type " + modname + ",@object" ) #emit ( " .size " + modname + "," + string(@length(modstr)+1) ) #emit( modname + ":" ) #emit( " .string """ + modstr + """" ) #endmacro; #if( @defined( __kernel__ ))type inter_module_entry: record list :list_head; im_name :pointer to char; owner :pointer to module_t; userdata:dword; endrecord; procedure _inter_module_register ( _string :string; var module :module_t; var data :var ); @cdecl; @external( "inter_module_register" ); #macro inter_module_register( __s, __m, __d ); returns ({ push( eax ); push( ecx ); push( edx ); _inter_module_register( __s, __m, __d ); add( 12, esp ); pop( edx ); pop( ecx ); pop( eax ); },"" ) #endmacro; procedure _inter_module_unregister ( _string :string ); @cdecl; @external( "inter_module_unregister" ); #macro inter_module_unregister( __s, __m, __d ); returns ({ push( eax ); push( ecx ); push( edx ); _inter_module_register( __s ); pop( eax ); // removes __s pop( edx ); pop( ecx ); pop( eax ); },"" ) #endmacro; procedure _inter_module_get ( _string :string ); @cdecl; @external( "inter_module_get" ); #macro inter_module_get( __s ); returns ({ push( ecx ); push( edx ); _inter_module_get( __s ); pop( ecx ); // removes __s pop( edx ); pop( ecx ); },"eax" ) #endmacro; procedure _inter_module_put ( _string :string ); @cdecl; @external( "inter_module_put" ); #macro inter_module_put( __s ); returns ({ push( eax ); push( ecx ); push( edx ); _inter_module_put( __s ); pop( ecx ); // removes __s pop( edx ); pop( ecx ); pop( eax ); },"" ) #endmacro; procedure _inter_module_get_request ( _string :string; _module :string ); @cdecl; @external( "inter_module_get_request" ); #macro inter_module_get_request( __s, __m ); returns ({ push( ecx ); push( edx ); _inter_module_get_request( __s, __m ); add( 8, esp ); pop( edx ); pop( ecx ); },"eax" ) #endmacro; #endif //__kernel__ end linux; #endif // module_hhf
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -