forked from OSchip/llvm-project
Revert r361206 "[COFF] Store alignment in log2 form, NFC"
Makes the linker crash when linking nasm.exe. llvm-svn: 361212
This commit is contained in:
parent
a5401e48dd
commit
67510fac36
|
@ -41,7 +41,7 @@ SectionChunk::SectionChunk(ObjFile *F, const coff_section *H)
|
|||
SectionNameData = SectionName.data();
|
||||
SectionNameSize = SectionName.size();
|
||||
|
||||
setAlignment(Header->getAlignment());
|
||||
Alignment = Header->getAlignment();
|
||||
|
||||
// If linker GC is disabled, every chunk starts out alive. If linker GC is
|
||||
// enabled, treat non-comdat sections as roots. Generally optimized object
|
||||
|
@ -53,7 +53,7 @@ SectionChunk::SectionChunk(ObjFile *F, const coff_section *H)
|
|||
// SectionChunk is one of the most frequently allocated classes, so it is
|
||||
// important to keep it as compact as possible. As of this writing, the number
|
||||
// below is the size of this class on x64 platforms.
|
||||
static_assert(sizeof(SectionChunk) <= 104, "SectionChunk grew unexpectedly");
|
||||
static_assert(sizeof(SectionChunk) <= 112, "SectionChunk grew unexpectedly");
|
||||
|
||||
static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }
|
||||
static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
|
||||
|
@ -625,7 +625,7 @@ SectionChunk *SectionChunk::findByName(ArrayRef<SectionChunk *> Sections,
|
|||
}
|
||||
|
||||
void SectionChunk::replace(SectionChunk *Other) {
|
||||
P2Align = std::max(P2Align, Other->P2Align);
|
||||
Alignment = std::max(Alignment, Other->Alignment);
|
||||
Other->Repl = Repl;
|
||||
Other->Live = false;
|
||||
}
|
||||
|
@ -640,7 +640,7 @@ uint32_t SectionChunk::getSectionNumber() const {
|
|||
CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) {
|
||||
// Common symbols are aligned on natural boundaries up to 32 bytes.
|
||||
// This is what MSVC link.exe does.
|
||||
setAlignment(std::min(32U, Sym.getValue()));
|
||||
Alignment = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue()));
|
||||
}
|
||||
|
||||
uint32_t CommonChunk::getOutputCharacteristics() const {
|
||||
|
@ -656,7 +656,7 @@ void StringChunk::writeTo(uint8_t *Buf) const {
|
|||
ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(S) {
|
||||
// Intel Optimization Manual says that all branch targets
|
||||
// should be 16-byte aligned. MSVC linker does this too.
|
||||
setAlignment(16);
|
||||
Alignment = 16;
|
||||
}
|
||||
|
||||
void ImportThunkChunkX64::writeTo(uint8_t *Buf) const {
|
||||
|
@ -854,20 +854,17 @@ uint8_t Baserel::getDefaultType() {
|
|||
}
|
||||
}
|
||||
|
||||
MergeChunk *MergeChunk::Instances[Log2MaxSectionAlignment + 1] = {};
|
||||
std::map<uint32_t, MergeChunk *> MergeChunk::Instances;
|
||||
|
||||
MergeChunk::MergeChunk(uint32_t Alignment)
|
||||
: Builder(StringTableBuilder::RAW, Alignment) {
|
||||
setAlignment(Alignment);
|
||||
this->Alignment = Alignment;
|
||||
}
|
||||
|
||||
void MergeChunk::addSection(SectionChunk *C) {
|
||||
assert(isPowerOf2_32(C->getAlignment()));
|
||||
uint8_t P2Align = llvm::Log2_32(C->getAlignment());
|
||||
assert(P2Align >= 0 && P2Align < array_lengthof(Instances));
|
||||
auto *&MC = Instances[P2Align];
|
||||
auto *&MC = Instances[C->Alignment];
|
||||
if (!MC)
|
||||
MC = make<MergeChunk>(C->getAlignment());
|
||||
MC = make<MergeChunk>(C->Alignment);
|
||||
MC->Sections.push_back(C);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,9 +44,6 @@ const uint32_t PermMask = 0xFE000000;
|
|||
// Mask for section types (code, data, bss).
|
||||
const uint32_t TypeMask = 0x000000E0;
|
||||
|
||||
// The log base 2 of the largest section alignment, which is log2(8192), or 13.
|
||||
enum : unsigned { Log2MaxSectionAlignment = 13 };
|
||||
|
||||
// A Chunk represents a chunk of data that will occupy space in the
|
||||
// output (if the resolver chose that). It may or may not be backed by
|
||||
// a section of an input file. It could be linker-created data, or
|
||||
|
@ -60,18 +57,6 @@ public:
|
|||
// Returns the size of this chunk (even if this is a common or BSS.)
|
||||
virtual size_t getSize() const = 0;
|
||||
|
||||
// Returns chunk alignment in power of two form. Value values are powers of
|
||||
// two from 1 to 8192.
|
||||
uint32_t getAlignment() const { return 1U << P2Align; }
|
||||
void setAlignment(uint32_t Align) {
|
||||
// Treat zero byte alignment as 1 byte alignment.
|
||||
Align = Align ? Align : 1;
|
||||
assert(llvm::isPowerOf2_32(Align) && "alignment is not a power of 2");
|
||||
P2Align = llvm::Log2_32(Align);
|
||||
assert(P2Align <= Log2MaxSectionAlignment &&
|
||||
"impossible requested alignment");
|
||||
}
|
||||
|
||||
// Write this chunk to a mmap'ed file, assuming Buf is pointing to
|
||||
// beginning of the file. Because this function may use RVA values
|
||||
// of other chunks for relocations, you need to set them properly
|
||||
|
@ -118,6 +103,9 @@ public:
|
|||
// bytes, so this is used only for logging or debugging.
|
||||
virtual StringRef getDebugName() { return ""; }
|
||||
|
||||
// The alignment of this chunk. The writer uses the value.
|
||||
uint32_t Alignment = 1;
|
||||
|
||||
virtual bool isHotPatchable() const { return false; }
|
||||
|
||||
protected:
|
||||
|
@ -130,10 +118,6 @@ public:
|
|||
bool KeepUnique = false;
|
||||
|
||||
protected:
|
||||
// The alignment of this chunk, stored in log2 form. The writer uses the
|
||||
// value.
|
||||
uint8_t P2Align = 0;
|
||||
|
||||
// The RVA of this chunk in the output. The writer sets a value.
|
||||
uint32_t RVA = 0;
|
||||
|
||||
|
@ -329,7 +313,7 @@ public:
|
|||
size_t getSize() const override;
|
||||
void writeTo(uint8_t *Buf) const override;
|
||||
|
||||
static MergeChunk *Instances[Log2MaxSectionAlignment + 1];
|
||||
static std::map<uint32_t, MergeChunk *> Instances;
|
||||
std::vector<SectionChunk *> Sections;
|
||||
|
||||
private:
|
||||
|
@ -453,7 +437,7 @@ public:
|
|||
class LocalImportChunk : public Chunk {
|
||||
public:
|
||||
explicit LocalImportChunk(Defined *S) : Sym(S) {
|
||||
setAlignment(Config->Wordsize);
|
||||
Alignment = Config->Wordsize;
|
||||
}
|
||||
size_t getSize() const override;
|
||||
void getBaserels(std::vector<Baserel> *Res) override;
|
||||
|
@ -544,7 +528,7 @@ class PseudoRelocTableChunk : public Chunk {
|
|||
public:
|
||||
PseudoRelocTableChunk(std::vector<RuntimePseudoReloc> &Relocs)
|
||||
: Relocs(std::move(Relocs)) {
|
||||
setAlignment(4);
|
||||
Alignment = 4;
|
||||
}
|
||||
size_t getSize() const override;
|
||||
void writeTo(uint8_t *Buf) const override;
|
||||
|
@ -574,7 +558,7 @@ public:
|
|||
class AbsolutePointerChunk : public Chunk {
|
||||
public:
|
||||
AbsolutePointerChunk(uint64_t Value) : Value(Value) {
|
||||
setAlignment(getSize());
|
||||
Alignment = getSize();
|
||||
}
|
||||
size_t getSize() const override;
|
||||
void writeTo(uint8_t *Buf) const override;
|
||||
|
|
|
@ -59,9 +59,7 @@ private:
|
|||
// A chunk for the import descriptor table.
|
||||
class LookupChunk : public Chunk {
|
||||
public:
|
||||
explicit LookupChunk(Chunk *C) : HintName(C) {
|
||||
setAlignment(Config->Wordsize);
|
||||
}
|
||||
explicit LookupChunk(Chunk *C) : HintName(C) { Alignment = Config->Wordsize; }
|
||||
size_t getSize() const override { return Config->Wordsize; }
|
||||
|
||||
void writeTo(uint8_t *Buf) const override {
|
||||
|
@ -80,7 +78,7 @@ public:
|
|||
class OrdinalOnlyChunk : public Chunk {
|
||||
public:
|
||||
explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) {
|
||||
setAlignment(Config->Wordsize);
|
||||
Alignment = Config->Wordsize;
|
||||
}
|
||||
size_t getSize() const override { return Config->Wordsize; }
|
||||
|
||||
|
@ -366,7 +364,7 @@ public:
|
|||
class DelayAddressChunk : public Chunk {
|
||||
public:
|
||||
explicit DelayAddressChunk(Chunk *C) : Thunk(C) {
|
||||
setAlignment(Config->Wordsize);
|
||||
Alignment = Config->Wordsize;
|
||||
}
|
||||
size_t getSize() const override { return Config->Wordsize; }
|
||||
|
||||
|
@ -578,7 +576,7 @@ void DelayLoadContents::create(Defined *H) {
|
|||
for (int I = 0, E = Syms.size(); I < E; ++I)
|
||||
Syms[I]->setLocation(Addresses[Base + I]);
|
||||
auto *MH = make<NullChunk>(8);
|
||||
MH->setAlignment(8);
|
||||
MH->Alignment = 8;
|
||||
ModuleHandles.push_back(MH);
|
||||
|
||||
// Fill the delay import table header fields.
|
||||
|
|
|
@ -1743,7 +1743,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
|||
continue;
|
||||
|
||||
CommonChunk *C = DC->getChunk();
|
||||
C->setAlignment(std::max(C->getAlignment(), Alignment));
|
||||
C->Alignment = std::max(C->Alignment, Alignment);
|
||||
}
|
||||
|
||||
// Windows specific -- Create a side-by-side manifest file.
|
||||
|
|
|
@ -256,10 +256,9 @@ void ICF::run(ArrayRef<Chunk *> Vec) {
|
|||
|
||||
// Make sure that ICF doesn't merge sections that are being handled by string
|
||||
// tail merging.
|
||||
for (MergeChunk *MC : MergeChunk::Instances)
|
||||
if (MC)
|
||||
for (SectionChunk *SC : MC->Sections)
|
||||
SC->Class[0] = NextId++;
|
||||
for (auto &P : MergeChunk::Instances)
|
||||
for (SectionChunk *SC : P.second->Sections)
|
||||
SC->Class[0] = NextId++;
|
||||
|
||||
// Initially, we use hash values to partition sections.
|
||||
parallelForEach(Chunks, [&](SectionChunk *SC) {
|
||||
|
|
|
@ -114,7 +114,7 @@ void coff::writeMapFile(ArrayRef<OutputSection *> OutputSections) {
|
|||
if (!SC)
|
||||
continue;
|
||||
|
||||
writeHeader(OS, SC->getRVA(), SC->getSize(), SC->getAlignment());
|
||||
writeHeader(OS, SC->getRVA(), SC->getSize(), SC->Alignment);
|
||||
OS << Indent8 << SC->File->getName() << ":(" << SC->getSectionName()
|
||||
<< ")\n";
|
||||
for (DefinedRegular *Sym : SectionSyms[SC])
|
||||
|
|
|
@ -865,9 +865,8 @@ void Writer::createSections() {
|
|||
}
|
||||
|
||||
void Writer::createMiscChunks() {
|
||||
for (MergeChunk *P : MergeChunk::Instances)
|
||||
if (P)
|
||||
RdataSec->addChunk(P);
|
||||
for (auto &P : MergeChunk::Instances)
|
||||
RdataSec->addChunk(P.second);
|
||||
|
||||
// Create thunks for locally-dllimported symbols.
|
||||
if (!Symtab->LocalImportChunks.empty()) {
|
||||
|
@ -1160,7 +1159,7 @@ void Writer::assignAddresses() {
|
|||
for (Chunk *C : Sec->Chunks) {
|
||||
if (Padding && C->isHotPatchable())
|
||||
VirtualSize += Padding;
|
||||
VirtualSize = alignTo(VirtualSize, C->getAlignment());
|
||||
VirtualSize = alignTo(VirtualSize, C->Alignment);
|
||||
C->setRVA(RVA + VirtualSize);
|
||||
C->finalizeContents();
|
||||
VirtualSize += C->getSize();
|
||||
|
@ -1520,8 +1519,8 @@ void Writer::createGuardCFTables() {
|
|||
|
||||
// Ensure sections referenced in the gfid table are 16-byte aligned.
|
||||
for (const ChunkAndOffset &C : AddressTakenSyms)
|
||||
if (C.InputChunk->getAlignment() < 16)
|
||||
C.InputChunk->setAlignment(16);
|
||||
if (C.InputChunk->Alignment < 16)
|
||||
C.InputChunk->Alignment = 16;
|
||||
|
||||
maybeAddRVATable(std::move(AddressTakenSyms), "__guard_fids_table",
|
||||
"__guard_fids_count");
|
||||
|
|
Loading…
Reference in New Issue