[lld] r188052 - [PECOFF] Create __ImageBase symbol.

Rui Ueyama ruiu at google.com
Thu Aug 8 21:44:15 PDT 2013


Author: ruiu
Date: Thu Aug  8 23:44:15 2013
New Revision: 188052

URL: http://llvm.org/viewvc/llvm-project?rev=188052&view=rev
Log:
[PECOFF] Create __ImageBase symbol.

__ImageBase is a symbol having 4 byte integer equal to the image base address
of the resultant executable. The linker is expected to create the symbol as if
it were read from a file.

In order to emit the symbol contents only when the symbol is actually
referenced, we created a pseudo library file to wrap the linker generated
symbol. The library file member is emitted to the output only when the member
is actually referenced, which is suitable for our purpose.

Added:
    lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
    lld/trunk/test/pecoff/Inputs/imagebase.obj.yaml
    lld/trunk/test/pecoff/imagebase.test
Modified:
    lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp

Added: lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h?rev=188052&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h (added)
+++ lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h Thu Aug  8 23:44:15 2013
@@ -0,0 +1,128 @@
+//===- lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.cpp --------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Atoms.h"
+#include "GroupedSectionsPass.h"
+#include "IdataPass.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Path.h"
+#include "lld/Core/ArchiveLibraryFile.h"
+#include "lld/Core/InputFiles.h"
+#include "lld/Core/PassManager.h"
+#include "lld/Passes/LayoutPass.h"
+#include "lld/ReaderWriter/PECOFFLinkingContext.h"
+#include "lld/ReaderWriter/Reader.h"
+#include "lld/ReaderWriter/Simple.h"
+#include "lld/ReaderWriter/Writer.h"
+
+namespace lld {
+namespace coff {
+
+namespace {
+
+// The symbol ___ImageBase is a linker generated symbol. No standard library
+// files define it, but the linker is expected to prepare it as if it was read
+// from a file. The content of the atom is a 4-byte integer equal to the image
+// base address.
+class ImageBaseAtom : public COFFLinkerInternalAtom {
+public:
+  ImageBaseAtom(const File &file, uint32_t imageBase)
+      : COFFLinkerInternalAtom(file, assembleRawContent(imageBase)) {}
+
+  virtual StringRef name() const { return "___ImageBase"; }
+  virtual uint64_t ordinal() const { return 0; }
+  virtual ContentType contentType() const { return typeData; }
+  virtual ContentPermissions permissions() const { return permRW_; }
+  virtual DeadStripKind deadStrip() const { return deadStripAlways; }
+
+private:
+  std::vector<uint8_t> assembleRawContent(uint32_t imageBase) {
+    std::vector<uint8_t> data = std::vector<uint8_t>(4);
+    *(reinterpret_cast<uint32_t *>(&data[0])) = imageBase;
+    return data;
+  }
+};
+
+// The file to wrap ImageBaseAtom. This is the only member file of
+// LinkerGeneratedSymbolFile.
+class MemberFile : public SimpleFile {
+public:
+  MemberFile(const PECOFFLinkingContext &context)
+      : SimpleFile(context, "Member of the Linker Internal File"),
+        _atom(*this, context.getBaseAddress()) {
+    addAtom(_atom);
+  };
+
+private:
+  ImageBaseAtom _atom;
+};
+
+} // anonymous namespace
+
+// A pseudo library file to wrap MemberFile, which in turn wraps ImageBaseAtom.
+// The file the core linker handle is this.
+//
+// The reason why we don't pass MemberFile to the core linker is because, if we
+// did so, ImageBaseAtom would always be emit to the resultant executable. By
+// wrapping the file by a library file, we made it to emit ImageBaseAtom only
+// when the atom is really referenced.
+class LinkerGeneratedSymbolFile : public ArchiveLibraryFile {
+public:
+  LinkerGeneratedSymbolFile(const PECOFFLinkingContext &context)
+      : ArchiveLibraryFile(context, "Linker Internal File"),
+        _memberFile(context) {};
+
+  virtual const File *find(StringRef name, bool dataSymbolOnly) const {
+    if (name == "___ImageBase")
+      return &_memberFile;
+    return nullptr;
+  }
+
+  virtual const atom_collection<DefinedAtom> &defined() const {
+    return _noDefinedAtoms;
+  }
+
+  virtual const atom_collection<UndefinedAtom> &undefined() const {
+    return _noUndefinedAtoms;
+  }
+
+  virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const {
+    return _noSharedLibraryAtoms;
+  }
+
+  virtual const atom_collection<AbsoluteAtom> &absolute() const {
+    return _noAbsoluteAtoms;
+  }
+
+private:
+  MemberFile _memberFile;
+};
+
+/// An instance of UndefinedSymbolFile has a list of undefined symbols
+/// specified by "/include" command line option. This will be added to the
+/// input file list to force the core linker to try to resolve the undefined
+/// symbols.
+class UndefinedSymbolFile : public SimpleFile {
+public:
+  UndefinedSymbolFile(const LinkingContext &ti)
+      : SimpleFile(ti, "Linker Internal File") {
+    for (StringRef symbol : ti.initialUndefinedSymbols()) {
+      UndefinedAtom *atom = new (_alloc) coff::COFFUndefinedAtom(*this, symbol);
+      addAtom(*atom);
+    }
+  }
+
+private:
+  llvm::BumpPtrAllocator _alloc;
+};
+
+} // end namespace coff
+} // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp?rev=188052&r1=188051&r2=188052&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp Thu Aug  8 23:44:15 2013
@@ -10,6 +10,7 @@
 #include "Atoms.h"
 #include "GroupedSectionsPass.h"
 #include "IdataPass.h"
+#include "LinkerGeneratedSymbolFile.h"
 
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Allocator.h"
@@ -30,24 +31,6 @@ bool containDirectoryName(StringRef path
   llvm::sys::path::remove_filename(smallStr);
   return !smallStr.str().empty();
 }
-
-/// An instance of UndefinedSymbolFile has a list of undefined symbols
-/// specified by "/include" command line option. This will be added to the
-/// input file list to force the core linker to try to resolve the undefined
-/// symbols.
-class UndefinedSymbolFile : public SimpleFile {
-public:
-  UndefinedSymbolFile(const LinkingContext &ti)
-      : SimpleFile(ti, "Linker Internal File") {
-    for (StringRef symbol : ti.initialUndefinedSymbols()) {
-      UndefinedAtom *atom = new (_alloc) coff::COFFUndefinedAtom(*this, symbol);
-      addAtom(*atom);
-    }
-  }
-
-private:
-  llvm::BumpPtrAllocator _alloc;
-};
 } // anonymous namespace
 
 error_code PECOFFLinkingContext::parseFile(
@@ -83,8 +66,11 @@ bool PECOFFLinkingContext::validateImpl(
 
 void PECOFFLinkingContext::addImplicitFiles(InputFiles &files) const {
   // Add a pseudo file for "/include" linker option.
-  auto *file = new (_alloc) UndefinedSymbolFile(*this);
-  files.prependFile(*file);
+  auto *undefFile = new (_alloc) coff::UndefinedSymbolFile(*this);
+  files.prependFile(*undefFile);
+
+  auto *linkerFile = new (_alloc) coff::LinkerGeneratedSymbolFile(*this);
+  files.appendFile(*linkerFile);
 }
 
 /// Append the given file to the input file list. The file must be an object

Added: lld/trunk/test/pecoff/Inputs/imagebase.obj.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/imagebase.obj.yaml?rev=188052&view=auto
==============================================================================
--- lld/trunk/test/pecoff/Inputs/imagebase.obj.yaml (added)
+++ lld/trunk/test/pecoff/Inputs/imagebase.obj.yaml Thu Aug  8 23:44:15 2013
@@ -0,0 +1,59 @@
+---
+header:
+  Machine:         IMAGE_FILE_MACHINE_I386
+  Characteristics: [  ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     A100000000C3
+    Relocations:
+      - VirtualAddress:  1
+        SymbolName:      ___ImageBase
+        Type:            IMAGE_REL_I386_DIR32
+  - Name:            .data
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       16
+    SectionData:     ""
+  - Name:            .drectve
+    Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
+    Alignment:       2147483648
+    SectionData:     2F454E5452593A5F737461727420
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    NumberOfAuxSymbols: 1
+    AuxiliaryData:   060000000100000000000000000000000000
+  - Name:            .data
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    NumberOfAuxSymbols: 1
+    AuxiliaryData:   000000000000000000000000000000000000
+  - Name:            ___ImageBase
+    Value:           0
+    SectionNumber:   0
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            __start
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            .drectve
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    NumberOfAuxSymbols: 1
+    AuxiliaryData:   0E0000000000000000000000000000000000
+...

Added: lld/trunk/test/pecoff/imagebase.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/imagebase.test?rev=188052&view=auto
==============================================================================
--- lld/trunk/test/pecoff/imagebase.test (added)
+++ lld/trunk/test/pecoff/imagebase.test Thu Aug  8 23:44:15 2013
@@ -0,0 +1,10 @@
+# RUN: yaml2obj %p/Inputs/imagebase.obj.yaml > %t.obj
+#
+# RUN: lld -flavor link /out:%t1 /subsystem:console -- %t.obj \
+# RUN:   && llvm-objdump -disassemble %t1 | FileCheck -check-prefix=CHECK1 %s
+#
+# RUN: lld -flavor link /out:%t1 /subsystem:console /base:65536 -- %t.obj \
+# RUN:   && llvm-objdump -disassemble %t1 | FileCheck -check-prefix=CHECK2 %s
+
+CHECK1: a1 00 20 40 00    movl    4202496, %eax
+CHECK2: a1 00 20 01 00    movl    73728, %eax





More information about the llvm-commits mailing list