[lld] r229762 - PECOFF: Fix symbol aliases
Rui Ueyama
ruiu at google.com
Wed Feb 18 15:11:48 PST 2015
Author: ruiu
Date: Wed Feb 18 17:11:48 2015
New Revision: 229762
URL: http://llvm.org/viewvc/llvm-project?rev=229762&view=rev
Log:
PECOFF: Fix symbol aliases
Weak aliases defined using /alternatename command line option were getting
wrong RVAs in the final output because of wrong atom ordinal. Alias atoms
were assigned large ordinals than any other regular atoms because they were
instantiated after other atoms and just got new (larger) ordinals.
Atoms are sorted by its file and atom ordinals in the order pass. Alias
atoms were located after all other atoms in the same file.
An alias atom's ordinal needs to be smaller than its alias target but larger
than the atom appeared before the target -- so that the alias is located
between the two. Since an alias has no size, the alias target will be located
at the same location as the alias.
In this patch, I made a gap between two regular atoms so that we can put
aliases after instantiating them (without re-numbering existing atoms).
Modified:
lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
lld/trunk/test/pecoff/entry.test
Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=229762&r1=229761&r2=229762&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp Wed Feb 18 17:11:48 2015
@@ -83,7 +83,7 @@ public:
FileCOFF(std::unique_ptr<MemoryBuffer> 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<uint8_t> array);
+ uint64_t getNextOrdinal();
std::unique_ptr<const llvm::object::COFFObjectFile> _obj;
std::unique_ptr<MemoryBuffer> _mb;
@@ -555,7 +551,7 @@ FileCOFF::createDefinedSymbols(const Sym
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::AtomizeDefined
: 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::AtomizeDefined
ArrayRef<uint8_t> 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::AtomizeDefined
ArrayRef<uint8_t> 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::AtomizeDefined
ArrayRef<uint8_t> 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(StringR
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::maybeCreateSXD
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<const ulittle32_t *>(sxdata.data());
@@ -1064,6 +1061,13 @@ StringRef FileCOFF::ArrayRefToString(Arr
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) {}
Modified: lld/trunk/test/pecoff/entry.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/entry.test?rev=229762&r1=229761&r2=229762&view=diff
==============================================================================
--- lld/trunk/test/pecoff/entry.test (original)
+++ lld/trunk/test/pecoff/entry.test Wed Feb 18 17:11:48 2015
@@ -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
More information about the llvm-commits
mailing list