2 * Debugger memory handling
4 * Copyright 1993 Eric Youngdale
5 * Copyright 1995 Alexandre Julliard
14 /************************************************************
16 * Check if linear pointer in [addr, addr+size[
20 ************************************************************/
23 BOOL32 DEBUG_checkmap_bad( const char *addr, size_t size, int rwflag)
26 char buf[80]; /* temporary line buffer */
27 char prot[5]; /* protection string */
32 The entries in /proc/self/maps are of the form:
33 08000000-08002000 r-xp 00000000 03:41 2361
34 08002000-08003000 rw-p 00001000 03:41 2361
35 08003000-08005000 rwxp 00000000 00:00 0
36 40000000-40005000 r-xp 00000000 03:41 67219
37 40005000-40006000 rw-p 00004000 03:41 67219
38 40006000-40007000 rw-p 00000000 00:00 0
40 start end perm ??? major:minor inode
42 Only permissions start and end are used here
45 if (!(fp = fopen("/proc/self/maps", "r")))
48 while (fgets( buf, 79, fp)) {
49 sscanf(buf, "%x-%x %3s", (int *) &start, (int *) &end, prot);
52 if (start <= addr && addr+size < end) {
54 ret = (prot[0] != 'r'); /* test for reading */
56 ret = (prot[1] != 'w'); /* test for writing */
64 /* FIXME: code needed for BSD et al. */
65 BOOL32 DEBUG_checkmap_bad(char *addr, size_t size, int rwflag)
72 /***********************************************************************
75 * Check if we are allowed to read memory at 'address'.
77 BOOL32 DEBUG_IsBadReadPtr( const DBG_ADDR *address, int size )
79 if (address->seg) /* segmented addr */
81 if (IsBadReadPtr16( (SEGPTR)MAKELONG( (WORD)address->off,
82 (WORD)address->seg ), size ))
85 return DEBUG_checkmap_bad( DBG_ADDR_TO_LIN(address), size, 1);
89 /***********************************************************************
92 * Check if we are allowed to write memory at 'address'.
94 BOOL32 DEBUG_IsBadWritePtr( const DBG_ADDR *address, int size )
96 if (address->seg) /* segmented addr */
98 /* Note: we use IsBadReadPtr here because we are */
99 /* always allowed to write to read-only segments */
100 if (IsBadReadPtr16( (SEGPTR)MAKELONG( (WORD)address->off,
101 (WORD)address->seg ), size ))
104 return DEBUG_checkmap_bad( DBG_ADDR_TO_LIN(address), size, 0);
108 /***********************************************************************
111 * Read a memory value.
113 int DEBUG_ReadMemory( const DBG_ADDR *address )
115 DBG_ADDR addr = *address;
117 DBG_FIX_ADDR_SEG( &addr, DS_reg(DEBUG_context) );
118 if (!DBG_CHECK_READ_PTR( &addr, sizeof(int) )) return 0;
119 return *(int *)DBG_ADDR_TO_LIN( &addr );
123 /***********************************************************************
126 * Store a value in memory.
128 void DEBUG_WriteMemory( const DBG_ADDR *address, int value )
130 DBG_ADDR addr = *address;
132 DBG_FIX_ADDR_SEG( &addr, DS_reg(DEBUG_context) );
133 if (!DBG_CHECK_WRITE_PTR( &addr, sizeof(int) )) return;
134 *(int *)DBG_ADDR_TO_LIN( &addr ) = value;
138 /***********************************************************************
139 * DEBUG_ExamineMemory
141 * Implementation of the 'x' command.
143 void DEBUG_ExamineMemory( const DBG_ADDR *address, int count, char format )
145 DBG_ADDR addr = *address;
148 unsigned short int * wdump;
151 DBG_FIX_ADDR_SEG( &addr, (format == 'i') ?
152 CS_reg(DEBUG_context) : DS_reg(DEBUG_context) );
154 if (format != 'i' && count > 1)
156 DEBUG_PrintAddress( &addr, dbg_mode );
157 fprintf(stderr,": ");
160 pnt = DBG_ADDR_TO_LIN( &addr );
165 if (count == 1) count = 256;
168 if (!DBG_CHECK_READ_PTR( &addr, sizeof(char) )) return;
171 fputc( *pnt++, stderr );
173 fprintf(stderr,"\n");
179 DEBUG_PrintAddress( &addr, dbg_mode );
180 fprintf(stderr,": ");
181 if (!DBG_CHECK_READ_PTR( &addr, 1 )) return;
182 DEBUG_Disasm( &addr );
183 fprintf(stderr,"\n");
187 dump = (unsigned int *)pnt;
188 for(i=0; i<count; i++)
190 if (!DBG_CHECK_READ_PTR( &addr, sizeof(int) )) return;
191 fprintf(stderr," %8.8x", *dump++);
192 addr.off += sizeof(int);
195 fprintf(stderr,"\n");
196 DEBUG_PrintAddress( &addr, dbg_mode );
197 fprintf(stderr,": ");
200 fprintf(stderr,"\n");
204 dump = (unsigned int *)pnt;
205 for(i=0; i<count; i++)
207 if (!DBG_CHECK_READ_PTR( &addr, sizeof(int) )) return;
208 fprintf(stderr," %d", *dump++);
209 addr.off += sizeof(int);
212 fprintf(stderr,"\n");
213 DEBUG_PrintAddress( &addr, dbg_mode );
214 fprintf(stderr,": ");
217 fprintf(stderr,"\n");
221 wdump = (unsigned short *)pnt;
222 for(i=0; i<count; i++)
224 if (!DBG_CHECK_READ_PTR( &addr, sizeof(short) )) return;
225 fprintf(stderr," %04x", *wdump++);
226 addr.off += sizeof(short);
229 fprintf(stderr,"\n");
230 DEBUG_PrintAddress( &addr, dbg_mode );
231 fprintf(stderr,": ");
234 fprintf(stderr,"\n");
238 for(i=0; i<count; i++)
240 if (!DBG_CHECK_READ_PTR( &addr, sizeof(char) )) return;
246 else fprintf(stderr," %c", *pnt++);
250 fprintf(stderr,"\n");
251 DEBUG_PrintAddress( &addr, dbg_mode );
252 fprintf(stderr,": ");
255 fprintf(stderr,"\n");
259 for(i=0; i<count; i++)
261 if (!DBG_CHECK_READ_PTR( &addr, sizeof(char) )) return;
262 fprintf(stderr," %02x", (*pnt++) & 0xff);
266 fprintf(stderr,"\n");
267 DEBUG_PrintAddress( &addr, dbg_mode );
268 fprintf(stderr,": ");
271 fprintf(stderr,"\n");