void addSyntheticIdata();
void fixPartialSectionChars(StringRef name, uint32_t chars);
bool fixGnuImportChunks();
- void fixTlsAlignment();
PartialSection *createPartialSection(StringRef name, uint32_t outChars);
PartialSection *findPartialSection(StringRef name, uint32_t outChars);
DelayLoadContents delayIdata;
EdataContents edata;
bool setNoSEHCharacteristic = false;
- uint32_t tlsAlignment = 0;
DebugDirectoryChunk *debugDirectory = nullptr;
std::vector<std::pair<COFF::DebugType, Chunk *>> debugRecords;
writeSections();
sortExceptionTable();
- // Fix up the alignment in the TLS Directory's characteristic field,
- // if a specific alignment value is needed
- if (tlsAlignment)
- fixTlsAlignment();
-
t1.stop();
if (!config->pdbPath.empty() && config->debug) {
StringRef name = c->getSectionName();
if (shouldStripSectionSuffix(sc, name))
name = name.split('$').first;
-
- if (name.startswith(".tls"))
- tlsAlignment = std::max(tlsAlignment, c->getAlignment());
-
PartialSection *pSec = createPartialSection(name,
c->getOutputCharacteristics());
pSec->chunks.push_back(c);
return it->second;
return nullptr;
}
-
-void Writer::fixTlsAlignment() {
- Defined *tlsSym =
- dyn_cast_or_null<Defined>(symtab->findUnderscore("_tls_used"));
- if (!tlsSym)
- return;
-
- OutputSection *sec = tlsSym->getChunk()->getOutputSection();
- assert(sec && tlsSym->getRVA() >= sec->getRVA() &&
- "no output section for _tls_used");
-
- uint8_t *secBuf = buffer->getBufferStart() + sec->getFileOff();
- uint64_t tlsOffset = tlsSym->getRVA() - sec->getRVA();
- uint64_t directorySize = config->is64()
- ? sizeof(object::coff_tls_directory64)
- : sizeof(object::coff_tls_directory32);
-
- if (tlsOffset + directorySize > sec->getRawSize())
- fatal("_tls_used sym is malformed");
-
- if (config->is64()) {
- object::coff_tls_directory64 *tlsDir =
- reinterpret_cast<object::coff_tls_directory64 *>(&secBuf[tlsOffset]);
- tlsDir->setAlignment(tlsAlignment);
- } else {
- object::coff_tls_directory32 *tlsDir =
- reinterpret_cast<object::coff_tls_directory32 *>(&secBuf[tlsOffset]);
- tlsDir->setAlignment(tlsAlignment);
- }
-}
uint32_t getAlignment() const {
// Bit [20:24] contains section alignment.
- uint32_t Shift = (Characteristics & COFF::IMAGE_SCN_ALIGN_MASK) >> 20;
+ uint32_t Shift = (Characteristics & 0x00F00000) >> 20;
if (Shift > 0)
return 1U << (Shift - 1);
return 0;
}
-
- void setAlignment(uint32_t Align) {
- uint32_t AlignBits = 0;
- if (Align) {
- assert(llvm::isPowerOf2_32(Align) && "alignment is not a power of 2");
- assert(llvm::Log2_32(Align) <= 13 && "alignment requested is too large");
- AlignBits = (llvm::Log2_32(Align) + 1) << 20;
- }
- Characteristics =
- (Characteristics & ~COFF::IMAGE_SCN_ALIGN_MASK) | AlignBits;
- }
};
using coff_tls_directory32 = coff_tls_directory<support::little32_t>;