Documentation for XML_TI_OFD.pm |
XML_TI_OFD.pm
Perl module for converting XML files generated by TI OFD utilities into Perl data structures
use XML_TI_OFD; # don't check version
OR ...
use XML_TI_OFD 3.10; # check module version
The second form insures you are picking up the module version 3.10 or later.
This is an alpha version of capability for processing ELF files. Only fully linked .out files have been tested as input. Other types of ELF files such as unlinked .obj files, library files, dynamically linked files, have NOT been tested.
OFD stands for Object File Display utility. Examples include ofd6x for C6000 and ofd55 for C5500. This utility outputs information about TI object files, or libraries of TI object files. This utility can output this information in XML format with the -x option. Use this module to turn that XML data into far more useful Perl data structures.
This module should be delivered with at least one example usage file "dump_ofd.pl". Start by using and exploring that script. All it does is read in the XML file and dump out the resulting Perl data structures. Understanding those data structures is key to implementing any further object file post-processing routines.
The most commonly used functions in the module.
Input: Name of the XML file, or a string that holds all the XML
Returns: Reference to data structure representing XML tree
Main entry point to the module.
Input: Reference to Perl data structure returned by ofd_process_xml_file
Returns: Name of the library, if it exists. undef otherwise.
The main way to check if input file is a library or not.
Input: Reference to Perl data structure returned by ofd_process_xml_file
Returns: The name of the input object file or library used to build the XML information.
Input: Reference to Perl data structure returned by ofd_process_xml_file
Returns: Array of references, one per file in the XML data structure
It doesn't matter whether the underlying data structure came from a library or a single .obj/.out file. Typical usage ...
$xml_data = ofd_process_xml_file($file_name);
if ($lib_name = ofd_find_lib_name($xml_data))
{
print "Processing library $lib_name ...";
}
foreach $file_data (ofd_each_file($xml_data))
{
print "Processing file $file_data->{'name'} ...";
process_file($file_data);
}
Note that if the underlying file is not a library, a library name will not be printed, and the foreach loop will execute only once.
If you just want the first file no matter how many there may be ...
@file_list = ofd_each_file($xml_data);
$file_data = $file_list[0];
Input: An element from an array returned by ofd_each_file
Returns: Array of references, one per section in the file
Typical usage:
foreach $file_data (ofd_each_file($xml_data))
{
foreach $sect_data (ofd_each_section($file_data))
{
...
}
}
Input: An element from an array returned by ofd_each_file
Returns: Array of references, one per symbol in the file
Typical usage:
foreach $file_data (ofd_each_file($xml_data))
{
foreach $symbol_data (ofd_each_symbol($file_data))
{
...
}
}
Input: A compile_unit reference from the dwarf data
Returns: Array of references, one per DIE entry
Typical usage:
foreach my $die_tag (ofd_each_die_entry($compile_unit)) {
...
}
DIE entries can be at 2 different levels hence the need for a function in this module to abstract such details. Object files (and .out's linked with -b to disable type merging) have an extra level {'die'}->[0]->{'die'} compared to standard TI out files {'die'} for their type information. XML can only be represented by 1 or the other so check for which & return it.
Input: - Name of the XML file, or undef if passing a string
- Reference to a string
- A hash of arguments described below
Returns: Nothing directly. String is returned via ref (2nd argument).
The XML files created by OFD can be very large, especially if the -g option is used to include the Dwarf information. Files in the tens of megabytes are common. Use this function to filter the XML file, keeping only the parts you specify, thus making the rest of your script run much faster.
Using this function is not required for correctness. It only affects execution speed.
The 2nd argument is a reference to a string. If no filename is passed, then this string is the input to be stripped. It is assigned all the lines from the stripped down XML file. This string (not a reference to it) can be passed to ofd_process_xml_file().
The hash that, taken together, comprises arguments 3 through N, can have the following key/value pairs:
SECTION : Reference to a list of section names. All <section>'s are
removed except those named here. If this argument is not supplied,
no sections are removed.
DIE_TAG : Reference to a list of Dwarf tag names. All DIE'S, except
those with the given tag names, are removed. If this argument is not
supplied, no DIE's are removed.
If a proposed part of XML to remove is found to nest another similar part, it is not removed. For example, DIE's that nest other DIE's are not removed, no matter what the tag name is.
Input: - Name of the XML file, or undef if passing a string
- Reference to a string
- A hash of arguments described below
Returns: Nothing directly. String is returned via ref (2nd argument).
Similar to ofd_filter_xml, except you specify what should be stripped away. And you can pass an additional argument: GENERAL.
The hash that, taken together, comprises arguments 3 through N, can have the following key/value pairs:
GENERAL : Reference to a list of XML tags. Everything enclosed by one
of these XML tags is removed.
SECTION : Reference to a list of section names. Every <section> with
one of these names is removed.
DIE_TAG : Reference to a list of Dwarf tag names. Every DIE with one
of these tag names is removed.
If a proposed part of XML to remove is found to nest another similar part, it is not removed. For example, DIE's that nest other DIE's are not removed, even it matches the name of a tag you supply.
Calling this function is tricky. It is easy to make a mistake. You need detailed knowledge of both the OFD XML and the information the script is using from the XML. Your best bet is to find an example script that uses it and understand what it is doing.
Input: - Name of the XML file, or '-' for stdin
- A hash of arguments described below
Returns: Reference to data structure representing the XML
This function does (conceptually) the same thing as ...
ofd_filter_xml(...);
ofd_strip_xml(...);
$xml_data = ofd_process_xml_file(...);
For a very large (> 10 MB) XML file, using this function instead takes much less memory. By thus avoiding or reducing memory thrashing, it can run much faster.
The hash passed after the filename is composed of ...
FILTER => reference to a hash of arguments passed to ofd_filter_xml
STRIP => reference to a hash of arguments passed to ofd_strip_xml
XML_PEEK => reference to a function that expects a reference to the
$all_lines scalar (from the XML file). This function usually saves off
bits of information about the XML.
A typical call looks like ...
$xml_data =
ofd_filter_and_parse_xml(
$xml_file,
FILTER => { SECTION => [qw(.debug_info)],
DIE_TAG => [qw(DW_TAG_TI_branch
DW_TAG_compile_unit
DW_TAG_TI_reserved_3
DW_TAG_subprogram)] },
STRIP => { GENERAL => [qw(string_table
raw_data
line_numbers)] },
XML_PEEK => \&xml_peek);
Input: An element from an array returned by ofd_each_file
Returns: True if XML data has Dwarf information, false otherwise
Input: An element from an array returned by ofd_each_file
Returns: Reference to the .debug_info section from the Dwarf information.
Returns undef if it is not found or is poorly formed.
Input: A reference to a single element of the "compile_unit" array at
the top level of the Dwarf data structure.
Returns: A reference to the DIE contained within the compile unit that
has the tag DW_TAG_compile_unit
A "compile unit" is really just a fancy name for a file. A compile unit data structure almost always looks like ...
'compile_unit' => [ # list of files
{
'die' => [ # list of top level DIE's
{
'tag' => 'DW_TAG_compile_unit'
...
It is possible there are no DIE's, or when there is more than one, the DW_TAG_compile unit DIE is not the first one. This routine sorts through all that to return the DW_TAG_compile_unit DIE, or undef if not found.
Input: - A reference to the first DIE to search
- A reference to a hash for saving off all the DIE's, indexed by
DIE id. Pass undef if not desired.
- The remaining argument are a hash described below.
Use this function to organize DIE's into hashes separated by tag name, and indexed by DIE id.
The arguments 3 through N comprise a hash where keys are Dwarf tags and values are references to a hash, keyed by id, that saves off DIE's with the matching tag. There is no limit on the length of this hash. Search for as many tags as you want.
Arguments 2 through N can be undef (though it is pointless for all of them to be undef).
A typical call looks like ...
ofd_find_all_dies($top_level_die, \%dies_by_id,
DW_TAG_TI_branch => \%branch_dies,
DW_TAG_TI_reserved_3 => \%branch_dies);
Input: - A reference to the first DIE to search
- The remaining arguments are a hash described below
Use this function to organize DIE's into arrays separated by tag name.
Arguments 2 through N comprise a hash where keys are Dwarf tags and values are references to an array used to save off the DIE's with the matching tag. There is no limit on the length of this hash. Search for as many tags as you want. DIE's are searched and placed into the corresponding array in the same order as they are found in the XML, which is the same order as they are placed in the object file.
Input: - A reference to the first DIE to search
- The remaining argument are a hash described below.
Use this function to organize DIE's into hashes separated by tag name, and indexed by DIE id.
The arguments 2 through N comprise a hash where keys are Dwarf tags and values are references to a hash, keyed by id, that saves off DIE's with the matching tag. There is no limit on the length of this hash. Search for as many tags as you want.
Input: - Reference to a DIE whose attributes are searched
- The remaining arguments are a hash described below
Use this function to copy the attributes of a DIE to variables.
Arguments 2 through N comprise a hash where keys are Dwarf attributes and values are references to variables which are assigned the value of the attribute. There is no limit to the length of this hash. Search for as many attributes as you want.
A typical call looks like ...
ofd_find_attrs($func_die,
DW_AT_TI_symbol_name => \$func_name,
DW_AT_low_pc => \$start_addr,
DW_AT_high_pc => \$end_addr);
Tip on recommended use: Set all the scalars to undef just before calling, then insure that subsequent code can handle any one scalar remaining undef.
If the command line option --cg_xml_version is present, print out, on stderr, the version of the cg_xml package in use. Must be called BEFORE the main script does any command line processing.
You can have Perl automatically check you are using the correct version of XML_TI_OFD.pm by writing something similar to ...
use XML_TI_OFD 2.11;
So you know what version to check for, here is a quick summary of what version introduced which functions or changes ...
Introduce the functions:
- ofd_process_xml_file
- ofd_find_lib_name
- ofd_get_input_file_name
- ofd_each_file
- ofd_each_section
- ofd_each_symbol
- ofd_each_die_entry
Introduces the function:
- ofd_strip_xml
Introduces the functions:
- ofd_filter_xml
- ofd_has_dwarf
- ofd_find_debug_info
- ofd_find_compile_unit_die
- ofd_find_all_dies
- ofd_find_attrs
Also, can pass string to ofd_strip_xml by passing undef for the file arg
Introduces the functions:
- ofd_filter_and_parse_xml
- ofd_put_dies_in_array
- ofd_put_dies_in_hash
Introduces support for ELF files.
Introduces the function: ofd_cg_xml_version
Access to this variable and function are strictly limited to the fully qualified XML_TI_OFD:: syntax. These names are too widely used to be handled any other way.
Whether to dump the Perl data structures to stdout. Set to undef by default.
Input: Reference to all or part of the Perl data structure corresponding to the XML file.
Returns: Nothing
Dumps the Perl data structure to STDOUT. Helpful for understanding how to traverse the data structure, or diagnose bugs.
Documentation for XML_TI_OFD.pm |