From: Frederic Riss Date: Sun, 15 Mar 2015 01:29:30 +0000 (+0000) Subject: [dsymutil] Add function size to the debug map. X-Git-Tag: llvmorg-3.7.0-rc1~9198 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=912d0f1261d0a56cc7a8a23d83dfb03b11597c19;p=platform%2Fupstream%2Fllvm.git [dsymutil] Add function size to the debug map. The debug map embedded by ld64 in binaries conatins function sizes. These sizes are less precise than the ones given by the debug information (byte granularity vs linker atom granularity), but they might cover code that is referenced in the line table but not in the DIE tree (that might very well be a compiler bug that I need to investigate later). Anyway, extracting that information is necessary to be able to mimic dsymutil's behavior exactly. llvm-svn: 232300 --- diff --git a/llvm/test/tools/dsymutil/debug-map-parsing.test b/llvm/test/tools/dsymutil/debug-map-parsing.test index b64ad9f..3422316 100644 --- a/llvm/test/tools/dsymutil/debug-map-parsing.test +++ b/llvm/test/tools/dsymutil/debug-map-parsing.test @@ -10,16 +10,16 @@ Check that We can parse the debug map of the basic executable. CHECK-NOT: error CHECK: DEBUG MAP: x86_64-unknown-unknown-macho CHECK: /Inputs/basic1.macho.x86_64.o: -CHECK: 0000000000000000 => 0000000100000ea0 _main +CHECK: 0000000000000000 => 0000000100000ea0+0x24 _main CHECK: /Inputs/basic2.macho.x86_64.o: -CHECK: 0000000000000310 => 0000000100001000 _baz -CHECK: 0000000000000020 => 0000000100000ed0 _foo -CHECK: 0000000000000070 => 0000000100000f20 _inc -CHECK: 0000000000000560 => 0000000100001008 _private_int +CHECK: 0000000000000310 => 0000000100001000+0x0 _baz +CHECK: 0000000000000020 => 0000000100000ed0+0x50 _foo +CHECK: 0000000000000070 => 0000000100000f20+0x17 _inc +CHECK: 0000000000000560 => 0000000100001008+0x0 _private_int CHECK: /Inputs/basic3.macho.x86_64.o: -CHECK: 0000000000000020 => 0000000100000f40 _bar -CHECK: 0000000000000070 => 0000000100000f90 _inc -CHECK: 0000000000000004 => 0000000100001004 _val +CHECK: 0000000000000020 => 0000000100000f40+0x50 _bar +CHECK: 0000000000000070 => 0000000100000f90+0x19 _inc +CHECK: 0000000000000004 => 0000000100001004+0x0 _val CHECK: END DEBUG MAP @@ -28,12 +28,12 @@ Check that we can parse the debug-map of the basic-lto executable CHECK-LTO-NOT: error CHECK-LTO: DEBUG MAP: x86_64-unknown-unknown-macho CHECK-LTO: /Inputs/basic-lto.macho.x86_64.o: -CHECK-LTO: 0000000000000050 => 0000000100000f90 _bar -CHECK-LTO: 0000000000000658 => 0000000100001000 _baz -CHECK-LTO: 0000000000000010 => 0000000100000f50 _foo -CHECK-LTO: 0000000000000000 => 0000000100000f40 _main -CHECK-LTO: 00000000000008e8 => 0000000100001008 _private_int -CHECK-LTO: 00000000000008ec => 0000000100001004 _val +CHECK-LTO: 0000000000000050 => 0000000100000f90+0x24 _bar +CHECK-LTO: 0000000000000658 => 0000000100001000+0x0 _baz +CHECK-LTO: 0000000000000010 => 0000000100000f50+0x40 _foo +CHECK-LTO: 0000000000000000 => 0000000100000f40+0x10 _main +CHECK-LTO: 00000000000008e8 => 0000000100001008+0x0 _private_int +CHECK-LTO: 00000000000008ec => 0000000100001004+0x0 _val CHECK-LTO: END DEBUG MAP Check thet we correctly handle debug maps with archive members (including only @@ -51,16 +51,16 @@ CHECK-ARCHIVE-NEXT: found member in current archive. CHECK-ARCHIVE: DEBUG MAP: x86_64-unknown-unknown-macho CHECK-ARCHIVE: object addr => executable addr symbol name CHECK-ARCHIVE: /Inputs/basic1.macho.x86_64.o: -CHECK-ARCHIVE: 0000000000000000 => 0000000100000ea0 _main +CHECK-ARCHIVE: 0000000000000000 => 0000000100000ea0+0x24 _main CHECK-ARCHIVE: /Inputs/./libbasic.a(basic2.macho.x86_64.o): -CHECK-ARCHIVE: 0000000000000310 => 0000000100001000 _baz -CHECK-ARCHIVE: 0000000000000020 => 0000000100000ed0 _foo -CHECK-ARCHIVE: 0000000000000070 => 0000000100000f20 _inc -CHECK-ARCHIVE: 0000000000000560 => 0000000100001004 _private_int +CHECK-ARCHIVE: 0000000000000310 => 0000000100001000+0x0 _baz +CHECK-ARCHIVE: 0000000000000020 => 0000000100000ed0+0x50 _foo +CHECK-ARCHIVE: 0000000000000070 => 0000000100000f20+0x17 _inc +CHECK-ARCHIVE: 0000000000000560 => 0000000100001004+0x0 _private_int CHECK-ARCHIVE: /Inputs/./libbasic.a(basic3.macho.x86_64.o): -CHECK-ARCHIVE: 0000000000000020 => 0000000100000f40 _bar -CHECK-ARCHIVE: 0000000000000070 => 0000000100000f90 _inc -CHECK-ARCHIVE: 0000000000000004 => 0000000100001008 _val +CHECK-ARCHIVE: 0000000000000020 => 0000000100000f40+0x50 _bar +CHECK-ARCHIVE: 0000000000000070 => 0000000100000f90+0x19 _inc +CHECK-ARCHIVE: 0000000000000004 => 0000000100001008+0x0 _val CHECK-ARCHIVE: END DEBUG MAP Check that we warn about missing object files (this presumes that the files aren't diff --git a/llvm/tools/dsymutil/DebugMap.cpp b/llvm/tools/dsymutil/DebugMap.cpp index c04b2fe..9fa3f78 100644 --- a/llvm/tools/dsymutil/DebugMap.cpp +++ b/llvm/tools/dsymutil/DebugMap.cpp @@ -23,9 +23,9 @@ DebugMapObject::DebugMapObject(StringRef ObjectFilename) : Filename(ObjectFilename) {} bool DebugMapObject::addSymbol(StringRef Name, uint64_t ObjectAddress, - uint64_t LinkedAddress) { + uint64_t LinkedAddress, uint32_t Size) { auto InsertResult = Symbols.insert( - std::make_pair(Name, SymbolMapping(ObjectAddress, LinkedAddress))); + std::make_pair(Name, SymbolMapping(ObjectAddress, LinkedAddress, Size))); if (InsertResult.second) AddressToMapping[ObjectAddress] = &*InsertResult.first; @@ -45,9 +45,9 @@ void DebugMapObject::print(raw_ostream &OS) const { Entries.begin(), Entries.end(), [](const Entry &LHS, const Entry &RHS) { return LHS.first < RHS.first; }); for (const auto &Sym : Entries) { - OS << format("\t%016" PRIx64 " => %016" PRIx64 "\t%s\n", + OS << format("\t%016" PRIx64 " => %016" PRIx64 "+0x%x\t%s\n", Sym.second.ObjectAddress, Sym.second.BinaryAddress, - Sym.first.data()); + Sym.second.Size, Sym.first.data()); } OS << '\n'; } diff --git a/llvm/tools/dsymutil/DebugMap.h b/llvm/tools/dsymutil/DebugMap.h index 5bcf7a5..b24efa9f 100644 --- a/llvm/tools/dsymutil/DebugMap.h +++ b/llvm/tools/dsymutil/DebugMap.h @@ -101,8 +101,10 @@ public: struct SymbolMapping { uint64_t ObjectAddress; uint64_t BinaryAddress; - SymbolMapping(uint64_t ObjectAddress, uint64_t BinaryAddress) - : ObjectAddress(ObjectAddress), BinaryAddress(BinaryAddress) {} + uint32_t Size; + SymbolMapping(uint64_t ObjectAddress, uint64_t BinaryAddress, uint32_t Size) + : ObjectAddress(ObjectAddress), BinaryAddress(BinaryAddress), + Size(Size) {} }; typedef StringMapEntry DebugMapEntry; @@ -111,7 +113,7 @@ public: /// \returns false if the symbol was already registered. The request /// is discarded in this case. bool addSymbol(llvm::StringRef SymName, uint64_t ObjectAddress, - uint64_t LinkedAddress); + uint64_t LinkedAddress, uint32_t Size); /// \brief Lookup a symbol mapping. /// \returns null if the symbol isn't found. diff --git a/llvm/tools/dsymutil/MachODebugMapParser.cpp b/llvm/tools/dsymutil/MachODebugMapParser.cpp index 2f4a987..bf64303 100644 --- a/llvm/tools/dsymutil/MachODebugMapParser.cpp +++ b/llvm/tools/dsymutil/MachODebugMapParser.cpp @@ -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."); }