bionic (3) avcall.3.gz

Provided by: libffcall-dev_2.1-1_amd64 bug

NAME

       avcall - build a C argument list incrementally and call a C function on it.

SYNOPSIS

       #include <avcall.h>

       av_alist alist;

       av_start_type(alist, &func [[, return_type], &return_value ]);

       av_type(alist, [arg_type,] value);

       av_call(alist);

DESCRIPTION

       This  set  of  macros  builds  an  argument  list  for  a  C  function  and  calls the function on it. It
       significantly reduces the amount of `glue' code required for parsers, debuggers, imbedded interpreters, C
       extensions  to application programs and other situations where collections of functions need to be called
       on lists of externally-supplied arguments.

       Function calling conventions differ considerably on different machines and  avcall  attempts  to  provide
       some degree of isolation from such architecture dependencies.

       The  interface  is  like  stdarg(3)  in  reverse. All of the macros return 0 for success, < 0 for failure
       (e.g., argument list overflow or type-not-supported).

       (1)    #include <avcall.h>
              and declare the argument list structure
              av_alist alist;

       (2)    Set any special flags. This is architecture and compiler dependent.  Compiler options that  affect
              passing  conventions  may need to be flagged by #defines before the #include <avcall.h> statement.
              However, the configure script should have determined which #defines are needed and put them at the
              top of avcall.h.

       (3)    Initialize  the  alist  with  the  function  address and return value pointer (if any). There is a
              separate macro for each simple return  type  ([u]char,  [u]short,  [u]int,  [u]long,  [u]longlong,
              float,  double,  where `u' indicates `unsigned'). The macros for functions returning structures or
              pointers require an explicit type argument.

       E.g.,

       av_start_int (alist, &func, &int_return);

       av_start_double (alist, &func, &double_return);

       av_start_void (alist, &func);

       av_start_struct (alist, &func, struct_type, splittable,
                        &struct_return);

       av_start_ptr (alist, &func, pointer_type,
                     &pointer_return);

       The splittable flag specifies whether the struct_type can be returned in registers such that every struct
       field  fits entirely in a single register. This needs to be specified for structs of size 2*sizeof(long).
       For structs of size <= sizeof(long), splittable is ignored and assumed to be 1. For  structs  of  size  >
       2*sizeof(long), splittable is ignored and assumed to be 0. There are some handy macros for this:
       av_word_splittable_1 (type1)
       av_word_splittable_2 (type1, type2)
       av_word_splittable_3 (type1, type2, type3)
       av_word_splittable_4 (type1, type2, type3, type4)
       For a struct with three slots
       struct { type1 id1; type2 id2; type3 id3; }
       you can specify splittable as av_word_splittable_3 (type1, type2, type3) .

       (4)    Push  the arguments on to the list in order. Again there is a macro for each simple built-in type,
              and the macros for structure and pointer arguments require an extra type argument:

       av_int (alist, int_value);

       av_double (alist, double_value);

       av_struct (alist, struct_or_union_type, struct_value);

       av_ptr (alist, pointer_type, pointer_value);

       (5)    Call the function, set the return value, and tidy up:

       av_call (alist);

NOTES

       (1) Functions whose first declaration is in Kernighan & Ritchie style (i.e.,  without  a  typed  argument
       list)  MUST use default K&R C expression promotions (char and short to int, float to double) whether they
       are compiled by a K&R or an ANSI compiler, because the true argument types may not be known at  the  call
       point. Such functions typically back-convert their arguments to the declared types on function entry. (In
       fact, the  only  way  to  pass  a  true  char,  short  or  float  in  K&R  C  is  by  an  explicit  cast:
       func((char)c,(float)f)  ).  Similarly, some K&R compilers (such as Sun cc on the sparc) actually return a
       float as a double.

       Hence, for arguments of functions declared in K&R style you should use av_int()  and  av_double()  rather
       than av_char(), av_short() or av_float().  If you use a K&R compiler, the avcall header files may be able
       to detect this and define av_float(), etc, appropriately, but with an  ANSI  compiler  there  is  no  way
       avcall can know how a function was declared, so you have to correct the argument types yourself.

       (2)  The  explicit  type arguments of the av_struct() and av_ptr() macros are typically used to calculate
       size, alignment, and passing conventions.  This may not be sufficient  for  some  machines  with  unusual
       structure  and  pointer  handling:  in  this  case additional av_start_type() and av_type() macros may be
       defined.

       (3) The macros av_start_longlong(), av_start_ulonglong(), av_longlong() and av_ulonglong() work  only  if
       the C compiler has a working long long 64-bit integer type.

       (4)  The  struct  types  used in av_start_struct() and av_struct() must only contain (signed or unsigned)
       int, long, long long or pointer fields.  Struct types containing (signed or unsigned) char, short, float,
       double or other structs are not supported.

SEE ALSO

       stdarg(3), varargs(3).

BUGS

       The  current implementations have been tested on a selection of common cases but there are probably still
       many bugs.

       There are typically built-in limits on the size of the argument-list, which may also include the size  of
       any structure arguments.

       The  decision  whether  a  struct is to be returned in registers or in memory considers only the struct's
       size and alignment. This is inaccurate: for example, gcc on m68k-next returns struct { char a,b,c;  }  in
       registers  and  struct  {  char  a[3];  }  in memory, although both types have the same size and the same
       alignment.

NON-BUGS

       All information is passed in CPU registers and the stack. The avcall package  is  therefore  multithread-
       safe.

PORTING AVCALL

       Ports,  bug-fixes,  and suggestions are most welcome. The macros required for argument pushing are pretty
       grungy, but it does seem to be possible to port avcall to a range of machines. Ports to  non-standard  or
       non-32-bit machines are especially welcome so we can sort the interface out before it's too late.

       Knowledge   about   argument   passing   conventions   can   be   found   in   the   gcc   source,   file
       gcc-2.6.3/config/cpu/cpu.h, section "Stack layout; function entry, exit and calling."

       Some of the grunge is usually handled by a C or assembly level glue  routine  that  actually  pushes  the
       arguments,  calls the function and unpacks any return value.  This is called avcall_call(). A precompiled
       assembler version for people without gcc is also made available. The routine should  ideally  have  flags
       for the passing conventions of other compilers.

       Many of the current routines waste a lot of stack space and generally do hairy things to stack frames - a
       bit more assembly code would probably help things along quite a bit here.

AUTHOR

       Bill Triggs <Bill.Triggs@inrialpes.fr>.

ACKNOWLEDGEMENTS

       Some initial ideas were stolen from the C interface to the Zelk extensions to Oliver Laumann's Elk scheme
       interpreter  by  J.P.Lewis,  NEC  C&C  Research,  <zilla@ccrl.nj.nec.com>  (for  Sun4  &  SGI),  and  Roy
       Featherstone's <roy@robots.oxford.ac.uk> personal C interface library for Sun[34] & SGI.  I  also  looked
       at the machine-dependent parts of the GCC and GDB distributions, and put the gcc asm() extensions to good
       use. Thanks guys!

       This work was partly supported by EC-ESPRIT Basic Research Action SECOND.

                                                  23 July 2017                                         AVCALL(3)