[Lldb-commits] [lldb] r235737 - Look for both .debug and dsym debugging symbol information for stripped executable.
Robert Flack
flackr at gmail.com
Wed May 20 14:18:52 PDT 2015
Thanks for the information! I've put up a patch at
http://reviews.llvm.org/D9896 which should do the right thing, please take
a look.
On Wed, May 20, 2015 at 12:59 AM, Jason Molenda <jmolenda at apple.com> wrote:
> Hi Robert, this change introduced a bit of a regression in Mac native
> lldb. It's not easy to spot on a Mac but in other environments it's a
> problem.
>
>
> LocateDSYMInVincinityOfExecutable is a function in
> Host/common/Symbols.cpp. It takes a ModuleSpec (the details about the
> executable binary -- the filename, architecture, UUID, etc) and it looks
> for a dSYM bundle near that executable. It adds things on to the file path
> and if it finds a likely candidate, retrieves the ModuleSpecs for that dSYM
> (in the case of a multiple-architecture universal dSYM binary) and compares
> them to the original executable binary's ModuleSpec.
>
> The problem comes from using ModuleSpec::FindMatchingModuleSpec(). This
> calls ModuleSpec::Matches() and this method, among the things it checks,
> requires that the *filenames* match between the executable and the dSYM.
>
> As a reminder, an executable name might be /tmp/a.out. Its dSYM would be
> /tmp/a.out.dSYM/Contents/Resources/a.out.
>
> After r235737, LocateDSYMInVincinityOfExecutable() never matches anything.
>
> The only reason it escaped all of our notices is that lldb then asks the
> DebugSymbols framework to find the dSYM -- and it has usually been able to
> do that.
>
> But if the DebugSymbols framework is not available or not working, lldb is
> completely broken for automatically loading a dSYM next to a binary.
>
> The old version of LocateDSYMInVincinityOfExecutable() was written in very
> Mac specific terms, e.g.
>
> if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID
> (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
> {
> return true;
> }
>
> (and FileAtPathContainsArchAndUUID was very mac-only) so you had a bit of
> rewriting to do there in making it non-mac-specific. But I think using
> ModuleSpec::FindMatchingModuleSpec() in place of this is not correct.
>
> As a quick workaround I made this patch,
>
>
>
>
> which looks to see if the executable module has a UUID in its ModuleSpec
> -- and if so, it creates a new ModuleSpec with only that one field. That
> is always enough to disambiguate among a multi-architecture dSYM, and to
> ensure that we have the correct dSYM. (and on Mac, it's nigh impossible to
> get a binary that doesn't have a UUID in it--you never see them in
> practice.)
>
> Do you want to take another look at this function?
>
>
> Thanks!
>
>
> Jason
>
>
>
> > On Apr 24, 2015, at 11:09 AM, Robert Flack <flackr at gmail.com> wrote:
> >
> > Author: flackr
> > Date: Fri Apr 24 13:09:54 2015
> > New Revision: 235737
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=235737&view=rev
> > Log:
> > Look for both .debug and dsym debugging symbol information for stripped
> executable.
> >
> > Currently Symbols::LocateExecutableSymbolFile on MacOSX only looks for
> external
> > dsym debugging information, however if running on a stripped dwarf
> executable it
> > should also check for a .debug file as well.
> >
> > Test Plan:
> > ./dotest.py $DOTEST_OPTS -t -p TestSharedLibStrippedSymbols.py
> > This test now passes when running a remote Mac -> Linux test, and still
> passes
> > running locally on Mac or locally on Linux.
> >
> > Differential Revision: http://reviews.llvm.org/D9174
> >
> > Modified:
> > lldb/trunk/source/Host/common/Symbols.cpp
> > lldb/trunk/source/Host/macosx/Symbols.cpp
> >
> > Modified: lldb/trunk/source/Host/common/Symbols.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Symbols.cpp?rev=235737&r1=235736&r2=235737&view=diff
> >
> ==============================================================================
> > --- lldb/trunk/source/Host/common/Symbols.cpp (original)
> > +++ lldb/trunk/source/Host/common/Symbols.cpp Fri Apr 24 13:09:54 2015
> > @@ -18,139 +18,253 @@
> > #include "lldb/Core/UUID.h"
> > #include "lldb/Symbol/ObjectFile.h"
> > #include "lldb/Target/Target.h"
> > +#include "lldb/Utility/SafeMachO.h"
> >
> > #include "llvm/Support/FileSystem.h"
> >
> > +// From MacOSX system header "mach/machine.h"
> > +typedef int cpu_type_t;
> > +typedef int cpu_subtype_t;
> > +
> > using namespace lldb;
> > using namespace lldb_private;
> > +using namespace llvm::MachO;
> > +
> > +#if defined(__APPLE__)
> > +
> > +// Forward declaration of method defined in
> source/Host/macosx/Symbols.cpp
> > +int
> > +LocateMacOSXFilesUsingDebugSymbols
> > +(
> > + const ModuleSpec &module_spec,
> > + FileSpec *out_exec_fspec, // If non-NULL, try and find the
> executable
> > + FileSpec *out_dsym_fspec // If non-NULL try and find the debug
> symbol file
> > +);
> > +
> > +#else
> > +
> > +int
> > +LocateMacOSXFilesUsingDebugSymbols
> > +(
> > + const ModuleSpec &module_spec,
> > + FileSpec *out_exec_fspec, // If non-NULL, try and find the
> executable
> > + FileSpec *out_dsym_fspec // If non-NULL try and find the debug
> symbol file
> > +) {
> > + // Cannot find MacOSX files using debug symbols on non MacOSX.
> > + return 0;
> > +}
> > +
> > +#endif
> > +
> > +static bool
> > +LocateDSYMInVincinityOfExecutable (const ModuleSpec &module_spec,
> FileSpec &dsym_fspec)
> > +{
> > + const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
> > + if (exec_fspec)
> > + {
> > + char path[PATH_MAX];
> > + if (exec_fspec->GetPath(path, sizeof(path)))
> > + {
> > + // Make sure the module isn't already just a dSYM file...
> > + if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") ==
> NULL)
> > + {
> > + size_t obj_file_path_length = strlen(path);
> > + ::strncat(path, ".dSYM/Contents/Resources/DWARF/",
> sizeof(path) - strlen(path) - 1);
> > + ::strncat(path, exec_fspec->GetFilename().AsCString(),
> sizeof(path) - strlen(path) - 1);
> > +
> > + dsym_fspec.SetFile(path, false);
> > +
> > + ModuleSpecList module_specs;
> > + ModuleSpec matched_module_spec;
> > + if (dsym_fspec.Exists() &&
> > + ObjectFile::GetModuleSpecifications(dsym_fspec, 0,
> 0, module_specs) &&
> > + module_specs.FindMatchingModuleSpec(module_spec,
> matched_module_spec))
> > + {
> > + return true;
> > + }
> > + else
> > + {
> > + path[obj_file_path_length] = '\0';
> > +
> > + char *last_dot = strrchr(path, '.');
> > + while (last_dot != NULL && last_dot[0])
> > + {
> > + char *next_slash = strchr(last_dot, '/');
> > + if (next_slash != NULL)
> > + {
> > + *next_slash = '\0';
> > + ::strncat(path,
> ".dSYM/Contents/Resources/DWARF/", sizeof(path) - strlen(path) - 1);
> > + ::strncat(path,
> exec_fspec->GetFilename().AsCString(), sizeof(path) - strlen(path) - 1);
> > + dsym_fspec.SetFile(path, false);
> > + if (dsym_fspec.Exists() &&
> > +
> ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs) &&
> > +
> module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
> > + {
> > + return true;
> > + }
> > + else
> > + {
> > + *last_dot = '\0';
> > + char *prev_slash = strrchr(path, '/');
> > + if (prev_slash != NULL)
> > + *prev_slash = '\0';
> > + else
> > + break;
> > + }
> > + }
> > + else
> > + {
> > + break;
> > + }
> > + }
> > + }
> > + }
> > + }
> > + }
> > + dsym_fspec.Clear();
> > + return false;
> > +}
> >
> > -#if defined (__linux__) || defined (__FreeBSD__)
> > +FileSpec
> > +LocateExecutableSymbolFileDsym (const ModuleSpec &module_spec)
> > +{
> > + const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
> > + const ArchSpec *arch = module_spec.GetArchitecturePtr();
> > + const UUID *uuid = module_spec.GetUUIDPtr();
> > +
> > + Timer scoped_timer (__PRETTY_FUNCTION__,
> > + "LocateExecutableSymbolFileDsym (file = %s,
> arch = %s, uuid = %p)",
> > + exec_fspec ?
> exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",
> > + arch ? arch->GetArchitectureName() : "<NULL>",
> > + uuid);
> > +
> > + FileSpec symbol_fspec;
> > + // First try and find the dSYM in the same directory as the
> executable or in
> > + // an appropriate parent directory
> > + if (LocateDSYMInVincinityOfExecutable (module_spec, symbol_fspec)
> == false)
> > + {
> > + // We failed to easily find the dSYM above, so use DebugSymbols
> > + LocateMacOSXFilesUsingDebugSymbols (module_spec, NULL,
> &symbol_fspec);
> > + }
> > + return symbol_fspec;
> > +}
> >
> > FileSpec
> > Symbols::LocateExecutableObjectFile (const ModuleSpec &module_spec)
> > {
> > - // FIXME
> > - return FileSpec();
> > + const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
> > + const ArchSpec *arch = module_spec.GetArchitecturePtr();
> > + const UUID *uuid = module_spec.GetUUIDPtr();
> > + Timer scoped_timer (__PRETTY_FUNCTION__,
> > + "LocateExecutableObjectFile (file = %s, arch =
> %s, uuid = %p)",
> > + exec_fspec ?
> exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",
> > + arch ? arch->GetArchitectureName() : "<NULL>",
> > + uuid);
> > +
> > + FileSpec objfile_fspec;
> > + ModuleSpecList module_specs;
> > + ModuleSpec matched_module_spec;
> > + if (exec_fspec &&
> > + ObjectFile::GetModuleSpecifications(*exec_fspec, 0, 0,
> module_specs) &&
> > + module_specs.FindMatchingModuleSpec(module_spec,
> matched_module_spec))
> > + {
> > + objfile_fspec = exec_fspec;
> > + }
> > + else
> > + {
> > + LocateMacOSXFilesUsingDebugSymbols (module_spec,
> &objfile_fspec, NULL);
> > + }
> > + return objfile_fspec;
> > }
> >
> > FileSpec
> > Symbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)
> > {
> > const char *symbol_filename =
> module_spec.GetSymbolFileSpec().GetFilename().AsCString();
> > - if (!symbol_filename || !symbol_filename[0])
> > - return FileSpec();
> > -
> > - FileSpecList debug_file_search_paths
> (Target::GetDefaultDebugFileSearchPaths());
> > -
> > - // Add module directory.
> > - const ConstString &file_dir =
> module_spec.GetFileSpec().GetDirectory();
> > - debug_file_search_paths.AppendIfUnique
> (FileSpec(file_dir.AsCString("."), true));
> > + if (symbol_filename && symbol_filename[0])
> > + {
> > + FileSpecList debug_file_search_paths
> (Target::GetDefaultDebugFileSearchPaths());
> >
> > - // Add current working directory.
> > - debug_file_search_paths.AppendIfUnique (FileSpec(".", true));
> > + // Add module directory.
> > + const ConstString &file_dir =
> module_spec.GetFileSpec().GetDirectory();
> > + debug_file_search_paths.AppendIfUnique
> (FileSpec(file_dir.AsCString("."), true));
> >
> > - // Add /usr/lib/debug directory.
> > - debug_file_search_paths.AppendIfUnique (FileSpec("/usr/lib/debug",
> true));
> > + // Add current working directory.
> > + debug_file_search_paths.AppendIfUnique (FileSpec(".", true));
> >
> > - 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("");
> > - uuid_str.insert (2, 1, '/');
> > - uuid_str = uuid_str + ".debug";
> > - }
> > + // Add /usr/lib/debug directory.
> > + debug_file_search_paths.AppendIfUnique
> (FileSpec("/usr/lib/debug", true));
> >
> > - // Get directory of our module. Needed to check debug files like
> this:
> > - // /usr/lib/debug/usr/lib/library.so.debug
> > - std::string module_directory =
> module_spec.GetFileSpec().GetDirectory().AsCString();
> > + 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("");
> > + 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);
> > - dirspec.ResolvePath();
> > - if (!dirspec.Exists() || !dirspec.IsDirectory())
> > - continue;
> > -
> > - std::vector<std::string> files;
> > - std::string dirname = dirspec.GetPath();
> > -
> > - files.push_back (dirname + "/" + symbol_filename);
> > - files.push_back (dirname + "/.debug/" + symbol_filename);
> > - files.push_back (dirname + "/.build-id/" + uuid_str);
> > - files.push_back (dirname + module_directory + "/" +
> symbol_filename);
> > + // Get directory of our module. Needed to check debug files
> like this:
> > + // /usr/lib/debug/usr/lib/library.so.debug
> > + std::string module_directory =
> module_spec.GetFileSpec().GetDirectory().AsCString();
> >
> > - const uint32_t num_files = files.size();
> > - for (size_t idx_file = 0; idx_file < num_files; ++idx_file)
> > + size_t num_directories = debug_file_search_paths.GetSize();
> > + for (size_t idx = 0; idx < num_directories; ++idx)
> > {
> > - const std::string &filename = files[idx_file];
> > - FileSpec file_spec (filename.c_str(), true);
> > -
> > - if (llvm::sys::fs::equivalent (file_spec.GetPath(),
> module_spec.GetFileSpec().GetPath()))
> > + FileSpec dirspec =
> debug_file_search_paths.GetFileSpecAtIndex (idx);
> > + dirspec.ResolvePath();
> > + if (!dirspec.Exists() || !dirspec.IsDirectory())
> > continue;
> >
> > - if (file_spec.Exists())
> > + std::vector<std::string> files;
> > + std::string dirname = dirspec.GetPath();
> > +
> > + files.push_back (dirname + "/" + symbol_filename);
> > + files.push_back (dirname + "/.debug/" + symbol_filename);
> > + files.push_back (dirname + "/.build-id/" + uuid_str);
> > + files.push_back (dirname + module_directory + "/" +
> symbol_filename);
> > +
> > + const uint32_t num_files = files.size();
> > + for (size_t idx_file = 0; idx_file < num_files; ++idx_file)
> > {
> > - 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)
> > + const std::string &filename = files[idx_file];
> > + FileSpec file_spec (filename.c_str(), true);
> > +
> > + if (llvm::sys::fs::equivalent (file_spec.GetPath(),
> module_spec.GetFileSpec().GetPath()))
> > + continue;
> > +
> > + if (file_spec.Exists())
> > {
> > - ModuleSpec mspec;
> > - if (specs.GetModuleSpecAtIndex (0, mspec))
> > + 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)
> > {
> > - if (mspec.GetUUID() == module_uuid)
> > - return file_spec;
> > + ModuleSpec mspec;
> > + if (specs.GetModuleSpecAtIndex (0, mspec))
> > + {
> > + if (mspec.GetUUID() == module_uuid)
> > + return file_spec;
> > + }
> > }
> > }
> > }
> > }
> > }
> >
> > - return FileSpec();
> > + return LocateExecutableSymbolFileDsym(module_spec);
> > }
> >
> > -FileSpec
> > -Symbols::FindSymbolFileInBundle (const FileSpec& symfile_bundle,
> > - const lldb_private::UUID *uuid,
> > - const ArchSpec *arch)
> > -{
> > - // FIXME
> > - return FileSpec();
> > -}
> > -
> > -bool
> > -Symbols::DownloadObjectAndSymbolFile (ModuleSpec &module_spec, bool
> force_lookup)
> > -{
> > - // Fill in the module_spec.GetFileSpec() for the object file and/or
> the
> > - // module_spec.GetSymbolFileSpec() for the debug symbols file.
> > - return false;
> > -}
> > -
> > -#elif !defined (__APPLE__)
> > -
> > -FileSpec
> > -Symbols::LocateExecutableObjectFile (const ModuleSpec &module_spec)
> > -{
> > - // FIXME
> > - return FileSpec();
> > -}
> > -
> > -FileSpec
> > -Symbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)
> > -{
> > - // FIXME
> > - return FileSpec();
> > -}
> > +#if !defined (__APPLE__)
> >
> > FileSpec
> > Symbols::FindSymbolFileInBundle (const FileSpec& symfile_bundle,
> > const lldb_private::UUID *uuid,
> > const ArchSpec *arch)
> > {
> > + // FIXME
> > return FileSpec();
> > }
> >
> >
> > Modified: lldb/trunk/source/Host/macosx/Symbols.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Symbols.cpp?rev=235737&r1=235736&r2=235737&view=diff
> >
> ==============================================================================
> > --- lldb/trunk/source/Host/macosx/Symbols.cpp (original)
> > +++ lldb/trunk/source/Host/macosx/Symbols.cpp Fri Apr 24 13:09:54 2015
> > @@ -29,6 +29,7 @@
> > #include "lldb/Core/UUID.h"
> > #include "lldb/Host/Endian.h"
> > #include "lldb/Host/Host.h"
> > +#include "lldb/Symbol/ObjectFile.h"
> > #include "lldb/Utility/CleanUp.h"
> > #include "Host/macosx/cfcpp/CFCBundle.h"
> > #include "Host/macosx/cfcpp/CFCData.h"
> > @@ -36,7 +37,6 @@
> > #include "Host/macosx/cfcpp/CFCString.h"
> > #include "mach/machine.h"
> >
> > -
> > using namespace lldb;
> > using namespace lldb_private;
> > using namespace llvm::MachO;
> > @@ -50,234 +50,7 @@ CFDictionaryRef DBGCopyDSYMPropertyLists
> > }
> > #endif
> >
> > -static bool
> > -SkinnyMachOFileContainsArchAndUUID
> > -(
> > - const FileSpec &file_spec,
> > - const ArchSpec *arch,
> > - const lldb_private::UUID *uuid, // the UUID we are looking for
> > - off_t file_offset,
> > - DataExtractor& data,
> > - lldb::offset_t data_offset,
> > - const uint32_t magic
> > -)
> > -{
> > - assert(magic == MH_MAGIC || magic == MH_CIGAM || magic ==
> MH_MAGIC_64 || magic == MH_CIGAM_64);
> > - if (magic == MH_MAGIC || magic == MH_MAGIC_64)
> > - data.SetByteOrder (lldb::endian::InlHostByteOrder());
> > - else if (lldb::endian::InlHostByteOrder() == eByteOrderBig)
> > - data.SetByteOrder (eByteOrderLittle);
> > - else
> > - data.SetByteOrder (eByteOrderBig);
> > -
> > - uint32_t i;
> > - const uint32_t cputype = data.GetU32(&data_offset); // cpu
> specifier
> > - const uint32_t cpusubtype = data.GetU32(&data_offset); //
> machine specifier
> > - data_offset+=4; // Skip mach file type
> > - const uint32_t ncmds = data.GetU32(&data_offset); //
> number of load commands
> > - const uint32_t sizeofcmds = data.GetU32(&data_offset); // the
> size of all the load commands
> > - data_offset+=4; // Skip flags
> > -
> > - // Check the architecture if we have a valid arch pointer
> > - if (arch)
> > - {
> > - ArchSpec file_arch(eArchTypeMachO, cputype, cpusubtype);
> > -
> > - if (!file_arch.IsCompatibleMatch(*arch))
> > - return false;
> > - }
> > -
> > - // The file exists, and if a valid arch pointer was passed in we
> know
> > - // if already matches, so we can return if we aren't looking for a
> specific
> > - // UUID
> > - if (uuid == NULL)
> > - return true;
> > -
> > - if (magic == MH_CIGAM_64 || magic == MH_MAGIC_64)
> > - data_offset += 4; // Skip reserved field for in mach_header_64
> > -
> > - // Make sure we have enough data for all the load commands
> > - if (magic == MH_CIGAM_64 || magic == MH_MAGIC_64)
> > - {
> > - if (data.GetByteSize() < sizeof(struct mach_header_64) +
> sizeofcmds)
> > - {
> > - DataBufferSP data_buffer_sp (file_spec.ReadFileContents
> (file_offset, sizeof(struct mach_header_64) + sizeofcmds));
> > - data.SetData (data_buffer_sp);
> > - }
> > - }
> > - else
> > - {
> > - if (data.GetByteSize() < sizeof(struct mach_header) +
> sizeofcmds)
> > - {
> > - DataBufferSP data_buffer_sp (file_spec.ReadFileContents
> (file_offset, sizeof(struct mach_header) + sizeofcmds));
> > - data.SetData (data_buffer_sp);
> > - }
> > - }
> > -
> > - for (i=0; i<ncmds; i++)
> > - {
> > - const lldb::offset_t cmd_offset = data_offset; // Save this
> data_offset in case parsing of the segment goes awry!
> > - uint32_t cmd = data.GetU32(&data_offset);
> > - uint32_t cmd_size = data.GetU32(&data_offset);
> > - if (cmd == LC_UUID)
> > - {
> > - lldb_private::UUID file_uuid (data.GetData(&data_offset,
> 16), 16);
> > - if (file_uuid == *uuid)
> > - return true;
> > - return false;
> > - }
> > - data_offset = cmd_offset + cmd_size;
> > - }
> > - return false;
> > -}
> > -
> > -bool
> > -UniversalMachOFileContainsArchAndUUID
> > -(
> > - const FileSpec &file_spec,
> > - const ArchSpec *arch,
> > - const lldb_private::UUID *uuid,
> > - off_t file_offset,
> > - DataExtractor& data,
> > - lldb::offset_t data_offset,
> > - const uint32_t magic
> > -)
> > -{
> > - assert(magic == FAT_MAGIC || magic == FAT_CIGAM);
> > -
> > - // Universal mach-o files always have their headers encoded as BIG
> endian
> > - data.SetByteOrder(eByteOrderBig);
> > -
> > - uint32_t i;
> > - const uint32_t nfat_arch = data.GetU32(&data_offset); // number
> of structs that follow
> > - const uint32_t fat_header_and_arch_size = sizeof(struct fat_header)
> + nfat_arch * sizeof(struct fat_arch);
> > - if (data.GetByteSize() < fat_header_and_arch_size)
> > - {
> > - DataBufferSP data_buffer_sp (file_spec.ReadFileContents
> (file_offset, fat_header_and_arch_size));
> > - data.SetData (data_buffer_sp);
> > - }
> > -
> > - for (i=0; i<nfat_arch; i++)
> > - {
> > - cpu_type_t arch_cputype =
> data.GetU32(&data_offset); // cpu specifier (int)
> > - cpu_subtype_t arch_cpusubtype =
> data.GetU32(&data_offset); // machine specifier (int)
> > - uint32_t arch_offset =
> data.GetU32(&data_offset); // file offset to this object file
> > - // uint32_t arch_size =
> data.GetU32(&data_offset); // size of this object file
> > - // uint32_t arch_align =
> data.GetU32(&data_offset); // alignment as a power of 2
> > - data_offset += 8; // Skip size and align as we don't need
> those
> > - // Only process this slice if the cpu type/subtype matches
> > - if (arch)
> > - {
> > - ArchSpec fat_arch(eArchTypeMachO, arch_cputype,
> arch_cpusubtype);
> > - if (!fat_arch.IsExactMatch(*arch))
> > - continue;
> > - }
> > -
> > - // Create a buffer with only the arch slice date in it
> > - DataExtractor arch_data;
> > - DataBufferSP data_buffer_sp (file_spec.ReadFileContents
> (file_offset + arch_offset, 0x1000));
> > - arch_data.SetData(data_buffer_sp);
> > - lldb::offset_t arch_data_offset = 0;
> > - uint32_t arch_magic = arch_data.GetU32(&arch_data_offset);
> > -
> > - switch (arch_magic)
> > - {
> > - case MH_MAGIC:
> > - case MH_CIGAM:
> > - case MH_MAGIC_64:
> > - case MH_CIGAM_64:
> > - if (SkinnyMachOFileContainsArchAndUUID (file_spec, arch,
> uuid, file_offset + arch_offset, arch_data, arch_data_offset, arch_magic))
> > - return true;
> > - break;
> > - }
> > - }
> > - return false;
> > -}
> > -
> > -static bool
> > -FileAtPathContainsArchAndUUID
> > -(
> > - const FileSpec &file_spec,
> > - const ArchSpec *arch,
> > - const lldb_private::UUID *uuid
> > -)
> > -{
> > - DataExtractor data;
> > - off_t file_offset = 0;
> > - DataBufferSP data_buffer_sp (file_spec.ReadFileContents
> (file_offset, 0x1000));
> > -
> > - if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0)
> > - {
> > - data.SetData(data_buffer_sp);
> > -
> > - lldb::offset_t data_offset = 0;
> > - uint32_t magic = data.GetU32(&data_offset);
> > -
> > - switch (magic)
> > - {
> > - // 32 bit mach-o file
> > - case MH_MAGIC:
> > - case MH_CIGAM:
> > - case MH_MAGIC_64:
> > - case MH_CIGAM_64:
> > - return SkinnyMachOFileContainsArchAndUUID (file_spec, arch,
> uuid, file_offset, data, data_offset, magic);
> > -
> > - // fat mach-o file
> > - case FAT_MAGIC:
> > - case FAT_CIGAM:
> > - return UniversalMachOFileContainsArchAndUUID (file_spec,
> arch, uuid, file_offset, data, data_offset, magic);
> > -
> > - default:
> > - break;
> > - }
> > - }
> > - return false;
> > -}
> > -
> > -FileSpec
> > -Symbols::FindSymbolFileInBundle (const FileSpec& dsym_bundle_fspec,
> > - const lldb_private::UUID *uuid,
> > - const ArchSpec *arch)
> > -{
> > - char path[PATH_MAX];
> > -
> > - FileSpec dsym_fspec;
> > -
> > - if (dsym_bundle_fspec.GetPath(path, sizeof(path)))
> > - {
> > - ::strncat (path, "/Contents/Resources/DWARF", sizeof(path) -
> strlen(path) - 1);
> > -
> > - lldb_utility::CleanUp <DIR *, int> dirp (opendir(path), NULL,
> closedir);
> > - if (dirp.is_valid())
> > - {
> > - dsym_fspec.GetDirectory().SetCString(path);
> > - struct dirent* dp;
> > - while ((dp = readdir(dirp.get())) != NULL)
> > - {
> > - // Only search directories
> > - if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN)
> > - {
> > - if (dp->d_namlen == 1 && dp->d_name[0] == '.')
> > - continue;
> > -
> > - if (dp->d_namlen == 2 && dp->d_name[0] == '.' &&
> dp->d_name[1] == '.')
> > - continue;
> > - }
> > -
> > - if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN)
> > - {
> > - dsym_fspec.GetFilename().SetCString(dp->d_name);
> > - if (FileAtPathContainsArchAndUUID (dsym_fspec,
> arch, uuid))
> > - return dsym_fspec;
> > - }
> > - }
> > - }
> > - }
> > - dsym_fspec.Clear();
> > - return dsym_fspec;
> > -}
> > -
> > -static int
> > +int
> > LocateMacOSXFilesUsingDebugSymbols
> > (
> > const ModuleSpec &module_spec,
> > @@ -415,6 +188,8 @@ LocateMacOSXFilesUsingDebugSymbols
> > {
> > *dsym_extension_pos = '\0';
> > FileSpec file_spec (path, true);
> > + ModuleSpecList module_specs;
> > + ModuleSpec matched_module_spec;
> > switch (file_spec.GetFileType())
> > {
> > case
> FileSpec::eFileTypeDirectory: // Bundle directory?
> > @@ -426,8 +201,9 @@ LocateMacOSXFilesUsingDebugSymbols
> > if
> (::CFURLGetFileSystemRepresentation (bundle_exe_url.get(), true,
> (UInt8*)path, sizeof(path)-1))
> > {
> > FileSpec
> bundle_exe_file_spec (path, true);
> > -
> > - if
> (FileAtPathContainsArchAndUUID (bundle_exe_file_spec, arch, uuid))
> > + if
> (ObjectFile::GetModuleSpecifications(bundle_exe_file_spec, 0, 0,
> module_specs) &&
> > +
> module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
> > +
> > {
> >
> ++items_found;
> >
> *out_exec_fspec = bundle_exe_file_spec;
> > @@ -436,7 +212,7 @@ LocateMacOSXFilesUsingDebugSymbols
> > }
> > }
> > break;
> > -
> > +
> > case FileSpec::eFileTypePipe:
> // Forget pipes
> > case FileSpec::eFileTypeSocket:
> // We can't process socket files
> > case
> FileSpec::eFileTypeInvalid: // File doesn't exist...
> > @@ -446,7 +222,9 @@ LocateMacOSXFilesUsingDebugSymbols
> > case FileSpec::eFileTypeRegular:
> > case
> FileSpec::eFileTypeSymbolicLink:
> > case FileSpec::eFileTypeOther:
> > - if
> (FileAtPathContainsArchAndUUID (file_spec, arch, uuid))
> > + if
> (ObjectFile::GetModuleSpecifications(file_spec, 0, 0, module_specs) &&
> > +
> module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
> > +
> > {
> > ++items_found;
> > *out_exec_fspec =
> file_spec;
> > @@ -466,112 +244,61 @@ LocateMacOSXFilesUsingDebugSymbols
> > return items_found;
> > }
> >
> > -static bool
> > -LocateDSYMInVincinityOfExecutable (const ModuleSpec &module_spec,
> FileSpec &dsym_fspec)
> > +FileSpec
> > +Symbols::FindSymbolFileInBundle (const FileSpec& dsym_bundle_fspec,
> > + const lldb_private::UUID *uuid,
> > + const ArchSpec *arch)
> > {
> > - const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
> > - if (exec_fspec)
> > + char path[PATH_MAX];
> > +
> > + FileSpec dsym_fspec;
> > +
> > + if (dsym_bundle_fspec.GetPath(path, sizeof(path)))
> > {
> > - char path[PATH_MAX];
> > - if (exec_fspec->GetPath(path, sizeof(path)))
> > + ::strncat (path, "/Contents/Resources/DWARF", sizeof(path) -
> strlen(path) - 1);
> > +
> > + lldb_utility::CleanUp <DIR *, int> dirp (opendir(path), NULL,
> closedir);
> > + if (dirp.is_valid())
> > {
> > - // Make sure the module isn't already just a dSYM file...
> > - if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") ==
> NULL)
> > + dsym_fspec.GetDirectory().SetCString(path);
> > + struct dirent* dp;
> > + while ((dp = readdir(dirp.get())) != NULL)
> > {
> > - size_t obj_file_path_length = strlen(path);
> > - strlcat(path, ".dSYM/Contents/Resources/DWARF/",
> sizeof(path));
> > - strlcat(path, exec_fspec->GetFilename().AsCString(),
> sizeof(path));
> > -
> > - dsym_fspec.SetFile(path, false);
> > -
> > - if (dsym_fspec.Exists() &&
> FileAtPathContainsArchAndUUID (dsym_fspec,
> module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
> > + // Only search directories
> > + if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN)
> > {
> > - return true;
> > + if (dp->d_namlen == 1 && dp->d_name[0] == '.')
> > + continue;
> > +
> > + if (dp->d_namlen == 2 && dp->d_name[0] == '.' &&
> dp->d_name[1] == '.')
> > + continue;
> > }
> > - else
> > - {
> > - path[obj_file_path_length] = '\0';
> >
> > - char *last_dot = strrchr(path, '.');
> > - while (last_dot != NULL && last_dot[0])
> > + if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN)
> > + {
> > + dsym_fspec.GetFilename().SetCString(dp->d_name);
> > + ModuleSpecList module_specs;
> > + if (ObjectFile::GetModuleSpecifications(dsym_fspec,
> 0, 0, module_specs))
> > {
> > - char *next_slash = strchr(last_dot, '/');
> > - if (next_slash != NULL)
> > + ModuleSpec spec;
> > + for (size_t i = 0; i < module_specs.GetSize();
> ++i)
> > {
> > - *next_slash = '\0';
> > - strlcat(path,
> ".dSYM/Contents/Resources/DWARF/", sizeof(path));
> > - strlcat(path,
> exec_fspec->GetFilename().AsCString(), sizeof(path));
> > - dsym_fspec.SetFile(path, false);
> > - if (dsym_fspec.Exists() &&
> FileAtPathContainsArchAndUUID (dsym_fspec,
> module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
> > - return true;
> > - else
> > + assert(module_specs.GetModuleSpecAtIndex(i,
> spec));
> > + if ((uuid == NULL || (spec.GetUUIDPtr() &&
> spec.GetUUID() == *uuid)) &&
> > + (arch == NULL ||
> (spec.GetArchitecturePtr() &&
> spec.GetArchitecture().IsCompatibleMatch(*arch))))
> > {
> > - *last_dot = '\0';
> > - char *prev_slash = strrchr(path, '/');
> > - if (prev_slash != NULL)
> > - *prev_slash = '\0';
> > - else
> > - break;
> > + return dsym_fspec;
> > }
> > }
> > - else
> > - {
> > - break;
> > - }
> > }
> > }
> > }
> > }
> > }
> > dsym_fspec.Clear();
> > - return false;
> > -}
> > -
> > -FileSpec
> > -Symbols::LocateExecutableObjectFile (const ModuleSpec &module_spec)
> > -{
> > - const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
> > - const ArchSpec *arch = module_spec.GetArchitecturePtr();
> > - const UUID *uuid = module_spec.GetUUIDPtr();
> > - Timer scoped_timer (__PRETTY_FUNCTION__,
> > - "LocateExecutableObjectFile (file = %s, arch =
> %s, uuid = %p)",
> > - exec_fspec ?
> exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",
> > - arch ? arch->GetArchitectureName() : "<NULL>",
> > - uuid);
> > -
> > - FileSpec objfile_fspec;
> > - if (exec_fspec && FileAtPathContainsArchAndUUID (exec_fspec, arch,
> uuid))
> > - objfile_fspec = exec_fspec;
> > - else
> > - LocateMacOSXFilesUsingDebugSymbols (module_spec,
> &objfile_fspec, NULL);
> > - return objfile_fspec;
> > -}
> > -
> > -FileSpec
> > -Symbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)
> > -{
> > - const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
> > - const ArchSpec *arch = module_spec.GetArchitecturePtr();
> > - const UUID *uuid = module_spec.GetUUIDPtr();
> > -
> > - Timer scoped_timer (__PRETTY_FUNCTION__,
> > - "LocateExecutableSymbolFile (file = %s, arch =
> %s, uuid = %p)",
> > - exec_fspec ?
> exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",
> > - arch ? arch->GetArchitectureName() : "<NULL>",
> > - uuid);
> > -
> > - FileSpec symbol_fspec;
> > - // First try and find the dSYM in the same directory as the
> executable or in
> > - // an appropriate parent directory
> > - if (LocateDSYMInVincinityOfExecutable (module_spec, symbol_fspec)
> == false)
> > - {
> > - // We failed to easily find the dSYM above, so use DebugSymbols
> > - LocateMacOSXFilesUsingDebugSymbols (module_spec, NULL,
> &symbol_fspec);
> > - }
> > - return symbol_fspec;
> > + return dsym_fspec;
> > }
> >
> > -
> > static bool
> > GetModuleSpecInfoFromUUIDDictionary (CFDictionaryRef uuid_dict,
> ModuleSpec &module_spec)
> > {
> >
> >
> > _______________________________________________
> > lldb-commits mailing list
> > lldb-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20150520/145e8d99/attachment.html>
More information about the lldb-commits
mailing list