[Ltrace-devel] pmachata/revamp, formerly known as the ABI branch

Petr Machata pmachata at redhat.com
Mon Jan 9 05:44:33 UTC 2012

Dear all,

I think I'm about done, modulo fixing on less common arches, with what
used to be labeled as ABI branch, and what I've now pushed to

The principal reasons for most of the changes were twofold: enabling
proper ABI support, and cleaning up some cumbersome interfaces.  The
resulting changes impact most of the code, although back ends and
process control stay intact.  The only back end that changed
significantly is x86_64, which was rewritten from scratch to take
advantage of all the new plumbing.

The following lists the changes that I made:

* License headers with copyright notices were added to files that I
  touched.  I used "git blame" to figure out who to add to copyrights,
  and used arbitrary threshold of 10 lines to discard "minor" edits
  (except for tiny files).  I also tried to dig out companies that might
  be the actual copyright holder.  If you think that my way of
  attribution is unfair or that I omitted you, be sure to speak up.

* Header file backend.h contains declarations of system-dependent
  functions.  Each interface is documented.

* Arbitrary-sized values are implemented in value.c/.h.  This is so that
  we can carry small structs, copied out from registers, from the
  inferior to the tracer.

* Array lengths are encoded using expression objects (expr.c/.h)

* Interfaces to function argument fetching are in fetch.c/.h

* Function arguments are stored in value dictionaries (value_dict.c/.h)
  that are mostly arrays with some support for named values (like
  "retval").  I envision using it one day to support named parameters,
  instead of numbering them.

* Type handling (arg_type, arg_type_info) was moved to type.c/.h mostly
  for aesthetic purposes.

* Function prototypes are described using parameters (param.c/.h).
  A parameter is either a type, or a pack.  Ordinary function parameters
  are types, packs are used to express vararg functions.  printf.c/.h
  contain an implementation of parameter pack that expands printf-like
  format strings.  The type ARGTYPE_FORMAT was thus removed.

* NULL-terminated arrays can be expressed using an expression "zero":
  void func(array(int, zero)); This should work for any element type.
  This is implemented in zero.c/.h.

* Lenses were added to support different "views" of the same underlying
  type.  The issue this is trying to solve is that we have ARGTYPE_OCT,
  which formats ints in octal, and ARGTYPE_ADDR, which formats longs in
  hex, but nothing to format longs in octal or ints in hex.  The same
  with enum, you just don't get to have a short enum field.  This can be
  solved either by making those types composite (cf ARGTYPE_POINTER), or
  introduce some other abstraction.  After writing about half a dozen
  switches in the back end, I'm leaning towards the latter.  Lenses are
  implemented in lens.c/.h, default lenses (oct, hex, bool, hide) are in
  lens_default.c/.h.  Correspondingly, ARGTYPE_OCT, ARGTYPE_ADDR, and

  The lens infrastructure was used also for enums, so now you can easily
  have long, short or byte enums in addition to ints.  This is in
  lens_enum.c/.h, and ARGTYPE_ENUM was dropped.

* The combination of lenses and "zero" was used to reimplement string
  support.  Strings are now char* or array(char,zero)* with a lens set.

* Many test cases were added to the test suite.

In addition to above, I'm seriously considering making unsigned types
lenses, too.  I view enum arg_type as an interface between the front end
and back end.  What's purely front end should be expressed with lenses.
So floats stay, because they are special cased by back ends.  By this
logic, pointers would also go away, but that would be way too awkward to
use.  But signed/unsigned is not an important distinction, and all the
switches would be suddenly a third smaller.

Note that through all this, the config file syntax stayed the same.  All
config files remain valid and their semantic shouldn't change.

Lenses are written using the following syntax:
  lens(type) function(lens(type));
  void function(octal);         # we still support the old "octal"
  void function(octal(short));  # but it can also be used as a lens
  octal(short) function();      # lens over a return type

The enum syntax was tweaked and, like string, uses brackets for the
extra parameter:
  void function(enum[short](A=1, B=2, C=4));

I don't like it, but parens are used for enum parameter and brackets for
string parameter, so either you add special syntax for string in lens
role, or for enum in lens role.

It's all on pmachata/revamp.  Feel free to peek and poke.


More information about the Ltrace-devel mailing list