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