diff --git a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp index 67177b7554fd..27d26c84985d 100644 --- a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp +++ b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp @@ -83,7 +83,7 @@ public: FileCOFF(std::unique_ptr mb, PECOFFLinkingContext &ctx) : File(mb->getBufferIdentifier(), kindObject), _mb(std::move(mb)), - _compatibleWithSEH(false), _ordinal(0), + _compatibleWithSEH(false), _ordinal(1), _machineType(llvm::COFF::MT_Invalid), _ctx(ctx) {} std::error_code doParse() override; @@ -108,11 +108,6 @@ public: void beforeLink() override; - void addDefinedAtom(AliasAtom *atom) { - atom->setOrdinal(_ordinal++); - _definedAtoms._atoms.push_back(atom); - } - void addUndefinedSymbol(StringRef sym) { _undefinedAtoms._atoms.push_back(new (_alloc) COFFUndefinedAtom(*this, sym)); } @@ -168,6 +163,7 @@ private: std::error_code addRelocationReferenceToAtoms(); std::error_code findSection(StringRef name, const coff_section *&result); StringRef ArrayRefToString(ArrayRef array); + uint64_t getNextOrdinal(); std::unique_ptr _obj; std::unique_ptr _mb; @@ -555,7 +551,7 @@ FileCOFF::createDefinedSymbols(const SymbolVectorT &symbols, uint32_t size = sym.getValue(); auto *atom = new (_alloc) COFFBSSAtom(*this, name, getScope(sym), DefinedAtom::permRW_, - DefinedAtom::mergeAsWeakAndAddressUsed, size, _ordinal++); + DefinedAtom::mergeAsWeakAndAddressUsed, size, getNextOrdinal()); // Common symbols should be aligned on natural boundaries with the maximum // of 32 byte. It's not documented anywhere, but it's what MSVC link.exe @@ -669,7 +665,7 @@ std::error_code FileCOFF::AtomizeDefinedSymbolsInSection( : si[1].getValue() - sym.getValue(); auto *atom = new (_alloc) COFFBSSAtom( *this, _symbolName[sym], getScope(sym), getPermissions(section), - DefinedAtom::mergeAsWeakAndAddressUsed, size, _ordinal++); + DefinedAtom::mergeAsWeakAndAddressUsed, size, getNextOrdinal()); atoms.push_back(atom); _symbolAtom[sym] = atom; } @@ -704,7 +700,7 @@ std::error_code FileCOFF::AtomizeDefinedSymbolsInSection( ArrayRef data(secData.data(), secData.size()); auto *atom = new (_alloc) COFFDefinedAtom( *this, "", sectionName, Atom::scopeTranslationUnit, type, isComdat, - perms, _merge[section], data, _ordinal++); + perms, _merge[section], data, getNextOrdinal()); atoms.push_back(atom); _definedAtomLocations[section][0].push_back(atom); return std::error_code(); @@ -717,7 +713,7 @@ std::error_code FileCOFF::AtomizeDefinedSymbolsInSection( ArrayRef data(secData.data(), size); auto *atom = new (_alloc) COFFDefinedAtom( *this, "", sectionName, Atom::scopeTranslationUnit, type, isComdat, - perms, _merge[section], data, _ordinal++); + perms, _merge[section], data, getNextOrdinal()); atoms.push_back(atom); _definedAtomLocations[section][0].push_back(atom); } @@ -730,7 +726,7 @@ std::error_code FileCOFF::AtomizeDefinedSymbolsInSection( ArrayRef data(start, end); auto *atom = new (_alloc) COFFDefinedAtom( *this, _symbolName[*si], sectionName, getScope(*si), type, isComdat, - perms, _merge[section], data, _ordinal++); + perms, _merge[section], data, getNextOrdinal()); atoms.push_back(atom); _symbolAtom[*si] = atom; _definedAtomLocations[section][si->getValue()].push_back(atom); @@ -868,6 +864,7 @@ AliasAtom *FileCOFF::createAlias(StringRef name, alias->setMerge(DefinedAtom::mergeAsWeak); if (target->contentType() == DefinedAtom::typeCode) alias->setDeadStrip(DefinedAtom::deadStripNever); + alias->setOrdinal(target->ordinal() - 1); return alias; } @@ -879,7 +876,7 @@ void FileCOFF::createAlternateNameAtoms() { aliases.push_back(createAlias(it->second, atom)); } for (AliasAtom *alias : aliases) - addDefinedAtom(alias); + _definedAtoms._atoms.push_back(alias); } // Interpret the contents of .drectve section. If exists, the section contains @@ -988,7 +985,7 @@ std::error_code FileCOFF::maybeCreateSXDataAtoms() { auto *atom = new (_alloc) COFFDefinedAtom( *this, "", ".sxdata", Atom::scopeTranslationUnit, DefinedAtom::typeData, false /*isComdat*/, DefinedAtom::permR__, DefinedAtom::mergeNo, - sxdata, _ordinal++); + sxdata, getNextOrdinal()); const ulittle32_t *symbolIndex = reinterpret_cast(sxdata.data()); @@ -1064,6 +1061,13 @@ StringRef FileCOFF::ArrayRefToString(ArrayRef array) { return StringRef(*contents).trim(); } +// getNextOrdinal returns a monotonically increasaing uint64_t number +// starting from 1. There's a large gap between two numbers returned +// from this function, so that you can put other atoms between them. +uint64_t FileCOFF::getNextOrdinal() { + return _ordinal++ << 32; +} + class COFFObjectReader : public Reader { public: COFFObjectReader(PECOFFLinkingContext &ctx) : _ctx(ctx) {} diff --git a/lld/test/pecoff/entry.test b/lld/test/pecoff/entry.test index c8338439be2a..b48e5a038293 100644 --- a/lld/test/pecoff/entry.test +++ b/lld/test/pecoff/entry.test @@ -33,7 +33,7 @@ WWINMAIN: _wWinMainCRTStartup # RUN: /alternatename:_mainCRTStartup=_bar -- %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=MAINADDR %s -MAINADDR: AddressOfEntryPoint: 0x100C +MAINADDR: AddressOfEntryPoint: 0x1004 # RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:baz -- %t.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=MANGLE %s