[llvm] r312756 - [llvm-objcopy] Add support for special section indexes in symbol table greater than SHN_LORESERVE

Petr Hosek via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 7 16:02:50 PDT 2017


Author: phosek
Date: Thu Sep  7 16:02:50 2017
New Revision: 312756

URL: http://llvm.org/viewvc/llvm-project?rev=312756&view=rev
Log:
[llvm-objcopy] Add support for special section indexes in symbol table greater than SHN_LORESERVE

As is indexes above SHN_LORESERVE will not be handled correctly because
they'll be treated as indexes of sections rather than special values
that should just be copied. This change adds support to copy them
though.

Patch by Jake Ehrlich

Differential Revision: https://reviews.llvm.org/D37393

Added:
    llvm/trunk/test/tools/llvm-objcopy/abs-symbol.test
    llvm/trunk/test/tools/llvm-objcopy/common-symbol.test
    llvm/trunk/test/tools/llvm-objcopy/section-index-unsupported.test
Modified:
    llvm/trunk/tools/llvm-objcopy/Object.cpp
    llvm/trunk/tools/llvm-objcopy/Object.h

Added: llvm/trunk/test/tools/llvm-objcopy/abs-symbol.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/abs-symbol.test?rev=312756&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/abs-symbol.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/abs-symbol.test Thu Sep  7 16:02:50 2017
@@ -0,0 +1,36 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy %t %t2
+# RUN: llvm-readobj -symbols %t2 | FileCheck %s
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+Symbols:
+  Global:
+    - Name:     test
+      Index:    SHN_ABS
+      Value:    0x1234
+
+#CHECK:     Symbols [
+#CHECK-NEXT:   Symbol {
+#CHECK-NEXT:    Name:
+#CHECK-NEXT:    Value: 0x0
+#CHECK-NEXT:    Size: 0
+#CHECK-NEXT:    Binding: Local (0x0)
+#CHECK-NEXT:    Type: None (0x0)
+#CHECK-NEXT:    Other: 0
+#CHECK-NEXT:    Section: Undefined (0x0)
+#CHECK-NEXT:  }
+#CHECK-NEXT:  Symbol {
+#CHECK-NEXT:    Name: test
+#CHECK-NEXT:    Value: 0x1234
+#CHECK-NEXT:    Size: 0
+#CHECK-NEXT:    Binding: Global (0x1)
+#CHECK-NEXT:    Type: None (0x0)
+#CHECK-NEXT:    Other: 0
+#CHECK-NEXT:    Section: Absolute (0xFFF1)
+#CHECK-NEXT:  }
+#CHECK-NEXT:]

Added: llvm/trunk/test/tools/llvm-objcopy/common-symbol.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/common-symbol.test?rev=312756&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/common-symbol.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/common-symbol.test Thu Sep  7 16:02:50 2017
@@ -0,0 +1,84 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy %t %t2
+# RUN: llvm-readobj -symbols %t2 | FileCheck %s
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+Symbols:
+  Global:
+    - Name:     test
+      Index:    SHN_COMMON
+      Value:    0x1234
+    - Name:     test2
+      Index:    SHN_HEXAGON_SCOMMON
+      Value:    0x1235
+    - Name:     test3
+      Index:    SHN_HEXAGON_SCOMMON_2
+      Value:    0x1236
+    - Name:     test4
+      Index:    SHN_HEXAGON_SCOMMON_4
+      Value:    0x1237
+    - Name:     test5
+      Index:    SHN_HEXAGON_SCOMMON_8
+      Value:    0x1238
+
+#CHECK:     Symbols [
+#CHECK-NEXT:   Symbol {
+#CHECK-NEXT:    Name:
+#CHECK-NEXT:    Value: 0x0
+#CHECK-NEXT:    Size: 0
+#CHECK-NEXT:    Binding: Local (0x0)
+#CHECK-NEXT:    Type: None (0x0)
+#CHECK-NEXT:    Other: 0
+#CHECK-NEXT:    Section: Undefined (0x0)
+#CHECK-NEXT:  }
+#CHECK-NEXT:  Symbol {
+#CHECK-NEXT:    Name: test
+#CHECK-NEXT:    Value: 0x1234
+#CHECK-NEXT:    Size: 0
+#CHECK-NEXT:    Binding: Global (0x1)
+#CHECK-NEXT:    Type: None (0x0)
+#CHECK-NEXT:    Other: 0
+#CHECK-NEXT:    Section: Common (0xFFF2)
+#CHECK-NEXT:  }
+#CHECK-NEXT:  Symbol {
+#CHECK-NEXT:    Name: test2
+#CHECK-NEXT:    Value: 0x1235
+#CHECK-NEXT:    Size: 0
+#CHECK-NEXT:    Binding: Global (0x1)
+#CHECK-NEXT:    Type: None (0x0)
+#CHECK-NEXT:    Other: 0
+#CHECK-NEXT:    Section: Processor Specific (0xFF00)
+#CHECK-NEXT:  }
+#CHECK-NEXT:  Symbol {
+#CHECK-NEXT:    Name: test3
+#CHECK-NEXT:    Value: 0x1236
+#CHECK-NEXT:    Size: 0
+#CHECK-NEXT:    Binding: Global (0x1)
+#CHECK-NEXT:    Type: None (0x0)
+#CHECK-NEXT:    Other: 0
+#CHECK-NEXT:    Section: Processor Specific (0xFF02)
+#CHECK-NEXT:  }
+#CHECK-NEXT:  Symbol {
+#CHECK-NEXT:    Name: test4
+#CHECK-NEXT:    Value: 0x1237
+#CHECK-NEXT:    Size: 0
+#CHECK-NEXT:    Binding: Global (0x1)
+#CHECK-NEXT:    Type: None (0x0)
+#CHECK-NEXT:    Other: 0
+#CHECK-NEXT:    Section: Processor Specific (0xFF03)
+#CHECK-NEXT:  }
+#CHECK-NEXT:  Symbol {
+#CHECK-NEXT:    Name: test5
+#CHECK-NEXT:    Value: 0x1238
+#CHECK-NEXT:    Size: 0
+#CHECK-NEXT:    Binding: Global (0x1)
+#CHECK-NEXT:    Type: None (0x0)
+#CHECK-NEXT:    Other: 0
+#CHECK-NEXT:    Section: Processor Specific (0xFF04)
+#CHECK-NEXT:  }
+#CHECK-NEXT:]

Added: llvm/trunk/test/tools/llvm-objcopy/section-index-unsupported.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/section-index-unsupported.test?rev=312756&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/section-index-unsupported.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/section-index-unsupported.test Thu Sep  7 16:02:50 2017
@@ -0,0 +1,15 @@
+# RUN: yaml2obj %s > %t
+# RUN: not llvm-objcopy %t %t2 2>&1 >/dev/null | FileCheck %s
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+Symbols:
+  Global:
+    - Name:     test
+      Index:    0xff05
+
+# CHECK: [[_:.*]] Symbol 'test' has unsupported value greater than or equal to SHN_LORESERVE: 65285

Modified: llvm/trunk/tools/llvm-objcopy/Object.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.cpp?rev=312756&r1=312755&r2=312756&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Object.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/Object.cpp Thu Sep  7 16:02:50 2017
@@ -90,14 +90,54 @@ void StringTableSection::writeSection(Fi
   StrTabBuilder.write(Out.getBufferStart() + Offset);
 }
 
+static bool isValidReservedSectionIndex(uint16_t Index) {
+  switch (Index) {
+  case SHN_ABS:
+  case SHN_COMMON:
+  case SHN_HEXAGON_SCOMMON:
+  case SHN_HEXAGON_SCOMMON_2:
+  case SHN_HEXAGON_SCOMMON_4:
+  case SHN_HEXAGON_SCOMMON_8:
+    return true;
+  default:
+    return false;
+  }
+}
+
+uint16_t Symbol::getShndx() const {
+  if (DefinedIn != nullptr) {
+    return DefinedIn->Index;
+  }
+  switch (ShndxType) {
+  // This means that we don't have a defined section but we do need to
+  // output a legitimate section index.
+  case SYMBOL_SIMPLE_INDEX:
+    return SHN_UNDEF;
+  case SYMBOL_ABS:
+  case SYMBOL_COMMON:
+  case SYMBOL_HEXAGON_SCOMMON:
+  case SYMBOL_HEXAGON_SCOMMON_2:
+  case SYMBOL_HEXAGON_SCOMMON_4:
+  case SYMBOL_HEXAGON_SCOMMON_8:
+    return static_cast<uint16_t>(ShndxType);
+  }
+  llvm_unreachable("Symbol with invalid ShndxType encountered");
+}
+
 void SymbolTableSection::addSymbol(StringRef Name, uint8_t Bind, uint8_t Type,
                                    SectionBase *DefinedIn, uint64_t Value,
-                                   uint64_t Sz) {
+                                   uint16_t Shndx, uint64_t Sz) {
   Symbol Sym;
   Sym.Name = Name;
   Sym.Binding = Bind;
   Sym.Type = Type;
   Sym.DefinedIn = DefinedIn;
+  if (DefinedIn == nullptr) {
+    if (isValidReservedSectionIndex(Shndx))
+      Sym.ShndxType = static_cast<SymbolShndxType>(Shndx);
+    else
+      Sym.ShndxType = SYMBOL_SIMPLE_INDEX;
+  }
   Sym.Value = Value;
   Sym.Size = Sz;
   Sym.Index = Symbols.size();
@@ -146,10 +186,7 @@ void SymbolTableSectionImpl<ELFT>::write
     Sym->st_size = Symbol->Size;
     Sym->setBinding(Symbol->Binding);
     Sym->setType(Symbol->Type);
-    if (Symbol->DefinedIn)
-      Sym->st_shndx = Symbol->DefinedIn->Index;
-    else
-      Sym->st_shndx = SHN_UNDEF;
+    Sym->st_shndx = Symbol->getShndx();
     ++Sym;
   }
 }
@@ -251,7 +288,14 @@ void Object<ELFT>::initSymbolTable(const
   for (const auto &Sym : unwrapOrError(ElfFile.symbols(&Shdr))) {
     SectionBase *DefSection = nullptr;
     StringRef Name = unwrapOrError(Sym.getName(StrTabData));
-    if (Sym.st_shndx != SHN_UNDEF) {
+    if (Sym.st_shndx >= SHN_LORESERVE) {
+      if (!isValidReservedSectionIndex(Sym.st_shndx)) {
+        error(
+            "Symbol '" + Name +
+            "' has unsupported value greater than or equal to SHN_LORESERVE: " +
+            Twine(Sym.st_shndx));
+      }
+    } else if (Sym.st_shndx != SHN_UNDEF) {
       if (Sym.st_shndx >= Sections.size())
         error("Symbol '" + Name +
               "' is defined in invalid section with index " +
@@ -259,7 +303,7 @@ void Object<ELFT>::initSymbolTable(const
       DefSection = Sections[Sym.st_shndx - 1].get();
     }
     SymTab->addSymbol(Name, Sym.getBinding(), Sym.getType(), DefSection,
-                      Sym.getValue(), Sym.st_size);
+                      Sym.getValue(), Sym.st_shndx, Sym.st_size);
   }
 }
 

Modified: llvm/trunk/tools/llvm-objcopy/Object.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.h?rev=312756&r1=312755&r2=312756&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Object.h (original)
+++ llvm/trunk/tools/llvm-objcopy/Object.h Thu Sep  7 16:02:50 2017
@@ -113,15 +113,32 @@ public:
   }
 };
 
+// Symbols have a st_shndx field that normally stores an index but occasionally
+// stores a different special value. This enum keeps track of what the st_shndx
+// field means. Most of the values are just copies of the special SHN_* values.
+// SYMBOL_SIMPLE_INDEX means that the st_shndx is just an index of a section.
+enum SymbolShndxType {
+  SYMBOL_SIMPLE_INDEX = 0,
+  SYMBOL_ABS = llvm::ELF::SHN_ABS,
+  SYMBOL_COMMON = llvm::ELF::SHN_COMMON,
+  SYMBOL_HEXAGON_SCOMMON = llvm::ELF::SHN_HEXAGON_SCOMMON,
+  SYMBOL_HEXAGON_SCOMMON_2 = llvm::ELF::SHN_HEXAGON_SCOMMON_2,
+  SYMBOL_HEXAGON_SCOMMON_4 = llvm::ELF::SHN_HEXAGON_SCOMMON_4,
+  SYMBOL_HEXAGON_SCOMMON_8 = llvm::ELF::SHN_HEXAGON_SCOMMON_8,
+};
+
 struct Symbol {
   uint8_t Binding;
   SectionBase *DefinedIn;
+  SymbolShndxType ShndxType;
   uint32_t Index;
   llvm::StringRef Name;
   uint32_t NameIndex;
   uint64_t Size;
   uint8_t Type;
   uint64_t Value;
+
+  uint16_t getShndx() const;
 };
 
 class SymbolTableSection : public SectionBase {
@@ -132,7 +149,8 @@ protected:
 public:
   void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; }
   void addSymbol(llvm::StringRef Name, uint8_t Bind, uint8_t Type,
-                 SectionBase *DefinedIn, uint64_t Value, uint64_t Sz);
+                 SectionBase *DefinedIn, uint64_t Value, uint16_t Shndx,
+                 uint64_t Sz);
   void addSymbolNames();
   const Symbol *getSymbolByIndex(uint32_t Index) const;
   void finalize() override;




More information about the llvm-commits mailing list