Use the same color conversion algorithm as the DIB code (and Windows),
[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;
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, &lo) == -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         default:
520             DEBUG_Printf(DBG_CHN_MESG, "Unknown type '%c'\n", *ptd->ptr);
521             return -1;
522         }
523     }
524
525     if ((filenr2 || subnr2) && !*DEBUG_FileSubNr2StabEnum(filenr2, subnr2)) {
526         if (!new_dt) {
527             /* this should be a basic type, define it, or even void */
528             new_dt = DEBUG_NewDataType(DT_BASIC, typename);
529         }
530         *DEBUG_FileSubNr2StabEnum(filenr2, subnr2) = new_dt;
531     }
532
533     if (!new_dt) {
534         dt1 = *DEBUG_FileSubNr2StabEnum(filenr1, subnr1);
535         if (!dt1) {
536             DEBUG_Printf(DBG_CHN_MESG, "Nothing has been defined <%s>\n", ptd->ptr);
537             return -1;
538         }
539         *ret_dt = dt1;
540         return 0;
541     }
542
543     *DEBUG_FileSubNr2StabEnum(filenr1, subnr1) = *ret_dt = new_dt;
544
545 #if 0
546     if (typename) {
547         DEBUG_Printf(DBG_CHN_MESG, "Adding (%d,%d) %s => ", filenr1, subnr1, typename);
548         DEBUG_PrintTypeCast(new_dt);
549         DEBUG_Printf(DBG_CHN_MESG, "\n");
550     }
551 #endif
552
553     return 0;
554 }
555
556 static int DEBUG_ParseTypedefStab(char* ptr, const char* typename)
557 {
558     struct ParseTypedefData     ptd;
559     struct datatype*            dt;
560     int                         ret = -1;
561
562     /* check for already existing definition */
563     
564     ptd.idx = 0;
565     if ((ptd.ptr = strchr(ptr, ':'))) {
566         ptd.ptr++;
567         if (*ptd.ptr != '(') ptd.ptr++;
568         ret = DEBUG_PTS_ReadTypedef(&ptd, typename, &dt);
569     }
570
571     if (ret == -1 || *ptd.ptr) {
572         DEBUG_Printf(DBG_CHN_MESG, "failure on %s at %s\n", ptr, ptd.ptr);
573         return FALSE;
574     }
575
576     return TRUE;
577 }
578
579 static struct datatype *
580 DEBUG_ParseStabType(const char * stab)
581 {
582   char * c;
583
584   /*
585    * Look through the stab definition, and figure out what datatype
586    * this represents.  If we have something we know about, assign the
587    * type.
588    */
589   c = strchr(stab, ':');
590   if( c == NULL )
591       return NULL;
592
593   c++;
594   /*
595    * The next character says more about the type (i.e. data, function, etc)
596    * of symbol.  Skip it.
597    */
598   if (*c != '(')
599     c++;
600   /* 
601    * The next is either an integer or a (integer,integer).
602    * The DEBUG_ReadTypeEnum takes care that stab_types is large enough.
603    */
604   return *DEBUG_ReadTypeEnum(&c);
605 }
606
607 enum DbgInfoLoad DEBUG_ParseStabs(char * addr, unsigned int load_offset,
608                                   unsigned int staboff, int stablen, 
609                                   unsigned int strtaboff, int strtablen)
610 {
611   struct name_hash    * curr_func = NULL;
612   struct wine_locals  * curr_loc = NULL;
613   struct name_hash    * curr_sym = NULL;
614   char                  currpath[PATH_MAX];
615   int                   i;
616   int                   in_external_file = FALSE;
617   int                   last_nso = -1;
618   unsigned int          len;
619   DBG_VALUE             new_value;
620   int                   nstab;
621   char                * ptr;
622   char                * stabbuff;
623   unsigned int          stabbufflen;
624   struct stab_nlist   * stab_ptr;
625   char                * strs;
626   int                   strtabinc;
627   char                * subpath = NULL;
628   char                  symname[4096];
629
630   nstab = stablen / sizeof(struct stab_nlist);
631   stab_ptr = (struct stab_nlist *) (addr + staboff);
632   strs  = (char *) (addr + strtaboff);
633
634   memset(currpath, 0, sizeof(currpath));
635
636   /*
637    * Allocate a buffer into which we can build stab strings for cases
638    * where the stab is continued over multiple lines.
639    */
640   stabbufflen = 65536;
641   stabbuff = (char *) DBG_alloc(stabbufflen);
642
643   strtabinc = 0;
644   stabbuff[0] = '\0';
645   for(i=0; i < nstab; i++, stab_ptr++ )
646     {
647       ptr = strs + (unsigned int) stab_ptr->n_un.n_name;
648       if( ptr[strlen(ptr) - 1] == '\\' )
649         {
650           /*
651            * Indicates continuation.  Append this to the buffer, and go onto the
652            * next record.  Repeat the process until we find a stab without the
653            * '/' character, as this indicates we have the whole thing.
654            */
655           len = strlen(ptr);
656           if( strlen(stabbuff) + len > stabbufflen )
657             {
658               stabbufflen += 65536;
659               stabbuff = (char *) DBG_realloc(stabbuff, stabbufflen);
660             }
661           strncat(stabbuff, ptr, len - 1);
662           continue;
663         }
664       else if( stabbuff[0] != '\0' )
665         {
666           strcat( stabbuff, ptr);
667           ptr = stabbuff;
668         }
669
670       if( strchr(ptr, '=') != NULL )
671         {
672           /*
673            * The stabs aren't in writable memory, so copy it over so we are
674            * sure we can scribble on it.
675            */
676           if( ptr != stabbuff )
677             {
678               strcpy(stabbuff, ptr);
679               ptr = stabbuff;
680             }
681           stab_strcpy(symname, sizeof(symname), ptr);
682           if (!DEBUG_ParseTypedefStab(ptr, symname)) {
683             /* skip this definition */
684             stabbuff[0] = '\0';
685             continue;
686           }
687         }
688
689       switch(stab_ptr->n_type)
690         {
691         case N_GSYM:
692           /*
693            * These are useless with ELF.  They have no value, and you have to
694            * read the normal symbol table to get the address.  Thus we
695            * ignore them, and when we process the normal symbol table
696            * we should do the right thing.
697            *
698            * With a.out or mingw, they actually do make some amount of sense.
699            */
700           new_value.addr.seg = 0;
701           new_value.type = DEBUG_ParseStabType(ptr);
702           new_value.addr.off = load_offset + stab_ptr->n_value;
703           new_value.cookie = DV_TARGET;
704
705           stab_strcpy(symname, sizeof(symname), ptr);
706 #ifdef __ELF__
707           curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath,
708                                       SYM_WINE | SYM_DATA | SYM_INVALID );
709 #else
710           curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath,
711                                       SYM_WINE | SYM_DATA );
712 #endif
713           break;
714         case N_RBRAC:
715         case N_LBRAC:
716           /*
717            * We need to keep track of these so we get symbol scoping
718            * right for local variables.  For now, we just ignore them.
719            * The hooks are already there for dealing with this however,
720            * so all we need to do is to keep count of the nesting level,
721            * and find the RBRAC for each matching LBRAC.
722            */
723           break;
724         case N_LCSYM:
725         case N_STSYM:
726           /*
727            * These are static symbols and BSS symbols.
728            */
729           new_value.addr.seg = 0;
730           new_value.type = DEBUG_ParseStabType(ptr);
731           new_value.addr.off = load_offset + stab_ptr->n_value;
732           new_value.cookie = DV_TARGET;
733
734           stab_strcpy(symname, sizeof(symname), ptr);
735           curr_sym = DEBUG_AddSymbol( symname, &new_value, currpath, 
736                                       SYM_WINE | SYM_DATA );
737           break;
738         case N_PSYM:
739           /*
740            * These are function parameters.
741            */
742           if( curr_func != NULL && !in_external_file )
743             {
744               stab_strcpy(symname, sizeof(symname), ptr);
745               curr_loc = DEBUG_AddLocal( curr_func, 0, 
746                                          stab_ptr->n_value, 0, 0, symname );
747               DEBUG_SetLocalSymbolType( curr_loc, DEBUG_ParseStabType(ptr) );
748             }
749           break;
750         case N_RSYM:
751           if( curr_func != NULL && !in_external_file )
752             {
753               stab_strcpy(symname, sizeof(symname), ptr);
754               curr_loc = DEBUG_AddLocal( curr_func, stab_ptr->n_value + 1, 
755                                          0, 0, 0, symname );
756               DEBUG_SetLocalSymbolType( curr_loc, DEBUG_ParseStabType(ptr) );
757             }
758           break;
759         case N_LSYM:
760           if( curr_func != NULL && !in_external_file )
761             {
762               stab_strcpy(symname, sizeof(symname), ptr);
763               curr_loc = DEBUG_AddLocal( curr_func, 0, 
764                                          stab_ptr->n_value, 0, 0, symname );
765               DEBUG_SetLocalSymbolType( curr_loc, DEBUG_ParseStabType(ptr) );
766             }
767           break;
768         case N_SLINE:
769           /*
770            * This is a line number.  These are always relative to the start
771            * of the function (N_FUN), and this makes the lookup easier.
772            */
773           if( curr_func != NULL && !in_external_file )
774             {
775 #ifdef __ELF__
776               DEBUG_AddLineNumber(curr_func, stab_ptr->n_desc, 
777                                   stab_ptr->n_value);
778 #else
779 #if 0
780               /*
781                * This isn't right.  The order of the stabs is different under
782                * a.out, and as a result we would end up attaching the line
783                * number to the wrong function.
784                */
785               DEBUG_AddLineNumber(curr_func, stab_ptr->n_desc, 
786                                   stab_ptr->n_value - curr_func->addr.off);
787 #endif
788 #endif
789             }
790           break;
791         case N_FUN:
792           /*
793            * First, clean up the previous function we were working on.
794            */
795           DEBUG_Normalize(curr_func);
796
797           /*
798            * For now, just declare the various functions.  Later
799            * on, we will add the line number information and the
800            * local symbols.
801            */
802           if( !in_external_file)
803             {
804               stab_strcpy(symname, sizeof(symname), ptr);
805               if (*symname)
806                 {
807                   new_value.addr.seg = 0;
808                   new_value.type = DEBUG_ParseStabType(ptr);
809                   new_value.addr.off = load_offset + stab_ptr->n_value;
810                   new_value.cookie = DV_TARGET;
811                   /*
812                    * Copy the string to a temp buffer so we
813                    * can kill everything after the ':'.  We do
814                    * it this way because otherwise we end up dirtying
815                    * all of the pages related to the stabs, and that
816                    * sucks up swap space like crazy.
817                    */
818 #ifdef __ELF__
819                   curr_func = DEBUG_AddSymbol( symname, &new_value, currpath,
820                                                SYM_WINE | SYM_FUNC | SYM_INVALID );
821 #else
822                   curr_func = DEBUG_AddSymbol( symname, &new_value, currpath,
823                                                SYM_WINE | SYM_FUNC );
824 #endif
825                 } 
826               else
827                 {
828                   /* some GCC seem to use a N_FUN "" to mark the end of a function */
829                   curr_func = NULL;
830                 }
831             }
832           else
833             {
834               /*
835                * Don't add line number information for this function
836                * any more.
837                */
838               curr_func = NULL;
839             }
840           break;
841         case N_SO:
842           /*
843            * This indicates a new source file.  Append the records
844            * together, to build the correct path name.
845            */
846 #ifndef __ELF__
847           /*
848            * With a.out, there is no NULL string N_SO entry at the end of
849            * the file.  Thus when we find non-consecutive entries,
850            * we consider that a new file is started.
851            */
852           if( last_nso < i-1 )
853             {
854               currpath[0] = '\0';
855               DEBUG_Normalize(curr_func);
856               curr_func = NULL;
857             }
858 #endif
859
860           if( *ptr == '\0' )
861             {
862               /*
863                * Nuke old path.
864                */
865               currpath[0] = '\0';
866               DEBUG_Normalize(curr_func);
867               curr_func = NULL;
868             }
869           else
870             {
871               if (*ptr != '/')
872                 strcat(currpath, ptr);
873               else
874                 strcpy(currpath, ptr);
875               subpath = ptr;
876               DEBUG_ResetIncludes();
877             }
878           last_nso = i;
879           break;
880         case N_SOL:
881           /*
882            * This indicates we are including stuff from an include file.
883            * If this is the main source, enable the debug stuff, otherwise
884            * ignore it.
885            */
886           in_external_file = !(subpath == NULL || strcmp(ptr, subpath) == 0);
887           break;
888         case N_UNDF:
889           strs += strtabinc;
890           strtabinc = stab_ptr->n_value;
891           DEBUG_Normalize(curr_func);
892           curr_func = NULL;
893           break;
894         case N_OPT:
895           /*
896            * Ignore this.  We don't care what it points to.
897            */
898           break;
899         case N_BINCL:
900            DEBUG_AddInclude(DEBUG_CreateInclude(ptr, stab_ptr->n_value));
901            break;
902         case N_EINCL:
903            break;
904         case N_EXCL:
905            DEBUG_AddInclude(DEBUG_FindInclude(ptr, stab_ptr->n_value));
906            break;
907         case N_MAIN:
908           /*
909            * Always ignore these.  GCC doesn't even generate them.
910            */
911           break;
912         default:
913           DEBUG_Printf(DBG_CHN_MESG, "Unknown stab type 0x%02x\n", stab_ptr->n_type);
914           break;
915         }
916
917       stabbuff[0] = '\0';
918
919 #if 0
920       DEBUG_Printf(DBG_CHN_MESG, "%d %x %s\n", stab_ptr->n_type, 
921                    (unsigned int) stab_ptr->n_value,
922                    strs + (unsigned int) stab_ptr->n_un.n_name);
923 #endif
924     }
925
926   DEBUG_FreeIncludes();
927
928   return DIL_LOADED;
929 }
930
931 #ifdef __ELF__
932
933 /*
934  * Walk through the entire symbol table and add any symbols we find there.
935  * This can be used in cases where we have stripped ELF shared libraries,
936  * or it can be used in cases where we have data symbols for which the address
937  * isn't encoded in the stabs.
938  *
939  * This is all really quite easy, since we don't have to worry about line
940  * numbers or local data variables.
941  */
942 static int DEBUG_ProcessElfSymtab(DBG_MODULE* module, char* addr, 
943                                   u_long load_addr, Elf32_Shdr* symtab, 
944                                   Elf32_Shdr* strtab)
945 {
946   char          * curfile = NULL;
947   struct name_hash * curr_sym = NULL;
948   int             flags;
949   int             i;
950   DBG_VALUE       new_value;
951   int             nsym;
952   char          * strp;
953   char          * symname;
954   Elf32_Sym     * symp;
955
956   symp = (Elf32_Sym *) (addr + symtab->sh_offset);
957   nsym = symtab->sh_size / sizeof(*symp);
958   strp = (char *) (addr + strtab->sh_offset);
959
960   for(i=0; i < nsym; i++, symp++)
961     {
962       /*
963        * Ignore certain types of entries which really aren't of that much
964        * interest.
965        */
966       if( ELF32_ST_TYPE(symp->st_info) == STT_SECTION ||
967           symp->st_shndx == STN_UNDEF )
968         {
969           continue;
970         }
971
972       symname = strp + symp->st_name;
973
974       /*
975        * Save the name of the current file, so we have a way of tracking
976        * static functions/data.
977        */
978       if( ELF32_ST_TYPE(symp->st_info) == STT_FILE )
979         {
980           curfile = symname;
981           continue;
982         }
983
984       /*
985        * See if we already have something for this symbol.
986        * If so, ignore this entry, because it would have come from the
987        * stabs or from a previous symbol.  If the value is different,
988        * we will have to keep the darned thing, because there can be
989        * multiple local symbols by the same name.
990        */
991       if(    (DEBUG_GetSymbolValue(symname, -1, &new_value, FALSE ) == TRUE)
992           && (new_value.addr.off == (load_addr + symp->st_value)) )
993           continue;
994
995       new_value.addr.seg = 0;
996       new_value.type = NULL;
997       new_value.addr.off = load_addr + symp->st_value;
998       new_value.cookie = DV_TARGET;
999       flags = SYM_WINE | ((ELF32_ST_TYPE(symp->st_info) == STT_FUNC) 
1000                           ? SYM_FUNC : SYM_DATA);
1001       if( ELF32_ST_BIND(symp->st_info) == STB_GLOBAL )
1002           curr_sym = DEBUG_AddSymbol( symname, &new_value, NULL, flags );
1003       else
1004           curr_sym = DEBUG_AddSymbol( symname, &new_value, curfile, flags );
1005
1006       /*
1007        * Record the size of the symbol.  This can come in handy in
1008        * some cases.  Not really used yet, however.
1009        */
1010       if( symp->st_size != 0 )
1011           DEBUG_SetSymbolSize(curr_sym, symp->st_size);
1012     }
1013
1014   return TRUE;
1015 }
1016
1017 /*
1018  * Loads the symbolic information from ELF module stored in 'filename'
1019  * the module has been loaded at 'load_offset' address, so symbols' address
1020  * relocation is performed
1021  * returns 
1022  *      -1 if the file cannot be found/opened
1023  *      0 if the file doesn't contain symbolic info (or this info cannot be 
1024  *      read or parsed)
1025  *      1 on success
1026  */
1027 enum DbgInfoLoad DEBUG_LoadElfStabs(DBG_MODULE* module)
1028 {
1029     enum DbgInfoLoad dil = DIL_ERROR;
1030     char*       addr = (char*)0xffffffff;
1031     int         fd = -1;
1032     struct stat statbuf;
1033     Elf32_Ehdr* ehptr;
1034     Elf32_Shdr* spnt;
1035     char*       shstrtab;
1036     int         i;
1037     int         stabsect;
1038     int         stabstrsect;
1039
1040     if (module->type != DMT_ELF || ! module->elf_info) {
1041         DEBUG_Printf(DBG_CHN_ERR, "Bad elf module '%s'\n", module->module_name);
1042         return DIL_ERROR;
1043     }
1044
1045     /* check that the file exists, and that the module hasn't been loaded yet */
1046     if (stat(module->module_name, &statbuf) == -1) goto leave;
1047     if (S_ISDIR(statbuf.st_mode)) goto leave;
1048
1049     /*
1050      * Now open the file, so that we can mmap() it.
1051      */
1052     if ((fd = open(module->module_name, O_RDONLY)) == -1) goto leave;
1053     
1054     dil = DIL_NOINFO;
1055     /*
1056      * Now mmap() the file.
1057      */
1058     addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
1059     if (addr == (char*)0xffffffff) goto leave;
1060     
1061     /*
1062      * Next, we need to find a few of the internal ELF headers within
1063      * this thing.  We need the main executable header, and the section
1064      * table.
1065      */
1066     ehptr = (Elf32_Ehdr*) addr;
1067     spnt = (Elf32_Shdr*) (addr + ehptr->e_shoff);
1068     shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);
1069     
1070     stabsect = stabstrsect = -1;
1071     
1072     for (i = 0; i < ehptr->e_shnum; i++) {
1073         if (strcmp(shstrtab + spnt[i].sh_name, ".stab") == 0)
1074             stabsect = i;
1075         
1076         if (strcmp(shstrtab + spnt[i].sh_name, ".stabstr") == 0)
1077             stabstrsect = i;
1078     }
1079     
1080     if (stabsect == -1 || stabstrsect == -1) {
1081         DEBUG_Printf(DBG_CHN_WARN, "no .stab section\n");
1082         goto leave;
1083     }
1084     
1085     /*
1086      * OK, now just parse all of the stabs.
1087      */
1088     if (DEBUG_ParseStabs(addr, 
1089                          module->elf_info->elf_addr, 
1090                          spnt[stabsect].sh_offset,
1091                          spnt[stabsect].sh_size,
1092                          spnt[stabstrsect].sh_offset,
1093                          spnt[stabstrsect].sh_size)) {
1094         dil = DIL_LOADED;
1095     } else {
1096         dil = DIL_ERROR;
1097         DEBUG_Printf(DBG_CHN_WARN, "bad stabs\n");
1098         goto leave;
1099     }
1100     
1101     for (i = 0; i < ehptr->e_shnum; i++) {
1102         if (   (strcmp(shstrtab + spnt[i].sh_name, ".symtab") == 0)
1103             && (spnt[i].sh_type == SHT_SYMTAB))
1104             DEBUG_ProcessElfSymtab(module, addr, module->elf_info->elf_addr,
1105                                    spnt + i, spnt + spnt[i].sh_link);
1106         
1107         if (   (strcmp(shstrtab + spnt[i].sh_name, ".dynsym") == 0)
1108             && (spnt[i].sh_type == SHT_DYNSYM))
1109             DEBUG_ProcessElfSymtab(module, addr, module->elf_info->elf_addr, 
1110                                    spnt + i, spnt + spnt[i].sh_link);
1111     }
1112
1113  leave:
1114     if (addr != (char*)0xffffffff) munmap(addr, statbuf.st_size);
1115     if (fd != -1) close(fd);
1116     
1117     return dil;
1118 }
1119
1120 /*
1121  * Loads the information for ELF module stored in 'filename'
1122  * the module has been loaded at 'load_offset' address
1123  * returns 
1124  *      -1 if the file cannot be found/opened
1125  *      0 if the file doesn't contain symbolic info (or this info cannot be 
1126  *      read or parsed)
1127  *      1 on success
1128  */
1129 static enum DbgInfoLoad DEBUG_ProcessElfFile(const char* filename, 
1130                                              unsigned int load_offset,
1131                                              unsigned int* dyn_addr)
1132 {
1133     enum DbgInfoLoad dil = DIL_ERROR;
1134     char*       addr = (char*)0xffffffff;
1135     int         fd = -1;
1136     struct stat statbuf;
1137     Elf32_Ehdr* ehptr;
1138     Elf32_Shdr* spnt;
1139     Elf32_Phdr* ppnt;
1140     char      * shstrtab;
1141     int         i;
1142     DBG_MODULE* module = NULL;
1143     DWORD       size;
1144     DWORD       delta;
1145
1146     DEBUG_Printf(DBG_CHN_TRACE, "Processing elf file '%s'\n", filename);
1147
1148     /* check that the file exists, and that the module hasn't been loaded yet */
1149     if (stat(filename, &statbuf) == -1) goto leave;
1150     
1151     /*
1152      * Now open the file, so that we can mmap() it.
1153      */
1154     if ((fd = open(filename, O_RDONLY)) == -1) goto leave;
1155     
1156     /*
1157      * Now mmap() the file.
1158      */
1159     addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
1160     if (addr == (char*)0xffffffff) goto leave;
1161
1162     dil = DIL_NOINFO;
1163     
1164     /*
1165      * Next, we need to find a few of the internal ELF headers within
1166      * this thing.  We need the main executable header, and the section
1167      * table.
1168      */
1169     ehptr = (Elf32_Ehdr*) addr;
1170     spnt = (Elf32_Shdr*) (addr + ehptr->e_shoff);
1171     shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);
1172
1173     /* if non relocatable ELF, then remove fixed address from computation
1174      * otherwise, all addresses are zero based
1175      */
1176     delta = (load_offset == 0) ? ehptr->e_entry : 0;
1177
1178     /* grab size of module once loaded in memory */
1179     ppnt = (Elf32_Phdr*) (addr + ehptr->e_phoff);
1180     size = 0;
1181     for (i = 0; i < ehptr->e_phnum; i++) {
1182         if (ppnt[i].p_type != PT_LOAD) continue;
1183         if (size < ppnt[i].p_vaddr - delta + ppnt[i].p_memsz)
1184             size = ppnt[i].p_vaddr - delta + ppnt[i].p_memsz;
1185     }
1186     
1187     for (i = 0; i < ehptr->e_shnum; i++) {
1188         if (strcmp(shstrtab + spnt[i].sh_name, ".bss") == 0 &&
1189             spnt[i].sh_type == SHT_NOBITS) {
1190             if (size < spnt[i].sh_addr - delta + spnt[i].sh_size)
1191                 size = spnt[i].sh_addr - delta + spnt[i].sh_size;
1192         }
1193         if (strcmp(shstrtab + spnt[i].sh_name, ".dynamic") == 0 &&
1194             spnt[i].sh_type == SHT_DYNAMIC) {
1195             if (dyn_addr) *dyn_addr = spnt[i].sh_addr;
1196         }
1197     }
1198     
1199     module = DEBUG_RegisterELFModule((load_offset == 0) ? ehptr->e_entry : load_offset, 
1200                                      size, filename);
1201     if (!module) {
1202         dil = DIL_ERROR;
1203         goto leave;
1204     }
1205
1206     if ((module->elf_info = DBG_alloc(sizeof(ELF_DBG_INFO))) == NULL) {
1207         DEBUG_Printf(DBG_CHN_ERR, "OOM\n");
1208         exit(0);
1209     }
1210
1211     module->elf_info->elf_addr = load_offset;
1212     dil = DEBUG_LoadElfStabs(module);
1213
1214  leave:
1215     if (addr != (char*)0xffffffff) munmap(addr, statbuf.st_size);
1216     if (fd != -1) close(fd);
1217     if (module) module->dil = dil;
1218     
1219     return dil;
1220 }
1221
1222 static enum DbgInfoLoad DEBUG_ProcessElfFileFromPath(const char * filename, 
1223                                                      unsigned int load_offset, 
1224                                                      unsigned int* dyn_addr, 
1225                                                      const char* path)
1226 {
1227     enum DbgInfoLoad    dil = DIL_ERROR;
1228     char        *s, *t, *fn;
1229     char*       paths = NULL;
1230
1231     if (!path) return -1;
1232
1233     for (s = paths = DBG_strdup(path); s && *s; s = (t) ? (t+1) : NULL) {
1234         t = strchr(s, ':');
1235         if (t) *t = '\0';
1236         fn = (char*)DBG_alloc(strlen(filename) + 1 + strlen(s) + 1);
1237         if (!fn) break;
1238         strcpy(fn, s );
1239         strcat(fn, "/");
1240         strcat(fn, filename);
1241         dil = DEBUG_ProcessElfFile(fn, load_offset, dyn_addr);
1242         DBG_free(fn);
1243         if (dil != DIL_ERROR) break;
1244         s = (t) ? (t+1) : NULL;
1245     }
1246
1247     DBG_free(paths);
1248     return dil;
1249 }
1250
1251 static enum DbgInfoLoad DEBUG_ProcessElfObject(const char* filename, 
1252                                                unsigned int load_offset,
1253                                                unsigned int* dyn_addr)
1254 {
1255    enum DbgInfoLoad     dil = DIL_ERROR;
1256
1257    if (filename == NULL) return DIL_ERROR;
1258    if (DEBUG_FindModuleByName(filename, DMT_ELF)) return DIL_LOADED;
1259
1260    dil = DEBUG_ProcessElfFile(filename, load_offset, dyn_addr);
1261
1262    /* if relative pathname, try some absolute base dirs */
1263    if (dil == DIL_ERROR && !strchr(filename, '/')) {
1264       dil = DEBUG_ProcessElfFileFromPath(filename, load_offset, dyn_addr, getenv("PATH"));
1265       if (dil == DIL_ERROR)
1266         dil = DEBUG_ProcessElfFileFromPath(filename, load_offset, dyn_addr, getenv("LD_LIBRARY_PATH"));
1267    }
1268
1269    DEBUG_ReportDIL(dil, "ELF", filename, load_offset);
1270
1271    return dil;
1272 }
1273    
1274 static  BOOL    DEBUG_WalkList(struct r_debug* dbg_hdr)
1275 {
1276     u_long              lm_addr;
1277     struct link_map     lm;
1278     Elf32_Ehdr          ehdr;
1279     char                bufstr[256];
1280
1281     /*
1282      * Now walk the linked list.  In all known ELF implementations,
1283      * the dynamic loader maintains this linked list for us.  In some
1284      * cases the first entry doesn't appear with a name, in other cases it
1285      * does.
1286      */
1287     for (lm_addr = (u_long)dbg_hdr->r_map; lm_addr; lm_addr = (u_long)lm.l_next) {
1288         if (!DEBUG_READ_MEM_VERBOSE((void*)lm_addr, &lm, sizeof(lm)))
1289             return FALSE;
1290         if (lm.l_addr != 0 &&
1291             DEBUG_READ_MEM_VERBOSE((void*)lm.l_addr, &ehdr, sizeof(ehdr)) &&
1292             ehdr.e_type == ET_DYN && /* only look at dynamic modules */
1293             lm.l_name != NULL &&
1294             DEBUG_READ_MEM_VERBOSE((void*)lm.l_name, bufstr, sizeof(bufstr))) {
1295             bufstr[sizeof(bufstr) - 1] = '\0';
1296             DEBUG_ProcessElfObject(bufstr, (unsigned)lm.l_addr, NULL);
1297         }
1298     }
1299     
1300     return TRUE;
1301 }
1302
1303 static BOOL DEBUG_RescanElf(void)
1304 {
1305     struct r_debug        dbg_hdr;
1306
1307     if (!DEBUG_CurrProcess || 
1308         !DEBUG_READ_MEM_VERBOSE((void*)DEBUG_CurrProcess->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr)))
1309        return FALSE;
1310
1311     switch (dbg_hdr.r_state) {
1312     case RT_CONSISTENT: 
1313        DEBUG_WalkList(&dbg_hdr);
1314        DEBUG_CheckDelayedBP();
1315        break;
1316     case RT_ADD:
1317        break;
1318     case RT_DELETE:
1319        /* FIXME: this is not currently handled, would need some kind of mark&sweep algo */
1320       break;
1321     }
1322     return FALSE;
1323 }
1324
1325 enum DbgInfoLoad        DEBUG_ReadExecutableDbgInfo(const char* exe_name)
1326 {
1327     Elf32_Dyn           dyn;
1328     struct r_debug      dbg_hdr;
1329     enum DbgInfoLoad    dil = DIL_NOINFO;
1330     unsigned int        dyn_addr;
1331     
1332     /*
1333      * Make sure we can stat and open this file.
1334      */
1335     if (exe_name == NULL) goto leave;
1336     DEBUG_ProcessElfObject(exe_name, 0, &dyn_addr);
1337     
1338     do {
1339         if (!DEBUG_READ_MEM_VERBOSE((void*)dyn_addr, &dyn, sizeof(dyn)))
1340             goto leave;
1341         dyn_addr += sizeof(dyn);
1342     } while (dyn.d_tag != DT_DEBUG && dyn.d_tag != DT_NULL);
1343     if (dyn.d_tag == DT_NULL) goto leave;
1344     
1345     /*
1346      * OK, now dig into the actual tables themselves.
1347      */
1348     if (!DEBUG_READ_MEM_VERBOSE((void*)dyn.d_un.d_ptr, &dbg_hdr, sizeof(dbg_hdr)))
1349         goto leave;
1350     
1351     assert(!DEBUG_CurrProcess->dbg_hdr_addr);
1352     DEBUG_CurrProcess->dbg_hdr_addr = (u_long)dyn.d_un.d_ptr;
1353     
1354     if (dbg_hdr.r_brk) {
1355         DBG_VALUE       value;
1356         
1357         DEBUG_Printf(DBG_CHN_TRACE, "Setting up a breakpoint on r_brk(%lx)\n",
1358                      (unsigned long)dbg_hdr.r_brk);
1359         
1360         DEBUG_SetBreakpoints(FALSE);
1361         value.type = NULL;
1362         value.cookie = DV_TARGET;
1363         value.addr.seg = 0;
1364         value.addr.off = (DWORD)dbg_hdr.r_brk;
1365         DEBUG_AddBreakpoint(&value, DEBUG_RescanElf);
1366         DEBUG_SetBreakpoints(TRUE);
1367     }
1368     
1369     dil = DEBUG_WalkList(&dbg_hdr);
1370     
1371  leave:
1372     return dil;
1373 }
1374
1375 #else   /* !__ELF__ */
1376
1377 enum DbgInfoLoad        DEBUG_ReadExecutableDbgInfo(const char* exe_name)
1378 {
1379   return FALSE;
1380 }
1381
1382 #endif  /* __ELF__ */