+ segTEXTB = (vm_offset_t) getsegdatafromheader(&_mh_execute_header,
+ "__TEXT", &segSizeTEXT);
+ segDATAB = (vm_offset_t) getsegdatafromheader(&_mh_execute_header,
+ "__DATA", &segSizeDATA);
+ segLINKB = (vm_offset_t) getsegdatafromheader(&_mh_execute_header,
+ "__LINKEDIT", &segSizeLINK);
+ segHIBB = (vm_offset_t) getsegdatafromheader(&_mh_execute_header,
+ "__HIB", &segSizeHIB);
+ segPRELINKTEXTB = (vm_offset_t) getsegdatafromheader(&_mh_execute_header,
+ "__PRELINK_TEXT", &segSizePRELINKTEXT);
+ segPRELINKINFOB = (vm_offset_t) getsegdatafromheader(&_mh_execute_header,
+ "__PRELINK_INFO", &segSizePRELINKINFO);
+ segTEXT = getsegbynamefromheader(&_mh_execute_header,
+ "__TEXT");
+ segDATA = getsegbynamefromheader(&_mh_execute_header,
+ "__DATA");
+ segCONST = getsegbynamefromheader(&_mh_execute_header,
+ "__DATA_CONST");
+ cursectTEXT = lastsectTEXT = firstsect(segTEXT);
+ /* Discover the last TEXT section within the TEXT segment */
+ while ((cursectTEXT = nextsect(segTEXT, cursectTEXT)) != NULL) {
+ lastsectTEXT = cursectTEXT;
+ }
+
+ sHIB = segHIBB;
+ eHIB = segHIBB + segSizeHIB;
+ vm_hib_base = sHIB;
+ /* Zero-padded from ehib to stext if text is 2M-aligned */
+ stext = segTEXTB;
+ lowGlo.lgStext = stext;
+ etext = (vm_offset_t) round_page_64(lastsectTEXT->addr + lastsectTEXT->size);
+ /* Zero-padded from etext to sdata if text is 2M-aligned */
+ sdata = segDATAB;
+ edata = segDATAB + segSizeDATA;
+
+ sconst = segCONST->vmaddr;
+ segSizeConst = segCONST->vmsize;
+ econst = sconst + segSizeConst;
+
+ kc_format_t kc_format = KCFormatUnknown;
+
+ /* XXX: FIXME_IN_dyld: For new-style kernel caches, the ending address of __DATA_CONST may not be page-aligned */
+ if (PE_get_primary_kc_format(&kc_format) && kc_format == KCFormatFileset) {
+ /* Round up the end */
+ econst = P2ROUNDUP(econst, PAGE_SIZE);
+ edata = P2ROUNDUP(edata, PAGE_SIZE);
+ } else {
+ assert(((sconst | econst) & PAGE_MASK) == 0);
+ assert(((sdata | edata) & PAGE_MASK) == 0);
+ }
+
+ DPRINTF("segTEXTB = %p\n", (void *) segTEXTB);
+ DPRINTF("segDATAB = %p\n", (void *) segDATAB);
+ DPRINTF("segLINKB = %p\n", (void *) segLINKB);
+ DPRINTF("segHIBB = %p\n", (void *) segHIBB);
+ DPRINTF("segPRELINKTEXTB = %p\n", (void *) segPRELINKTEXTB);
+ DPRINTF("segPRELINKINFOB = %p\n", (void *) segPRELINKINFOB);
+ DPRINTF("sHIB = %p\n", (void *) sHIB);
+ DPRINTF("eHIB = %p\n", (void *) eHIB);
+ DPRINTF("stext = %p\n", (void *) stext);
+ DPRINTF("etext = %p\n", (void *) etext);
+ DPRINTF("sdata = %p\n", (void *) sdata);
+ DPRINTF("edata = %p\n", (void *) edata);
+ DPRINTF("sconst = %p\n", (void *) sconst);
+ DPRINTF("econst = %p\n", (void *) econst);
+ DPRINTF("kernel_top = %p\n", (void *) &last_kernel_symbol);
+
+ vm_kernel_base = sHIB;
+ vm_kernel_top = (vm_offset_t) &last_kernel_symbol;
+ vm_kernel_stext = stext;
+ vm_kernel_etext = etext;
+ vm_prelink_stext = segPRELINKTEXTB;
+ vm_prelink_etext = segPRELINKTEXTB + segSizePRELINKTEXT;
+ vm_prelink_sinfo = segPRELINKINFOB;
+ vm_prelink_einfo = segPRELINKINFOB + segSizePRELINKINFO;
+ vm_slinkedit = segLINKB;
+ vm_elinkedit = segLINKB + segSizeLINK;
+
+ /*
+ * In the fileset world, we want to be able to (un)slide addresses from
+ * the kernel or any of the kexts (e.g., for kernel logging metadata
+ * passed between the kernel and logd in userspace). VM_KERNEL_UNSLIDE
+ * (via VM_KERNEL_IS_SLID) should apply to the addresses in the range
+ * from the first basement address to the last boot kc address.
+ *
+ * ^
+ * :
+ * |
+ * vm_kernel_slid_top - ---------------------------------------------
+ * |
+ * :
+ * : Boot kc (kexts in the boot kc here)
+ * : - - - - - - - - - - - - - - - - - - - - - - -
+ * :
+ * :
+ * | Boot kc (kernel here)
+ * - ---------------------------------------------
+ * |
+ * :
+ * | Basement (kexts in pageable and aux kcs here)
+ * vm_kernel_slid_base - ---------------------------------------------
+ * 0
+ */
+
+ vm_kernel_slid_base = vm_kext_base + vm_kernel_slide;
+ vm_kernel_slid_top = (kc_format == KCFormatFileset) ?
+ vm_slinkedit : vm_prelink_einfo;