home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!stanford.edu!agate!dog.ee.lbl.gov!network.ucsd.edu!mvb.saic.com!macro32
- From: Hunter Goatley <goathunter@WKUVX1.BITNET>
- Newsgroups: vmsnet.internals
- Subject: Locking down C routines under Alpha
- Message-ID: <00963AA1.423C6B80.1463@WKUVX1.BITNET>
- Date: Sun, 15 Nov 1992 19:04:38 CST
- Organization: Macro32<==>Vmsnet.Internals Gateway
- X-Gateway-Source-Info: Mailing List
- Lines: 182
-
- Patrick Mahan (mahan@TGV.COM) sent me the following message and asked
- me to forward it to MACRO32.
-
- Hunter
- ------
- Hunter Goatley, VMS Systems Programmer, Western Kentucky University
- goathunter@WKUVX1.BITNET, 502-745-5251
-
- ---------------------------------------------------------------------------
- Date: Sun, 15 Nov 92 16:44:44 PST
- From: <mahan@TGV.COM>
-
- #
- #gleason@mwk.uucp writes:
- #>
- #> OK, got my Alpha station, and I'm converting reams of MACRO-32 to
- #>C, learning C as I go (and this gives me plenty of practice reading
- #>Alpha crash dumps ;-) ).
- #>
- #Fun, isn't it? 8-)
- #
-
- LDL, LDL, LDL, LDL, LDL, STO, LDL, LDL, LDL (yea, almost like a song ;-)).
-
- #
- #> In many of these programs, entire routines need to be locked in the
- #>working set.
- #>
- #> In the original MACRO program, all I had to do was something like...
- #[...]
- #> What's the best way to do the equivalent in C? Getting the start
- #>address is not so hard...(int*)&funcname seems to be adequate...but
- #>I don't know how to get the ending address...
- #>
- #The only way I've been able to do it is by putting another (possibly
- #void) routine after the one you want.
- #
-
- Correct. Under VAX C you can used stub procedures to bracket the code
- you want to lock down.
-
- #
- #Note however that this still doesn't do what you want/need to do.
- #Under Alpha, the address of the function is actually the address of
- #the procedure descriptor for that function. Specifying those
- #addresses just locks down the procedure descriptor, which needs to be
- #done, but you must also still lock down the code itself.
- #
- #With the Alpha porting toolkit, there is a MACRO-32 example in the
- #_Porting MACRO-32 Code_ (whatever it's really called). It uses some
- #new macros to lock things down: $LOCKED_PAGE_START and
- #$LOCKED_PAGE_END. There's also $LOCK_PAGE and $LOCK_PAGE_INIT, but
- #I'm not sure how they're used. The macros are not available for
- #anything except MACRO-32, as far as I can tell.
- #
- #Another manual (_Recompiling and Relinking_) talked about this
- #problem, but the C example was "To be supplied" in all the field test
- #documentation. I haven't had time to take the macros and figure
- #out how to do it for C.
- #
-
- The way to perform this same feat under GEM C on the Alpha is in three
- steps.
-
- 1) Place all of the code that needs to be locked down inside of
- one or more code modules where they WILL NOT share with code
- that doesn't need to be locked down.
-
- Now using the CLUSTER link option, create 3 clusters in your
- image like so
-
- CLUSTER=START_OF_LOCKED_CODE
- CLUSTER=LOCKED_CODE,,,LOCKED_CODE.OBJ
- CLUSTER=END_OF_LOCKED_CODE
-
- Using the COLLECT link option, place a symbol in the clusters
- START_OF_LOCKED_CODE and END_OF_LOCKED_CODE so that you can
- later reference them, for example:
-
- COLLECT=START_OF_LOCKED_CODE,START_OF_CODE
- COLLECT=END_OF_LOCKED_CODE,END_OF_CODE
-
- You now have two references that bracket the code, including the
- linkage sections, that you want to lock down.
-
- 2) In the routine you wish to lock the code down in, declare both
- "endpoints" of your lock code like so -
-
- extern START_OF_CODE(), END_OF_CODE();
-
- However, you cannot just lock down everything in memory starting
- at START_OF_CODE and ending at END_OF_CODE because of the way the
- Alpha linker works. On the Alpha, the linker does some page
- aligning which will cause "holes" in your image, this side
- effect is documented in the RECOMPILING_RELINKING manual provided
- with the cross tools.
-
- Instead, first retrieve the system PAGE SIZE via a call to
- $GETSYI using the item code (SYI$_PAGE_SIZE). Then starting with
- the address pointed to by START_OF_CODE, first check to see if
- the page is readable using the C builtin __PAL_PROBER instruction.
- If it is readable, then lock that page down, and move on to
- the next page in memory. Repeat this until you have reached the
- address pointed to by END_OF_CODE. Below is a C routine I wrote
- to lock down all of the known pages between two addresses.
-
-
- #include <syidef.h>
- #include <decc$library_include:builtins.h>
- /*
- * Lock pages in memory for Alpha. We do this because the address
- * space we want to lock down is not contiguous. Thus we probe
- * each page for Read then lock it down.
- */
- int Lock_Alpha_Pages(Addr_Start, Addr_End)
- char *Addr_Start, *Addr_End;
- {
- int i;
- unsigned long int Page_Size;
- unsigned long int InAddr[2];
- char Error[200];
- struct {
- unsigned short int Size;
- unsigned short int Code;
- char *Buffer;
- unsigned short int *Resultant_Length;
- } ItemList[2];
-
- /*
- * Get the PAGE SIZE of the System
- */
- ItemList[0].Size = sizeof(Page_Size);
- ItemList[0].Code = SYI$_PAGE_SIZE;
- ItemList[0].Buffer = (char *)&Page_Size;
- ItemList[0].Resultant_Length = 0;
- ItemList[1].Size = 0;
- ItemList[1].Code = 0;
- if (!(i = SYS$GETSYI(0, 0, 0, ItemList, 0, 0, 0) & 1)) {
- return (i);
- }
- /*
- * From Start Address until End Address, probe and
- * lockdown the pages
- */
- for (InAddr[0] = (unsigned long int)Addr_Start;
- InAddr[0] < (unsigned long int)Addr_End;
- InAddr[0] = InAddr[0] + Page_Size) {
-
- /*
- * Set up the input address range
- */
- InAddr[1] = InAddr[0] + Page_Size - 4;
- /*
- * Probe the page for 4 bytes
- */
- i = __PAL_PROBER((void *)InAddr[0], 4, 0);
- /*
- * Check for probe success
- */
- if (!(i & 1)) continue;
- /*
- * Lock the Page down
- */
- i = sys$lkwset(InAddr, 0, 0);
- if (!(i & 1)) {
- return(i);
- }
- }
- /*
- * Done, return success
- */
- return(1);
- }
-
- This should allow you to lock down any code you need.
-
- Patrick L. Mahan
-
- --- TGV Window Washer ------------------------------- Mahan@TGV.COM ---------
-
- Waking a person unnecessarily should not be considered - Lazarus Long
- a capital crime. For a first offense, that is From the Notebooks of
-