[llvm] r221444 - Object, COFF: Infer symbol sizes from adjacent symbols

David Majnemer david.majnemer at gmail.com
Thu Nov 6 00:10:41 PST 2014


Author: majnemer
Date: Thu Nov  6 02:10:41 2014
New Revision: 221444

URL: http://llvm.org/viewvc/llvm-project?rev=221444&view=rev
Log:
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.

Modified:
    llvm/trunk/lib/Object/COFFObjectFile.cpp
    llvm/trunk/test/Object/nm-trivial-object.test

Modified: llvm/trunk/lib/Object/COFFObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/COFFObjectFile.cpp?rev=221444&r1=221443&r2=221444&view=diff
==============================================================================
--- llvm/trunk/lib/Object/COFFObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/COFFObjectFile.cpp Thu Nov  6 02:10:41 2014
@@ -250,20 +250,52 @@ std::error_code COFFObjectFile::getSymbo
       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;
 }
 

Modified: llvm/trunk/test/Object/nm-trivial-object.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/nm-trivial-object.test?rev=221444&r1=221443&r2=221444&view=diff
==============================================================================
--- llvm/trunk/test/Object/nm-trivial-object.test (original)
+++ llvm/trunk/test/Object/nm-trivial-object.test Thu Nov  6 02:10:41 2014
@@ -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-prefi
 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





More information about the llvm-commits mailing list