- const struct libent *lesc = NULL; /* libent ref for shared cache */
- if (r->r_insharedregion) {
- uuid_t uusc;
- if (get_sc_uuid(dpi, uusc)) {
- lesc = libent_lookup_byuuid(uusc);
- assert(NULL == lesc->le_mh && 0 == lesc->le_mhaddr);
- }
- }
-
- /*
- * Only very specific segment types get to be filerefs
- */
- for (i = 0; i < r->r_nsubregions; i++) {
- struct subregion *s = r->r_subregions[i];
- /*
- * Anything writable is trivially disqualified
- */
- if (s->s_segcmd.initprot & VM_PROT_WRITE)
- continue;
- /*
- * As long as there's a filename, __TEXT and __LINKEDIT
- * end up as a file reference.
- *
- * __LINKEDIT is more complicated: the segment commands point
- * at a unified segment in the shared cache mapping.
- * Ditto for __UNICODE(?)
- */
- if (issubregiontype(s, SEG_TEXT)) {
- /* fall through */;
- } else if (issubregiontype(s, SEG_LINKEDIT)) {
- if (r->r_insharedregion)
- s->s_libent = lesc;
- } else if (issubregiontype(s, "__UNICODE")) {
- if (r->r_insharedregion)
- s->s_libent = lesc;
- } else
- continue;
-
- if (s->s_libent)
- s->s_isfileref = true;
- }
- }
+ if (r->r_info.external_pager) {
+ /*
+ * Only very specific segment types get to be filerefs
+ */
+ for (i = 0; i < r->r_nsubregions; i++) {
+ struct subregion *s = r->r_subregions[i];
+ /*
+ * Anything marked writable is trivially disqualified; we're
+ * going to copy it anyway.
+ */
+ if (s->s_segcmd.initprot & VM_PROT_WRITE)
+ continue;
+
+ /* __TEXT and __LINKEDIT are our real targets */
+ if (!issubregiontype(s, SEG_TEXT) && !issubregiontype(s, SEG_LINKEDIT) && !issubregiontype(s, "__UNICODE")) {
+ if (OPTIONS_DEBUG(opt, 3)) {
+ hsize_str_t hstr;
+ printvr(S_RANGE(s), "skipping read-only %s segment %s\n", S_MACHO_TYPE(s), str_hsize(hstr, S_SIZE(s)));
+ }
+ continue;
+ }
+ if (r->r_insharedregion) {
+ /*
+ * Part of the shared region: things get more complicated.
+ */
+ if (r->r_fileref) {
+ /*
+ * There's a file reference here for the whole region.
+ * For __TEXT subregions, we could, in principle (though
+ * see below) generate references to the individual
+ * dylibs that dyld reports in the region. If the
+ * debugger could then use the __LINKEDIT info in the
+ * file, then we'd be done. But as long as the dump
+ * includes __LINKEDIT sections, we're going to
+ * end up generating a file reference to the combined
+ * __LINKEDIT section in the shared cache anyway, so
+ * we might as well do that for the __TEXT regions as
+ * well.
+ */
+ s->s_libent = r->r_fileref->fr_libent;
+ s->s_isuuidref = true;
+ } else {
+ /*
+ * If we get here, it's likely that the shared cache
+ * name can't be found e.g. update_dyld_shared_cache(1).
+ * For __TEXT subregions, we could generate refs to
+ * the individual dylibs, but note that the mach header
+ * and segment commands in memory are still pointing
+ * into the shared cache so any act of reconstruction
+ * is fiendishly complex. So copy it.
+ */
+ assert(!s->s_isuuidref);
+ }
+ } else {
+ /* Just a regular dylib? */
+ if (s->s_libent)
+ s->s_isuuidref = true;
+ }
+ }
+ }
+ }