Index: /trunk/source/lisp-kernel/lisp-debug.c
===================================================================
--- /trunk/source/lisp-kernel/lisp-debug.c	(revision 14589)
+++ /trunk/source/lisp-kernel/lisp-debug.c	(revision 14590)
@@ -886,15 +886,15 @@
             (cs_area->low), (cs_area->high));
     fprintf(dbgout, "Value (lisp) stack area: low = 0x" LISP ", high = 0x" LISP "\n",
-            (u64_t)(natural)(vs_area->low), (u64_t)(natural)vs_area->high);
+            (natural)(vs_area->low), (natural)vs_area->high);
     if (xp) {
       fprintf(dbgout, "Exception stack pointer = 0x" LISP "\n",
 #ifdef PPC
-              (u64_t) (natural)(xpGPR(xp,1))
+              (natural)(xpGPR(xp,1))
 #endif
 #ifdef X86
-              (u64_t) (natural)(xpGPR(xp,Isp))
+              (natural)(xpGPR(xp,Isp))
 #endif           
 #ifdef ARM
-              (u64_t) (natural)(xpGPR(xp,Rsp))
+              (natural)(xpGPR(xp,Rsp))
 #endif
               );
Index: /trunk/source/lisp-kernel/mach-o-image.c
===================================================================
--- /trunk/source/lisp-kernel/mach-o-image.c	(revision 14589)
+++ /trunk/source/lisp-kernel/mach-o-image.c	(revision 14590)
@@ -26,4 +26,5 @@
 typedef struct mach_header_64 macho_header;
 #define MACHO_MAGIC MH_MAGIC_64
+#define MACHO_LC_SEGMENT LC_SEGMENT_64
 typedef struct segment_command_64 macho_segment_command;
 typedef struct section_64 macho_section;
@@ -32,4 +33,5 @@
 typedef struct mach_header_64 macho_header;
 #define MACHO_MAGIC MH_MAGIC
+#define MACHO_LC_SEGMENT LC_SEGMENT
 typedef struct segment_command macho_segment_command;
 typedef struct section macho_section;
@@ -53,4 +55,10 @@
 macho_symbol_table *all_symbols, *local_symbols, *defined_external_symbols, *undefined_external_symbols;
 
+macho_section *
+nth_section_in_segment(macho_segment_command *segment, int sectno)
+{
+  return (macho_section *)(((char *)segment)+sizeof(macho_segment_command)+(sizeof(macho_section) *sectno));
+}
+
 ssize_t
 safe_read(int fd, char *buf, size_t nbytes)
@@ -71,4 +79,25 @@
     if (n == 0) {
       fprintf(stderr, "unexpected end of file reading image\n");
+      exit(1);
+    }
+    total += n;
+    buf += n;
+  }
+  return total;
+}
+
+ssize_t
+safe_write(int fd, char *buf, size_t nbytes)
+{
+  size_t total = 0;
+  ssize_t n;
+  while (total <  nbytes) {
+    n = nbytes-total;
+    if (n > INT_MAX) {
+      n = INT_MAX;
+    }
+    n = write(fd, buf, n);
+    if (n < 0) {
+      perror("writing to image");
       exit(1);
     }
@@ -216,2 +245,190 @@
 }
 
+void
+add_lisp_function_stab(LispObj f, natural size_in_bytes, macho_string_table *strings, macho_symbol_table *syms, int section_ordinal)
+{
+  macho_nlist symbol;
+  
+  symbol.n_type = N_BNSYM;
+  symbol.n_un.n_strx = 1;
+  symbol.n_sect = section_ordinal;
+  symbol.n_desc = 0;
+  symbol.n_value = f;
+  add_symbol(&symbol, syms);
+
+  symbol.n_type = N_FUN;
+  symbol.n_un.n_strx = save_string(print_lisp_object(f),strings);
+  symbol.n_sect = section_ordinal;
+  symbol.n_desc = 0;
+  symbol.n_value = f;
+  add_symbol(&symbol, syms);
+
+  symbol.n_type = N_FUN;
+  symbol.n_un.n_strx = 1;
+  symbol.n_sect = NO_SECT;
+  symbol.n_desc = 0;
+  symbol.n_value = size_in_bytes;
+  add_symbol(&symbol, syms);
+
+  symbol.n_type = N_ENSYM;
+  symbol.n_un.n_strx = 1;
+  symbol.n_sect = section_ordinal;
+  symbol.n_desc = 0;
+  symbol.n_value = size_in_bytes;
+  add_symbol(&symbol, syms);
+}
+
+#ifdef X86
+void
+add_lisp_function_stabs(macho_symbol_table *symbols, macho_string_table *strings, int section_ordinal)
+{
+  LispObj 
+    *start = (LispObj *) readonly_area->low,
+    *end = (LispObj *) readonly_area->active,
+    header,
+    f;
+  int tag;
+  natural size_in_bytes;
+
+  while (start < end) {
+    header = *start;
+    tag = header_subtag(header);
+    if (tag == subtag_function) {
+#ifdef X8632
+      f = ((LispObj)start)+fulltag_misc;
+      size_in_bytes = (header_element_count(header)<<node_shift)-tag_misc;
+#endif
+#ifdef X8664
+      f = ((LispObj)start)+fulltag_function;
+      size_in_bytes = (header_element_count(header)<<node_shift)-tag_function;
+#endif
+
+      add_lisp_function_stab(f,size_in_bytes,strings,symbols,section_ordinal);
+      start += ((header_element_count(header)+2)&~1);
+    } else {
+      start = (LispObj *)skip_over_ivector((LispObj)start,header);
+    }
+  }
+}
+#endif
+
+typedef struct {
+  char page[4096];
+  int used;
+  int load_command_offsets[16];
+} macho_prefix;
+
+macho_prefix *
+init_macho_prefix(uint32_t magic, cpu_type_t cputype, cpu_subtype_t cpusubtype, uint32_t filetype, uint32_t flags) {
+  macho_prefix *p = calloc(1,sizeof(macho_prefix));
+  macho_header *h = (macho_header *) p;
+
+  h->magic = magic;
+  h->cputype = cputype;
+  h->cpusubtype = cpusubtype;
+  h->filetype = filetype;
+  h->flags = flags;
+  p->used = sizeof(macho_header);
+  return p;
+}
+
+struct load_command *
+add_load_command(macho_prefix *p, uint32_t cmd, uint32_t cmdsize)
+{
+  struct load_command *l = (struct load_command *)&(p->page[p->used]);
+  macho_header *h = (macho_header *)p;
+
+  cmdsize = align_to_power_of_2(cmdsize,node_shift);
+  p->load_command_offsets[h->ncmds] = p->used;
+  p->used += cmdsize;
+  l->cmd = cmd;
+  l->cmdsize += cmdsize;
+  h->ncmds++;
+  h->sizeofcmds += cmdsize;
+  return l;
+}
+
+macho_segment_command *
+add_segment(macho_prefix *p,char *segname, int nsections, ...) /* sectnames */
+{
+  macho_segment_command *seg = (macho_segment_command *) add_load_command(p, MACHO_LC_SEGMENT, sizeof(macho_segment_command)+(nsections * sizeof(macho_section)));
+  macho_section *sect = nth_section_in_segment(seg, 0);
+  va_list sectnames;
+  char *sectname;
+  
+  seg->nsects = nsections;
+  strncpy(seg->segname,segname,sizeof(seg->segname));
+  va_start(sectnames,nsections);
+  while(nsections--) {
+    sectname = va_arg(sectnames,char *);
+    strncpy(sect->sectname,sectname,sizeof(sect->sectname));
+    strncpy(sect->segname,segname,sizeof(sect->segname));
+    sect++;
+  }
+  return seg;
+}
+
+    
+void
+save_native_library(int fd)
+{
+  macho_prefix *p = init_macho_prefix(MACHO_MAGIC,
+#ifdef X8632
+                                      CPU_TYPE_I386,
+                                      CPU_SUBTYPE_X86_ALL,
+#endif
+#ifdef X8664
+                                      CPU_TYPE_X86_64,
+                                      CPU_SUBTYPE_X86_64_ALL,
+#endif
+#ifdef PPC32
+                                      CPU_TYPE_POWERPC,
+                                      CPU_SUBTYPE_POWERPC_ALL,
+#endif
+#ifdef PPC64
+                                      CPU_TYPE_POWERPC64,
+                                      CPU_TYPE_POWERPC_ALL,
+#endif
+#ifdef ARM
+                                      CPU_TYPE_ARM,
+                                      CPU_SUBTYPE_ARM_ALL,
+#endif
+                                      MH_DYLIB,
+                                      MH_NOUNDEFS);
+  macho_segment_command *seg;
+  macho_section *sect;
+  off_t curpos = 4096;
+
+
+  seg = add_segment(p, "innocent", 1, "bystander");
+  seg->vmaddr = (natural)(readonly_area->low-4096);
+  seg->vmsize = 4096;
+  seg->fileoff = 0;
+  seg->filesize = 4096;
+  seg->maxprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
+  seg->initprot = VM_PROT_READ|VM_PROT_EXECUTE;
+  sect = nth_section_in_segment(seg,0);
+  sect->addr = (natural)(readonly_area->low-1);
+  sect->size = 1;
+  sect->offset = 4095;
+  sect->flags = S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
+  p->page[4095] = 0xcc;
+
+  seg = add_segment(p,"READONLY",1,"readonly");
+  seg->vmaddr = (natural)(readonly_area->low);
+  seg->vmsize = align_to_power_of_2(readonly_area->active-readonly_area->low,12);
+  seg->fileoff = curpos;
+  seg->filesize = seg->vmsize;
+  seg->maxprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
+  seg->initprot = VM_PROT_READ|VM_PROT_EXECUTE;
+  sect = nth_section_in_segment(seg,0);
+  sect->addr = (natural)(readonly_area->low);
+  sect->size = readonly_area->active-readonly_area->low;
+  sect->offset = seg->fileoff;
+  sect->flags = S_ATTR_SOME_INSTRUCTIONS;
+  lseek(fd,curpos,SEEK_SET);
+  safe_write(fd,readonly_area->low,seg->filesize);
+
+
+
+}
