Stop inventing symbol sizes.

MachO and COFF quite reasonably only define the size for common symbols.

We used to try to figure out the "size" by computing the gap from one symbol to
the next.

This would not be correct in general, since a part of a section can belong to no
visible symbol (padding, private globals).

It was also really expensive, since we would walk every symbol to find the size
of one.

If a caller really wants this, it can sort all the symbols once and get all the
gaps ("size") in O(n log n) instead of O(n^2).

On MachO this also has the advantage of centralizing all the checks for an
invalid n_sect.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238028 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola
2015-05-22 15:43:00 +00:00
parent 08bac7b901
commit 7b677dd986
7 changed files with 14 additions and 112 deletions

View File

@@ -240,59 +240,10 @@ std::error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref,
uint64_t &Result) const {
COFFSymbolRef Symb = getCOFFSymbol(Ref);
if (Symb.isAnyUndefined()) {
Result = UnknownAddressOrSize;
return object_error::success;
}
if (Symb.isCommon()) {
if (Symb.isCommon())
Result = Symb.getValue();
return object_error::success;
}
// 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)) {
// 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();
} else {
// Take the difference between our symbol and the symbol that comes after
// our symbol.
Result = AfterAddr - SymbAddr;
}
else
Result = UnknownAddressOrSize;
return object_error::success;
}