Article 151182 of comp.os.vms:
Chris Sharman <chris@ccagroup.co.uk> wrote on Tue, 16 Jul 1996 14:06:06 GMT:

> We've used Patch on VAX for a long time, simply to turn off the LNKDEBUG bit in
> the image header:
> 
<snip> patch code
>
> This means we can leave full debug info in the image (which gives us an
> overhead on disk, but no significant run-time overhead, I believe), we can
> RUN/DEBUG or ANAL/PROC if we want to, but normal use (either RUN, RUN process,
> MCR or foreign command invocation) doesn't get the debugger.
> 
> Any suggestions on how to do this on Alpha ? Can PATCH be VESTed ?
> RUN/NODEBUG isn't enough, since we do use the other ways of invoking images.

Attached is a C program Wayne Sewell of Tachyon Software posted to Info-VAX
a while back.

Attached below that is Hein van den Heuvel's DCL patch.

Ed James                       Manager, Computer & Communications Services
Lockheed Martin Laboratories   Internet james@mml.mmc.com
1450 South Rolling Road        Voice    410-204-2042
Baltimore MD, 21227-3898       Fax      410-204-2115

From: wayne@tachyon.com (Wayne Sewell)
Date: 21 Nov 95 15:58:14 CST

===============================================================================
#include <descrip.h>
#include <psldef.h>
#include <stdio.h>
#include <string.h>
#include <lib$routines.h>
#include <starlet.h>
#include <rms.h>

#ifdef __DECC	/* If this is DEC C */
#pragma extern_model save
#pragma extern_model globalvalue 
#ifdef __VAX	/* If this is the VAX */
extern int ihd$m_lnkdebug;
extern int ihd$l_lnkflags;
extern int ihd$c_length;
extern int sys$imgsta;
#else		/* Must be the AXP */
extern int eihd$m_lnkdebug;
extern int eihd$l_lnkflags;
extern int eihd$c_length;
extern int eiha$q_tfradr1;
#endif
#pragma extern_model restore
#else		/* Must be VAX C */
globalvalue ihd$m_lnkdebug;
globalvalue ihd$l_lnkflags;
globalvalue ihd$c_length;
globalvalue sys$imgsta;
#endif

#include <secdef.h>

#define program_region 0
#define control_region 1
#define global              SEC$M_GBL
#define writable_section    SEC$M_WRT
#define copy_on_reference   SEC$M_CRF
#define demand_zero         SEC$M_DZRO
#define permanent_section   SEC$M_PERM
#define no_overmap_of_pages SEC$M_NO_OVERMAP
#define expand_region       SEC$M_EXPREG
#define page_file_section   SEC$M_PAGFIL     
#define permanent_section   SEC$M_PERM

void do_the_mod(void *starting_addr)

{
int *intptr;
char *charptr;
int debug_mask;
int debug_is_on;

charptr = starting_addr;
#ifdef __VAX	/* If this is the VAX */
charptr += ihd$l_lnkflags;
debug_mask= ihd$m_lnkdebug;
#else		/* Must be the AXP */
charptr += eihd$l_lnkflags;
debug_mask= eihd$m_lnkdebug;
#endif
intptr = (int *) charptr;
printf("link flags = %x\n",*intptr);
debug_is_on = (*intptr & debug_mask);
if (debug_is_on) {
   printf("debug flag is set; turning off\n");
   *intptr &= ~debug_mask;
   }
else {
   printf("debug flag is off; turning on\n");
   *intptr |= debug_mask;
   }
printf("new link flags = %x\n",*intptr);
charptr = starting_addr;
#ifdef __VAX	/* If this is the VAX */
charptr += ihd$c_length;
intptr = (int *) charptr;
printf("vectors (before) = %08x, %08x, %08x\n",intptr[0],intptr[1],intptr[2]);
if (intptr[0] != sys$imgsta) {
   intptr[2] = intptr[1];
   intptr[1] = intptr[0];
   intptr[0] = sys$imgsta;
   }
printf("vectors (after) = %08x, %08x, %08x\n",intptr[0],intptr[1],intptr[2]);
#else		/* Must be the AXP */
charptr += eihd$c_length + eiha$q_tfradr1;
intptr = (int *) charptr;
printf("vectors (before) = %08x %08x,  %08x %08x,  %08x %08x\n",intptr[1],
		intptr[0],intptr[3],intptr[2],intptr[5],intptr[4]);
if ((intptr[0] != 0x0340) && (intptr[1] != 0x0ffffffff) ) {
   intptr[5] = intptr[3];
   intptr[4] = intptr[2];
   intptr[3] = intptr[1];
   intptr[2] = intptr[0];
   intptr[1] = 0x0ffffffff;
   intptr[0] = 0x0340;
   }
printf("vectors (after) = %08x %08x,  %08x %08x,  %08x %08x\n",intptr[1],
		intptr[0],intptr[3],intptr[2],intptr[5],intptr[4]);
#endif

}

int get_channel_from_file_name(char file_name[], int *chan)

{
/* Allocate the RMS user structures */
struct	FAB	the_fab; /* File Access Block */
struct	NAM	the_nam; /* name block */
int status;    	/* Check completion status of RMS operations */

/* Initialize RMS user structures for the file. */
the_fab  	   = cc$rms_fab;
the_fab.fab$l_fna = file_name;
the_fab.fab$b_fns = strlen (file_name);
the_fab.fab$b_fac = FAB$M_GET | FAB$M_PUT ;
the_fab.fab$l_nam = &the_nam;
the_fab.fab$l_fop = FAB$M_UFO ;

the_nam  = cc$rms_nam;

/* Open the file */
status =  sys$open (&the_fab,0,0);

if (!(status & 1)) return status;

*chan = the_fab.fab$l_stv;		/* channel number */
return status;
}

int create_and_map_global_section(char sect_file[],int access_mode,
			int relative_page_number,int page_count,
			int virtual_block_number,int protection,
			int page_fault_cluster,
			int flags, void *starting_addr, int length,
			void **actual_starting_addr, 
			int *actual_length)

{
int sts;
int inadr[2];
int retadr[2];
int file_channel_number;

lib$establish(lib$sig_to_ret);
sts = get_channel_from_file_name(sect_file,&file_channel_number);
if (!(sts & 1)) return sts;
inadr[0] = 0;

sts = sys$crmpsc(inadr,retadr,access_mode,flags,0,
		0,relative_page_number, file_channel_number,page_count, 
		virtual_block_number,protection,page_fault_cluster);

if (!(sts & 1)) return sts;

*actual_starting_addr = (void *) retadr[0];
*actual_length = retadr[1] - retadr[0] + 1;

return sts;
}  
  
int map_file_to_local_section(char file_name[],int start_block,
			int relative_page_number,int page_count,
			int virtual_block_number,int protection,
			int num_blocks, void *starting_addr,
			void **actual_starting_addr,
			int access_mode, int flags,
                        int *actual_number_of_blocks,int which_region)

{
int sts;
int actual_len;

flags = flags & (~(page_file_section));
sts = create_and_map_global_section(file_name,access_mode,
			relative_page_number,page_count,
			virtual_block_number,protection,0,
			flags, starting_addr, num_blocks * 512,
			actual_starting_addr,&actual_len);
*actual_number_of_blocks = actual_len / 512;
return sts;
}

int main (int argc, char **argv) 

{
char filename_string[2048];
int sts;
void *starting_addr;
int actual_number_of_blocks;
void *context;

strcpy(filename_string,argv[1]);
/* open the file for write access and get the channel */

sts = map_file_to_local_section(filename_string,0,0,1,0,0x0ffff,
			1, 0,&starting_addr,PSL$C_USER, 
			expand_region+writable_section,
                        &actual_number_of_blocks,program_region);

if (!(sts & 1)) return sts;
do_the_mod(starting_addr);
return sts;
}
===============================================================================

This program will toggle the flag every time you run it.

===============================================================================
Wayne Sewell, Tachyon Software Consulting  (214)553-9760   wayne@tachyon.com
http://www.tachyon.com/www/tachyon.html and wayne.html    pgp key via web/finger
Key fingerprint =  77 A5 C1 56 9C ED F1 8E  89 F9 27 3C 86 79 F7 1B 
===============================================================================

From: vandenheuvel@eps.enet.dec.com (Hein RMS van den Heuvel)
Date: 12 FEB 96 00:43:36

<snip> discussion of patching Mail.

Just flipping the debug bit in the file header for the image tends to 
work just fine for me. Shuffling transfer vectors is sometimes needed.
I wrote the following little (5 worker lines, 15 fluff) DCL procedure 
to patch the image. Check with $ANAL/IMAGE/INTERACTIVE

$if p1.eqs."" then $inquire p1 "image file name"
$open/read/write file 'f$parse(p1,".exe")
$offset = 80 !Alpha. We'll assume exe matches current system.
$if f$getsyi("arch_name").eqs."VAX" then offset = 32
$read file header
$old_state = "OFF"
$new_state = "OFF"
$old_bit = f$cvsi(offset*8,1,header)
$new_bit = 0
$if old_bit then old_state = "ON"
$if p2.eqs."" then p2 = .not.old_bit
$if p2 then new_bit = 1
$if p2 then new_state = "ON"
$header[offset*8,1] = new_bit
$write/update/symbol file header
$close file
$write sys$output "Debug bit was ", old_state, ". Now ", new_state, "."

Hope this helps,		+--------------------------------------+
Hein van den Heuvel, Digital.	| All opinions expressed are mine, and |
  "Makers of VMS and other	| may not reflect those of my employer |
   fine Operating Systems."	+--------------------------------------+


