[x86] Update the order of instructions after I switched to a bitcast
[oota-llvm.git] / tools / dsymutil / MachODebugMapParser.cpp
index c67e90c64eb486bfb6f0e97f0366460c504fcf5d..bf64303b9eab2872ffcea0abffcbbc3837b98602 100644 (file)
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "BinaryHolder.h"
 #include "DebugMap.h"
 #include "dsymutil.h"
 #include "llvm/Object/MachO.h"
@@ -20,8 +21,11 @@ using namespace llvm::object;
 
 class MachODebugMapParser {
 public:
-  MachODebugMapParser(StringRef BinaryPath, StringRef PathPrefix = "")
-      : BinaryPath(BinaryPath), PathPrefix(PathPrefix) {}
+  MachODebugMapParser(StringRef BinaryPath, StringRef PathPrefix = "",
+                      bool Verbose = false)
+      : BinaryPath(BinaryPath), PathPrefix(PathPrefix),
+        MainBinaryHolder(Verbose), CurrentObjectHolder(Verbose),
+        CurrentDebugMapObject(nullptr) {}
 
   /// \brief Parses and returns the DebugMap of the input binary.
   /// \returns an error in case the provided BinaryPath doesn't exist
@@ -32,21 +36,25 @@ private:
   std::string BinaryPath;
   std::string PathPrefix;
 
-  /// OwningBinary constructed from the BinaryPath.
-  object::OwningBinary<object::MachOObjectFile> MainOwningBinary;
+  /// Owns the MemoryBuffer for the main binary.
+  BinaryHolder MainBinaryHolder;
   /// Map of the binary symbol addresses.
   StringMap<uint64_t> MainBinarySymbolAddresses;
   StringRef MainBinaryStrings;
   /// The constructed DebugMap.
   std::unique_ptr<DebugMap> Result;
 
-  /// Handle to the currently processed object file.
-  object::OwningBinary<object::MachOObjectFile> CurrentObjectFile;
+  /// Owns the MemoryBuffer for the currently handled object file.
+  BinaryHolder CurrentObjectHolder;
   /// Map of the currently processed object file symbol addresses.
   StringMap<uint64_t> CurrentObjectAddresses;
   /// Element of the debug map corresponfing to the current object file.
   DebugMapObject *CurrentDebugMapObject;
 
+  /// Holds function info while function scope processing.
+  const char *CurrentFunctionName;
+  uint64_t CurrentFunctionAddress;
+
   void switchToNewDebugMapObject(StringRef Filename);
   void resetParserState();
   uint64_t getMainBinarySymbolAddress(StringRef Name);
@@ -65,26 +73,10 @@ private:
 static void Warning(const Twine &Msg) { errs() << "warning: " + Msg + "\n"; }
 }
 
-static ErrorOr<OwningBinary<MachOObjectFile>>
-createMachOBinary(StringRef File) {
-  auto MemBufOrErr = MemoryBuffer::getFile(File);
-  if (auto Error = MemBufOrErr.getError())
-    return Error;
-
-  MemoryBufferRef BufRef = (*MemBufOrErr)->getMemBufferRef();
-  auto MachOOrErr = ObjectFile::createMachOObjectFile(BufRef);
-  if (auto Error = MachOOrErr.getError())
-    return Error;
-
-  return OwningBinary<MachOObjectFile>(std::move(*MachOOrErr),
-                                       std::move(*MemBufOrErr));
-}
-
 /// Reset the parser state coresponding to the current object
 /// file. This is to be called after an object file is finished
 /// processing.
 void MachODebugMapParser::resetParserState() {
-  CurrentObjectFile = OwningBinary<object::MachOObjectFile>();
   CurrentObjectAddresses.clear();
   CurrentDebugMapObject = nullptr;
 }
@@ -98,30 +90,35 @@ void MachODebugMapParser::switchToNewDebugMapObject(StringRef Filename) {
   SmallString<80> Path(PathPrefix);
   sys::path::append(Path, Filename);
 
-  auto MachOOrError = createMachOBinary(Path);
+  auto MachOOrError = CurrentObjectHolder.GetFileAs<MachOObjectFile>(Path);
   if (auto Error = MachOOrError.getError()) {
     Warning(Twine("cannot open debug object \"") + Path.str() + "\": " +
             Error.message() + "\n");
     return;
   }
 
-  CurrentObjectFile = std::move(*MachOOrError);
   loadCurrentObjectFileSymbols();
   CurrentDebugMapObject = &Result->addDebugMapObject(Path);
 }
 
+static Triple getTriple(const object::MachOObjectFile &Obj) {
+  Triple TheTriple("unknown-unknown-unknown");
+  TheTriple.setArch(Triple::ArchType(Obj.getArch()));
+  TheTriple.setObjectFormat(Triple::MachO);
+  return TheTriple;
+}
+
 /// This main parsing routine tries to open the main binary and if
 /// successful iterates over the STAB entries. The real parsing is
 /// done in handleStabSymbolTableEntry.
 ErrorOr<std::unique_ptr<DebugMap>> MachODebugMapParser::parse() {
-  auto MainBinaryOrError = createMachOBinary(BinaryPath);
-  if (auto Error = MainBinaryOrError.getError())
+  auto MainBinOrError = MainBinaryHolder.GetFileAs<MachOObjectFile>(BinaryPath);
+  if (auto Error = MainBinOrError.getError())
     return Error;
 
-  MainOwningBinary = std::move(*MainBinaryOrError);
+  const MachOObjectFile &MainBinary = *MainBinOrError;
   loadMainBinarySymbols();
-  Result = make_unique<DebugMap>();
-  const auto &MainBinary = *MainOwningBinary.getBinary();
+  Result = make_unique<DebugMap>(getTriple(MainBinary));
   MainBinaryStrings = MainBinary.getStringTableData();
   for (const SymbolRef &Symbol : MainBinary.symbols()) {
     const DataRefImpl &DRI = Symbol.getRawDataRefImpl();
@@ -156,6 +153,7 @@ void MachODebugMapParser::handleStabSymbolTableEntry(uint32_t StringIndex,
   if (!CurrentDebugMapObject)
     return;
 
+  uint32_t Size = 0;
   switch (Type) {
   case MachO::N_GSYM:
     // This is a global variable. We need to query the main binary
@@ -166,11 +164,18 @@ void MachODebugMapParser::handleStabSymbolTableEntry(uint32_t StringIndex,
       return;
     break;
   case MachO::N_FUN:
-    // Functions are scopes in STABS. They have an end marker that we
-    // need to ignore.
-    if (Name[0] == '\0')
+    // Functions are scopes in STABS. They have an end marker that
+    // contains the function size.
+    if (Name[0] == '\0') {
+      Size = Value;
+      Value = CurrentFunctionAddress;
+      Name = CurrentFunctionName;
+      break;
+    } else {
+      CurrentFunctionName = Name;
+      CurrentFunctionAddress = Value;
       return;
-    break;
+    }
   case MachO::N_STSYM:
     break;
   default:
@@ -181,7 +186,8 @@ void MachODebugMapParser::handleStabSymbolTableEntry(uint32_t StringIndex,
   if (ObjectSymIt == CurrentObjectAddresses.end())
     return Warning("could not find object file symbol for symbol " +
                    Twine(Name));
-  if (!CurrentDebugMapObject->addSymbol(Name, ObjectSymIt->getValue(), Value))
+  if (!CurrentDebugMapObject->addSymbol(Name, ObjectSymIt->getValue(), Value,
+                                        Size))
     return Warning(Twine("failed to insert symbol '") + Name +
                    "' in the debug map.");
 }
@@ -189,9 +195,8 @@ void MachODebugMapParser::handleStabSymbolTableEntry(uint32_t StringIndex,
 /// Load the current object file symbols into CurrentObjectAddresses.
 void MachODebugMapParser::loadCurrentObjectFileSymbols() {
   CurrentObjectAddresses.clear();
-  const auto &Binary = *CurrentObjectFile.getBinary();
 
-  for (auto Sym : Binary.symbols()) {
+  for (auto Sym : CurrentObjectHolder.Get().symbols()) {
     StringRef Name;
     uint64_t Addr;
     if (Sym.getAddress(Addr) || Addr == UnknownAddressOrSize ||
@@ -214,9 +219,9 @@ uint64_t MachODebugMapParser::getMainBinarySymbolAddress(StringRef Name) {
 /// Load the interesting main binary symbols' addresses into
 /// MainBinarySymbolAddresses.
 void MachODebugMapParser::loadMainBinarySymbols() {
-  const MachOObjectFile &Binary = *MainOwningBinary.getBinary();
-  section_iterator Section = Binary.section_end();
-  for (const auto &Sym : Binary.symbols()) {
+  const MachOObjectFile &MainBinary = MainBinaryHolder.GetAs<MachOObjectFile>();
+  section_iterator Section = MainBinary.section_end();
+  for (const auto &Sym : MainBinary.symbols()) {
     SymbolRef::Type Type;
     // Skip undefined and STAB entries.
     if (Sym.getType(Type) || (Type & SymbolRef::ST_Debug) ||
@@ -239,9 +244,9 @@ void MachODebugMapParser::loadMainBinarySymbols() {
 
 namespace llvm {
 namespace dsymutil {
-llvm::ErrorOr<std::unique_ptr<DebugMap>> parseDebugMap(StringRef InputFile,
-                                                       StringRef PrependPath) {
-  MachODebugMapParser Parser(InputFile, PrependPath);
+llvm::ErrorOr<std::unique_ptr<DebugMap>>
+parseDebugMap(StringRef InputFile, StringRef PrependPath, bool Verbose) {
+  MachODebugMapParser Parser(InputFile, PrependPath, Verbose);
   return Parser.parse();
 }
 }