<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>