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

Rui Ueyama ruiu at google.com
Wed Sep 17 19:26:22 PDT 2014


Good point. I only tested it on x86. x64 is the next step.

On Wed, Sep 17, 2014 at 7:23 PM, David Majnemer <david.majnemer at gmail.com>
wrote:

> 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/4ea6a1b7/attachment.html>


More information about the llvm-commits mailing list