<div dir="ltr">On Thu, Aug 8, 2013 at 9:44 PM, Rui Ueyama <span dir="ltr"><<a href="mailto:ruiu@google.com" target="_blank">ruiu@google.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: ruiu<br>
Date: Thu Aug  8 23:44:15 2013<br>
New Revision: 188052<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=188052&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=188052&view=rev</a><br>
Log:<br>
[PECOFF] Create __ImageBase symbol.<br>
<br>
__ImageBase is a symbol having 4 byte integer equal to the image base address<br>
of the resultant executable. The linker is expected to create the symbol as if<br>
it were read from a file.<br>
<br>
In order to emit the symbol contents only when the symbol is actually<br>
referenced, we created a pseudo library file to wrap the linker generated<br>
symbol. The library file member is emitted to the output only when the member<br>
is actually referenced, which is suitable for our purpose.<br>
<br>
Added:<br>
    lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h<br>
    lld/trunk/test/pecoff/Inputs/imagebase.obj.yaml<br>
    lld/trunk/test/pecoff/imagebase.test<br>
Modified:<br>
    lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp<br>
<br>
Added: lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h?rev=188052&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h?rev=188052&view=auto</a><br>

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

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

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

==============================================================================<br>
--- lld/trunk/test/pecoff/imagebase.test (added)<br>
+++ lld/trunk/test/pecoff/imagebase.test Thu Aug  8 23:44:15 2013<br>
@@ -0,0 +1,10 @@<br>
+# RUN: yaml2obj %p/Inputs/imagebase.obj.yaml > %t.obj<br>
+#<br>
+# RUN: lld -flavor link /out:%t1 /subsystem:console -- %t.obj \<br>
+# RUN:   && llvm-objdump -disassemble %t1 | FileCheck -check-prefix=CHECK1 %s<br>
+#<br>
+# RUN: lld -flavor link /out:%t1 /subsystem:console /base:65536 -- %t.obj \<br>
+# RUN:   && llvm-objdump -disassemble %t1 | FileCheck -check-prefix=CHECK2 %s<br>
+<br>
+CHECK1: a1 00 20 40 00    movl    4202496, %eax<br>
+CHECK2: a1 00 20 01 00    movl    73728, %eax<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>Saleem Abdulrasool<br>compnerd (at) compnerd (dot) org
</div></div>