![]() |
Software > OpenVMS Systems > Ask the Wizard ![]() HP OpenVMS Systemsask the wizard |
![]() |
The Question is: Hello M. Wizard, I would like to use the system service sys$lckpag to lock a homemade C routine in memory. Is there a formula to evaluate the number of pages to lock using the size of the source code? The Answer is : The first question asked usually involves "why?". What problem(s) do you seek to solve? Use of tools such as INSTALL typically do a good job of keeping the necessary pages in memory, and should generally be overridden only in very specific circumstances... (And when necessary, a set of batch or detached procedures that do nothing more than run and simply hold open the installed image(s).) That said, the usual technique for locking routines in memory involves the use of the sys$lkwset call, and not sys$lckpag. The usual technique for locating the beginning and end of the routine uses LINKER directives and C external variables -- you create and collect the memory into specific sequences, and can then use the addresses of the variables in the PSECTs to locate the ranges of virtual memory involved. On OpenVMS Alpha, you must account for both the contents of the code PSECT and the linkage PSECT. (The linkage PSECT construct contains information describing the procedure. OpenVMS VAX does not have this construct.) An example follows: $ CC /OBJECT=TEST /LIST=TEST /MACHINE SYS$INPUT: #pragma module test_code "v1.0" /* Define the references to the linkage and code psects */ #pragma extern_model save #pragma extern_model strict_refdef "$$C$LINKAGE_BEGIN" noshr void *__linkage_begin ; #pragma extern_model restore #pragma extern_model save #pragma extern_model strict_refdef "__C$LINKAGE_END" noshr void *__linkage_end ; #pragma extern_model restore #pragma extern_model save #pragma extern_model strict_refdef "$$C$CODE_BEGIN" shr void *__code_begin ; #pragma extern_model restore #pragma extern_model save #pragma extern_model strict_refdef "__C$CODE_END" shr void *__code_end ; #pragma extern_model restore #include <stdio.h> void test_routine() ; main() int *lp ; printf("The addresses of the linkage section are:\n"); printf(" begin: %08p end: %08p\n", &__linkage_begin, &__linkage_end); printf("The addresses of the code section are:\n"); printf(" begin: %08p end: %08p\n", &__code_begin, &__code_end); printf("The address of main(linkage) is: %08p\n", main) ; printf("The address of test_routine(linkage) is %08p\n", test_routine); lp = (int*) &main ; printf("The address of main(code) is: %08p\n", lp[2] ) ; lp = (int*) &test_routine ; printf("The address of test_routine(code) is %08p\n", lp[2] ) ; void test_routine() printf("Test Routine") ; $ LINK /MAP=TEST_CODE /CROSS/FULL/EXE=TEST_CODE TEST - + SYS$INPUT:/OPT ! Match code and linkage section psect attributes psect= $$C$CODE_BEGIN,PIC,CON,REL,LCL, SHR, EXE,NOWRT,NOVEC, MOD psect= __C$CODE_END,PIC,CON,REL,LCL, SHR, EXE,NOWRT,NOVEC, MOD psect=$$C$LINKAGE_BEGIN,NOPIC,CON,REL,LCL,NOSHR,NOEXE,NOWRT,NOVEC,MOD psect=__C$LINKAGE_END,NOPIC,CON,REL,LCL,NOSHR,NOEXE,NOWRT,NOVEC,MOD $ RUN TEST_CODE
|