|
Packit |
0021fb |
-*-org-*-
|
|
Packit |
0021fb |
* TODO
|
|
Packit |
0021fb |
** Automatic prototype discovery:
|
|
Packit |
0021fb |
*** Use debuginfo if available
|
|
Packit |
0021fb |
Alternatively, use debuginfo to generate configure file.
|
|
Packit |
0021fb |
*** Mangled identifiers contain partial prototypes themselves
|
|
Packit |
0021fb |
They don't contain return type info, which can change the
|
|
Packit |
0021fb |
parameter passing convention. We could use it and hope for the
|
|
Packit |
0021fb |
best. Also they don't include the potentially present hidden this
|
|
Packit |
0021fb |
pointer.
|
|
Packit |
0021fb |
** Automatically update list of syscalls?
|
|
Packit |
0021fb |
** More operating systems (solaris?)
|
|
Packit |
0021fb |
** Get rid of EVENT_ARCH_SYSCALL and EVENT_ARCH_SYSRET
|
|
Packit |
0021fb |
** Implement displaced tracing
|
|
Packit |
0021fb |
A technique used in GDB (and in uprobes, I believe), whereby the
|
|
Packit |
0021fb |
instruction under breakpoint is moved somewhere else, and followed
|
|
Packit |
0021fb |
by a jump back to original place. When the breakpoint hits, the IP
|
|
Packit |
0021fb |
is moved to the displaced instruction, and the process is
|
|
Packit |
0021fb |
continued. We avoid all the fuss with singlestepping and
|
|
Packit |
0021fb |
reenablement.
|
|
Packit |
0021fb |
** Create different ltrace processes to trace different children
|
|
Packit |
0021fb |
** Config file syntax
|
|
Packit |
0021fb |
*** mark some symbols as exported
|
|
Packit |
0021fb |
For PLT hits, only exported prototypes would be considered. For
|
|
Packit |
0021fb |
symtab entry point hits, all would be.
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
*** named arguments
|
|
Packit |
0021fb |
This would be useful for replacing the arg1, emt2 etc.
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
*** parameter pack improvements
|
|
Packit |
0021fb |
The above format tweaks require that packs that expand to no types
|
|
Packit |
0021fb |
at all be supported. If this works, then it should be relatively
|
|
Packit |
0021fb |
painless to implement conditionals:
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
| void ptrace(REQ=enum(PTRACE_TRACEME=0,...),
|
|
Packit |
0021fb |
| if[REQ==0](pack(),pack(pid_t, void*, void *)))
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
This is of course dangerously close to a programming language, and
|
|
Packit |
0021fb |
I think ltrace should be careful to stay as simple as possible.
|
|
Packit |
0021fb |
(We can hook into Lua, or TinyScheme, or some such if we want more
|
|
Packit |
0021fb |
general scripting capabilities. Implementing something ad-hoc is
|
|
Packit |
0021fb |
undesirable.) But the above can be nicely expressed by pattern
|
|
Packit |
0021fb |
matching:
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
| void ptrace(REQ=enum[int](...)):
|
|
Packit |
0021fb |
| [REQ==0] => ()
|
|
Packit |
0021fb |
| [REQ==1 or REQ==2] => (pid_t, void*)
|
|
Packit |
0021fb |
| [true] => (pid_t, void*, void*);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
Or:
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
| int open(string, FLAGS=flags[int](O_RDONLY=00,...,O_CREAT=0100,...)):
|
|
Packit |
0021fb |
| [(FLAGS & 0100) != 0] => (flags[int](S_IRWXU,...))
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
This would still require pretty complete expression evaluation.
|
|
Packit |
0021fb |
_Including_ pointer dereferences and such. And e.g. in accept, we
|
|
Packit |
0021fb |
need subtraction:
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
| int accept(int, +struct(short, +array(hex(char), X-2))*, (X=uint)*);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
Perhaps we should hook to something after all.
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
*** system call error returns
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
This is closely related to above. Take the following syscall
|
|
Packit |
0021fb |
prototype:
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
| long read(int,+string0,ulong);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
string0 means the same as string(array(char, zero(retval))*). But
|
|
Packit |
0021fb |
if read returns a negative value, that signifies errno. But zero
|
|
Packit |
0021fb |
takes this at face value and is suspicious:
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
| read@SYS(3 <no return ...>
|
|
Packit |
0021fb |
| error: maximum array length seems negative
|
|
Packit |
0021fb |
| , "\n\003\224\003\n", 4096) = -11
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
Ideally we would do what strace does, e.g.:
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
| read@SYS(3, 0x12345678, 4096) = -EAGAIN
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
*** errno tracking
|
|
Packit |
0021fb |
Some calls result in setting errno. Somehow mark those, and on
|
|
Packit |
0021fb |
failure, show errno. System calls return errno as a negative
|
|
Packit |
0021fb |
value (see the previous point).
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
*** second conversions?
|
|
Packit |
0021fb |
This definitely calls for some general scripting. The goal is to
|
|
Packit |
0021fb |
have seconds in adjtimex calls show as e.g. 10s, 1m15s or some
|
|
Packit |
0021fb |
such.
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
*** format should take arguments like string does
|
|
Packit |
0021fb |
Format should take value argument describing the value that should
|
|
Packit |
0021fb |
be analyzed. The following overwriting rules would then apply:
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
| format | format(array(char, zero)*) |
|
|
Packit |
0021fb |
| format(LENS) | X=LENS, format[X] |
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
The latter expanded form would be canonical.
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
This depends on named arguments and parameter pack improvements
|
|
Packit |
0021fb |
(we need to be able to construct parameter packs that expand to
|
|
Packit |
0021fb |
nothing).
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
*** More fine-tuned control of right arguments
|
|
Packit |
0021fb |
Combination of named arguments and some extensions could take care
|
|
Packit |
0021fb |
of that:
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
| void func(X=hide(int*), long*, +pack(X)); |
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
This would show long* as input argument (i.e. the function could
|
|
Packit |
0021fb |
mangle it), and later show the pre-fetched X. The "pack" syntax is
|
|
Packit |
0021fb |
utterly undeveloped as of now. The general idea is to produce
|
|
Packit |
0021fb |
arguments that expand to some mix of types and values. But maybe
|
|
Packit |
0021fb |
all we need is something like
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
| void func(out int*, long*); |
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
ltrace would know that out/inout/in arguments are given in the
|
|
Packit |
0021fb |
right order, but left pass should display in and inout arguments
|
|
Packit |
0021fb |
only, and right pass then out and inout. + would be
|
|
Packit |
0021fb |
backward-compatible syntactic sugar, expanded like so:
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
| void func(int*, int*, +long*, long*); |
|
|
Packit |
0021fb |
| void func(in int*, in int*, out long*, out long*); |
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
But sometimes we may want to see a different type on the way in and
|
|
Packit |
0021fb |
on the way out. E.g. in asprintf, what's interesting on the way in
|
|
Packit |
0021fb |
is the address, but on the way out we want to see buffer contents.
|
|
Packit |
0021fb |
Does something like the following make sense?
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
| void func(X=void*, long*, out string(X)); |
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
** Support for functions that never return
|
|
Packit |
0021fb |
This would be useful for __cxa_throw, presumably also for longjmp
|
|
Packit |
0021fb |
(do we handle that at all?) and perhaps a handful of others.
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
** Support flag fields
|
|
Packit |
0021fb |
enum-like syntax, except disjunction of several values is assumed.
|
|
Packit |
0021fb |
** Support long long
|
|
Packit |
0021fb |
We currently can't define time_t on 32bit machines. That mean we
|
|
Packit |
0021fb |
can't describe a range of time-related functions.
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
** Support signed char, unsigned char, char
|
|
Packit |
0021fb |
Also, don't format it as characted by default, string lens can do
|
|
Packit |
0021fb |
it. Perhaps introduce byte and ubyte and leave 'char' as alias of
|
|
Packit |
0021fb |
one of those with string lens applied by default.
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
** Support fixed-width types
|
|
Packit |
0021fb |
Really we should keep everything as {u,}int{8,16,32,64} internally,
|
|
Packit |
0021fb |
and have long, short and others be translated to one of those
|
|
Packit |
0021fb |
according to architecture rules. Maybe this could be achieved by a
|
|
Packit |
0021fb |
per-arch config file with typedefs such as:
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
| typedef ulong = uint8_t; |
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
** Support for ARM/AARCH64 types
|
|
Packit |
0021fb |
- ARM and AARCH64 both support half-precision floating point
|
|
Packit |
0021fb |
- there are two different half-precision formats, IEEE 754-2008
|
|
Packit |
0021fb |
and "alternative". Both have 10 bits of mantissa and 5 bits of
|
|
Packit |
0021fb |
exponent, and differ only in how exponent==0x1F is handled. In
|
|
Packit |
0021fb |
IEEE format, we get NaN's and infinities; in alternative
|
|
Packit |
0021fb |
format, this encodes normalized value -1S × 2¹⁶ × (1.mant)
|
|
Packit |
0021fb |
- The Floating-Point Control Register, FPCR, controls: — The
|
|
Packit |
0021fb |
half-precision format where applicable, FPCR.AHP bit.
|
|
Packit |
0021fb |
- AARCH64 supports fixed-point interpretation of {,double}words
|
|
Packit |
0021fb |
- e.g. fixed(int, X) (int interpreted as a decimal number with X
|
|
Packit |
0021fb |
binary digits of fraction).
|
|
Packit |
0021fb |
- AARCH64 supports 128-bit quad words in SIMD
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
** Some more functions in vect might be made to take const*
|
|
Packit |
0021fb |
Or even marked __attribute__((pure)).
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
** pretty printer support
|
|
Packit |
0021fb |
GDB supports python pretty printers. We migh want to hook this in
|
|
Packit |
0021fb |
and use it to format certain types.
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
* BUGS
|
|
Packit |
0021fb |
** After a clone(), syscalls may be seen as sysrets in s390 (see trace.c:syscall_p())
|