summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-01-21 01:26:43 +0000
committerRui Ueyama <ruiu@google.com>2015-01-21 01:26:43 +0000
commite6556a9ceac2a2fab2062822a910877b4491b939 (patch)
tree0fa2652be3372feab09b8215734999b5be66ddb7
parente527c5810ca929c6e22a7c11efbdd5022f75e690 (diff)
downloadbcm5719-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.h2
-rw-r--r--lld/lib/Core/Resolver.cpp16
-rw-r--r--lld/test/pecoff/Inputs/vars-main-x86.obj.yaml6
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
...
OpenPOWER on IntegriCloud