diff options
| author | Nick Kledzik <kledzik@apple.com> | 2011-12-22 02:38:01 +0000 |
|---|---|---|
| committer | Nick Kledzik <kledzik@apple.com> | 2011-12-22 02:38:01 +0000 |
| commit | 38eec3d931eeb273f2388f4a0248618226a4b2de (patch) | |
| tree | 5372aec4c5a9c85be6998e6d6f94284d9c305eeb /lld/lib/Core | |
| parent | cc369ac0a2453e7e170b91864f03c8fc5e894c21 (diff) | |
| download | bcm5719-llvm-38eec3d931eeb273f2388f4a0248618226a4b2de.tar.gz bcm5719-llvm-38eec3d931eeb273f2388f4a0248618226a4b2de.zip | |
Add more merging/coalescing test cases and make core linking work for them
llvm-svn: 147130
Diffstat (limited to 'lld/lib/Core')
| -rw-r--r-- | lld/lib/Core/SymbolTable.cpp | 41 | ||||
| -rw-r--r-- | lld/lib/Core/YamlReader.cpp | 30 | ||||
| -rw-r--r-- | lld/lib/Core/YamlWriter.cpp | 27 |
3 files changed, 77 insertions, 21 deletions
diff --git a/lld/lib/Core/SymbolTable.cpp b/lld/lib/Core/SymbolTable.cpp index ebd4c0bde50..223f15e6cda 100644 --- a/lld/lib/Core/SymbolTable.cpp +++ b/lld/lib/Core/SymbolTable.cpp @@ -24,6 +24,10 @@ namespace lld { +SymbolTable::SymbolTable(Platform& plat) + : _platform(plat) { +} + void SymbolTable::add(const Atom &atom) { assert(atom.scope() != Atom::scopeTranslationUnit); if ( !atom.internalName() ) { @@ -39,6 +43,7 @@ enum NameCollisionResolution { NCR_Second, NCR_Weak, NCR_Larger, + NCR_Dup, NCR_Error }; @@ -46,7 +51,7 @@ static NameCollisionResolution cases[6][6] = { //regular weak tentative absolute undef sharedLib { // first is regular - NCR_Error, NCR_First, NCR_First, NCR_Error, NCR_First, NCR_First + NCR_Dup, NCR_First, NCR_First, NCR_Error, NCR_First, NCR_First }, { // first is weak @@ -75,26 +80,44 @@ static NameCollisionResolution collide(Atom::Definition first, return cases[first][second]; } -void SymbolTable::addByName(const Atom &atom) { - llvm::StringRef name = atom.name(); +void SymbolTable::addByName(const Atom & newAtom) { + llvm::StringRef name = newAtom.name(); const Atom *existing = this->findByName(name); if (existing == NULL) { // name is not in symbol table yet, add it associate with this atom - _nameTable[name] = &atom; + _nameTable[name] = &newAtom; } else { // name is already in symbol table and associated with another atom - switch (collide(existing->definition(), atom.definition())) { + switch (collide(existing->definition(), newAtom.definition())) { case NCR_First: // using first, just add new to _replacedAtoms - _replacedAtoms[&atom] = existing; + _replacedAtoms[&newAtom] = existing; break; case NCR_Second: // using second, update tables - _nameTable[name] = &atom; - _replacedAtoms[existing] = &atom; + _nameTable[name] = &newAtom; + _replacedAtoms[existing] = &newAtom; + break; + case NCR_Dup: + if ( existing->mergeDuplicates() && newAtom.mergeDuplicates() ) { + // using existing atom, add new atom to _replacedAtoms + _replacedAtoms[&newAtom] = existing; + } + else { + const Atom& use = _platform.handleMultipleDefinitions(*existing, newAtom); + if ( &use == existing ) { + // using existing atom, add new atom to _replacedAtoms + _replacedAtoms[&newAtom] = existing; + } + else { + // using new atom, update tables + _nameTable[name] = &newAtom; + _replacedAtoms[existing] = &newAtom; + } + } break; default: - llvm::report_fatal_error("unhandled switch clause"); + llvm::report_fatal_error("SymbolTable::addByName(): unhandled switch clause"); } } } diff --git a/lld/lib/Core/YamlReader.cpp b/lld/lib/Core/YamlReader.cpp index 6250939b8a7..c35664e0280 100644 --- a/lld/lib/Core/YamlReader.cpp +++ b/lld/lib/Core/YamlReader.cpp @@ -137,6 +137,8 @@ void YAML::parse(llvm::MemoryBuffer *mb, std::vector<const Entry *> &entries) { state = inTriplePeriod; } else if (c == '\n') { // ignore empty lines + } else if (c == '\t') { + llvm::report_fatal_error("TAB character found in yaml file"); } else { return; } @@ -244,13 +246,14 @@ public: , ContentType ct , SectionChoice sc , bool intn + , bool md , DeadStripKind dsk , bool tb , bool al , Alignment a , YAMLFile& f , const char *n) - : Atom(ord, d, s, ct, sc, intn, dsk, tb, al, a) + : Atom(ord, d, s, ct, sc, intn, md, dsk, tb, al, a) , _file(f) , _name(n) , _size(0) @@ -311,6 +314,7 @@ public: void setType(const char *n); void setAlign2(const char *n); void setDefinition(const char *n); + void setMergeDuplicates(const char *n); void setFixupKind(const char *n); void setFixupOffset(const char *n); @@ -328,7 +332,7 @@ private: Atom::Definition _def; Atom::SectionChoice _sectionChoice; bool _internalName; - bool _userVisibleName; + bool _mergeDuplicates; Atom::DeadStripKind _dontDeadStrip; bool _thumb; bool _alias; @@ -341,7 +345,8 @@ YAMLAtomState::YAMLAtomState() , _align(0, 0) , _type(Atom::typeData) , _scope(Atom::scopeGlobal) - , _userVisibleName(true) + , _internalName(false) + , _mergeDuplicates(false) , _dontDeadStrip(Atom::deadStripNormal) , _thumb(false) , _alias(false) { @@ -354,8 +359,8 @@ YAMLAtomState::YAMLAtomState() void YAMLAtomState::makeAtom(YAMLFile& f) { Atom *a = new YAMLAtom(_ordinal, _def, _scope, _type, _sectionChoice, - _internalName, _dontDeadStrip, _thumb, _alias, - _align, f, _name); + _internalName, _mergeDuplicates, _dontDeadStrip, + _thumb, _alias, _align, f, _name); f._atoms.push_back(a); ++_ordinal; @@ -369,6 +374,7 @@ void YAMLAtomState::makeAtom(YAMLFile& f) { _def = Atom::definitionRegular; _sectionChoice = Atom::sectionBasedOnContent; _internalName = false; + _mergeDuplicates = false; _dontDeadStrip = Atom::deadStripNormal; _thumb = false; _alias = false; @@ -419,12 +425,23 @@ void YAMLAtomState::setDefinition(const char *s) { _def = Atom::definitionRegular; else if (strcmp(s, "tentative") == 0) _def = Atom::definitionTentative; + else if (strcmp(s, "weak") == 0) + _def = Atom::definitionWeak; else if (strcmp(s, "absolute") == 0) _def = Atom::definitionAbsolute; else llvm::report_fatal_error("bad definition value"); } +void YAMLAtomState::setMergeDuplicates(const char *s) { + if (strcmp(s, "true") == 0) + _mergeDuplicates = true; + else if (strcmp(s, "false") == 0) + _mergeDuplicates = false; + else + llvm::report_fatal_error("bad merge-duplicates value"); +} + void YAMLAtomState::setFixupKind(const char *s) { if (strcmp(s, "pcrel32") == 0) _ref.kind = 1; @@ -525,6 +542,9 @@ llvm::error_code parseObjectText( llvm::MemoryBuffer *mb } else if (strcmp(entry->key, "definition") == 0) { atomState.setDefinition(entry->value); haveAtom = true; + } else if (strcmp(entry->key, "merge-duplicates") == 0) { + atomState.setMergeDuplicates(entry->value); + haveAtom = true; } else if (strcmp(entry->key, "fixups") == 0) { inFixups = true; } diff --git a/lld/lib/Core/YamlWriter.cpp b/lld/lib/Core/YamlWriter.cpp index 711fd1ac027..e5711068c7c 100644 --- a/lld/lib/Core/YamlWriter.cpp +++ b/lld/lib/Core/YamlWriter.cpp @@ -28,11 +28,22 @@ public: virtual void doFile(const class File &) { } virtual void doAtom(const class Atom &atom) { - _out << " - name: " << atom.name() << "\n"; - _out << " internal-name:" << atom.internalName() << "\n"; - _out << " definition: " << definitionString(atom.definition()) <<"\n"; - _out << " scope: " << scopeString(atom.scope()) << "\n"; - _out << " type: " << typeString(atom.contentType()) << "\n"; + _out << " - name: " << atom.name() << "\n"; + + if ( atom.internalName() ) + _out << " internal-name: true\n"; + + if ( atom.definition() != Atom::definitionRegular ) + _out << " definition: " << definitionString(atom.definition()) <<"\n"; + + if ( atom.scope() != Atom::scopeTranslationUnit ) + _out << " scope: " << scopeString(atom.scope()) << "\n"; + + _out << " type: " << typeString(atom.contentType()) << "\n"; + + if ( atom.mergeDuplicates() ) + _out << " merge-duplicates: true\n"; + if (atom.referencesBegin() != atom.referencesEnd()) { _out << " fixups:\n"; for (Reference::iterator it = atom.referencesBegin(), @@ -76,6 +87,8 @@ private: switch (def) { case Atom::definitionRegular: return "regular"; + case Atom::definitionWeak: + return "weak"; case Atom::definitionTentative: return "tentative"; case Atom::definitionAbsolute: @@ -88,11 +101,11 @@ private: llvm::raw_ostream &_out; }; -void writeObjectText(File *file, llvm::raw_ostream &out) { +void writeObjectText(File &file, llvm::raw_ostream &out) { Handler h(out); out << "---\n"; out << "atoms:\n"; - file->forEachAtom(h); + file.forEachAtom(h); out << "...\n"; } |

