# oxref(1)

## oxref - cross reference utility
(oxref.2.02.00)

## 2012-2024

## NAME

oxref - cross reference utility for various languages

## SYNOPSIS

oxref [OPTIONS] arguments
[OPTIONS] - see the OPTIONS section below
arguments - object files and/or libraries to process

The cross reference listing is written to the standard output stram.

## DESCRIPTION

The program oxref generates cross reference listings, program or function call-trees, and/or (recursive) called-by overviews of specified functions using non-stripped object files and/or libraries.

Cross reference listings contain the names and source files of functions defined in the specified object files and/or libraries, as well as an overview of the functions calling these functions.

Call-trees show the (nested) tree of functions directly or indirectly called from the top-level (main program) function.

Called-by overviews start from a specified function name, and (recursively) show the functions calling the specified function.

Brief examples of these three modes of operation are shown below.

Especially the 'called-by' overview is useful information during program development and debugging phases, as it immediately provides the hierarchy of functions directly or indirectly calling the specified function name.

E.g., assuming that the signature; the pre-conditions or the post-conditions of a function must be changed it is important to know from what function(s) the function-to-modify is called to verify that the changes to the modified function do not break its calling functions.

Oxref's output starts with a header showing information about the program, a time stamp and the arguments passed to oxref. E.g.,

    oxref by Frank B. Brokken (f.b.brokken@rug.nl)
    oxref V 2.01.00 2012-2023

    CREATED Wed, 25 Oct 2023 11:56:44 +0000
    OXREF ARGUMENTS: -t main -r replace -fxs tmp/main.o tmp/libmodules.a
    ----------------------------------------------------------------------

The header is (depending on the specified options) followed by the cross reference information, the call tree and/or the called-by overview.

Cross reference listings show the symbols, as well as (optionally) their full names (e.g., prefixed by class-names), source files and the source files and names of functions using the symbols. The cross reference listings of a global variable and a function looks like this:

        author
          Full name: Icmbuild::author
          Source:    version.cc
          Used By:
            header.cc: header(int, char**)
            usage.cc: usage(std::string const&)

        calledFrom(unsigned long)
          Full name: XrefData::calledFrom(unsigned long)
          Source:    calledfrom.cc
          Used By:
            undefined.cc: Store::undefined(std::string const&)

Call trees show the names of all entities used or called from a certain starting point. For C and C++ programs the starting point main produces the program's full call tree. A (partially shown) call tree might look like this:

        CALL TREE FOR: main

        main
        +-usage(std::string const&)
        | +-Icmbuild::version
        +-Storage::Storage()
        | +-Store::Store()
        | +-Storage::patternFile(std::string const&)
        +-Storage::tree() const
          +-Store::tree(std::string const&) const
            +-Tree::print(unsigned long, unsigned long)
              +-Tree::calls(unsigned long, unsigned long)
              | +-Tree::calls(unsigned long, XrefData const&)
              +-Tree::indent(unsigned long) const

Calling levels are indented using +- indicators, continuation at identical levels are indicated by vertical lines, using | characters. In the shown call tree main calls usage, the Storage constructor and the Storage::tree() member. Likewise, the Storage constructor calls the Store constructor and the member Storage::patternFile. Recursively called functions appear in the overview where their names are followed by ==> nr arrows where nr refers to the call-level where the function is defined. The top level (e.g. main) is referred to as level 0. Here is an example showing recursion in the call-tree of the bisonc++ program:

        main
        ...
        +-Grammar::deriveSentence()
        | +-Rules::s_startSymbol
        | +-Grammar::derivable(Symbol const*)
        |   +-Grammar::becomesDerivable(Production const*)
        |   | +-Grammar::derivable(Symbol const*) ==> 2
        |   +-Grammar::isDerivable(Production const*)
        ...

Indirect recursion is shown this way as well.

Caveat: in order to produce the program's call tree the object file containing the program's starting point (e.g., main) must be available to oxref. If main.o is the object file of the function main then main.o must explicitly be specified as oxref's command-line argument (see, e.g., the command specification shown above in the header line of oxref's output).

Called-by listings start from a specified function (specified as a regular expression but usually simply specified as ClassName::memberFunction, showing (recursively) the functions calling the specified function (see option --called-by below):

        CALLED-BY LISTING:

        Store::define(std::string const&, bool) (define.cc): called by
            Store::setFunction(std::string const&) (setfunction.cc)
            Store::setObject(std::string const&) (setobject.cc)
            Store::setSource(std::string const&) (setsource.cc)

        Store::setFunction(std::string const&) (setfunction.cc): called by
            Storage::function(std::string const&) (function.cc)

        Store::setObject(std::string const&) (setobject.cc): called by
            Storage::object(std::string const&) (object.cc)

        Store::setSource(std::string const&) (setsource.cc): called by
            Storage::sourceFile(std::string const&) (sourcefile.cc)

        Storage::function(std::string const&) (function.cc): called by
            Storage::push_back(std::string) (pushback.cc)

        Storage::object(std::string const&) (object.cc): called by
            Storage::push_back(std::string) (pushback.cc)

        Storage::sourceFile(std::string const&) (sourcefile.cc): called by
            Storage::push_back(std::string) (pushback.cc)

        Storage::push_back(std::string) (pushback.cc): called by
            main (main.cc)

## RETURN VALUE

Oxref returns 1 to the operating system if an error occurs or if oxref automatically shows its usage info.

Oxref returns 0 if the requested action was successfully completed, or if the --version or --help options are specified.

## OPTIONS

Where available, single letter options are listed between parentheses following their associated long-option variants. Single letter options require arguments if their associated long options require arguments as well.

- --arg=mode (-a)
  Mode specifies the way the output is abbreviated:

  count - function parameters are suppressed; instead the number of arguments required by a function is shown in its parameter list. Example:

          usage(1)

  instead of

          usage(std::string const&)

  first - only show the first word of parameters. Example:

          insertDefined(unsigned, std::ostream&, std::vector&)

  instead of

          insertDefined(unsigned int, std::ostream&,
                        std::vector<XrefData,
                        std::allocator<XrefData> > const&)

  len - where len is a positive integral number (5 is used if len is less than 5). The value len specifies the maximum length of parameter names. If parameter names need to be truncated, an ellipsis replaces the truncated characters. Example using -a 12:

          insertDefined(unsigned int, std::ostream&, std::vect...&)

  instead of

          insertDefined(unsigned int, std::ostream&,
                        std::vector<XrefData,
                        std::allocator<XrefData> > const&)

- --called-by=spec (-c)
  spec is a regular expression showing (recursively) the function(s) and the functions calling those functions. Although spec can refer to multiple functions, a single function can be specified as, e.g., its name, prefixed by the function's class. E.g., Store::define (which is a member function of oxref's Store class, see the DESCRIPTION section).

  When specifying the --called-by option the -f and -s options do not have to be specified. If only the called-by hierarchy is requested the --no-xref option can be specified to prevent writing the cross-reference listing to the standard output stream.

  As an example: to generated the called-by listing for oxref's Store::define function the following command was issued:

      oxref -Xc Store::define -r replacements tmp/main.o tmp/libmodules.a

  (with replacements being the file containing oxref's type replacements, see option --replace-file below).

- --full-symbol -f
  The full names of the symbols are shown, in addition to the plain symbol names (see also options object-files, source-files and xref-source-files).
  Full names include class names and/or namespace identifiers. Example:

      insertDefined(unsigned int, std::ostream&, std::vector<XrefData,
                    std::allocator<XrefData> > const&)
        Full name: Store::insertDefined(unsigned int, std::ostream&,
                std::vector<XrefData, std::allocator<XrefData> > const&)

- --help (-h)
  Basic usage information is written to the standard error stream.

- --no-xref (-X)
  The no-xref option prevents the cross-reference information from being written to the standard output stream. It can be useful in situations where you're only interested in the program's call-tree (cf. option --tree).

- --objdump=command
  The command option value specifies how the object-dumping program is called. By default it is called as /usr/bin/objdump -C -t. In practice there's probably no reason for using this option.

- --object-files (-o)
  Include in the cross reference listing the name of object files in which symbols (data, functions) are defined (see also options full-symbol, source-files and xref-source-files)

- --replace=spec (-R)
  Output generated by objdump may show the compiler's ideas of what, e.g., a C++ std::string is. Thus, instead of a parameter std::sting const & it may show

          std::__cxx11::basic_string<char, std::char_traits<char>
                                                          const &

  R options are used to specify text replacements of the form

          #find#replace#

  where # can be any character not used in either the find text or the replace text. For example:

          #std::__cxx11::basic_string<char, std::char_traits<char>#std::string#

  Multiple R options may be specified, which are applied in sequence line-by-line to all output lines of objdump. E.g, after replacing the above long definition of a string into std::string subsequent replacements should use std::string rather than the original long definition provided by the compiler.

  In practice replacement specifications are specified after initially running oxref without any specifications. The required replacements are then derived from the obtained output

- --replace-file=fname (-r)
  Replacement specifications can also be stored in a file. Specifications read from file are handled like those obtained from replace options with the replace options being processed before the replacement specifications read from the file specified with the replace_file are processed.

- --select=name
  Only display the cross-reference of name, where name is the (case sensitive) initial substring of a symbol

- --select-pattern=regex
  Only display the cross-reference of symbols matching the regular expression regex, where regex is a regular expression matching the regex(7) specification, including the extensions offered by the pattern(3bobcat) Pattern class. Case sensitive matching is used here, too.

- --source-files (-s)
  Include in the cross reference listing the names of the source files in which symbols are defined (see also options full-symbol, object-files and xref-source-files)

- --tree=fname (-t)
  The tree option generates a call tree for function fname. The argument fname defines the starting point of the call tree. Note that the program's starting point (usually main) does not normally appear in a cross-reference listing, as it is not used by other parts of the program. To obtain the call tree for the program's starting function in these cases specify --tree main. Otherwise, if the call tree of another function is requested its `Full name' specification as used in the cross-reference listing must be used.

- --xref-source-files (-x)
  Include in the cross reference listing the name of source files in which used symbols are defined (see also options full-symbol, object-files and source-files)

- --version (-v)
  Oxref's version number is written to the standard error stream.

## EXAMPLES

The examples show how oxref was called, followed by a representative example of a cross-reference listing for a symbol. Oxref's own cross reference listing was used:

    called as: oxref liboxref

    define(std::string const&, bool)
      Used By:
        Store::setFunction(std::string const&)
        Store::setObject(std::string const&)
        Store::setSource(std::string const&)

    --------------------

    called as: oxref -foxs liboxref

    define(std::string const&, bool)
      Full name: Store::define(std::string const&, bool)
      Source:    define.cc (1define.o)
      Used By:
        setfunction.cc: Store::setFunction(std::string const&)
        setobject.cc: Store::setObject(std::string const&)
        setsource.cc: Store::setSource(std::string const&)

## BUGS

No bugs reported

## ABOUT

In theory, creating cross reference listings is a complex matter as it requires a full syntax analysis of the sources defining a program. Especially with complex languages like C++ this is a difficult hurdle to pass.

Looking for `cross reference programs' using a search engine returns remarkably few hits. LXR is a promising cross referencing program (see http://lxr.linux.no/), but it requires the use of data base packages, making it somewhat complex to use. Other links refer to cross-reference programs for textual documents, not programs.

The complexity of developing a program generating a cross reference listing has baffled me for a long time. Eventually I realized that in practice the essential information has already been generated by the compiler, when it compiles our source files. So why do it all again?

Once a program has been compiled one or (usually) more object files are available. The linker uses tables of defined and external symbols embedded in the object files to connect the various functions. If all requirements can be satisfied the linker is able to create a running program.

Programs like nm(1) and objdump(1) can be used to produce human readable output from the information embedded in object files. Oxref reads this information and organizes it, creating a cross reference listing.

Since all compilable program languages generate identically organized object files (or maybe better: generate object files that can be interpreted by objdump(1)), oxref can broadly be applied. As long as objdump(1) produces sensible output oxref should be able to generate a cross reference listing.

Oxref's name consists of two syllables: o and xref. The o represents the program objdump(1), called from oxref as a child program. The important part is of course the cross-referencing of symbols. Like the common abbreviation of rail-road crossing, rail-road xing, cross referencing is abbreviated to xref. Hence oxref.

Of course, nearly everybody will read oxref as ox-ref. Fortunately, here too we're on familiar ground: Bison, Cow, Gnu, Yacc: all are bovine animals. To that important list oxref adds the Ox.

## FILES

An example of oxref's own cross reference listing is provided (on Debian systems) in the file

        /usr/share/doc/oxref/oxref.xref.gz

## SEE ALSO

nm(1), objdump(1), pattern(3bobcat), regex(7)

## AUTHOR

Frank B. Brokken (f.b.brokken@rug.nl).