Blame TODO

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())