/tags/rel-1-3-15/SWIG/Tools/WAD/Wad/vars.c
C | 271 lines | 202 code | 25 blank | 44 comment | 34 complexity | cd5957424cc8a1eedd15c0c870e62807 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
1/* -----------------------------------------------------------------------------
2 * vars.c
3 *
4 * This file examines the stack trace and tries to make some sense out of
5 * collected debugging information. This includes locating the data on
6 * the stack and/or registers.
7 *
8 * This feature is detached from the debugging info collector to make
9 * it independent of debugging formats.
10 *
11 * Author(s) : David Beazley (beazley@cs.uchicago.edu)
12 *
13 * Copyright (C) 2000. The University of Chicago.
14 *
15 * This library is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2.1 of the License, or (at your option) any later version.
19 *
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
29 * See the file COPYING for a complete copy of the LGPL.
30 * ----------------------------------------------------------------------------- */
31
32#include "wad.h"
33
34static char cvs[] = "$Header$";
35
36/* -----------------------------------------------------------------------------
37 * wad_build_vars()
38 *
39 * Build variable information for a single stack frame
40 * ----------------------------------------------------------------------------- */
41
42void wad_build_vars(WadFrame *f) {
43 char *stack = 0;
44 char *nstack = 0;
45 char *pstack = 0;
46 WadLocal *loc;
47 int n;
48
49 stack = (char *) f->stack;
50 if (f->next) {
51 nstack = (char *) f->next->stack;
52 }
53 if (f->prev) {
54 pstack = (char *) f->prev->stack;
55 }
56
57 for (n = 0; n < 2; n++) {
58 if (n == 0) loc = f->debug_args;
59 else loc = f->debug_locals;
60
61 while (loc) {
62 loc->ptr = 0;
63 if (loc->loc == PARM_STACK) {
64 if ((loc->stack >= 0) && (nstack)) {
65 loc->ptr = (void *) (nstack + loc->stack);
66 } else if (loc->stack < 0) {
67 loc->ptr = (void *) (stack + f->stack_size + loc->stack);
68 }
69 loc->size = sizeof(long);
70 }
71 if (loc->loc == PARM_REGISTER) {
72 /* Parameter is located in a register */
73#ifdef WAD_SOLARIS
74 if ((loc->reg >= 24) && (loc->reg < 32)) {
75 /* Value is located in the %in registers. */
76 loc->ptr = (void *) (stack + (loc->reg - 16)*sizeof(int));
77 loc->size = sizeof(int);
78 } else if ((loc->reg >= 8) && (loc->reg < 16)) {
79
80 /* Value is located in the %on registers */
81 if (nstack) {
82 loc->ptr = (void *) (stack + (loc->reg)*sizeof(int));
83 loc->size = sizeof(int);
84 }
85 } else if ((loc->reg >= 16) && (loc->reg < 24)) {
86 /* Value has been placed in the %ln registers */
87 loc->ptr = (void *) (stack + (loc->reg - 16)*sizeof(int));
88 loc->size = sizeof(int);
89 }
90#endif
91 }
92 loc = loc->next;
93 }
94 }
95}
96
97/* This function creates a formatted integer given a pointer, size, and sign flag */
98static
99char *wad_format_int(char *ptr, int nbytes, int sgn) {
100 static char fmt[128];
101 unsigned char *s;
102 int incr;
103 unsigned long value = 0;
104 int i;
105
106#ifdef WAD_LITTLE_ENDIAN
107 s = (unsigned char *) (ptr + nbytes - 1);
108 incr = -1;
109#else
110 s = (unsigned char *) (ptr);
111 incr = +1;
112#endif
113 for (i = 0; i < nbytes; i++, s += incr) {
114 value = (value << 8) + *s;
115 }
116 if (sgn) {
117 return wad_format_signed((long) value,-1);
118 } else {
119 return wad_format_unsigned((unsigned long) value, -1);
120 }
121 return fmt;
122}
123
124/* Try to make a formatted version of a local */
125char *wad_format_var(WadLocal *l) {
126 static char hexdigits[] = "0123456789abcdef";
127 static char buffer[1024];
128 double dval;
129 float fval;
130
131 buffer[0] = 0;
132
133 switch(l->type) {
134 case WAD_TYPE_INT32:
135 wad_strcpy(buffer,wad_format_int(l->ptr,4,1));
136 break;
137 case WAD_TYPE_UINT32:
138 wad_strcpy(buffer,wad_format_int(l->ptr,4,0));
139 break;
140 case WAD_TYPE_INT16:
141 wad_strcpy(buffer,wad_format_int(l->ptr,2,1));
142 break;
143 case WAD_TYPE_UINT16:
144 wad_strcpy(buffer,wad_format_int(l->ptr,2,0));
145 break;
146 case WAD_TYPE_INT8:
147 wad_strcpy(buffer,wad_format_int(l->ptr,1,1));
148 break;
149 case WAD_TYPE_UINT8:
150 wad_strcpy(buffer,wad_format_int(l->ptr,1,0));
151 break;
152 case WAD_TYPE_CHAR:
153 buffer[0] = '\'';
154 buffer[1] = *((char *) l->ptr);
155 buffer[2] = '\'';
156 buffer[3] = 0;
157 break;
158 case WAD_TYPE_FLOAT:
159 wad_memcpy(&fval,l->ptr,sizeof(float));
160 sprintf(buffer,"%g",fval);
161 break;
162 case WAD_TYPE_DOUBLE:
163 wad_memcpy(&dval,l->ptr,sizeof(double));
164 sprintf(buffer,"%g",dval);
165 break;
166 case WAD_TYPE_UNKNOWN:
167 case WAD_TYPE_POINTER:
168 default:
169 /* Hmmm. Unknown data type. We'll just treat it as a word */
170 if (l->ptr) {
171 int incr,i;
172 int b;
173 int leading = 1;
174 char *c;
175 char *ptr;
176
177#ifdef WAD_LITTLE_ENDIAN
178 ptr = ((char *) l->ptr) + 3;
179 incr = -1;
180#else
181 ptr = (char *) l->ptr;
182 incr =1 ;
183#endif
184 wad_strcat(buffer,"0x");
185 c = buffer+2;
186 for (i = 0; i < sizeof(void *); i++) {
187 b = (int) *ptr;
188 if (!leading || (b)) {
189 if (!leading || (b & 0xf0))
190 *(c++) = hexdigits[(b & 0xf0) >> 4];
191 *(c++) = hexdigits[(b & 0xf)];
192 leading = 0;
193 }
194 ptr += incr;
195 }
196 if (leading)
197 *(c++) = '0';
198
199 *c = 0;
200 }
201 }
202 return buffer;
203}
204
205/* Convert a wad local variable to a long */
206long wad_local_as_long(WadLocal *loc) {
207 long value = 0;
208 int32 i32;
209 int16 i16;
210 int8 i8;
211 uint32 u32;
212 uint16 u16;
213 uint8 u8;
214
215 switch(loc->type) {
216 case WAD_TYPE_INT32:
217 wad_memcpy(&i32,loc->ptr,4);
218 value = (long) i32;
219 break;
220 case WAD_TYPE_UINT32:
221 wad_memcpy(&u32,loc->ptr,4);
222 value = (long) u32;
223 break;
224 case WAD_TYPE_INT16:
225 wad_memcpy(&i16,loc->ptr,2);
226 value = (long) i16;
227 break;
228 case WAD_TYPE_UINT16:
229 wad_memcpy(&u16,loc->ptr,2);
230 value = (long) u16;
231 break;
232 case WAD_TYPE_INT8:
233 case WAD_TYPE_CHAR:
234 wad_memcpy(&i8, loc->ptr,1);
235 value = (long) i8;
236 break;
237 case WAD_TYPE_UINT8:
238 wad_memcpy(&u8, loc->ptr,1);
239 value = (long) u8;
240 break;
241 default:
242 wad_memcpy(&u32,loc->ptr,4);
243 value = (long) u32;
244 }
245 return value;
246}
247
248/* Convert a wad local variable to a long */
249double wad_local_as_double(WadLocal *loc) {
250 double value = 0;
251 float fval;
252
253 switch(loc->type) {
254 case WAD_TYPE_DOUBLE:
255 wad_memcpy(&value,loc->ptr,8);
256 break;
257 case WAD_TYPE_FLOAT:
258 wad_memcpy(&fval,loc->ptr,4);
259 value = (double) fval;
260 break;
261 default:
262 value = 0;
263 }
264 return value;
265}
266
267
268
269
270
271