[Lldb-commits] [lldb] [lldb][Darwin] Don't add zero-length segments to SectionLoadList (PR #195206)

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Thu Apr 30 18:42:27 PDT 2026


https://github.com/jasonmolenda created https://github.com/llvm/llvm-project/pull/195206

On Darwin systems with a shared cache, all the system binaries are combined into a single range of virtual address space, placing all the TEXT segments together, all the DATA segments together, etc.  It shrinks the sizes of the segments from their on-disk file size to the actual size needed for their contents, instead of observing page alignment rules for segments.

And in one uncommon case, it is possible for a segment to not be put in the shared cache virtual range at all.

When DynamicLoaderDarwin adds each file's segments to the Target SectionLoadList (the table showing what VM ranges they are mapped to), we're using the original file's segment sizes.  But the in-memory segment sizes may be different for binaries in the shared cache. And for a segment which is eliminated entirely (zero length), we'll get warnings as the next segment is added to the same address in the SectionLoadList.

To start with, this PR is handling the special case of these segments that become zero length -- but not adding them to the SectionLoadList at all.

rdar://174948380

>From c0f30c41630d4639c8ad812edd3e7c9909bb07ac Mon Sep 17 00:00:00 2001
From: Jason Molenda <jmolenda at apple.com>
Date: Thu, 30 Apr 2026 18:36:23 -0700
Subject: [PATCH] [lldb][Darwin] Don't add zero-length segments to
 SectionLoadList

On Darwin systems with a shared cache, all the system binaries
are combined into a single range of virtual address space,
placing all the TEXT segments together, all the DATA segments
together, etc.  It shrinks the sizes of the segments from their
on-disk file size to the actual size needed for their contents,
instead of observing page alignment rules for segments.

And in one uncommon case, it is possible for a segment to not be
put in the shared cache virtual range at all.

When DynamicLoaderDarwin adds each file's segments to the Target
SectionLoadList (the table showing what VM ranges they are mapped
to), we're using the original file's segment sizes.  But the in-memory
segment sizes may be different for binaries in the shared cache.
And for a segment which is eliminated entirely (zero length), we'll
get warnings as the next segment is added to the same address in
the SectionLoadList.

To start with, this PR is handling the special case of these
segments that become zero length -- but not adding them to the
SectionLoadList at all.

rdar://174948380
---
 .../MacOSX-DYLD/DynamicLoaderDarwin.cpp        | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
index afa0ef28a381d..894ee16935e7e 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -275,6 +275,7 @@ void DynamicLoaderDarwin::UnloadAllImages() {
 bool DynamicLoaderDarwin::UpdateImageLoadAddress(Module *module,
                                                  ImageInfo &info) {
   bool changed = false;
+  Log *log = GetLog(LLDBLog::DynamicLoader);
   if (module) {
     ObjectFile *image_object_file = module->GetObjectFile();
     if (image_object_file) {
@@ -305,6 +306,23 @@ bool DynamicLoaderDarwin::UpdateImageLoadAddress(Module *module,
               const bool warn_multiple =
                   section_sp->GetName() != g_section_name_LINKEDIT;
 
+              // If a segment was eliminated for the in-memory image,
+              // don't map it into lldb's target section load list.
+              if (info.segments[i].vmsize == 0) {
+                LLDB_LOGF(log, "%s: Omitting zero-size segment %s",
+                          info.file_spec.GetFilename().AsCString(""),
+                          info.segments[i].name.AsCString(""));
+                continue;
+              }
+
+              if (info.segments[i].vmsize != section_sp->GetByteSize())
+                LLDB_LOGF(log,
+                          "%s: In-memory segment size for %s is %" PRIx64
+                          " but file segment size is %" PRIx64,
+                          info.file_spec.GetFilename().AsCString(""),
+                          info.segments[i].name.AsCString(""),
+                          info.segments[i].vmsize, section_sp->GetByteSize());
+
               changed = m_process->GetTarget().SetSectionLoadAddress(
                   section_sp, new_section_load_addr, warn_multiple);
             }



More information about the lldb-commits mailing list