Index: lldb/trunk/lit/Modules/ELF/build-id-case.yaml =================================================================== --- lldb/trunk/lit/Modules/ELF/build-id-case.yaml +++ lldb/trunk/lit/Modules/ELF/build-id-case.yaml @@ -1,7 +1,7 @@ # RUN: mkdir -p %t/.build-id/1b # RUN: yaml2obj %s > %t/.build-id/1b/8a73ac238390e32a7ff4ac8ebe4d6a41ecf5c9.debug # RUN: cd %t -# RUN: llvm-objcopy --strip-all --add-gnu-debuglink=.build-id/1b/8a73ac238390e32a7ff4ac8ebe4d6a41ecf5c9.debug %t/.build-id/1b/8a73ac238390e32a7ff4ac8ebe4d6a41ecf5c9.debug %t/stripped.out +# RUN: llvm-objcopy --strip-all %t/.build-id/1b/8a73ac238390e32a7ff4ac8ebe4d6a41ecf5c9.debug %t/stripped.out # RUN: lldb-test object-file %t/stripped.out | FileCheck %s # CHECK: Name: .debug_frame Index: lldb/trunk/lit/Modules/ELF/gnu-debuglink.yaml =================================================================== --- lldb/trunk/lit/Modules/ELF/gnu-debuglink.yaml +++ lldb/trunk/lit/Modules/ELF/gnu-debuglink.yaml @@ -0,0 +1,32 @@ +# RUN: yaml2obj %s > %t +# RUN: llvm-objcopy --strip-all --add-gnu-debuglink=%t %t %t.stripped +# RUN: lldb-test object-file %t.stripped | FileCheck %s + +# CHECK: Name: .debug_frame +# CHECK-NEXT: Type: dwarf-frame + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 + Entry: 0x00000000004003D0 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x00000000004003D0 + AddressAlign: 0x0000000000000010 + Content: DEADBEEFBAADF00D + - Name: .debug_frame + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000008 + Content: DEADBEEFBAADF00D +Symbols: + - Name: main + Type: STT_FUNC + Section: .text + Value: 0x00000000004003D0 + Size: 0x0000000000000008 +... Index: lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp +++ lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp @@ -71,16 +71,17 @@ if (!uuid) return nullptr; + // If the main object file already contains debug info, then we are done. + if (obj_file->GetSectionList()->FindSectionByType( + lldb::eSectionTypeDWARFDebugInfo, true)) + return nullptr; + // If the module specified a filespec, use that. FileSpec fspec = module_sp->GetSymbolFileFileSpec(); // Otherwise, try gnu_debuglink, if one exists. if (!fspec) fspec = obj_file->GetDebugLink().getValueOr(FileSpec()); - // If we have no debug symbol files, then nothing to do. - if (!fspec) - return nullptr; - static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "SymbolVendorELF::CreateInstance (module = %s)", module_sp->GetFileSpec().GetPath().c_str()); Index: lldb/trunk/source/Symbol/LocateSymbolFile.cpp =================================================================== --- lldb/trunk/source/Symbol/LocateSymbolFile.cpp +++ lldb/trunk/source/Symbol/LocateSymbolFile.cpp @@ -261,107 +261,110 @@ FileSystem::Instance().Exists(symbol_file_spec)) return symbol_file_spec; - const char *symbol_filename = symbol_file_spec.GetFilename().AsCString(); - if (symbol_filename && symbol_filename[0]) { - FileSpecList debug_file_search_paths = default_search_paths; - - // Add module directory. - FileSpec module_file_spec = module_spec.GetFileSpec(); - // We keep the unresolved pathname if it fails. - FileSystem::Instance().ResolveSymbolicLink(module_file_spec, - module_file_spec); + FileSpecList debug_file_search_paths = default_search_paths; - ConstString file_dir = module_file_spec.GetDirectory(); + // Add module directory. + FileSpec module_file_spec = module_spec.GetFileSpec(); + // We keep the unresolved pathname if it fails. + FileSystem::Instance().ResolveSymbolicLink(module_file_spec, + module_file_spec); + + ConstString file_dir = module_file_spec.GetDirectory(); + { + FileSpec file_spec(file_dir.AsCString(".")); + FileSystem::Instance().Resolve(file_spec); + debug_file_search_paths.AppendIfUnique(file_spec); + } + + if (ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) { + + // Add current working directory. { - FileSpec file_spec(file_dir.AsCString(".")); + FileSpec file_spec("."); FileSystem::Instance().Resolve(file_spec); debug_file_search_paths.AppendIfUnique(file_spec); } - if (ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) { - - // Add current working directory. - { - FileSpec file_spec("."); - FileSystem::Instance().Resolve(file_spec); - debug_file_search_paths.AppendIfUnique(file_spec); - } - #ifndef _WIN32 #if defined(__NetBSD__) - // Add /usr/libdata/debug directory. - { - FileSpec file_spec("/usr/libdata/debug"); - FileSystem::Instance().Resolve(file_spec); - debug_file_search_paths.AppendIfUnique(file_spec); - } + // Add /usr/libdata/debug directory. + { + FileSpec file_spec("/usr/libdata/debug"); + FileSystem::Instance().Resolve(file_spec); + debug_file_search_paths.AppendIfUnique(file_spec); + } #else - // Add /usr/lib/debug directory. - { - FileSpec file_spec("/usr/lib/debug"); - FileSystem::Instance().Resolve(file_spec); - debug_file_search_paths.AppendIfUnique(file_spec); - } + // Add /usr/lib/debug directory. + { + FileSpec file_spec("/usr/lib/debug"); + FileSystem::Instance().Resolve(file_spec); + debug_file_search_paths.AppendIfUnique(file_spec); + } #endif #endif // _WIN32 - } + } - std::string uuid_str; - const UUID &module_uuid = module_spec.GetUUID(); - if (module_uuid.IsValid()) { - // Some debug files are stored in the .build-id directory like this: - // /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug - uuid_str = module_uuid.GetAsString(""); - std::transform(uuid_str.begin(), uuid_str.end(), uuid_str.begin(), - ::tolower); - uuid_str.insert(2, 1, '/'); - uuid_str = uuid_str + ".debug"; - } + std::string uuid_str; + const UUID &module_uuid = module_spec.GetUUID(); + if (module_uuid.IsValid()) { + // Some debug files are stored in the .build-id directory like this: + // /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug + uuid_str = module_uuid.GetAsString(""); + std::transform(uuid_str.begin(), uuid_str.end(), uuid_str.begin(), + ::tolower); + uuid_str.insert(2, 1, '/'); + uuid_str = uuid_str + ".debug"; + } - size_t num_directories = debug_file_search_paths.GetSize(); - for (size_t idx = 0; idx < num_directories; ++idx) { - FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx); - FileSystem::Instance().Resolve(dirspec); - if (!FileSystem::Instance().IsDirectory(dirspec)) - continue; + size_t num_directories = debug_file_search_paths.GetSize(); + for (size_t idx = 0; idx < num_directories; ++idx) { + FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx); + FileSystem::Instance().Resolve(dirspec); + if (!FileSystem::Instance().IsDirectory(dirspec)) + continue; - std::vector files; - std::string dirname = dirspec.GetPath(); + std::vector files; + std::string dirname = dirspec.GetPath(); - files.push_back(dirname + "/" + symbol_filename); - files.push_back(dirname + "/.debug/" + symbol_filename); + if (!uuid_str.empty()) files.push_back(dirname + "/.build-id/" + uuid_str); + if (symbol_file_spec.GetFilename()) { + files.push_back(dirname + "/" + + symbol_file_spec.GetFilename().GetCString()); + files.push_back(dirname + "/.debug/" + + symbol_file_spec.GetFilename().GetCString()); // Some debug files may stored in the module directory like this: // /usr/lib/debug/usr/lib/library.so.debug if (!file_dir.IsEmpty()) - files.push_back(dirname + file_dir.AsCString() + "/" + symbol_filename); + files.push_back(dirname + file_dir.AsCString() + "/" + + symbol_file_spec.GetFilename().GetCString()); + } - const uint32_t num_files = files.size(); - for (size_t idx_file = 0; idx_file < num_files; ++idx_file) { - const std::string &filename = files[idx_file]; - FileSpec file_spec(filename); - FileSystem::Instance().Resolve(file_spec); - - if (llvm::sys::fs::equivalent(file_spec.GetPath(), - module_file_spec.GetPath())) - continue; - - if (FileSystem::Instance().Exists(file_spec)) { - lldb_private::ModuleSpecList specs; - const size_t num_specs = - ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs); - assert(num_specs <= 1 && - "Symbol Vendor supports only a single architecture"); - if (num_specs == 1) { - ModuleSpec mspec; - if (specs.GetModuleSpecAtIndex(0, mspec)) { - // Skip the uuids check if module_uuid is invalid. For example, - // this happens for *.dwp files since at the moment llvm-dwp - // doesn't output build ids, nor does binutils dwp. - if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID()) - return file_spec; - } + const uint32_t num_files = files.size(); + for (size_t idx_file = 0; idx_file < num_files; ++idx_file) { + const std::string &filename = files[idx_file]; + FileSpec file_spec(filename); + FileSystem::Instance().Resolve(file_spec); + + if (llvm::sys::fs::equivalent(file_spec.GetPath(), + module_file_spec.GetPath())) + continue; + + if (FileSystem::Instance().Exists(file_spec)) { + lldb_private::ModuleSpecList specs; + const size_t num_specs = + ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs); + assert(num_specs <= 1 && + "Symbol Vendor supports only a single architecture"); + if (num_specs == 1) { + ModuleSpec mspec; + if (specs.GetModuleSpecAtIndex(0, mspec)) { + // Skip the uuids check if module_uuid is invalid. For example, + // this happens for *.dwp files since at the moment llvm-dwp + // doesn't output build ids, nor does binutils dwp. + if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID()) + return file_spec; } } }