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
;
150 struct datatype
* testtype
;
151 unsigned short int * wdump
;
153 DBG_FIX_ADDR_SEG( &addr
, (format
== 'i') ?
154 CS_reg(&DEBUG_context
) : DS_reg(&DEBUG_context
) );
157 * Dereference pointer to get actual memory address we need to be
158 * reading. We will use the same segment as what we have already,
159 * and hope that this is a sensible thing to do.
161 if( addr
.type
!= NULL
)
163 if( addr
.type
== DEBUG_TypeIntConst
)
166 * We know that we have the actual offset stored somewhere
167 * else in 32-bit space. Grab it, and we
172 addr
.off
= DEBUG_GetExprValue(&addr
, NULL
);
177 if (!DBG_CHECK_READ_PTR( &addr
, 1 )) return;
178 DEBUG_TypeDerefPointer(&addr
, &testtype
);
179 if( testtype
!= NULL
|| addr
.type
== DEBUG_TypeIntConst
)
181 addr
.off
= DEBUG_GetExprValue(&addr
, NULL
);
185 else if (!addr
.seg
&& !addr
.off
)
187 fprintf(stderr
,"Invalid expression\n");
191 if (format
!= 'i' && count
> 1)
193 DEBUG_PrintAddress( &addr
, dbg_mode
, FALSE
);
194 fprintf(stderr
,": ");
197 pnt
= DBG_ADDR_TO_LIN( &addr
);
202 if (count
== 1) count
= 256;
205 if (!DBG_CHECK_READ_PTR( &addr
, sizeof(char) )) return;
208 fputc( *pnt
++, stderr
);
210 fprintf(stderr
,"\n");
216 DEBUG_PrintAddress( &addr
, dbg_mode
, TRUE
);
217 fprintf(stderr
,": ");
218 if (!DBG_CHECK_READ_PTR( &addr
, 1 )) return;
219 DEBUG_Disasm( &addr
, TRUE
);
220 fprintf(stderr
,"\n");
224 dump
= (unsigned int *)pnt
;
225 for(i
=0; i
<count
; i
++)
227 if (!DBG_CHECK_READ_PTR( &addr
, sizeof(int) )) return;
228 fprintf(stderr
," %8.8x", *dump
++);
229 addr
.off
+= sizeof(int);
232 fprintf(stderr
,"\n");
233 DEBUG_PrintAddress( &addr
, dbg_mode
, FALSE
);
234 fprintf(stderr
,": ");
237 fprintf(stderr
,"\n");
241 dump
= (unsigned int *)pnt
;
242 for(i
=0; i
<count
; i
++)
244 if (!DBG_CHECK_READ_PTR( &addr
, sizeof(int) )) return;
245 fprintf(stderr
," %d", *dump
++);
246 addr
.off
+= sizeof(int);
249 fprintf(stderr
,"\n");
250 DEBUG_PrintAddress( &addr
, dbg_mode
, FALSE
);
251 fprintf(stderr
,": ");
254 fprintf(stderr
,"\n");
258 wdump
= (unsigned short *)pnt
;
259 for(i
=0; i
<count
; i
++)
261 if (!DBG_CHECK_READ_PTR( &addr
, sizeof(short) )) return;
262 fprintf(stderr
," %04x", *wdump
++);
263 addr
.off
+= sizeof(short);
266 fprintf(stderr
,"\n");
267 DEBUG_PrintAddress( &addr
, dbg_mode
, FALSE
);
268 fprintf(stderr
,": ");
271 fprintf(stderr
,"\n");
275 for(i
=0; i
<count
; i
++)
277 if (!DBG_CHECK_READ_PTR( &addr
, sizeof(char) )) return;
283 else fprintf(stderr
," %c", *pnt
++);
287 fprintf(stderr
,"\n");
288 DEBUG_PrintAddress( &addr
, dbg_mode
, FALSE
);
289 fprintf(stderr
,": ");
292 fprintf(stderr
,"\n");
296 for(i
=0; i
<count
; i
++)
298 if (!DBG_CHECK_READ_PTR( &addr
, sizeof(char) )) return;
299 fprintf(stderr
," %02x", (*pnt
++) & 0xff);
303 fprintf(stderr
,"\n");
304 DEBUG_PrintAddress( &addr
, dbg_mode
, FALSE
);
305 fprintf(stderr
,": ");
308 fprintf(stderr
,"\n");