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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221444 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Majnemer 2014-11-06 08:10:41 +00:00
parent a67e1693fc
commit 42b17f97cf
2 changed files with 45 additions and 13 deletions

View File

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

View File

@ -1,6 +1,6 @@
RUN: yaml2obj %p/Inputs/COFF/i386.yaml | llvm-nm -a - \
RUN: yaml2obj %p/Inputs/COFF/i386.yaml | llvm-nm -a -S - \
RUN: | FileCheck %s -check-prefix COFF
RUN: yaml2obj %p/Inputs/COFF/x86-64.yaml | llvm-nm -a - \
RUN: yaml2obj %p/Inputs/COFF/x86-64.yaml | llvm-nm -a -S - \
RUN: | FileCheck %s -check-prefix COFF
RUN: llvm-nm %p/Inputs/trivial-object-test.elf-i386 \
RUN: | FileCheck %s -check-prefix ELF
@ -49,11 +49,11 @@ RUN: llvm-nm | FileCheck %s -check-prefix A-OUT
REQUIRES: shell
COFF: 00000000 d .data
COFF: 00000000 t .text
COFF: 00000000 d L{{_?}}.str
COFF: 00000000 {{.*}} d .data
COFF: 00000000 {{.*}} t .text
COFF: 00000000 0000000d d L{{_?}}.str
COFF: U {{_?}}SomeOtherFunction
COFF: 00000000 T {{_?}}main
COFF: 00000000 {{.*}} T {{_?}}main
COFF: U {{_?}}puts
COFF-COMMON: 00000000 00000000 b .bss