Implement generic debugging support. Implement a stabs reader and
[platform/upstream/binutils.git] / binutils / rddbg.c
1 /* rddbg.c -- Read debugging information into a generic form.
2    Copyright (C) 1995 Free Software Foundation, Inc.
3    Written by Ian Lance Taylor <ian@cygnus.com>.
4
5    This file is part of GNU Binutils.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA.  */
21
22 /* This file reads debugging information into a generic form.  This
23    file knows how to dig the debugging information out of an object
24    file.  */
25
26 #include "bfd.h"
27 #include "bucomm.h"
28 #include "libiberty.h"
29 #include "debug.h"
30 #include "budbg.h"
31
32 static boolean read_section_stabs_debugging_info
33   PARAMS ((bfd *, PTR, boolean *));
34
35 /* Read debugging information from a BFD.  Returns a generic debugging
36    pointer.  */
37
38 PTR
39 read_debugging_info (abfd)
40      bfd *abfd;
41 {
42   PTR dhandle;
43   boolean found;
44
45   dhandle = debug_init ();
46   if (dhandle == NULL)
47     return NULL;
48
49   /* All we know about right now is stabs in sections.  */
50
51   if (! read_section_stabs_debugging_info (abfd, dhandle, &found))
52     return NULL;
53
54   if (! found)
55     {
56       fprintf (stderr, "%s: no recognized debugging information\n",
57                bfd_get_filename (abfd));
58       return NULL;
59     }
60
61   return dhandle;
62 }
63
64 /* Read stabs in sections debugging information from a BFD.  */
65
66 static boolean
67 read_section_stabs_debugging_info (abfd, dhandle, pfound)
68      bfd *abfd;
69      PTR dhandle;
70      boolean *pfound;
71 {
72   static struct
73     {
74       const char *secname;
75       const char *strsecname;
76     } names[] = { { ".stab", ".stabstr" } };
77   unsigned int i;
78   PTR shandle;
79
80   *pfound = false;
81   shandle = NULL;
82
83   for (i = 0; i < sizeof names / sizeof names[0]; i++)
84     {
85       asection *sec, *strsec;
86
87       sec = bfd_get_section_by_name (abfd, names[i].secname);
88       strsec = bfd_get_section_by_name (abfd, names[i].strsecname);
89       if (sec != NULL && strsec != NULL)
90         {
91           bfd_size_type stabsize, strsize;
92           bfd_byte *stabs, *strings;
93           bfd_byte *stab;
94           bfd_size_type stroff, next_stroff;
95
96           stabsize = bfd_section_size (abfd, sec);
97           stabs = (bfd_byte *) xmalloc (stabsize);
98           if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
99             {
100               fprintf (stderr, "%s: %s: %s\n",
101                        bfd_get_filename (abfd), names[i].secname,
102                        bfd_errmsg (bfd_get_error ()));
103               return false;
104             }
105
106           strsize = bfd_section_size (abfd, strsec);
107           strings = (bfd_byte *) xmalloc (strsize);
108           if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
109             {
110               fprintf (stderr, "%s: %s: %s\n",
111                        bfd_get_filename (abfd), names[i].strsecname,
112                        bfd_errmsg (bfd_get_error ()));
113               return false;
114             }
115
116           if (shandle == NULL)
117             {
118               shandle = start_stab (dhandle);
119               if (shandle == NULL)
120                 return false;
121             }
122
123           *pfound = true;
124
125           stroff = 0;
126           next_stroff = 0;
127           for (stab = stabs; stab < stabs + stabsize; stab += 12)
128             {
129               bfd_size_type strx;
130               int type;
131               int other;
132               int desc;
133               bfd_vma value;
134
135               /* This code presumes 32 bit values.  */
136
137               strx = bfd_get_32 (abfd, stab);
138               type = bfd_get_8 (abfd, stab + 4);
139               other = bfd_get_8 (abfd, stab + 5);
140               desc = bfd_get_16 (abfd, stab + 6);
141               value = bfd_get_32 (abfd, stab + 8);
142
143               if (type == 0)
144                 {
145                   /* Special type 0 stabs indicate the offset to the
146                      next string table.  */
147                   stroff = next_stroff;
148                   next_stroff += value;
149                 }
150               else
151                 {
152                   char *f, *s;
153
154                   f = NULL;
155                   s = (char *) strings + stroff + strx;
156                   while (s[strlen (s) - 1] == '\\'
157                          && stab + 12 < stabs + stabsize)
158                     {
159                       stab += 12;
160                       s[strlen (s) - 1] = '\0';
161                       s = concat (s,
162                                   ((char *) strings
163                                    + stroff
164                                    + bfd_get_32 (abfd, stab)),
165                                   (const char *) NULL);
166                       if (f != NULL)
167                         free (f);
168                       f = s;
169                     }
170
171                   if (! parse_stab (dhandle, shandle, type, desc, value, s))
172                     return false;
173
174                   /* Don't free f, since I think the stabs code
175                      expects strings to hang around.  This should be
176                      straightened out.  FIXME.  */
177                 }
178             }
179
180           free (stabs);
181
182           /* Don't free strings, since I think the stabs code expects
183              the strings to hang around.  This should be straightened
184              out.  FIXME.  */
185         }
186     }
187
188   if (shandle != NULL)
189     {
190       if (! finish_stab (dhandle, shandle))
191         return false;
192     }
193
194   return true;
195 }