Skip to content

Commit ba20d3d

Browse files
committed
[llvm-gsymutil] Option --symtab-file to specify a separate binary for symbol table
Summary: I made minimal changes possible to enable this for Strobelight's llvm-gsymutil migration. Since Strobelight is only on linux dealing with ELF, and no Universal Binary will be involved, I am making the `--symtab-file` option limited to the simple object file case. We will need to refactor the code to better handle the `MachOUniversalBinary` type given there're different arch involved. Test Plan: I made a private build of `llvm-gsymutil` that can be downloaded with ``` jf download GICWmABaZb_9K94FAI4uIkiuhtZebpZBAAAB --file "llvm-gsymutil" ``` Manually tested the conversion using files from IndexerTest.cpp unit tests. Use both `main` & `main.debug` ``` $ /home/wanyi/llvm-sand/build/Debug/fbcode-x86_64/toolchain/bin/llvm-gsymutil --convert main.debug --symtab-file main -o main.gsym Input file: main.debug Output file (x86_64): main.gsym Loaded 1 functions from DWARF. Using symbol table file: main Loaded 9 functions from symbol table. Pruned 0 functions, ended with 10 total ``` Use only `main.debug` (debug info only) ``` $ /home/wanyi/llvm-sand/build/Debug/fbcode-x86_64/toolchain/bin/llvm-gsymutil --convert main.debug -o debug_info_only.gsym Input file: main.debug Output file (x86_64): debug_info_only.gsym Loaded 1 functions from DWARF. Loaded 0 functions from symbol table. Pruned 0 functions, ended with 1 total ``` Use only `main` (symbol table only) ``` $ /home/wanyi/llvm-sand/build/Debug/fbcode-x86_64/toolchain/bin/llvm-gsymutil --convert main -o symbol_table_only.gsym Input file: main Output file (x86_64): symbol_table_only.gsym Loaded 0 functions from DWARF. Loaded 10 functions from symbol table. Pruned 0 functions, ended with 10 total ``` ELF debug info + universal binary for symbol table ``` [[email protected] ~/fbsource/fbcode/services_efficiency/symbol_service/tests/testpackage3 (71a39fcf2|remote/master)]$ file universal universal: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit x86_64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|WEAK_DEFINES|BINDS_TO_WEAK|PIE>] [arm64:Mach-O 64-bit arm64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|WEAK_DEFINES|BINDS_TO_WEAK|PIE>] [[email protected] ~/fbsource/fbcode/services_efficiency/symbol_service/tests/testpackage3 (71a39fcf2|remote/master)]$ /home/wanyi/llvm-sand/build/Debug/fbcode-x86_64/toolchain/bin/llvm-gsymutil --convert main.debug --symtab-file universal Input file: main.debug Output file (x86_64): main.debug.gsym Loaded 1 functions from DWARF. Using symbol table file: universal DWARF conversion failed: : Input symbol table file universal is not a valid object file. Supported files are ELF and mach-o (exclude universal binary) files. ``` Symbol table only ``` Desktop/tmp/test_llvm-gsymutil ▶ /Users/wanyi/llvm-sand/build/Debug/Darwin-arm64/toolchain/bin/llvm-gsymutil --convert universal Input file: universal Output file (x86_64): universal.gsym.x86_64 Loaded 0 functions from DWARF. Loaded 50 functions from symbol table. Pruned 0 functions, ended with 50 total Output file (arm64): universal.gsym.arm64 Loaded 0 functions from DWARF. Loaded 50 functions from symbol table. Pruned 0 functions, ended with 50 total ``` dSYM -both debug info & symbol table ``` Desktop/tmp/test_llvm-gsymutil ▶ /Users/wanyi/llvm-sand/build/Debug/Darwin-arm64/toolchain/bin/llvm-gsymutil --convert universal.dSYM/Contents/Resources/DWARF/universal -o debug_info Input file: universal.dSYM/Contents/Resources/DWARF/universal Output file (x86_64): debug_info.x86_64 Loaded 49 functions from DWARF. Loaded 1 functions from symbol table. Pruned 0 functions, ended with 50 total Output file (arm64): debug_info.arm64 Loaded 49 functions from DWARF. Loaded 1 functions from symbol table. Pruned 0 functions, ended with 50 total ``` `--symtab-file` flag should fail ``` Desktop/tmp/test_llvm-gsymutil ▶ /Users/wanyi/llvm-sand/build/Debug/Darwin-arm64/toolchain/bin/llvm-gsymutil --convert universal.dSYM/Contents/Resources/DWARF/universal --symtab-file universal Input file: universal.dSYM/Contents/Resources/DWARF/universal DWARF conversion failed: : --symtab-file is not accepted for universal binary conversion ``` I wasn't able to strip the symbol table out of the DWARF Tried following ``` Desktop/tmp/test_llvm-gsymutil ▶ /opt/llvm/bin/llvm-objcopy --only-keep-debug arm64.dSYM/Contents/Resources/DWARF/arm64 arm64.debug Desktop/tmp/test_llvm-gsymutil ▶ objdump --syms arm64.debug | awk '{print $5;}' > symbols Desktop/tmp/test_llvm-gsymutil ▶ /opt/llvm/bin/llvm-objcopy --strip-symbols=./symbols arm64.debug ``` dSYM - both debug info & symbol table ``` Desktop/tmp/test_llvm-gsymutil ▶ /Users/wanyi/llvm-sand/build/Debug/Darwin-arm64/toolchain/bin/llvm-gsymutil --convert arm64.dSYM/Contents/Resources/DWARF/arm64 -o arm64_debug_info Input file: arm64.dSYM/Contents/Resources/DWARF/arm64 Output file (aarch64): arm64_debug_info Loaded 49 functions from DWARF. Loaded 1 functions from symbol table. Pruned 0 functions, ended with 50 total ``` Symbol table only ``` Desktop/tmp/test_llvm-gsymutil ▶ /Users/wanyi/llvm-sand/build/Debug/Darwin-arm64/toolchain/bin/llvm-gsymutil --convert arm64 -o arm64_symbol_table Input file: arm64 Output file (aarch64): arm64_symbol_table Loaded 0 functions from DWARF. Loaded 50 functions from symbol table. Pruned 0 functions, ended with 50 total ``` Reviewers: slinger, jeffreytan Reviewed By: jeffreytan Subscribers: ayermolo, #lldb_team Differential Revision: https://phabricator.intern.facebook.com/D45341225 Tasks: T151296270 Tags: aarch64 Commit #2 Differential Revision: https://phabricator.intern.facebook.com/D45792908 Commit #2 Tasks: T152287419 Commit llvm#3 Differential Revision: https://phabricator.intern.facebook.com/D49360184
1 parent 4159b47 commit ba20d3d

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

llvm/tools/llvm-gsymutil/Opts.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,6 @@ def addresses_from_stdin :
4040
defm json_summary_file :
4141
Eq<"json-summary-file",
4242
"Output a categorized summary of errors into the JSON file specified.">;
43+
defm symtab_file :
44+
Eq<"symtab-file",
45+
"Specify a separate file for symbol table to GSYM conversion.\nIn case the symbol table and debug info are not in the same binary. Does not support universal binary.">;

llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ static bool Quiet;
9696
static std::vector<uint64_t> LookupAddresses;
9797
static bool LookupAddressesFromStdin;
9898
static bool StoreMergedFunctionInfo = false;
99+
static std::string SymbolTableFilename;
99100

100101
static void parseArgs(int argc, char **argv) {
101102
GSYMUtilOptTable Tbl;
@@ -114,8 +115,9 @@ static void parseArgs(int argc, char **argv) {
114115
"information in each GSYM file.\n"
115116
"Specify a single GSYM file along with one or more --lookup options to "
116117
"lookup addresses within that GSYM file.\n"
117-
"Use the --convert option to specify a file with option --out-file "
118-
"option to convert to GSYM format.\n";
118+
"Use the --convert option to specify a file (with --symtab-file if "
119+
"needed) "
120+
"with option --out-file option to convert to GSYM format.\n";
119121

120122
Tbl.printHelp(llvm::outs(), "llvm-gsymutil [options] <input GSYM files>",
121123
Overview);
@@ -177,6 +179,9 @@ static void parseArgs(int argc, char **argv) {
177179

178180
LookupAddressesFromStdin = Args.hasArg(OPT_addresses_from_stdin);
179181
StoreMergedFunctionInfo = Args.hasArg(OPT_merged_functions);
182+
183+
if (const llvm::opt::Arg *A = Args.getLastArg(OPT_symtab_file_EQ))
184+
SymbolTableFilename = A->getValue();
180185
}
181186

182187
/// @}
@@ -367,7 +372,38 @@ static llvm::Error handleObjectFile(ObjectFile &Obj, const std::string &OutFile,
367372
Gsym.prepareMergedFunctions(Out);
368373

369374
// Get the UUID and convert symbol table to GSYM.
370-
if (auto Err = ObjectFileTransformer::convert(Obj, Out, Gsym))
375+
// Use a separate file for symbol table if specified
376+
std::string SymtabFile = SymbolTableFilename;
377+
ErrorOr<std::unique_ptr<MemoryBuffer>> SymtabBuffOrErr = nullptr;
378+
std::unique_ptr<MemoryBuffer> SymtabBuffer = nullptr;
379+
if (!SymtabFile.empty()) {
380+
outs() << "Using symbol table file: " << SymbolTableFilename << "\n";
381+
SymtabBuffOrErr = MemoryBuffer::getFileOrSTDIN(SymtabFile);
382+
error(SymtabFile, SymtabBuffOrErr.getError());
383+
SymtabBuffer = std::move(SymtabBuffOrErr.get());
384+
Expected<std::unique_ptr<Binary>> SymtabBinOrErr =
385+
object::createBinary(*SymtabBuffer);
386+
error(SymtabFile, errorToErrorCode(SymtabBinOrErr.takeError()));
387+
if (auto Symtab = dyn_cast<ObjectFile>(SymtabBinOrErr->get())) {
388+
Triple ObjTriple(Obj.makeTriple());
389+
Triple SymtabTriple(Symtab->makeTriple());
390+
if (ObjTriple.getArchName() != SymtabTriple.getArchName())
391+
return createStringError(std::errc::invalid_argument,
392+
"Cannot use symbol table file %s in %s for "
393+
"binary in %s architecture.",
394+
SymtabFile.c_str(),
395+
ObjTriple.getArchName().data(),
396+
SymtabTriple.getArchName().data());
397+
if (auto Err = ObjectFileTransformer::convert(*Symtab, Out, Gsym))
398+
return Err;
399+
} else
400+
return createStringError(std::errc::invalid_argument,
401+
"Input symbol table file %s is not a "
402+
"valid object file.\n"
403+
"Supported files are ELF and mach-o "
404+
"(exclude universal binary) files.",
405+
SymtabFile.c_str());
406+
} else if (auto Err = ObjectFileTransformer::convert(Obj, Out, Gsym))
371407
return Err;
372408

373409
// Finalize the GSYM to make it ready to save to disk. This will remove
@@ -410,6 +446,12 @@ static llvm::Error handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
410446
if (auto Err = handleObjectFile(*Obj, OutFile, Out))
411447
return Err;
412448
} else if (auto *Fat = dyn_cast<MachOUniversalBinary>(BinOrErr->get())) {
449+
// Symbol table file is not accepted with universal binary
450+
std::string SymtabFile = SymbolTableFilename;
451+
if (!SymtabFile.empty())
452+
return createStringError(std::errc::invalid_argument,
453+
"--symtab-file is not accepted for "
454+
"universal binary conversion");
413455
// Iterate over all contained architectures and filter out any that were
414456
// not specified with the "--arch <arch>" option. If the --arch option was
415457
// not specified on the command line, we will process all architectures.

0 commit comments

Comments
 (0)