summaryrefslogtreecommitdiffstats
path: root/lld/lib/Core
diff options
context:
space:
mode:
authorNick Kledzik <kledzik@apple.com>2011-12-22 02:38:01 +0000
committerNick Kledzik <kledzik@apple.com>2011-12-22 02:38:01 +0000
commit38eec3d931eeb273f2388f4a0248618226a4b2de (patch)
tree5372aec4c5a9c85be6998e6d6f94284d9c305eeb /lld/lib/Core
parentcc369ac0a2453e7e170b91864f03c8fc5e894c21 (diff)
downloadbcm5719-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.cpp41
-rw-r--r--lld/lib/Core/YamlReader.cpp30
-rw-r--r--lld/lib/Core/YamlWriter.cpp27
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";
}
OpenPOWER on IntegriCloud