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 c29clang compiler allows a function containing an asm() statement to be considered for inlining. The TI C28x 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 C28x compiler does not allow any function that contains an asm() statement to be inlined. Thus, in the above example, the TI C28x compiler would not attempt to inline func_a in any other function that references func_a.

The c29clang compiler behavior with respect to functions that contain asm() statements is different from the TI C28x compiler. The c29clang 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 c29clang 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 c29clang 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 c29clang compiler emits an error diagnostic.

You can prevent the c29clang 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 (c29dem)

The TI C29x Clang (c29clang) Compiler Tools include an LLVM-based version of the C++ Name Demangler Utility (c29dem). While the LLVM-based version of this utility is functionally equivalent to the TI C28x compiler tools’ version, the command-line interface for the new version is different from the TI C28x version.

The C++ name demangler (c29dem) is a debugging aid that translates C++ mangled names to their original name found in the relevant C++ source code. The c29dem 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 c29clang is:

c29dem [options] <mangled names ...>
  • options - affect how the name demangler behaves. The c29dem utility is derived from the LLVM project’s llvm-cxxfilt tool. To display a list of available options, use the help option (-h), c29dem -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 C28x version of the C++ name demangler and the c29clang version of the C++ name demangler are as follows.

1.3.2.1. Processing Text Input

Unlike the TI C28x version of the C++ name demangler, the c29clang version of c29dem does not process a text file specified as an argument to c29dem. Assuming that test.s is a compiler generated assembly file, you cannot specify test.s as an argument to c29dem. Instead, you can pipe the text file as input to the c29dem utility as follows:

c29dem < test.s

or

cat test.s | c29dem

1.3.2.2. Saving Output to a File

The TI C28x version of the C++ name demangler supported an “--output-file” option that allowed you to write the output of the c29dem utility to a file. The c29clang version of c29dem does not support a --output option. Instead, the output can be redirected to a file like so:

cat test.s | c29dem > c29demout

1.3.2.3. No ABI Option Needed

The TI C28x 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 c29clang compiler. The c29clang version of c29dem assumes EABI and no ABI option is needed to process c29clang compiler generated C++ mangled names.

1.3.3. Updated Name Utility (c29nm)

The TI C29x Clang (c29clang) Compiler Tools include an LLVM-based version of the Name Utility (c29nm). While the LLVM-based version of this utility is functionally equivalent to the TI C28x compiler tools’ version, the command-line interface for the new version is different from the TI C28x version.

The name utility (c29nm) 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:

c29nm [options] <input files>
  • options - affect how the name utility behaves. The c29nm utility is derived from the LLVM project’s llvm-nm tool. To display a list of available options, use the help option (-h), c29nm -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 C28x version of the C++ name utility and the c29clang version of the C++ name utility are as follows.

1.3.3.1. Symbol Kind Annotations

In the output from the c29nm utility, symbol names are annotated with an indication of their kind. The c29clang version of the c29nm 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.3. Debug Symbol Names

The TI C28x version of the name utility would include debug symbol names in the output. However, to include debug symbols in the output of the c29clang version of c29nm, you must specify the c29nm’s --debug-syms option on the command-line.

1.3.3.4. Functionally Equivalent Option Mappings

Several of the options available in the TI C28x version of the name utility now have functionally equivalent options with different syntax in the c29clang version of the c29nm utility. Below is a list of option mappings where the TI C28x’s nm2000 option syntax is specified first and the c29clang’s c29nm option syntax is specified second:

KEY: TI C28x nm2000 option syntax -> TI C29x c29nm 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 C28x version of the name utility supported several command-line options that are no longer supported in the c29clang version of the c29nm 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 C28x version of the name utility annotates some symbols with kind information differently than the c29clang version of the c29nm 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 c29nm uses ‘N’. There may be other differences. Please consult the above list of symbol kind annotations for the c29nm utility for more information.

1.3.3.7. Saving Output to a File

As indicated above, the TI C28x version of the name utility supports a command-line option to write the output to a specified file, but the c29clang version of the c29nm utility does not support such a command-line option. Instead, you can elect to pipe the output of c29nm to a file:

c29nm test.o > c29nmout

or to the C++ name demangler utility, for example:

c29nm test.o | c29dem > c29demout

1.3.4. An Example Using the Name Utility (c29nm) and the Name Demangler Utility (c29dem)

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:

c29clang -mcpu=c29.c0 -c test.cpp

We can then use the c29nm utility to write out the symbol names in test.o:

%> c29nm 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 c29nm to c29dem to demangle the mangled names that are present in the c29nm output:

%> c29nm test.o | c29dem
00000000 T f()
00000000 D NS::ns_my_num
00000000 B g_my_num
00000000 T main

1.3.5. Disassembling Object Files

The c29clang compiler toolchain provides a utility that can be used to disassemble TI C29x object files: c29objdump.

When invoked with the --disassemble (or -d) command, c29objdump emits disassembled output for a C29x object file. If a C29x 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.

c29objdump –disassemble [options] filename

See the c29objdump - Object File Dumper section for more information about the c29objdump utility.

The dis2000 utility that is provided with the proprietary TI C29x C/C++ compiler toolchain (cl2000) has no equivalent in the c29clang compiler toolchain. Use the c29objdump utility instead.