TODO revision 2699445f5219da48e25fc59f1a4b929d5e1e830b
1-*-org-*-
2* TODO
3** Automatic prototype discovery:
4*** Use debuginfo if available
5    Alternatively, use debuginfo to generate configure file.
6*** Mangled identifiers contain partial prototypes themselves
7    They don't contain return type info, which can change the
8    parameter passing convention.  We could use it and hope for the
9    best.
10** Automatically update list of syscalls?
11** More operating systems (solaris?)
12** Get rid of EVENT_ARCH_SYSCALL and EVENT_ARCH_SYSRET
13** Implement displaced tracing
14   A technique used in GDB (and in uprobes, I believe), whereby the
15   instruction under breakpoint is moved somewhere else, and followed
16   by a jump back to original place.  When the breakpoint hits, the IP
17   is moved to the displaced instruction, and the process is
18   continued.  We avoid all the fuss with singlestepping and
19   reenablement.
20** Create different ltrace processes to trace different children
21** Config file syntax
22*** mark some symbols as exported
23    For PLT hits, only exported prototypes would be considered.  For
24    symtab entry point hits, all would be.
25
26*** named arguments
27    This would be useful for replacing the arg1, emt2 etc.
28
29*** parameter pack improvements
30    The above format tweaks require that packs that expand to no types
31    at all be supported.  If this works, then it should be relatively
32    painless to implement conditionals:
33
34    | void ptrace(REQ=enum(PTRACE_TRACEME=0,...),
35    |             if[REQ==0](pack(),pack(pid_t, void*, void *)))
36
37    This is of course dangerously close to a programming language, and
38    I think ltrace should be careful to stay as simple as possible.
39    (We can hook into Lua, or TinyScheme, or some such if we want more
40    general scripting capabilities.  Implementing something ad-hoc is
41    undesirable.)  But the above can be nicely expressed by pattern
42    matching:
43
44    | void ptrace(REQ=enum[int](...)):
45    |   [REQ==0] => ()
46    |   [REQ==1 or REQ==2] => (pid_t, void*)
47    |   [true] => (pid_t, void*, void*);
48
49    Or:
50
51    | int open(string, FLAGS=flags[int](O_RDONLY=00,...,O_CREAT=0100,...)):
52    |   [(FLAGS & 0100) != 0] => (flags[int](S_IRWXU,...))
53
54    This would still require pretty complete expression evaluation.
55    _Including_ pointer dereferences and such.  And e.g. in accept, we
56    need subtraction:
57
58    | int accept(int, +struct(short, +array(hex(char), X-2))*, (X=uint)*);
59
60    Perhaps we should hook to something after all.
61
62*** errno tracking
63    Some calls result in setting errno.  Somehow mark those, and on
64    failure, show errno.
65
66*** second conversions?
67    This definitely calls for some general scripting.  The goal is to
68    have seconds in adjtimex calls show as e.g. 10s, 1m15s or some
69    such.
70
71*** format should take arguments like string does
72    Format should take value argument describing the value that should
73    be analyzed.  The following overwriting rules would then apply:
74
75    | format       | format(array(char, zero)*) |
76    | format(LENS) | X=LENS, format[X]          |
77
78    The latter expanded form would be canonical.
79
80    This depends on named arguments and parameter pack improvements
81    (we need to be able to construct parameter packs that expand to
82    nothing).
83
84*** More fine-tuned control of right arguments
85    Combination of named arguments and some extensions could take care
86    of that:
87
88    | void func(X=hide(int*), long*, +pack(X)); |
89
90    This would show long* as input argument (i.e. the function could
91    mangle it), and later show the pre-fetched X.  The "pack" syntax is
92    utterly undeveloped as of now.  The general idea is to produce
93    arguments that expand to some mix of types and values.  But maybe
94    all we need is something like
95
96    | void func(out int*, long*); |
97
98    ltrace would know that out/inout/in arguments are given in the
99    right order, but left pass should display in and inout arguments
100    only, and right pass then out and inout.  + would be
101    backward-compatible syntactic sugar, expanded like so:
102
103    | void func(int*, int*, +long*, long*);              |
104    | void func(in int*, in int*, out long*, out long*); |
105
106    But sometimes we may want to see a different type on the way in and
107    on the way out.  E.g. in asprintf, what's interesting on the way in
108    is the address, but on the way out we want to see buffer contents.
109    Does something like the following make sense?
110
111    | void func(X=void*, long*, out string(X)); |
112
113** Support for functions that never return
114   This would be useful for __cxa_throw, presumably also for longjmp
115   (do we handle that at all?) and perhaps a handful of others.
116
117** Support flag fields
118   enum-like syntax, except disjunction of several values is assumed.
119** Support long long
120   We currently can't define time_t on 32bit machines.  That mean we
121   can't describe a range of time-related functions.
122
123** Support signed char, unsigned char, char
124   Also, don't format it as characted by default, string lens can do
125   it.  Perhaps introduce byte and ubyte and leave 'char' as alias of
126   one of those with string lens applied by default.
127
128** Support fixed-width types
129   Really we should keep everything as {u,}int{8,16,32,64} internally,
130   and have long, short and others be translated to one of those
131   according to architecture rules.  Maybe this could be achieved by a
132   per-arch config file with typedefs such as:
133
134   | typedef ulong = uint8_t; |
135
136** Some more functions in vect might be made to take const*
137   Or even marked __attribute__((pure)).
138
139** pretty printer support
140   GDB supports python pretty printers.  We migh want to hook this in
141   and use it to format certain types.
142
143* BUGS
144** After a clone(), syscalls may be seen as sysrets in s390 (see trace.c:syscall_p())
145