[lld] r218007 - [PECOFF] Support TLS callbacks.

David Majnemer david.majnemer at gmail.com
Wed Sep 17 19:23:15 PDT 2014


I thought the symbol name varies depending on the platform, x86 is
__tls_used and all other platforms have _tls_used.

On Wed, Sep 17, 2014 at 10:02 PM, Rui Ueyama <ruiu at google.com> wrote:

> Author: ruiu
> Date: Wed Sep 17 21:02:52 2014
> New Revision: 218007
>
> URL: http://llvm.org/viewvc/llvm-project?rev=218007&view=rev
> Log:
> [PECOFF] Support TLS callbacks.
>
> The contents from section .CRT$XLA to .CRT$XLZ is an array of function
> pointers. They are called by the runtime when a new thread is created
> or (gracefully) terminated.
>
> You can make your own initialization function to be called by that
> mechanism. All you have to do is:
>
> - Define a pointer to a function in a .CRT$XL* section using pragma
> - Make an external reference to "__tls_used" symbol
>
> That technique is used in many projects. This patch is to support that.
>
> What this patch does is to set the relative virtual address of
> "__tls_used" to the PECOFF directory table. __tls_used is actually a
> struct containing pointers to a symbol in .CRT$XLA and another symbol
> in .CRT$XLZ. The runtime looks at the directory table, gets the address
> of the struct, and call the function pointers between XLA and XLZ.
>
> Added:
>     lld/trunk/test/pecoff/Inputs/tlsused.obj.yaml
>     lld/trunk/test/pecoff/tls.test
> Modified:
>     lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
>
> Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=218007&r1=218006&r2=218007&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
> +++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Wed Sep 17 21:02:52
> 2014
> @@ -885,6 +885,9 @@ private:
>    // The size of the image on disk. This is basically the sum of all
> chunks in
>    // the output file with paddings between them.
>    uint32_t _imageSizeOnDisk;
> +
> +  // The map from atom to its relative virtual address.
> +  std::map<const Atom *, uint64_t> _atomRva;
>  };
>
>  StringRef customSectionName(const DefinedAtom *atom) {
> @@ -933,6 +936,13 @@ void groupAtoms(const PECOFFLinkingConte
>    }
>  }
>
> +static const DefinedAtom *findTLSUsedSymbol(const File &file) {
> +  for (const DefinedAtom *atom : file.defined())
> +    if (atom->name() == "__tls_used")
> +      return atom;
> +  return nullptr;
> +}
> +
>  // Create all chunks that consist of the output file.
>  template <class PEHeader>
>  void PECOFFWriter::build(const File &linkedFile) {
> @@ -949,6 +959,7 @@ void PECOFFWriter::build(const File &lin
>    addChunk(dataDirectory);
>    addChunk(sectionTable);
>
> +  // Create sections and add the atoms to them.
>    for (auto i : atoms) {
>      StringRef sectionName = i.first;
>      std::vector<const DefinedAtom *> &contents = i.second;
> @@ -957,9 +968,14 @@ void PECOFFWriter::build(const File &lin
>        addSectionChunk(section, sectionTable);
>    }
>
> -  // Now that we know the addresses of all defined atoms that needs to be
> -  // relocated. So we can create the ".reloc" section which contains all
> the
> -  // relocation sites.
> +  // Build atom to its RVA map.
> +  for (std::unique_ptr<Chunk> &cp : _chunks)
> +    if (AtomChunk *chunk = dyn_cast<AtomChunk>(&*cp))
> +      chunk->buildAtomRvaMap(_atomRva);
> +
> +  // We know the addresses of all defined atoms that needs to be
> +  // relocated. So we can create the ".reloc" section which contains
> +  // all the relocation sites.
>    if (_ctx.getBaseRelocationEnabled()) {
>      BaseRelocChunk *baseReloc = new BaseRelocChunk(_chunks, _ctx);
>      if (baseReloc->size()) {
> @@ -1014,6 +1030,11 @@ void PECOFFWriter::build(const File &lin
>                                section->getVirtualAddress(),
> section->size());
>    }
>
> +  if (const DefinedAtom *atom = findTLSUsedSymbol(linkedFile)) {
> +    dataDirectory->setField(DataDirectoryIndex::TLS_TABLE,
> +                            _atomRva[atom], 0x18);
> +  }
> +
>    // Now that we know the size and file offset of sections. Set the file
>    // header accordingly.
>    peHeader->setSizeOfCode(calcSizeOfCode());
> @@ -1057,27 +1078,20 @@ std::error_code PECOFFWriter::writeFile(
>  /// address. In the second pass, we visit all relocation references to fix
>  /// up addresses in the buffer.
>  void PECOFFWriter::applyAllRelocations(uint8_t *bufferStart) {
> -  std::map<const Atom *, uint64_t> atomRva;
> +  // Create the list of section start addresses. It's needed for
> +  // relocations of SECREL type.
>    std::vector<uint64_t> sectionRva;
> -
> -  // Create the list of section start addresses.
>    for (auto &cp : _chunks)
>      if (SectionChunk *section = dyn_cast<SectionChunk>(&*cp))
>        sectionRva.push_back(section->getVirtualAddress());
>
> -  // Pass 1
> -  for (auto &cp : _chunks)
> -    if (AtomChunk *chunk = dyn_cast<AtomChunk>(&*cp))
> -      chunk->buildAtomRvaMap(atomRva);
> -
> -  // Pass 2
>    uint64_t base = _ctx.getBaseAddress();
>    for (auto &cp : _chunks) {
>      if (AtomChunk *chunk = dyn_cast<AtomChunk>(&*cp)) {
>        if (_ctx.is64Bit()) {
> -        chunk->applyRelocations64(bufferStart, atomRva, sectionRva, base);
> +        chunk->applyRelocations64(bufferStart, _atomRva, sectionRva,
> base);
>        } else {
> -        chunk->applyRelocations32(bufferStart, atomRva, sectionRva, base);
> +        chunk->applyRelocations32(bufferStart, _atomRva, sectionRva,
> base);
>        }
>      }
>    }
>
> Added: lld/trunk/test/pecoff/Inputs/tlsused.obj.yaml
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/tlsused.obj.yaml?rev=218007&view=auto
>
> ==============================================================================
> --- lld/trunk/test/pecoff/Inputs/tlsused.obj.yaml (added)
> +++ lld/trunk/test/pecoff/Inputs/tlsused.obj.yaml Wed Sep 17 21:02:52 2014
> @@ -0,0 +1,29 @@
> +---
> +header:
> +  Machine:         IMAGE_FILE_MACHINE_I386
> +  Characteristics: []
> +sections:
> +  - Name:            .data
> +    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA,
> IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
> +    Alignment:       4
> +    SectionData:     "0000000000000000"
> +symbols:
> +  - Name:            .data
> +    Value:           0
> +    SectionNumber:   1
> +    SimpleType:      IMAGE_SYM_TYPE_NULL
> +    ComplexType:     IMAGE_SYM_DTYPE_NULL
> +    StorageClass:    IMAGE_SYM_CLASS_STATIC
> +    SectionDefinition:
> +      Length:          8
> +      NumberOfRelocations: 0
> +      NumberOfLinenumbers: 0
> +      CheckSum:        0
> +      Number:          0
> +  - Name:            __tls_used
> +    Value:           0
> +    SectionNumber:   1
> +    SimpleType:      IMAGE_SYM_TYPE_NULL
> +    ComplexType:     IMAGE_SYM_DTYPE_NULL
> +    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
> +...
>
> Added: lld/trunk/test/pecoff/tls.test
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/tls.test?rev=218007&view=auto
>
> ==============================================================================
> --- lld/trunk/test/pecoff/tls.test (added)
> +++ lld/trunk/test/pecoff/tls.test Wed Sep 17 21:02:52 2014
> @@ -0,0 +1,14 @@
> +# RUN: yaml2obj %p/Inputs/hello.obj.yaml > %t1.obj
> +# RUN: yaml2obj %p/Inputs/tlsused.obj.yaml > %t2.obj
> +
> +# RUN: lld -flavor link /out:%t1.exe /subsystem:console /force -- %t1.obj
> +# RUN: llvm-readobj -file-headers %t1.exe | FileCheck -check-prefix=NOTLS
> %s
> +
> +# RUN: lld -flavor link /out:%t2.exe /subsystem:console /force -- %t1.obj
> %t2.obj
> +# RUN: llvm-readobj -file-headers %t2.exe | FileCheck -check-prefix=TLS %s
> +
> +NOTLS: TLSTableRVA: 0x0
> +NOTLS: TLSTableSize: 0x0
> +
> +TLS: TLSTableRVA: 0x1014
> +TLS: TLSTableSize: 0x18
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140917/ec7d32a6/attachment.html>


More information about the llvm-commits mailing list