2 * File source.c - source file handling for internal debugger.
4 * Copyright (C) 1997, Eric Youngdale.
11 #include <sys/types.h>
19 #define PATH_MAX _MAX_PATH
32 struct searchlist
* next
;
40 struct open_filelist
* next
;
43 unsigned int * linelist
;
46 static struct open_filelist
* ofiles
;
48 static struct searchlist
* listhead
;
49 static char DEBUG_current_sourcefile
[PATH_MAX
];
50 static int DEBUG_start_sourceline
= -1;
51 static int DEBUG_end_sourceline
= -1;
56 struct searchlist
* sl
;
58 fprintf(stderr
,"Search list :\n");
59 for(sl
= listhead
; sl
; sl
= sl
->next
)
61 fprintf(stderr
, "\t%s\n", sl
->path
);
63 fprintf(stderr
, "\n");
67 DEBUG_AddPath(const char * path
)
69 struct searchlist
* sl
;
71 sl
= (struct searchlist
*) xmalloc(sizeof(struct searchlist
));
78 sl
->path
= xstrdup(path
);
85 struct searchlist
* sl
;
86 struct searchlist
* nxt
;
88 for(sl
= listhead
; sl
; sl
= nxt
)
100 DEBUG_DisplaySource(char * sourcefile
, int start
, int end
)
106 struct open_filelist
* ol
;
110 struct searchlist
* sl
;
113 char tmppath
[PATH_MAX
];
116 * First see whether we have the file open already. If so, then
117 * use that, otherwise we have to try and open it.
119 for(ol
= ofiles
; ol
; ol
= ol
->next
)
121 if( strcmp(ol
->path
, sourcefile
) == 0 )
130 * Try again, stripping the path from the opened file.
132 for(ol
= ofiles
; ol
; ol
= ol
->next
)
134 pnt
= strrchr(ol
->path
, '/');
135 if( pnt
!= NULL
&& strcmp(pnt
+ 1, sourcefile
) == 0 )
146 * See if this is a DOS style name or not.
148 pnt
= strchr(sourcefile
, '\\' );
151 pnt
= strchr(sourcefile
, '/' );
159 * Crapola. We need to try and open the file.
161 status
= stat(sourcefile
, &statbuf
);
164 strcpy(tmppath
, sourcefile
);
168 for(sl
= listhead
; sl
; sl
= sl
->next
)
170 strcpy(tmppath
, sl
->path
);
171 if( tmppath
[strlen(tmppath
)-1] != '/' )
173 strcat(tmppath
, "/");
176 * Now append the base file name.
178 strcat(tmppath
, pnt
);
180 status
= stat(tmppath
, &statbuf
);
190 * Still couldn't find it. Ask user for path to add.
192 fprintf(stderr
,"Enter path to file %s: ", sourcefile
);
193 fgets(tmppath
, sizeof(tmppath
), stdin
);
195 if( tmppath
[strlen(tmppath
)-1] == '\n' )
197 tmppath
[strlen(tmppath
)-1] = '\0';
200 if( tmppath
[strlen(tmppath
)-1] != '/' )
202 strcat(tmppath
, "/");
205 * Now append the base file name.
207 strcat(tmppath
, pnt
);
209 status
= stat(tmppath
, &statbuf
);
213 * OK, I guess the user doesn't really want to see it
216 ol
= (struct open_filelist
*) xmalloc(sizeof(*ol
));
217 ol
->path
= xstrdup(sourcefile
);
218 ol
->real_path
= NULL
;
223 fprintf(stderr
,"Unable to open file %s\n", tmppath
);
229 * Create header for file.
231 ol
= (struct open_filelist
*) xmalloc(sizeof(*ol
));
232 ol
->path
= xstrdup(sourcefile
);
233 ol
->real_path
= xstrdup(tmppath
);
237 ol
->size
= statbuf
.st_size
;
241 * Now open and map the file.
243 fd
= open(tmppath
, O_RDONLY
);
249 addr
= mmap(0, statbuf
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
250 if( addr
== (char *) -1 )
256 * Now build up the line number mapping table.
260 while(pnt
< addr
+ ol
->size
)
269 ol
->linelist
= (unsigned int*) xmalloc(ol
->nlines
* sizeof(unsigned int) );
273 ol
->linelist
[nlines
++] = 0;
274 while(pnt
< addr
+ ol
->size
)
278 ol
->linelist
[nlines
++] = pnt
- addr
;
281 ol
->linelist
[nlines
++] = pnt
- addr
;
287 * We know what the file is, we just need to reopen it and remap it.
289 fd
= open(ol
->real_path
, O_RDONLY
);
295 addr
= mmap(0, ol
->size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
296 if( addr
== (char *) -1 )
303 * All we need to do is to display the source lines here.
306 for(i
=start
- 1; i
<= end
- 1; i
++)
308 if( i
< 0 || i
>= ol
->nlines
- 1)
314 memset(&buffer
, 0, sizeof(buffer
));
315 if( ol
->linelist
[i
+1] != ol
->linelist
[i
] )
317 memcpy(&buffer
, addr
+ ol
->linelist
[i
],
318 (ol
->linelist
[i
+1] - ol
->linelist
[i
]) - 1);
320 fprintf(stderr
,"%d\t%s\n", i
+ 1, buffer
);
323 munmap(addr
, ol
->size
);
331 DEBUG_List(struct list_id
* source1
, struct list_id
* source2
,
340 * We need to see what source file we need. Hopefully we only have
341 * one specified, otherwise we might as well punt.
345 && source1
->sourcefile
!= NULL
346 && source2
->sourcefile
!= NULL
347 && strcmp(source1
->sourcefile
, source2
->sourcefile
) != 0 )
349 fprintf(stderr
, "Ambiguous source file specification.\n");
354 if( source1
!= NULL
&& source1
->sourcefile
!= NULL
)
356 sourcefile
= source1
->sourcefile
;
359 if( sourcefile
== NULL
361 && source2
->sourcefile
!= NULL
)
363 sourcefile
= source2
->sourcefile
;
366 if( sourcefile
== NULL
)
368 sourcefile
= (char *) &DEBUG_current_sourcefile
;
371 if( sourcefile
== NULL
)
373 fprintf(stderr
, "No source file specified.\n");
378 * Now figure out the line number range to be listed.
383 if( source1
!= NULL
)
385 start
= source1
->line
;
388 if( source2
!= NULL
)
393 if( start
== -1 && end
== -1 )
397 end
= DEBUG_start_sourceline
;
402 start
= DEBUG_end_sourceline
;
406 else if( start
== -1 )
416 * Now call this function to do the dirty work.
418 rtn
= DEBUG_DisplaySource(sourcefile
, start
, end
);
420 if( sourcefile
!= (char *) &DEBUG_current_sourcefile
)
422 strcpy(DEBUG_current_sourcefile
, sourcefile
);
424 DEBUG_start_sourceline
= start
;
425 DEBUG_end_sourceline
= end
;
428 DBG_ADDR DEBUG_LastDisassemble
={NULL
,0,0};
431 _disassemble(DBG_ADDR
*addr
)
433 DEBUG_PrintAddress( addr
, dbg_mode
, TRUE
);
434 fprintf(stderr
,": ");
435 if (!DBG_CHECK_READ_PTR( addr
, 1 )) return 0;
436 DEBUG_Disasm( addr
, TRUE
);
437 fprintf(stderr
,"\n");
442 _disassemble_fixaddr(DBG_ADDR
*addr
) {
444 struct datatype
*testtype
;
446 DBG_FIX_ADDR_SEG(addr
,CS_reg(&DEBUG_context
));
447 if( addr
->type
!= NULL
)
449 if( addr
->type
== DEBUG_TypeIntConst
)
452 * We know that we have the actual offset stored somewhere
453 * else in 32-bit space. Grab it, and we
458 addr
->off
= DEBUG_GetExprValue(addr
, NULL
);
463 if (!DBG_CHECK_READ_PTR( addr
, 1 )) return;
464 DEBUG_TypeDerefPointer(addr
, &testtype
);
465 if( testtype
!= NULL
|| addr
->type
== DEBUG_TypeIntConst
)
466 addr
->off
= DEBUG_GetExprValue(addr
, NULL
);
469 else if (!addr
->seg
&& !addr
->off
)
471 fprintf(stderr
,"Invalid expression\n");
477 DEBUG_Disassemble(const DBG_ADDR
*xstart
,const DBG_ADDR
*xend
,int offset
)
486 _disassemble_fixaddr(&start
);
490 _disassemble_fixaddr(&end
);
492 if (!xstart
&& !xend
) {
493 last
= DEBUG_LastDisassemble
;
494 if (!last
.seg
&& !last
.off
) {
495 last
.seg
= (CS_reg(&DEBUG_context
)==WINE_CODE_SELECTOR
)?0:CS_reg(&DEBUG_context
);
496 last
.off
= EIP_reg(&DEBUG_context
);
498 for (i
=0;i
<offset
;i
++)
499 if (!_disassemble(&last
)) break;
500 memcpy(&DEBUG_LastDisassemble
,&last
,sizeof(last
));
505 for (i
=0;i
<offset
;i
++)
506 if (!_disassemble(&last
)) break;
507 memcpy(&DEBUG_LastDisassemble
,&last
,sizeof(last
));
510 while (last
.off
<= end
.off
)
511 if (!_disassemble(&last
)) break;
512 memcpy(&DEBUG_LastDisassemble
,&last
,sizeof(last
));
522 DEBUG_AddPath("../../de");
525 fscanf(stdin
,"%d %d", &i
, &j
);
526 DEBUG_DisplaySource("dumpexe.c", i
, j
);