[lld] r188052 - [PECOFF] Create __ImageBase symbol.
Saleem Abdulrasool
compnerd at compnerd.org
Thu Aug 8 23:01:48 PDT 2013
On Thu, Aug 8, 2013 at 9:44 PM, Rui Ueyama <ruiu at google.com> wrote:
> 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"; }
>
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".
> + 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
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
--
Saleem Abdulrasool
compnerd (at) compnerd (dot) org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130808/32634d5b/attachment.html>
More information about the llvm-commits
mailing list