1.3. Binary Utility Differences¶
There are several differences in the behavior of the asm() statement and binary utilities used for C++ name demangling, symbol name listing, and disassembly. These differences are described here.
1.3.1. Inlining Functions that Contain asm() Statements¶
The tiarmclang compiler allows a function containing an asm() statement to be considered for inlining. The TI ARM compiler does not allow a function containing an asm() statement to be inlined.
If an asm() statement in a function contains the definition of a symbol, then you should strongly consider applying a noinline attribute to the function that contains such an asm() statement.
For example, consider the following function definition:
void func_a() {
...
asm("a_label:\n");
...
}
The above function contains a definition of a_label. The TI ARM compiler does not allow any function that contains an asm() statement to be inlined. Thus, in the above example, the TI ARM compiler would not attempt to inline func_a in any other function that references func_a.
The tiarmclang compiler behavior with respect to functions that contain asm() statements is different from the TI ARM compiler. The tiarmclang compiler allows functions containing asm() statements to be considered for inlining where those functions are referenced. If a function contains an asm() statement that defines a symbol and is inlined multiple times in the same compilation unit, this can cause the tiarmclang compiler to emit a “symbol multiply defined” error diagnostic.
Consider that the above definition of func_a is in the same compilation unit as another function, func_b:
void func_b() {
...
func_a();
...
func_a();
...
}
If the tiarmclang compiler decides that it is beneficial to inline func_a where that function is referenced in func_b, the result is multiple definitions of the label a_label and the tiarmclang compiler emits an error diagnostic.
You can prevent the tiarmclang compiler from inlining a function by applying a noinline attribute to the function in question. For example, you could rewrite func_a as follows:
__attribute__((noinline))
void func_a() {
...
asm("a_label:\n");
...
}
This adjustment to the definition of func_a prevents func_a from being inlined anywhere where it is referenced and avoid any potential of defining a_label multiple times in the same compilation unit.
1.3.2. Updated C++ Name Demangler Utility (tiarmdem)¶
The TI Arm Clang (tiarmclang) Compiler Tools include an LLVM-based version of the C++ Name Demangler Utility (tiarmdem). While the LLVM-based version of this utility is functionally equivalent to the TI ARM compiler tools’ version, the command-line interface for the new version is different from the TI ARM version.
The C++ name demangler (tiarmdem) is a debugging aid that translates C++ mangled names to their original name found in the relevant C++ source code. The tiarmdem utility reads in input, looking for mangled names. All unmangled text is copied to output unaltered. All mangled names are demangled before being copied to output.
The syntax for invoking the C++ name demangler provided with tiarmclang is:
tiarmdem [options] <mangled names ...>
options - affect how the name demangler behaves. The tiarmdem utility is derived from the LLVM project’s llvm-cxxfilt tool. To display a list of available options, use the help option (-h), tiarmdem -h. You can also refer to the LLVM project’s llvm-cxxfilt page for more information.
mangled names … - if no names are specified on the command-line, names are read interactively from the standard input stream.
By default, the C++ name demangler writes output to stdout. You can pipe the output to a file if desired.
Differences between the TI ARM version of the C++ name demangler and the tiarmclang version of the C++ name demangler are as follows.
1.3.2.1. Processing Text Input¶
Unlike the TI ARM version of the C++ name demangler, the tiarmclang version of tiarmdem does not process a text file specified as an argument to tiarmdem. Assuming that test.s is a compiler generated assembly file, you cannot specify test.s as an argument to tiarmdem. Instead, you can pipe the text file as input to the tiarmdem utility as follows:
tiarmdem < test.s
or
cat test.s | tiarmdem
1.3.2.2. Saving Output to a File¶
The TI ARM version of the C++ name demangler supported an “--output-file” option that allowed you to write the output of the tiarmdem utility to a file. The tiarmclang version of tiarmdem does not support a --output option. Instead, the output can be redirected to a file like so:
cat test.s | tiarmdem > tiarmdemout
1.3.2.3. No ABI Option Needed¶
The TI ARM version of the C++ name demangler required that an --abi=eabi option be specified in order to demangle C++ names that are generated by the tiarmclang compiler. The tiarmclang version of tiarmdem assumes EABI and no ABI option is needed to process tiarmclang compiler generated C++ mangled names.
1.3.3. Updated Name Utility (tiarmnm)¶
The TI Arm Clang (tiarmclang) Compiler Tools include an LLVM-based version of the Name Utility (tiarmnm). While the LLVM-based version of this utility is functionally equivalent to the TI ARM compiler tools’ version, the command-line interface for the new version is different from the TI ARM version.
The name utility (tiarmnm) prints the list of symbol names defined and referenced in an object file, executable file, or object library. It also prints the symbol value and an indication of the symbol’s kind.
The syntax for invoking the name utility is:
tiarmnm [options] <input files>
options - affect how the name utility behaves. The tiarmnm utility is derived from the LLVM project’s llvm-nm tool. To display a list of available options, use the help option (-h), tiarmnm -h. You can also refer to the LLVM project’s llvm-nm page for more information.
input files - an input file can be an object file, an executable file, or an object library
The output of the name utility is written to stdout. You can also elect to pipe the output to a file or as input to the C++ name demangler.
Differences between the TI ARM version of the C++ name utility and the tiarmclang version of the C++ name utility are as follows.
1.3.3.1. Symbol Kind Annotations¶
In the output from the tiarmnm utility, symbol names are annotated with an indication of their kind. The tiarmclang version of the tiarmnm utility uses the following list of annotation characters to represent the different symbol kinds:
a, A - absolute symbol
b, B - uninitialized data (bss) object
C - common symbol
d, D - writable data object
n - local symbol from a non-alloc section
N - debug symbol or global symbol from a non-alloc section
r, R - read-only data object
t, T - code (text) object
u - GNU unique symbol
U - named object is undefined in this file
v - undefined weak object symbol
V - defined weak object symbol
? - something unrecognizable
1.3.3.2. Thumb Function Symbols¶
In the TI ARM version of the name utility, the value of a thumb function symbol would include a 1 in the least significant bit (the thumb mode bit), but the tiarmclang version of tiarmnm does not report a 1 in the least significant bit position for thumb function symbol values.
1.3.3.3. Debug Symbol Names¶
The TI ARM version of the name utility would include debug symbol names in the output. However, to include debug symbols in the output of the tiarmclang version of tiarmnm, you must specify the tiarmnm’s --debug-syms option on the command-line.
1.3.3.4. Functionally Equivalent Option Mappings¶
Several of the options available in the TI ARM version of the name utility now have functionally equivalent options with different syntax in the tiarmclang version of the tiarmnm utility. Below is a list of option mappings where the TI ARM’s armnm option syntax is specified first and the tiarmclang’s tiarmnm option syntax is specified second:
KEY: TI ARM armnm option syntax -> TI Arm tiarmnm option syntax - description
--all -> --debug-syms - print all symbols
--prep_fname -> --print-file-name - prepend file name to each symbol
--undefined -> --undefined-only - only print undefined symbols
--sort:value -> --numeric-sort - sort symbols numerically rather than alphabetically
--sort:reverse -> --reverse-sort - sort symbols in reverse order
--global -> --externs-only - print only global symbols
--sort:none -> --no-sort - don’t sort any symbols
1.3.3.5. Options No Longer Supported¶
The TI ARM version of the name utility supported several command-line options that are no longer supported in the tiarmclang version of the tiarmnm utility. These include:
--format:long - produce detailed listing of symbol information
--output - write output to a specified file
--quiet - suppress banner and progress information
1.3.3.6. Symbol Kind Annotations¶
The TI ARM version of the name utility annotates some symbols with kind information differently than the tiarmclang version of the tiarmnm utility. One of the known differences is that the previous version of the name utility uses ‘d’ to annotate debug symbols, whereas the new version of tiarmnm uses ‘N’. There may be other differences. Please consult the above list of symbol kind annotations for the tiarmnm utility for more information.
1.3.3.7. Saving Output to a File¶
As indicated above, the TI ARM version of the name utility supports a command-line option to write the output to a specified file, but the tiarmclang version of the tiarmnm utility does not support such a command-line option. Instead, you can elect to pipe the output of tiarmnm to a file:
tiarmnm test.o > tiarmnmout
or to the C++ name demangler utility, for example:
tiarmnm test.o | tiarmdem > tiarmdemout
1.3.4. An Example Using the Name Utility (tiarmnm) and the Name Demangler Utility (tiarmdem)¶
Consider the following source file (test.cpp):
int g_my_num;
namespace NS { int ns_my_num = 2; }
int f() { return g_my_num + NS::ns_my_num; }
int main() { return f(); }
If the above test.cpp is compiled:
tiarmclang -mcpu=cortex-m4 -c test.cpp
We can then use the tiarmnm utility to write out the symbol names in test.o:
%> tiarmnm test.o
00000000 T _Z1fv
00000000 D _ZN2NS9ns_my_numE
00000000 B g_my_num
00000000 T main
and we could pass the output of tiarmnm to tiarmdem to demangle the mangled names that are present in the tiarmnm output:
%> tiarmnm test.o | tiarmdem
00000000 T f()
00000000 D NS::ns_my_num
00000000 B g_my_num
00000000 T main
1.3.5. Disassembling Object Files¶
The tiarmclang compiler toolchain provides two utilities that can be used to disassemble TI Arm object files, tiarmobjdump and tiarmdis.
tiarmobjdump
When invoked with the --disassemble (or -d) command, tiarmobjdump emits disassembled output for an Arm object file. If an Arm object file contains C/C++ source debug information, then the --source (or -S) option can be used to emit interlisted C/C++ source with the disassembled output.
tiarmobjdump –disassemble [options] filename
See the tiarmobjdump - Object File Dumper section for more information about the tiarmobjdump utility.
tiarmdis
The standalone tiarmdis disassembler installed as part of the tiarmclang compiler toolchain is identical to the armdis utility that is provided with the legacy TI Arm C/C++ compiler toolchain (armcl).
tiarmdis [options] input_file [output_file]
If an output_file is not specified, the disassembly output is written to stdout.
See the tiarmdis - Standalone Disassembler Tool section for more information about the tiarmdis utility.