Directly test section alignment, fix internal reloc probing length
[ghc.git] / rts / linker / MachO.c
1 #include "Rts.h"
2
3 #if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
4
5 #if defined(ios_HOST_OS) && !RTS_LINKER_USE_MMAP
6 #error "ios must use mmap and mprotect!"
7 #endif
8
9 /* for roundUpToPage */
10 #include "sm/OSMem.h"
11
12 #include "RtsUtils.h"
13 #include "GetEnv.h"
14 #include "LinkerInternals.h"
15 #include "linker/MachO.h"
16 #include "linker/CacheFlush.h"
17 #include "linker/SymbolExtras.h"
18
19 #include <string.h>
20 #include <regex.h>
21 #include <mach/machine.h>
22 #include <mach-o/fat.h>
23 #include <mach-o/loader.h>
24 #include <mach-o/nlist.h>
25 #include <mach-o/reloc.h>
26
27 #if defined(HAVE_SYS_MMAN_H) && RTS_LINKER_USE_MMAP
28 # include <sys/mman.h>
29 #endif
30
31 #if defined(x86_64_HOST_ARCH)
32 # include <mach-o/x86_64/reloc.h>
33 #endif
34
35 #if defined(aarch64_HOST_ARCH)
36 # include <mach-o/arm64/reloc.h>
37 #endif
38
39 /*
40 Support for MachO linking on Darwin/MacOS X
41 by Wolfgang Thaller (wolfgang.thaller@gmx.net)
42
43 I hereby formally apologize for the hackish nature of this code.
44 Things that need to be done:
45 *) implement ocVerifyImage_MachO
46 *) add still more sanity checks.
47 */
48 #if defined(aarch64_HOST_ARCH)
49 /* aarch64 linker by moritz angermann <moritz@lichtzwerge.de> */
50
51 /* often times we need to extend some value of certain number of bits
52 * int an int64_t for e.g. relative offsets.
53 */
54 int64_t signExtend(uint64_t val, uint8_t bits);
55 /* Helper functions to check some instruction properties */
56 bool isVectorPp(uint32_t *p);
57 bool isLoadStore(uint32_t *p);
58
59 /* aarch64 relocations may contain an addend alreay in the position
60 * where we want to write the address offset to. Thus decoding as well
61 * as encoding is needed.
62 */
63 bool fitsBits(size_t bits, int64_t value);
64 int64_t decodeAddend(ObjectCode * oc, Section * section,
65 MachORelocationInfo * ri);
66 void encodeAddend(ObjectCode * oc, Section * section,
67 MachORelocationInfo * ri, int64_t addend);
68
69 /* finding and making stubs. We don't need to care about the symbol they
70 * represent. As long as two stubs point to the same address, they are identical
71 */
72 bool findStub(Section * section, void ** addr);
73 bool makeStub(Section * section, void ** addr);
74 void freeStubs(Section * section);
75
76 /* Global Offset Table logic */
77 bool isGotLoad(MachORelocationInfo * ri);
78 bool needGotSlot(MachONList * symbol);
79 bool makeGot(ObjectCode * oc);
80 void freeGot(ObjectCode * oc);
81 #endif /* aarch64_HOST_ARCH */
82
83 #if defined(ios_HOST_OS)
84 /* on iOS we need to ensure we only have r+w or r+x pages hence we need to mmap
85 * pages r+w and r+x mprotect them later on.
86 */
87 bool ocMprotect_MachO( ObjectCode *oc );
88 #endif /* ios_HOST_OS */
89
90 /*
91 * Initialize some common data in the object code so we don't have to
92 * continuously look up the addresses.
93 */
94 void
95 ocInit_MachO(ObjectCode * oc)
96 {
97 ocDeinit_MachO(oc);
98
99 oc->info = (struct ObjectCodeFormatInfo*)stgCallocBytes(
100 1, sizeof *oc->info,
101 "ocInit_MachO(ObjectCodeFormatInfo)");
102 oc->info->header = (MachOHeader *) oc->image;
103 oc->info->symCmd = NULL;
104 oc->info->segCmd = NULL;
105 oc->info->dsymCmd = NULL;
106
107 MachOLoadCommand *lc = (MachOLoadCommand*)(oc->image + sizeof(MachOHeader));
108 for(size_t i = 0; i < oc->info->header->ncmds; i++) {
109 if (lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64) {
110 oc->info->segCmd = (MachOSegmentCommand*) lc;
111 }
112 else if (lc->cmd == LC_SYMTAB) {
113 oc->info->symCmd = (MachOSymtabCommand*) lc;
114 }
115 else if (lc->cmd == LC_DYSYMTAB) {
116 oc->info->dsymCmd = (MachODsymtabCommand*) lc;
117 }
118 lc = (MachOLoadCommand *) ( ((char*)lc) + lc->cmdsize );
119 }
120 if (NULL == oc->info->segCmd) {
121 barf("ocGetNames_MachO: no segment load command");
122 }
123
124 oc->info->macho_sections = (MachOSection*) (oc->info->segCmd+1);
125 oc->n_sections = oc->info->segCmd->nsects;
126
127 oc->info->nlist = oc->info->symCmd == NULL
128 ? NULL
129 : (MachONList *)(oc->image + oc->info->symCmd->symoff);
130 oc->info->names = oc->info->symCmd == NULL
131 ? NULL
132 : (oc->image + oc->info->symCmd->stroff);
133
134 /* If we have symbols, allocate and fill the macho_symbols
135 * This will make relocation easier.
136 */
137 oc->info->n_macho_symbols = 0;
138 oc->info->macho_symbols = NULL;
139
140 if(NULL != oc->info->nlist) {
141 oc->info->n_macho_symbols = oc->info->symCmd->nsyms;
142 oc->info->macho_symbols = (MachOSymbol*)stgCallocBytes(
143 oc->info->symCmd->nsyms,
144 sizeof(MachOSymbol),
145 "ocInit_MachO(MachOSymbol)");
146 for(uint32_t i = 0; i < oc->info->symCmd->nsyms; i++) {
147 oc->info->macho_symbols[i].name = oc->info->names
148 + oc->info->nlist[i].n_un.n_strx;
149 oc->info->macho_symbols[i].nlist = &oc->info->nlist[i];
150 /* We don't have an address for this symbol yet; this
151 * will be populated during ocGetNames_MachO. Hence init
152 * with NULL
153 */
154 oc->info->macho_symbols[i].addr = NULL;
155 oc->info->macho_symbols[i].got_addr = NULL;
156 }
157 }
158 }
159
160 void
161 ocDeinit_MachO(ObjectCode * oc) {
162 if (oc->info != NULL) {
163 if(oc->info->n_macho_symbols > 0) {
164 stgFree(oc->info->macho_symbols);
165 }
166 #if defined(aarch64_HOST_ARCH)
167 freeGot(oc);
168 for(int i = 0; i < oc->n_sections; i++) {
169 freeStubs(&oc->sections[i]);
170 }
171 #endif
172 stgFree(oc->info);
173 oc->info = NULL;
174 }
175 }
176
177 static int
178 resolveImports(
179 ObjectCode* oc,
180 MachOSection *sect, // ptr to lazy or non-lazy symbol pointer section
181 unsigned long *indirectSyms);
182
183 #if NEED_SYMBOL_EXTRAS
184 #if defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH)
185
186 int
187 ocAllocateExtras_MachO(ObjectCode* oc)
188 {
189 IF_DEBUG(linker, debugBelch("ocAllocateExtras_MachO: start\n"));
190
191 if (NULL != oc->info->symCmd) {
192 IF_DEBUG(linker,
193 debugBelch("ocAllocateExtras_MachO: allocate %d symbols\n",
194 oc->info->symCmd->nsyms));
195 IF_DEBUG(linker, debugBelch("ocAllocateExtras_MachO: done\n"));
196 return ocAllocateExtras(oc, oc->info->symCmd->nsyms, 0, 0);
197 }
198
199 IF_DEBUG(linker,
200 debugBelch("ocAllocateExtras_MachO: allocated no symbols\n"));
201 IF_DEBUG(linker, debugBelch("ocAllocateExtras_MachO: done\n"));
202 return ocAllocateExtras(oc, 0, 0, 0);
203 }
204
205 #else
206 #error Unknown MachO architecture
207 #endif /* HOST_ARCH */
208 #endif /* NEED_SYMBOL_EXTRAS */
209
210 int
211 ocVerifyImage_MachO(ObjectCode * oc)
212 {
213 char *image = (char*) oc->image;
214 MachOHeader *header = (MachOHeader*) image;
215
216 IF_DEBUG(linker, debugBelch("ocVerifyImage_MachO: start\n"));
217
218 if(header->magic != MH_MAGIC_64) {
219 errorBelch("Could not load image %s: bad magic!\n"
220 " Expected %08x (64bit), got %08x%s\n",
221 oc->fileName, MH_MAGIC_64, header->magic,
222 header->magic == MH_MAGIC ? " (32bit)." : ".");
223 return 0;
224 }
225
226 // FIXME: do some more verifying here
227 IF_DEBUG(linker, debugBelch("ocVerifyImage_MachO: done\n"));
228 return 1;
229 }
230
231 static int
232 resolveImports(
233 ObjectCode* oc,
234 MachOSection *sect, // ptr to lazy or non-lazy symbol pointer section
235 unsigned long *indirectSyms)
236 {
237 size_t itemSize = 4;
238
239 IF_DEBUG(linker, debugBelch("resolveImports: start\n"));
240
241 for(unsigned i = 0; i * itemSize < sect->size; i++)
242 {
243 // according to otool, reserved1 contains the first index into the
244 // indirect symbol table
245 unsigned long indirectSymbolIndex = indirectSyms[sect->reserved1+i];
246 MachOSymbol *symbol = &oc->info->macho_symbols[indirectSymbolIndex];
247 SymbolAddr* addr = NULL;
248
249 IF_DEBUG(linker, debugBelch("resolveImports: resolving %s\n", symbol->name));
250
251 if ((symbol->nlist->n_type & N_TYPE) == N_UNDF
252 && (symbol->nlist->n_type & N_EXT) && (symbol->nlist->n_value != 0)) {
253 addr = (SymbolAddr*) (symbol->nlist->n_value);
254 IF_DEBUG(linker, debugBelch("resolveImports: undefined external %s has value %p\n", symbol->name, addr));
255 } else {
256 addr = lookupSymbol_(symbol->name);
257 IF_DEBUG(linker, debugBelch("resolveImports: looking up %s, %p\n", symbol->name, addr));
258 }
259
260 if (addr == NULL)
261 {
262 errorBelch("\nlookupSymbol failed in resolveImports\n"
263 "%s: unknown symbol `%s'", oc->fileName, symbol->name);
264 return 0;
265 }
266 ASSERT(addr);
267
268 checkProddableBlock(oc,
269 ((void**)(oc->image + sect->offset)) + i,
270 sizeof(void *));
271 ((void**)(oc->image + sect->offset))[i] = addr;
272 }
273
274 IF_DEBUG(linker, debugBelch("resolveImports: done\n"));
275 return 1;
276 }
277
278 #if defined(aarch64_HOST_ARCH)
279 /* aarch64 linker by moritz angermann <moritz@lichtzwerge.de> */
280
281 int64_t
282 signExtend(uint64_t val, uint8_t bits) {
283 return (int64_t)(val << (64-bits)) >> (64-bits);
284 }
285
286 bool
287 isVectorOp(uint32_t *p) {
288 return (*p & 0x04800000) == 0x04800000;
289 }
290
291 bool
292 isLoadStore(uint32_t *p) {
293 return (*p & 0x3B000000) == 0x39000000;
294 }
295
296 int64_t
297 decodeAddend(ObjectCode * oc, Section * section, MachORelocationInfo * ri) {
298
299 /* the instruction. It is 32bit wide */
300 uint32_t * p = (uint32_t*)((uint8_t*)section->start + ri->r_address);
301
302 checkProddableBlock(oc, (void*)p, 1 << ri->r_length);
303
304 switch(ri->r_type) {
305 case ARM64_RELOC_UNSIGNED:
306 case ARM64_RELOC_SUBTRACTOR: {
307 switch (ri->r_length) {
308 case 0: return signExtend(*(uint8_t*)p, 8 * (1 << ri->r_length));
309 case 1: return signExtend(*(uint16_t*)p, 8 * (1 << ri->r_length));
310 case 2: return signExtend(*(uint32_t*)p, 8 * (1 << ri->r_length));
311 case 3: return signExtend(*(uint64_t*)p, 8 * (1 << ri->r_length));
312 default:
313 barf("Unsupported r_length (%d) for SUBTRACTOR relocation",
314 ri->r_length);
315 }
316 }
317 case ARM64_RELOC_BRANCH26:
318 /* take the lower 26 bits and shift them by 2. The last two are
319 * implicilty 0 (as the instructions must be aligned!) and sign
320 * extend to 64 bits.
321 */
322 return signExtend( (*p & 0x03FFFFFF) << 2, 28 );
323 case ARM64_RELOC_PAGE21:
324 case ARM64_RELOC_GOT_LOAD_PAGE21:
325 /* take the instruction bits masked with 0x6 (0110), and push them
326 * down. into the last two bits, and mask in the
327 *
328 * the 21 bits are encoded as follows in the instruction
329 *
330 * -**- ---* **** **** **** **** ***-- ----
331 * ^^
332 * ''-- these are the low two bits.
333 */
334 return signExtend( (*p & 0x60000000) >> 29
335 | ((*p & 0x01FFFFE0) >> 3) << 12, 33);
336 case ARM64_RELOC_PAGEOFF12:
337 case ARM64_RELOC_GOT_LOAD_PAGEOFF12: {
338 /* the 12 bits for the page offset are encoded from bit 11 onwards
339 *
340 * ---- ---- --** **** **** **-- ---- ----
341 */
342 int64_t a = (*p & 0x003FFC00) >> 10;
343 int shift = 0;
344 if (isLoadStore(p)) {
345 shift = (*p >> 30) & 0x3;
346 if(0 == shift && isVectorOp(p)) {
347 shift = 4;
348 }
349 }
350 return a << shift;
351 }
352 }
353 barf("unsupported relocation type: %d\n", ri->r_type);
354 }
355
356 inline bool
357 fitsBits(size_t bits, int64_t value) {
358 if(bits == 64) return true;
359 if(bits > 64) barf("fits_bits with %d bits and an 64bit integer!", bits);
360 return 0 == (value >> bits) // All bits off: 0
361 || -1 == (value >> bits); // All bits on: -1
362 }
363
364 void
365 encodeAddend(ObjectCode * oc, Section * section,
366 MachORelocationInfo * ri, int64_t addend) {
367 uint32_t * p = (uint32_t*)((uint8_t*)section->start + ri->r_address);
368
369 checkProddableBlock(oc, (void*)p, 1 << ri->r_length);
370
371 switch (ri->r_type) {
372 case ARM64_RELOC_UNSIGNED:
373 case ARM64_RELOC_SUBTRACTOR: {
374 if(!fitsBits(8 << ri->r_length, addend))
375 barf("Relocation out of range for UNSIGNED/SUBTRACTOR");
376 switch (ri->r_length) {
377 case 0: *(uint8_t*)p = (uint8_t)addend; break;
378 case 1: *(uint16_t*)p = (uint16_t)addend; break;
379 case 2: *(uint32_t*)p = (uint32_t)addend; break;
380 case 3: *(uint64_t*)p = (uint64_t)addend; break;
381 default:
382 barf("Unsupported r_length (%d) for SUBTRACTOR relocation",
383 ri->r_length);
384 }
385 return;
386 }
387 case ARM64_RELOC_BRANCH26: {
388 /* We can only store 26 bits in the instruction, due to alignment we
389 * do not need the last two bits of the value. If the value >> 2
390 * still exceeds 26bits, we won't be able to reach it.
391 */
392 if(!fitsBits(26, addend >> 2))
393 barf("Relocation target for BRACH26 out of range.");
394 *p = (*p & 0xFC000000) | ((uint32_t)(addend >> 2) & 0x03FFFFFF);
395 return;
396 }
397 case ARM64_RELOC_PAGE21:
398 case ARM64_RELOC_GOT_LOAD_PAGE21: {
399 /* We store 21bits, in bits 6 to 24, and bits 30 and 31.
400 * The encoded value describes a multiple of 4k pages, and together
401 * with the PAGEOFF12 relocation allows to address a relative range
402 * of +-4GB.
403 */
404 if(!fitsBits(21, addend >> 12))
405 barf("Relocation target for PAGE21 out of range.");
406 *p = (*p & 0x9F00001F) | (uint32_t)((addend << 17) & 0x60000000)
407 | (uint32_t)((addend >> 9) & 0x00FFFFE0);
408 return;
409 }
410 case ARM64_RELOC_PAGEOFF12:
411 case ARM64_RELOC_GOT_LOAD_PAGEOFF12: {
412 /* Store an offset into a page (4k). Depending on the instruction
413 * the bits are stored at slightly different positions.
414 */
415 if(!fitsBits(12, addend))
416 barf("Relocation target for PAGEOFF12 out or range.");
417
418 int shift = 0;
419 if(isLoadStore(p)) {
420 shift = (*p >> 30) & 0x3;
421 if(0 == shift && isVectorOp(p)) {
422 shift = 4;
423 }
424 }
425 *p = (*p & 0xFFC003FF)
426 | ((uint32_t)(addend >> shift << 10) & 0x003FFC00);
427 return;
428 }
429 }
430 barf("unsupported relocation type: %d\n", ri->r_type);
431 }
432
433 bool
434 isGotLoad(struct relocation_info * ri) {
435 return ri->r_type == ARM64_RELOC_GOT_LOAD_PAGE21
436 || ri->r_type == ARM64_RELOC_GOT_LOAD_PAGEOFF12;
437 }
438
439 /* This is very similar to makeSymbolExtra
440 * However, as we load sections into different
441 * pages, that may be further appart than
442 * branching allows, we'll use some extra
443 * space at the end of each section allocated
444 * for stubs.
445 */
446 bool
447 findStub(Section * section, void ** addr) {
448
449 for(Stub * s = section->info->stubs; s != NULL; s = s->next) {
450 if(s->target == *addr) {
451 *addr = s->addr;
452 return EXIT_SUCCESS;
453 }
454 }
455 return EXIT_FAILURE;
456 }
457
458 bool
459 makeStub(Section * section, void ** addr) {
460
461 Stub * s = stgCallocBytes(1, sizeof(Stub), "makeStub(Stub)");
462 s->target = *addr;
463 s->addr = (uint8_t*)section->info->stub_offset
464 + ((8+8)*section->info->nstubs) + 8;
465 s->next = NULL;
466
467 /* target address */
468 *(uint64_t*)((uint8_t*)s->addr - 8) = (uint64_t)s->target;
469 /* ldr x16, - (8 bytes) */
470 *(uint32_t*)(s->addr) = (uint32_t)0x58ffffd0;
471 /* br x16 */
472 *(uint32_t*)((uint8_t*)s->addr + 4) = (uint32_t)0xd61f0200;
473
474 if(section->info->nstubs == 0) {
475 /* no stubs yet, let's just create this one */
476 section->info->stubs = s;
477 } else {
478 Stub * tail = section->info->stubs;
479 while(tail->next != NULL) tail = tail->next;
480 tail->next = s;
481 }
482 section->info->nstubs += 1;
483 *addr = s->addr;
484 return EXIT_SUCCESS;
485 }
486 void
487 freeStubs(Section * section) {
488 if(section->info->nstubs == 0)
489 return;
490 Stub * last = section->info->stubs;
491 while(last->next != NULL) {
492 Stub * t = last;
493 last = last->next;
494 stgFree(t);
495 }
496 section->info->stubs = NULL;
497 section->info->nstubs = 0;
498 }
499
500 /*
501 * Check if we need a global offset table slot for a
502 * given symbol
503 */
504 bool
505 needGotSlot(MachONList * symbol) {
506 return (symbol->n_type & N_EXT) /* is an external symbol */
507 && (N_UNDF == (symbol->n_type & N_TYPE) /* and is undefined */
508 || NO_SECT != symbol->n_sect); /* or is defined in a
509 * different section */
510 }
511
512 bool
513 makeGot(ObjectCode * oc) {
514 size_t got_slots = 0;
515
516 for(size_t i=0; i < oc->info->n_macho_symbols; i++)
517 if(needGotSlot(oc->info->macho_symbols[i].nlist))
518 got_slots += 1;
519
520 if(got_slots > 0) {
521 oc->info->got_size = got_slots * sizeof(void*);
522 oc->info->got_start = mmap(NULL, oc->info->got_size,
523 PROT_READ | PROT_WRITE,
524 MAP_ANON | MAP_PRIVATE,
525 -1, 0);
526 if( oc->info->got_start == MAP_FAILED ) {
527 barf("MAP_FAILED. errno=%d", errno );
528 return EXIT_FAILURE;
529 }
530 /* update got_addr */
531 size_t slot = 0;
532 for(size_t i=0; i < oc->info->n_macho_symbols; i++)
533 if(needGotSlot(oc->info->macho_symbols[i].nlist))
534 oc->info->macho_symbols[i].got_addr
535 = ((uint8_t*)oc->info->got_start)
536 + (slot++ * sizeof(void *));
537 }
538 return EXIT_SUCCESS;
539 }
540
541 void
542 freeGot(ObjectCode * oc) {
543 munmap(oc->info->got_start, oc->info->got_size);
544 oc->info->got_start = NULL;
545 oc->info->got_size = 0;
546 }
547
548 static int
549 relocateSectionAarch64(ObjectCode * oc, Section * section)
550 {
551 if(section->size == 0)
552 return 1;
553 /* at this point, we have:
554 *
555 * - loaded the sections (potentially into non-contiguous memory),
556 * (in ocGetNames_MachO)
557 * - registered exported sybmols
558 * (in ocGetNames_MachO)
559 * - and fixed the nlist[i].n_value for common storage symbols (N_UNDF,
560 * N_EXT and n_value != 0) so that they point into the common storage.
561 * (in ocGetNames_MachO)
562 * - All oc->symbols however should now point at the right place.
563 */
564
565 /* we need to care about the explicit addend */
566 int64_t explicit_addend = 0;
567 size_t nreloc = section->info->macho_section->nreloc;
568
569 for(size_t i = 0; i < nreloc; i++) {
570 MachORelocationInfo * ri = &section->info->relocation_info[i];
571 switch (ri->r_type) {
572 case ARM64_RELOC_UNSIGNED: {
573 MachOSymbol* symbol = &oc->info->macho_symbols[ri->r_symbolnum];
574 int64_t addend = decodeAddend(oc, section, ri);
575 uint64_t value = 0;
576 if(symbol->nlist->n_type & N_EXT) {
577 /* external symbols should be able to be
578 * looked up via the lookupSymbol_ function.
579 * Either through the global symbol hashmap
580 * or asking the system, if not found
581 * in the symbol hashmap
582 */
583 value = (uint64_t)lookupSymbol_((char*)symbol->name);
584 if(!value)
585 barf("Could not lookup symbol: %s!", symbol->name);
586 } else {
587 value = (uint64_t)symbol->addr; // address of the symbol.
588 }
589 encodeAddend(oc, section, ri, value + addend);
590 break;
591 }
592 case ARM64_RELOC_SUBTRACTOR:
593 {
594 MachOSymbol* symbol = &oc->info->macho_symbols[ri->r_symbolnum];
595 // subtractor and unsigned are called in tandem:
596 // first pc <- pc - symbol address (SUBTRACTOR)
597 // second pc <- pc + symbol address (UNSIGNED)
598 // to achieve pc <- pc + target - base.
599 //
600 // the current implementation uses absolute addresses,
601 // which is simpler than trying to do this section
602 // relative, but could more easily lead to overflow.
603 //
604 if(!(i+1 < nreloc)
605 || !(section->info->relocation_info[i+1].r_type
606 == ARM64_RELOC_UNSIGNED))
607 barf("SUBTRACTOR relocation *must* be followed by UNSIGNED relocation.");
608
609 int64_t addend = decodeAddend(oc, section, ri);
610 int64_t value = (uint64_t)symbol->addr;
611 encodeAddend(oc, section, ri, addend - value);
612 break;
613 }
614 case ARM64_RELOC_BRANCH26: {
615 MachOSymbol* symbol = &oc->info->macho_symbols[ri->r_symbolnum];
616
617 // pre-existing addend
618 int64_t addend = decodeAddend(oc, section, ri);
619 // address of the branch (b/bl) instruction.
620 uint64_t pc = (uint64_t)section->start + ri->r_address;
621 uint64_t value = 0;
622 if(symbol->nlist->n_type & N_EXT) {
623 value = (uint64_t)lookupSymbol_((char*)symbol->name);
624 if(!value)
625 barf("Could not lookup symbol: %s!", symbol->name);
626 } else {
627 value = (uint64_t)symbol->addr; // address of the symbol.
628 }
629 if((value - pc + addend) >> (2 + 26)) {
630 /* we need a stub */
631 /* check if we already have that stub */
632 if(findStub(section, (void**)&value)) {
633 /* did not find it. Crete a new stub. */
634 if(makeStub(section, (void**)&value)) {
635 barf("could not find or make stub");
636 }
637 }
638 }
639 encodeAddend(oc, section, ri, value - pc + addend);
640 break;
641 }
642 case ARM64_RELOC_PAGE21:
643 case ARM64_RELOC_GOT_LOAD_PAGE21: {
644 MachOSymbol* symbol = &oc->info->macho_symbols[ri->r_symbolnum];
645 int64_t addend = decodeAddend(oc, section, ri);
646 if(!(explicit_addend == 0 || addend == 0))
647 barf("explicit_addend and addend can't be set at the same time.");
648 uint64_t pc = (uint64_t)section->start + ri->r_address;
649 uint64_t value = (uint64_t)(isGotLoad(ri) ? symbol->got_addr : symbol->addr);
650 encodeAddend(oc, section, ri, ((value + addend + explicit_addend) & (-4096)) - (pc & (-4096)));
651
652 // reset, just in case.
653 explicit_addend = 0;
654 break;
655 }
656 case ARM64_RELOC_PAGEOFF12:
657 case ARM64_RELOC_GOT_LOAD_PAGEOFF12: {
658 MachOSymbol* symbol = &oc->info->macho_symbols[ri->r_symbolnum];
659 int64_t addend = decodeAddend(oc, section, ri);
660 if(!(explicit_addend == 0 || addend == 0))
661 barf("explicit_addend and addend can't be set at the same time.");
662 uint64_t value = (uint64_t)(isGotLoad(ri) ? symbol->got_addr : symbol->addr);
663 encodeAddend(oc, section, ri, 0xFFF & (value + addend + explicit_addend));
664
665 // reset, just in case.
666 explicit_addend = 0;
667 break;
668 }
669 case ARM64_RELOC_ADDEND: {
670 explicit_addend = signExtend(ri->r_symbolnum, 24);
671 if(!(i+1 < nreloc)
672 || !(section->info->relocation_info[i+1].r_type == ARM64_RELOC_PAGE21
673 || section->info->relocation_info[i+1].r_type == ARM64_RELOC_PAGEOFF12))
674 barf("ADDEND relocation *must* be followed by PAGE or PAGEOFF relocation");
675 break;
676 }
677 default: {
678 barf("Relocation of type: %d not (yet) supported!\n", ri->r_type);
679 }
680 }
681 }
682 return 1;
683 }
684 #endif /* aarch64_HOST_ARCH */
685
686 #if defined(x86_64_HOST_ARCH)
687 static int
688 relocateSection(ObjectCode* oc, int curSection)
689 {
690 Section * sect = &oc->sections[curSection];
691 MachOSection * msect = sect->info->macho_section; // for access convenience
692 MachORelocationInfo * relocs = sect->info->relocation_info;
693 MachOSymbol * symbols = oc->info->macho_symbols;
694
695 IF_DEBUG(linker, debugBelch("relocateSection %d (%s, %s): start\n",
696 curSection, msect->segname, msect->sectname));
697
698 if(!strcmp(msect->sectname,"__la_symbol_ptr"))
699 return 1;
700 else if(!strcmp(msect->sectname,"__nl_symbol_ptr"))
701 return 1;
702 else if(!strcmp(msect->sectname,"__la_sym_ptr2"))
703 return 1;
704 else if(!strcmp(msect->sectname,"__la_sym_ptr3"))
705 return 1;
706
707 IF_DEBUG(linker, debugBelch("relocateSection: number of relocations: %d\n", msect->nreloc));
708
709 for(uint32_t i = 0; i < msect->nreloc; i++)
710 {
711 MachORelocationInfo *reloc = &relocs[i];
712
713 char *thingPtr = (char *) sect->start + reloc->r_address;
714 uint64_t thing;
715 /* We shouldn't need to initialise this, but gcc on OS X 64 bit
716 complains that it may be used uninitialized if we don't */
717 uint64_t value = 0;
718 uint64_t baseValue;
719 int type = reloc->r_type;
720 int relocLenBytes;
721 int nextInstrAdj = 0;
722
723 IF_DEBUG(linker, debugBelch("relocateSection: relocation %d\n", i));
724 IF_DEBUG(linker, debugBelch(" : type = %d\n", reloc->r_type));
725 IF_DEBUG(linker, debugBelch(" : address = %d\n", reloc->r_address));
726 IF_DEBUG(linker, debugBelch(" : symbolnum = %u\n", reloc->r_symbolnum));
727 IF_DEBUG(linker, debugBelch(" : pcrel = %d\n", reloc->r_pcrel));
728 IF_DEBUG(linker, debugBelch(" : length = %d\n", reloc->r_length));
729 IF_DEBUG(linker, debugBelch(" : extern = %d\n", reloc->r_extern));
730 IF_DEBUG(linker, debugBelch(" : type = %d\n", reloc->r_type));
731
732 switch(reloc->r_length)
733 {
734 case 0:
735 thing = *(uint8_t*)thingPtr;
736 relocLenBytes = 1;
737 break;
738 case 1:
739 thing = *(uint16_t*)thingPtr;
740 relocLenBytes = 2;
741 break;
742 case 2:
743 thing = *(uint32_t*)thingPtr;
744 relocLenBytes = 4;
745 break;
746 case 3:
747 thing = *(uint64_t*)thingPtr;
748 relocLenBytes = 8;
749 break;
750 default:
751 barf("Unknown size.");
752 }
753 checkProddableBlock(oc,thingPtr,relocLenBytes);
754
755 /*
756 * With SIGNED_N the relocation is not at the end of the
757 * instruction and baseValue needs to be adjusted accordingly.
758 */
759 switch (type) {
760 case X86_64_RELOC_SIGNED_1:
761 nextInstrAdj = 1;
762 break;
763 case X86_64_RELOC_SIGNED_2:
764 nextInstrAdj = 2;
765 break;
766 case X86_64_RELOC_SIGNED_4:
767 nextInstrAdj = 4;
768 break;
769 }
770 baseValue = (uint64_t)thingPtr + relocLenBytes + nextInstrAdj;
771
772
773
774 IF_DEBUG(linker,
775 debugBelch("relocateSection: length = %d, thing = %" PRId64 ", baseValue = %p\n",
776 reloc->r_length, thing, (char *)baseValue));
777
778 if (type == X86_64_RELOC_GOT
779 || type == X86_64_RELOC_GOT_LOAD)
780 {
781 MachOSymbol *symbol = &symbols[reloc->r_symbolnum];
782 SymbolName* nm = symbol->name;
783 SymbolAddr* addr = NULL;
784
785 IF_DEBUG(linker, debugBelch("relocateSection: making jump island for %s, extern = %d, X86_64_RELOC_GOT\n",
786 nm, reloc->r_extern));
787
788 if (reloc->r_extern == 0) {
789 errorBelch("\nrelocateSection: global offset table relocation for symbol with r_extern == 0\n");
790 }
791
792 if (symbol->nlist->n_type & N_EXT) {
793 // The external bit is set, meaning the symbol is exported,
794 // and therefore can be looked up in this object module's
795 // symtab, or it is undefined, meaning dlsym must be used
796 // to resolve it.
797
798 addr = lookupSymbol_(nm);
799 IF_DEBUG(linker, debugBelch("relocateSection: looked up %s, "
800 "external X86_64_RELOC_GOT or X86_64_RELOC_GOT_LOAD\n"
801 " : addr = %p\n", nm, addr));
802
803 if (addr == NULL) {
804 errorBelch("\nlookupSymbol failed in relocateSection (RELOC_GOT)\n"
805 "%s: unknown symbol `%s'", oc->fileName, nm);
806 return 0;
807 }
808 } else {
809 IF_DEBUG(linker, debugBelch("relocateSection: %s is not an exported symbol\n", nm));
810
811 // The symbol is not exported, or defined in another
812 // module, so it must be in the current object module,
813 // at the location given by the section index and
814 // symbol address (symbol->n_value)
815
816 if ((symbol->nlist->n_type & N_TYPE) == N_SECT) {
817 ASSERT(symbol->addr != NULL);
818 addr = symbol->addr;
819
820 IF_DEBUG(linker, debugBelch("relocateSection: calculated relocation of "
821 "non-external X86_64_RELOC_GOT or X86_64_RELOC_GOT_LOAD\n"));
822 IF_DEBUG(linker, debugBelch(" : addr = %p\n", addr));
823 } else {
824 errorBelch("\nrelocateSection: %s is not exported,"
825 " and should be defined in a section, but isn't!\n", nm);
826 }
827 }
828
829 // creates a jump island for every relocation entry for a symbol
830 // TODO (AP): use got_addr to store the loc. of a jump island to reuse later
831 value = (uint64_t) &makeSymbolExtra(oc, reloc->r_symbolnum, (unsigned long)addr)->addr;
832
833 type = X86_64_RELOC_SIGNED;
834 }
835 else if (reloc->r_extern)
836 {
837 MachOSymbol *symbol = &symbols[reloc->r_symbolnum];
838 SymbolName* nm = symbol->name;
839 SymbolAddr* addr = NULL;
840
841 IF_DEBUG(linker, debugBelch("relocateSection: looking up external symbol %s\n", nm));
842 IF_DEBUG(linker, debugBelch(" : type = %d\n", symbol->nlist->n_type));
843 IF_DEBUG(linker, debugBelch(" : sect = %d\n", symbol->nlist->n_sect));
844 IF_DEBUG(linker, debugBelch(" : desc = %d\n", symbol->nlist->n_desc));
845 IF_DEBUG(linker, debugBelch(" : value = %p\n", (void *)symbol->nlist->n_value));
846
847 if ((symbol->nlist->n_type & N_TYPE) == N_SECT) {
848 ASSERT(symbol->addr != NULL);
849 value = (uint64_t) symbol->addr;
850 IF_DEBUG(linker, debugBelch("relocateSection, defined external symbol %s, relocated address %p\n",
851 nm, (void *)value));
852 }
853 else {
854 addr = lookupSymbol_(nm);
855 if (addr == NULL)
856 {
857 errorBelch("\nlookupSymbol failed in relocateSection (relocate external)\n"
858 "%s: unknown symbol `%s'", oc->fileName, nm);
859 return 0;
860 }
861
862 value = (uint64_t) addr;
863 IF_DEBUG(linker, debugBelch("relocateSection: external symbol %s, address %p\n", nm, (void *)value));
864 }
865 }
866 else
867 {
868 /* Since the relocation is internal, r_symbolnum contains a section
869 * number relative to which the relocation is. Depending on whether
870 * the relocation is unsigned or signed, the given displacement is
871 * relative to the image or the section respectively.
872 *
873 * For instance, in a signed case:
874 * thing = <displ. to to section r_symbolnum *in the image*> (1)
875 * + <offset within r_symbolnum section>
876 * (1) needs to be updated due to different section placement in memory.
877 */
878
879 CHECKM(reloc->r_symbolnum > 0,
880 "relocateSection: unsupported r_symbolnum = %" PRIu32 " < 1 for internal relocation",
881 reloc->r_symbolnum);
882
883 int targetSecNum = reloc->r_symbolnum - 1; // sec numbers start with 1
884 Section * targetSec = &oc->sections[targetSecNum];
885 MachOSection * targetMacho = targetSec->info->macho_section;
886
887 IF_DEBUG(linker,
888 debugBelch("relocateSection: internal relocation relative to section %d (%s, %s)\n",
889 targetSecNum, targetMacho->segname, targetMacho->sectname));
890
891 switch (type) {
892 case X86_64_RELOC_UNSIGNED: {
893 CHECKM(thing >= targetMacho->addr,
894 "relocateSection: unsigned displacement %" PRIx64 "before target section start address %" PRIx64 "\n",
895 thing, (uint64_t) targetMacho->addr);
896
897 uint64_t thingRelativeOffset = thing - targetMacho->addr;
898 IF_DEBUG(linker, debugBelch(" "
899 "unsigned displacement %" PRIx64 " with section relative offset %" PRIx64 "\n",
900 thing, thingRelativeOffset));
901
902 thing = (uint64_t) targetSec->start + thingRelativeOffset;
903 IF_DEBUG(linker, debugBelch(" "
904 "relocated address is %p\n", (void *) thing));
905
906 /* Compared to external relocation we don't need to adjust value
907 * any further since thing already has absolute address.
908 */
909 value = 0;
910 break;
911 }
912 case X86_64_RELOC_SIGNED:
913 case X86_64_RELOC_SIGNED_1:
914 case X86_64_RELOC_SIGNED_2:
915 case X86_64_RELOC_SIGNED_4: {
916 uint32_t baseValueOffset = reloc->r_address + relocLenBytes + nextInstrAdj;
917 uint64_t imThingLoc = msect->addr + baseValueOffset + (int64_t) thing;
918
919 CHECKM(imThingLoc >= targetMacho->addr,
920 "relocateSection: target location %p in image before target section start address %p\n",
921 (void *) imThingLoc, (void *) targetMacho->addr);
922
923 int64_t thingRelativeOffset = imThingLoc - targetMacho->addr;
924 IF_DEBUG(linker,
925 debugBelch(" "
926 "original displacement %" PRId64 " to %p with section relative offset %" PRIu64 "\n",
927 thing, (void *) imThingLoc, thingRelativeOffset));
928
929 thing = (int64_t) ((uint64_t) targetSec->start + thingRelativeOffset)
930 - ((uint64_t) sect->start + baseValueOffset);
931 value = baseValue; // so that it further cancels out with baseValue
932 IF_DEBUG(linker,
933 debugBelch(" "
934 "relocated displacement %" PRId64 " to %p\n",
935 (int64_t) thing, (void *) (baseValue + thing)));
936 break;
937 }
938 default:
939 barf("relocateSection: unexpected internal relocation type %d\n", type);
940 return 0;
941 }
942 }
943
944 IF_DEBUG(linker, debugBelch("relocateSection: value = %p\n", (void *) value));
945
946 if (type == X86_64_RELOC_BRANCH)
947 {
948 if((int32_t)(value - baseValue) != (int64_t)(value - baseValue))
949 {
950 ASSERT(reloc->r_extern);
951 value = (uint64_t) &makeSymbolExtra(oc, reloc->r_symbolnum, value)
952 -> jumpIsland;
953 }
954 ASSERT((int32_t)(value - baseValue) == (int64_t)(value - baseValue));
955 type = X86_64_RELOC_SIGNED;
956 }
957
958 switch(type)
959 {
960 case X86_64_RELOC_UNSIGNED:
961 ASSERT(!reloc->r_pcrel);
962 thing += value;
963 break;
964 case X86_64_RELOC_SIGNED:
965 case X86_64_RELOC_SIGNED_1:
966 case X86_64_RELOC_SIGNED_2:
967 case X86_64_RELOC_SIGNED_4:
968 ASSERT(reloc->r_pcrel);
969 thing += value - baseValue;
970 break;
971 case X86_64_RELOC_SUBTRACTOR:
972 ASSERT(!reloc->r_pcrel);
973 thing -= value;
974 break;
975 default:
976 barf("unknown relocation");
977 }
978
979 IF_DEBUG(linker, debugBelch("relocateSection: thing = %p\n", (void *) thing));
980
981 /* Thing points to memory within one of the relocated sections. We can
982 * probe the first byte to sanity check internal relocations.
983 */
984 if (0 == reloc->r_extern) {
985 if (reloc->r_pcrel) {
986 checkProddableBlock(oc, (void *)((char *)thing + baseValue), 1);
987 } else {
988 checkProddableBlock(oc, (void *)thing, 1);
989 }
990 }
991
992 switch(reloc->r_length)
993 {
994 case 0:
995 *(uint8_t*)thingPtr = thing;
996 break;
997 case 1:
998 *(uint16_t*)thingPtr = thing;
999 break;
1000 case 2:
1001 *(uint32_t*)thingPtr = thing;
1002 break;
1003 case 3:
1004 *(uint64_t*)thingPtr = thing;
1005 break;
1006 }
1007 }
1008
1009 IF_DEBUG(linker, debugBelch("relocateSection: done\n"));
1010 return 1;
1011 }
1012 #endif /* x86_64_HOST_ARCH */
1013
1014 /* Note [mmap r+w+x]
1015 * ~~~~~~~~~~~~~~~~~
1016 *
1017 * iOS does not permit to mmap r+w+x, hence wo only mmap r+w, and later change
1018 * to r+x via mprotect. While this could would be nice to have for all hosts
1019 * and not just for iOS, it entail that the rest of the linker code supports
1020 * that, this includes:
1021 *
1022 * - mmap and mprotect need to be available.
1023 * - text and data sections need to be mapped into different pages. Ideally
1024 * the text and data sections would be aggregated, to prevent using a single
1025 * page for every section, however tiny.
1026 * - the relocation code for each object file format / architecture, needs to
1027 * respect the (now) non-contiguousness of the sections.
1028 * - with sections being mapped potentially far apart from each other, it must
1029 * be made sure that the pages are reachable within the architectures
1030 * addressability for relative or absolute access.
1031 */
1032
1033 SectionKind
1034 getSectionKind_MachO(MachOSection *section)
1035 {
1036 SectionKind kind;
1037
1038 /* todo: Use section flags instead */
1039 if (0==strcmp(section->sectname,"__text")) {
1040 kind = SECTIONKIND_CODE_OR_RODATA;
1041 } else if (0==strcmp(section->sectname,"__const") ||
1042 0==strcmp(section->sectname,"__data") ||
1043 0==strcmp(section->sectname,"__bss") ||
1044 0==strcmp(section->sectname,"__common") ||
1045 0==strcmp(section->sectname,"__mod_init_func")) {
1046 kind = SECTIONKIND_RWDATA;
1047 } else {
1048 kind = SECTIONKIND_OTHER;
1049 }
1050
1051 return kind;
1052 }
1053
1054 /* Calculate the # of active segments and their sizes based on section
1055 * sizes and alignments. This is done in 2 passes over sections:
1056 * 1. Calculate how many sections is going to be in each segment and
1057 * the total segment size.
1058 * 2. Fill in segment's sections_idx arrays.
1059 *
1060 * gbZerofillSegment is there because of this comment in mach-o/loader.h:
1061 * The gigabyte zero fill sections, those with the section type
1062 * S_GB_ZEROFILL, can only be in a segment with sections of this
1063 * type. These segments are then placed after all other segments.
1064 */
1065 int
1066 ocBuildSegments_MachO(ObjectCode *oc)
1067 {
1068 int n_rxSections = 0;
1069 size_t size_rxSegment = 0;
1070 Segment *rxSegment = NULL;
1071
1072 int n_rwSections = 0;
1073 size_t size_rwSegment = 0;
1074 Segment *rwSegment = NULL;
1075
1076 int n_gbZerofills = 0;
1077 size_t size_gbZerofillSegment = 0;
1078 Segment *gbZerofillSegment = NULL;
1079
1080 int n_activeSegments = 0;
1081 int curSegment = 0;
1082 size_t size_compound;
1083
1084 Segment *segments = NULL;
1085 void *mem = NULL, *curMem = NULL;
1086
1087 for (int i = 0; i < oc->n_sections; i++) {
1088 MachOSection *macho = &oc->info->macho_sections[i];
1089 size_t alignment = 1 << macho->align;
1090
1091 if (S_GB_ZEROFILL == (macho->flags & SECTION_TYPE)) {
1092 size_gbZerofillSegment = roundUpToAlign(size_gbZerofillSegment, alignment);
1093 size_gbZerofillSegment += macho->size;
1094 n_gbZerofills++;
1095 } else if (getSectionKind_MachO(macho) == SECTIONKIND_CODE_OR_RODATA) {
1096 size_rxSegment = roundUpToAlign(size_rxSegment, alignment);
1097 size_rxSegment += macho->size;
1098 n_rxSections++;
1099 } else {
1100 size_rwSegment = roundUpToAlign(size_rwSegment, alignment);
1101 size_rwSegment += macho->size;
1102 n_rwSections++;
1103 }
1104 }
1105
1106 size_compound = roundUpToPage(size_rxSegment) +
1107 roundUpToPage(size_rwSegment) +
1108 roundUpToPage(size_gbZerofillSegment);
1109
1110 if (n_rxSections > 0) {
1111 n_activeSegments++;
1112 }
1113 if (n_rwSections > 0) {
1114 n_activeSegments++;
1115 }
1116 if (n_gbZerofills >0) {
1117 n_activeSegments++;
1118 }
1119
1120 mem = mmapForLinker(size_compound, MAP_ANON, -1, 0);
1121 if (NULL == mem) return 0;
1122
1123 IF_DEBUG(linker, debugBelch("ocBuildSegments: allocating %d segments\n", n_activeSegments));
1124 segments = (Segment*)stgCallocBytes(n_activeSegments, sizeof(Segment),
1125 "ocBuildSegments_MachO(segments)");
1126 curMem = mem;
1127
1128 /* Allocate space for RX segment */
1129 if (n_rxSections > 0) {
1130 rxSegment = &segments[curSegment];
1131 initSegment(rxSegment,
1132 curMem,
1133 roundUpToPage(size_rxSegment),
1134 SEGMENT_PROT_RX,
1135 n_rxSections);
1136 IF_DEBUG(linker, debugBelch("ocBuildSegments_MachO: init segment %d (RX) at %p size %zu\n",
1137 curSegment, rxSegment->start, rxSegment->size));
1138 curMem = (char *)curMem + rxSegment->size;
1139 curSegment++;
1140 }
1141
1142 /* Allocate space for RW segment */
1143 if (n_rwSections > 0) {
1144 rwSegment = &segments[curSegment];
1145 initSegment(rwSegment,
1146 curMem,
1147 roundUpToPage(size_rwSegment),
1148 SEGMENT_PROT_RWO,
1149 n_rwSections);
1150 IF_DEBUG(linker, debugBelch("ocBuildSegments_MachO: init segment %d (RWO) at %p size %zu\n",
1151 curSegment, rwSegment->start, rwSegment->size));
1152 curMem = (char *)curMem + rwSegment->size;
1153 curSegment++;
1154 }
1155
1156 /* Allocate space for GB_ZEROFILL segment */
1157 if (n_gbZerofills > 0) {
1158 gbZerofillSegment = &segments[curSegment];
1159 initSegment(gbZerofillSegment,
1160 curMem,
1161 roundUpToPage(size_gbZerofillSegment),
1162 SEGMENT_PROT_RWO,
1163 n_gbZerofills);
1164 IF_DEBUG(linker, debugBelch("ocBuildSegments_MachO: init segment %d (GB_ZEROFILL) at %p size %zu\n",
1165 curSegment, gbZerofillSegment->start, gbZerofillSegment->size));
1166 curMem = (char *)curMem + gbZerofillSegment->size;
1167 curSegment++;
1168 }
1169
1170 /* Second pass over sections to fill in sections_idx arrays */
1171 for (int i = 0, rx = 0, rw = 0, gb = 0;
1172 i < oc->n_sections;
1173 i++)
1174 {
1175 MachOSection *macho = &oc->info->macho_sections[i];
1176
1177 if (S_GB_ZEROFILL == (macho->flags & SECTION_TYPE)) {
1178 gbZerofillSegment->sections_idx[gb++] = i;
1179 } else if (getSectionKind_MachO(macho) == SECTIONKIND_CODE_OR_RODATA) {
1180 rxSegment->sections_idx[rx++] = i;
1181 } else {
1182 rwSegment->sections_idx[rw++] = i;
1183 }
1184 }
1185
1186 oc->segments = segments;
1187 oc->n_segments = n_activeSegments;
1188
1189 return 1;
1190 }
1191
1192 int
1193 ocGetNames_MachO(ObjectCode* oc)
1194 {
1195 unsigned curSymbol = 0;
1196
1197 unsigned long commonSize = 0;
1198 SymbolAddr* commonStorage = NULL;
1199 unsigned long commonCounter;
1200
1201 IF_DEBUG(linker,debugBelch("ocGetNames_MachO: start\n"));
1202
1203 Section *secArray;
1204 secArray = (Section*)stgCallocBytes(
1205 oc->info->segCmd->nsects,
1206 sizeof(Section),
1207 "ocGetNames_MachO(sections)");
1208
1209 oc->sections = secArray;
1210
1211 IF_DEBUG(linker, debugBelch("ocGetNames_MachO: will load %d sections\n",
1212 oc->n_sections));
1213
1214 #if defined (ios_HOST_OS)
1215 for(int i=0; i < oc->n_sections; i++)
1216 {
1217 MachOSection * section = &oc->info->macho_sections[i];
1218
1219 IF_DEBUG(linker, debugBelch("ocGetNames_MachO: section %d\n", i));
1220
1221 if (section->size == 0) {
1222 IF_DEBUG(linker, debugBelch("ocGetNames_MachO: found a zero length section, skipping\n"));
1223 continue;
1224 }
1225
1226 SectionKind kind = getSectionKind_MachO(section);
1227
1228 switch(section->flags & SECTION_TYPE) {
1229 case S_ZEROFILL:
1230 case S_GB_ZEROFILL: {
1231 // See Note [mmap r+w+x]
1232 void * mem = mmap(NULL, section->size,
1233 PROT_READ | PROT_WRITE,
1234 MAP_ANON | MAP_PRIVATE,
1235 -1, 0);
1236 if( mem == MAP_FAILED ) {
1237 barf("failed to mmap allocate memory for zerofill section %d of size %d. errno = %d",
1238 i, section->size, errno);
1239 }
1240 addSection(&secArray[i], kind, SECTION_MMAP, mem, section->size,
1241 0, mem, roundUpToPage(section->size));
1242 addProddableBlock(oc, mem, (int)section->size);
1243
1244 secArray[i].info->nstubs = 0;
1245 secArray[i].info->stub_offset = NULL;
1246 secArray[i].info->stub_size = 0;
1247 secArray[i].info->stubs = NULL;
1248
1249 secArray[i].info->macho_section = section;
1250 secArray[i].info->relocation_info
1251 = (MachORelocationInfo*)(oc->image + section->reloff);
1252 break;
1253 }
1254 default: {
1255 // The secion should have a non-zero offset. As the offset is
1256 // relativ to the image, and must be somewhere after the header.
1257 if(section->offset == 0) barf("section with zero offset!");
1258 /* on iOS, we must allocate the code in r+x sections and
1259 * the data in r+w sections, as the system does not allow
1260 * for r+w+x, we must allocate each section in a new page
1261 * range.
1262 *
1263 * copy the sections's memory to some page-aligned place via
1264 * mmap and memcpy. This will later allow us to selectively
1265 * use mprotect on pages with data (r+w) and pages text (r+x).
1266 * We initially start with r+w, so that we can modify the
1267 * pages during relocations, prior to setting it r+x.
1268 */
1269
1270 /* We also need space for stubs. As pages can be assigned
1271 * randomly in the addressable space, we need to keep the
1272 * stubs close to the section. The strategy we are going
1273 * to use is to allocate them right after the section. And
1274 * we are going to be generous and allocare a stub slot
1275 * for each relocation to keep it simple.
1276 */
1277 size_t n_ext_sec_sym = section->nreloc; /* number of relocations
1278 * for this section. Should
1279 * be a good upper bound
1280 */
1281 size_t stub_space = /* eight bytes for the 64 bit address,
1282 * and another eight bytes for the two
1283 * instructions (ldr, br) for each relocation.
1284 */ 16 * n_ext_sec_sym;
1285 // See Note [mmap r+w+x]
1286 void * mem = mmap(NULL, section->size+stub_space,
1287 PROT_READ | PROT_WRITE,
1288 MAP_ANON | MAP_PRIVATE,
1289 -1, 0);
1290 if( mem == MAP_FAILED ) {
1291 barf("failed to mmap allocate memory to load section %d. errno = %d", i, errno );
1292 }
1293 memcpy( mem, oc->image + section->offset, section->size);
1294
1295 addSection(&secArray[i], kind, SECTION_MMAP,
1296 mem, section->size,
1297 0, mem, roundUpToPage(section->size+stub_space));
1298 addProddableBlock(oc, mem, (int)section->size);
1299
1300 secArray[i].info->nstubs = 0;
1301 secArray[i].info->stub_offset = ((uint8_t*)mem) + section->size;
1302 secArray[i].info->stub_size = stub_space;
1303 secArray[i].info->stubs = NULL;
1304
1305 secArray[i].info->macho_section = section;
1306 secArray[i].info->relocation_info
1307 = (MachORelocationInfo*)(oc->image + section->reloff);
1308 break;
1309 }
1310 }
1311 }
1312 #else /* !ios_HOST_OS */
1313 IF_DEBUG(linker, debugBelch("ocGetNames_MachO: building segments\n"));
1314
1315 CHECKM(ocBuildSegments_MachO(oc), "ocGetNames_MachO: failed to build segments\n");
1316
1317 for (int seg_n = 0; seg_n < oc->n_segments; seg_n++) {
1318 Segment *segment = &oc->segments[seg_n];
1319 void *curMem = segment->start;
1320
1321 IF_DEBUG(linker,
1322 debugBelch("ocGetNames_MachO: loading segment %d "
1323 "(address = %p, size = %zu) "
1324 "with %d sections\n",
1325 seg_n, segment->start, segment->size, segment->n_sections));
1326
1327 for (int sec_n = 0; sec_n < segment->n_sections; sec_n++) {
1328 int sec_idx = segment->sections_idx[sec_n];
1329 MachOSection *section = &oc->info->macho_sections[sec_idx];
1330
1331 size_t alignment = 1 << section->align;
1332 SectionKind kind = getSectionKind_MachO(section);
1333
1334 void *secMem = (void *)roundUpToAlign((size_t)curMem, alignment);
1335
1336 IF_DEBUG(linker,
1337 debugBelch("ocGetNames_MachO: loading section %d in segment %d "
1338 "(#%d, %s %s)\n"
1339 " skipped %zu bytes due to alignment of %zu\n",
1340 sec_n, seg_n, sec_idx, section->segname, section->sectname,
1341 (char *)secMem - (char *)curMem, alignment));
1342
1343 switch (section->flags & SECTION_TYPE) {
1344 case S_ZEROFILL:
1345 case S_GB_ZEROFILL:
1346 IF_DEBUG(linker, debugBelch("ocGetNames_MachO: memset to 0 a ZEROFILL section\n"));
1347 memset(secMem, 0, section->size);
1348 break;
1349 default:
1350 IF_DEBUG(linker,
1351 debugBelch("ocGetNames_MachO: copying from %p to %p"
1352 " a block of %" PRIu64 " bytes\n",
1353 (void *) (oc->image + section->offset), secMem, section->size));
1354
1355 memcpy(secMem, oc->image + section->offset, section->size);
1356 }
1357
1358 /* SECTION_NOMEM since memory is already allocated in segments */
1359 addSection(&secArray[sec_idx], kind, SECTION_NOMEM,
1360 secMem, section->size,
1361 0, 0, 0);
1362 addProddableBlock(oc, secMem, section->size);
1363
1364 curMem = (char*) secMem + section->size;
1365
1366 secArray[sec_idx].info->nstubs = 0;
1367 secArray[sec_idx].info->stub_offset = NULL;
1368 secArray[sec_idx].info->stub_size = 0;
1369 secArray[sec_idx].info->stubs = NULL;
1370
1371 secArray[sec_idx].info->macho_section = section;
1372 secArray[sec_idx].info->relocation_info
1373 = (MachORelocationInfo*)(oc->image + section->reloff);
1374
1375 }
1376
1377 }
1378 #endif
1379
1380 /* now, as all sections have been loaded, we can resolve the absolute
1381 * address of symbols defined in those sections.
1382 */
1383 for(size_t i=0; i < oc->info->n_macho_symbols; i++) {
1384 MachOSymbol * s = &oc->info->macho_symbols[i];
1385 if( N_SECT == (s->nlist->n_type & N_TYPE) ) {
1386 if( NO_SECT == s->nlist->n_sect )
1387 barf("Symbol with N_SECT type, but no section.");
1388
1389 /* section is given, and n_sect is >0 */
1390 uint8_t n = s->nlist->n_sect - 1;
1391 if(0 == oc->info->macho_sections[n].size) {
1392 continue;
1393 }
1394
1395 /* addr <- address in memory where the relocated section resides | (a)
1396 * - section's address in the image | (b)
1397 * + symbol's address in the image | (c)
1398 * (c) - (b) gives symbol's offset relative to section start
1399 * (a) - (b) + (c) gives symbol's address for the relocated section
1400 *
1401 * (c) and (b) are not _real_ addresses and not equal
1402 * to file offsets in the image.
1403 * Rather they are (virtual) aligned addresses within
1404 * a single segment of MH_OBJECT object file.
1405 */
1406 s->addr = (uint8_t*)oc->sections[n].start
1407 - oc->info->macho_sections[n].addr
1408 + s->nlist->n_value;
1409 if(NULL == s->addr)
1410 barf("Failed to compute address for symbol %s", s->name);
1411 }
1412 }
1413
1414 // count external symbols defined here
1415 oc->n_symbols = 0;
1416 if (oc->info->symCmd) {
1417 for (size_t i = 0; i < oc->info->n_macho_symbols; i++) {
1418 if (oc->info->nlist[i].n_type & N_STAB) {
1419 ;
1420 }
1421 else if(oc->info->nlist[i].n_type & N_EXT)
1422 {
1423 if((oc->info->nlist[i].n_type & N_TYPE) == N_UNDF
1424 && (oc->info->nlist[i].n_value != 0))
1425 {
1426 commonSize += oc->info->nlist[i].n_value;
1427 oc->n_symbols++;
1428 }
1429 else if((oc->info->nlist[i].n_type & N_TYPE) == N_SECT)
1430 oc->n_symbols++;
1431 }
1432 }
1433 }
1434 /* allocate space for the exported symbols
1435 * in the object code. This is used to track
1436 * which symbols will have to be removed when
1437 * this object code is unloaded
1438 */
1439 IF_DEBUG(linker, debugBelch("ocGetNames_MachO: %d external symbols\n",
1440 oc->n_symbols));
1441 oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(Symbol_t),
1442 "ocGetNames_MachO(oc->symbols)");
1443
1444 if (oc->info->symCmd) {
1445 for (size_t i = 0; i < oc->info->n_macho_symbols; i++) {
1446 SymbolName* nm = oc->info->macho_symbols[i].name;
1447 if (oc->info->nlist[i].n_type & N_STAB)
1448 {
1449 IF_DEBUG(linker, debugBelch("ocGetNames_MachO: Skip STAB: %s\n", nm));
1450 }
1451 else if ((oc->info->nlist[i].n_type & N_TYPE) == N_SECT)
1452 {
1453 if (oc->info->nlist[i].n_type & N_EXT)
1454 {
1455 if ( (oc->info->nlist[i].n_desc & N_WEAK_DEF)
1456 && lookupSymbol_(nm)) {
1457 // weak definition, and we already have a definition
1458 IF_DEBUG(linker, debugBelch(" weak: %s\n", nm));
1459 }
1460 else
1461 {
1462 IF_DEBUG(linker, debugBelch("ocGetNames_MachO: inserting %s\n", nm));
1463 SymbolAddr* addr = oc->info->macho_symbols[i].addr;
1464
1465 ghciInsertSymbolTable( oc->fileName
1466 , symhash
1467 , nm
1468 , addr
1469 , HS_BOOL_FALSE
1470 , oc);
1471
1472 oc->symbols[curSymbol].name = nm;
1473 oc->symbols[curSymbol].addr = addr;
1474 curSymbol++;
1475 }
1476 }
1477 else
1478 {
1479 IF_DEBUG(linker, debugBelch("ocGetNames_MachO: \t...not external, skipping %s\n", nm));
1480 }
1481 }
1482 else
1483 {
1484 IF_DEBUG(linker, debugBelch("ocGetNames_MachO: \t...not defined in this section, skipping %s\n", nm));
1485 }
1486 }
1487 }
1488
1489 /* setup the common storage */
1490 commonStorage = stgCallocBytes(1,commonSize,"ocGetNames_MachO(common symbols)");
1491 commonCounter = (unsigned long)commonStorage;
1492
1493 if (oc->info->symCmd) {
1494 for (size_t i = 0; i < oc->info->n_macho_symbols; i++) {
1495 SymbolName* nm = oc->info->macho_symbols[i].name;
1496 MachONList *nlist = &oc->info->nlist[i];
1497 if((nlist->n_type & N_TYPE) == N_UNDF
1498 && (nlist->n_type & N_EXT)
1499 && (nlist->n_value != 0)) {
1500 unsigned long sz = nlist->n_value;
1501
1502 nlist->n_value = commonCounter;
1503
1504 /* also set the final address to the macho_symbol */
1505 oc->info->macho_symbols[i].addr = (void*)commonCounter;
1506
1507 IF_DEBUG(linker, debugBelch("ocGetNames_MachO: inserting common symbol: %s\n", nm));
1508 ghciInsertSymbolTable(oc->fileName, symhash, nm,
1509 (void*)commonCounter, HS_BOOL_FALSE, oc);
1510 oc->symbols[curSymbol].name = nm;
1511 oc->symbols[curSymbol].addr = oc->info->macho_symbols[i].addr;
1512 curSymbol++;
1513
1514 commonCounter += sz;
1515 }
1516 }
1517 }
1518 #if defined(aarch64_HOST_ARCH)
1519 /* Setup the global offset table
1520 * This is for symbols that are external, and not defined here.
1521 * So that we can load their address indirectly.
1522 *
1523 * We will get GOT request for any symbol that is
1524 * - EXT and UNDF
1525 * - EXT and not in the same section.
1526 *
1527 * As sections are not necessarily contiguous and can live
1528 * anywhere in the addressable space. This obviously makes
1529 * sense. However it took me a while to figure this out.
1530 */
1531 makeGot(oc);
1532
1533 /* at this point, macho_symbols, should know the addresses for
1534 * all symbols defined by this object code.
1535 * - those that are defined in sections.
1536 * - those that are undefined, but have a value (common storage).
1537 */
1538 #endif
1539 IF_DEBUG(linker, debugBelch("ocGetNames_MachO: done\n"));
1540 return 1;
1541 }
1542
1543 #if defined(ios_HOST_OS)
1544 bool
1545 ocMprotect_MachO( ObjectCode *oc ) {
1546 for(int i=0; i < oc->n_sections; i++) {
1547 Section * section = &oc->sections[i];
1548 if(section->size == 0) continue;
1549 if( (section->info->macho_section->flags & SECTION_ATTRIBUTES_USR)
1550 == S_ATTR_PURE_INSTRUCTIONS) {
1551 if( 0 != mprotect(section->start,
1552 section->size + section->info->stub_size,
1553 PROT_READ | PROT_EXEC) ) {
1554 barf("mprotect failed! errno = %d", errno);
1555 return false;
1556 }
1557 }
1558 }
1559 return true;
1560 }
1561 #endif
1562
1563 int
1564 ocResolve_MachO(ObjectCode* oc)
1565 {
1566 IF_DEBUG(linker, debugBelch("ocResolve_MachO: start\n"));
1567
1568 if(NULL != oc->info->dsymCmd)
1569 {
1570 unsigned long *indirectSyms
1571 = (unsigned long*) (oc->image + oc->info->dsymCmd->indirectsymoff);
1572
1573 IF_DEBUG(linker, debugBelch("ocResolve_MachO: resolving dsymLC\n"));
1574 for (int i = 0; i < oc->n_sections; i++)
1575 {
1576 const char * sectionName = oc->info->macho_sections[i].sectname;
1577 if( !strcmp(sectionName,"__la_symbol_ptr")
1578 || !strcmp(sectionName,"__la_sym_ptr2")
1579 || !strcmp(sectionName,"__la_sym_ptr3"))
1580 {
1581 if(!resolveImports(oc,&oc->info->macho_sections[i],
1582 indirectSyms))
1583 return 0;
1584 }
1585 else if(!strcmp(sectionName,"__nl_symbol_ptr")
1586 || !strcmp(sectionName,"__pointers"))
1587 {
1588 if(!resolveImports(oc,&oc->info->macho_sections[i],
1589 indirectSyms))
1590 return 0;
1591 }
1592 else if(!strcmp(sectionName,"__jump_table"))
1593 {
1594 if(!resolveImports(oc,&oc->info->macho_sections[i],
1595 indirectSyms))
1596 return 0;
1597 }
1598 else
1599 {
1600 IF_DEBUG(linker, debugBelch("ocResolve_MachO: unknown section\n"));
1601 }
1602 }
1603 }
1604 #if defined(aarch64_HOST_ARCH)
1605 /* fill the GOT table */
1606 for(size_t i = 0; i < oc->info->n_macho_symbols; i++) {
1607 MachOSymbol * symbol = &oc->info->macho_symbols[i];
1608 if(needGotSlot(symbol->nlist)) {
1609 if(N_UNDF == (symbol->nlist->n_type & N_TYPE)) {
1610 /* an undefined symbol. So we need to ensure we
1611 * have the address.
1612 */
1613 if(NULL == symbol->addr) {
1614 symbol->addr = lookupSymbol_((char*)symbol->name);
1615 if(NULL == symbol->addr)
1616 barf("Failed to lookup symbol: %s", symbol->name);
1617 } else {
1618 // we already have the address.
1619 }
1620 } /* else it was defined in the same object,
1621 * just a different section. We should have
1622 * the address as well already
1623 */
1624 if(NULL == symbol->addr) {
1625 barf("Something went wrong!");
1626 }
1627 if(NULL == symbol->got_addr) {
1628 barf("Not good either!");
1629 }
1630 *(uint64_t*)symbol->got_addr = (uint64_t)symbol->addr;
1631 }
1632 }
1633 #endif
1634
1635 for(int i = 0; i < oc->n_sections; i++)
1636 {
1637 IF_DEBUG(linker, debugBelch("ocResolve_MachO: relocating section %d\n", i));
1638
1639 #if defined aarch64_HOST_ARCH
1640 if (!relocateSectionAarch64(oc, &oc->sections[i]))
1641 return 0;
1642 #else
1643 if (!relocateSection(oc, i))
1644 return 0;
1645 #endif
1646 }
1647 #if defined(ios_HOST_OS)
1648 if(!ocMprotect_MachO ( oc ))
1649 return 0;
1650 #endif
1651
1652 return 1;
1653 }
1654
1655 int
1656 ocRunInit_MachO ( ObjectCode *oc )
1657 {
1658 if (NULL == oc->info->segCmd) {
1659 barf("ocRunInit_MachO: no segment load command");
1660 }
1661
1662 int argc, envc;
1663 char **argv, **envv;
1664
1665 getProgArgv(&argc, &argv);
1666 getProgEnvv(&envc, &envv);
1667
1668 for (int i = 0; i < oc->n_sections; i++) {
1669 IF_DEBUG(linker, debugBelch("ocRunInit_MachO: checking section %d\n", i));
1670
1671 // ToDo: replace this with a proper check for the S_MOD_INIT_FUNC_POINTERS
1672 // flag. We should do this elsewhere in the Mach-O linker code
1673 // too. Note that the system linker will *refuse* to honor
1674 // sections which don't have this flag, so this could cause
1675 // weird behavior divergence (albeit reproducible).
1676 if (0 == strcmp(oc->info->macho_sections[i].sectname, "__mod_init_func")) {
1677 IF_DEBUG(linker, debugBelch("ocRunInit_MachO: running mod init functions\n"));
1678
1679 void *init_startC = oc->sections[i].start;
1680 init_t *init = (init_t*)init_startC;
1681 init_t *init_end = (init_t*)((uint8_t*)init_startC
1682 + oc->sections[i].info->macho_section->size);
1683
1684 for (int pn = 0; init < init_end; init++, pn++) {
1685 IF_DEBUG(linker, debugBelch("ocRunInit_MachO: function pointer %d at %p to %p\n",
1686 pn, (void *) init, (void *) *init));
1687 (*init)(argc, argv, envv);
1688 }
1689 }
1690 }
1691
1692 freeProgEnvv(envc, envv);
1693 return 1;
1694 }
1695
1696 /*
1697 * Figure out by how much to shift the entire Mach-O file in memory
1698 * when loading so that its single segment ends up 16-byte-aligned
1699 */
1700 int
1701 machoGetMisalignment( FILE * f )
1702 {
1703 MachOHeader header;
1704 int misalignment;
1705
1706 {
1707 size_t n = fread(&header, sizeof(header), 1, f);
1708 if (n != 1) {
1709 barf("machoGetMisalignment: can't read the Mach-O header");
1710 }
1711 }
1712 fseek(f, -sizeof(header), SEEK_CUR);
1713
1714 if(header.magic != MH_MAGIC_64) {
1715 barf("Bad magic. Expected: %08x, got: %08x.",
1716 MH_MAGIC_64, header.magic);
1717 }
1718
1719 misalignment = (header.sizeofcmds + sizeof(header))
1720 & 0xF;
1721
1722 IF_DEBUG(linker, debugBelch("mach-o misalignment %d\n", misalignment));
1723 return misalignment ? (16 - misalignment) : 0;
1724 }
1725
1726 #endif /* darwin_HOST_OS || ios_HOST_OS */