Index: lld/ELF/LinkerScript.h
===================================================================
--- lld/ELF/LinkerScript.h
+++ lld/ELF/LinkerScript.h
@@ -272,7 +272,7 @@
 
   std::vector<size_t> getPhdrIndices(OutputSection *sec);
 
-  MemoryRegion *findMemoryRegion(OutputSection *sec);
+  MemoryRegion *findMemoryRegion(OutputSection *sec, MemoryRegion *prev);
 
   void switchTo(OutputSection *sec);
   uint64_t advance(uint64_t size, unsigned align);
Index: lld/ELF/LinkerScript.cpp
===================================================================
--- lld/ELF/LinkerScript.cpp
+++ lld/ELF/LinkerScript.cpp
@@ -883,7 +883,8 @@
 // This function searches for a memory region to place the given output
 // section in. If found, a pointer to the appropriate memory region is
 // returned. Otherwise, a nullptr is returned.
-MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *sec) {
+MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *sec,
+                                             MemoryRegion *prev) {
   // If a memory region name was specified in the output section command,
   // then try to find that region first.
   if (!sec->memoryRegionName.empty()) {
@@ -899,6 +900,10 @@
   if (memoryRegions.empty())
     return nullptr;
 
+  // An allocatable orphan section should continue the previous memory region.
+  if (sec->sectionIndex == UINT32_MAX && sec->flags & SHF_ALLOC && prev)
+    return prev;
+
   // See if a region can be found by matching section flags.
   for (auto &pair : memoryRegions) {
     MemoryRegion *m = pair.second;
@@ -1132,6 +1137,7 @@
 
 void LinkerScript::adjustSectionsAfterSorting() {
   // Try and find an appropriate memory region to assign offsets in.
+  MemoryRegion *prev = nullptr;
   for (BaseCommand *base : sectionCommands) {
     if (auto *sec = dyn_cast<OutputSection>(base)) {
       if (!sec->lmaRegionName.empty()) {
@@ -1140,7 +1146,8 @@
         else
           error("memory region '" + sec->lmaRegionName + "' not declared");
       }
-      sec->memRegion = findMemoryRegion(sec);
+      sec->memRegion = findMemoryRegion(sec, prev);
+      prev = sec->memRegion;
     }
   }
 
Index: lld/ELF/Writer.cpp
===================================================================
--- lld/ELF/Writer.cpp
+++ lld/ELF/Writer.cpp
@@ -1256,10 +1256,13 @@
   // Consider all existing sections with the same proximity.
   int proximity = getRankProximity(sec, *i);
   unsigned sortRank = sec->sortRank;
-  if (script->hasPhdrsCommands())
-    // Prevent the orphan section to be placed before the found section because
-    // that can result in adding it to a previous segment and changing flags of
-    // that segment, for example, making a read-only segment writable.
+  if (script->hasPhdrsCommands() || !script->memoryRegions.empty())
+    // Prevent the orphan section to be placed before the found section. If
+    // custom program headers are defined, that helps to avoid adding it to a
+    // previous segment and changing flags of that segment, for example, making
+    // a read-only segment writable. If memory regions are defined, an orphan
+    // section should continue the same region as the found section to better
+    // resemble the behavior of GNU ld.
     sortRank = std::max(sortRank, foundSec->sortRank);
   for (; i != e; ++i) {
     auto *curSec = dyn_cast<OutputSection>(*i);
Index: lld/test/ELF/linkerscript/orphan-memory.test
===================================================================
--- /dev/null
+++ lld/test/ELF/linkerscript/orphan-memory.test
@@ -0,0 +1,46 @@
+# REQUIRES: x86
+
+# RUN: split-file %s %ts
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %ts/s -o %t.o
+# RUN: ld.lld -o %t -T %ts/t %t.o
+# RUN: llvm-readelf -S %t | FileCheck %s
+
+## Check that despite having a lower sort rank, an orphan section '.init_array'
+## is placed after '.data' and in the same memory region.
+
+## Also check that a non-SHF_ALLOC orphan section, which is '.nonalloc' in the
+## test, is not placed in a memory region. Both defined memory regions are
+## exhausted after all expected sections are added, thus, trying to put any
+## unexpected section would lead to an error.
+
+CHECK: Name        Type       Address          Off           Size
+CHECK: .text       PROGBITS   0000000000008000 {{[0-9a-f]+}} 000004
+CHECK: .data       PROGBITS   0000000000009000 {{[0-9a-f]+}} 000008
+CHECK: .init_array INIT_ARRAY 0000000000009008 {{[0-9a-f]+}} 000010
+CHECK: .nonalloc   PROGBITS   0000000000000000 {{[0-9a-f]+}} 000010
+
+#--- s
+  .text
+  .zero 4
+
+  .data
+  .zero 8
+
+  .section .init_array,"aw",@init_array
+  .zero 0x10
+
+  .section .nonalloc,""
+  .zero 0x10
+
+#--- t
+MEMORY
+{
+  TEXT : ORIGIN = 0x8000, LENGTH = 0x4
+  DATA : ORIGIN = 0x9000, LENGTH = 0x18
+}
+
+SECTIONS
+{
+  .text : { *(.text) } > TEXT
+  .data : { *(.data) } > DATA
+}