+
+/*
+ ocAllocateJumpIslands_MachO
+
+ Allocate additional space at the end of the object file image to make room
+ for jump islands.
+
+ PowerPC relative branch instructions have a 24 bit displacement field.
+ As PPC code is always 4-byte-aligned, this yields a +-32MB range.
+ If a particular imported symbol is outside this range, we have to redirect
+ the jump to a short piece of new code that just loads the 32bit absolute
+ address and jumps there.
+ This function just allocates space for one 16 byte jump island for every
+ undefined symbol in the object file. The code for the islands is filled in by
+ makeJumpIsland below.
+*/
+
+static const int islandSize = 16;
+
+static int ocAllocateJumpIslands_MachO(ObjectCode* oc)
+{
+ char *image = (char*) oc->image;
+ struct mach_header *header = (struct mach_header*) image;
+ struct load_command *lc = (struct load_command*) (image + sizeof(struct mach_header));
+ unsigned i;
+
+ for(i=0;i<header->ncmds;i++)
+ {
+ if(lc->cmd == LC_DYSYMTAB)
+ {
+ struct dysymtab_command *dsymLC = (struct dysymtab_command*) lc;
+ unsigned long nundefsym = dsymLC->nundefsym;
+ oc->island_start_symbol = dsymLC->iundefsym;
+ oc->n_islands = nundefsym;
+
+ if(nundefsym > 0)
+ {
+#ifdef USE_MMAP
+ #error ocAllocateJumpIslands_MachO doesnt want USE_MMAP to be defined
+#else
+ oc->image = stgReallocBytes(
+ image, oc->fileSize + islandSize * nundefsym,
+ "ocAllocateJumpIslands_MachO");
+#endif
+ oc->jump_islands = oc->image + oc->fileSize;
+ memset(oc->jump_islands, 0, islandSize * nundefsym);
+ }
+
+ break; // there can be only one LC_DSYMTAB
+ }
+ lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize );
+ }
+ return 1;
+}
+