1.3. Behavioral Differences Between armcl and tiarmclang Binary Utilities

1.3.1. Inlining Functions that Contain asm() Statements

The tiarmclang will allow a function containing an asm() statement to be considered for inlining. The armcl compiler will 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 armcl compiler will not allow any function that contains an asm() statement to be inlined. Thus, in the above example, the armcl 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 armcl 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, then this will result in multiple definitions of the label a_label and the tiarmclang compiler will emit 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 will prevent 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 (tiarmdem) and Name (tiarmnm) Utilities

The TI Arm Clang (tiarmclang) Compiler Tools include LLVM-based versions of the C++ Name Demangler Utility (tiarmdem) and the Name Utility (tiarmnm). While the LLVM-based versions of these utilities are functionally equivalent to the armcl compiler tools’ versions, the command-line interfaces for the new versions are different from the armcl versions.

1.3.2.1. C++ Name Demangler Utility (tiarmdem)

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 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.

1.3.2.1.1. Differences vs. armcl Version of C++ Name Demangler

Processing Text Input

Unlike the armcl version of the C++ name demangler, the tiarmclang version of tiarmdem will 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

Saving Output to a File

The armcl 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

No ABI Option Needed

The armcl 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.2.2. Name Utility (tiarmnm)

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.

1.3.2.2.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.2.2.2. Differences vs. armcl Version of Name Utility

Thumb Function Symbols

In the armcl 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 will not report a 1 in the least significant bit position for thumb function symbol values.

Debug Symbol Names

The armcl 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.

Command-Line Options

Functionally Equivalent Option Mappings

Several of the options available in the armcl 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 armcl’s armnm option syntax is specified first and the tiarmclang’s tiarmnm option syntax is specified second:

KEY: armnm option syntax -> 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

Options No Longer Supported

The armcl 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

Symbol Kind Annotations

The armcl version of the name utility will annotate 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.

Saving Output to a File

As indicated above, the armcl 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.2.3. An Example

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.3. Disassembling Object Files - tiarmobjdump and tiarmdis

The tiarmclang compiler toolchain provides two utilities that can be used to disassemble Arm object files, tiarmobjdump and tiarmdis.

tiarmobjdump

When invoked with the --disassemble* (or -d) command, tiarmobjdump will emit 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.

Note

The tiarmobjdump utility that is provided with version 1.1.0+STS of the tiarmclang compiler toolchain will emit incorrect disassembly output for some instructions. A fix for this defect will be made available in the tiarmclang version 1.2.0.STS release.

In the meantime, it is recommended that you use the standalone tiarmdis disassembler utility to disassemble Arm object files. 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.