-*-org-*-
* TODO
** Keep exit code of traced process
   See https://bugzilla.redhat.com/show_bug.cgi?id=105371 for details.

** Automatic prototype discovery:
*** Use debuginfo if available
    Alternatively, use debuginfo to generate configure file.
*** Mangled identifiers contain partial prototypes themselves
    They don't contain return type info, which can change the
    parameter passing convention.  We could use it and hope for the
    best.  Also they don't include the potentially present hidden this
    pointer.
** Automatically update list of syscalls?
** More operating systems (solaris?)
** Get rid of EVENT_ARCH_SYSCALL and EVENT_ARCH_SYSRET
** Implement displaced tracing
   A technique used in GDB (and in uprobes, I believe), whereby the
   instruction under breakpoint is moved somewhere else, and followed
   by a jump back to original place.  When the breakpoint hits, the IP
   is moved to the displaced instruction, and the process is
   continued.  We avoid all the fuss with singlestepping and
   reenablement.
** Create different ltrace processes to trace different children
** Config file syntax
*** mark some symbols as exported
    For PLT hits, only exported prototypes would be considered.  For
    symtab entry point hits, all would be.

*** named arguments
    This would be useful for replacing the arg1, emt2 etc.

*** parameter pack improvements
    The above format tweaks require that packs that expand to no types
    at all be supported.  If this works, then it should be relatively
    painless to implement conditionals:

    | void ptrace(REQ=enum(PTRACE_TRACEME=0,...),
    |             if[REQ==0](pack(),pack(pid_t, void*, void *)))

    This is of course dangerously close to a programming language, and
    I think ltrace should be careful to stay as simple as possible.
    (We can hook into Lua, or TinyScheme, or some such if we want more
    general scripting capabilities.  Implementing something ad-hoc is
    undesirable.)  But the above can be nicely expressed by pattern
    matching:

    | void ptrace(REQ=enum[int](...)):
    |   [REQ==0] => ()
    |   [REQ==1 or REQ==2] => (pid_t, void*)
    |   [true] => (pid_t, void*, void*);

    Or:

    | int open(string, FLAGS=flags[int](O_RDONLY=00,...,O_CREAT=0100,...)):
    |   [(FLAGS & 0100) != 0] => (flags[int](S_IRWXU,...))

    This would still require pretty complete expression evaluation.
    _Including_ pointer dereferences and such.  And e.g. in accept, we
    need subtraction:

    | int accept(int, +struct(short, +array(hex(char), X-2))*, (X=uint)*);

    Perhaps we should hook to something after all.

*** system call error returns

    This is closely related to above.  Take the following syscall
    prototype:

    | long read(int,+string0,ulong);

    string0 means the same as string(array(char, zero(retval))*).  But
    if read returns a negative value, that signifies errno.  But zero
    takes this at face value and is suspicious:

    | read@SYS(3 <no return ...>
    | error: maximum array length seems negative
    | , "\n\003\224\003\n", 4096)                  = -11

    Ideally we would do what strace does, e.g.:

    | read@SYS(3, 0x12345678, 4096)                = -EAGAIN

*** errno tracking
    Some calls result in setting errno.  Somehow mark those, and on
    failure, show errno.  System calls return errno as a negative
    value (see the previous point).

*** second conversions?
    This definitely calls for some general scripting.  The goal is to
    have seconds in adjtimex calls show as e.g. 10s, 1m15s or some
    such.

*** format should take arguments like string does
    Format should take value argument describing the value that should
    be analyzed.  The following overwriting rules would then apply:

    | format       | format(array(char, zero)*) |
    | format(LENS) | X=LENS, format[X]          |

    The latter expanded form would be canonical.

    This depends on named arguments and parameter pack improvements
    (we need to be able to construct parameter packs that expand to
    nothing).

*** More fine-tuned control of right arguments
    Combination of named arguments and some extensions could take care
    of that:

    | void func(X=hide(int*), long*, +pack(X)); |

    This would show long* as input argument (i.e. the function could
    mangle it), and later show the pre-fetched X.  The "pack" syntax is
    utterly undeveloped as of now.  The general idea is to produce
    arguments that expand to some mix of types and values.  But maybe
    all we need is something like

    | void func(out int*, long*); |

    ltrace would know that out/inout/in arguments are given in the
    right order, but left pass should display in and inout arguments
    only, and right pass then out and inout.  + would be
    backward-compatible syntactic sugar, expanded like so:

    | void func(int*, int*, +long*, long*);              |
    | void func(in int*, in int*, out long*, out long*); |

    This is useful in particular for:

    | ulong mbsrtowcs(+wstring3_t, string*, ulong, addr); |
    | ulong wcsrtombs(+string3, wstring_t*, ulong, addr); |

    Where we would like to render arg2 on the way in, and arg1 on the
    way out.

    But sometimes we may want to see a different type on the way in and
    on the way out.  E.g. in asprintf, what's interesting on the way in
    is the address, but on the way out we want to see buffer contents.
    Does something like the following make sense?

    | void func(X=void*, long*, out string(X)); |

** Support for functions that never return
   This would be useful for __cxa_throw, presumably also for longjmp
   (do we handle that at all?) and perhaps a handful of others.

** Support flag fields
   enum-like syntax, except disjunction of several values is assumed.
** Support long long
   We currently can't define time_t on 32bit machines.  That mean we
   can't describe a range of time-related functions.

** Support signed char, unsigned char, char
   Also, don't format it as characted by default, string lens can do
   it.  Perhaps introduce byte and ubyte and leave 'char' as alias of
   one of those with string lens applied by default.

** Support fixed-width types
   Really we should keep everything as {u,}int{8,16,32,64} internally,
   and have long, short and others be translated to one of those
   according to architecture rules.  Maybe this could be achieved by a
   per-arch config file with typedefs such as:

   | typedef ulong = uint8_t; |

** Support for ARM/AARCH64 types
   - ARM and AARCH64 both support half-precision floating point
     - there are two different half-precision formats, IEEE 754-2008
       and "alternative".  Both have 10 bits of mantissa and 5 bits of
       exponent, and differ only in how exponent==0x1F is handled.  In
       IEEE format, we get NaN's and infinities; in alternative
       format, this encodes normalized value -1S × 2¹⁶ × (1.mant)
     - The Floating-Point Control Register, FPCR, controls: — The
       half-precision format where applicable, FPCR.AHP bit.
   - AARCH64 supports fixed-point interpretation of {,double}words
     - e.g. fixed(int, X) (int interpreted as a decimal number with X
       binary digits of fraction).
   - AARCH64 supports 128-bit quad words in SIMD

** Some more functions in vect might be made to take const*
   Or even marked __attribute__((pure)).

** pretty printer support
   GDB supports python pretty printers.  We migh want to hook this in
   and use it to format certain types.

** support new Linux kernel features
   - PTRACE_SIEZE
   - /proc/PID/map_files/* (but only root seems to be able to read
     this as of now)

* BUGS
** After a clone(), syscalls may be seen as sysrets in s390 (see trace.c:syscall_p())
