~ubuntu-branches/ubuntu/natty/ltrace/natty

« back to all changes in this revision

Viewing changes to display_args.c

  • Committer: Bazaar Package Importer
  • Author(s): Bhavani Shankar, Colin Watson
  • Date: 2009-01-06 17:46:28 UTC
  • mfrom: (1.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090106174628-pt1541aq1ykev7m1
Tags: 0.5.1-2ubuntu1
[ Bhavani Shankar ]
* Merge from debian unstable, remaining changes: LP: #313530
  - Add lpia to architecture list.
  - Use libelf-dev instead of libelfg0-dev
  - Define _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE in debian/rules CFLAGS.
    The configure script has a bug where it can't properly cope with the need
    to define these before detecting the use of elfutils.

[ Colin Watson ]
* Remove stray dpatch build-dependency.
* Change libelfg0-dev to libelf-dev in debian/control.in as well as in
  debian/control.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
#include "config.h"
3
3
#endif
4
4
 
 
5
#include <ctype.h>
5
6
#include <stdio.h>
6
7
#include <stdlib.h>
7
8
#include <string.h>
11
12
#include "options.h"
12
13
 
13
14
static int display_char(int what);
14
 
static int display_string(enum tof type, struct process *proc, int arg_num);
15
 
static int display_stringN(int arg2, enum tof type, struct process *proc,
16
 
                           int arg_num);
17
 
static int display_unknown(enum tof type, struct process *proc, int arg_num);
 
15
static int display_string(enum tof type, struct process *proc,
 
16
                          void* addr, size_t maxlen);
 
17
static int display_value(enum tof type, struct process *proc,
 
18
                         long value, arg_type_info *info,
 
19
                         void *st, arg_type_info* st_info);
 
20
static int display_unknown(enum tof type, struct process *proc, long value);
18
21
static int display_format(enum tof type, struct process *proc, int arg_num);
19
22
 
20
 
int
21
 
display_arg(enum tof type, struct process *proc, int arg_num, enum arg_type at)
 
23
static int string_maxlength = INT_MAX;
 
24
static int array_maxlength = INT_MAX;
 
25
 
 
26
static long get_length(enum tof type, struct process *proc, int len_spec,
 
27
                       void *st, arg_type_info* st_info)
 
28
{
 
29
        long len;
 
30
        arg_type_info info;
 
31
 
 
32
        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],
 
36
                           &len, st_info->u.struct_info.fields[-len_spec-1]);
 
37
                return len;
 
38
        }
 
39
 
 
40
        info.type = ARGTYPE_INT;
 
41
        return gimme_arg(type, proc, -len_spec-1, &info);
 
42
}
 
43
 
 
44
static int display_ptrto(enum tof type, struct process *proc, long item,
 
45
                         arg_type_info * info,
 
46
                         void *st, arg_type_info* st_info)
 
47
{
 
48
        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);
 
52
}
 
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
 */
 
62
static int display_arrayptr(enum tof type, struct process *proc,
 
63
                            void *addr, arg_type_info * info,
 
64
                            void *st, arg_type_info* st_info)
 
65
{
 
66
        int len = 0;
 
67
        int i;
 
68
        int array_len;
 
69
 
 
70
        if (addr == NULL)
 
71
                return fprintf(output, "NULL");
 
72
 
 
73
        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;
 
91
}
 
92
 
 
93
/* addr - A pointer to the beginning of the memory region occupied by
 
94
 *        the struct (aka a pointer to the struct)
 
95
 */
 
96
static 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
 
 
124
static int display_pointer(enum tof type, struct process *proc, long value,
 
125
                           arg_type_info * info,
 
126
                           void *st, arg_type_info* st_info)
 
127
{
 
128
        long pointed_to;
 
129
        arg_type_info *inner = info->u.ptr_info.info;
 
130
 
 
131
        if (inner->type == ARGTYPE_ARRAY) {
 
132
                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);
 
136
        } else {
 
137
                if (value == 0)
 
138
                        return fprintf(output, "NULL");
 
139
                else if (umovelong (proc, (void *) value, &pointed_to,
 
140
                                    info->u.ptr_info.info) < 0)
 
141
                        return fprintf(output, "?");
 
142
                else
 
143
                        return display_value(type, proc, pointed_to, inner,
 
144
                                        st, st_info);
 
145
        }
 
146
}
 
147
 
 
148
static int display_enum(enum tof type, struct process *proc,
 
149
                arg_type_info* info, long value)
 
150
{
 
151
        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
        }
 
156
 
 
157
        return display_unknown(type, proc, value);
 
158
}
 
159
 
 
160
/* 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
 
165
   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.
 
170
*/
 
171
int display_value(enum tof type, struct process *proc,
 
172
                long value, arg_type_info *info,
 
173
                void *st, arg_type_info* st_info)
22
174
{
23
175
        int tmp;
24
 
        long arg;
25
176
 
26
 
        switch (at) {
 
177
        switch (info->type) {
27
178
        case ARGTYPE_VOID:
28
179
                return 0;
29
180
        case ARGTYPE_INT:
30
 
                return fprintf(output, "%d",
31
 
                               (int)gimme_arg(type, proc, arg_num));
 
181
                return fprintf(output, "%d", (int) value);
32
182
        case ARGTYPE_UINT:
33
 
                return fprintf(output, "%u",
34
 
                               (unsigned)gimme_arg(type, proc, arg_num));
 
183
                return fprintf(output, "%u", (unsigned) value);
35
184
        case ARGTYPE_LONG:
36
185
                if (proc->mask_32bit)
37
 
                        return fprintf(output, "%d",
38
 
                                       (int)gimme_arg(type, proc, arg_num));
39
 
                return fprintf(output, "%ld", gimme_arg(type, proc, arg_num));
 
186
                        return fprintf(output, "%d", (int) value);
 
187
                else
 
188
                        return fprintf(output, "%ld", value);
40
189
        case ARGTYPE_ULONG:
41
190
                if (proc->mask_32bit)
42
 
                        return fprintf(output, "%u",
43
 
                                       (unsigned)gimme_arg(type, proc,
44
 
                                                           arg_num));
45
 
                return fprintf(output, "%lu",
46
 
                               (unsigned long)gimme_arg(type, proc, arg_num));
 
191
                        return fprintf(output, "%u", (unsigned) value);
 
192
                else
 
193
                        return fprintf(output, "%lu", (unsigned long) value);
47
194
        case ARGTYPE_OCTAL:
48
 
                return fprintf(output, "0%o",
49
 
                               (unsigned)gimme_arg(type, proc, arg_num));
 
195
                return fprintf(output, "0%o", (unsigned) value);
50
196
        case ARGTYPE_CHAR:
51
197
                tmp = fprintf(output, "'");
52
 
                tmp += display_char((int)gimme_arg(type, proc, arg_num));
 
198
                tmp += display_char(value == -1 ? value : (char) value);
53
199
                tmp += fprintf(output, "'");
54
200
                return tmp;
 
201
        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: {
 
206
                union { long l; float f; double d; } cvt;
 
207
                cvt.l = value;
 
208
                return fprintf(output, "%f", cvt.f);
 
209
        }
 
210
        case ARGTYPE_DOUBLE: {
 
211
                union { long l; float f; double d; } cvt;
 
212
                cvt.l = value;
 
213
                return fprintf(output, "%lf", cvt.d);
 
214
        }
55
215
        case ARGTYPE_ADDR:
56
 
                arg = gimme_arg(type, proc, arg_num);
57
 
                if (!arg) {
 
216
                if (!value)
58
217
                        return fprintf(output, "NULL");
59
 
                } else {
60
 
                        return fprintf(output, "%p", (void *)arg);
61
 
                }
 
218
                else
 
219
                        return fprintf(output, "0x%08lx", value);
62
220
        case ARGTYPE_FORMAT:
63
 
                return display_format(type, proc, arg_num);
 
221
                fprintf(stderr, "Should never encounter a format anywhere but at the top level (for now?)\n");
 
222
                exit(1);
64
223
        case ARGTYPE_STRING:
65
 
                return display_string(type, proc, arg_num);
66
 
        case ARGTYPE_STRING0:
67
 
                return display_stringN(0, type, proc, arg_num);
68
 
        case ARGTYPE_STRING1:
69
 
                return display_stringN(1, type, proc, arg_num);
70
 
        case ARGTYPE_STRING2:
71
 
                return display_stringN(2, type, proc, arg_num);
72
 
        case ARGTYPE_STRING3:
73
 
                return display_stringN(3, type, proc, arg_num);
74
 
        case ARGTYPE_STRING4:
75
 
                return display_stringN(4, type, proc, arg_num);
76
 
        case ARGTYPE_STRING5:
77
 
                return display_stringN(5, type, proc, arg_num);
 
224
                return display_string(type, proc, (void*) value,
 
225
                                      string_maxlength);
 
226
        case ARGTYPE_STRING_N:
 
227
                return display_string(type, proc, (void*) value,
 
228
                                      get_length(type, proc,
 
229
                                                 info->u.string_n_info.size_spec, st, st_info));
 
230
        case ARGTYPE_ARRAY:
 
231
                return fprintf(output, "<array without address>");
 
232
        case ARGTYPE_ENUM:
 
233
                return display_enum(type, proc, info, value);
 
234
        case ARGTYPE_STRUCT:
 
235
                return fprintf(output, "<struct without address>");
 
236
        case ARGTYPE_POINTER:
 
237
                return display_pointer(type, proc, value, info,
 
238
                                       st, st_info);
78
239
        case ARGTYPE_UNKNOWN:
79
240
        default:
80
 
                return display_unknown(type, proc, arg_num);
81
 
        }
82
 
        return fprintf(output, "?");
 
241
                return display_unknown(type, proc, value);
 
242
        }
 
243
}
 
244
 
 
245
int display_arg(enum tof type, struct process *proc, int arg_num, arg_type_info * info)
 
246
{
 
247
        long arg;
 
248
 
 
249
        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
        }
83
257
}
84
258
 
85
259
static int display_char(int what)
98
272
        case '\\':
99
273
                return fprintf(output, "\\\\");
100
274
        default:
101
 
                if ((what < 32) || (what > 126)) {
 
275
                if (isprint(what)) {
 
276
                        return fprintf(output, "%c", what);
 
277
                } else {
102
278
                        return fprintf(output, "\\%03o", (unsigned char)what);
103
 
                } else {
104
 
                        return fprintf(output, "%c", what);
105
279
                }
106
280
        }
107
281
}
108
282
 
109
 
static int string_maxlength = INT_MAX;
110
 
 
111
283
#define MIN(a,b) (((a)<(b)) ? (a) : (b))
112
284
 
113
 
static int display_string(enum tof type, struct process *proc, int arg_num)
 
285
static int display_string(enum tof type, struct process *proc, void *addr,
 
286
                          size_t maxlength)
114
287
{
115
 
        void *addr;
116
288
        unsigned char *str1;
117
289
        int i;
118
290
        int len = 0;
119
291
 
120
 
        addr = (void *)gimme_arg(type, proc, arg_num);
121
292
        if (!addr) {
122
293
                return fprintf(output, "NULL");
123
294
        }
124
295
 
125
 
        str1 = malloc(MIN(opt_s, string_maxlength) + 3);
 
296
        str1 = malloc(MIN(opt_s, maxlength) + 3);
126
297
        if (!str1) {
127
298
                return fprintf(output, "???");
128
299
        }
129
 
        umovestr(proc, addr, MIN(opt_s, string_maxlength) + 1, str1);
 
300
        umovestr(proc, addr, MIN(opt_s, maxlength) + 1, str1);
130
301
        len = fprintf(output, "\"");
131
 
        for (i = 0; i < MIN(opt_s, string_maxlength); i++) {
 
302
        for (i = 0; i < MIN(opt_s, maxlength); i++) {
132
303
                if (str1[i]) {
133
304
                        len += display_char(str1[i]);
134
305
                } else {
136
307
                }
137
308
        }
138
309
        len += fprintf(output, "\"");
139
 
        if (str1[i] && (opt_s <= string_maxlength)) {
 
310
        if (str1[i] && (opt_s <= maxlength)) {
140
311
                len += fprintf(output, "...");
141
312
        }
142
313
        free(str1);
143
314
        return len;
144
315
}
145
316
 
146
 
static int
147
 
display_stringN(int arg2, enum tof type, struct process *proc, int arg_num)
148
 
{
149
 
        int a;
150
 
 
151
 
        string_maxlength = gimme_arg(type, proc, arg2 - 1);
152
 
        a = display_string(type, proc, arg_num);
153
 
        string_maxlength = INT_MAX;
154
 
        return a;
155
 
}
156
 
 
157
 
static int display_unknown(enum tof type, struct process *proc, int arg_num)
158
 
{
159
 
        long tmp;
160
 
 
161
 
        tmp = gimme_arg(type, proc, arg_num);
162
 
 
 
317
static int display_unknown(enum tof type, struct process *proc, long value)
 
318
{
163
319
        if (proc->mask_32bit) {
164
 
                if ((int)tmp < 1000000 && (int)tmp > -1000000)
165
 
                        return fprintf(output, "%d", (int)tmp);
 
320
                if ((int)value < 1000000 && (int)value > -1000000)
 
321
                        return fprintf(output, "%d", (int)value);
166
322
                else
167
 
                        return fprintf(output, "%p", (void *)tmp);
168
 
        } else if (tmp < 1000000 && tmp > -1000000) {
169
 
                return fprintf(output, "%ld", tmp);
 
323
                        return fprintf(output, "%p", (void *)value);
 
324
        } else if (value < 1000000 && value > -1000000) {
 
325
                return fprintf(output, "%ld", value);
170
326
        } else {
171
 
                return fprintf(output, "%p", (void *)tmp);
 
327
                return fprintf(output, "%p", (void *)value);
172
328
        }
173
329
}
174
330
 
178
334
        unsigned char *str1;
179
335
        int i;
180
336
        int len = 0;
 
337
        arg_type_info info;
181
338
 
182
 
        addr = (void *)gimme_arg(type, proc, arg_num);
 
339
        info.type = ARGTYPE_POINTER;
 
340
        addr = (void *)gimme_arg(type, proc, arg_num, &info);
183
341
        if (!addr) {
184
342
                return fprintf(output, "NULL");
185
343
        }
222
380
                                                break;
223
381
                                        }
224
382
                                } else if (c == 'd' || c == 'i') {
 
383
                                        info.type = ARGTYPE_LONG;
225
384
                                        if (!is_long || proc->mask_32bit)
226
385
                                                len +=
227
386
                                                    fprintf(output, ", %d",
228
 
                                                            (int)gimme_arg(type,
229
 
                                                                           proc,
230
 
                                                                           ++arg_num));
 
387
                                                            (int)gimme_arg(type, proc, ++arg_num, &info));
231
388
                                        else
232
389
                                                len +=
233
390
                                                    fprintf(output, ", %ld",
234
 
                                                            gimme_arg(type,
235
 
                                                                      proc,
236
 
                                                                      ++arg_num));
 
391
                                                            gimme_arg(type, proc, ++arg_num, &info));
237
392
                                        break;
238
393
                                } else if (c == 'u') {
 
394
                                        info.type = ARGTYPE_LONG;
239
395
                                        if (!is_long || proc->mask_32bit)
240
396
                                                len +=
241
397
                                                    fprintf(output, ", %u",
242
 
                                                            (int)gimme_arg(type,
243
 
                                                                           proc,
244
 
                                                                           ++arg_num));
 
398
                                                            (int)gimme_arg(type, proc, ++arg_num, &info));
245
399
                                        else
246
400
                                                len +=
247
401
                                                    fprintf(output, ", %lu",
248
 
                                                            gimme_arg(type,
249
 
                                                                      proc,
250
 
                                                                      ++arg_num));
 
402
                                                            gimme_arg(type, proc, ++arg_num, &info));
251
403
                                        break;
252
404
                                } else if (c == 'o') {
 
405
                                        info.type = ARGTYPE_LONG;
253
406
                                        if (!is_long || proc->mask_32bit)
254
407
                                                len +=
255
408
                                                    fprintf(output, ", 0%o",
256
 
                                                            (int)gimme_arg(type,
257
 
                                                                           proc,
258
 
                                                                           ++arg_num));
 
409
                                                            (int)gimme_arg(type, proc, ++arg_num, &info));
259
410
                                        else
260
411
                                                len +=
261
412
                                                    fprintf(output, ", 0%lo",
262
 
                                                            gimme_arg(type,
263
 
                                                                      proc,
264
 
                                                                      ++arg_num));
 
413
                                                            gimme_arg(type, proc, ++arg_num, &info));
265
414
                                        break;
266
415
                                } else if (c == 'x' || c == 'X') {
 
416
                                        info.type = ARGTYPE_LONG;
267
417
                                        if (!is_long || proc->mask_32bit)
268
418
                                                len +=
269
419
                                                    fprintf(output, ", %#x",
270
 
                                                            (int)gimme_arg(type,
271
 
                                                                           proc,
272
 
                                                                           ++arg_num));
 
420
                                                            (int)gimme_arg(type, proc, ++arg_num, &info));
273
421
                                        else
274
422
                                                len +=
275
423
                                                    fprintf(output, ", %#lx",
276
 
                                                            gimme_arg(type,
277
 
                                                                      proc,
278
 
                                                                      ++arg_num));
 
424
                                                            gimme_arg(type, proc, ++arg_num, &info));
279
425
                                        break;
280
426
                                } else if (strchr("eEfFgGaACS", c)
281
427
                                           || (is_long
284
430
                                        str1[i + 1] = '\0';
285
431
                                        break;
286
432
                                } else if (c == 'c') {
 
433
                                        info.type = ARGTYPE_LONG;
287
434
                                        len += fprintf(output, ", '");
288
435
                                        len +=
289
436
                                            display_char((int)
290
 
                                                         gimme_arg(type, proc,
291
 
                                                                   ++arg_num));
 
437
                                                         gimme_arg(type, proc, ++arg_num, &info));
292
438
                                        len += fprintf(output, "'");
293
439
                                        break;
294
440
                                } else if (c == 's') {
 
441
                                        info.type = ARGTYPE_POINTER;
295
442
                                        len += fprintf(output, ", ");
296
443
                                        len +=
297
444
                                            display_string(type, proc,
298
 
                                                           ++arg_num);
 
445
                                                           (void *)gimme_arg(type, proc, ++arg_num, &info),
 
446
                                                           string_maxlength);
299
447
                                        break;
300
448
                                } else if (c == 'p' || c == 'n') {
 
449
                                        info.type = ARGTYPE_POINTER;
301
450
                                        len +=
302
451
                                            fprintf(output, ", %p",
303
 
                                                    (void *)gimme_arg(type,
304
 
                                                                      proc,
305
 
                                                                      ++arg_num));
 
452
                                                    (void *)gimme_arg(type, proc, ++arg_num, &info));
306
453
                                        break;
307
454
                                } else if (c == '*') {
 
455
                                        info.type = ARGTYPE_LONG;
308
456
                                        len +=
309
457
                                            fprintf(output, ", %d",
310
 
                                                    (int)gimme_arg(type, proc,
311
 
                                                                   ++arg_num));
 
458
                                                    (int)gimme_arg(type, proc, ++arg_num, &info));
312
459
                                }
313
460
                        }
314
461
                }