forked from OSchip/llvm-project
[BOLT] Add initial bits for parsing MachO files
Summary: Start adding initial bits for MachO, this diff contains some small preparations for finding functions inside a MachO binary, this will be done in the next diff. The concept of a section in the MachO world is quite different from ELF, nevertheless, for functions for now it more or less fits into the current picture (in BOLT), but things will diverge more significantly a bit later. (cherry picked from FBD19648161)
This commit is contained in:
parent
58a129a602
commit
36cf37c4c1
|
@ -89,12 +89,13 @@ class BinarySection {
|
|||
}
|
||||
static StringRef getContents(SectionRef Section) {
|
||||
StringRef Contents;
|
||||
if (ELFSectionRef(Section).getType() != ELF::SHT_NOBITS) {
|
||||
if (auto EC = Section.getContents(Contents)) {
|
||||
errs() << "BOLT-ERROR: cannot get section contents for "
|
||||
<< getName(Section) << ": " << EC.message() << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
if (Section.getObject()->isELF() && ELFSectionRef(Section).getType() == ELF::SHT_NOBITS)
|
||||
return Contents;
|
||||
|
||||
if (auto EC = Section.getContents(Contents)) {
|
||||
errs() << "BOLT-ERROR: cannot get section contents for "
|
||||
<< getName(Section) << ": " << EC.message() << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
return Contents;
|
||||
}
|
||||
|
@ -152,10 +153,12 @@ public:
|
|||
Address(Section.getAddress()),
|
||||
Size(Section.getSize()),
|
||||
Alignment(Section.getAlignment()),
|
||||
ELFType(ELFSectionRef(Section).getType()),
|
||||
ELFFlags(ELFSectionRef(Section).getFlags()),
|
||||
IsLocal(IsLocal || StringRef(Name).startswith(".local.")),
|
||||
OutputName(Name) {
|
||||
if (Section.getObject()->isELF()) {
|
||||
ELFType = ELFSectionRef(Section).getType();
|
||||
ELFFlags = ELFSectionRef(Section).getFlags();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: pass Data as StringRef/ArrayRef? use StringRef::copy method.
|
||||
|
|
|
@ -92,12 +92,14 @@ add_llvm_tool(llvm-bolt
|
|||
ExecutableFileMemoryManager.cpp
|
||||
Heatmap.cpp
|
||||
JumpTable.cpp
|
||||
MachORewriteInstance.cpp
|
||||
MCPlusBuilder.cpp
|
||||
ParallelUtilities.cpp
|
||||
ProfileReader.cpp
|
||||
ProfileWriter.cpp
|
||||
Relocation.cpp
|
||||
RewriteInstance.cpp
|
||||
Utils.cpp
|
||||
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
//===--- MachORewriteInstance.cpp - Instance of a rewriting process. ------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "MachORewriteInstance.h"
|
||||
#include "BinaryContext.h"
|
||||
#include "BinaryFunction.h"
|
||||
#include "Utils.h"
|
||||
#include "llvm/Support/Timer.h"
|
||||
|
||||
namespace opts {
|
||||
|
||||
using namespace llvm;
|
||||
extern cl::opt<bool> PrintSections;
|
||||
|
||||
} // namespace opts
|
||||
|
||||
namespace llvm {
|
||||
namespace bolt {
|
||||
|
||||
#undef DEBUG_TYPE
|
||||
#define DEBUG_TYPE "bolt"
|
||||
|
||||
MachORewriteInstance::MachORewriteInstance(object::MachOObjectFile *InputFile,
|
||||
DataReader &DR)
|
||||
: InputFile(InputFile),
|
||||
BC(BinaryContext::createBinaryContext(
|
||||
InputFile, DR,
|
||||
DWARFContext::create(*InputFile, nullptr,
|
||||
DWARFContext::defaultErrorHandler, "", false))) {
|
||||
}
|
||||
|
||||
void MachORewriteInstance::readSpecialSections() {
|
||||
for (const auto &Section : InputFile->sections()) {
|
||||
StringRef SectionName;
|
||||
check_error(Section.getName(SectionName), "cannot get section name");
|
||||
// Only register sections with names.
|
||||
if (!SectionName.empty()) {
|
||||
BC->registerSection(Section);
|
||||
DEBUG(dbgs() << "BOLT-DEBUG: registering section " << SectionName
|
||||
<< " @ 0x" << Twine::utohexstr(Section.getAddress()) << ":0x"
|
||||
<< Twine::utohexstr(Section.getAddress() + Section.getSize())
|
||||
<< "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (opts::PrintSections) {
|
||||
outs() << "BOLT-INFO: Sections from original binary:\n";
|
||||
BC->printSections(outs());
|
||||
}
|
||||
}
|
||||
|
||||
void MachORewriteInstance::run() {
|
||||
readSpecialSections();
|
||||
}
|
||||
|
||||
MachORewriteInstance::~MachORewriteInstance() {}
|
||||
|
||||
} // namespace bolt
|
||||
} // namespace llvm
|
|
@ -0,0 +1,43 @@
|
|||
//===--- MachORewriteInstance.h - Instance of a rewriting process. --------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Interface to control an instance of a macho binary rewriting process.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TOOLS_LLVM_BOLT_MACHO_REWRITE_INSTANCE_H
|
||||
#define LLVM_TOOLS_LLVM_BOLT_MACHO_REWRITE_INSTANCE_H
|
||||
|
||||
#include "llvm/Object/MachO.h"
|
||||
#include <memory>
|
||||
|
||||
namespace llvm {
|
||||
namespace bolt {
|
||||
|
||||
class BinaryContext;
|
||||
class DataReader;
|
||||
|
||||
class MachORewriteInstance {
|
||||
object::MachOObjectFile *InputFile;
|
||||
std::unique_ptr<BinaryContext> BC;
|
||||
|
||||
void readSpecialSections();
|
||||
|
||||
public:
|
||||
MachORewriteInstance(object::MachOObjectFile *InputFile, DataReader &DR);
|
||||
~MachORewriteInstance();
|
||||
|
||||
/// Run all the necessary steps to read, optimize and rewrite the binary.
|
||||
void run();
|
||||
};
|
||||
|
||||
} // namespace bolt
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
|
@ -27,6 +27,7 @@
|
|||
#include "ProfileReader.h"
|
||||
#include "ProfileWriter.h"
|
||||
#include "Relocation.h"
|
||||
#include "Utils.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/BinaryFormat/Dwarf.h"
|
||||
|
@ -292,12 +293,7 @@ PrintGlobals("print-globals",
|
|||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintSections("print-sections",
|
||||
cl::desc("print all registered sections"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
extern cl::opt<bool> PrintSections;
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintLoopInfo("print-loops",
|
||||
|
@ -539,38 +535,11 @@ const char RewriteInstance::TimerGroupDesc[] = "Rewrite passes";
|
|||
|
||||
namespace llvm {
|
||||
namespace bolt {
|
||||
|
||||
extern const char *BoltRevision;
|
||||
|
||||
void report_error(StringRef Message, std::error_code EC) {
|
||||
assert(EC);
|
||||
errs() << "BOLT-ERROR: '" << Message << "': " << EC.message() << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void report_error(StringRef Message, Error E) {
|
||||
assert(E);
|
||||
errs() << "BOLT-ERROR: '" << Message << "': " << toString(std::move(E))
|
||||
<< ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void check_error(std::error_code EC, StringRef Message) {
|
||||
if (!EC)
|
||||
return;
|
||||
report_error(Message, EC);
|
||||
}
|
||||
|
||||
void check_error(Error E, Twine Message) {
|
||||
if (!E)
|
||||
return;
|
||||
handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) {
|
||||
llvm::errs() << "BOLT-ERROR: '" << Message << "': " << EIB.message()
|
||||
<< '\n';
|
||||
exit(1);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace bolt
|
||||
} // namespace llvm
|
||||
|
||||
namespace {
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===--- RewriteInstance.h - Interface for machine-level function ---------===//
|
||||
//===--- RewriteInstance.h - Instance of a rewriting process. -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
//===--- Utils.cpp - Common helper functions ------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Common helper functions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Utils.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace bolt {
|
||||
|
||||
void report_error(StringRef Message, std::error_code EC) {
|
||||
assert(EC);
|
||||
errs() << "BOLT-ERROR: '" << Message << "': " << EC.message() << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void report_error(StringRef Message, Error E) {
|
||||
assert(E);
|
||||
errs() << "BOLT-ERROR: '" << Message << "': " << toString(std::move(E))
|
||||
<< ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void check_error(std::error_code EC, StringRef Message) {
|
||||
if (!EC)
|
||||
return;
|
||||
report_error(Message, EC);
|
||||
}
|
||||
|
||||
void check_error(Error E, Twine Message) {
|
||||
if (!E)
|
||||
return;
|
||||
handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) {
|
||||
llvm::errs() << "BOLT-ERROR: '" << Message << "': " << EIB.message()
|
||||
<< '\n';
|
||||
exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace bolt
|
||||
} // namespace llvm
|
|
@ -0,0 +1,35 @@
|
|||
//===--- Utils.h - Common helper functions --------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Common helper functions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TOOLS_LLVM_BOLT_UTILS_H
|
||||
#define LLVM_TOOLS_LLVM_BOLT_UTILS_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace bolt {
|
||||
|
||||
void report_error(StringRef Message, std::error_code EC);
|
||||
|
||||
void report_error(StringRef Message, Error E);
|
||||
|
||||
void check_error(std::error_code EC, StringRef Message);
|
||||
|
||||
void check_error(Error E, Twine Message);
|
||||
|
||||
} // namespace bolt
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "DataAggregator.h"
|
||||
#include "DataReader.h"
|
||||
#include "MachORewriteInstance.h"
|
||||
#include "RewriteInstance.h"
|
||||
#include "llvm/Object/Binary.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
@ -106,7 +107,15 @@ PerfDataA("p",
|
|||
cl::aliasopt(PerfData),
|
||||
cl::cat(AggregatorCategory));
|
||||
|
||||
cl::opt<bool>
|
||||
PrintSections("print-sections",
|
||||
cl::desc("print all registered sections"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
} // namespace opts
|
||||
|
||||
static StringRef ToolName;
|
||||
|
||||
static void report_error(StringRef Message, std::error_code EC) {
|
||||
|
@ -324,6 +333,9 @@ int main(int argc, char **argv) {
|
|||
if (auto *e = dyn_cast<ELFObjectFileBase>(&Binary)) {
|
||||
RewriteInstance RI(e, *DR.get(), *DA.get(), argc, argv, ToolPath);
|
||||
RI.run();
|
||||
} else if (auto *O = dyn_cast<MachOObjectFile>(&Binary)) {
|
||||
MachORewriteInstance MachORI(O, *DR);
|
||||
MachORI.run();
|
||||
} else {
|
||||
report_error(opts::InputFilename, object_error::invalid_file_type);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue