Implement generic debugging support. Implement a stabs reader and
[deliverable/binutils-gdb.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 }
This page took 0.034965 seconds and 5 git commands to generate.