Result = Symb.getValue();
return object_error::success;
}
- if (Symb.isFunctionDefinition()) {
- ArrayRef<uint8_t> AuxData = getSymbolAuxData(Symb);
- if (!AuxData.empty()) {
- const auto *CAFD =
- reinterpret_cast<const coff_aux_function_definition *>(
- AuxData.data());
- Result = CAFD->TotalSize;
- 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;
}