blob: 92f3e7d3d37ced1f05b8920e456e6354718dde1a [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
Steve Finke4b32632006-08-07 06:10:08 +020026static long get_length(enum tof type, struct process *proc, int len_spec,
27 void *st, arg_type_info* st_info)
Steve Fink6a48a6d2006-08-07 04:29:06 +020028{
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) {
35 umovelong(proc, st + st_info->u.struct_info.offset[-len_spec-1], &len);
36 return len;
37 }
Steve Fink65b53df2006-09-25 02:27:08 +020038
Juan Cespedesa413e5b2007-09-04 17:34:53 +020039 info.type = ARGTYPE_INT;
40 return gimme_arg(type, proc, -len_spec-1, &info);
Steve Fink6a48a6d2006-08-07 04:29:06 +020041}
42
Steve Fink1150bc42006-08-07 06:04:43 +020043static int display_ptrto(enum tof type, struct process *proc, long item,
Steve Finke4b32632006-08-07 06:10:08 +020044 arg_type_info * info,
45 void *st, arg_type_info* st_info)
Steve Fink1150bc42006-08-07 06:04:43 +020046{
Juan Cespedesa413e5b2007-09-04 17:34:53 +020047 arg_type_info temp;
48 temp.type = ARGTYPE_POINTER;
49 temp.u.ptr_info.info = info;
50 return display_value(type, proc, item, &temp, st, st_info);
Steve Fink1150bc42006-08-07 06:04:43 +020051}
52
53/*
54 * addr - A pointer to the first element of the array
55 *
56 * The function name is used to indicate that we're not actually
57 * looking at an 'array', which is a contiguous region of memory
58 * containing a sequence of elements of some type; instead, we have a
59 * pointer to that region of memory.
60 */
61static int display_arrayptr(enum tof type, struct process *proc,
Steve Finke4b32632006-08-07 06:10:08 +020062 void *addr, arg_type_info * info,
63 void *st, arg_type_info* st_info)
Steve Fink1150bc42006-08-07 06:04:43 +020064{
Juan Cespedesa413e5b2007-09-04 17:34:53 +020065 int len = 0;
66 int i;
67 int array_len;
Steve Fink1150bc42006-08-07 06:04:43 +020068
Juan Cespedesa413e5b2007-09-04 17:34:53 +020069 if (addr == NULL)
70 return fprintf(output, "NULL");
Steve Fink1150bc42006-08-07 06:04:43 +020071
Juan Cespedesa413e5b2007-09-04 17:34:53 +020072 array_len = get_length(type, proc, info->u.array_info.len_spec,
73 st, st_info);
74 len += fprintf(output, "[ ");
75 for (i = 0; i < opt_A && i < array_maxlength && i < array_len; i++) {
76 arg_type_info *elt_type = info->u.array_info.elt_type;
77 size_t elt_size = info->u.array_info.elt_size;
78 if (i != 0)
79 len += fprintf(output, ", ");
80 if (opt_d)
81 len += fprintf(output, "%p=", addr);
82 len +=
83 display_ptrto(type, proc, (long) addr, elt_type, st, st_info);
84 addr += elt_size;
85 }
86 if (i < array_len)
87 len += fprintf(output, "...");
88 len += fprintf(output, " ]");
89 return len;
Steve Fink1150bc42006-08-07 06:04:43 +020090}
Juan Cespedesa413e5b2007-09-04 17:34:53 +020091
Steve Finke4b32632006-08-07 06:10:08 +020092/* addr - A pointer to the beginning of the memory region occupied by
93 * the struct (aka a pointer to the struct)
94 */
95static int display_structptr(enum tof type, struct process *proc,
96 void *addr, arg_type_info * info)
97{
Juan Cespedesa413e5b2007-09-04 17:34:53 +020098 int i;
99 arg_type_info *field;
100 int len = 0;
Steve Finke4b32632006-08-07 06:10:08 +0200101
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200102 if (addr == NULL)
103 return fprintf(output, "NULL");
Steve Finke4b32632006-08-07 06:10:08 +0200104
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200105 len += fprintf(output, "{ ");
106 for (i = 0; (field = info->u.struct_info.fields[i]) != NULL; i++) {
107 if (i != 0)
108 len += fprintf(output, ", ");
109 if (opt_d)
110 len +=
111 fprintf(output, "%p=",
112 addr + info->u.struct_info.offset[i]);
113 len +=
114 display_ptrto(LT_TOF_STRUCT, proc,
115 (long) addr + info->u.struct_info.offset[i],
116 field, addr, info);
117 }
118 len += fprintf(output, " }");
Steve Finke4b32632006-08-07 06:10:08 +0200119
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200120 return len;
Steve Finke4b32632006-08-07 06:10:08 +0200121}
122
Steve Fink7bafff02006-08-07 04:50:42 +0200123static int display_pointer(enum tof type, struct process *proc, long value,
Steve Finke4b32632006-08-07 06:10:08 +0200124 arg_type_info * info,
125 void *st, arg_type_info* st_info)
Steve Fink7bafff02006-08-07 04:50:42 +0200126{
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200127 long pointed_to;
128 arg_type_info *inner = info->u.ptr_info.info;
Steve Fink7bafff02006-08-07 04:50:42 +0200129
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200130 if (inner->type == ARGTYPE_ARRAY) {
131 return display_arrayptr(type, proc, (void*) value, inner,
Steve Finke4b32632006-08-07 06:10:08 +0200132 st, st_info);
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200133 } else if (inner->type == ARGTYPE_STRUCT) {
134 return display_structptr(type, proc, (void *) value, inner);
135 } else {
136 if (value == 0)
137 return fprintf(output, "NULL");
138 else if (umovelong(proc, (void *) value, &pointed_to) < 0)
139 return fprintf(output, "?");
140 else
141 return display_value(type, proc, pointed_to, inner,
142 st, st_info);
143 }
Steve Fink7bafff02006-08-07 04:50:42 +0200144}
145
Steve Fink6a3e24d2006-08-07 05:53:19 +0200146static int display_enum(enum tof type, struct process *proc,
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200147 arg_type_info* info, long value)
Steve Fink6a3e24d2006-08-07 05:53:19 +0200148{
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200149 int ii;
150 for (ii = 0; ii < info->u.enum_info.entries; ++ii) {
151 if (info->u.enum_info.values[ii] == value)
152 return fprintf(output, "%s", info->u.enum_info.keys[ii]);
153 }
Steve Fink6a3e24d2006-08-07 05:53:19 +0200154
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200155 return display_unknown(type, proc, value);
Steve Fink6a3e24d2006-08-07 05:53:19 +0200156}
157
Steve Fink7bafff02006-08-07 04:50:42 +0200158/* Args:
159 type - syscall or shared library function or memory
160 proc - information about the traced process
161 value - the value to display
162 info - the description of the type to display
Steve Finke4b32632006-08-07 06:10:08 +0200163 st - if the current value is a struct member, the address of the struct
164 st_info - type of the above struct
165
166 Those last two parameters are used for structs containing arrays or
167 strings whose length is given by another structure element.
Steve Fink7bafff02006-08-07 04:50:42 +0200168*/
169int display_value(enum tof type, struct process *proc,
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200170 long value, arg_type_info *info,
171 void *st, arg_type_info* st_info)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100172{
Juan Cespedes5e01f651998-03-08 22:31:44 +0100173 int tmp;
Juan Cespedes5e01f651998-03-08 22:31:44 +0100174
Steve Fink6a48a6d2006-08-07 04:29:06 +0200175 switch (info->type) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100176 case ARGTYPE_VOID:
177 return 0;
178 case ARGTYPE_INT:
Juan Cespedesaee09312007-08-31 18:49:48 +0200179 return fprintf(output, "%d", (int) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100180 case ARGTYPE_UINT:
Juan Cespedesaee09312007-08-31 18:49:48 +0200181 return fprintf(output, "%u", (unsigned) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100182 case ARGTYPE_LONG:
183 if (proc->mask_32bit)
Steve Fink7bafff02006-08-07 04:50:42 +0200184 return fprintf(output, "%d", (int) value);
185 else
186 return fprintf(output, "%ld", value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100187 case ARGTYPE_ULONG:
188 if (proc->mask_32bit)
Steve Fink7bafff02006-08-07 04:50:42 +0200189 return fprintf(output, "%u", (unsigned) value);
190 else
191 return fprintf(output, "%lu", (unsigned long) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100192 case ARGTYPE_OCTAL:
Steve Fink7bafff02006-08-07 04:50:42 +0200193 return fprintf(output, "0%o", (unsigned) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100194 case ARGTYPE_CHAR:
195 tmp = fprintf(output, "'");
Steve Fink7bafff02006-08-07 04:50:42 +0200196 tmp += display_char(value == -1 ? value : (char) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100197 tmp += fprintf(output, "'");
198 return tmp;
Steve Fink6fa27c32006-08-07 05:56:56 +0200199 case ARGTYPE_SHORT:
200 return fprintf(output, "%hd", (short) value);
201 case ARGTYPE_USHORT:
202 return fprintf(output, "%hu", (unsigned short) value);
203 case ARGTYPE_FLOAT: {
Steve Fink65b53df2006-09-25 02:27:08 +0200204 union { long l; float f; double d; } cvt;
Steve Fink6fa27c32006-08-07 05:56:56 +0200205 cvt.l = value;
206 return fprintf(output, "%f", cvt.f);
207 }
Steve Fink65b53df2006-09-25 02:27:08 +0200208 case ARGTYPE_DOUBLE: {
209 union { long l; float f; double d; } cvt;
210 cvt.l = value;
211 return fprintf(output, "%lf", cvt.d);
212 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100213 case ARGTYPE_ADDR:
Steve Fink7bafff02006-08-07 04:50:42 +0200214 if (!value)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100215 return fprintf(output, "NULL");
Steve Fink7bafff02006-08-07 04:50:42 +0200216 else
217 return fprintf(output, "0x%08lx", value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100218 case ARGTYPE_FORMAT:
Steve Fink7bafff02006-08-07 04:50:42 +0200219 fprintf(stderr, "Should never encounter a format anywhere but at the top level (for now?)\n");
220 exit(1);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100221 case ARGTYPE_STRING:
Steve Fink7bafff02006-08-07 04:50:42 +0200222 return display_string(type, proc, (void*) value,
Steve Fink6a48a6d2006-08-07 04:29:06 +0200223 string_maxlength);
224 case ARGTYPE_STRING_N:
Steve Fink7bafff02006-08-07 04:50:42 +0200225 return display_string(type, proc, (void*) value,
Steve Fink6a48a6d2006-08-07 04:29:06 +0200226 get_length(type, proc,
Steve Finke4b32632006-08-07 06:10:08 +0200227 info->u.string_n_info.size_spec, st, st_info));
Steve Fink1150bc42006-08-07 06:04:43 +0200228 case ARGTYPE_ARRAY:
229 return fprintf(output, "<array without address>");
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200230 case ARGTYPE_ENUM:
Steve Fink6a3e24d2006-08-07 05:53:19 +0200231 return display_enum(type, proc, info, value);
Steve Finke4b32632006-08-07 06:10:08 +0200232 case ARGTYPE_STRUCT:
233 return fprintf(output, "<struct without address>");
Steve Fink7bafff02006-08-07 04:50:42 +0200234 case ARGTYPE_POINTER:
Steve Finke4b32632006-08-07 06:10:08 +0200235 return display_pointer(type, proc, value, info,
236 st, st_info);
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200237 case ARGTYPE_UNKNOWN:
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100238 default:
Steve Fink7bafff02006-08-07 04:50:42 +0200239 return display_unknown(type, proc, value);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100240 }
Steve Fink7bafff02006-08-07 04:50:42 +0200241}
242
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200243int display_arg(enum tof type, struct process *proc, int arg_num, arg_type_info * info)
Steve Fink7bafff02006-08-07 04:50:42 +0200244{
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200245 long arg;
Steve Fink7bafff02006-08-07 04:50:42 +0200246
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200247 if (info->type == ARGTYPE_VOID) {
248 return 0;
249 } else if (info->type == ARGTYPE_FORMAT) {
250 return display_format(type, proc, arg_num);
251 } else {
252 arg = gimme_arg(type, proc, arg_num, info);
253 return display_value(type, proc, arg, info, NULL, NULL);
254 }
Juan Cespedes5e01f651998-03-08 22:31:44 +0100255}
256
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100257static int display_char(int what)
258{
259 switch (what) {
260 case -1:
261 return fprintf(output, "EOF");
262 case '\r':
263 return fprintf(output, "\\r");
264 case '\n':
265 return fprintf(output, "\\n");
266 case '\t':
267 return fprintf(output, "\\t");
268 case '\b':
269 return fprintf(output, "\\b");
270 case '\\':
271 return fprintf(output, "\\\\");
272 default:
Steve Fink7bafff02006-08-07 04:50:42 +0200273 if (isprint(what)) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100274 return fprintf(output, "%c", what);
Steve Fink7bafff02006-08-07 04:50:42 +0200275 } else {
276 return fprintf(output, "\\%03o", (unsigned char)what);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100277 }
Juan Cespedes5e01f651998-03-08 22:31:44 +0100278 }
279}
280
Juan Cespedes2c4a8cb1998-03-11 23:33:18 +0100281#define MIN(a,b) (((a)<(b)) ? (a) : (b))
282
Steve Fink7bafff02006-08-07 04:50:42 +0200283static int display_string(enum tof type, struct process *proc, void *addr,
284 size_t maxlength)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100285{
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100286 unsigned char *str1;
Juan Cespedes5e01f651998-03-08 22:31:44 +0100287 int i;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100288 int len = 0;
Juan Cespedes5e01f651998-03-08 22:31:44 +0100289
Juan Cespedes5e01f651998-03-08 22:31:44 +0100290 if (!addr) {
291 return fprintf(output, "NULL");
292 }
293
Steve Fink6a48a6d2006-08-07 04:29:06 +0200294 str1 = malloc(MIN(opt_s, maxlength) + 3);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100295 if (!str1) {
296 return fprintf(output, "???");
297 }
Steve Fink6a48a6d2006-08-07 04:29:06 +0200298 umovestr(proc, addr, MIN(opt_s, maxlength) + 1, str1);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100299 len = fprintf(output, "\"");
Steve Fink6a48a6d2006-08-07 04:29:06 +0200300 for (i = 0; i < MIN(opt_s, maxlength); i++) {
Juan Cespedes5e01f651998-03-08 22:31:44 +0100301 if (str1[i]) {
302 len += display_char(str1[i]);
303 } else {
304 break;
305 }
306 }
307 len += fprintf(output, "\"");
Steve Fink6a48a6d2006-08-07 04:29:06 +0200308 if (str1[i] && (opt_s <= maxlength)) {
Juan Cespedes5e01f651998-03-08 22:31:44 +0100309 len += fprintf(output, "...");
310 }
311 free(str1);
312 return len;
313}
314
Steve Fink7bafff02006-08-07 04:50:42 +0200315static int display_unknown(enum tof type, struct process *proc, long value)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100316{
Ian Wienand9a2ad352006-02-20 22:44:45 +0100317 if (proc->mask_32bit) {
Steve Fink7bafff02006-08-07 04:50:42 +0200318 if ((int)value < 1000000 && (int)value > -1000000)
319 return fprintf(output, "%d", (int)value);
Ian Wienand9a2ad352006-02-20 22:44:45 +0100320 else
Steve Fink7bafff02006-08-07 04:50:42 +0200321 return fprintf(output, "%p", (void *)value);
322 } else if (value < 1000000 && value > -1000000) {
323 return fprintf(output, "%ld", value);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100324 } else {
Steve Fink7bafff02006-08-07 04:50:42 +0200325 return fprintf(output, "%p", (void *)value);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100326 }
327}
Juan Cespedesac3db291998-04-25 14:31:58 +0200328
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100329static int display_format(enum tof type, struct process *proc, int arg_num)
330{
331 void *addr;
332 unsigned char *str1;
Juan Cespedesac3db291998-04-25 14:31:58 +0200333 int i;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100334 int len = 0;
Steve Fink65b53df2006-09-25 02:27:08 +0200335 arg_type_info info;
Juan Cespedesac3db291998-04-25 14:31:58 +0200336
Steve Fink65b53df2006-09-25 02:27:08 +0200337 info.type = ARGTYPE_POINTER;
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200338 addr = (void *)gimme_arg(type, proc, arg_num, &info);
Juan Cespedesac3db291998-04-25 14:31:58 +0200339 if (!addr) {
340 return fprintf(output, "NULL");
341 }
342
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100343 str1 = malloc(MIN(opt_s, string_maxlength) + 3);
Juan Cespedesac3db291998-04-25 14:31:58 +0200344 if (!str1) {
345 return fprintf(output, "???");
346 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100347 umovestr(proc, addr, MIN(opt_s, string_maxlength) + 1, str1);
Juan Cespedesac3db291998-04-25 14:31:58 +0200348 len = fprintf(output, "\"");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100349 for (i = 0; len < MIN(opt_s, string_maxlength) + 1; i++) {
Juan Cespedesac3db291998-04-25 14:31:58 +0200350 if (str1[i]) {
351 len += display_char(str1[i]);
352 } else {
353 break;
354 }
355 }
356 len += fprintf(output, "\"");
357 if (str1[i] && (opt_s <= string_maxlength)) {
358 len += fprintf(output, "...");
359 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100360 for (i = 0; str1[i]; i++) {
361 if (str1[i] == '%') {
Juan Cespedesd914a202004-11-10 00:15:33 +0100362 int is_long = 0;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100363 while (1) {
Juan Cespedes5c3fe062004-06-14 18:08:37 +0200364 unsigned char c = str1[++i];
Juan Cespedesac3db291998-04-25 14:31:58 +0200365 if (c == '%') {
366 break;
367 } else if (!c) {
368 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100369 } else if (strchr("lzZtj", c)) {
Juan Cespedesd914a202004-11-10 00:15:33 +0100370 is_long++;
371 if (c == 'j')
372 is_long++;
Ian Wienand3219f322006-02-16 06:00:00 +0100373 if (is_long > 1
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100374 && (sizeof(long) < sizeof(long long)
375 || proc->mask_32bit)) {
Juan Cespedesd914a202004-11-10 00:15:33 +0100376 len += fprintf(output, ", ...");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100377 str1[i + 1] = '\0';
Juan Cespedesd914a202004-11-10 00:15:33 +0100378 break;
379 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100380 } else if (c == 'd' || c == 'i') {
Steve Fink65b53df2006-09-25 02:27:08 +0200381 info.type = ARGTYPE_LONG;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100382 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100383 len +=
384 fprintf(output, ", %d",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200385 (int)gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100386 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100387 len +=
388 fprintf(output, ", %ld",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200389 gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200390 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100391 } else if (c == 'u') {
Steve Fink65b53df2006-09-25 02:27:08 +0200392 info.type = ARGTYPE_LONG;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100393 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100394 len +=
395 fprintf(output, ", %u",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200396 (int)gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100397 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100398 len +=
399 fprintf(output, ", %lu",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200400 gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200401 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100402 } else if (c == 'o') {
Steve Fink65b53df2006-09-25 02:27:08 +0200403 info.type = ARGTYPE_LONG;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100404 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100405 len +=
406 fprintf(output, ", 0%o",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200407 (int)gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100408 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100409 len +=
410 fprintf(output, ", 0%lo",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200411 gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200412 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100413 } else if (c == 'x' || c == 'X') {
Steve Fink65b53df2006-09-25 02:27:08 +0200414 info.type = ARGTYPE_LONG;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100415 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100416 len +=
417 fprintf(output, ", %#x",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200418 (int)gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100419 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100420 len +=
421 fprintf(output, ", %#lx",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200422 gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100423 break;
424 } else if (strchr("eEfFgGaACS", c)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100425 || (is_long
426 && (c == 'c' || c == 's'))) {
Juan Cespedesd914a202004-11-10 00:15:33 +0100427 len += fprintf(output, ", ...");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100428 str1[i + 1] = '\0';
Juan Cespedesac3db291998-04-25 14:31:58 +0200429 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100430 } else if (c == 'c') {
Steve Fink65b53df2006-09-25 02:27:08 +0200431 info.type = ARGTYPE_LONG;
Juan Cespedesac3db291998-04-25 14:31:58 +0200432 len += fprintf(output, ", '");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100433 len +=
434 display_char((int)
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200435 gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200436 len += fprintf(output, "'");
437 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100438 } else if (c == 's') {
Steve Fink65b53df2006-09-25 02:27:08 +0200439 info.type = ARGTYPE_POINTER;
Juan Cespedesac3db291998-04-25 14:31:58 +0200440 len += fprintf(output, ", ");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100441 len +=
442 display_string(type, proc,
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200443 (void *)gimme_arg(type, proc, ++arg_num, &info),
Steve Fink6a48a6d2006-08-07 04:29:06 +0200444 string_maxlength);
Juan Cespedesac3db291998-04-25 14:31:58 +0200445 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100446 } else if (c == 'p' || c == 'n') {
Steve Fink65b53df2006-09-25 02:27:08 +0200447 info.type = ARGTYPE_POINTER;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100448 len +=
449 fprintf(output, ", %p",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200450 (void *)gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200451 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100452 } else if (c == '*') {
Steve Fink65b53df2006-09-25 02:27:08 +0200453 info.type = ARGTYPE_LONG;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100454 len +=
455 fprintf(output, ", %d",
Juan Cespedesa413e5b2007-09-04 17:34:53 +0200456 (int)gimme_arg(type, proc, ++arg_num, &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200457 }
458 }
459 }
460 }
461 free(str1);
462 return len;
463}