[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