Imported Upstream version 0.7.91
[platform/upstream/ltrace.git] / lens_default.c
1 /*
2  * This file is part of ltrace.
3  * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc.
4  * Copyright (C) 1998,2004,2007,2008,2009 Juan Cespedes
5  * Copyright (C) 2006 Ian Wienand
6  * Copyright (C) 2006 Steve Fink
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  */
23
24 #include <ctype.h>
25 #include <stdlib.h>
26 #include <assert.h>
27 #include <inttypes.h>
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <string.h>
31
32 #include "bits.h"
33 #include "proc.h"
34 #include "lens_default.h"
35 #include "value.h"
36 #include "expr.h"
37 #include "type.h"
38 #include "common.h"
39 #include "zero.h"
40
41 #define READER(NAME, TYPE)                                              \
42         static int                                                      \
43         NAME(struct value *value, TYPE *ret, struct value_dict *arguments) \
44         {                                                               \
45                 union {                                                 \
46                         TYPE val;                                       \
47                         unsigned char buf[0];                           \
48                 } u;                                                    \
49                 if (value_extract_buf(value, u.buf, arguments) < 0)     \
50                         return -1;                                      \
51                 *ret = u.val;                                           \
52                 return 0;                                               \
53         }
54
55 READER(read_float, float)
56 READER(read_double, double)
57
58 #undef READER
59
60 #define HANDLE_WIDTH(BITS)                                              \
61         do {                                                            \
62                 long l;                                                 \
63                 if (value_extract_word(value, &l, arguments) < 0)       \
64                         return -1;                                      \
65                 int##BITS##_t i = l;                                    \
66                 uint64_t v = (uint64_t)(uint##BITS##_t)i;               \
67                 switch (format) {                                       \
68                 case INT_FMT_unknown:                                   \
69                         if (l < -10000 || l > 10000)                    \
70                 case INT_FMT_x:                                         \
71                         return fprintf(stream, "%#"PRIx64, v);          \
72                 case INT_FMT_i:                                         \
73                 case INT_FMT_default:                                   \
74                         return fprintf(stream, "%"PRIi##BITS, i);       \
75                 case INT_FMT_u:                                         \
76                         return fprintf(stream, "%"PRIu64, v);           \
77                 case INT_FMT_o:                                         \
78                         return fprintf(stream, "0%"PRIo64, v);          \
79                 }                                                       \
80         } while (0)
81
82 enum int_fmt_t
83 {
84         INT_FMT_i,
85         INT_FMT_u,
86         INT_FMT_o,
87         INT_FMT_x,
88         INT_FMT_unknown,
89         INT_FMT_default,
90 };
91
92 static int
93 format_integer(FILE *stream, struct value *value, enum int_fmt_t format,
94                struct value_dict *arguments)
95 {
96         switch (type_sizeof(value->inferior, value->type)) {
97
98         case 1: HANDLE_WIDTH(8);
99         case 2: HANDLE_WIDTH(16);
100         case 4: HANDLE_WIDTH(32);
101         case 8: HANDLE_WIDTH(64);
102
103         default:
104                 assert(!"unsupported integer width");
105                 abort();
106
107         case -1:
108                 return -1;
109         }
110 }
111
112 #undef HANDLE_WIDTH
113
114 static int
115 acc_fprintf(int *countp, FILE *stream, const char *format, ...)
116 {
117         va_list pa;
118         va_start(pa, format);
119         int i = account_output(countp, vfprintf(stream, format, pa));
120         va_end(pa);
121
122         return i;
123 }
124
125 static int
126 format_char(FILE *stream, struct value *value, struct value_dict *arguments)
127 {
128         long lc;
129         if (value_extract_word(value, &lc, arguments) < 0)
130                 return -1;
131         int c = (int)lc;
132
133         const char *fmt;
134         switch (c) {
135         case -1:
136                 fmt = "EOF";
137                 break;
138         case 0:
139                 fmt = "\\0";
140                 break;
141         case '\a':
142                 fmt = "\\a";
143                 break;
144         case '\b':
145                 fmt = "\\b";
146                 break;
147         case '\t':
148                 fmt = "\\t";
149                 break;
150         case '\n':
151                 fmt = "\\n";
152                 break;
153         case '\v':
154                 fmt = "\\v";
155                 break;
156         case '\f':
157                 fmt = "\\f";
158                 break;
159         case '\r':
160                 fmt = "\\r";
161                 break;
162         case '\\':
163                 fmt = "\\\\";
164                 break;
165         default:
166                 if (isprint(c) || c == ' ')
167                         fmt = "%c";
168                 else
169                         fmt = "\\%03o";
170         }
171
172         return fprintf(stream, fmt, c);
173 }
174
175 static int
176 format_naked_char(FILE *stream, struct value *value,
177                   struct value_dict *arguments)
178 {
179         int written = 0;
180         if (acc_fprintf(&written, stream, "'") < 0
181             || account_output(&written,
182                               format_char(stream, value, arguments)) < 0
183             || acc_fprintf(&written, stream, "'") < 0)
184                 return -1;
185
186         return written;
187 }
188
189 static int
190 format_double(FILE *stream, double value, enum int_fmt_t format)
191 {
192         if (format == INT_FMT_x)
193                 return fprintf(stream, "%a", value);
194         else
195                 return fprintf(stream, "%f", value);
196 }
197
198 static int
199 format_floating(FILE *stream, struct value *value, struct value_dict *arguments,
200                 enum int_fmt_t format)
201 {
202         switch (value->type->type) {
203                 float f;
204                 double d;
205         case ARGTYPE_FLOAT:
206                 if (read_float(value, &f, arguments) < 0)
207                         return -1;
208                 return format_double(stream, f, format);
209         case ARGTYPE_DOUBLE:
210                 if (read_double(value, &d, arguments) < 0)
211                         return -1;
212                 return format_double(stream, d, format);
213         default:
214                 abort();
215         }
216 }
217
218 struct format_argument_data
219 {
220         struct value *value;
221         struct value_dict *arguments;
222 };
223
224 static int
225 format_argument_cb(FILE *stream, void *ptr)
226 {
227         struct format_argument_data *data = ptr;
228         return format_argument(stream, data->value, data->arguments);
229 }
230
231 static int
232 format_struct(FILE *stream, struct value *value, struct value_dict *arguments)
233 {
234         int written = 0;
235         if (acc_fprintf(&written, stream, "{ ") < 0)
236                 return -1;
237
238         int need_delim = 0;
239         size_t i;
240         for (i = 0; i < type_struct_size(value->type); ++i) {
241                 struct value element;
242                 if (value_init_element(&element, value, i) < 0)
243                         return -1;
244
245                 struct format_argument_data data = { &element, arguments };
246                 int o = delim_output(stream, &need_delim,
247                                      format_argument_cb, &data);
248                 value_destroy(&element);
249                 if (o < 0)
250                         return -1;
251
252                 written += o;
253         }
254         if (acc_fprintf(&written, stream, " }") < 0)
255                 return -1;
256         return written;
257 }
258
259 static const char null_message[] = "nil";
260 int
261 format_pointer(FILE *stream, struct value *value, struct value_dict *arguments)
262 {
263         if (value_is_zero(value, arguments))
264                 return fprintf(stream, null_message);
265
266         /* The following is for detecting recursion.  We keep track of
267          * the values that were already displayed.  Each time a
268          * pointer should be dereferenced, we compare its value to the
269          * value of each of the pointers dereferenced so far.  If one
270          * of them matches, instead of recursing, we just printf which
271          * superstructure this pointer recurses to.  */
272         static struct vect pointers = {};
273         if (pointers.elt_size == 0)
274                 VECT_INIT(&pointers, struct value *);
275
276         /* Trim number of expanded structures of the same type.  Even
277          * for non-recursive structure, we don't want to expand all of
278          * it if it's huge.  */
279         size_t i;
280         size_t len = vect_size(&pointers);
281         assert(value->type->type == ARGTYPE_POINTER);
282         struct arg_type_info *pointee = value->type->u.ptr_info.info;
283         if (pointee->type == ARGTYPE_STRUCT) {
284                 size_t depth = 0;
285                 for (i = 0; i < len; ++i) {
286                         struct value *old
287                                 = *VECT_ELEMENT(&pointers, struct value *, i);
288                         assert(old->type->type == ARGTYPE_POINTER);
289                         struct arg_type_info *old_pointee
290                                 = old->type->u.ptr_info.info;
291                         if (old_pointee == pointee)
292                                 depth++;
293                 }
294                 if (depth >= options.arraylen)
295                         return fprintf(stream, "...");
296         }
297
298         for (i = len; i-- > 0 ;) {
299                 struct value **old = VECT_ELEMENT(&pointers, struct value *, i);
300                 int rc = value_equal(value, *old, arguments);
301                 if (rc < 0)
302                         return -1;
303                 if (rc > 0) {
304                         size_t reclevel = len - i - 1;
305                         char buf[reclevel + 1];
306                         memset(buf, '^', sizeof buf);
307                         buf[reclevel] = 0;
308                         return fprintf(stream, "recurse%s", buf);
309                 }
310         }
311
312         /* OK, not a recursion.  Remember this value for tracking.  */
313         if (VECT_PUSHBACK(&pointers, &value) < 0)
314                 return -1;
315
316         struct value element;
317         int o;
318         if (value_init_deref(&element, value) < 0) {
319                 o = -1;
320                 goto done;
321         }
322         o = format_argument(stream, &element, arguments);
323         value_destroy(&element);
324
325 done:
326         VECT_POPBACK(&pointers, struct value *, NULL, NULL);
327         return o;
328 }
329
330 /*
331  * LENGTH is an expression whose evaluation will yield the actual
332  *    length of the array.
333  *
334  * MAXLEN is the actual maximum length that we care about
335  *
336  * BEFORE if LENGTH>MAXLEN, we display ellipsis.  We display it before
337  *    the closing parenthesis if BEFORE, otherwise after it.
338  *
339  * OPEN, CLOSE, DELIM are opening and closing parenthesis and element
340  *    delimiter.
341  */
342 int
343 format_array(FILE *stream, struct value *value, struct value_dict *arguments,
344              struct expr_node *length, size_t maxlen, int before,
345              const char *open, const char *close, const char *delim)
346 {
347         /* We need "long" to be long enough to cover the whole address
348          * space.  */
349         (void)sizeof(char[1 - 2*(sizeof(long) < sizeof(void *))]);
350         long l;
351         if (expr_eval_word(length, value, arguments, &l) < 0)
352                 return -1;
353         size_t len = (size_t)l;
354
355         int written = 0;
356         if (acc_fprintf(&written, stream, "%s", open) < 0)
357                 return -1;
358
359         size_t i;
360         for (i = 0; i < len && i <= maxlen; ++i) {
361                 if (i == maxlen) {
362                         if (before && acc_fprintf(&written, stream, "...") < 0)
363                                 return -1;
364                         break;
365                 }
366
367                 if (i > 0 && acc_fprintf(&written, stream, "%s", delim) < 0)
368                         return -1;
369
370                 struct value element;
371                 if (value_init_element(&element, value, i) < 0)
372                         return -1;
373                 int o = format_argument(stream, &element, arguments);
374                 value_destroy(&element);
375                 if (o < 0)
376                         return -1;
377                 written += o;
378         }
379         if (acc_fprintf(&written, stream, "%s", close) < 0)
380                 return -1;
381         if (i == maxlen && !before && acc_fprintf(&written, stream, "...") < 0)
382                 return -1;
383
384         return written;
385 }
386
387 static int
388 toplevel_format_lens(struct lens *lens, FILE *stream,
389                      struct value *value, struct value_dict *arguments,
390                      enum int_fmt_t int_fmt)
391 {
392         switch (value->type->type) {
393         case ARGTYPE_VOID:
394                 return fprintf(stream, "<void>");
395
396         case ARGTYPE_SHORT:
397         case ARGTYPE_INT:
398         case ARGTYPE_LONG:
399                 return format_integer(stream, value, int_fmt, arguments);
400
401         case ARGTYPE_USHORT:
402         case ARGTYPE_UINT:
403         case ARGTYPE_ULONG:
404                 if (int_fmt == INT_FMT_i || int_fmt == INT_FMT_default)
405                         int_fmt = INT_FMT_u;
406                 return format_integer(stream, value, int_fmt, arguments);
407
408         case ARGTYPE_CHAR:
409                 if (int_fmt == INT_FMT_default)
410                         return format_naked_char(stream, value, arguments);
411                 return format_integer(stream, value, int_fmt, arguments);
412
413         case ARGTYPE_FLOAT:
414         case ARGTYPE_DOUBLE:
415                 return format_floating(stream, value, arguments, int_fmt);
416
417         case ARGTYPE_STRUCT:
418                 return format_struct(stream, value, arguments);
419
420         case ARGTYPE_POINTER:
421                 if (value_is_zero(value, arguments))
422                         return fprintf(stream, null_message);
423                 if (value->type->u.array_info.elt_type->type != ARGTYPE_VOID)
424                         return format_pointer(stream, value, arguments);
425                 return format_integer(stream, value, INT_FMT_x, arguments);
426
427         case ARGTYPE_ARRAY:
428                 return format_array(stream, value, arguments,
429                                     value->type->u.array_info.length,
430                                     options.arraylen, 1, "[ ", " ]", ", ");
431         }
432         abort();
433 }
434
435 static int
436 default_lens_format_cb(struct lens *lens, FILE *stream,
437                        struct value *value, struct value_dict *arguments)
438 {
439         return toplevel_format_lens(lens, stream, value, arguments,
440                                     INT_FMT_default);
441 }
442
443 struct lens default_lens = {
444         .format_cb = default_lens_format_cb,
445 };
446
447
448 static int
449 blind_lens_format_cb(struct lens *lens, FILE *stream,
450                      struct value *value, struct value_dict *arguments)
451 {
452         return 0;
453 }
454
455 struct lens blind_lens = {
456         .format_cb = blind_lens_format_cb,
457 };
458
459
460 static int
461 octal_lens_format_cb(struct lens *lens, FILE *stream,
462                      struct value *value, struct value_dict *arguments)
463 {
464         return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_o);
465 }
466
467 struct lens octal_lens = {
468         .format_cb = octal_lens_format_cb,
469 };
470
471
472 static int
473 hex_lens_format_cb(struct lens *lens, FILE *stream,
474                    struct value *value, struct value_dict *arguments)
475 {
476         return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_x);
477 }
478
479 struct lens hex_lens = {
480         .format_cb = hex_lens_format_cb,
481 };
482
483
484 static int
485 dec_lens_format_cb(struct lens *lens, FILE *stream,
486                    struct value *value, struct value_dict *arguments)
487 {
488         return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_u);
489 }
490
491 struct lens dec_lens = {
492         .format_cb = dec_lens_format_cb,
493 };
494
495
496 static int
497 guess_lens_format_cb(struct lens *lens, FILE *stream,
498                      struct value *value, struct value_dict *arguments)
499 {
500         return toplevel_format_lens(lens, stream, value, arguments,
501                                     INT_FMT_unknown);
502 }
503
504 struct lens guess_lens = {
505         .format_cb = guess_lens_format_cb,
506 };
507
508
509 static int
510 bool_lens_format_cb(struct lens *lens, FILE *stream,
511                     struct value *value, struct value_dict *arguments)
512 {
513         switch (value->type->type) {
514         case ARGTYPE_VOID:
515         case ARGTYPE_FLOAT:
516         case ARGTYPE_DOUBLE:
517         case ARGTYPE_STRUCT:
518         case ARGTYPE_POINTER:
519         case ARGTYPE_ARRAY:
520                 return toplevel_format_lens(lens, stream, value,
521                                             arguments, INT_FMT_default);
522
523                 int zero;
524         case ARGTYPE_SHORT:
525         case ARGTYPE_INT:
526         case ARGTYPE_LONG:
527         case ARGTYPE_USHORT:
528         case ARGTYPE_UINT:
529         case ARGTYPE_ULONG:
530         case ARGTYPE_CHAR:
531                 if ((zero = value_is_zero(value, arguments)) < 0)
532                         return -1;
533                 if (zero)
534                         return fprintf(stream, "false");
535                 else
536                         return fprintf(stream, "true");
537         }
538         abort();
539 }
540
541 struct lens bool_lens = {
542         .format_cb = bool_lens_format_cb,
543 };
544
545
546 static int
547 string_lens_format_cb(struct lens *lens, FILE *stream,
548                       struct value *value, struct value_dict *arguments)
549 {
550         switch (value->type->type) {
551         case ARGTYPE_POINTER:
552                 /* This should really be written as either "string",
553                  * or, if lens, then string(array(char, zero)*).  But
554                  * I suspect people are so used to the char * C idiom,
555                  * that string(char *) might actually turn up.  So
556                  * let's just support it.  */
557                 if (value->type->u.ptr_info.info->type == ARGTYPE_CHAR) {
558                         struct arg_type_info info[2];
559                         type_init_array(&info[1],
560                                         value->type->u.ptr_info.info, 0,
561                                         expr_node_zero(), 0);
562                         type_init_pointer(&info[0], &info[1], 0);
563                         info->lens = lens;
564                         info->own_lens = 0;
565                         struct value tmp;
566                         if (value_clone(&tmp, value) < 0)
567                                 return -1;
568                         value_set_type(&tmp, info, 0);
569                         int ret = string_lens_format_cb(lens, stream, &tmp,
570                                                         arguments);
571                         type_destroy(&info[0]);
572                         type_destroy(&info[1]);
573                         value_destroy(&tmp);
574                         return ret;
575                 }
576
577                 /* fall-through */
578         case ARGTYPE_VOID:
579         case ARGTYPE_FLOAT:
580         case ARGTYPE_DOUBLE:
581         case ARGTYPE_STRUCT:
582         case ARGTYPE_SHORT:
583         case ARGTYPE_INT:
584         case ARGTYPE_LONG:
585         case ARGTYPE_USHORT:
586         case ARGTYPE_UINT:
587         case ARGTYPE_ULONG:
588                 return toplevel_format_lens(lens, stream, value,
589                                             arguments, INT_FMT_default);
590
591         case ARGTYPE_CHAR:
592                 return format_char(stream, value, arguments);
593
594         case ARGTYPE_ARRAY:
595                 return format_array(stream, value, arguments,
596                                     value->type->u.array_info.length,
597                                     options.strlen, 0, "\"", "\"", "");
598         }
599         abort();
600 }
601
602 struct lens string_lens = {
603         .format_cb = string_lens_format_cb,
604 };
605
606 static int
607 out_bits(FILE *stream, size_t low, size_t high)
608 {
609         if (low == high)
610                 return fprintf(stream, "%zd", low);
611         else
612                 return fprintf(stream, "%zd-%zd", low, high);
613 }
614
615 static int
616 bitvect_lens_format_cb(struct lens *lens, FILE *stream,
617                        struct value *value, struct value_dict *arguments)
618 {
619         unsigned char *data = value_get_data(value, arguments);
620         if (data == NULL)
621                 return -1;
622         size_t sz = type_sizeof(value->inferior, value->type);
623         if (sz == (size_t)-1)
624                 return -1;
625
626         size_t i;
627         unsigned char buf[sz];
628         switch ((int)value->type->type) {
629                 union bitvect_integral_64
630                 {
631                         uint8_t u8;
632                         uint16_t u16;
633                         uint32_t u32;
634                         uint64_t u64;
635                         unsigned char buf[0];
636                 } bv;
637
638         case ARGTYPE_POINTER:
639                 return format_pointer(stream, value, arguments);
640
641         case ARGTYPE_STRUCT:
642         case ARGTYPE_ARRAY:
643                 break;
644
645         default:
646                 assert(sz <= sizeof(bv));
647                 memmove(bv.buf, data, sz);
648
649                 if (sz == 1)
650                         bv.u64 = bv.u8;
651                 else if (sz == 2)
652                         bv.u64 = bv.u16;
653                 else if (sz == 4)
654                         bv.u64 = bv.u32;
655
656                 for (i = 0; i < sz; ++i) {
657                         buf[i] = bv.u64 & 0xff;
658                         bv.u64 >>= 8;
659                 }
660                 data = buf;
661         }
662
663         size_t bits = 0;
664         for (i = 0; i < sz; ++i)
665                 bits += bitcount(data[i]);
666
667         /* If there's more 1's than 0's, show inverse.  */
668         unsigned neg = bits > sz * 4 ? 0xff : 0x00;
669
670         int o = 0;
671         if (acc_fprintf(&o, stream, "%s<", &"~"[neg == 0x00]) < 0)
672                 return -1;
673
674         size_t bitno = 0;
675         ssize_t low = -1;
676         for (i = 0; i < sz; ++i) {
677                 unsigned char m;
678                 unsigned char d = data[i] ^ neg;
679                 for (m = 0x01; m != 0; m <<= 1) {
680                         int bit = !!(m & d);
681                         if (low < 0) {
682                                 if (bit) {
683                                         if (low == -2
684                                             && acc_fprintf(&o, stream, ",") < 0)
685                                                 return -1;
686                                         low = bitno;
687                                 }
688                         } else if (!bit) {
689                                 if (account_output(&o, out_bits(stream, low,
690                                                                 bitno-1)) < 0)
691                                         return -1;
692                                 low = -2;
693                         }
694                         bitno++;
695                 }
696         }
697         if (low >= 0 && account_output(&o, out_bits(stream, low, bitno-1)) < 0)
698                 return -1;
699
700         if (fputc('>', stream) < 0)
701                 return -1;
702         o += 1;
703
704         return o;
705 }
706
707 struct lens bitvect_lens = {
708         .format_cb = bitvect_lens_format_cb,
709 };