[dsymutil] Handle the -oso-prepend-path option when the input is a YAML debug map
[oota-llvm.git] / tools / dsymutil / MachODebugMapParser.cpp
index 7bb0011fbfdb3d16731c0050a6c1df2f418e3e01..14dafb4065b43885f02d939031de97fef65436fe 100644 (file)
@@ -51,6 +51,10 @@ private:
   /// 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);
@@ -149,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
@@ -159,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:
@@ -174,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.");
 }
@@ -229,13 +242,32 @@ void MachODebugMapParser::loadMainBinarySymbols() {
   }
 }
 
+ErrorOr<std::unique_ptr<DebugMap>>
+parseYAMLDebugMap(StringRef InputFile, StringRef PrependPath, bool Verbose) {
+  auto ErrOrFile = MemoryBuffer::getFileOrSTDIN(InputFile);
+  if (auto Err =ErrOrFile.getError())
+    return Err;
+
+  std::unique_ptr<DebugMap> Res;
+  yaml::Input yin((*ErrOrFile)->getBuffer(), &PrependPath);
+  yin >> Res;
+
+  if (auto EC = yin.error())
+    return EC;
+
+  return std::move(Res);
+}
+
 namespace llvm {
 namespace dsymutil {
-llvm::ErrorOr<std::unique_ptr<DebugMap>> parseDebugMap(StringRef InputFile,
-                                                       StringRef PrependPath,
-                                                       bool Verbose) {
-  MachODebugMapParser Parser(InputFile, PrependPath, Verbose);
-  return Parser.parse();
+llvm::ErrorOr<std::unique_ptr<DebugMap>>
+parseDebugMap(StringRef InputFile, StringRef PrependPath, bool Verbose, bool InputIsYAML) {
+  if (!InputIsYAML) {
+    MachODebugMapParser Parser(InputFile, PrependPath, Verbose);
+    return Parser.parse();
+  } else {
+    return parseYAMLDebugMap(InputFile, PrependPath, Verbose);
+  }
 }
 }
 }