summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2017-11-03 08:21:51 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2017-11-03 08:21:51 +0000
commit8c825db25e32365652c9d68177224f8c3c1a551a (patch)
tree0dff873d733bbbbf74e69f6276538974552da14a
parentcbed0e615b3658add66600d89e1d47c80a99a22d (diff)
downloadbcm5719-llvm-8c825db25e32365652c9d68177224f8c3c1a551a.tar.gz
bcm5719-llvm-8c825db25e32365652c9d68177224f8c3c1a551a.zip
[ELF] - Linkerscript: fixed non-determinism when handling MEMORY.
When findMemoryRegion do search to find a region for output section it iterates over MemoryRegions which is DenseMap and so does not guarantee iteration in insertion order. As a result selected region depends on its name and not on its definition position Testcase shows the issue, patch fixes it. Behavior after applying the patch seems consistent with bfd. Differential revision: https://reviews.llvm.org/D39544 llvm-svn: 317307
-rw-r--r--lld/ELF/LinkerScript.h2
-rw-r--r--lld/ELF/ScriptParser.cpp2
-rw-r--r--lld/test/ELF/linkerscript/memory3.s23
3 files changed, 25 insertions, 2 deletions
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 478405d463f..ba9e87720f7 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -277,7 +277,7 @@ public:
std::vector<InputSectionDescription *> KeptSections;
// A map from memory region name to a memory region descriptor.
- llvm::DenseMap<llvm::StringRef, MemoryRegion *> MemoryRegions;
+ llvm::MapVector<llvm::StringRef, MemoryRegion *> MemoryRegions;
// A list of symbols referenced by the script.
std::vector<llvm::StringRef> ReferencedSymbols;
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 7ec61226d7e..af9bf1994b4 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -422,7 +422,7 @@ void ScriptParser::readRegionAlias() {
setError("redefinition of memory region '" + Alias + "'");
if (!Script->MemoryRegions.count(Name))
setError("memory region '" + Name + "' is not defined");
- Script->MemoryRegions[Alias] = Script->MemoryRegions[Name];
+ Script->MemoryRegions.insert({Alias, Script->MemoryRegions[Name]});
}
void ScriptParser::readSearchDir() {
diff --git a/lld/test/ELF/linkerscript/memory3.s b/lld/test/ELF/linkerscript/memory3.s
new file mode 100644
index 00000000000..f85d0890157
--- /dev/null
+++ b/lld/test/ELF/linkerscript/memory3.s
@@ -0,0 +1,23 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: echo "MEMORY { ram2 (ax) : ORIGIN = 0x1000, LENGTH = 1K \
+# RUN: ram1 (ax) : ORIGIN = 0x4000, LENGTH = 1K } \
+# RUN: SECTIONS {}" > %t1.script
+# RUN: ld.lld -o %t1 --script %t1.script %t
+# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
+
+# RUN: echo "MEMORY { ram1 (ax) : ORIGIN = 0x1000, LENGTH = 1K \
+# RUN: ram2 (ax) : ORIGIN = 0x4000, LENGTH = 1K } \
+# RUN: SECTIONS {}" > %t2.script
+# RUN: ld.lld -o %t2 --script %t2.script %t
+# RUN: llvm-objdump -section-headers %t2 | FileCheck %s
+
+## Check we place .text into first defined memory region with appropriate flags.
+# CHECK: Sections:
+# CHECK: Idx Name Size Address
+# CHECK: 0 00000000 0000000000000000
+# CHECK: 1 .text 00000001 0000000000001000
+
+.section .text.foo,"ax",%progbits
+foo:
+ nop
OpenPOWER on IntegriCloud