diff options
| author | Rui Ueyama <ruiu@google.com> | 2015-01-21 01:26:43 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2015-01-21 01:26:43 +0000 |
| commit | e6556a9ceac2a2fab2062822a910877b4491b939 (patch) | |
| tree | 0fa2652be3372feab09b8215734999b5be66ddb7 | |
| parent | e527c5810ca929c6e22a7c11efbdd5022f75e690 (diff) | |
| download | bcm5719-llvm-e6556a9ceac2a2fab2062822a910877b4491b939.tar.gz bcm5719-llvm-e6556a9ceac2a2fab2062822a910877b4491b939.zip | |
Fix --start-group/end-group.
We used to manage the state whether we are in a group or not
using a counter. The counter is incremented by one if we jump from
end-group to start-group, and decremented by one if we don't.
The counter was assumed to be either zero or one, but obviously it
could be negative (if there's a group which is not repeated at all).
This is a fix for that issue.
llvm-svn: 226632
| -rw-r--r-- | lld/include/lld/Core/Resolver.h | 2 | ||||
| -rw-r--r-- | lld/lib/Core/Resolver.cpp | 16 | ||||
| -rw-r--r-- | lld/test/pecoff/Inputs/vars-main-x86.obj.yaml | 6 |
3 files changed, 15 insertions, 9 deletions
diff --git a/lld/include/lld/Core/Resolver.h b/lld/include/lld/Core/Resolver.h index 63ed68b2561..0e827bee953 100644 --- a/lld/include/lld/Core/Resolver.h +++ b/lld/include/lld/Core/Resolver.h @@ -58,7 +58,7 @@ private: typedef std::function<void(StringRef, bool)> UndefCallback; bool undefinesAdded(int begin, int end); - File *getFile(int &index, int &groupLevel); + File *getFile(int &index, bool &inGroup); /// \brief Add section group/.gnu.linkonce if it does not exist previously. void maybeAddSectionGroupOrGnuLinkOnce(const DefinedAtom &atom); diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp index 79432bebb84..2fcd254aa68 100644 --- a/lld/lib/Core/Resolver.cpp +++ b/lld/lib/Core/Resolver.cpp @@ -254,7 +254,7 @@ bool Resolver::undefinesAdded(int begin, int end) { return false; } -File *Resolver::getFile(int &index, int &groupLevel) { +File *Resolver::getFile(int &index, bool &inGroup) { std::vector<std::unique_ptr<Node>> &inputs = _context.getNodes(); if ((size_t)index >= inputs.size()) return nullptr; @@ -265,12 +265,12 @@ File *Resolver::getFile(int &index, int &groupLevel) { int size = group->getSize(); if (undefinesAdded(index - size, index)) { index -= size; - ++groupLevel; - return getFile(index, groupLevel); + inGroup = true; + return getFile(index, inGroup); } ++index; - --groupLevel; - return getFile(index, groupLevel); + inGroup = false; + return getFile(index, inGroup); } return cast<FileNode>(inputs[index++].get())->getFile(); } @@ -290,10 +290,10 @@ void Resolver::makePreloadArchiveMap() { bool Resolver::resolveUndefines() { ScopedTask task(getDefaultDomain(), "resolveUndefines"); int index = 0; - int groupLevel = 0; + bool inGroup = false; for (;;) { bool undefAdded = false; - File *file = getFile(index, groupLevel); + File *file = getFile(index, inGroup); if (!file) return true; if (std::error_code ec = file->parse()) { @@ -304,7 +304,7 @@ bool Resolver::resolveUndefines() { file->beforeLink(); switch (file->kind()) { case File::kindObject: - if (groupLevel > 0) + if (inGroup) break; assert(!file->hasOrdinal()); file->setOrdinal(_context.getNextOrdinalAndIncrement()); diff --git a/lld/test/pecoff/Inputs/vars-main-x86.obj.yaml b/lld/test/pecoff/Inputs/vars-main-x86.obj.yaml index 4bee575ddf4..fb016828df9 100644 --- a/lld/test/pecoff/Inputs/vars-main-x86.obj.yaml +++ b/lld/test/pecoff/Inputs/vars-main-x86.obj.yaml @@ -60,4 +60,10 @@ symbols: SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: ___ImageBase + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL ... |

