blob: dcd833a3455e6ed8964045d7641881b04a2c56e6 [file] [log] [blame]
Juan Cespedesd44c6b81998-09-25 14:48:42 +02001#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
Steve Fink7bafff02006-08-07 04:50:42 +02005#include <ctype.h>
Juan Cespedes5e01f651998-03-08 22:31:44 +01006#include <stdio.h>
7#include <stdlib.h>
Juan Cespedesd914a202004-11-10 00:15:33 +01008#include <string.h>
Juan Cespedes2c4a8cb1998-03-11 23:33:18 +01009#include <limits.h>
Juan Cespedes5e01f651998-03-08 22:31:44 +010010
11#include "ltrace.h"
12#include "options.h"
13
Juan Cespedesac3db291998-04-25 14:31:58 +020014static int display_char(int what);
Steve Fink6a48a6d2006-08-07 04:29:06 +020015static int display_string(enum tof type, struct process *proc,
Steve Fink7bafff02006-08-07 04:50:42 +020016 void* addr, size_t maxlen);
17static int display_value(enum tof type, struct process *proc,
Steve Finke4b32632006-08-07 06:10:08 +020018 long value, arg_type_info *info,
19 void *st, arg_type_info* st_info);
Steve Fink7bafff02006-08-07 04:50:42 +020020static int display_unknown(enum tof type, struct process *proc, long value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +010021static int display_format(enum tof type, struct process *proc, int arg_num);
Juan Cespedes5e01f651998-03-08 22:31:44 +010022
Steve Fink6a48a6d2006-08-07 04:29:06 +020023static int string_maxlength = INT_MAX;
Steve Fink1150bc42006-08-07 06:04:43 +020024static int array_maxlength = INT_MAX;
Steve Fink6a48a6d2006-08-07 04:29:06 +020025
Juan Cespedesf1350522008-12-16 18:19:58 +010026static long
27get_length(enum tof type, struct process *proc, int len_spec,
28 void *st, arg_type_info* st_info) {
Juan Cespedesa413e5b2007-09-04 17:34:53 +020029 long len;
30 arg_type_info info;
Steve Fink65b53df2006-09-25 02:27:08 +020031
Juan Cespedesa413e5b2007-09-04 17:34:53 +020032 if (len_spec > 0)
33 return len_spec;
34 if (type == LT_TOF_STRUCT) {
Luis Machado55c5feb2008-03-12 15:56:01 +010035 umovelong (proc, st + st_info->u.struct_info.offset[-len_spec-1],
36 &len, st_info->u.struct_info.fields[-len_spec-1]);
Juan Cespedesa413e5b2007-09-04 17:34:53 +020037 return len;
38 }
Steve Fink65b53df2006-09-25 02:27:08 +020039
Juan Cespedesa413e5b2007-09-04 17:34:53 +020040 info.type = ARGTYPE_INT;
41 return gimme_arg(type, proc, -len_spec-1, &info);
Steve Fink6a48a6d2006-08-07 04:29:06 +020042}
43
Juan Cespedesf1350522008-12-16 18:19:58 +010044static int
45display_ptrto(enum tof type, struct process *proc, long item,
Steve Finke4b32632006-08-07 06:10:08 +020046 arg_type_info * info,
Juan Cespedesf1350522008-12-16 18:19:58 +010047 void *st, arg_type_info* st_info) {
Juan Cespedesa413e5b2007-09-04 17:34:53 +020048 arg_type_info temp;
49 temp.type = ARGTYPE_POINTER;
50 temp.u.ptr_info.info = info;
51 return display_value(type, proc, item, &temp, st, st_info);
Steve Fink1150bc42006-08-07 06:04:43 +020052}
53
54/*
55 * addr - A pointer to the first element of the array
56 *
57 * The function name is used to indicate that we're not actually
58 * looking at an 'array', which is a contiguous region of memory
59 * containing a sequence of elements of some type; instead, we have a
60 * pointer to that region of memory.
61 */
Juan Cespedesf1350522008-12-16 18:19:58 +010062static int
63display_arrayptr(enum tof type, struct process *proc,
Steve Finke4b32632006-08-07 06:10:08 +020064 void *addr, arg_type_info * info,
Juan Cespedesf1350522008-12-16 18:19:58 +010065 void *st, arg_type_info* st_info) {
Juan Cespedesa413e5b2007-09-04 17:34:53 +020066 int len = 0;
67 int i;
68 int array_len;
Steve Fink1150bc42006-08-07 06:04:43 +020069
Juan Cespedesa413e5b2007-09-04 17:34:53 +020070 if (addr == NULL)
71 return fprintf(output, "NULL");
Steve Fink1150bc42006-08-07 06:04:43 +020072
Juan Cespedesa413e5b2007-09-04 17:34:53 +020073 array_len = get_length(type, proc, info->u.array_info.len_spec,
74 st, st_info);
75 len += fprintf(output, "[ ");
76 for (i = 0; i < opt_A && i < array_maxlength && i < array_len; i++) {
77 arg_type_info *elt_type = info->u.array_info.elt_type;
78 size_t elt_size = info->u.array_info.elt_size;
79 if (i != 0)
80 len += fprintf(output, ", ");
81 if (opt_d)
82 len += fprintf(output, "%p=", addr);
83 len +=
84 display_ptrto(type, proc, (long) addr, elt_type, st, st_info);
85 addr += elt_size;
86 }
87 if (i < array_len)
88 len += fprintf(output, "...");
89 len += fprintf(output, " ]");
90 return len;
Steve Fink1150bc42006-08-07 06:04:43 +020091}
Juan Cespedesa413e5b2007-09-04 17:34:53 +020092
Steve Finke4b32632006-08-07 06:10:08 +020093/* addr - A pointer to the beginning of the memory region occupied by
94 * the struct (aka a pointer to the struct)
95 */
Juan Cespedesf1350522008-12-16 18:19:58 +010096static int
97display_structptr(enum tof type, struct process *proc,
98 void *addr, arg_type_info * info) {
Juan Cespedesa413e5b2007-09-04 17:34:53 +020099 int i;
100 arg_type_info *field;
101 int len = 0;
Steve Finke4b32632006-08-07 06:10:08 +0200102
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200103 if (addr == NULL)
104 return fprintf(output, "NULL");
Steve Finke4b32632006-08-07 06:10:08 +0200105
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200106 len += fprintf(output, "{ ");
107 for (i = 0; (field = info->u.struct_info.fields[i]) != NULL; i++) {
108 if (i != 0)
109 len += fprintf(output, ", ");
110 if (opt_d)
111 len +=
112 fprintf(output, "%p=",
113 addr + info->u.struct_info.offset[i]);
114 len +=
115 display_ptrto(LT_TOF_STRUCT, proc,
116 (long) addr + info->u.struct_info.offset[i],
117 field, addr, info);
118 }
119 len += fprintf(output, " }");
Steve Finke4b32632006-08-07 06:10:08 +0200120
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200121 return len;
Steve Finke4b32632006-08-07 06:10:08 +0200122}
123
Juan Cespedesf1350522008-12-16 18:19:58 +0100124static int
125display_pointer(enum tof type, struct process *proc, long value,
Steve Finke4b32632006-08-07 06:10:08 +0200126 arg_type_info * info,
Juan Cespedesf1350522008-12-16 18:19:58 +0100127 void *st, arg_type_info* st_info) {
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200128 long pointed_to;
129 arg_type_info *inner = info->u.ptr_info.info;
Steve Fink7bafff02006-08-07 04:50:42 +0200130
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200131 if (inner->type == ARGTYPE_ARRAY) {
132 return display_arrayptr(type, proc, (void*) value, inner,
Steve Finke4b32632006-08-07 06:10:08 +0200133 st, st_info);
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200134 } else if (inner->type == ARGTYPE_STRUCT) {
135 return display_structptr(type, proc, (void *) value, inner);
136 } else {
137 if (value == 0)
138 return fprintf(output, "NULL");
Luis Machado55c5feb2008-03-12 15:56:01 +0100139 else if (umovelong (proc, (void *) value, &pointed_to,
140 info->u.ptr_info.info) < 0)
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200141 return fprintf(output, "?");
142 else
143 return display_value(type, proc, pointed_to, inner,
144 st, st_info);
145 }
Steve Fink7bafff02006-08-07 04:50:42 +0200146}
147
Juan Cespedesf1350522008-12-16 18:19:58 +0100148static int
149display_enum(enum tof type, struct process *proc,
150 arg_type_info* info, long value) {
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200151 int ii;
152 for (ii = 0; ii < info->u.enum_info.entries; ++ii) {
153 if (info->u.enum_info.values[ii] == value)
154 return fprintf(output, "%s", info->u.enum_info.keys[ii]);
155 }
Steve Fink6a3e24d2006-08-07 05:53:19 +0200156
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200157 return display_unknown(type, proc, value);
Steve Fink6a3e24d2006-08-07 05:53:19 +0200158}
159
Steve Fink7bafff02006-08-07 04:50:42 +0200160/* Args:
161 type - syscall or shared library function or memory
162 proc - information about the traced process
163 value - the value to display
164 info - the description of the type to display
Steve Finke4b32632006-08-07 06:10:08 +0200165 st - if the current value is a struct member, the address of the struct
166 st_info - type of the above struct
167
168 Those last two parameters are used for structs containing arrays or
169 strings whose length is given by another structure element.
Steve Fink7bafff02006-08-07 04:50:42 +0200170*/
Juan Cespedesf1350522008-12-16 18:19:58 +0100171int
172display_value(enum tof type, struct process *proc,
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200173 long value, arg_type_info *info,
Juan Cespedesf1350522008-12-16 18:19:58 +0100174 void *st, arg_type_info* st_info) {
Juan Cespedes5e01f651998-03-08 22:31:44 +0100175 int tmp;
Juan Cespedes5e01f651998-03-08 22:31:44 +0100176
Steve Fink6a48a6d2006-08-07 04:29:06 +0200177 switch (info->type) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100178 case ARGTYPE_VOID:
179 return 0;
180 case ARGTYPE_INT:
Juan Cespedesaee09312007-08-31 18:49:48 +0200181 return fprintf(output, "%d", (int) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100182 case ARGTYPE_UINT:
Juan Cespedesaee09312007-08-31 18:49:48 +0200183 return fprintf(output, "%u", (unsigned) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100184 case ARGTYPE_LONG:
185 if (proc->mask_32bit)
Steve Fink7bafff02006-08-07 04:50:42 +0200186 return fprintf(output, "%d", (int) value);
187 else
188 return fprintf(output, "%ld", value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100189 case ARGTYPE_ULONG:
190 if (proc->mask_32bit)
Steve Fink7bafff02006-08-07 04:50:42 +0200191 return fprintf(output, "%u", (unsigned) value);
192 else
193 return fprintf(output, "%lu", (unsigned long) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100194 case ARGTYPE_OCTAL:
Steve Fink7bafff02006-08-07 04:50:42 +0200195 return fprintf(output, "0%o", (unsigned) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100196 case ARGTYPE_CHAR:
197 tmp = fprintf(output, "'");
Steve Fink7bafff02006-08-07 04:50:42 +0200198 tmp += display_char(value == -1 ? value : (char) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100199 tmp += fprintf(output, "'");
200 return tmp;
Steve Fink6fa27c32006-08-07 05:56:56 +0200201 case ARGTYPE_SHORT:
202 return fprintf(output, "%hd", (short) value);
203 case ARGTYPE_USHORT:
204 return fprintf(output, "%hu", (unsigned short) value);
205 case ARGTYPE_FLOAT: {
Steve Fink65b53df2006-09-25 02:27:08 +0200206 union { long l; float f; double d; } cvt;
Steve Fink6fa27c32006-08-07 05:56:56 +0200207 cvt.l = value;
208 return fprintf(output, "%f", cvt.f);
209 }
Steve Fink65b53df2006-09-25 02:27:08 +0200210 case ARGTYPE_DOUBLE: {
211 union { long l; float f; double d; } cvt;
212 cvt.l = value;
213 return fprintf(output, "%lf", cvt.d);
214 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100215 case ARGTYPE_ADDR:
Steve Fink7bafff02006-08-07 04:50:42 +0200216 if (!value)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100217 return fprintf(output, "NULL");
Steve Fink7bafff02006-08-07 04:50:42 +0200218 else
219 return fprintf(output, "0x%08lx", value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100220 case ARGTYPE_FORMAT:
Steve Fink7bafff02006-08-07 04:50:42 +0200221 fprintf(stderr, "Should never encounter a format anywhere but at the top level (for now?)\n");
222 exit(1);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100223 case ARGTYPE_STRING:
Steve Fink7bafff02006-08-07 04:50:42 +0200224 return display_string(type, proc, (void*) value,
Steve Fink6a48a6d2006-08-07 04:29:06 +0200225 string_maxlength);
226 case ARGTYPE_STRING_N:
Steve Fink7bafff02006-08-07 04:50:42 +0200227 return display_string(type, proc, (void*) value,
Steve Fink6a48a6d2006-08-07 04:29:06 +0200228 get_length(type, proc,
Steve Finke4b32632006-08-07 06:10:08 +0200229 info->u.string_n_info.size_spec, st, st_info));
Steve Fink1150bc42006-08-07 06:04:43 +0200230 case ARGTYPE_ARRAY:
231 return fprintf(output, "<array without address>");
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200232 case ARGTYPE_ENUM:
Steve Fink6a3e24d2006-08-07 05:53:19 +0200233 return display_enum(type, proc, info, value);
Steve Finke4b32632006-08-07 06:10:08 +0200234 case ARGTYPE_STRUCT:
235 return fprintf(output, "<struct without address>");
Steve Fink7bafff02006-08-07 04:50:42 +0200236 case ARGTYPE_POINTER:
Steve Finke4b32632006-08-07 06:10:08 +0200237 return display_pointer(type, proc, value, info,
238 st, st_info);
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200239 case ARGTYPE_UNKNOWN:
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100240 default:
Steve Fink7bafff02006-08-07 04:50:42 +0200241 return display_unknown(type, proc, value);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100242 }
Steve Fink7bafff02006-08-07 04:50:42 +0200243}
244
Juan Cespedesf1350522008-12-16 18:19:58 +0100245int
246display_arg(enum tof type, struct process *proc, int arg_num, arg_type_info * info) {
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200247 long arg;
Steve Fink7bafff02006-08-07 04:50:42 +0200248
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200249 if (info->type == ARGTYPE_VOID) {
250 return 0;
251 } else if (info->type == ARGTYPE_FORMAT) {
252 return display_format(type, proc, arg_num);
253 } else {
254 arg = gimme_arg(type, proc, arg_num, info);
255 return display_value(type, proc, arg, info, NULL, NULL);
256 }
Juan Cespedes5e01f651998-03-08 22:31:44 +0100257}
258
Juan Cespedesf1350522008-12-16 18:19:58 +0100259static int
260display_char(int what) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100261 switch (what) {
262 case -1:
263 return fprintf(output, "EOF");
264 case '\r':
265 return fprintf(output, "\\r");
266 case '\n':
267 return fprintf(output, "\\n");
268 case '\t':
269 return fprintf(output, "\\t");
270 case '\b':
271 return fprintf(output, "\\b");
272 case '\\':
273 return fprintf(output, "\\\\");
274 default:
Steve Fink7bafff02006-08-07 04:50:42 +0200275 if (isprint(what)) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100276 return fprintf(output, "%c", what);
Steve Fink7bafff02006-08-07 04:50:42 +0200277 } else {
278 return fprintf(output, "\\%03o", (unsigned char)what);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100279 }
Juan Cespedes5e01f651998-03-08 22:31:44 +0100280 }
281}
282
Juan Cespedes2c4a8cb1998-03-11 23:33:18 +0100283#define MIN(a,b) (((a)<(b)) ? (a) : (b))
284
Juan Cespedesf1350522008-12-16 18:19:58 +0100285static int
286display_string(enum tof type, struct process *proc, void *addr,
287 size_t maxlength) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100288 unsigned char *str1;
Juan Cespedes5e01f651998-03-08 22:31:44 +0100289 int i;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100290 int len = 0;
Juan Cespedes5e01f651998-03-08 22:31:44 +0100291
Juan Cespedes5e01f651998-03-08 22:31:44 +0100292 if (!addr) {
293 return fprintf(output, "NULL");
294 }
295
Steve Fink6a48a6d2006-08-07 04:29:06 +0200296 str1 = malloc(MIN(opt_s, maxlength) + 3);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100297 if (!str1) {
298 return fprintf(output, "???");
299 }
Steve Fink6a48a6d2006-08-07 04:29:06 +0200300 umovestr(proc, addr, MIN(opt_s, maxlength) + 1, str1);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100301 len = fprintf(output, "\"");
Steve Fink6a48a6d2006-08-07 04:29:06 +0200302 for (i = 0; i < MIN(opt_s, maxlength); i++) {
Juan Cespedes5e01f651998-03-08 22:31:44 +0100303 if (str1[i]) {
304 len += display_char(str1[i]);
305 } else {
306 break;
307 }
308 }
309 len += fprintf(output, "\"");
Steve Fink6a48a6d2006-08-07 04:29:06 +0200310 if (str1[i] && (opt_s <= maxlength)) {
Juan Cespedes5e01f651998-03-08 22:31:44 +0100311 len += fprintf(output, "...");
312 }
313 free(str1);
314 return len;
315}
316
Juan Cespedesf1350522008-12-16 18:19:58 +0100317static int
318display_unknown(enum tof type, struct process *proc, long value) {
Ian Wienand9a2ad352006-02-20 22:44:45 +0100319 if (proc->mask_32bit) {
Steve Fink7bafff02006-08-07 04:50:42 +0200320 if ((int)value < 1000000 && (int)value > -1000000)
321 return fprintf(output, "%d", (int)value);
Ian Wienand9a2ad352006-02-20 22:44:45 +0100322 else
Steve Fink7bafff02006-08-07 04:50:42 +0200323 return fprintf(output, "%p", (void *)value);
324 } else if (value < 1000000 && value > -1000000) {
325 return fprintf(output, "%ld", value);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100326 } else {
Steve Fink7bafff02006-08-07 04:50:42 +0200327 return fprintf(output, "%p", (void *)value);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100328 }
329}
Juan Cespedesac3db291998-04-25 14:31:58 +0200330
Juan Cespedesf1350522008-12-16 18:19:58 +0100331static int
332display_format(enum tof type, struct process *proc, int arg_num) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100333 void *addr;
334 unsigned char *str1;
Juan Cespedesac3db291998-04-25 14:31:58 +0200335 int i;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100336 int len = 0;
Steve Fink65b53df2006-09-25 02:27:08 +0200337 arg_type_info info;
Juan Cespedesac3db291998-04-25 14:31:58 +0200338
Steve Fink65b53df2006-09-25 02:27:08 +0200339 info.type = ARGTYPE_POINTER;
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200340 addr = (void *)gimme_arg(type, proc, arg_num, &info);
Juan Cespedesac3db291998-04-25 14:31:58 +0200341 if (!addr) {
342 return fprintf(output, "NULL");
343 }
344
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100345 str1 = malloc(MIN(opt_s, string_maxlength) + 3);
Juan Cespedesac3db291998-04-25 14:31:58 +0200346 if (!str1) {
347 return fprintf(output, "???");
348 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100349 umovestr(proc, addr, MIN(opt_s, string_maxlength) + 1, str1);
Juan Cespedesac3db291998-04-25 14:31:58 +0200350 len = fprintf(output, "\"");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100351 for (i = 0; len < MIN(opt_s, string_maxlength) + 1; i++) {
Juan Cespedesac3db291998-04-25 14:31:58 +0200352 if (str1[i]) {
353 len += display_char(str1[i]);
354 } else {
355 break;
356 }
357 }
358 len += fprintf(output, "\"");
359 if (str1[i] && (opt_s <= string_maxlength)) {
360 len += fprintf(output, "...");
361 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100362 for (i = 0; str1[i]; i++) {
363 if (str1[i] == '%') {
Juan Cespedesd914a202004-11-10 00:15:33 +0100364 int is_long = 0;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100365 while (1) {
Juan Cespedes5c3fe062004-06-14 18:08:37 +0200366 unsigned char c = str1[++i];
Juan Cespedesac3db291998-04-25 14:31:58 +0200367 if (c == '%') {
368 break;
369 } else if (!c) {
370 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100371 } else if (strchr("lzZtj", c)) {
Juan Cespedesd914a202004-11-10 00:15:33 +0100372 is_long++;
373 if (c == 'j')
374 is_long++;
Ian Wienand3219f322006-02-16 06:00:00 +0100375 if (is_long > 1
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100376 && (sizeof(long) < sizeof(long long)
377 || proc->mask_32bit)) {
Juan Cespedesd914a202004-11-10 00:15:33 +0100378 len += fprintf(output, ", ...");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100379 str1[i + 1] = '\0';
Juan Cespedesd914a202004-11-10 00:15:33 +0100380 break;
381 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100382 } else if (c == 'd' || c == 'i') {
Steve Fink65b53df2006-09-25 02:27:08 +0200383 info.type = ARGTYPE_LONG;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100384 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100385 len +=
386 fprintf(output, ", %d",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200387 (int)gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100388 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100389 len +=
390 fprintf(output, ", %ld",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200391 gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200392 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100393 } else if (c == 'u') {
Steve Fink65b53df2006-09-25 02:27:08 +0200394 info.type = ARGTYPE_LONG;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100395 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100396 len +=
397 fprintf(output, ", %u",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200398 (int)gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100399 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100400 len +=
401 fprintf(output, ", %lu",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200402 gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200403 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100404 } else if (c == 'o') {
Steve Fink65b53df2006-09-25 02:27:08 +0200405 info.type = ARGTYPE_LONG;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100406 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100407 len +=
408 fprintf(output, ", 0%o",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200409 (int)gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100410 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100411 len +=
412 fprintf(output, ", 0%lo",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200413 gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200414 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100415 } else if (c == 'x' || c == 'X') {
Steve Fink65b53df2006-09-25 02:27:08 +0200416 info.type = ARGTYPE_LONG;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100417 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100418 len +=
419 fprintf(output, ", %#x",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200420 (int)gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100421 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100422 len +=
423 fprintf(output, ", %#lx",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200424 gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100425 break;
426 } else if (strchr("eEfFgGaACS", c)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100427 || (is_long
428 && (c == 'c' || c == 's'))) {
Juan Cespedesd914a202004-11-10 00:15:33 +0100429 len += fprintf(output, ", ...");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100430 str1[i + 1] = '\0';
Juan Cespedesac3db291998-04-25 14:31:58 +0200431 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100432 } else if (c == 'c') {
Steve Fink65b53df2006-09-25 02:27:08 +0200433 info.type = ARGTYPE_LONG;
Juan Cespedesac3db291998-04-25 14:31:58 +0200434 len += fprintf(output, ", '");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100435 len +=
436 display_char((int)
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200437 gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200438 len += fprintf(output, "'");
439 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100440 } else if (c == 's') {
Steve Fink65b53df2006-09-25 02:27:08 +0200441 info.type = ARGTYPE_POINTER;
Juan Cespedesac3db291998-04-25 14:31:58 +0200442 len += fprintf(output, ", ");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100443 len +=
444 display_string(type, proc,
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200445 (void *)gimme_arg(type, proc, ++arg_num, &info),
Steve Fink6a48a6d2006-08-07 04:29:06 +0200446 string_maxlength);
Juan Cespedesac3db291998-04-25 14:31:58 +0200447 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100448 } else if (c == 'p' || c == 'n') {
Steve Fink65b53df2006-09-25 02:27:08 +0200449 info.type = ARGTYPE_POINTER;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100450 len +=
451 fprintf(output, ", %p",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200452 (void *)gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200453 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100454 } else if (c == '*') {
Steve Fink65b53df2006-09-25 02:27:08 +0200455 info.type = ARGTYPE_LONG;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100456 len +=
457 fprintf(output, ", %d",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200458 (int)gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200459 }
460 }
461 }
462 }
463 free(str1);
464 return len;
465}