[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