1/* 2 Hercules Dynamic Loader 3 4 The dynamic loader is intended to supply a loading and linking 5 mechanism, whereby routines, commands, instructions and functions 6 can be dynamically added to hercules, without the need to rebuild 7 or even restart hercules. 8 9 The loader can be controlled by the following hercules commands: 10 11 ldmod <module list> - Load modules named in module list 12 rmmod <module list> - Unload modules named in list 13 lsmod - List all modules and entry points 14 lsdep - List all dependencies 15 16 The ldmod statement may also appear in the hercules 17 configuration file. 18 19 configuration statement: 20 modpath <pathname> - Specifies where modules are loaded from 21 22 23 The loader has 2 basic functions module load and module unload. 24 25 Module load: 26 27 int hdl_load(char *name, int flags); 28 29 Where name is the module name, this name may include the 30 path. If no path is given then the module is loaded from 31 the default library search order. Note that this is 32 different from the standard search order. 33 34 flags may be one of the following: 35 36 HDL_LOAD_DEFAULT or 0 - Default load 37 HDL_LOAD_MAIN - Reserved for hercules use 38 HDL_LOAD_NOUNLOAD - Module cannot be unloaded 39 HDL_LOAD_FORCE - Override dependency check 40 HDL_LOAD_NOMSG - Do not issue any error messages 41 42 This function returns a zero value when the load is successful. 43 44 45 Module unload: 46 47 int hdl_dele(char *name); 48 49 Where name is the name of the module that is to be unloaded. 50 51 This function returns a zero value when the unload is successful. 52 53 54 Resolving Symbols: 55 56 void * HDL_FINDSYM(char *symbolname); 57 58 This function will return the entry point of symbolname or 59 zero when the symbol cannot be resolved. 60 61 void * HDL_FINDNXT(current_entry point); 62 63 This function will return the previous entry point. 64 That is, the entry point which was current before the entry point 65 as identified by current_entry point was registered. 66 67 This function is intended to allow a module to call the original 68 routine. An example of this is given in the panel_command entry 69 as listed below. 70 71 72 There are some special considerations for systems that do not support 73 the concept of back-linking. Back-linking is the operating system 74 support of dynamically resolving unresolved external references in 75 a dynamic module, with the main module, or other loaded modules. 76 Cygwin does not support back-linking and Cygwin specials are listed 77 in this example with #if defined(WIN32). 78 79 80 Some additional notes: 81 82 Unload will remove all references to a specific module, but currently 83 it will not actually remove the loaded module from memory. This is 84 because there is no safe way (yet) to synchronize unloading of code 85 and, besides, it may still be in use. This should however pose no 86 practical limitations. 87 88 When a module lists a new dependency, that dependency will be regis- 89 tered. Unloading the module does not remove the dependency, this is 90 to be consistent with the previous note about unloading. 91 92 93 94 Diagnose F14 - dll interface 95 96 Purpose: 97 98 Allow external routines to be called from OS running under hercules 99 external routines must reside in hercules dll's 100 101 102 Instruction: 103 104 Format: 105 106 83 r1 r3 d2(b2) 107 108 r1: register containing real address of external routine name to be 109 called this routine name is defined as CL32, and is subject to 110 EBCDIC to ASCII translation under control of hercules codepages. 111 This parameter must be 32 byte aligned. 112 113 r3: register containing user parameter. 114 115 d2(b2): 0xF14 116 117 118 External routine: 119 120 void xxxx_diagf14_routine_name(int r1, int r3, REGS *regs); 121 122 xxxx_diagf14_ prefix to routine_name 123 xxxx being either s370, s390 or z900 depending on architecture mode. 124 125 The instruction is subject to machine malfunction checking. 126 The external routine may be interrupted when an extended wait or loop 127 occurs. 128 129 130*/ 131 132#include "hercules.h" 133#include "devtype.h" 134#include "opcode.h" 135 136 137/* Local definitions */ 138 139 140static void *gui_cpu_state(REGS *regs) 141{ 142 void *(*prev_cpu_state)(REGS *); 143 144 /* CPU status update processing */ 145 146 /* Call higher level routine if one exists */ 147 if((prev_cpu_state = HDL_FINDNXT(gui_cpu_state))) 148 return prev_cpu_state(regs); 149 150 return NULL; 151} 152 153 154void *ProcessCommand (char *command) 155{ 156void * (*prev_panel_command)(char *); 157 158 if (strncasecmp(command,"ourcmd",6) == 0) 159 { 160 logmsg ("This is our command\n"); 161 } 162 else 163 /* Call higher level command handler */ 164 if((prev_panel_command = HDL_FINDNXT(ProcessCommand))) 165 return prev_panel_command(command); 166 167 return NULL; 168} 169 170 171/* 172 The dependency section is - for all intents and purposes - called 173 before the module is loaded. Its function is to check that there 174 are no incompatibilities between this module and the version of 175 hercules that we are running. Dependencies are identified by 176 name, this name is given on the HDL_DEPENDENCY statement. 177 178 Each dependency then has a version code, and a size code, where 179 the version code is a character string, and the size code an 180 integer value. If the version or size codes do not match with 181 those in the hercules main module, the module cannot be loaded. 182 The version is usually a character string that identifies the 183 version of the component, and the size is to be the size of 184 the component in the case of structures or unions. 185 186 Version and size should be coded as following: 187 188 #define HDL_VERS_SOMETHING "1.0" 189 #define HDL_SIZE_SOMETHING sizeof(SOMETHING) 190 191 where SOMETHING can be a structure or other component. 192 193 the associated dependency statement: 194 195 HDL_DEPENDENCY(SOMETHING); 196 197 When a dependency is given that has not yet been registered, 198 it will be registered, such that it can be checked in subsequent 199 module loads. 200 201 The dependency section is mandatory. 202 203*/ 204 205HDL_DEPENDENCY_SECTION; 206{ 207 /* Define version dependencies that this module requires */ 208 HDL_DEPENDENCY ( HERCULES ); 209 HDL_DEPENDENCY ( SYSBLK ); 210 HDL_DEPENDENCY ( REGS ); 211 HDL_DEPENDENCY ( DEVBLK ); 212} 213END_DEPENDENCY_SECTION; 214 215 216/* 217 The registration exports labels and their associated entry points 218 to hercules, such that the symbols and associated entry points may 219 be known to hercules and any other module that may have been loaded. 220 The registration section is called once during module load. 221 222 If we have registered a function that is also called from this DLL, 223 then it must also be listed in the resolver section. This to ensure 224 that the symbol is properly resolved when other modules are loaded. 225 226 The registration section is optional. 227 228*/ 229 230 231HDL_REGISTER_SECTION; 232{ 233 /* These are the entry points we export to Hercules 234 All functions and labels used this dll must be static 235 and non exportable, this to ensure that no foreign 236 names are included by the system loader on systems 237 that provide back-link support (mostly *nix systems) 238 */ 239 240 HDL_REGISTER ( daemon_task, external_gui_interface ); 241 HDL_REGISTER ( debug_cpu_state, gui_cpu_state ); 242 HDL_REGISTER ( panel_command, ProcessCommand ); 243} 244END_REGISTER_SECTION; 245 246 247/* 248 The resolver section imports the entry points of symbols that 249 have been previously registered. 250 251 When a symbol is requested that has not been previously registered 252 then the resolve function will search the loaded modules for 253 that symbol, and register it implicitly. This latter function 254 is mainly provided to support systems that do not have back-link 255 support (most notably Cygwin). 256 257 Entry points that are resolved should be indirect pointers, for 258 example the panel_command routine is defined as: 259 260 void *(*panel_command)(char *) 261 262 The resolver may be called multiple times, the first time it is 263 called is during module load, immediately after the registration 264 section is called. It is subsequently called when other modules 265 are loaded or unloaded. 266 267 When a symbol cannot be resolved it will be set to NULL. 268 269 The resolver section is optional. 270 271*/ 272 273 274HDL_RESOLVER_SECTION; 275{ 276 /* These are Hercules's entry points that we need access to 277 these may be updated by other loadable modules, so we need 278 to resolve them here. 279 */ 280 281 HDL_RESOLVE ( panel_command ); 282 HDL_RESOLVE ( debug_cpu_state ); 283 284 HDL_RESOLVE_PTRVAR ( my_sysblk_ptr, sysblk ); 285} 286END_RESOLVER_SECTION; 287 288 289/* 290 The device section is to register device drivers with hercules. 291 It associates device types with device handlers 292 293 If a device handler is not registered for a specific device type 294 then and a loadable mode with the name of "hdtxxxx" (where xxxx 295 is the device type) exists then that module is loaded 296 297 Search order: 298 1) The most recently registered (ie loaded) device of the 299 requested device type. 300 2) Device driver in external loadable module, where the 301 module name is hdtxxxx (where xxxx is the device type 302 ie module name hdtlcs for device type LCS or hdt2703 303 for device type 2703) 304 3) If the device is listed in the alias table (hdteq.c) 305 then external module hdtyyyy will be loaded, where 306 yyyy is the base name as listed in hdteq.c. 307 The device name is always mapped to lower case when searching 308 for loadable modules. 309 310 The device section is optional 311*/ 312 313HDL_DEVICE_SECTION; 314{ 315 HDL_DEVICE(1052,constty_device_hndinfo); 316 HDL_DEVICE(3215,constty_device_hndinfo); 317} 318END_DEVICE_SECTION; 319 320/* The instruction section registers inserts optional instructions, 321 or modifies existing instructions. 322 323 Instructions are generally defined with DEF_INST(instname) which results 324 in an external reference of s370_instname, s390_instname and z900_instname. 325 If an instruction is not defined for a certain architecture mode then 326 UNDEF_INST(instname) must be used for that given architecture mode. 327 328 The instruction section is optional 329*/ 330 331HDL_INSTRUCTION_SECTION; 332{ 333 HDL_DEFINST(HDL_INSTARCH_370,0xB2FE,new_B2FE_inst_doing_something); 334 HDL_DEFINST(HDL_INSTARCH_390|HDL_INSTARCH_900,0xB2FD,new_B2FD_inst_doing_something_else); 335} 336END_INSTRUCTION_SECTION; 337 338 339/* 340 The final section is called once, when the module is unloaded 341 or when hercules terminates. 342 343 A dll can reject being unloaded by returning a non-zero value 344 in the final section. 345 346 The final section is intended to be used to perform cleanup or 347 indicate cleanup action to be taken. It may set a shutdown 348 flag that is used within this dll that all local functions 349 must now terminate. 350 351 The final section is optional 352*/ 353 354HDL_FINAL_SECTION; 355{ 356 357} 358END_FINAL_SECTION; 359 360 361 362 363Below is Fish's sample code... 364 365 366/* Define version dependencies that this module requires... 367** 368** The following are the various Hercules structures whose layout your 369** module depends on. The layout of the following structures (size and 370** version) MUST match the layout that was used to build Hercules with. 371** If the size/version of any of the following structures changes (and 372** a new version of Hercules is built using the new layout), then YOUR 373** module must also be built with the new layout as well. The layout of 374** the structures as they were when your module is built MUST MATCH the 375** layout as it was when the version of Hercules you're using was built. 376** Further note that the below HDL_DEPENDENCY_SECTION is actually just 377** a function that the hdl logic calls, and thus allows you to insert 378** directly into the below section any specialized 'C' code you need. 379*/ 380HDL_DEPENDENCY_SECTION; 381{ 382 HDL_DEPENDENCY(HERCULES); 383 HDL_DEPENDENCY(REGS); 384 HDL_DEPENDENCY(DEVBLK); 385 HDL_DEPENDENCY(SYSBLK); 386 HDL_DEPENDENCY(WEBBLK); 387} 388END_DEPENDENCY_SECTION; 389 390 391/* Register re-bindable entry point with resident version, or UNRESOLVED 392** 393** The following section defines the entry points within Hercules that 394** your module is overriding (replacing). Your module's functions will 395** be called by Hercules instead of the normal Hercules function (if any). 396** The functions defined below thus provide additional/new functionality 397** above/beyond the functionality normally provided by Hercules. Be aware 398** however that it is entirely possible for other dlls to subsequently 399** override the same functions that you've overridden such that they end 400** up being called before your override does and your override may thus 401** not get called at all (depending on how their override is written). 402** Note that the "entry-point name" does not need to correspond to any 403** existing variable or function (i.e. the entry-point name is just that: 404** a name, and nothing more. There does not need to be a variable defined 405** anywhere in your module with that name). Further note that the below 406** HDL_REGISTER_SECTION is actually just a function that the hdl logic 407** calls, thus allowing you to insert directly into the below section 408** any specialized 'C' code that you may need. 409*/ 410HDL_REGISTER_SECTION; 411{ 412 /* register this as the address of 413 entry-point name, this var or func 414 */ 415 HDL_REGISTER( panel_command, my_panel_command ); 416 HDL_REGISTER( panel_display, my_panel_display ); 417 HDL_REGISTER( some_exitpoint, UNRESOLVED ); 418} 419END_REGISTER_SECTION; 420 421 422/* Resolve re-bindable entry point on module load or unload... 423** 424** The following entries "resolve" entry points that your module 425** needs. These entries define the names of registered entry points 426** that you need "imported" into your dll so that you may call them 427** directly yourself. The HDL_RESOLVE_PTRVAR macro is used to auto- 428** matically set one of your own pointer variables to the registered 429** entry point's currently registered value (usually an address of 430** a function or variable). Note that the HDL_RESOLVER_SECTION is 431** actually just a function that the hdl logic calls, thus allowing 432** you to insert directly into the below section any specialized 'C' 433** code that you may need. 434*/ 435HDL_RESOLVER_SECTION; 436{ 437 /* Herc's registered 438 entry points that 439 you need to call 440 directly yourself 441 */ 442 HDL_RESOLVE( config_command ); 443 HDL_RESOLVE( some_exitpoint ); 444 HDL_RESOLVE( debug_cpu_state ); 445 HDL_RESOLVE( debug_program_interrupt ); 446 HDL_RESOLVE( debug_diagnose ); 447 448 /* The following illustrates how to use HDL_RESOLVE_PTRVAR 449 macro to retrieve the address of one of Herc's registered 450 entry points. 451 452 Your pointer- Herc's registered 453 variable name entry-point name 454 */ 455 HDL_RESOLVE_PTRVAR( my_sysblk_ptr, sysblk ); 456} 457END_RESOLVER_SECTION; 458 459 460/* The following section defines what should be done just before 461** your module is unloaded. It is nothing more than a function that 462** is called by hdl logic just before your module is unloaded, and 463** nothing more. Thus you can place any 'C' code here that you want. 464*/ 465HDL_FINAL_SECTION; 466{ 467 my_cleanup(); 468} 469END_FINAL_SECTION; 470 471 472 473 474/* DYNDIAG.C (c) Copyright Jan Jaeger, 2003 */ 475/* Hercules Dynamic Loader */ 476 477/* Sample diagf14 dll routine */ 478 479/* */ 480/* Assembler to call routine: */ 481/* */ 482/* LRA R1,=CL32'test' */ 483/* LRA R2,=X'01020304' USERPARM */ 484/* DC X'83120F14' DIAG R1,R2,X'F14' */ 485/* */ 486 487 488#include "hercules.h" 489 490#include "opcode.h" 491 492#include "inline.h" 493 494 495void ARCH_DEP(diagf14_test) (int r1, int r3, REGS *regs) 496{ 497U32 r3loc; 498 499 logmsg("diagf14: r3 = %8.8X\n",regs->GR_L(r3)); 500 r3loc = ARCH_DEP(vfetch4) (regs->GR_L(r3), USE_REAL_ADDR, regs); 501 logmsg("diagf14: *r3 = %8.8X\n",r3loc); 502} 503 504 505 506#if !defined(_GEN_ARCH) 507 508#if defined(_ARCHMODE2) 509 #define _GEN_ARCH _ARCHMODE2 510 #include "dyndiag.c" 511#endif 512 513#if defined(_ARCHMODE3) 514 #undef _GEN_ARCH 515 #define _GEN_ARCH _ARCHMODE3 516 #include "dyndiag.c" 517#endif 518 519 520HDL_DEPENDENCY_SECTION; 521{ 522 HDL_DEPENDENCY (HERCULES); 523 HDL_DEPENDENCY (REGS); 524 HDL_DEPENDENCY (DEVBLK); 525 HDL_DEPENDENCY (SYSBLK); 526 527} END_DEPENDENCY_SECTION; 528 529 530HDL_REGISTER_SECTION; 531{ 532 533 HDL_REGISTER(s370_diagf14_test,s370_diagf14_test); 534 HDL_REGISTER(s390_diagf14_test,s390_diagf14_test); 535 HDL_REGISTER(z900_diagf14_test,z900_diagf14_test); 536 537} END_REGISTER_SECTION; 538 539 540HDL_RESOLVER_SECTION; 541{ 542 543} END_RESOLVER_SECTION; 544 545HDL_FINAL_SECTION; 546{ 547 548} END_FINAL_SECTION; 549 550 551#endif /*!defined(_GEN_ARCH)*/ 552 553/* END DYNDIAG.C */ 554 555 556 557/* DYNCGI.C (c)Copyright Jan Jaeger, 2002-2003 */ 558/* HTTP cgi-bin routines */ 559 560/* This file contains cgi routines that may be executed on the */ 561/* server (ie under control of a hercules thread) */ 562/* */ 563/* */ 564/* Dynamically loaded cgi routines must be registered under the */ 565/* pathname that they are accessed with (ie /cgi-bin/test) */ 566/* All cgi pathnames must start with /cgi-bin/ */ 567/* */ 568/* */ 569/* The cgi-bin routines may call the following HTTP service routines */ 570/* */ 571/* char *cgi_variable(WEBBLK *webblk, char *name); */ 572/* This call returns a pointer to the cgi variable requested */ 573/* or a NULL pointer if the variable is not found */ 574/* */ 575/* char *cgi_cookie(WEBBLK *webblk, char *name); */ 576/* This call returns a pointer to the cookie requested */ 577/* or a NULL pointer if the cookie is not found */ 578/* */ 579/* char *cgi_username(WEBBLK *webblk); */ 580/* Returns the username for which the user has been authenticated */ 581/* or NULL if not authenticated (refer to auth/noauth parameter */ 582/* on the HTTPPORT configuration statement) */ 583/* */ 584/* char *cgi_baseurl(WEBBLK *webblk); */ 585/* Returns the url as requested by the user */ 586/* */ 587/* void html_header(WEBBLK *webblk); */ 588/* Sets up the standard html header, and includes the */ 589/* html/header.htmlpart file. */ 590/* */ 591/* void html_footer(WEBBLK *webblk); */ 592/* Sets up the standard html footer, and includes the */ 593/* html/footer.htmlpart file. */ 594/* */ 595/* int html_include(WEBBLK *webblk, char *filename); */ 596/* Includes an html file */ 597/* */ 598/* */ 599/* Jan Jaeger - 28/03/2002 */ 600 601#include "hstdinc.h" 602#include "hercules.h" 603#include "devtype.h" 604#include "opcode.h" 605#include "httpmisc.h" 606 607#if defined(OPTION_HTTP_SERVER) 608 609void cgibin_test(WEBBLK *webblk) 610{ 611 html_header(webblk); 612 hprintf(webblk->hsock, "<H2>Sample cgi routine</H2>\n"); 613 html_footer(webblk); 614} 615 616 617HDL_DEPENDENCY_SECTION; 618{ 619 HDL_DEPENDENCY(HERCULES); 620// HDL_DEPENDENCY(REGS); 621// HDL_DEPENDENCY(DEVBLK); 622// HDL_DEPENDENCY(SYSBLK); 623 HDL_DEPENDENCY(WEBBLK); 624} 625END_DEPENDENCY_SECTION; 626 627 628HDL_REGISTER_SECTION; 629{ 630 HDL_REGISTER( /cgi-bin/test, cgibin_test ); 631} 632END_REGISTER_SECTION; 633 634 635HDL_RESOLVER_SECTION; 636{ 637} 638END_RESOLVER_SECTION; 639 640 641HDL_FINAL_SECTION; 642{ 643} 644END_FINAL_SECTION; 645 646#endif /*defined(OPTION_HTTP_SERVER)*/ 647 648 649 650/* TESTINS.C Test instruction */ 651 652#include "hercules.h" 653 654#include "opcode.h" 655 656/*-------------------------------------------------------------------*/ 657/* 0000 BARF - Barf [RR] */ 658/*-------------------------------------------------------------------*/ 659DEF_INST(barf) 660{ 661int r1, r2; /* register values */ 662 663 RR(inst, regs, r1, r2) 664 665 logmsg("Barf\n"); 666 667 ARCH_DEP(program_interrupt)(regs, PGM_OPERATION_EXCEPTION); 668} 669 670 671#if !defined(_GEN_ARCH) 672 673#if defined(_ARCHMODE2) 674 #define _GEN_ARCH _ARCHMODE2 675 #include "testins.c" 676#endif 677 678#if defined(_ARCHMODE3) 679 #undef _GEN_ARCH 680 #define _GEN_ARCH _ARCHMODE3 681 #include "testins.c" 682#endif 683 684 685HDL_DEPENDENCY_SECTION; 686{ 687 688} END_DEPENDENCY_SECTION; 689 690 691HDL_INSTRUCTION_SECTION; 692{ 693 HDL_DEFINST(HDL_INSTARCH_ALL,0x00,barf); 694 695} END_INSTRUCTION_SECTION; 696 697#endif /*!defined(_GEN_ARCH)*/ 698