blob: 08c735a3a72807e9100dd1c1e0a8d37a8b601986 [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{
Steve Finke4b32632006-08-07 06:10:08 +020029 long len;
Steve Fink65b53df2006-09-25 02:27:08 +020030 arg_type_info info;
31
Steve Fink6a48a6d2006-08-07 04:29:06 +020032 if (len_spec > 0)
33 return len_spec;
Steve Finke4b32632006-08-07 06:10:08 +020034 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
39 info.arg_num = -len_spec - 1;
40 info.type = ARGTYPE_INT;
41 return gimme_arg(type, proc, &info);
Steve Fink6a48a6d2006-08-07 04:29:06 +020042}
43
Steve Fink1150bc42006-08-07 06:04:43 +020044static int display_ptrto(enum tof type, struct process *proc, long item,
Steve Finke4b32632006-08-07 06:10:08 +020045 arg_type_info * info,
46 void *st, arg_type_info* st_info)
Steve Fink1150bc42006-08-07 06:04:43 +020047{
48 arg_type_info temp;
49 temp.type = ARGTYPE_POINTER;
50 temp.u.ptr_info.info = info;
Steve Finke4b32632006-08-07 06:10:08 +020051 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 */
62static int display_arrayptr(enum tof type, struct process *proc,
Steve Finke4b32632006-08-07 06:10:08 +020063 void *addr, arg_type_info * info,
64 void *st, arg_type_info* st_info)
Steve Fink1150bc42006-08-07 06:04:43 +020065{
66 int len = 0;
67 int i;
68 int array_len;
69
70 if (addr == NULL)
71 return fprintf(output, "NULL");
72
Steve Finke4b32632006-08-07 06:10:08 +020073 array_len = get_length(type, proc, info->u.array_info.len_spec,
74 st, st_info);
Steve Fink1150bc42006-08-07 06:04:43 +020075 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 +=
Steve Finke4b32632006-08-07 06:10:08 +020084 display_ptrto(type, proc, (long) addr, elt_type, st, st_info);
Steve Fink1150bc42006-08-07 06:04:43 +020085 addr += elt_size;
86 }
87 if (i < array_len)
88 len += fprintf(output, "...");
89 len += fprintf(output, " ]");
90 return len;
91}
92
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 */
96static int display_structptr(enum tof type, struct process *proc,
97 void *addr, arg_type_info * info)
98{
99 int i;
100 arg_type_info *field;
101 int len = 0;
102
103 if (addr == NULL)
104 return fprintf(output, "NULL");
105
106 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, " }");
120
121 return len;
122}
123
Steve Fink7bafff02006-08-07 04:50:42 +0200124static int display_pointer(enum tof type, struct process *proc, long value,
Steve Finke4b32632006-08-07 06:10:08 +0200125 arg_type_info * info,
126 void *st, arg_type_info* st_info)
Steve Fink7bafff02006-08-07 04:50:42 +0200127{
128 long pointed_to;
129 arg_type_info *inner = info->u.ptr_info.info;
130
Steve Fink1150bc42006-08-07 06:04:43 +0200131 if (inner->type == ARGTYPE_ARRAY) {
Steve Finke4b32632006-08-07 06:10:08 +0200132 return display_arrayptr(type, proc, (void*) value, inner,
133 st, st_info);
134 } else if (inner->type == ARGTYPE_STRUCT) {
135 return display_structptr(type, proc, (void *) value, inner);
Steve Fink1150bc42006-08-07 06:04:43 +0200136 } else {
137 if (value == 0)
138 return fprintf(output, "NULL");
139 else if (umovelong(proc, (void *) value, &pointed_to) < 0)
140 return fprintf(output, "?");
141 else
Steve Finke4b32632006-08-07 06:10:08 +0200142 return display_value(type, proc, pointed_to, inner,
143 st, st_info);
Steve Fink1150bc42006-08-07 06:04:43 +0200144 }
Steve Fink7bafff02006-08-07 04:50:42 +0200145}
146
Steve Fink6a3e24d2006-08-07 05:53:19 +0200147static int display_enum(enum tof type, struct process *proc,
148 arg_type_info* info, long value)
149{
150 int ii;
151 for (ii = 0; ii < info->u.enum_info.entries; ++ii) {
152 if (info->u.enum_info.values[ii] == value)
153 return fprintf(output, "%s", info->u.enum_info.keys[ii]);
154 }
155
156 return display_unknown(type, proc, value);
157}
158
Steve Fink7bafff02006-08-07 04:50:42 +0200159/* Args:
160 type - syscall or shared library function or memory
161 proc - information about the traced process
162 value - the value to display
163 info - the description of the type to display
Steve Finke4b32632006-08-07 06:10:08 +0200164 st - if the current value is a struct member, the address of the struct
165 st_info - type of the above struct
166
167 Those last two parameters are used for structs containing arrays or
168 strings whose length is given by another structure element.
Steve Fink7bafff02006-08-07 04:50:42 +0200169*/
170int display_value(enum tof type, struct process *proc,
Steve Finke4b32632006-08-07 06:10:08 +0200171 long value, arg_type_info *info,
172 void *st, arg_type_info* st_info)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100173{
Juan Cespedes5e01f651998-03-08 22:31:44 +0100174 int tmp;
Juan Cespedes5e01f651998-03-08 22:31:44 +0100175
Steve Fink6a48a6d2006-08-07 04:29:06 +0200176 switch (info->type) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100177 case ARGTYPE_VOID:
178 return 0;
Steve Fink6b175832006-08-07 04:37:33 +0200179 case ARGTYPE_IGNORE:
180 return 0; /* Empty gap between commas */
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100181 case ARGTYPE_INT:
Steve Fink7bafff02006-08-07 04:50:42 +0200182 return fprintf(output, "%d", (int) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100183 case ARGTYPE_UINT:
Steve Fink7bafff02006-08-07 04:50:42 +0200184 return fprintf(output, "%u", (unsigned) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100185 case ARGTYPE_LONG:
186 if (proc->mask_32bit)
Steve Fink7bafff02006-08-07 04:50:42 +0200187 return fprintf(output, "%d", (int) value);
188 else
189 return fprintf(output, "%ld", value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100190 case ARGTYPE_ULONG:
191 if (proc->mask_32bit)
Steve Fink7bafff02006-08-07 04:50:42 +0200192 return fprintf(output, "%u", (unsigned) value);
193 else
194 return fprintf(output, "%lu", (unsigned long) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100195 case ARGTYPE_OCTAL:
Steve Fink7bafff02006-08-07 04:50:42 +0200196 return fprintf(output, "0%o", (unsigned) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100197 case ARGTYPE_CHAR:
198 tmp = fprintf(output, "'");
Steve Fink7bafff02006-08-07 04:50:42 +0200199 tmp += display_char(value == -1 ? value : (char) value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100200 tmp += fprintf(output, "'");
201 return tmp;
Steve Fink6fa27c32006-08-07 05:56:56 +0200202 case ARGTYPE_SHORT:
203 return fprintf(output, "%hd", (short) value);
204 case ARGTYPE_USHORT:
205 return fprintf(output, "%hu", (unsigned short) value);
206 case ARGTYPE_FLOAT: {
Steve Fink65b53df2006-09-25 02:27:08 +0200207 union { long l; float f; double d; } cvt;
Steve Fink6fa27c32006-08-07 05:56:56 +0200208 cvt.l = value;
209 return fprintf(output, "%f", cvt.f);
210 }
Steve Fink65b53df2006-09-25 02:27:08 +0200211 case ARGTYPE_DOUBLE: {
212 union { long l; float f; double d; } cvt;
213 cvt.l = value;
214 return fprintf(output, "%lf", cvt.d);
215 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100216 case ARGTYPE_ADDR:
Steve Fink7bafff02006-08-07 04:50:42 +0200217 if (!value)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100218 return fprintf(output, "NULL");
Steve Fink7bafff02006-08-07 04:50:42 +0200219 else
220 return fprintf(output, "0x%08lx", value);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100221 case ARGTYPE_FORMAT:
Steve Fink7bafff02006-08-07 04:50:42 +0200222 fprintf(stderr, "Should never encounter a format anywhere but at the top level (for now?)\n");
223 exit(1);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100224 case ARGTYPE_STRING:
Steve Fink7bafff02006-08-07 04:50:42 +0200225 return display_string(type, proc, (void*) value,
Steve Fink6a48a6d2006-08-07 04:29:06 +0200226 string_maxlength);
227 case ARGTYPE_STRING_N:
Steve Fink7bafff02006-08-07 04:50:42 +0200228 return display_string(type, proc, (void*) value,
Steve Fink6a48a6d2006-08-07 04:29:06 +0200229 get_length(type, proc,
Steve Finke4b32632006-08-07 06:10:08 +0200230 info->u.string_n_info.size_spec, st, st_info));
Steve Fink1150bc42006-08-07 06:04:43 +0200231 case ARGTYPE_ARRAY:
232 return fprintf(output, "<array without address>");
Steve Fink6a3e24d2006-08-07 05:53:19 +0200233 case ARGTYPE_ENUM:
234 return display_enum(type, proc, info, value);
Steve Finke4b32632006-08-07 06:10:08 +0200235 case ARGTYPE_STRUCT:
236 return fprintf(output, "<struct without address>");
Steve Fink7bafff02006-08-07 04:50:42 +0200237 case ARGTYPE_POINTER:
Steve Finke4b32632006-08-07 06:10:08 +0200238 return display_pointer(type, proc, value, info,
239 st, st_info);
Steve Fink7bafff02006-08-07 04:50:42 +0200240 case ARGTYPE_UNKNOWN:
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100241 default:
Steve Fink7bafff02006-08-07 04:50:42 +0200242 return display_unknown(type, proc, value);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100243 }
Steve Fink7bafff02006-08-07 04:50:42 +0200244}
245
Steve Fink65b53df2006-09-25 02:27:08 +0200246int display_arg(enum tof type, struct process *proc, arg_type_info * info)
Steve Fink7bafff02006-08-07 04:50:42 +0200247{
248 long arg;
249
250 if (info->type == ARGTYPE_VOID) {
251 return 0;
252 } else if (info->type == ARGTYPE_FORMAT) {
Steve Fink65b53df2006-09-25 02:27:08 +0200253 return display_format(type, proc, info->arg_num);
Steve Fink7bafff02006-08-07 04:50:42 +0200254 } else {
Steve Fink65b53df2006-09-25 02:27:08 +0200255 arg = gimme_arg(type, proc, info);
Steve Finke4b32632006-08-07 06:10:08 +0200256 return display_value(type, proc, arg, info, NULL, NULL);
Steve Fink7bafff02006-08-07 04:50:42 +0200257 }
Juan Cespedes5e01f651998-03-08 22:31:44 +0100258}
259
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100260static int display_char(int what)
261{
262 switch (what) {
263 case -1:
264 return fprintf(output, "EOF");
265 case '\r':
266 return fprintf(output, "\\r");
267 case '\n':
268 return fprintf(output, "\\n");
269 case '\t':
270 return fprintf(output, "\\t");
271 case '\b':
272 return fprintf(output, "\\b");
273 case '\\':
274 return fprintf(output, "\\\\");
275 default:
Steve Fink7bafff02006-08-07 04:50:42 +0200276 if (isprint(what)) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100277 return fprintf(output, "%c", what);
Steve Fink7bafff02006-08-07 04:50:42 +0200278 } else {
279 return fprintf(output, "\\%03o", (unsigned char)what);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100280 }
Juan Cespedes5e01f651998-03-08 22:31:44 +0100281 }
282}
283
Juan Cespedes2c4a8cb1998-03-11 23:33:18 +0100284#define MIN(a,b) (((a)<(b)) ? (a) : (b))
285
Steve Fink7bafff02006-08-07 04:50:42 +0200286static int display_string(enum tof type, struct process *proc, void *addr,
287 size_t maxlength)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100288{
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100289 unsigned char *str1;
Juan Cespedes5e01f651998-03-08 22:31:44 +0100290 int i;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100291 int len = 0;
Juan Cespedes5e01f651998-03-08 22:31:44 +0100292
Juan Cespedes5e01f651998-03-08 22:31:44 +0100293 if (!addr) {
294 return fprintf(output, "NULL");
295 }
296
Steve Fink6a48a6d2006-08-07 04:29:06 +0200297 str1 = malloc(MIN(opt_s, maxlength) + 3);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100298 if (!str1) {
299 return fprintf(output, "???");
300 }
Steve Fink6a48a6d2006-08-07 04:29:06 +0200301 umovestr(proc, addr, MIN(opt_s, maxlength) + 1, str1);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100302 len = fprintf(output, "\"");
Steve Fink6a48a6d2006-08-07 04:29:06 +0200303 for (i = 0; i < MIN(opt_s, maxlength); i++) {
Juan Cespedes5e01f651998-03-08 22:31:44 +0100304 if (str1[i]) {
305 len += display_char(str1[i]);
306 } else {
307 break;
308 }
309 }
310 len += fprintf(output, "\"");
Steve Fink6a48a6d2006-08-07 04:29:06 +0200311 if (str1[i] && (opt_s <= maxlength)) {
Juan Cespedes5e01f651998-03-08 22:31:44 +0100312 len += fprintf(output, "...");
313 }
314 free(str1);
315 return len;
316}
317
Steve Fink7bafff02006-08-07 04:50:42 +0200318static int display_unknown(enum tof type, struct process *proc, long value)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100319{
Ian Wienand9a2ad352006-02-20 22:44:45 +0100320 if (proc->mask_32bit) {
Steve Fink7bafff02006-08-07 04:50:42 +0200321 if ((int)value < 1000000 && (int)value > -1000000)
322 return fprintf(output, "%d", (int)value);
Ian Wienand9a2ad352006-02-20 22:44:45 +0100323 else
Steve Fink7bafff02006-08-07 04:50:42 +0200324 return fprintf(output, "%p", (void *)value);
325 } else if (value < 1000000 && value > -1000000) {
326 return fprintf(output, "%ld", value);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100327 } else {
Steve Fink7bafff02006-08-07 04:50:42 +0200328 return fprintf(output, "%p", (void *)value);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100329 }
330}
Juan Cespedesac3db291998-04-25 14:31:58 +0200331
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100332static int display_format(enum tof type, struct process *proc, int arg_num)
333{
334 void *addr;
335 unsigned char *str1;
Juan Cespedesac3db291998-04-25 14:31:58 +0200336 int i;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100337 int len = 0;
Steve Fink65b53df2006-09-25 02:27:08 +0200338 arg_type_info info;
Juan Cespedesac3db291998-04-25 14:31:58 +0200339
Steve Fink65b53df2006-09-25 02:27:08 +0200340 info.arg_num = arg_num;
341 info.type = ARGTYPE_POINTER;
342 addr = (void *)gimme_arg(type, proc, &info);
Juan Cespedesac3db291998-04-25 14:31:58 +0200343 if (!addr) {
344 return fprintf(output, "NULL");
345 }
346
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100347 str1 = malloc(MIN(opt_s, string_maxlength) + 3);
Juan Cespedesac3db291998-04-25 14:31:58 +0200348 if (!str1) {
349 return fprintf(output, "???");
350 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100351 umovestr(proc, addr, MIN(opt_s, string_maxlength) + 1, str1);
Juan Cespedesac3db291998-04-25 14:31:58 +0200352 len = fprintf(output, "\"");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100353 for (i = 0; len < MIN(opt_s, string_maxlength) + 1; i++) {
Juan Cespedesac3db291998-04-25 14:31:58 +0200354 if (str1[i]) {
355 len += display_char(str1[i]);
356 } else {
357 break;
358 }
359 }
360 len += fprintf(output, "\"");
361 if (str1[i] && (opt_s <= string_maxlength)) {
362 len += fprintf(output, "...");
363 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100364 for (i = 0; str1[i]; i++) {
365 if (str1[i] == '%') {
Juan Cespedesd914a202004-11-10 00:15:33 +0100366 int is_long = 0;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100367 while (1) {
Juan Cespedes5c3fe062004-06-14 18:08:37 +0200368 unsigned char c = str1[++i];
Juan Cespedesac3db291998-04-25 14:31:58 +0200369 if (c == '%') {
370 break;
371 } else if (!c) {
372 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100373 } else if (strchr("lzZtj", c)) {
Juan Cespedesd914a202004-11-10 00:15:33 +0100374 is_long++;
375 if (c == 'j')
376 is_long++;
Ian Wienand3219f322006-02-16 06:00:00 +0100377 if (is_long > 1
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100378 && (sizeof(long) < sizeof(long long)
379 || proc->mask_32bit)) {
Juan Cespedesd914a202004-11-10 00:15:33 +0100380 len += fprintf(output, ", ...");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100381 str1[i + 1] = '\0';
Juan Cespedesd914a202004-11-10 00:15:33 +0100382 break;
383 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100384 } else if (c == 'd' || c == 'i') {
Steve Fink65b53df2006-09-25 02:27:08 +0200385 info.arg_num = ++arg_num;
386 info.type = ARGTYPE_LONG;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100387 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100388 len +=
389 fprintf(output, ", %d",
390 (int)gimme_arg(type,
391 proc,
Steve Fink65b53df2006-09-25 02:27:08 +0200392 &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100393 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100394 len +=
395 fprintf(output, ", %ld",
396 gimme_arg(type,
397 proc,
Steve Fink65b53df2006-09-25 02:27:08 +0200398 &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200399 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100400 } else if (c == 'u') {
Steve Fink65b53df2006-09-25 02:27:08 +0200401 info.arg_num = ++arg_num;
402 info.type = ARGTYPE_LONG;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100403 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100404 len +=
405 fprintf(output, ", %u",
406 (int)gimme_arg(type,
407 proc,
Steve Fink65b53df2006-09-25 02:27:08 +0200408 &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100409 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100410 len +=
411 fprintf(output, ", %lu",
412 gimme_arg(type,
413 proc,
Steve Fink65b53df2006-09-25 02:27:08 +0200414 &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200415 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100416 } else if (c == 'o') {
Steve Fink65b53df2006-09-25 02:27:08 +0200417 info.arg_num = ++arg_num;
418 info.type = ARGTYPE_LONG;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100419 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100420 len +=
421 fprintf(output, ", 0%o",
422 (int)gimme_arg(type,
423 proc,
Steve Fink65b53df2006-09-25 02:27:08 +0200424 &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100425 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100426 len +=
427 fprintf(output, ", 0%lo",
428 gimme_arg(type,
429 proc,
Steve Fink65b53df2006-09-25 02:27:08 +0200430 &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200431 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100432 } else if (c == 'x' || c == 'X') {
Steve Fink65b53df2006-09-25 02:27:08 +0200433 info.arg_num = ++arg_num;
434 info.type = ARGTYPE_LONG;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100435 if (!is_long || proc->mask_32bit)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100436 len +=
437 fprintf(output, ", %#x",
438 (int)gimme_arg(type,
439 proc,
Steve Fink65b53df2006-09-25 02:27:08 +0200440 &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100441 else
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100442 len +=
443 fprintf(output, ", %#lx",
444 gimme_arg(type,
445 proc,
Steve Fink65b53df2006-09-25 02:27:08 +0200446 &info));
Juan Cespedesd914a202004-11-10 00:15:33 +0100447 break;
448 } else if (strchr("eEfFgGaACS", c)
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100449 || (is_long
450 && (c == 'c' || c == 's'))) {
Juan Cespedesd914a202004-11-10 00:15:33 +0100451 len += fprintf(output, ", ...");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100452 str1[i + 1] = '\0';
Juan Cespedesac3db291998-04-25 14:31:58 +0200453 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100454 } else if (c == 'c') {
Steve Fink65b53df2006-09-25 02:27:08 +0200455 info.arg_num = ++arg_num;
456 info.type = ARGTYPE_LONG;
Juan Cespedesac3db291998-04-25 14:31:58 +0200457 len += fprintf(output, ", '");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100458 len +=
459 display_char((int)
460 gimme_arg(type, proc,
Steve Fink65b53df2006-09-25 02:27:08 +0200461 &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200462 len += fprintf(output, "'");
463 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100464 } else if (c == 's') {
Steve Fink65b53df2006-09-25 02:27:08 +0200465 info.arg_num = ++arg_num;
466 info.type = ARGTYPE_POINTER;
Juan Cespedesac3db291998-04-25 14:31:58 +0200467 len += fprintf(output, ", ");
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100468 len +=
469 display_string(type, proc,
Steve Fink7bafff02006-08-07 04:50:42 +0200470 (void *)gimme_arg(type,
471 proc,
Steve Fink65b53df2006-09-25 02:27:08 +0200472 &info),
Steve Fink6a48a6d2006-08-07 04:29:06 +0200473 string_maxlength);
Juan Cespedesac3db291998-04-25 14:31:58 +0200474 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100475 } else if (c == 'p' || c == 'n') {
Steve Fink65b53df2006-09-25 02:27:08 +0200476 info.arg_num = ++arg_num;
477 info.type = ARGTYPE_POINTER;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100478 len +=
479 fprintf(output, ", %p",
480 (void *)gimme_arg(type,
481 proc,
Steve Fink65b53df2006-09-25 02:27:08 +0200482 &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200483 break;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100484 } else if (c == '*') {
Steve Fink65b53df2006-09-25 02:27:08 +0200485 info.arg_num = ++arg_num;
486 info.type = ARGTYPE_LONG;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100487 len +=
488 fprintf(output, ", %d",
489 (int)gimme_arg(type, proc,
Steve Fink65b53df2006-09-25 02:27:08 +0200490 &info));
Juan Cespedesac3db291998-04-25 14:31:58 +0200491 }
492 }
493 }
494 }
495 free(str1);
496 return len;
497}