Stop inventing symbol sizes.
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 22 May 2015 15:43:00 +0000 (15:43 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 22 May 2015 15:43:00 +0000 (15:43 +0000)
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

lib/Object/COFFObjectFile.cpp
lib/Object/MachOObjectFile.cpp
test/Object/Inputs/macho-invalid-getsection-index [deleted file]
test/Object/Inputs/macho64-invalid-getsection-index [deleted file]
test/Object/macho-invalid.test
test/Object/objdump-symbol-table.test
test/tools/llvm-objdump/X86/macho-symbol-table.test

index d4f3b4306147f995a9b226fe4f6c8956be5fbce7..74709c88ba26c7050a3608f2b4a1eb75eab9c48a 100644 (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;
 }
index 504b3172c9d10c591f9ca374c7977188140b0e14..79f8100649881b2e9458616dd9011b3baf6e1a7a 100644 (file)
@@ -415,49 +415,13 @@ std::error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
 
 std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
                                                uint64_t &Result) const {
-  uint64_t BeginOffset;
-  uint64_t EndOffset = 0;
-  uint8_t SectionIndex;
-
-  MachO::nlist_base Entry = getSymbolTableEntryBase(this, DRI);
   uint64_t Value;
   getSymbolAddress(DRI, Value);
-  if (Value == UnknownAddressOrSize) {
+  uint32_t flags = getSymbolFlags(DRI);
+  if (flags & SymbolRef::SF_Common)
+    Result = Value;
+  else
     Result = UnknownAddressOrSize;
-    return object_error::success;
-  }
-
-  BeginOffset = Value;
-
-  SectionIndex = Entry.n_sect;
-  if (!SectionIndex) {
-    uint32_t flags = getSymbolFlags(DRI);
-    if (flags & SymbolRef::SF_Common)
-      Result = Value;
-    else
-      Result = UnknownAddressOrSize;
-    return object_error::success;
-  }
-  // Unfortunately symbols are unsorted so we need to touch all
-  // symbols from load command
-  for (const SymbolRef &Symbol : symbols()) {
-    DataRefImpl DRI = Symbol.getRawDataRefImpl();
-    Entry = getSymbolTableEntryBase(this, DRI);
-    getSymbolAddress(DRI, Value);
-    if (Value == UnknownAddressOrSize)
-      continue;
-    if (Entry.n_sect == SectionIndex && Value > BeginOffset)
-      if (!EndOffset || Value < EndOffset)
-        EndOffset = Value;
-  }
-  if (!EndOffset) {
-    DataRefImpl Sec;
-    Sec.d.a = SectionIndex-1;
-    uint64_t Size = getSectionSize(Sec);
-    EndOffset = getSectionAddress(Sec);
-    EndOffset += Size;
-  }
-  Result = EndOffset - BeginOffset;
   return object_error::success;
 }
 
@@ -2263,16 +2227,12 @@ MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
 }
 
 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const {
-  // TODO: What if Sections.size() == 0?
-  if (DRI.d.a >= Sections.size())
-    report_fatal_error("getSection: Invalid section index.");
+  assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
   return getStruct<MachO::section>(this, Sections[DRI.d.a]);
 }
 
 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
-  // TODO: What if Sections.size() == 0?
-  if (DRI.d.a >= Sections.size())
-    report_fatal_error("getSection64: Invalid section index.");
+  assert(DRI.d.a < Sections.size() && "Should have detected this earlier");
   return getStruct<MachO::section_64>(this, Sections[DRI.d.a]);
 }
 
diff --git a/test/Object/Inputs/macho-invalid-getsection-index b/test/Object/Inputs/macho-invalid-getsection-index
deleted file mode 100644 (file)
index b7e4b95..0000000
Binary files a/test/Object/Inputs/macho-invalid-getsection-index and /dev/null differ
diff --git a/test/Object/Inputs/macho64-invalid-getsection-index b/test/Object/Inputs/macho64-invalid-getsection-index
deleted file mode 100644 (file)
index a2a7bc1..0000000
Binary files a/test/Object/Inputs/macho64-invalid-getsection-index and /dev/null differ
index dae5c4eda7e7ab7a32cba84cb56a30424738f855..e2c9b6b7360e055bf01135d368dce907e435d241 100644 (file)
@@ -28,13 +28,6 @@ RUN:      | FileCheck -check-prefix NAME-PAST-EOF %s
 RUN: not llvm-nm %p/Inputs/macho-invalid-section-index-getSectionRawName 2>&1 \
 RUN:      | FileCheck -check-prefix INVALID-SECTION-IDX-SYMBOL-SEC %s
 
-RUN: not llvm-objdump -t %p/Inputs/macho-invalid-getsection-index 2>&1 \
-RUN:      | FileCheck -check-prefix INVALID-SECTION-IDX-GETSECT %s
-
-RUN: not llvm-objdump -t %p/Inputs/macho64-invalid-getsection-index 2>&1 \
-RUN:      | FileCheck -check-prefix INVALID-SECTION-IDX-GETSECT64 %s
-
-
 SMALL-LOADC-SIZE: Load command with size < 8 bytes
 SMALL-SEGLOADC-SIZE: Segment load command size is too small
 INCOMPLETE-LOADC: Malformed MachO file
@@ -43,5 +36,3 @@ BAD-SYMBOL: Requested symbol index is out of range
 NAME-PAST-EOF: Symbol name entry points before beginning or past end of file
 
 INVALID-SECTION-IDX-SYMBOL-SEC: getSymbolSection: Invalid section index
-INVALID-SECTION-IDX-GETSECT: getSection: Invalid section index
-INVALID-SECTION-IDX-GETSECT64: getSection64: Invalid section index
index 071091766381671cca6bdc5e0b98649927fb8079..3d09e1a45f39c3cea7ab947481e64278cd4bd41c 100644 (file)
@@ -30,7 +30,7 @@ ELF-i386: 00000000         *UND*  00000000 puts
 
 macho-i386: trivial-object-test.macho-i386:        file format Mach-O 32-bit i386
 macho-i386: SYMBOL TABLE:
-macho-i386: 00000000 g     F __TEXT,__text  00000024 _main
+macho-i386: 00000000 g     F __TEXT,__text  00000000 _main
 macho-i386: 00000000         *UND*  00000000 _SomeOtherFunction
 macho-i386: 00000000         *UND*  00000000 _puts
 
index 5b9a4f849763a428040e6d964e31c360d54fa697..3fe5aea6c37753f6d0ec657f598752aa95155dbe 100644 (file)
@@ -1,8 +1,8 @@
 RUN: llvm-objdump -macho -t %p/Inputs/hello.obj.macho-x86_64 | FileCheck %s
 
 CHECK: SYMBOL TABLE:
-CHECK: 000000000000003b l     F __TEXT,__cstring       0000000d L_.str
-CHECK: 0000000000000068 l     F __TEXT,__eh_frame      00000018 EH_frame0
-CHECK: 0000000000000000 g     F __TEXT,__text  0000003b _main
-CHECK: 0000000000000080 g     F __TEXT,__eh_frame      00000028 _main.eh
+CHECK: 000000000000003b l     F __TEXT,__cstring       00000000 L_.str
+CHECK: 0000000000000068 l     F __TEXT,__eh_frame      00000000 EH_frame0
+CHECK: 0000000000000000 g     F __TEXT,__text  00000000 _main
+CHECK: 0000000000000080 g     F __TEXT,__eh_frame      00000000 _main.eh
 CHECK: 0000000000000000         *UND*  00000000 _printf