[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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232300 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Frederic Riss 2015-03-15 01:29:30 +00:00
parent 40510a07cf
commit e7a356409d
4 changed files with 49 additions and 34 deletions

View File

@ -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

View File

@ -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';
}

View File

@ -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<SymbolMapping> 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.

View 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.");
}