- Forward ordinals 40, 41, 143, 362 to appropriate routines.
[wine] / debugger / stabs.c
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2
3 /*
4  * File stabs.c - read stabs information from the wine executable itself.
5  *
6  * Copyright (C) 1996, Eric Youngdale.
7  *               1999, 2000 Eric Pouech
8  */
9
10 #include "config.h"
11
12 #include <sys/types.h>
13 #include <fcntl.h>
14 #include <sys/stat.h>
15 #ifdef HAVE_SYS_MMAN_H
16 #include <sys/mman.h>
17 #endif
18 #include <limits.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <unistd.h>
22 #ifndef PATH_MAX
23 #define PATH_MAX _MAX_PATH
24 #endif
25
26 #include "debugger.h"
27
28 #if defined(__svr4__) || defined(__sun)
29 #define __ELF__
30 #endif
31
32 #ifdef __ELF__
33 #ifdef HAVE_ELF_H
34 # include <elf.h>
35 #endif
36 #ifdef HAVE_LINK_H
37 # include <link.h>
38 #endif
39 #ifdef HAVE_SYS_LINK_H
40 # include <sys/link.h>
41 #endif
42 #endif
43
44 #ifndef N_UNDF
45 #define N_UNDF          0x00
46 #endif
47
48 #ifndef STN_UNDEF
49 # define STN_UNDEF      0
50 #endif
51
52 #define N_GSYM          0x20
53 #define N_FUN           0x24
54 #define N_STSYM         0x26
55 #define N_LCSYM         0x28
56 #define N_MAIN          0x2a
57 #define N_ROSYM         0x2c
58 #define N_OPT           0x3c
59 #define N_RSYM          0x40
60 #define N_SLINE         0x44
61 #define N_SO            0x64
62 #define N_LSYM          0x80
63 #define N_BINCL         0x82
64 #define N_SOL           0x84
65 #define N_PSYM          0xa0
66 #define N_EINCL         0xa2
67 #define N_LBRAC         0xc0
68 #define N_EXCL          0xc2
69 #define N_RBRAC         0xe0
70
71 typedef struct tagELF_DBG_INFO {
72     unsigned long       elf_addr;
73 } ELF_DBG_INFO;
74
75 struct stab_nlist {
76   union {
77     char *n_name;
78     struct stab_nlist *n_next;
79     long n_strx;
80   } n_un;
81   unsigned char n_type;
82   char n_other;
83   short n_desc;
84   unsigned long n_value;
85 };
86
87 static void stab_strcpy(char * dest, int sz, const char * source)
88 {
89   /*
90    * A strcpy routine that stops when we hit the ':' character.
91    * Faster than copying the whole thing, and then nuking the
92    * ':'.
93    */
94   while(*source != '\0' && *source != ':' && sz-- > 0)
95       *dest++ = *source++;
96   *dest = '\0';
97   assert(sz > 0);
98 }
99
100 typedef struct {
101    char*                name;
102    unsigned long        value;
103    int                  idx;
104    struct datatype**    vector;
105    int                  nrofentries;
106 } include_def;
107
108 #define MAX_INCLUDES    512
109
110 static  include_def*    include_defs = NULL;
111 static  int             num_include_def = 0;
112 static  int             num_alloc_include_def = 0;
113 static  int             cu_include_stack[MAX_INCLUDES];
114 static  int             cu_include_stk_idx = 0;
115 static  struct datatype**       cu_vector = NULL;
116 static  int             cu_nrofentries = 0;
117
118 static 
119 int     
120 DEBUG_CreateInclude(const char* file, unsigned long val)
121 {
122   if (num_include_def == num_alloc_include_def) 
123     {
124       num_alloc_include_def += 256;
125       include_defs = DBG_realloc(include_defs, sizeof(include_defs[0])*num_alloc_include_def);
126       memset(include_defs+num_include_def, 0, sizeof(include_defs[0])*256);
127     }
128   include_defs[num_include_def].name = DBG_strdup(file);
129   include_defs[num_include_def].value = val;
130   include_defs[num_include_def].vector = NULL;
131   include_defs[num_include_def].nrofentries = 0;
132   
133   return num_include_def++;
134 }
135
136 static 
137 int     
138 DEBUG_FindInclude(const char* file, unsigned long val)
139 {
140   int           i;
141   
142   for (i = 0; i < num_include_def; i++) 
143     {
144       if (val == include_defs[i].value && 
145           strcmp(file, include_defs[i].name) == 0)
146         return i;
147     }
148   return -1;
149 }
150
151 static 
152 int
153 DEBUG_AddInclude(int idx)
154 {
155   ++cu_include_stk_idx;
156   
157   /* is this happen, just bump MAX_INCLUDES */
158   /* we could also handle this as another dynarray */
159   assert(cu_include_stk_idx < MAX_INCLUDES);
160   
161   cu_include_stack[cu_include_stk_idx] = idx;
162   return cu_include_stk_idx;
163 }
164
165 static
166 void
167 DEBUG_ResetIncludes(void)
168 {
169   /*
170    * The datatypes that we would need to use are reset when
171    * we start a new file. (at least the ones in filenr == 0
172    */
173   cu_include_stk_idx = 0;/* keep 0 as index for the .c file itself */
174   memset(cu_vector, 0, sizeof(cu_vector[0]) * cu_nrofentries);
175 }
176
177 static
178 void
179 DEBUG_FreeIncludes(void)
180 {
181   int   i;
182   
183   DEBUG_ResetIncludes();
184   
185   for (i = 0; i < num_include_def; i++) 
186     {
187       DBG_free(include_defs[i].name);
188       DBG_free(include_defs[i].vector);
189     }
190   DBG_free(include_defs);
191   include_defs = NULL;
192   num_include_def = 0;
193   num_alloc_include_def = 0;
194   DBG_free(cu_vector);
195   cu_vector = NULL;
196   cu_nrofentries = 0;
197 }
198
199 static
200 struct datatype**
201 DEBUG_FileSubNr2StabEnum(int filenr, int subnr) 
202 {
203   struct datatype** ret;
204   
205   /* DEBUG_Printf(DBG_CHN_MESG, "creating type id for (%d,%d)\n", filenr, subnr); */
206   
207   /* FIXME: I could perhaps create a dummy include_def for each compilation
208    * unit which would allow not to handle those two cases separately
209    */
210   if (filenr == 0) 
211     {
212       if (cu_nrofentries <= subnr) 
213         {
214           cu_vector = DBG_realloc(cu_vector, sizeof(cu_vector[0])*(subnr+1));
215           memset(cu_vector+cu_nrofentries, 0, sizeof(cu_vector[0])*(subnr+1-cu_nrofentries));
216           cu_nrofentries = subnr + 1;
217         }
218       ret = &cu_vector[subnr];
219     }
220   else
221     {
222       include_def*      idef;
223       
224       assert(filenr <= cu_include_stk_idx);
225       
226       idef = &include_defs[cu_include_stack[filenr]];
227       
228       if (idef->nrofentries <= subnr)
229         {
230           idef->vector = DBG_realloc(idef->vector, sizeof(idef->vector[0])*(subnr+1));
231           memset(idef->vector + idef->nrofentries, 0, sizeof(idef->vector[0])*(subnr+1-idef->nrofentries));
232           idef->nrofentries = subnr + 1;
233         }
234       ret = &idef->vector[subnr];
235     }
236   /* DEBUG_Printf(DBG_CHN_MESG,"(%d,%d) is %d\n",filenr,subnr,ret); */
237   return ret;
238 }
239
240 static 
241 struct datatype**
242 DEBUG_ReadTypeEnum(char **x) {
243     int filenr,subnr;
244
245     if (**x=='(') {
246         (*x)++;                                 /* '(' */
247         filenr=strtol(*x,x,10);                 /* <int> */
248         (*x)++;                                 /* ',' */
249         subnr=strtol(*x,x,10);                  /* <int> */
250         (*x)++;                                 /* ')' */
251     } else {
252         filenr = 0;
253         subnr = strtol(*x,x,10);                /* <int> */
254     }
255     return DEBUG_FileSubNr2StabEnum(filenr,subnr);
256 }
257
258 struct ParseTypedefData {
259     char*               ptr;
260     char                buf[1024];
261     int                 idx;
262 };
263
264 static int DEBUG_PTS_ReadTypedef(struct ParseTypedefData* ptd, const char* typename,
265                                  struct datatype** dt);
266
267 static int DEBUG_PTS_ReadID(struct ParseTypedefData* ptd)
268 {
269     char*       first = ptd->ptr;
270     unsigned int        len;
271
272     if ((ptd->ptr = strchr(ptd->ptr, ':')) == NULL) return -1;
273     len = ptd->ptr - first;
274     if (len >= sizeof(ptd->buf) - ptd->idx) return -1;
275     memcpy(ptd->buf + ptd->idx, first, len);
276     ptd->buf[ptd->idx + len] = '\0';
277     ptd->idx += len + 1;
278     ptd->ptr++; /* ':' */
279     return 0;
280 }
281
282 static int DEBUG_PTS_ReadNum(struct ParseTypedefData* ptd, int* v)
283 {
284     char*       last;
285
286     *v = strtol(ptd->ptr, &last, 10);
287     if (last == ptd->ptr) return -1;
288     ptd->ptr = last;
289     return 0;
290 }
291
292 static int DEBUG_PTS_ReadTypeReference(struct ParseTypedefData* ptd, 
293                                        int* filenr, int* subnr)
294 {
295     if (*ptd->ptr == '(') {
296         /* '(' <int> ',' <int> ')' */
297         ptd->ptr++;
298         if (DEBUG_PTS_ReadNum(ptd, filenr) == -1) return -1;
299         if (*ptd->ptr++ != ',') return -1;
300         if (DEBUG_PTS_ReadNum(ptd, subnr) == -1) return -1;
301         if (*ptd->ptr++ != ')') return -1;
302     } else {
303         *filenr = 0;
304         if (DEBUG_PTS_ReadNum(ptd, subnr) == -1) return -1;
305     }
306     return 0;
307 }
308
309 static int DEBUG_PTS_ReadRange(struct ParseTypedefData* ptd, struct datatype** dt, 
310                                int* lo, int* hi)
311 {
312     /* type ';' <int> ';' <int> ';' */
313     if (DEBUG_PTS_ReadTypedef(ptd, NULL, dt) == -1) return -1;
314     if (*ptd->ptr++ != ';') return -1;  /* ';' */
315     if (DEBUG_PTS_ReadNum(ptd, lo) == -1) return -1;
316     if (*ptd->ptr++ != ';') return -1;  /* ';' */
317     if (DEBUG_PTS_ReadNum(ptd, hi) == -1) return -1;
318     if (*ptd->ptr++ != ';') return -1;  /* ';' */
319     return 0;
320 }
321
322 static inline int DEBUG_PTS_ReadAggregate(struct ParseTypedefData* ptd, struct datatype* sdt)
323 {
324     int                 sz, ofs;
325     char*               last;
326     struct datatype*    adt;
327     int                 idx;
328     int                 doadd;
329
330     sz = strtol(ptd->ptr, &last, 10);
331     if (last == ptd->ptr) return -1;
332     ptd->ptr = last;
333
334     doadd = DEBUG_SetStructSize(sdt, sz);
335     /* if the structure has already been filled, just redo the parsing
336      * but don't store results into the struct
337      * FIXME: there's a quite ugly memory leak in there...
338      */
339           
340     /* Now parse the individual elements of the structure/union. */
341     while (*ptd->ptr != ';') {
342         /* agg_name : type ',' <int:offset> ',' <int:size> */
343         idx = ptd->idx;
344         if (DEBUG_PTS_ReadID(ptd) == -1) return -1;
345
346         if (DEBUG_PTS_ReadTypedef(ptd, NULL, &adt) == -1) return -1;
347         if (!adt) return -1;
348
349         if (*ptd->ptr++ != ',') return -1;
350         if (DEBUG_PTS_ReadNum(ptd, &ofs) == -1) return -1;
351         if (*ptd->ptr++ != ',') return -1;
352         if (DEBUG_PTS_ReadNum(ptd, &sz) == -1) return -1;
353         if (*ptd->ptr++ != ';') return -1;
354
355         if (doadd) DEBUG_AddStructElement(sdt, ptd->buf + idx, adt, ofs, sz);
356         ptd->idx = idx;
357     }
358     ptd->ptr++; /* ';' */
359     return 0;
360 }
361
362 static inline int DEBUG_PTS_ReadEnum(struct ParseTypedefData* ptd, struct datatype* edt)
363 {
364     int                 ofs;
365     int                 idx;
366
367     while (*ptd->ptr != ';') {
368         idx = ptd->idx;
369         if (DEBUG_PTS_ReadID(ptd) == -1) return -1;
370         if (DEBUG_PTS_ReadNum(ptd, &ofs) == -1) return -1;
371         if (*ptd->ptr++ != ',') return -1;
372         DEBUG_AddStructElement(edt, ptd->buf + idx, NULL, ofs, 0);
373         ptd->idx = idx;
374     }
375     ptd->ptr++;
376     return 0;
377 }
378
379 static inline int DEBUG_PTS_ReadArray(struct ParseTypedefData* ptd, struct datatype* adt)
380 {
381     int                 lo, hi;
382     struct datatype*    rdt;
383
384     /* ar<typeinfo_nodef>;<int>;<int>;<typeinfo> */
385           
386     if (*ptd->ptr++ != 'r') return -1;
387     /* FIXME: range type is lost, always assume int */
388     if (DEBUG_PTS_ReadRange(ptd, &rdt, &lo, &hi) == -1) return -1;
389     if (DEBUG_PTS_ReadTypedef(ptd, NULL, &rdt) == -1) return -1;
390
391     DEBUG_SetArrayParams(adt, lo, hi, rdt);
392     return 0;
393 }
394
395 static int DEBUG_PTS_ReadTypedef(struct ParseTypedefData* ptd, const char* typename,
396                                  struct datatype** ret_dt)
397 {
398     int                 idx, lo, hi, sz = -1;
399     struct datatype*    new_dt = NULL;  /* newly created data type */
400     struct datatype*    ref_dt;         /* referenced data type (pointer...) */
401     struct datatype*    dt1;            /* intermediate data type (scope is limited) */
402     struct datatype*    dt2;            /* intermediate data type: t1=t2=new_dt */
403     int                 filenr1, subnr1;
404     int                 filenr2 = 0, subnr2 = 0;
405
406     /* things are a bit complicated because of the way the typedefs are stored inside
407      * the file (we cannot keep the struct datatype** around, because address can
408      * change when realloc is done, so we must call over and over
409      * DEBUG_FileSubNr2StabEnum to keep the correct values around
410      * (however, keeping struct datatype* is valid
411      */
412     if (DEBUG_PTS_ReadTypeReference(ptd, &filenr1, &subnr1) == -1) return -1;
413
414     while (*ptd->ptr == '=') {
415         ptd->ptr++;
416         if (new_dt) {
417             DEBUG_Printf(DBG_CHN_MESG, "Bad recursion (1) in typedef\n");
418             return -1;
419         }
420         /* first handle attribute if any */
421         switch (*ptd->ptr) {
422         case '@':
423             if (*++ptd->ptr == 's') {
424                 ptd->ptr++;
425                 if (DEBUG_PTS_ReadNum(ptd, &sz) == -1) {
426                     DEBUG_Printf(DBG_CHN_MESG, "Not an attribute... NIY\n");
427                     ptd->ptr -= 2;
428                     return -1;
429                 }
430                 if (*ptd->ptr++ != ';') return -1;
431             }
432             break;
433         }
434         /* then the real definitions */
435         switch (*ptd->ptr++) {
436         case '*':
437             new_dt = DEBUG_NewDataType(DT_POINTER, NULL);
438             if (DEBUG_PTS_ReadTypedef(ptd, NULL, &ref_dt) == -1) return -1;
439             DEBUG_SetPointerType(new_dt, ref_dt);
440             break;
441         case '(':
442             ptd->ptr--;
443             /* doit a two level by hand, otherwise we'd need a stack */
444             if (filenr2 || subnr2) {
445                 DEBUG_Printf(DBG_CHN_MESG, "Bad recursion (2) in typedef\n");
446                 return -1;
447             }
448             if (DEBUG_PTS_ReadTypeReference(ptd, &filenr2, &subnr2) == -1) return -1;
449
450             dt1 = *DEBUG_FileSubNr2StabEnum(filenr1, subnr1);
451             dt2 = *DEBUG_FileSubNr2StabEnum(filenr2, subnr2);
452
453             if (!dt1 && dt2) {
454                 new_dt = dt2;
455                 filenr2 = subnr2 = 0;
456             } else if (!dt1 && !dt2)  {
457                 new_dt = NULL;
458             } else {
459                 DEBUG_Printf(DBG_CHN_MESG, "Unknown condition %08lx %08lx (%s)\n", 
460                              (unsigned long)dt1, (unsigned long)dt2, ptd->ptr);
461                 return -1;
462             }
463             break;
464         case 'a':
465             new_dt = DEBUG_NewDataType(DT_ARRAY, NULL);
466             if (DEBUG_PTS_ReadArray(ptd, new_dt) == -1) return -1;
467             break;
468         case 'r':
469             new_dt = DEBUG_NewDataType(DT_BASIC, typename);
470             assert(!*DEBUG_FileSubNr2StabEnum(filenr1, subnr1));
471             *DEBUG_FileSubNr2StabEnum(filenr1, subnr1) = new_dt;
472             if (DEBUG_PTS_ReadRange(ptd, &ref_dt, &lo, &hi) == -1) return -1;
473             /* should perhaps do more here... */
474             break;
475         case 'f':
476             new_dt = DEBUG_NewDataType(DT_FUNC, NULL);
477             if (DEBUG_PTS_ReadTypedef(ptd, NULL, &ref_dt) == -1) return -1;
478             DEBUG_SetPointerType(new_dt, ref_dt);
479             break;
480         case 'e':
481             new_dt = DEBUG_NewDataType(DT_ENUM, NULL);
482             if (DEBUG_PTS_ReadEnum(ptd, new_dt) == -1) return -1;
483             break;
484         case 's':
485         case 'u':
486             /* dt1 can have been already defined in a forward definition */
487             dt1 = *DEBUG_FileSubNr2StabEnum(filenr1, subnr1);
488             dt2 = DEBUG_TypeCast(DT_STRUCT, typename);
489             if (!dt1) {
490                 new_dt = DEBUG_NewDataType(DT_STRUCT, typename);
491                 /* we need to set it here, because a struct can hold a pointer 
492                  * to itself 
493                  */
494                 *DEBUG_FileSubNr2StabEnum(filenr1, subnr1) = new_dt;
495             } else {
496                 if (DEBUG_GetType(dt1) != DT_STRUCT) {
497                     DEBUG_Printf(DBG_CHN_MESG, 
498                                  "Forward declaration is not an aggregate\n");
499                     return -1;
500                 }
501
502                 /* should check typename is the same too */
503                 new_dt = dt1;
504             }
505             if (DEBUG_PTS_ReadAggregate(ptd, new_dt) == -1) return -1;
506             break;
507         case 'x':
508             switch (*ptd->ptr++) {
509             case 'e':                   lo = DT_ENUM;   break;
510             case 's':   case 'u':       lo = DT_STRUCT; break;
511             default: return -1;
512             }
513             
514             idx = ptd->idx;
515             if (DEBUG_PTS_ReadID(ptd) == -1) return -1;
516             new_dt = DEBUG_NewDataType(lo, ptd->buf + idx); 
517             ptd->idx = idx;
518             break;
519         case '-':
520             if (DEBUG_PTS_ReadNum(ptd, &lo) == -1) {
521                 DEBUG_Printf(DBG_CHN_MESG, "Should be a number (%s)...\n", ptd->ptr);
522                 return -1;
523             } else {
524                 enum debug_type_basic basic = DT_BASIC_LAST;
525                 switch (lo)
526                 {
527                 case  1: basic = DT_BASIC_INT; break;      
528                 case  2: basic = DT_BASIC_CHAR; break;
529                 case  3: basic = DT_BASIC_SHORTINT; break;
530                 case  4: basic = DT_BASIC_LONGINT; break;
531                 case  5: basic = DT_BASIC_UCHAR; break;
532                 case  6: basic = DT_BASIC_SCHAR; break;
533                 case  7: basic = DT_BASIC_USHORTINT; break;
534                 case  8: basic = DT_BASIC_UINT; break;
535 /*              case  9: basic = DT_BASIC_UINT";  */
536                 case 10: basic = DT_BASIC_ULONGINT; break;
537                 case 11: basic = DT_BASIC_VOID; break;
538                 case 12: basic = DT_BASIC_FLOAT; break;
539                 case 13: basic = DT_BASIC_DOUBLE; break;
540                 case 14: basic = DT_BASIC_LONGDOUBLE; break;
541 /*              case 15: basic = DT_BASIC_INT; break; */
542                 case 16:
543                     switch (sz) {
544                     case 32: basic = DT_BASIC_BOOL1; break;
545                     case 16: basic = DT_BASIC_BOOL2; break;
546                     case  8: basic = DT_BASIC_BOOL4; break;
547                     }
548                     break;
549 /*              case 17: basic = DT_BASIC_SHORT real; break; */
550 /*              case 18: basic = DT_BASIC_REAL; break; */
551                 case 25: basic = DT_BASIC_CMPLX_FLOAT; break;
552                 case 26: basic = DT_BASIC_CMPLX_DOUBLE; break;
553 /*              case 30: basic = DT_BASIC_wchar"; break; */
554                 case 31: basic = DT_BASIC_LONGLONGINT; break;
555                 case 32: basic = DT_BASIC_ULONGLONGINT; break;
556                 default:
557                     DEBUG_Printf(DBG_CHN_MESG, "Unsupported integral type (%d/%d)\n", lo, sz);
558                     return -1;
559                 }
560                 if (!(new_dt = DEBUG_GetBasicType(basic))) {
561                     DEBUG_Printf(DBG_CHN_MESG, "Basic type %d not found\n", basic);
562                     return -1;
563                 }
564                 if (*ptd->ptr++ != ';') return -1;
565             }
566             break;
567         default:
568             DEBUG_Printf(DBG_CHN_MESG, "Unknown type '%c'\n", ptd->ptr[-1]);
569             return -1;
570         }
571     }
572
573     if ((filenr2 || subnr2) && !*DEBUG_FileSubNr2StabEnum(filenr2, subnr2)) {
574         if (!new_dt) {
575             /* this should be a basic type, define it, or even void */
576             new_dt = DEBUG_NewDataType(DT_BASIC, typename);
577         }
578         *DEBUG_FileSubNr2StabEnum(filenr2, subnr2) = new_dt;
579     }
580
581     if (!new_dt) {
582         dt1 = *DEBUG_FileSubNr2StabEnum(filenr1, subnr1);
583         if (!dt1) {
584             DEBUG_Printf(DBG_CHN_MESG, "Nothing has been defined <%s>\n", ptd->ptr);
585             return -1;
586         }
587         *ret_dt = dt1;
588         return 0;
589     }
590
591     *DEBUG_FileSubNr2StabEnum(filenr1, subnr1) = *ret_dt = new_dt;
592
593 #if 0
594     if (typename) {
595         DEBUG_Printf(DBG_CHN_MESG, "Adding (%d,%d) %s => ", filenr1, subnr1, typename);
596         DEBUG_PrintTypeCast(new_dt);
597         DEBUG_Printf(DBG_CHN_MESG, "\n");
598     }
599 #endif
600
601     return 0;
602 }
603
604 static int DEBUG_ParseTypedefStab(char* ptr, const char* typename)
605 {
606     struct ParseTypedefData     ptd;
607     struct datatype*            dt;
608     int                         ret = -1;
609
610     /* check for already existing definition */
611     
612     ptd.idx = 0;
613     if ((ptd.ptr = strchr(ptr, ':'))) {
614         ptd.ptr++;
615         if (*ptd.ptr != '(') ptd.ptr++;
616         ret = DEBUG_PTS_ReadTypedef(&ptd, typename, &dt);
617     }
618
619     if (ret == -1 || *ptd.ptr) {
620         DEBUG_Printf(DBG_CHN_MESG, "failure on %s at %s\n", ptr, ptd.ptr);
621         return FALSE;
622     }
623
624     return TRUE;
625 }
626
627 static struct datatype *
628 DEBUG_ParseStabType(const char * stab)
629 {
630   char * c;
631
632   /*
633    * Look through the stab definition, and figure out what datatype
634    * this represents.  If we have something we know about, assign the
635    * type.
636    */
637   c = strchr(stab, ':');
638   if( c == NULL )
639       return NULL;
640
641   c++;
642   /*
643    * The next character says more about the type (i.e. data, function, etc)
644    * of symbol.  Skip it.
645    */
646   if (*c != '(')
647     c++;
648   /* 
649    * The next is either an integer or a (integer,integer).
650    * The DEBUG_ReadTypeEnum takes care that stab_types is large enough.
651    */
652   return *DEBUG_ReadTypeEnum(&c);
653 }
654
655 enum DbgInfoLoad DEBUG_ParseStabs(char * addr, unsigned int load_offset,
656                                   unsigned int staboff, int stablen, 
657                                   unsigned int strtaboff, int strtablen)
658 {
659   struct name_hash    * curr_func = NULL;
660   struct wine_locals  * curr_loc = NULL;
661   struct name_hash    * curr_sym = NULL;
662   char                  currpath[PATH_MAX];
663   int                   i;
664   int                   in_external_file = FALSE;
665   int                   last_nso = -1;
666   unsigned int          len;
667   DBG_VALUE             new_value;
668   int                   nstab;
669   char                * ptr;
670   char                * stabbuff;
671   unsigned int          stabbufflen;
672   struct stab_nlist   * stab_ptr;
673   char                * strs;
674   int                   strtabinc;
675   char                * subpath = NULL;
676   char                  symname[4096];
677
678   nstab = stablen / sizeof(struct stab_nlist);
679   stab_ptr = (struct stab_nlist *) (addr + staboff);
680   strs  = (char *) (addr + strtaboff);
681
682   memset(currpath, 0, sizeof(currpath));
683
684   /*
685    * Allocate a buffer into which we can build stab strings for cases
686    * where the stab is continued over multiple lines.
687    */
688   stabbufflen = 65536;
689   stabbuff = (char *) DBG_alloc(stabbufflen);
690
691   strtabinc = 0;
692   stabbuff[0] = '\0';
693   for(i=0; i < nstab; i++, stab_ptr++ )
694     {
695       ptr = strs + (unsigned int) stab_ptr->n_un.n_name;
696       if( ptr[strlen(ptr) - 1] == '\\' )
697         {
698           /*
699            * Indicates continuation.  Append this to the buffer, and go onto the
700            * next record.  Repeat the process until we find a stab without the
701            * '/' character, as this indicates we have the whole thing.
702            */
703           len = strlen(ptr);
704           if( strlen(stabbuff) + len > stabbufflen )
705             {
706               stabbufflen += 65536;
707               stabbuff = (char *) DBG_realloc(stabbuff, stabbufflen);
708             }
709           strncat(stabbuff, ptr, len - 1);
710           continue;
711         }
712       else if( stabbuff[0] != '\0' )
713         {
714           strcat( stabbuff, ptr);
715           ptr = stabbuff;
716         }
717
718       if( strchr(ptr, '=') != NULL )
719         {
720           /*
721            * The stabs aren't in writable memory, so copy it over so we are
722            * sure we can scribble on it.
723            */
724           if( ptr != stabbuff )
725             {
726               strcpy(stabbuff, ptr);
727               ptr = stabbuff;
728             }
729           stab_strcpy(symname, sizeof(symname), ptr);
730           if (!DEBUG_ParseTypedefStab(ptr, symname)) {
731             /* skip this definition */
732             stabbuff[0] = '\0';
733             continue;
734           }
735         }
736
737       switch(stab_ptr->n_type)
738         {
739         case N_GSYM:
740           /*
741            * These are useless with ELF.  They have no value, and you have to
742            * read the normal symbol table to get the address.  Thus we
743            * ignore them, and when we process the normal symbol table
744            * we should do the right thing.
745            *
746            * With a.out or mingw, they actually do make some amount of sense.
747            */
748           new_value.addr.seg = 0;
749           new_value.type = DEBUG_ParseStabType(ptr);
750           new_value.addr.off = load_offset + stab_ptr->n_value;
751           new_value.cookie = DV_TARGET;
752
753           stab_strcpy(symname, sizeof(symname), ptr);
754 #ifdef __ELF__
755           curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath,
756                                       SYM_WINE | SYM_DATA | SYM_INVALID );
757 #else
758           curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath,
759                                       SYM_WINE | SYM_DATA );
760 #endif
761           break;
762         case N_RBRAC:
763         case N_LBRAC:
764           /*
765            * We need to keep track of these so we get symbol scoping
766            * right for local variables.  For now, we just ignore them.
767            * The hooks are already there for dealing with this however,
768            * so all we need to do is to keep count of the nesting level,
769            * and find the RBRAC for each matching LBRAC.
770            */
771           break;
772         case N_LCSYM:
773         case N_STSYM:
774           /*
775            * These are static symbols and BSS symbols.
776            */
777           new_value.addr.seg = 0;
778           new_value.type = DEBUG_ParseStabType(ptr);
779           new_value.addr.off = load_offset + stab_ptr->n_value;
780           new_value.cookie = DV_TARGET;
781
782           stab_strcpy(symname, sizeof(symname), ptr);
783           curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath, 
784                                       SYM_WINE | SYM_DATA );
785           break;
786         case N_PSYM:
787           /*
788            * These are function parameters.
789            */
790           if( curr_func != NULL && !in_external_file )
791             {
792               stab_strcpy(symname, sizeof(symname), ptr);
793               curr_loc = DEBUG_AddLocal( curr_func, 0, 
794                                          stab_ptr->n_value, 0, 0, symname );
795               DEBUG_SetLocalSymbolType( curr_loc, DEBUG_ParseStabType(ptr) );
796             }
797           break;
798         case N_RSYM:
799           if( curr_func != NULL && !in_external_file )
800             {
801               stab_strcpy(symname, sizeof(symname), ptr);
802               curr_loc = DEBUG_AddLocal( curr_func, stab_ptr->n_value + 1, 
803                                          0, 0, 0, symname );
804               DEBUG_SetLocalSymbolType( curr_loc, DEBUG_ParseStabType(ptr) );
805             }
806           break;
807         case N_LSYM:
808           if( curr_func != NULL && !in_external_file )
809             {
810               stab_strcpy(symname, sizeof(symname), ptr);
811               curr_loc = DEBUG_AddLocal( curr_func, 0, 
812                                          stab_ptr->n_value, 0, 0, symname );
813               DEBUG_SetLocalSymbolType( curr_loc, DEBUG_ParseStabType(ptr) );
814             }
815           break;
816         case N_SLINE:
817           /*
818            * This is a line number.  These are always relative to the start
819            * of the function (N_FUN), and this makes the lookup easier.
820            */
821           if( curr_func != NULL && !in_external_file )
822             {
823 #ifdef __ELF__
824               DEBUG_AddLineNumber(curr_func, stab_ptr->n_desc, 
825                                   stab_ptr->n_value);
826 #else
827 #if 0
828               /*
829                * This isn't right.  The order of the stabs is different under
830                * a.out, and as a result we would end up attaching the line
831                * number to the wrong function.
832                */
833               DEBUG_AddLineNumber(curr_func, stab_ptr->n_desc, 
834                                   stab_ptr->n_value - curr_func->addr.off);
835 #endif
836 #endif
837             }
838           break;
839         case N_FUN:
840           /*
841            * First, clean up the previous function we were working on.
842            */
843           DEBUG_Normalize(curr_func);
844
845           /*
846            * For now, just declare the various functions.  Later
847            * on, we will add the line number information and the
848            * local symbols.
849            */
850           if( !in_external_file)
851             {
852               stab_strcpy(symname, sizeof(symname), ptr);
853               if (*symname)
854                 {
855                   new_value.addr.seg = 0;
856                   new_value.type = DEBUG_ParseStabType(ptr);
857                   new_value.addr.off = load_offset + stab_ptr->n_value;
858                   new_value.cookie = DV_TARGET;
859                   /*
860                    * Copy the string to a temp buffer so we
861                    * can kill everything after the ':'.  We do
862                    * it this way because otherwise we end up dirtying
863                    * all of the pages related to the stabs, and that
864                    * sucks up swap space like crazy.
865                    */
866 #ifdef __ELF__
867                   curr_func = DEBUG_AddSymbol( symname, &new_value, currpath,
868                                                SYM_WINE | SYM_FUNC | SYM_INVALID );
869 #else
870                   curr_func = DEBUG_AddSymbol( symname, &new_value, currpath,
871                                                SYM_WINE | SYM_FUNC );
872 #endif
873                 } 
874               else
875                 {
876                   /* some GCC seem to use a N_FUN "" to mark the end of a function */
877                   curr_func = NULL;
878                 }
879             }
880           else
881             {
882               /*
883                * Don't add line number information for this function
884                * any more.
885                */
886               curr_func = NULL;
887             }
888           break;
889         case N_SO:
890           /*
891            * This indicates a new source file.  Append the records
892            * together, to build the correct path name.
893            */
894 #ifndef __ELF__
895           /*
896            * With a.out, there is no NULL string N_SO entry at the end of
897            * the file.  Thus when we find non-consecutive entries,
898            * we consider that a new file is started.
899            */
900           if( last_nso < i-1 )
901             {
902               currpath[0] = '\0';
903               DEBUG_Normalize(curr_func);
904               curr_func = NULL;
905             }
906 #endif
907
908           if( *ptr == '\0' )
909             {
910               /*
911                * Nuke old path.
912                */
913               currpath[0] = '\0';
914               DEBUG_Normalize(curr_func);
915               curr_func = NULL;
916             }
917           else
918             {
919               if (*ptr != '/')
920                 strcat(currpath, ptr);
921               else
922                 strcpy(currpath, ptr);
923               subpath = ptr;
924               DEBUG_ResetIncludes();
925             }
926           last_nso = i;
927           break;
928         case N_SOL:
929           /*
930            * This indicates we are including stuff from an include file.
931            * If this is the main source, enable the debug stuff, otherwise
932            * ignore it.
933            */
934           in_external_file = !(subpath == NULL || strcmp(ptr, subpath) == 0);
935           break;
936         case N_UNDF:
937           strs += strtabinc;
938           strtabinc = stab_ptr->n_value;
939           DEBUG_Normalize(curr_func);
940           curr_func = NULL;
941           break;
942         case N_OPT:
943           /*
944            * Ignore this.  We don't care what it points to.
945            */
946           break;
947         case N_BINCL:
948            DEBUG_AddInclude(DEBUG_CreateInclude(ptr, stab_ptr->n_value));
949            break;
950         case N_EINCL:
951            break;
952         case N_EXCL:
953            DEBUG_AddInclude(DEBUG_FindInclude(ptr, stab_ptr->n_value));
954            break;
955         case N_MAIN:
956           /*
957            * Always ignore these.  GCC doesn't even generate them.
958            */
959           break;
960         default:
961           DEBUG_Printf(DBG_CHN_MESG, "Unknown stab type 0x%02x\n", stab_ptr->n_type);
962           break;
963         }
964
965       stabbuff[0] = '\0';
966
967 #if 0
968       DEBUG_Printf(DBG_CHN_MESG, "%d %x %s\n", stab_ptr->n_type, 
969                    (unsigned int) stab_ptr->n_value,
970                    strs + (unsigned int) stab_ptr->n_un.n_name);
971 #endif
972     }
973
974   DEBUG_FreeIncludes();
975
976   return DIL_LOADED;
977 }
978
979 #ifdef __ELF__
980
981 /*
982  * Walk through the entire symbol table and add any symbols we find there.
983  * This can be used in cases where we have stripped ELF shared libraries,
984  * or it can be used in cases where we have data symbols for which the address
985  * isn't encoded in the stabs.
986  *
987  * This is all really quite easy, since we don't have to worry about line
988  * numbers or local data variables.
989  */
990 static int DEBUG_ProcessElfSymtab(DBG_MODULE* module, char* addr, 
991                                   u_long load_addr, Elf32_Shdr* symtab, 
992                                   Elf32_Shdr* strtab)
993 {
994   char          * curfile = NULL;
995   struct name_hash * curr_sym = NULL;
996   int             flags;
997   int             i;
998   DBG_VALUE       new_value;
999   int             nsym;
1000   char          * strp;
1001   char          * symname;
1002   Elf32_Sym     * symp;
1003
1004   symp = (Elf32_Sym *) (addr + symtab->sh_offset);
1005   nsym = symtab->sh_size / sizeof(*symp);
1006   strp = (char *) (addr + strtab->sh_offset);
1007
1008   for(i=0; i < nsym; i++, symp++)
1009     {
1010       /*
1011        * Ignore certain types of entries which really aren't of that much
1012        * interest.
1013        */
1014       if( ELF32_ST_TYPE(symp->st_info) == STT_SECTION ||
1015           symp->st_shndx == STN_UNDEF )
1016         {
1017           continue;
1018         }
1019
1020       symname = strp + symp->st_name;
1021
1022       /*
1023        * Save the name of the current file, so we have a way of tracking
1024        * static functions/data.
1025        */
1026       if( ELF32_ST_TYPE(symp->st_info) == STT_FILE )
1027         {
1028           curfile = symname;
1029           continue;
1030         }
1031
1032       /*
1033        * See if we already have something for this symbol.
1034        * If so, ignore this entry, because it would have come from the
1035        * stabs or from a previous symbol.  If the value is different,
1036        * we will have to keep the darned thing, because there can be
1037        * multiple local symbols by the same name.
1038        */
1039       if(    (DEBUG_GetSymbolValue(symname, -1, &new_value, FALSE ) == TRUE)
1040           && (new_value.addr.off == (load_addr + symp->st_value)) )
1041           continue;
1042
1043       new_value.addr.seg = 0;
1044       new_value.type = NULL;
1045       new_value.addr.off = load_addr + symp->st_value;
1046       new_value.cookie = DV_TARGET;
1047       flags = SYM_WINE | ((ELF32_ST_TYPE(symp->st_info) == STT_FUNC) 
1048                           ? SYM_FUNC : SYM_DATA);
1049       if( ELF32_ST_BIND(symp->st_info) == STB_GLOBAL )
1050           curr_sym = DEBUG_AddSymbol( symname, &new_value, NULL, flags );
1051       else
1052           curr_sym = DEBUG_AddSymbol( symname, &new_value, curfile, flags );
1053
1054       /*
1055        * Record the size of the symbol.  This can come in handy in
1056        * some cases.  Not really used yet, however.
1057        */
1058       if( symp->st_size != 0 )
1059           DEBUG_SetSymbolSize(curr_sym, symp->st_size);
1060     }
1061
1062   return TRUE;
1063 }
1064
1065 /*
1066  * Loads the symbolic information from ELF module stored in 'filename'
1067  * the module has been loaded at 'load_offset' address, so symbols' address
1068  * relocation is performed
1069  * returns 
1070  *      -1 if the file cannot be found/opened
1071  *      0 if the file doesn't contain symbolic info (or this info cannot be 
1072  *      read or parsed)
1073  *      1 on success
1074  */
1075 enum DbgInfoLoad DEBUG_LoadElfStabs(DBG_MODULE* module)
1076 {
1077     enum DbgInfoLoad dil = DIL_ERROR;
1078     char*       addr = (char*)0xffffffff;
1079     int         fd = -1;
1080     struct stat statbuf;
1081     Elf32_Ehdr* ehptr;
1082     Elf32_Shdr* spnt;
1083     char*       shstrtab;
1084     int         i;
1085     int         stabsect;
1086     int         stabstrsect;
1087
1088     if (module->type != DMT_ELF || ! module->elf_info) {
1089         DEBUG_Printf(DBG_CHN_ERR, "Bad elf module '%s'\n", module->module_name);
1090         return DIL_ERROR;
1091     }
1092
1093     /* check that the file exists, and that the module hasn't been loaded yet */
1094     if (stat(module->module_name, &statbuf) == -1) goto leave;
1095     if (S_ISDIR(statbuf.st_mode)) goto leave;
1096
1097     /*
1098      * Now open the file, so that we can mmap() it.
1099      */
1100     if ((fd = open(module->module_name, O_RDONLY)) == -1) goto leave;
1101     
1102     dil = DIL_NOINFO;
1103     /*
1104      * Now mmap() the file.
1105      */
1106     addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
1107     if (addr == (char*)0xffffffff) goto leave;
1108     
1109     /*
1110      * Next, we need to find a few of the internal ELF headers within
1111      * this thing.  We need the main executable header, and the section
1112      * table.
1113      */
1114     ehptr = (Elf32_Ehdr*) addr;
1115     spnt = (Elf32_Shdr*) (addr + ehptr->e_shoff);
1116     shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);
1117     
1118     stabsect = stabstrsect = -1;
1119     
1120     for (i = 0; i < ehptr->e_shnum; i++) {
1121         if (strcmp(shstrtab + spnt[i].sh_name, ".stab") == 0)
1122             stabsect = i;
1123         
1124         if (strcmp(shstrtab + spnt[i].sh_name, ".stabstr") == 0)
1125             stabstrsect = i;
1126     }
1127     
1128     if (stabsect == -1 || stabstrsect == -1) {
1129         DEBUG_Printf(DBG_CHN_WARN, "no .stab section\n");
1130         goto leave;
1131     }
1132     
1133     /*
1134      * OK, now just parse all of the stabs.
1135      */
1136     if (DEBUG_ParseStabs(addr, 
1137                          module->elf_info->elf_addr, 
1138                          spnt[stabsect].sh_offset,
1139                          spnt[stabsect].sh_size,
1140                          spnt[stabstrsect].sh_offset,
1141                          spnt[stabstrsect].sh_size)) {
1142         dil = DIL_LOADED;
1143     } else {
1144         dil = DIL_ERROR;
1145         DEBUG_Printf(DBG_CHN_WARN, "bad stabs\n");
1146         goto leave;
1147     }
1148     
1149     for (i = 0; i < ehptr->e_shnum; i++) {
1150         if (   (strcmp(shstrtab + spnt[i].sh_name, ".symtab") == 0)
1151             && (spnt[i].sh_type == SHT_SYMTAB))
1152             DEBUG_ProcessElfSymtab(module, addr, module->elf_info->elf_addr,
1153                                    spnt + i, spnt + spnt[i].sh_link);
1154         
1155         if (   (strcmp(shstrtab + spnt[i].sh_name, ".dynsym") == 0)
1156             && (spnt[i].sh_type == SHT_DYNSYM))
1157             DEBUG_ProcessElfSymtab(module, addr, module->elf_info->elf_addr, 
1158                                    spnt + i, spnt + spnt[i].sh_link);
1159     }
1160
1161  leave:
1162     if (addr != (char*)0xffffffff) munmap(addr, statbuf.st_size);
1163     if (fd != -1) close(fd);
1164     
1165     return dil;
1166 }
1167
1168 /*
1169  * Loads the information for ELF module stored in 'filename'
1170  * the module has been loaded at 'load_offset' address
1171  * returns 
1172  *      -1 if the file cannot be found/opened
1173  *      0 if the file doesn't contain symbolic info (or this info cannot be 
1174  *      read or parsed)
1175  *      1 on success
1176  */
1177 static enum DbgInfoLoad DEBUG_ProcessElfFile(const char* filename, 
1178                                              unsigned int load_offset,
1179                                              unsigned int* dyn_addr)
1180 {
1181     enum DbgInfoLoad dil = DIL_ERROR;
1182     char*       addr = (char*)0xffffffff;
1183     int         fd = -1;
1184     struct stat statbuf;
1185     Elf32_Ehdr* ehptr;
1186     Elf32_Shdr* spnt;
1187     Elf32_Phdr* ppnt;
1188     char      * shstrtab;
1189     int         i;
1190     DBG_MODULE* module = NULL;
1191     DWORD       size;
1192     DWORD       delta;
1193
1194     DEBUG_Printf(DBG_CHN_TRACE, "Processing elf file '%s'\n", filename);
1195
1196     /* check that the file exists, and that the module hasn't been loaded yet */
1197     if (stat(filename, &statbuf) == -1) goto leave;
1198     
1199     /*
1200      * Now open the file, so that we can mmap() it.
1201      */
1202     if ((fd = open(filename, O_RDONLY)) == -1) goto leave;
1203     
1204     /*
1205      * Now mmap() the file.
1206      */
1207     addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
1208     if (addr == (char*)0xffffffff) goto leave;
1209
1210     dil = DIL_NOINFO;
1211     
1212     /*
1213      * Next, we need to find a few of the internal ELF headers within
1214      * this thing.  We need the main executable header, and the section
1215      * table.
1216      */
1217     ehptr = (Elf32_Ehdr*) addr;
1218     spnt = (Elf32_Shdr*) (addr + ehptr->e_shoff);
1219     shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);
1220
1221     /* if non relocatable ELF, then remove fixed address from computation
1222      * otherwise, all addresses are zero based
1223      */
1224     delta = (load_offset == 0) ? ehptr->e_entry : 0;
1225
1226     /* grab size of module once loaded in memory */
1227     ppnt = (Elf32_Phdr*) (addr + ehptr->e_phoff);
1228     size = 0;
1229     for (i = 0; i < ehptr->e_phnum; i++) {
1230         if (ppnt[i].p_type != PT_LOAD) continue;
1231         if (size < ppnt[i].p_vaddr - delta + ppnt[i].p_memsz)
1232             size = ppnt[i].p_vaddr - delta + ppnt[i].p_memsz;
1233     }
1234     
1235     for (i = 0; i < ehptr->e_shnum; i++) {
1236         if (strcmp(shstrtab + spnt[i].sh_name, ".bss") == 0 &&
1237             spnt[i].sh_type == SHT_NOBITS) {
1238             if (size < spnt[i].sh_addr - delta + spnt[i].sh_size)
1239                 size = spnt[i].sh_addr - delta + spnt[i].sh_size;
1240         }
1241         if (strcmp(shstrtab + spnt[i].sh_name, ".dynamic") == 0 &&
1242             spnt[i].sh_type == SHT_DYNAMIC) {
1243             if (dyn_addr) *dyn_addr = spnt[i].sh_addr;
1244         }
1245     }
1246     
1247     module = DEBUG_RegisterELFModule((load_offset == 0) ? ehptr->e_entry : load_offset, 
1248                                      size, filename);
1249     if (!module) {
1250         dil = DIL_ERROR;
1251         goto leave;
1252     }
1253
1254     if ((module->elf_info = DBG_alloc(sizeof(ELF_DBG_INFO))) == NULL) {
1255         DEBUG_Printf(DBG_CHN_ERR, "OOM\n");
1256         exit(0);
1257     }
1258
1259     module->elf_info->elf_addr = load_offset;
1260     dil = DEBUG_LoadElfStabs(module);
1261
1262  leave:
1263     if (addr != (char*)0xffffffff) munmap(addr, statbuf.st_size);
1264     if (fd != -1) close(fd);
1265     if (module) module->dil = dil;
1266     
1267     return dil;
1268 }
1269
1270 static enum DbgInfoLoad DEBUG_ProcessElfFileFromPath(const char * filename, 
1271                                                      unsigned int load_offset, 
1272                                                      unsigned int* dyn_addr, 
1273                                                      const char* path)
1274 {
1275     enum DbgInfoLoad    dil = DIL_ERROR;
1276     char        *s, *t, *fn;
1277     char*       paths = NULL;
1278
1279     if (!path) return -1;
1280
1281     for (s = paths = DBG_strdup(path); s && *s; s = (t) ? (t+1) : NULL) {
1282         t = strchr(s, ':');
1283         if (t) *t = '\0';
1284         fn = (char*)DBG_alloc(strlen(filename) + 1 + strlen(s) + 1);
1285         if (!fn) break;
1286         strcpy(fn, s );
1287         strcat(fn, "/");
1288         strcat(fn, filename);
1289         dil = DEBUG_ProcessElfFile(fn, load_offset, dyn_addr);
1290         DBG_free(fn);
1291         if (dil != DIL_ERROR) break;
1292         s = (t) ? (t+1) : NULL;
1293     }
1294
1295     DBG_free(paths);
1296     return dil;
1297 }
1298
1299 static enum DbgInfoLoad DEBUG_ProcessElfObject(const char* filename, 
1300                                                unsigned int load_offset,
1301                                                unsigned int* dyn_addr)
1302 {
1303    enum DbgInfoLoad     dil = DIL_ERROR;
1304
1305    if (filename == NULL) return DIL_ERROR;
1306    if (DEBUG_FindModuleByName(filename, DMT_ELF)) return DIL_LOADED;
1307
1308    dil = DEBUG_ProcessElfFile(filename, load_offset, dyn_addr);
1309
1310    /* if relative pathname, try some absolute base dirs */
1311    if (dil == DIL_ERROR && !strchr(filename, '/')) {
1312       dil = DEBUG_ProcessElfFileFromPath(filename, load_offset, dyn_addr, getenv("PATH"));
1313       if (dil == DIL_ERROR)
1314         dil = DEBUG_ProcessElfFileFromPath(filename, load_offset, dyn_addr, getenv("LD_LIBRARY_PATH"));
1315    }
1316
1317    DEBUG_ReportDIL(dil, "ELF", filename, load_offset);
1318
1319    return dil;
1320 }
1321    
1322 static  BOOL    DEBUG_WalkList(struct r_debug* dbg_hdr)
1323 {
1324     u_long              lm_addr;
1325     struct link_map     lm;
1326     Elf32_Ehdr          ehdr;
1327     char                bufstr[256];
1328
1329     /*
1330      * Now walk the linked list.  In all known ELF implementations,
1331      * the dynamic loader maintains this linked list for us.  In some
1332      * cases the first entry doesn't appear with a name, in other cases it
1333      * does.
1334      */
1335     for (lm_addr = (u_long)dbg_hdr->r_map; lm_addr; lm_addr = (u_long)lm.l_next) {
1336         if (!DEBUG_READ_MEM_VERBOSE((void*)lm_addr, &lm, sizeof(lm)))
1337             return FALSE;
1338         if (lm.l_addr != 0 &&
1339             DEBUG_READ_MEM_VERBOSE((void*)lm.l_addr, &ehdr, sizeof(ehdr)) &&
1340             ehdr.e_type == ET_DYN && /* only look at dynamic modules */
1341             lm.l_name != NULL &&
1342             DEBUG_READ_MEM_VERBOSE((void*)lm.l_name, bufstr, sizeof(bufstr))) {
1343             bufstr[sizeof(bufstr) - 1] = '\0';
1344             DEBUG_ProcessElfObject(bufstr, (unsigned)lm.l_addr, NULL);
1345         }
1346     }
1347     
1348     return TRUE;
1349 }
1350
1351 static BOOL DEBUG_RescanElf(void)
1352 {
1353     struct r_debug        dbg_hdr;
1354
1355     if (!DEBUG_CurrProcess || 
1356         !DEBUG_READ_MEM_VERBOSE((void*)DEBUG_CurrProcess->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr)))
1357        return FALSE;
1358
1359     switch (dbg_hdr.r_state) {
1360     case RT_CONSISTENT: 
1361        DEBUG_WalkList(&dbg_hdr);
1362        DEBUG_CheckDelayedBP();
1363        break;
1364     case RT_ADD:
1365        break;
1366     case RT_DELETE:
1367        /* FIXME: this is not currently handled, would need some kind of mark&sweep algo */
1368       break;
1369     }
1370     return FALSE;
1371 }
1372
1373 enum DbgInfoLoad        DEBUG_ReadExecutableDbgInfo(const char* exe_name)
1374 {
1375     Elf32_Dyn           dyn;
1376     struct r_debug      dbg_hdr;
1377     enum DbgInfoLoad    dil = DIL_NOINFO;
1378     unsigned int        dyn_addr;
1379     
1380     /*
1381      * Make sure we can stat and open this file.
1382      */
1383     if (exe_name == NULL) goto leave;
1384     DEBUG_ProcessElfObject(exe_name, 0, &dyn_addr);
1385     
1386     do {
1387         if (!DEBUG_READ_MEM_VERBOSE((void*)dyn_addr, &dyn, sizeof(dyn)))
1388             goto leave;
1389         dyn_addr += sizeof(dyn);
1390     } while (dyn.d_tag != DT_DEBUG && dyn.d_tag != DT_NULL);
1391     if (dyn.d_tag == DT_NULL) goto leave;
1392     
1393     /*
1394      * OK, now dig into the actual tables themselves.
1395      */
1396     if (!DEBUG_READ_MEM_VERBOSE((void*)dyn.d_un.d_ptr, &dbg_hdr, sizeof(dbg_hdr)))
1397         goto leave;
1398     
1399     assert(!DEBUG_CurrProcess->dbg_hdr_addr);
1400     DEBUG_CurrProcess->dbg_hdr_addr = (u_long)dyn.d_un.d_ptr;
1401     
1402     if (dbg_hdr.r_brk) {
1403         DBG_VALUE       value;
1404         
1405         DEBUG_Printf(DBG_CHN_TRACE, "Setting up a breakpoint on r_brk(%lx)\n",
1406                      (unsigned long)dbg_hdr.r_brk);
1407         
1408         DEBUG_SetBreakpoints(FALSE);
1409         value.type = NULL;
1410         value.cookie = DV_TARGET;
1411         value.addr.seg = 0;
1412         value.addr.off = (DWORD)dbg_hdr.r_brk;
1413         DEBUG_AddBreakpoint(&value, DEBUG_RescanElf);
1414         DEBUG_SetBreakpoints(TRUE);
1415     }
1416     
1417     dil = DEBUG_WalkList(&dbg_hdr);
1418     
1419  leave:
1420     return dil;
1421 }
1422
1423 #else   /* !__ELF__ */
1424
1425 enum DbgInfoLoad        DEBUG_ReadExecutableDbgInfo(const char* exe_name)
1426 {
1427   return FALSE;
1428 }
1429
1430 #endif  /* __ELF__ */