Skip to content

Commit

Permalink
[dwarf][NFC] Move expandBundle() to MachO.h
Browse files Browse the repository at this point in the history
The function `expandBundle()` is defined both in `llvm-dwarfdump.cpp` and
`llvm-gsymutil.cpp` in the exact same way. Reduce code duplication by
moving this function to the `MachOObjectFile` class.

Reviewed By: jhenderson, clayborg

Differential Revision: https://reviews.llvm.org/D115418
  • Loading branch information
ellishg committed Dec 16, 2021
1 parent d3c2ad1 commit b68061a
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 74 deletions.
7 changes: 7 additions & 0 deletions llvm/include/llvm/Object/MachO.h
Expand Up @@ -652,6 +652,13 @@ class MachOObjectFile : public ObjectFile {
return std::string(std::string(Version.str()));
}

/// If the input path is a .dSYM bundle (as created by the dsymutil tool),
/// return the paths to the object files found in the bundle, otherwise return
/// an empty vector. If the path appears to be a .dSYM bundle but no objects
/// were found or there was a filesystem error, then return an error.
static Expected<std::vector<std::string>>
findDsymObjectMembers(StringRef Path);

private:
MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
Error &Err, uint32_t UniversalCputype = 0,
Expand Down
46 changes: 46 additions & 0 deletions llvm/lib/Object/MachOObjectFile.cpp
Expand Up @@ -26,12 +26,15 @@
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SwapByteOrder.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
Expand Down Expand Up @@ -4719,3 +4722,46 @@ StringRef MachOObjectFile::mapDebugSectionName(StringRef Name) const {
.Case("debug_str_offs", "debug_str_offsets")
.Default(Name);
}

Expected<std::vector<std::string>>
MachOObjectFile::findDsymObjectMembers(StringRef Path) {
SmallString<256> BundlePath(Path);
// Normalize input path. This is necessary to accept `bundle.dSYM/`.
sys::path::remove_dots(BundlePath);
if (!sys::fs::is_directory(BundlePath) ||
sys::path::extension(BundlePath) != ".dSYM")
return std::vector<std::string>();
sys::path::append(BundlePath, "Contents", "Resources", "DWARF");
bool IsDir;
auto EC = sys::fs::is_directory(BundlePath, IsDir);
if (EC == errc::no_such_file_or_directory || (!EC && !IsDir))
return createStringError(
EC, "%s: expected directory 'Contents/Resources/DWARF' in dSYM bundle",
Path.str().c_str());
if (EC)
return createFileError(BundlePath, errorCodeToError(EC));

std::vector<std::string> ObjectPaths;
for (sys::fs::directory_iterator Dir(BundlePath, EC), DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
StringRef ObjectPath = Dir->path();
sys::fs::file_status Status;
if (auto EC = sys::fs::status(ObjectPath, Status))
return createFileError(ObjectPath, errorCodeToError(EC));
switch (Status.type()) {
case sys::fs::file_type::regular_file:
case sys::fs::file_type::symlink_file:
case sys::fs::file_type::type_unknown:
ObjectPaths.push_back(ObjectPath.str());
break;
default: /*ignore*/;
}
}
if (EC)
return createFileError(BundlePath, errorCodeToError(EC));
if (ObjectPaths.empty())
return createStringError(std::error_code(),
"%s: no objects found in dSYM bundle",
Path.str().c_str());
return ObjectPaths;
}
53 changes: 15 additions & 38 deletions llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
Expand Up @@ -24,7 +24,6 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
Expand Down Expand Up @@ -265,6 +264,13 @@ static cl::extrahelp
/// @}
//===----------------------------------------------------------------------===//

static void error(Error Err) {
if (!Err)
return;
WithColor::error() << toString(std::move(Err)) << "\n";
exit(1);
}

static void error(StringRef Prefix, Error Err) {
if (!Err)
return;
Expand Down Expand Up @@ -583,41 +589,6 @@ static bool handleFile(StringRef Filename, HandlerFn HandleObj,
return handleBuffer(Filename, *Buffer, HandleObj, OS);
}

/// If the input path is a .dSYM bundle (as created by the dsymutil tool),
/// replace it with individual entries for each of the object files inside the
/// bundle otherwise return the input path.
static std::vector<std::string> expandBundle(const std::string &InputPath) {
std::vector<std::string> BundlePaths;
SmallString<256> BundlePath(InputPath);
// Normalize input path. This is necessary to accept `bundle.dSYM/`.
sys::path::remove_dots(BundlePath);
// Manually open up the bundle to avoid introducing additional dependencies.
if (sys::fs::is_directory(BundlePath) &&
sys::path::extension(BundlePath) == ".dSYM") {
std::error_code EC;
sys::path::append(BundlePath, "Contents", "Resources", "DWARF");
for (sys::fs::directory_iterator Dir(BundlePath, EC), DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
const std::string &Path = Dir->path();
sys::fs::file_status Status;
EC = sys::fs::status(Path, Status);
error(Path, EC);
switch (Status.type()) {
case sys::fs::file_type::regular_file:
case sys::fs::file_type::symlink_file:
case sys::fs::file_type::type_unknown:
BundlePaths.push_back(Path);
break;
default: /*ignore*/;
}
}
error(BundlePath, EC);
}
if (!BundlePaths.size())
BundlePaths.push_back(InputPath);
return BundlePaths;
}

int main(int argc, char **argv) {
InitLLVM X(argc, argv);

Expand Down Expand Up @@ -686,8 +657,14 @@ int main(int argc, char **argv) {
// Expand any .dSYM bundles to the individual object files contained therein.
std::vector<std::string> Objects;
for (const auto &F : InputFilenames) {
auto Objs = expandBundle(F);
llvm::append_range(Objects, Objs);
if (auto DsymObjectsOrErr = MachOObjectFile::findDsymObjectMembers(F)) {
if (DsymObjectsOrErr->empty())
Objects.push_back(F);
else
llvm::append_range(Objects, *DsymObjectsOrErr);
} else {
error(DsymObjectsOrErr.takeError());
}
}

bool Success = true;
Expand Down
52 changes: 16 additions & 36 deletions llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp
Expand Up @@ -20,7 +20,6 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/Signals.h"
Expand Down Expand Up @@ -126,6 +125,13 @@ static opt<bool> LookupAddressesFromStdin(
/// @}
//===----------------------------------------------------------------------===//

static void error(Error Err) {
if (!Err)
return;
WithColor::error() << toString(std::move(Err)) << "\n";
exit(1);
}

static void error(StringRef Prefix, llvm::Error Err) {
if (!Err)
return;
Expand All @@ -141,39 +147,6 @@ static void error(StringRef Prefix, std::error_code EC) {
exit(1);
}

/// If the input path is a .dSYM bundle (as created by the dsymutil tool),
/// replace it with individual entries for each of the object files inside the
/// bundle otherwise return the input path.
static std::vector<std::string> expandBundle(const std::string &InputPath) {
std::vector<std::string> BundlePaths;
SmallString<256> BundlePath(InputPath);
// Manually open up the bundle to avoid introducing additional dependencies.
if (sys::fs::is_directory(BundlePath) &&
sys::path::extension(BundlePath) == ".dSYM") {
std::error_code EC;
sys::path::append(BundlePath, "Contents", "Resources", "DWARF");
for (sys::fs::directory_iterator Dir(BundlePath, EC), DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
const std::string &Path = Dir->path();
sys::fs::file_status Status;
EC = sys::fs::status(Path, Status);
error(Path, EC);
switch (Status.type()) {
case sys::fs::file_type::regular_file:
case sys::fs::file_type::symlink_file:
case sys::fs::file_type::type_unknown:
BundlePaths.push_back(Path);
break;
default: /*ignore*/;
}
}
error(BundlePath, EC);
}
if (!BundlePaths.size())
BundlePaths.push_back(InputPath);
return BundlePaths;
}

static uint32_t getCPUType(MachOObjectFile &MachO) {
if (MachO.is64Bit())
return MachO.getHeader64().cputype;
Expand Down Expand Up @@ -420,8 +393,15 @@ static llvm::Error convertFileToGSYM(raw_ostream &OS) {

OS << "Input file: " << ConvertFilename << "\n";

auto Objs = expandBundle(ConvertFilename);
llvm::append_range(Objects, Objs);
if (auto DsymObjectsOrErr =
MachOObjectFile::findDsymObjectMembers(ConvertFilename)) {
if (DsymObjectsOrErr->empty())
Objects.push_back(ConvertFilename);
else
llvm::append_range(Objects, *DsymObjectsOrErr);
} else {
error(DsymObjectsOrErr.takeError());
}

for (auto Object : Objects) {
if (auto Err = handleFileConversionToGSYM(Object, OutFile))
Expand Down

0 comments on commit b68061a

Please sign in to comment.