[lld] r217497 - [PECOFF] Add support for bigobj

David Majnemer david.majnemer at gmail.com
Wed Sep 10 05:52:03 PDT 2014


Author: majnemer
Date: Wed Sep 10 07:52:03 2014
New Revision: 217497

URL: http://llvm.org/viewvc/llvm-project?rev=217497&view=rev
Log:
[PECOFF] Add support for bigobj

lld shouldn't directly use the COFF header nor should it use raw
coff_symbols.  Instead, query the header properties from the
COFFObjectFile and use COFFSymbolRef to abstractly reference COFF
symbols.

This is just enough to get lld compiling with the changes to
llvm::object.  Bigobj specific testing will come later.

Differential Revision: http://reviews.llvm.org/D5280

Modified:
    lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp

Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=217497&r1=217496&r2=217497&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp Wed Sep 10 07:52:03 2014
@@ -56,7 +56,7 @@ namespace {
 
 class FileCOFF : public File {
 private:
-  typedef std::vector<const coff_symbol *> SymbolVectorT;
+  typedef std::vector<llvm::object::COFFSymbolRef> SymbolVectorT;
   typedef std::map<const coff_section *, SymbolVectorT> SectionToSymbolsT;
   typedef std::map<const StringRef, Atom *> SymbolNameToAtomT;
   typedef std::map<const coff_section *, std::vector<COFFDefinedFileAtom *>>
@@ -98,7 +98,7 @@ public:
   mutable llvm::BumpPtrAllocator _alloc;
 
 private:
-  std::error_code readSymbolTable(std::vector<const coff_symbol *> &result);
+  std::error_code readSymbolTable(SymbolVectorT &result);
 
   void createAbsoluteAtoms(const SymbolVectorT &symbols,
                            std::vector<const AbsoluteAtom *> &result);
@@ -116,7 +116,7 @@ private:
 
   std::error_code
   AtomizeDefinedSymbolsInSection(const coff_section *section,
-                                 std::vector<const coff_symbol *> &symbols,
+                                 SymbolVectorT &symbols,
                                  std::vector<COFFDefinedFileAtom *> &atoms);
 
   std::error_code
@@ -161,13 +161,13 @@ private:
 
   // A map from symbol to its name. All symbols should be in this map except
   // unnamed ones.
-  std::map<const coff_symbol *, StringRef> _symbolName;
+  std::map<llvm::object::COFFSymbolRef, StringRef> _symbolName;
 
   // A map from symbol to its resultant atom.
-  std::map<const coff_symbol *, Atom *> _symbolAtom;
+  std::map<llvm::object::COFFSymbolRef, Atom *> _symbolAtom;
 
   // A map from symbol to its aux symbol.
-  std::map<const coff_symbol *, const coff_symbol *> _auxSymbol;
+  std::map<llvm::object::COFFSymbolRef, llvm::object::COFFSymbolRef> _auxSymbol;
 
   // A map from section to its atoms.
   std::map<const coff_section *, std::vector<COFFDefinedFileAtom *>>
@@ -208,8 +208,8 @@ private:
 };
 
 // Converts the COFF symbol attribute to the LLD's atom attribute.
-Atom::Scope getScope(const coff_symbol *symbol) {
-  switch (symbol->StorageClass) {
+Atom::Scope getScope(llvm::object::COFFSymbolRef symbol) {
+  switch (symbol.getStorageClass()) {
   case llvm::COFF::IMAGE_SYM_CLASS_EXTERNAL:
     return Atom::scopeGlobal;
   case llvm::COFF::IMAGE_SYM_CLASS_STATIC:
@@ -339,22 +339,18 @@ std::error_code FileCOFF::parse() {
 
 /// Iterate over the symbol table to retrieve all symbols.
 std::error_code
-FileCOFF::readSymbolTable(std::vector<const coff_symbol *> &result) {
-  const llvm::object::coff_file_header *header = nullptr;
-  if (std::error_code ec = _obj->getHeader(header))
-    return ec;
-
-  for (uint32_t i = 0, e = header->NumberOfSymbols; i != e; ++i) {
+FileCOFF::readSymbolTable(SymbolVectorT &result) {
+  for (uint32_t i = 0, e = _obj->getNumberOfSymbols(); i != e; ++i) {
     // Retrieve the symbol.
-    const coff_symbol *sym;
+    ErrorOr<llvm::object::COFFSymbolRef> sym = _obj->getSymbol(i);
     StringRef name;
-    if (std::error_code ec = _obj->getSymbol(i, sym))
+    if (std::error_code ec = sym.getError())
       return ec;
-    if (sym->SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)
+    if (sym->getSectionNumber() == llvm::COFF::IMAGE_SYM_DEBUG)
       goto next;
-    result.push_back(sym);
+    result.push_back(*sym);
 
-    if (std::error_code ec = _obj->getSymbolName(sym, name))
+    if (std::error_code ec = _obj->getSymbolName(*sym, name))
       return ec;
 
     // Existence of the symbol @feat.00 indicates that object file is compatible
@@ -365,21 +361,21 @@ FileCOFF::readSymbolTable(std::vector<co
     }
 
     // Cache the name.
-    _symbolName[sym] = name;
+    _symbolName[*sym] = name;
 
     // Symbol may be followed by auxiliary symbol table records. The aux
     // record can be in any format, but the size is always the same as the
     // regular symbol. The aux record supplies additional information for the
     // standard symbol. We do not interpret the aux record here, but just
     // store it to _auxSymbol.
-    if (sym->NumberOfAuxSymbols > 0) {
-      const coff_symbol *aux = nullptr;
-      if (std::error_code ec = _obj->getAuxSymbol(i + 1, aux))
+    if (sym->getNumberOfAuxSymbols() > 0) {
+      ErrorOr<llvm::object::COFFSymbolRef> aux = _obj->getSymbol(i + 1);
+      if (std::error_code ec = aux.getError())
         return ec;
-      _auxSymbol[sym] = aux;
+      _auxSymbol[*sym] = *aux;
     }
   next:
-    i += sym->NumberOfAuxSymbols;
+    i += sym->getNumberOfAuxSymbols();
   }
   return std::error_code();
 }
@@ -387,11 +383,11 @@ FileCOFF::readSymbolTable(std::vector<co
 /// Create atoms for the absolute symbols.
 void FileCOFF::createAbsoluteAtoms(const SymbolVectorT &symbols,
                                    std::vector<const AbsoluteAtom *> &result) {
-  for (const coff_symbol *sym : symbols) {
-    if (sym->SectionNumber != llvm::COFF::IMAGE_SYM_ABSOLUTE)
+  for (llvm::object::COFFSymbolRef sym : symbols) {
+    if (sym.getSectionNumber() != llvm::COFF::IMAGE_SYM_ABSOLUTE)
       continue;
-    auto *atom = new (_alloc)
-        COFFAbsoluteAtom(*this, _symbolName[sym], getScope(sym), sym->Value);
+    auto *atom = new (_alloc) COFFAbsoluteAtom(*this, _symbolName[sym],
+                                               getScope(sym), sym.getValue());
 
     result.push_back(atom);
     _symbolAtom[sym] = atom;
@@ -409,10 +405,11 @@ std::error_code
 FileCOFF::createUndefinedAtoms(const SymbolVectorT &symbols,
                                std::vector<const UndefinedAtom *> &result) {
   // Sort out undefined symbols from all symbols.
-  std::set<const coff_symbol *> undefines;
-  std::map<const coff_symbol *, const coff_symbol *> weakExternal;
-  for (const coff_symbol *sym : symbols) {
-    if (sym->SectionNumber != llvm::COFF::IMAGE_SYM_UNDEFINED)
+  std::set<llvm::object::COFFSymbolRef> undefines;
+  std::map<llvm::object::COFFSymbolRef, llvm::object::COFFSymbolRef>
+      weakExternal;
+  for (llvm::object::COFFSymbolRef sym : symbols) {
+    if (sym.getSectionNumber() != llvm::COFF::IMAGE_SYM_UNDEFINED)
       continue;
     undefines.insert(sym);
 
@@ -422,11 +419,12 @@ FileCOFF::createUndefinedAtoms(const Sym
     if (iter == _auxSymbol.end())
       continue;
     const coff_aux_weak_external *aux =
-        reinterpret_cast<const coff_aux_weak_external *>(iter->second);
-    const coff_symbol *sym2;
-    if (std::error_code ec = _obj->getSymbol(aux->TagIndex, sym2))
+        reinterpret_cast<const coff_aux_weak_external *>(
+            iter->second.getRawPtr());
+    ErrorOr<llvm::object::COFFSymbolRef> sym2 = _obj->getSymbol(aux->TagIndex);
+    if (std::error_code ec = sym2.getError())
       return ec;
-    weakExternal[sym] = sym2;
+    weakExternal[sym] = *sym2;
   }
 
   // Sort out sym1s from sym2s. Sym2s shouldn't be added to the undefined atom
@@ -436,13 +434,13 @@ FileCOFF::createUndefinedAtoms(const Sym
     undefines.erase(i.second);
 
   // Create atoms for the undefined symbols.
-  for (const coff_symbol *sym : undefines) {
+  for (llvm::object::COFFSymbolRef sym : undefines) {
     // If the symbol has sym2, create an undefiend atom for sym2, so that we
     // can pass it as a fallback atom.
     UndefinedAtom *fallback = nullptr;
     auto iter = weakExternal.find(sym);
     if (iter != weakExternal.end()) {
-      const coff_symbol *sym2 = iter->second;
+      llvm::object::COFFSymbolRef sym2 = iter->second;
       fallback = new (_alloc) COFFUndefinedAtom(*this, _symbolName[sym2]);
       _symbolAtom[sym2] = fallback;
     }
@@ -471,7 +469,7 @@ FileCOFF::createDefinedSymbols(const Sym
 
   // Filter non-defined atoms, and group defined atoms by its section.
   SectionToSymbolsT definedSymbols;
-  for (const coff_symbol *sym : symbols) {
+  for (llvm::object::COFFSymbolRef sym : symbols) {
     // A symbol with section number 0 and non-zero value represents a common
     // symbol. The MS COFF spec did not give a definition of what the common
     // symbol is. We should probably follow ELF's definition shown below.
@@ -487,10 +485,10 @@ FileCOFF::createDefinedSymbols(const Sym
     //
     // FIXME: We are currently treating the common symbol as a normal
     // mergeable atom. Implement the above semantcis.
-    if (sym->SectionNumber == llvm::COFF::IMAGE_SYM_UNDEFINED &&
-        sym->Value > 0) {
+    if (sym.getSectionNumber() == llvm::COFF::IMAGE_SYM_UNDEFINED &&
+        sym.getValue() > 0) {
       StringRef name = _symbolName[sym];
-      uint32_t size = sym->Value;
+      uint32_t size = sym.getValue();
       auto *atom = new (_alloc)
           COFFBSSAtom(*this, name, getScope(sym), DefinedAtom::permRW_,
                       DefinedAtom::mergeAsWeakAndAddressUsed, size, _ordinal++);
@@ -506,13 +504,13 @@ FileCOFF::createDefinedSymbols(const Sym
     }
 
     // Skip if it's not for defined atom.
-    if (sym->SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG ||
-        sym->SectionNumber == llvm::COFF::IMAGE_SYM_ABSOLUTE ||
-        sym->SectionNumber == llvm::COFF::IMAGE_SYM_UNDEFINED)
+    if (sym.getSectionNumber() == llvm::COFF::IMAGE_SYM_DEBUG ||
+        sym.getSectionNumber() == llvm::COFF::IMAGE_SYM_ABSOLUTE ||
+        sym.getSectionNumber() == llvm::COFF::IMAGE_SYM_UNDEFINED)
       continue;
 
     const coff_section *sec;
-    if (std::error_code ec = _obj->getSection(sym->SectionNumber, sec))
+    if (std::error_code ec = _obj->getSection(sym.getSectionNumber(), sec))
       return ec;
     assert(sec && "SectionIndex > 0, Sec must be non-null!");
 
@@ -523,11 +521,11 @@ FileCOFF::createDefinedSymbols(const Sym
     StringRef sectionName;
     if (std::error_code ec = _obj->getSectionName(sec, sectionName))
       return ec;
-    if (_symbolName[sym] == sectionName && sym->Value == 0 &&
+    if (_symbolName[sym] == sectionName && sym.getValue() == 0 &&
         _merge[sec] != DefinedAtom::mergeNo)
       continue;
 
-    uint8_t sc = sym->StorageClass;
+    uint8_t sc = sym.getStorageClass();
     if (sc != llvm::COFF::IMAGE_SYM_CLASS_EXTERNAL &&
         sc != llvm::COFF::IMAGE_SYM_CLASS_STATIC &&
         sc != llvm::COFF::IMAGE_SYM_CLASS_FUNCTION &&
@@ -556,16 +554,17 @@ std::error_code FileCOFF::cacheSectionAt
   // how COFF works.
   for (auto i : _auxSymbol) {
     // Read a section from the file
-    const coff_symbol *sym = i.first;
-    if (sym->SectionNumber == llvm::COFF::IMAGE_SYM_ABSOLUTE ||
-        sym->SectionNumber == llvm::COFF::IMAGE_SYM_UNDEFINED)
+    llvm::object::COFFSymbolRef sym = i.first;
+    if (sym.getSectionNumber() == llvm::COFF::IMAGE_SYM_ABSOLUTE ||
+        sym.getSectionNumber() == llvm::COFF::IMAGE_SYM_UNDEFINED)
       continue;
 
     const coff_section *sec;
-    if (std::error_code ec = _obj->getSection(sym->SectionNumber, sec))
+    if (std::error_code ec = _obj->getSection(sym.getSectionNumber(), sec))
       return ec;
     const coff_aux_section_definition *aux =
-        reinterpret_cast<const coff_aux_section_definition *>(i.second);
+        reinterpret_cast<const coff_aux_section_definition *>(
+            i.second.getRawPtr());
 
     if (sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_COMDAT) {
       // Read aux symbol data.
@@ -595,7 +594,7 @@ std::error_code FileCOFF::cacheSectionAt
 /// Atomize \p symbols and append the results to \p atoms. The symbols are
 /// assumed to have been defined in the \p section.
 std::error_code FileCOFF::AtomizeDefinedSymbolsInSection(
-    const coff_section *section, std::vector<const coff_symbol *> &symbols,
+    const coff_section *section, SymbolVectorT &symbols,
     std::vector<COFFDefinedFileAtom *> &atoms) {
   // Sort symbols by position.
   std::stable_sort(
@@ -603,9 +602,10 @@ std::error_code FileCOFF::AtomizeDefined
       // For some reason MSVC fails to allow the lambda in this context with a
       // "illegal use of local type in type instantiation". MSVC is clearly
       // wrong here. Force a conversion to function pointer to work around.
-      static_cast<bool (*)(const coff_symbol *, const coff_symbol *)>(
-          [](const coff_symbol *a, const coff_symbol *b)
-              -> bool { return a->Value < b->Value; }));
+      static_cast<bool (*)(llvm::object::COFFSymbolRef,
+                           llvm::object::COFFSymbolRef)>(
+          [](llvm::object::COFFSymbolRef a, llvm::object::COFFSymbolRef b)
+              -> bool { return a.getValue() < b.getValue(); }));
 
   StringRef sectionName;
   if (std::error_code ec = _obj->getSectionName(section, sectionName))
@@ -615,9 +615,9 @@ std::error_code FileCOFF::AtomizeDefined
   // COFFBSSAtom instead of COFFDefinedAtom.
   if (section->Characteristics & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
     for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
-      const coff_symbol *sym = *si;
-      uint32_t size = (si + 1 == se) ? section->SizeOfRawData - sym->Value
-                                     : si[1]->Value - sym->Value;
+      llvm::object::COFFSymbolRef sym = *si;
+      uint32_t size = (si + 1 == se) ? section->SizeOfRawData - sym.getValue()
+                                     : si[1].getValue() - sym.getValue();
       auto *atom = new (_alloc) COFFBSSAtom(
           *this, _symbolName[sym], getScope(sym), getPermissions(section),
           DefinedAtom::mergeAsWeakAndAddressUsed, size, _ordinal++);
@@ -663,8 +663,8 @@ std::error_code FileCOFF::AtomizeDefined
 
   // Create an unnamed atom if the first atom isn't at the start of the
   // section.
-  if (symbols[0]->Value != 0) {
-    uint64_t size = symbols[0]->Value;
+  if (symbols[0].getValue() != 0) {
+    uint64_t size = symbols[0].getValue();
     ArrayRef<uint8_t> data(secData.data(), size);
     auto *atom = new (_alloc) COFFDefinedAtom(
         *this, "", sectionName, Atom::scopeTranslationUnit, type, isComdat,
@@ -674,17 +674,17 @@ std::error_code FileCOFF::AtomizeDefined
   }
 
   for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
-    const uint8_t *start = secData.data() + (*si)->Value;
+    const uint8_t *start = secData.data() + si->getValue();
     // if this is the last symbol, take up the remaining data.
     const uint8_t *end = (si + 1 == se) ? secData.data() + secData.size()
-                                        : secData.data() + (*(si + 1))->Value;
+                                        : secData.data() + (si + 1)->getValue();
     ArrayRef<uint8_t> data(start, end);
     auto *atom = new (_alloc) COFFDefinedAtom(
         *this, _symbolName[*si], sectionName, getScope(*si), type, isComdat,
         perms, _merge[section], data, _ordinal++);
     atoms.push_back(atom);
     _symbolAtom[*si] = atom;
-    _definedAtomLocations[section][(*si)->Value].push_back(atom);
+    _definedAtomLocations[section][si->getValue()].push_back(atom);
   }
   return std::error_code();
 }
@@ -696,7 +696,7 @@ std::error_code FileCOFF::AtomizeDefined
   // section, and append the atoms to the result objects.
   for (auto &i : definedSymbols) {
     const coff_section *section = i.first;
-    std::vector<const coff_symbol *> &symbols = i.second;
+    SymbolVectorT &symbols = i.second;
     std::vector<COFFDefinedFileAtom *> atoms;
     if (std::error_code ec =
             AtomizeDefinedSymbolsInSection(section, symbols, atoms))
@@ -764,10 +764,10 @@ std::error_code FileCOFF::findAtomAt(con
 /// Find the atom for the symbol that was at the \p index in the symbol
 /// table.
 std::error_code FileCOFF::getAtomBySymbolIndex(uint32_t index, Atom *&ret) {
-  const coff_symbol *symbol;
-  if (std::error_code ec = _obj->getSymbol(index, symbol))
+  ErrorOr<llvm::object::COFFSymbolRef> symbol = _obj->getSymbol(index);
+  if (std::error_code ec = symbol.getError())
     return ec;
-  ret = _symbolAtom[symbol];
+  ret = _symbolAtom[*symbol];
   assert(ret);
   return std::error_code();
 }
@@ -813,10 +813,7 @@ std::error_code FileCOFF::getSectionCont
 
 /// Returns the target machine type of the current object file.
 std::error_code FileCOFF::getReferenceArch(Reference::KindArch &result) {
-  const llvm::object::coff_file_header *header = nullptr;
-  if (std::error_code ec = _obj->getHeader(header))
-    return ec;
-  switch (header->Machine) {
+  switch (_obj->getMachine()) {
   case llvm::COFF::IMAGE_FILE_MACHINE_I386:
     result = Reference::KindArch::x86;
     return std::error_code();
@@ -827,15 +824,12 @@ std::error_code FileCOFF::getReferenceAr
     result = Reference::KindArch::all;
     return std::error_code();
   }
-  llvm::errs() << "Unsupported machine type: " << header->Machine << "\n";
+  llvm::errs() << "Unsupported machine type: " << _obj->getMachine() << '\n';
   return llvm::object::object_error::parse_failed;
 }
 
 std::error_code FileCOFF::is64(bool &result) {
-  const llvm::object::coff_file_header *header = nullptr;
-  if (std::error_code ec = _obj->getHeader(header))
-    return ec;
-  result = (header->Machine == llvm::COFF::IMAGE_FILE_MACHINE_AMD64);
+  result = (_obj->getMachine() == llvm::COFF::IMAGE_FILE_MACHINE_AMD64);
   return std::error_code();
 }
 





More information about the llvm-commits mailing list