2 * Debugger memory handling
4 * Copyright 1993 Eric Youngdale
5 * Copyright 1995 Alexandre Julliard
11 #include "wine/winbase16.h"
16 /************************************************************
18 * Check if linear pointer in [addr, addr+size[
22 ************************************************************/
24 #if defined(linux) || defined(__FreeBSD__) || defined(__OpenBSD__)
25 BOOL
DEBUG_checkmap_bad( const char *addr
, size_t size
, int rwflag
)
28 char buf
[80]; /* temporary line buffer */
29 char prot
[5]; /* protection string */
35 The entries in /proc/self/maps are of the form:
36 08000000-08002000 r-xp 00000000 03:41 2361
37 08002000-08003000 rw-p 00001000 03:41 2361
38 08003000-08005000 rwxp 00000000 00:00 0
39 40000000-40005000 r-xp 00000000 03:41 67219
40 40005000-40006000 rw-p 00004000 03:41 67219
41 40006000-40007000 rw-p 00000000 00:00 0
43 start end perm ??? major:minor inode
45 Only permissions start and end are used here
49 % cat /proc/curproc/map
50 start end resident private perm type
51 0x1000 0xe000 12 0 r-x COW vnode
52 0xe000 0x10000 2 2 rwx COW vnode
53 0x10000 0x27000 4 4 rwx default
54 0x800e000 0x800f000 1 1 rw- default
55 0xefbde000 0xefbfe000 1 1 rwx default
63 if (!(fp
= fopen("/proc/self/maps", "r")))
65 if (!(fp
= fopen("/proc/curproc/map", "r")))
69 while (fgets( buf
, 79, fp
)) {
71 sscanf(buf
, "%x-%x %3s", (int *) &start
, (int *) &end
, prot
);
73 sscanf(buf
, "%x %x %*d %*d %3s", (int *) &start
, (int *) &end
, prot
);
77 if (start
<= addr
&& addr
+size
< end
) {
79 ret
= (prot
[0] != 'r'); /* test for reading */
81 ret
= (prot
[1] != 'w'); /* test for writing */
88 #else /* linux || FreeBSD */
89 /* FIXME: code needed for BSD et al. */
90 BOOL
DEBUG_checkmap_bad(char *addr
, size_t size
, int rwflag
)
94 #endif /* linux || FreeBSD */
97 /***********************************************************************
100 * Check if we are allowed to read memory at 'address'.
102 BOOL
DEBUG_IsBadReadPtr( const DBG_ADDR
*address
, int size
)
104 if (!IS_SELECTOR_V86(address
->seg
))
105 if (address
->seg
) /* segmented addr */
107 if (IsBadReadPtr16( (SEGPTR
)MAKELONG( (WORD
)address
->off
,
108 (WORD
)address
->seg
), size
))
111 return DEBUG_checkmap_bad( DBG_ADDR_TO_LIN(address
), size
, 1);
115 /***********************************************************************
116 * DEBUG_IsBadWritePtr
118 * Check if we are allowed to write memory at 'address'.
120 BOOL
DEBUG_IsBadWritePtr( const DBG_ADDR
*address
, int size
)
122 if (!IS_SELECTOR_V86(address
->seg
))
123 if (address
->seg
) /* segmented addr */
125 /* Note: we use IsBadReadPtr here because we are */
126 /* always allowed to write to read-only segments */
127 if (IsBadReadPtr16( (SEGPTR
)MAKELONG( (WORD
)address
->off
,
128 (WORD
)address
->seg
), size
))
131 return DEBUG_checkmap_bad( DBG_ADDR_TO_LIN(address
), size
, 0);
135 /***********************************************************************
138 * Read a memory value.
140 int DEBUG_ReadMemory( const DBG_ADDR
*address
)
142 DBG_ADDR addr
= *address
;
144 DBG_FIX_ADDR_SEG( &addr
, DS_reg(&DEBUG_context
) );
145 if (!DBG_CHECK_READ_PTR( &addr
, sizeof(int) )) return 0;
146 return *(int *)DBG_ADDR_TO_LIN( &addr
);
150 /***********************************************************************
153 * Store a value in memory.
155 void DEBUG_WriteMemory( const DBG_ADDR
*address
, int value
)
157 DBG_ADDR addr
= *address
;
159 DBG_FIX_ADDR_SEG( &addr
, DS_reg(&DEBUG_context
) );
160 if (!DBG_CHECK_WRITE_PTR( &addr
, sizeof(int) )) return;
161 *(int *)DBG_ADDR_TO_LIN( &addr
) = value
;
165 /***********************************************************************
166 * DEBUG_ExamineMemory
168 * Implementation of the 'x' command.
170 void DEBUG_ExamineMemory( const DBG_ADDR
*address
, int count
, char format
)
172 DBG_ADDR addr
= * address
;
177 struct datatype
* testtype
;
178 unsigned short int * wdump
;
180 DBG_FIX_ADDR_SEG( &addr
, (format
== 'i') ?
181 CS_reg(&DEBUG_context
) : DS_reg(&DEBUG_context
) );
184 * Dereference pointer to get actual memory address we need to be
185 * reading. We will use the same segment as what we have already,
186 * and hope that this is a sensible thing to do.
188 if( addr
.type
!= NULL
)
190 if( addr
.type
== DEBUG_TypeIntConst
)
193 * We know that we have the actual offset stored somewhere
194 * else in 32-bit space. Grab it, and we
199 addr
.off
= DEBUG_GetExprValue(&addr
, NULL
);
204 if (!DBG_CHECK_READ_PTR( &addr
, 1 )) return;
205 DEBUG_TypeDerefPointer(&addr
, &testtype
);
206 if( testtype
!= NULL
|| addr
.type
== DEBUG_TypeIntConst
)
208 addr
.off
= DEBUG_GetExprValue(&addr
, NULL
);
212 else if (!addr
.seg
&& !addr
.off
)
214 fprintf(stderr
,"Invalid expression\n");
218 if (format
!= 'i' && count
> 1)
220 DEBUG_PrintAddress( &addr
, dbg_mode
, FALSE
);
221 fprintf(stderr
,": ");
224 pnt
= DBG_ADDR_TO_LIN( &addr
);
229 WCHAR
*ptr
= (WCHAR
*)pnt
;
230 if (count
== 1) count
= 256;
233 if (!DBG_CHECK_READ_PTR( &addr
, sizeof(WCHAR
) )) return;
236 fputc( (char)*ptr
++, stderr
);
238 fprintf(stderr
,"\n");
242 if (count
== 1) count
= 256;
245 if (!DBG_CHECK_READ_PTR( &addr
, sizeof(char) )) return;
248 fputc( *pnt
++, stderr
);
250 fprintf(stderr
,"\n");
256 DEBUG_PrintAddress( &addr
, dbg_mode
, TRUE
);
257 fprintf(stderr
,": ");
258 if (!DBG_CHECK_READ_PTR( &addr
, 1 )) return;
259 DEBUG_Disasm( &addr
, TRUE
);
260 fprintf(stderr
,"\n");
264 dump
= (unsigned int *)pnt
;
265 for(i
=0; i
<count
; i
++)
267 if (!DBG_CHECK_READ_PTR( &addr
, sizeof(int) )) return;
268 fprintf(stderr
," %8.8x", *dump
++);
269 addr
.off
+= sizeof(int);
272 fprintf(stderr
,"\n");
273 DEBUG_PrintAddress( &addr
, dbg_mode
, FALSE
);
274 fprintf(stderr
,": ");
277 fprintf(stderr
,"\n");
281 dump
= (unsigned int *)pnt
;
282 for(i
=0; i
<count
; i
++)
284 if (!DBG_CHECK_READ_PTR( &addr
, sizeof(int) )) return;
285 fprintf(stderr
," %d", *dump
++);
286 addr
.off
+= sizeof(int);
289 fprintf(stderr
,"\n");
290 DEBUG_PrintAddress( &addr
, dbg_mode
, FALSE
);
291 fprintf(stderr
,": ");
294 fprintf(stderr
,"\n");
298 wdump
= (unsigned short *)pnt
;
299 for(i
=0; i
<count
; i
++)
301 if (!DBG_CHECK_READ_PTR( &addr
, sizeof(short) )) return;
302 fprintf(stderr
," %04x", *wdump
++);
303 addr
.off
+= sizeof(short);
306 fprintf(stderr
,"\n");
307 DEBUG_PrintAddress( &addr
, dbg_mode
, FALSE
);
308 fprintf(stderr
,": ");
311 fprintf(stderr
,"\n");
315 for(i
=0; i
<count
; i
++)
317 if (!DBG_CHECK_READ_PTR( &addr
, sizeof(char) )) return;
323 else fprintf(stderr
," %c", *pnt
++);
327 fprintf(stderr
,"\n");
328 DEBUG_PrintAddress( &addr
, dbg_mode
, FALSE
);
329 fprintf(stderr
,": ");
332 fprintf(stderr
,"\n");
336 for(i
=0; i
<count
; i
++)
338 if (!DBG_CHECK_READ_PTR( &addr
, sizeof(char) )) return;
339 fprintf(stderr
," %02x", (*pnt
++) & 0xff);
343 fprintf(stderr
,"\n");
344 DEBUG_PrintAddress( &addr
, dbg_mode
, FALSE
);
345 fprintf(stderr
,": ");
348 fprintf(stderr
,"\n");