[lld] r185195 - [PECOFF][Writer] Define COFFBaseDefinedAtom as the base class of COFF defined atoms.

Rui Ueyama ruiu at google.com
Fri Jun 28 12:08:57 PDT 2013


Author: ruiu
Date: Fri Jun 28 14:08:57 2013
New Revision: 185195

URL: http://llvm.org/viewvc/llvm-project?rev=185195&view=rev
Log:
[PECOFF][Writer] Define COFFBaseDefinedAtom as the base class of COFF defined atoms.

In order to support linking against DLL, the linker needs to create defined
atoms for jump tables and etc. Because such atoms are not read from a file,
they lack some information such as an ordinal. With this patch, COFFDefinedAtom
is split into two classes; one is the base class of all COFF defined atoms, and
another is a concrete class for atoms read from file. More classes inheriting
COFFBaseDefinedAtom will be added for jump tables and etc.

Modified:
    lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h

Modified: lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h?rev=185195&r1=185194&r2=185195&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h Fri Jun 28 14:08:57 2013
@@ -95,26 +95,99 @@ private:
   StringRef _name;
 };
 
-class COFFDefinedAtom : public DefinedAtom {
+/// The base class of all COFF defined atoms. A derived class of
+/// COFFBaseDefinedAtom may represent atoms read from a file or atoms created
+/// by the linker. An example of the latter case is the jump table for symbols
+/// in a DLL.
+class COFFBaseDefinedAtom : public DefinedAtom {
 public:
-  COFFDefinedAtom(const File &f, StringRef n, const coff_symbol *symb,
-                  const coff_section *sec, ArrayRef<uint8_t> d,
-                  StringRef sectionName, uint64_t ordinal)
-      : _owningFile(f), _name(n), _symbol(symb), _section(sec), _data(d),
-        _sectionName(sectionName), _ordinal(ordinal) {}
-
-  virtual const File &file() const { return _owningFile; }
+  enum class Kind {
+    File, Internal
+  };
 
+  virtual const File &file() const { return _file; }
   virtual StringRef name() const { return _name; }
+  virtual uint64_t size() const { return _dataref.size(); }
+  virtual Interposable interposable() const { return interposeNo; }
+  virtual Merge merge() const { return mergeNo; }
+  virtual Alignment alignment() const { return Alignment(1); }
+  virtual SectionChoice sectionChoice() const { return sectionBasedOnContent; }
+  virtual StringRef customSectionName() const { return ""; }
+  virtual SectionPosition sectionPosition() const { return sectionPositionAny; }
+  virtual DeadStripKind deadStrip() const { return deadStripNormal; }
+  virtual bool isAlias() const { return false; }
+  virtual ArrayRef<uint8_t> rawContent() const { return _dataref; }
 
-  virtual uint64_t ordinal() const { return _ordinal; }
+  Kind getKind() const { return _kind; }
+  void setKind(Kind kind) { _kind = kind; }
+
+  void addReference(std::unique_ptr<COFFReference> reference) {
+    _references.push_back(std::move(reference));
+  }
+
+  virtual reference_iterator begin() const {
+    return reference_iterator(*this, reinterpret_cast<const void *>(0));
+  }
+
+  virtual reference_iterator end() const {
+    return reference_iterator(
+        *this, reinterpret_cast<const void *>(_references.size()));
+  }
+
+protected:
+  COFFBaseDefinedAtom(const File &file, StringRef name)
+      : _file(file), _name(name), _kind(Kind::Internal) {}
+
+  COFFBaseDefinedAtom(const File &file, StringRef name, ArrayRef<uint8_t> data)
+      : _file(file), _name(name), _dataref(data), _kind(Kind::Internal) {}
+
+  COFFBaseDefinedAtom(const File &file, StringRef name,
+                      std::vector<uint8_t> *data)
+      : _file(file), _name(name), _dataref(*data),
+        _data(std::unique_ptr<std::vector<uint8_t>>(data)),
+        _kind(Kind::Internal) {}
+
+  void setRawContent(std::vector<uint8_t> *data) {
+    _dataref = *data;
+    _data = std::unique_ptr<std::vector<uint8_t>>(data);
+  }
 
-  virtual uint64_t size() const { return _data.size(); }
+private:
+  virtual const Reference *derefIterator(const void *iter) const {
+    size_t index = reinterpret_cast<size_t>(iter);
+    return _references[index].get();
+  }
 
+  virtual void incrementIterator(const void *&iter) const {
+    size_t index = reinterpret_cast<size_t>(iter);
+    iter = reinterpret_cast<const void *>(index + 1);
+  }
+
+  const File &_file;
+  StringRef _name;
+  ArrayRef<uint8_t> _dataref;
+  std::unique_ptr<std::vector<uint8_t>> _data;
+  Kind _kind;
+  std::vector<std::unique_ptr<COFFReference>> _references;
+};
+
+/// A COFFDefinedAtom represents an atom read from a file.
+class COFFDefinedAtom : public COFFBaseDefinedAtom {
+public:
+  COFFDefinedAtom(const File &file, StringRef name, const coff_symbol *symbol,
+                  const coff_section *section, ArrayRef<uint8_t> data,
+                  StringRef sectionName, uint64_t ordinal)
+      : COFFBaseDefinedAtom(file, name, data), _symbol(symbol),
+        _section(section), _sectionName(sectionName), _ordinal(ordinal) {
+    setKind(Kind::File);
+  }
+
+  virtual uint64_t ordinal() const { return _ordinal; }
   uint64_t originalOffset() const { return _symbol->Value; }
+  virtual StringRef getSectionName() const { return _sectionName; }
 
-  void addReference(std::unique_ptr<COFFReference> reference) {
-    _references.push_back(std::move(reference));
+  static bool classof(const COFFBaseDefinedAtom *atom) {
+    return atom->getKind() == Kind::File;
   }
 
   virtual Scope scope() const {
@@ -129,10 +202,6 @@ public:
     llvm_unreachable("Unknown scope!");
   }
 
-  virtual Interposable interposable() const { return interposeNo; }
-
-  virtual Merge merge() const { return mergeNo; }
-
   virtual ContentType contentType() const {
     if (_section->Characteristics & llvm::COFF::IMAGE_SCN_CNT_CODE)
       return typeCode;
@@ -144,16 +213,6 @@ public:
     return typeUnknown;
   }
 
-  virtual Alignment alignment() const { return Alignment(1); }
-
-  virtual SectionChoice sectionChoice() const { return sectionBasedOnContent; }
-
-  virtual StringRef customSectionName() const { return ""; }
-
-  virtual SectionPosition sectionPosition() const { return sectionPositionAny; }
-
-  virtual DeadStripKind deadStrip() const { return deadStripNormal; }
-
   virtual ContentPermissions permissions() const {
     if (_section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_READ &&
         _section->Characteristics & llvm::COFF::IMAGE_SCN_MEM_WRITE)
@@ -166,42 +225,40 @@ public:
     return perm___;
   }
 
-  virtual bool isAlias() const { return false; }
-
-  virtual StringRef getSectionName() const { return _sectionName; }
-
-  virtual ArrayRef<uint8_t> rawContent() const { return _data; }
-
-  virtual reference_iterator begin() const {
-    return reference_iterator(*this, reinterpret_cast<const void *>(0));
-  }
-
-  virtual reference_iterator end() const {
-    return reference_iterator(
-        *this, reinterpret_cast<const void *>(_references.size()));
-  }
-
 private:
-  virtual const Reference *derefIterator(const void *iter) const {
-    size_t index = reinterpret_cast<size_t>(iter);
-    return _references[index].get();
-  }
-
-  virtual void incrementIterator(const void *&iter) const {
-    size_t index = reinterpret_cast<size_t>(iter);
-    iter = reinterpret_cast<const void *>(index + 1);
-  }
-
-  const File &_owningFile;
-  StringRef _name;
   const coff_symbol *_symbol;
   const coff_section *_section;
-  std::vector<std::unique_ptr<COFFReference> > _references;
-  ArrayRef<uint8_t> _data;
   StringRef _sectionName;
+  std::vector<std::unique_ptr<COFFReference>> _references;
   uint64_t _ordinal;
 };
 
+class COFFSharedLibraryAtom : public SharedLibraryAtom {
+public:
+  enum class Kind {
+    DATA, FUNC
+  };
+
+  virtual const File &file() const { return _file; }
+  virtual StringRef name() const { return _symbolName; }
+  virtual StringRef loadName() const { return _loadName; }
+  virtual bool canBeNullAtRuntime() const { return false; }
+
+  Kind getKind() const { return _kind; }
+
+protected:
+  COFFSharedLibraryAtom(const File &file, StringRef symbolName,
+                        StringRef loadName, Kind kind)
+      : _file(file), _symbolName(symbolName), _loadName(loadName), _kind(kind) {
+  }
+
+private:
+  const File &_file;
+  StringRef _symbolName;
+  StringRef _loadName;
+  Kind _kind;
+};
+
 //===----------------------------------------------------------------------===//
 //
 // Utility functions to handle layout edges.





More information about the llvm-commits mailing list