summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Object/COFFObjectFile.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-11-06 08:10:41 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-11-06 08:10:41 +0000
commit51ff559500c460f7f779019c1bfa964a1c2f223d (patch)
treedc544ef02b8c0a222b2d091bae16179747a525b1 /llvm/lib/Object/COFFObjectFile.cpp
parent03d2c51cf266f84be4988e8700f4954189087f1d (diff)
downloadbcm5719-llvm-51ff559500c460f7f779019c1bfa964a1c2f223d.tar.gz
bcm5719-llvm-51ff559500c460f7f779019c1bfa964a1c2f223d.zip
Object, COFF: Infer symbol sizes from adjacent symbols
Use the position of the subsequent symbol in the object file to infer the size of it's predecessor. I hope to eventually remove whatever COFF specific details from this little algorithm so that we can unify this logic with what Mach-O does. llvm-svn: 221444
Diffstat (limited to 'llvm/lib/Object/COFFObjectFile.cpp')
-rw-r--r--llvm/lib/Object/COFFObjectFile.cpp46
1 files changed, 39 insertions, 7 deletions
diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index 4fbb78254ea..7a0892dd98d 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/lib/Object/COFFObjectFile.cpp
@@ -250,20 +250,52 @@ std::error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref,
return object_error::success;
}
}
- // FIXME: Return the correct size. This requires looking at all the symbols
- // in the same section as this symbol, and looking for either the next
- // symbol, or the end of the section.
+
+ // Let's attempt to get the size of the symbol by looking at the address of
+ // the symbol after the symbol in question.
+ uint64_t SymbAddr;
+ if (std::error_code EC = getSymbolAddress(Ref, SymbAddr))
+ return EC;
int32_t SectionNumber = Symb.getSectionNumber();
- if (!COFF::isReservedSectionNumber(SectionNumber)) {
+ if (COFF::isReservedSectionNumber(SectionNumber)) {
+ // Absolute and debug symbols aren't sorted in any interesting way.
+ Result = 0;
+ return object_error::success;
+ }
+ const section_iterator SecEnd = section_end();
+ uint64_t AfterAddr = UnknownAddressOrSize;
+ for (const symbol_iterator &SymbI : symbols()) {
+ section_iterator SecI = SecEnd;
+ if (std::error_code EC = SymbI->getSection(SecI))
+ return EC;
+ // Check the symbol's section, skip it if it's in the wrong section.
+ // First, make sure it is in any section.
+ if (SecI == SecEnd)
+ continue;
+ // Second, make sure it is in the same section as the symbol in question.
+ if (!sectionContainsSymbol(SecI->getRawDataRefImpl(), Ref))
+ continue;
+ uint64_t Addr;
+ if (std::error_code EC = SymbI->getAddress(Addr))
+ return EC;
+ // We want to compare our symbol in question with the closest possible
+ // symbol that comes after.
+ if (AfterAddr > Addr && Addr > SymbAddr)
+ AfterAddr = Addr;
+ }
+ if (AfterAddr == UnknownAddressOrSize) {
+ // No symbol comes after this one, assume that everything after our symbol
+ // is part of it.
const coff_section *Section = nullptr;
if (std::error_code EC = getSection(SectionNumber, Section))
return EC;
-
Result = Section->SizeOfRawData - Symb.getValue();
- return object_error::success;
+ } else {
+ // Take the difference between our symbol and the symbol that comes after
+ // our symbol.
+ Result = AfterAddr - SymbAddr;
}
- Result = 0;
return object_error::success;
}
OpenPOWER on IntegriCloud