Check LLVM TargetLibraryInfo Against Real Shared Libraries
You will finish with a repeatable check of whether LLVM's TargetLibraryInfo (TLI) agrees with the functions exported by one or more library files. The examples use llvm-tli-checker-20 from Debian package llvm-20, version 1:20.1.8~++20250804090239+87f0227cb601-1~exp1~20250804210352.139. Allow about fifteen minutes if the libraries are already available.
The route
Jump straight to the step you need, or tick off Done means at the end.
This is an inspection tool. It reads library files and reports differences; it does not modify LLVM, the libraries or the dynamic linker. You need a shell, the installed LLVM 20 tools and readable library files. The commands below do not require elevated privileges. If a library is readable only by root, fix the access decision separately rather than running an unfamiliar checker command with sudo.
1. Confirm the installed checker
Start by checking which executable will run and asking it for its option list:
$ command -v llvm-tli-checker-20
/usr/bin/llvm-tli-checker-20
$ dpkg-query -W -f='${Package} ${Version}\n' llvm-20
llvm-20 1:20.1.8~++20250804090239+87f0227cb601-1~exp1~20250804210352.139
$ llvm-tli-checker-20 --help
OVERVIEW: LLVM TargetLibraryInfo versus SDK checker
USAGE: llvm-tli-checker-20 [options] library-file [library-file...]
OPTIONS:
--dump-tli Dump TLI's list of functions and whether they are available
--help Display available options
-h Alias for --help
The checker compares TLI with symbols in the files you name. It is not a general ELF dependency checker, and a clean process exit does not mean that every comparison matched.
Checkpoint
The executable should be the LLVM 20 binary you intended to test. If command -v finds a wrapper or a different installation, stop and correct your PATH before interpreting its output.
2. Choose the target triple explicitly
TLI is target-specific, so make the target explicit rather than relying on an implicit or empty triple. For this x86-64 Linux host, use x86_64-pc-linux-gnu:
$ llvm-tli-checker-20 --triple=x86_64-pc-linux-gnu --dump-tli | sed -n '1,6p'
TLI knows 523 symbols, 477 available for 'x86_64-pc-linux-gnu'
not available: '??2@YAPAXI@Z' aka void * __cdecl operator new(unsigned int)
not available: '??2@YAPAXIABUnothrow_t@std@@@Z' aka void * __cdecl operator new(unsigned int, struct std::nothrow_t const &)
not available: '??2@YAPEAX_K@Z' aka void * __cdecl operator new(unsigned __int64)
not available: '??2@YAPEAX_KAEBUnothrow_t@std@@@Z' aka void * __cdecl operator new(unsigned __int64, struct std::nothrow_t const &)
--dump-tli needs no input library. It prints each library function known to TLI and whether it is available for the selected triple, then exits. The list is a useful sanity check for a triple, not a verdict about the libraries on disk.
3. Run a summary comparison
Pick an actual shared library. On this machine, the C library is /usr/lib/x86_64-linux-gnu/libc.so.6. Request a summary to keep the first report short:
$ llvm-tli-checker-20 \
--triple=x86_64-pc-linux-gnu \
--report=summary \
/usr/lib/x86_64-linux-gnu/libc.so.6
TLI knows 523 symbols, 477 available for 'x86_64-pc-linux-gnu'
Looking for symbols in '/usr/lib/x86_64-linux-gnu/libc.so.6'
Found 2641 global function symbols in '/usr/lib/x86_64-linux-gnu/libc.so.6'
Found a grand total of 2641 library symbols
<< Total TLI yes SDK no: 278
>> Total TLI no SDK yes: 0
== Total TLI yes SDK yes: 199
FAIL: LLVM TLI doesn't match SDK libraries.
The labels are comparisons, not shell failures. "TLI yes SDK no" means TLI considers a function available but the library did not export it. "TLI no SDK yes" is the reverse. "TLI yes SDK yes" is a match. The example deliberately shows a mismatch so you can recognise the report format.
Checkpoint
Verify the file path and target triple before acting on a discrepancy. A library for another architecture, ABI or SDK is not evidence that the selected TLI data is wrong.
4. See the mismatching symbols
The default report level is discrepancy, which lists mismatching symbols as well as totals. Use it when the summary identifies a problem:
$ llvm-tli-checker-20 \
--triple=x86_64-pc-linux-gnu \
--report=discrepancy \
/usr/lib/x86_64-linux-gnu/libc.so.6 | sed -n '1,18p'
TLI knows 523 symbols, 477 available for 'x86_64-pc-linux-gnu'
Looking for symbols in '/usr/lib/x86_64-linux-gnu/libc.so.6'
Found 2641 global function symbols in '/usr/lib/x86_64-linux-gnu/libc.so.6'
Found a grand total of 2641 library symbols
<< TLI yes SDK no: '...'
>> TLI no SDK yes: '...'
The exact names depend on the installed library, so do not hard-code a particular discrepancy into automation. Use the output to investigate the target's TLI definition, the SDK or library build, and the ABI assumptions that produced the pair.
--report=full is available when you need all symbols known to TLI, including matches. It can be much noisier than a discrepancy report and is usually better saved to a file for later inspection.
5. Compare several library files
Pass more than one library when the SDK is split across files. Add --separate to get a report for each file rather than only a combined result:
$ llvm-tli-checker-20 \
--triple=x86_64-pc-linux-gnu \
--separate \
--report=summary \
/usr/lib/x86_64-linux-gnu/libm.so.6 \
/usr/lib/x86_64-linux-gnu/libc.so.6
TLI knows 523 symbols, 477 available for 'x86_64-pc-linux-gnu'
Looking for symbols in '/usr/lib/x86_64-linux-gnu/libm.so.6'
Found 1067 global function symbols in '/usr/lib/x86_64-linux-gnu/libm.so.6'
<< Total TLI yes SDK no: 306
>> Total TLI no SDK yes: 3
== Total TLI yes SDK yes: 171
--separate implies summary unless you override it with another report level. This mode helps find a file that contributes no symbols TLI knows about. The checker still returns status 0 for a mismatch, so capture and interpret its text rather than using only the process status.
6. Make a script fail for operational errors
The command returns 0 even when TLI and the library disagree. It returns non-zero for an unrecognised option or when no input files are provided. A small wrapper can distinguish those tool errors, while leaving the domain decision to your review process:
if ! llvm-tli-checker-20 \
--triple=x86_64-pc-linux-gnu \
--report=summary \
/usr/lib/x86_64-linux-gnu/libc.so.6 \
> checker-report.txt 2>&1
then
status=$?
printf 'checker could not run, status %s\n' "$status" >&2
exit "$status"
fi
sed -n '1,12p' checker-report.txt
This creates or replaces checker-report.txt in the current directory. That is the only state-changing example in this guide. If you do not need the report, remove that file with rm -- checker-report.txt after checking its contents. Do not delete a report that is part of an audit record without following your retention policy.
Common traps
- Do not treat
FAIL: LLVM TLI doesn't match SDK libraries.as a non-zero exit status. The manpage explicitly says mismatches still return 0. - Do not omit
--triplewhen comparing a cross-compiled SDK. The target controls the TLI opinion. - Do not pass a directory where a library file is expected. Use
--libdir=when several named files share a base directory, or provide full paths. - Do not assume a symbol count proves ABI compatibility. The checker compares exported global function symbols with TLI's known functions; it does not replace an ABI or link test.
Done means
- The command path and installed
llvm-20version are confirmed. - The target triple matches the libraries being checked.
- You have run a summary comparison and, where needed, a discrepancy report.
- You know that exit status 0 does not mean that there were no mismatches.
- Any saved report has an intentional retention or removal decision.