static kern_return_t sect_export_macho_header_64(const KXLDSect *sect, u_char *buf,
u_long *header_offset, u_long header_size, u_long data_offset);
#endif
+extern boolean_t isSplitKext;
#if KXLD_USER_OR_ILP32
/*******************************************************************************
sect->align = src->align;
sect->reserved1 = src->reserved1;
sect->reserved2 = src->reserved2;
-
+
if (src->offset) {
sect->data = macho + src->offset;
} else {
relocs = (struct relocation_info *) ((void *) (macho + src->reloff));
- rval = kxld_reloc_create_macho(§->relocs, relocator,
+ rval = kxld_reloc_create_macho(§->relocs, relocator,
relocs, src->nreloc);
require_noerr(rval, finish);
relocs = (struct relocation_info *) ((void *) (macho + src->reloff));
- rval = kxld_reloc_create_macho(§->relocs, relocator,
- relocs, src->nreloc);
+ rval = kxld_reloc_create_macho(§->relocs, relocator,
+ relocs, src->nreloc);
require_noerr(rval, finish);
*sect_offset += sizeof(*src);
*data_offset += (u_long) sect->size;
}
-
rval = KERN_SUCCESS;
finish:
}
/*******************************************************************************
-*******************************************************************************/
+ *******************************************************************************/
kern_return_t
-kxld_sect_export_macho_to_vm(const KXLDSect *sect, u_char *buf,
- u_long *header_offset, u_long header_size,
- kxld_addr_t link_addr, u_long data_size,
- boolean_t is_32_bit __unused)
+kxld_sect_export_macho_to_vm(const KXLDSect *sect,
+ u_char *buf,
+ u_long *header_offset,
+ u_long header_size,
+ kxld_addr_t link_addr,
+ u_long data_size,
+ boolean_t is_32_bit __unused)
{
kern_return_t rval = KERN_FAILURE;
- u_long data_offset = (u_long) (sect->link_addr - link_addr);
-
+ u_long data_offset;
+
check(sect);
check(buf);
check(header_offset);
-
+
+ data_offset = (u_long) (sect->link_addr - link_addr);
+
KXLD_3264_FUNC(is_32_bit, rval,
- sect_export_macho_header_32, sect_export_macho_header_64,
- sect, buf, header_offset, header_size, data_offset);
+ sect_export_macho_header_32, sect_export_macho_header_64,
+ sect, buf, header_offset, header_size, data_offset);
require_noerr(rval, finish);
rval = export_macho(sect, buf, data_offset, data_size);
require_noerr(rval, finish);
-
+
rval = KERN_SUCCESS;
-
+
finish:
- return rval;
+ return rval;
}
/*******************************************************************************
check(sect);
check(buf);
-
+
if (!sect->data) {
rval = KERN_SUCCESS;
goto finish;
}
- /* Verify that the section is properly aligned */
-
- require_action(kxld_sect_align_address(sect, offset) == offset, finish,
- rval = KERN_FAILURE);
+ if (!isSplitKext) {
+ /* Verify that the section is properly aligned */
+ if (kxld_sect_align_address(sect, offset) != offset) {
+ kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
+ "Alignment error: %llu != %lu for %s %s <%s>",
+ kxld_sect_align_address(sect, offset), offset,
+ sect->segname, sect->sectname, __func__);
+ goto finish;
+ }
+ }
/* Verify that we have enough space to copy */
-
- require_action(sect->size <= bufsize - offset, finish,
- rval=KERN_FAILURE);
+ if (buf + offset + sect->size > buf + bufsize) {
+ kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
+ "Overflow: offset %lu + sect->size %llu > bufsize %lu for %s %s",
+ offset, sect->size, bufsize,
+ sect->segname, sect->sectname);
+ goto finish;
+ }
/* Copy section data */
-
switch (sect->flags & SECTION_TYPE) {
case S_NON_LAZY_SYMBOL_POINTERS:
case S_MOD_INIT_FUNC_POINTERS:
case S_COALESCED:
case S_16BYTE_LITERALS:
case S_SYMBOL_STUBS:
+#if SPLIT_KEXTS_DEBUG
+ kxld_log(kKxldLogLinking, kKxldLogErr,
+ " sectname %s copy from %p (sect->data) for %llu bytes (sect->size) to %p (buf %p + offset %lu <%s>",
+ sect->sectname[0] ? sect->sectname : "none",
+ (void *) sect->data,
+ sect->size,
+ (void *) (buf + offset),
+ (void *) buf,
+ offset,
+ __func__);
+
+ kxld_log(kKxldLogLinking, kKxldLogErr,
+ " %p >>> Start of %s section data (sect->size %llu) <%s>",
+ (void *) (buf + offset),
+ sect->sectname[0] ? sect->sectname : "none",
+ sect->size,
+ __func__);
+ kxld_log(kKxldLogLinking, kKxldLogErr,
+ " %p <<< End of %s section data <%s>",
+ (void *) (buf + offset + sect->size),
+ sect->sectname[0] ? sect->sectname : "none",
+ __func__);
+#endif
memcpy(buf + offset, sect->data, (size_t)sect->size);
break;
case S_ZEROFILL: /* sect->data should be NULL, so we'll never get here */
rval = KERN_SUCCESS;
finish:
- return rval;
+ return rval;
}
#if KXLD_USER_OR_ILP32
secthdr->reserved1 = sect->reserved1;
secthdr->reserved2 = sect->reserved2;
+#if SPLIT_KEXTS_DEBUG
+ {
+ kxld_log(kKxldLogLinking, kKxldLogErr,
+ "sectname %s secthdr: %p addr %p size %02X %u offset %02X %u <%s>",
+ sect->sectname[0] ? sect->sectname : "none",
+ (void *) secthdr,
+ (void *) ((uint64_t)secthdr->addr),
+ secthdr->size,
+ secthdr->size,
+ secthdr->offset,
+ secthdr->offset,
+ __func__);
+ }
+#endif
+
rval = KERN_SUCCESS;
finish:
check(buf);
check(header_offset);
+
require_action(sizeof(*secthdr) <= header_size - *header_offset, finish,
rval=KERN_FAILURE);
secthdr = (struct section_64 *) ((void *) (buf + *header_offset));
secthdr->reserved1 = sect->reserved1;
secthdr->reserved2 = sect->reserved2;
+#if SPLIT_KEXTS_DEBUG
+ kxld_log(kKxldLogLinking, kKxldLogErr,
+ " %p >>> Start of %s secthdr (size %lu) <%s>",
+ (void *) secthdr,
+ sect->sectname[0] ? sect->sectname : "none",
+ sizeof(*secthdr),
+ __func__);
+ kxld_log(kKxldLogLinking, kKxldLogErr,
+ " %p <<< End of %s secthdr <%s>",
+ (void *) ((u_char *)secthdr + sizeof(*secthdr)),
+ sect->sectname[0] ? sect->sectname : "none",
+ __func__);
+ kxld_log(kKxldLogLinking, kKxldLogErr,
+ " secthdr: addr %p size %llu offset %u sectname %s <%s>",
+ (void *) secthdr->addr,
+ secthdr->size,
+ secthdr->offset,
+ sect->sectname[0] ? sect->sectname : "none",
+ __func__);
+#endif
+
rval = KERN_SUCCESS;
finish:
void
kxld_sect_relocate(KXLDSect *sect, kxld_addr_t link_addr)
{
- sect->link_addr = kxld_sect_align_address(sect,
- sect->link_addr + link_addr);
+#if SPLIT_KEXTS_DEBUG
+ {
+ kxld_log(kKxldLogLinking, kKxldLogErr,
+ "%p >>> Start of %s section (sect->size %llu) <%s>",
+ (void *) (kxld_sect_align_address(sect, sect->link_addr + link_addr)),
+ sect->sectname[0] ? sect->sectname : "none",
+ sect->size,
+ __func__);
+ kxld_log(kKxldLogLinking, kKxldLogErr,
+ "%p <<< End of %s section <%s>",
+ (void *) (kxld_sect_align_address(sect, sect->link_addr + link_addr) + sect->size),
+ sect->sectname[0] ? sect->sectname : "none",
+ __func__);
+ }
+#endif
+
+ sect->link_addr = kxld_sect_align_address(sect,
+ sect->link_addr + link_addr);
}
#if KXLD_USER_OR_GOT