1 2#include <stdlib.h> 3#include <stdio.h> 4#include <assert.h> 5#include <sys/types.h> 6#include <sys/stat.h> 7#include <unistd.h> 8#include <elf.h> 9#include <fcntl.h> 10#include <string.h> 11#include <malloc.h> 12 13 14#define IF_DEBUG(x,y) /* */ 15static int debug_linker = 0; 16 17#define i386_TARGET_ARCH 18// #define arm_TARGET_ARCH 19 20#if !defined(i386_TARGET_ARCH) && !defined(arm_TARGET_ARCH) 21# error "Must #define i386_TARGET_ARCH or arm_TARGET_ARCH" 22#endif 23 24 25/////////////////////////////////////////////////////////////////// 26/////////////////////////////////////////////////////////////////// 27/////////////////////////////////////////////////////////////////// 28// 29// TYPES 30 31#define FALSE 0 32#define TRUE 1 33 34typedef enum { OBJECT_LOADED, OBJECT_RESOLVED } OStatus; 35 36 37#define N_FIXUP_PAGES 1 38 39 40/* Indication of section kinds for loaded objects. Needed by 41 the GC for deciding whether or not a pointer on the stack 42 is a code pointer. 43*/ 44typedef 45 enum { SECTIONKIND_CODE_OR_RODATA, 46 SECTIONKIND_RWDATA, 47 SECTIONKIND_OTHER, 48 SECTIONKIND_NOINFOAVAIL } 49 SectionKind; 50 51typedef 52 struct _Section { 53 void* start; 54 void* end; 55 SectionKind kind; 56 struct _Section* next; 57 } 58 Section; 59 60typedef 61 struct _ProddableBlock { 62 void* start; 63 int size; 64 struct _ProddableBlock* next; 65 } 66 ProddableBlock; 67 68/* Top-level structure for an object module. One of these is allocated 69 * for each object file in use. 70 */ 71typedef struct _ObjectCode { 72 OStatus status; 73 char* fileName; 74 int fileSize; 75 char* formatName; /* eg "ELF32", "DLL", "COFF", etc. */ 76 77 /* An array containing ptrs to all the symbol names copied from 78 this object into the global symbol hash table. This is so that 79 we know which parts of the latter mapping to nuke when this 80 object is removed from the system. */ 81 char** symbols; 82 int n_symbols; 83 84 /* ptr to malloc'd lump of memory holding the obj file */ 85 void* image; 86 87 /* Fixup area for long-distance jumps. */ 88 char* fixup; 89 int fixup_used; 90 int fixup_size; 91 92 /* The section-kind entries for this object module. Linked 93 list. */ 94 Section* sections; 95 96 /* A private hash table for local symbols. */ 97 /* HashTable* */ void* lochash; 98 99 /* Allow a chain of these things */ 100 struct _ObjectCode * next; 101 102 /* SANITY CHECK ONLY: a list of the only memory regions which may 103 safely be prodded during relocation. Any attempt to prod 104 outside one of these is an error in the linker. */ 105 ProddableBlock* proddables; 106 107} ObjectCode; 108 109/* 110 * Define a set of types which can be used for both ELF32 and ELF64 111 */ 112 113#ifdef ELF_64BIT 114#define ELFCLASS ELFCLASS64 115#define Elf_Addr Elf64_Addr 116#define Elf_Word Elf64_Word 117#define Elf_Sword Elf64_Sword 118#define Elf_Ehdr Elf64_Ehdr 119#define Elf_Phdr Elf64_Phdr 120#define Elf_Shdr Elf64_Shdr 121#define Elf_Sym Elf64_Sym 122#define Elf_Rel Elf64_Rel 123#define Elf_Rela Elf64_Rela 124#define ELF_ST_TYPE ELF64_ST_TYPE 125#define ELF_ST_BIND ELF64_ST_BIND 126#define ELF_R_TYPE ELF64_R_TYPE 127#define ELF_R_SYM ELF64_R_SYM 128#else 129#define ELFCLASS ELFCLASS32 130#define Elf_Addr Elf32_Addr 131#define Elf_Word Elf32_Word 132#define Elf_Sword Elf32_Sword 133#define Elf_Ehdr Elf32_Ehdr 134#define Elf_Phdr Elf32_Phdr 135#define Elf_Shdr Elf32_Shdr 136#define Elf_Sym Elf32_Sym 137#define Elf_Rel Elf32_Rel 138#define Elf_Rela Elf32_Rela 139#ifndef ELF_ST_TYPE 140#define ELF_ST_TYPE ELF32_ST_TYPE 141#endif 142#ifndef ELF_ST_BIND 143#define ELF_ST_BIND ELF32_ST_BIND 144#endif 145#ifndef ELF_R_TYPE 146#define ELF_R_TYPE ELF32_R_TYPE 147#endif 148#ifndef ELF_R_SYM 149#define ELF_R_SYM ELF32_R_SYM 150#endif 151#endif 152 153 154 155 156/////////////////////////////////////////////////////////////////// 157/////////////////////////////////////////////////////////////////// 158/////////////////////////////////////////////////////////////////// 159// 160// PARANOIA 161 162/* ----------------------------------------------------------------------- 163 * Sanity checking. For each ObjectCode, maintain a list of address ranges 164 * which may be prodded during relocation, and abort if we try and write 165 * outside any of these. 166 */ 167static void addProddableBlock ( ObjectCode* oc, void* start, int size ) 168{ 169 ProddableBlock* pb 170 = malloc(sizeof(ProddableBlock)); 171 if (debug_linker) 172 fprintf(stderr, "aPB oc=%p %p %d (%p .. %p)\n", oc, start, size, 173 start, ((char*)start)+size-1 ); 174 assert(size > 0); 175 pb->start = start; 176 pb->size = size; 177 pb->next = oc->proddables; 178 oc->proddables = pb; 179} 180 181static void checkProddableBlock ( ObjectCode* oc, void* addr ) 182{ 183 ProddableBlock* pb; 184 for (pb = oc->proddables; pb != NULL; pb = pb->next) { 185 char* s = (char*)(pb->start); 186 char* e = s + pb->size - 1; 187 char* a = (char*)addr; 188 /* Assumes that the biggest fixup involves a 4-byte write. This 189 probably needs to be changed to 8 (ie, +7) on 64-bit 190 plats. */ 191 if (a >= s && (a+3) <= e) return; 192 } 193 fprintf(stderr, 194 "checkProddableBlock: invalid fixup %p in runtime linker\n", 195 addr); 196 exit(1); 197} 198 199 200 201/////////////////////////////////////////////////////////////////// 202/////////////////////////////////////////////////////////////////// 203/////////////////////////////////////////////////////////////////// 204// 205// String->Addr mappings 206 207typedef 208 struct { char* mp_name; void* mp_addr; } 209 Maplet; 210 211typedef 212 struct { 213 int sm_size; 214 int sm_used; 215 Maplet* maplets; 216 } 217 StringMap; 218 219static StringMap* new_StringMap ( void ) 220{ 221 StringMap* sm = malloc(sizeof(StringMap)); 222 sm->sm_size = 10; 223 sm->sm_used = 0; 224 sm->maplets = malloc(10 * sizeof(Maplet)); 225 return sm; 226} 227 228static void delete_StringMap ( StringMap* sm ) 229{ 230 assert(sm->maplets != NULL); 231 free(sm->maplets); 232 sm->maplets = NULL; 233 free(sm); 234} 235 236static void ensure_StringMap ( StringMap* sm ) 237{ 238 int i; 239 Maplet* mp2; 240 assert(sm->maplets != NULL); 241 if (sm->sm_used < sm->sm_size) 242 return; 243 sm->sm_size *= 2; 244 mp2 = malloc(sm->sm_size * sizeof(Maplet)); 245 for (i = 0; i < sm->sm_used; i++) 246 mp2[i] = sm->maplets[i]; 247 free(sm->maplets); 248 sm->maplets = mp2; 249} 250 251static void* search_StringMap ( StringMap* sm, char* name ) 252{ 253 int i; 254 for (i = 0; i < sm->sm_used; i++) 255 if (0 == strcmp(name, sm->maplets[i].mp_name)) 256 return sm->maplets[i].mp_addr; 257 return NULL; 258} 259 260static void addto_StringMap ( StringMap* sm, char* name, void* addr ) 261{ 262 ensure_StringMap(sm); 263 sm->maplets[sm->sm_used].mp_name = name; 264 sm->maplets[sm->sm_used].mp_addr = addr; 265 sm->sm_used++; 266} 267 268static void paranoid_addto_StringMap ( StringMap* sm, char* name, void* addr ) 269{ 270 if (search_StringMap(sm,name) != NULL) { 271 fprintf(stderr, "paranoid_addto_StringMap(%s,%p)\n", name, addr); 272 exit(1); 273 } 274 addto_StringMap(sm,name,addr); 275} 276 277 278/////////////////////////////////////////////////////////////////// 279/////////////////////////////////////////////////////////////////// 280/////////////////////////////////////////////////////////////////// 281// 282// Top-level linker control. 283 284StringMap* global_symbol_table = NULL; 285ObjectCode* global_object_list = NULL; 286 287static void initLinker ( void ) 288{ 289 if (global_symbol_table != NULL) 290 return; 291 global_symbol_table = new_StringMap(); 292} 293 294 295 296/////////////////////////////////////////////////////////////////// 297/////////////////////////////////////////////////////////////////// 298/////////////////////////////////////////////////////////////////// 299// 300// SYMBOL TABLE(s) 301 302/* ----------------------------------------------------------------- 303 * lookup a symbol in the global symbol table 304 */ 305static 306void * lookupSymbol( char *lbl ) 307{ 308 void *val; 309 initLinker() ; 310 assert(global_symbol_table != NULL); 311 val = search_StringMap(global_symbol_table, lbl); 312 return val; 313} 314 315 316/////////////////////////////////////////////////////////////////// 317/////////////////////////////////////////////////////////////////// 318/////////////////////////////////////////////////////////////////// 319// 320// HELPERS 321 322/* 323 * Generic ELF functions 324 */ 325 326static char * 327findElfSection ( void* objImage, Elf_Word sh_type ) 328{ 329 char* ehdrC = (char*)objImage; 330 Elf_Ehdr* ehdr = (Elf_Ehdr*)ehdrC; 331 Elf_Shdr* shdr = (Elf_Shdr*)(ehdrC + ehdr->e_shoff); 332 char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset; 333 char* ptr = NULL; 334 int i; 335 336 for (i = 0; i < ehdr->e_shnum; i++) { 337 if (shdr[i].sh_type == sh_type 338 /* Ignore the section header's string table. */ 339 && i != ehdr->e_shstrndx 340 /* Ignore string tables named .stabstr, as they contain 341 debugging info. */ 342 && 0 != memcmp(".stabstr", sh_strtab + shdr[i].sh_name, 8) 343 ) { 344 ptr = ehdrC + shdr[i].sh_offset; 345 break; 346 } 347 } 348 return ptr; 349} 350 351#ifdef arm_TARGET_ARCH 352static 353char* alloc_fixup_bytes ( ObjectCode* oc, int nbytes ) 354{ 355 char* res; 356 assert(nbytes % 4 == 0); 357 assert(nbytes > 0); 358 res = &(oc->fixup[oc->fixup_used]); 359 oc->fixup_used += nbytes; 360 if (oc->fixup_used >= oc->fixup_size) { 361 fprintf(stderr, "fixup area too small for %s\n", oc->fileName); 362 exit(1); 363 } 364 return res; 365} 366#endif 367 368 369/////////////////////////////////////////////////////////////////// 370/////////////////////////////////////////////////////////////////// 371/////////////////////////////////////////////////////////////////// 372// 373// RESOLVE 374 375static 376void* lookup_magic_hacks ( char* sym ) 377{ 378 if (0==strcmp(sym, "printf")) return (void*)(&printf); 379 return NULL; 380} 381 382#ifdef arm_TARGET_ARCH 383static 384void arm_notify_new_code ( char* start, int length ) 385{ 386 __asm __volatile ("mov r1, %0\n\t" 387 "mov r2, %1\n\t" 388 "mov r3, %2\n\t" 389 "swi 0x9f0002\n\t" 390 : 391 : "ir" (start), "ir" (length), "ir" (0) ); 392} 393 394 395static 396void gen_armle_goto ( char* fixup, char* dstP ) 397{ 398 Elf_Word w = (Elf_Word)dstP; 399 /* 400 2 .text 401 3 0000 04F01FE5 ldr pc, value 402 4 0004 44332211 value: .word 0x11223344 403 */ 404 fprintf(stderr,"at %p generating jump to %p\n", fixup, dstP ); 405 fixup[0] = 0x04; fixup[1] = 0xF0; fixup[2] = 0x1F; fixup[3] = 0xE5; 406 fixup[4] = w & 0xFF; w >>= 8; 407 fixup[5] = w & 0xFF; w >>= 8; 408 fixup[6] = w & 0xFF; w >>= 8; 409 fixup[7] = w & 0xFF; w >>= 8; 410 arm_notify_new_code(fixup, 8); 411} 412#endif /* arm_TARGET_ARCH */ 413 414 415 416/* Do ELF relocations which lack an explicit addend. All x86-linux 417 relocations appear to be of this form. */ 418static int 419do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC, 420 Elf_Shdr* shdr, int shnum, 421 Elf_Sym* stab, char* strtab ) 422{ 423 int j; 424 char *symbol = NULL; 425 Elf_Word* targ; 426 Elf_Rel* rtab = (Elf_Rel*) (ehdrC + shdr[shnum].sh_offset); 427 int nent = shdr[shnum].sh_size / sizeof(Elf_Rel); 428 int target_shndx = shdr[shnum].sh_info; 429 int symtab_shndx = shdr[shnum].sh_link; 430 431 stab = (Elf_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset); 432 targ = (Elf_Word*)(ehdrC + shdr[ target_shndx ].sh_offset); 433 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d", 434 target_shndx, symtab_shndx )); 435 436 for (j = 0; j < nent; j++) { 437 Elf_Addr offset = rtab[j].r_offset; 438 Elf_Addr info = rtab[j].r_info; 439 440 Elf_Addr P = ((Elf_Addr)targ) + offset; 441 Elf_Word* pP = (Elf_Word*)P; 442 Elf_Addr A = *pP; 443 Elf_Addr S; 444 Elf_Addr value; 445 446 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p)", 447 j, (void*)offset, (void*)info )); 448 if (!info) { 449 IF_DEBUG(linker,belch( " ZERO" )); 450 S = 0; 451 } else { 452 Elf_Sym sym = stab[ELF_R_SYM(info)]; 453 /* First see if it is a local symbol. */ 454 if (ELF_ST_BIND(sym.st_info) == STB_LOCAL) { 455 /* Yes, so we can get the address directly from the ELF symbol 456 table. */ 457 symbol = sym.st_name==0 ? "(noname)" : strtab+sym.st_name; 458 S = (Elf_Addr) 459 (ehdrC + shdr[ sym.st_shndx ].sh_offset 460 + stab[ELF_R_SYM(info)].st_value); 461 462 } else { 463 /* No, so look up the name in our global table. */ 464 symbol = strtab + sym.st_name; 465 S = (Elf_Addr)lookupSymbol( symbol ); 466 } 467 if (!S) { 468 S = (Elf_Addr)lookup_magic_hacks(symbol); 469 } 470 if (!S) { 471 fprintf(stderr,"%s: unknown symbol `%s'\n", 472 oc->fileName, symbol); 473 return 0; 474 } 475 if (debug_linker>1) 476 fprintf(stderr, "\n`%s' resolves to %p\n", symbol, (void*)S ); 477 } 478 479 if (debug_linker>1) 480 fprintf(stderr, "Reloc: P = %p S = %p A = %p\n", 481 (void*)P, (void*)S, (void*)A ); 482 checkProddableBlock ( oc, pP ); 483 484 value = S + A; 485 486 switch (ELF_R_TYPE(info)) { 487# ifdef i386_TARGET_ARCH 488 case R_386_32: *pP = value; break; 489 case R_386_PC32: *pP = value - P; break; 490# endif 491# ifdef arm_TARGET_ARCH 492 case R_ARM_PC24: { 493 Elf_Word w, delta, deltaTop8; 494 /* Generate a jump sequence into the fixup area 495 and branch to that instead. */ 496 char* fixup = alloc_fixup_bytes(oc, 8); 497 /* First of all, figure out where we're really trying to 498 jump to. */ 499 // compensate for pc+8 bias 500 Elf_Word real_dst = (A & 0x00FFFFFF) + 2; 501 // sign-extend 24-to-32 of real_dst 502 if (real_dst & 0x00800000) 503 real_dst |= 0xFF000000; 504 else 505 real_dst &= 0x00FFFFFF; 506 507 real_dst <<= 2; 508 real_dst += S; 509 510 gen_armle_goto(fixup, (char*)real_dst); 511 512 /* Delta is in bytes .. */ 513 delta = (((Elf_Word)fixup) - ((Elf_Word)pP) - 8); 514 deltaTop8 = (delta >> 24) & 0xFF; 515 if (deltaTop8 != 0 && deltaTop8 != 0xFF) { 516 fprintf(stderr,"R_ARM_PC24: out of range delta 0x%x for %s\n", 517 delta, symbol); 518 exit(1); 519 } 520 delta >>= 2; 521 w = *pP; 522 w &= 0xFF000000; 523 w |= (0x00FFFFFF & delta ); 524 *pP = w; 525 break; 526 } 527 case R_ARM_ABS32: 528 *pP = value; 529 break; 530# endif 531 default: 532 fprintf(stderr, 533 "%s: unhandled ELF relocation(Rel) type %d\n\n", 534 oc->fileName, ELF_R_TYPE(info)); 535 return 0; 536 } 537 538 } 539 return 1; 540} 541 542/* Do ELF relocations for which explicit addends are supplied. 543 sparc-solaris relocations appear to be of this form. */ 544static int 545do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC, 546 Elf_Shdr* shdr, int shnum, 547 Elf_Sym* stab, char* strtab ) 548{ 549 int j; 550 char *symbol; 551 Elf_Addr targ; 552 Elf_Rela* rtab = (Elf_Rela*) (ehdrC + shdr[shnum].sh_offset); 553 int nent = shdr[shnum].sh_size / sizeof(Elf_Rela); 554 int target_shndx = shdr[shnum].sh_info; 555 int symtab_shndx = shdr[shnum].sh_link; 556 557 stab = (Elf_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset); 558 targ = (Elf_Addr) (ehdrC + shdr[ target_shndx ].sh_offset); 559 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d", 560 target_shndx, symtab_shndx )); 561 562 for (j = 0; j < nent; j++) { 563#if defined(DEBUG) || defined(sparc_TARGET_ARCH) || defined(ia64_TARGET_ARCH) 564 /* This #ifdef only serves to avoid unused-var warnings. */ 565 Elf_Addr offset = rtab[j].r_offset; 566 Elf_Addr P = targ + offset; 567#endif 568 Elf_Addr info = rtab[j].r_info; 569 Elf_Addr A = rtab[j].r_addend; 570 Elf_Addr S; 571 Elf_Addr value; 572# if defined(sparc_TARGET_ARCH) 573 Elf_Word* pP = (Elf_Word*)P; 574 Elf_Word w1, w2; 575# elif defined(ia64_TARGET_ARCH) 576 Elf64_Xword *pP = (Elf64_Xword *)P; 577 Elf_Addr addr; 578# endif 579 580 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p %6p) ", 581 j, (void*)offset, (void*)info, 582 (void*)A )); 583 if (!info) { 584 IF_DEBUG(linker,belch( " ZERO" )); 585 S = 0; 586 } else { 587 Elf_Sym sym = stab[ELF_R_SYM(info)]; 588 /* First see if it is a local symbol. */ 589 if (ELF_ST_BIND(sym.st_info) == STB_LOCAL) { 590 /* Yes, so we can get the address directly from the ELF symbol 591 table. */ 592 symbol = sym.st_name==0 ? "(noname)" : strtab+sym.st_name; 593 S = (Elf_Addr) 594 (ehdrC + shdr[ sym.st_shndx ].sh_offset 595 + stab[ELF_R_SYM(info)].st_value); 596#ifdef ELF_FUNCTION_DESC 597 /* Make a function descriptor for this function */ 598 if (S && ELF_ST_TYPE(sym.st_info) == STT_FUNC) { 599 S = allocateFunctionDesc(S + A); 600 A = 0; 601 } 602#endif 603 } else { 604 /* No, so look up the name in our global table. */ 605 symbol = strtab + sym.st_name; 606 S = (Elf_Addr)lookupSymbol( symbol ); 607 608#ifdef ELF_FUNCTION_DESC 609 /* If a function, already a function descriptor - we would 610 have to copy it to add an offset. */ 611 if (S && (ELF_ST_TYPE(sym.st_info) == STT_FUNC) && (A != 0)) 612 belch("%s: function %s with addend %p", oc->fileName, symbol, (void *)A); 613#endif 614 } 615 if (!S) { 616 fprintf(stderr,"%s: unknown symbol `%s'\n", oc->fileName, symbol); 617 return 0; 618 } 619 IF_DEBUG(linker,belch( "`%s' resolves to %p\n", symbol, (void*)S )); 620 } 621 622 IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p S = %p A = %p\n", 623 (void*)P, (void*)S, (void*)A )); 624 /* checkProddableBlock ( oc, (void*)P ); */ 625 626 value = S + A; 627 628 switch (ELF_R_TYPE(info)) { 629# if defined(sparc_TARGET_ARCH) 630 case R_SPARC_WDISP30: 631 w1 = *pP & 0xC0000000; 632 w2 = (Elf_Word)((value - P) >> 2); 633 ASSERT((w2 & 0xC0000000) == 0); 634 w1 |= w2; 635 *pP = w1; 636 break; 637 case R_SPARC_HI22: 638 w1 = *pP & 0xFFC00000; 639 w2 = (Elf_Word)(value >> 10); 640 ASSERT((w2 & 0xFFC00000) == 0); 641 w1 |= w2; 642 *pP = w1; 643 break; 644 case R_SPARC_LO10: 645 w1 = *pP & ~0x3FF; 646 w2 = (Elf_Word)(value & 0x3FF); 647 ASSERT((w2 & ~0x3FF) == 0); 648 w1 |= w2; 649 *pP = w1; 650 break; 651 /* According to the Sun documentation: 652 R_SPARC_UA32 653 This relocation type resembles R_SPARC_32, except it refers to an 654 unaligned word. That is, the word to be relocated must be treated 655 as four separate bytes with arbitrary alignment, not as a word 656 aligned according to the architecture requirements. 657 658 (JRS: which means that freeloading on the R_SPARC_32 case 659 is probably wrong, but hey ...) 660 */ 661 case R_SPARC_UA32: 662 case R_SPARC_32: 663 w2 = (Elf_Word)value; 664 *pP = w2; 665 break; 666# elif defined(ia64_TARGET_ARCH) 667 case R_IA64_DIR64LSB: 668 case R_IA64_FPTR64LSB: 669 *pP = value; 670 break; 671 case R_IA64_PCREL64LSB: 672 *pP = value - P; 673 break; 674 case R_IA64_SEGREL64LSB: 675 addr = findElfSegment(ehdrC, value); 676 *pP = value - addr; 677 break; 678 case R_IA64_GPREL22: 679 ia64_reloc_gprel22(P, value); 680 break; 681 case R_IA64_LTOFF22: 682 case R_IA64_LTOFF22X: 683 case R_IA64_LTOFF_FPTR22: 684 addr = allocateGOTEntry(value); 685 ia64_reloc_gprel22(P, addr); 686 break; 687 case R_IA64_PCREL21B: 688 ia64_reloc_pcrel21(P, S, oc); 689 break; 690 case R_IA64_LDXMOV: 691 /* This goes with R_IA64_LTOFF22X and points to the load to 692 * convert into a move. We don't implement relaxation. */ 693 break; 694# endif 695 default: 696 fprintf(stderr, 697 "%s: unhandled ELF relocation(RelA) type %d\n", 698 oc->fileName, ELF_R_TYPE(info)); 699 return 0; 700 } 701 702 } 703 return 1; 704} 705 706 707static int 708ocResolve_ELF ( ObjectCode* oc ) 709{ 710 char *strtab; 711 int shnum, ok; 712 Elf_Sym* stab = NULL; 713 char* ehdrC = (char*)(oc->image); 714 Elf_Ehdr* ehdr = (Elf_Ehdr*) ehdrC; 715 Elf_Shdr* shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff); 716 char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset; 717 718 /* first find "the" symbol table */ 719 stab = (Elf_Sym*) findElfSection ( ehdrC, SHT_SYMTAB ); 720 721 /* also go find the string table */ 722 strtab = findElfSection ( ehdrC, SHT_STRTAB ); 723 724 if (stab == NULL || strtab == NULL) { 725 fprintf(stderr,"%s: can't find string or symbol table\n", oc->fileName); 726 return 0; 727 } 728 729 /* Process the relocation sections. */ 730 for (shnum = 0; shnum < ehdr->e_shnum; shnum++) { 731 732 /* Skip sections called ".rel.stab". These appear to contain 733 relocation entries that, when done, make the stabs debugging 734 info point at the right places. We ain't interested in all 735 dat jazz, mun. */ 736 if (0 == memcmp(".rel.stab", sh_strtab + shdr[shnum].sh_name, 9)) 737 continue; 738 739 if (shdr[shnum].sh_type == SHT_REL ) { 740 ok = do_Elf_Rel_relocations ( oc, ehdrC, shdr, 741 shnum, stab, strtab ); 742 if (!ok) return ok; 743 } 744 else 745 if (shdr[shnum].sh_type == SHT_RELA) { 746 ok = do_Elf_Rela_relocations ( oc, ehdrC, shdr, 747 shnum, stab, strtab ); 748 if (!ok) return ok; 749 } 750 } 751 752 /* Free the local symbol table; we won't need it again. */ 753 delete_StringMap(oc->lochash); 754 oc->lochash = NULL; 755 756 return 1; 757} 758 759 760/////////////////////////////////////////////////////////////////// 761/////////////////////////////////////////////////////////////////// 762/////////////////////////////////////////////////////////////////// 763// 764// VERIFY 765 766static int 767ocVerifyImage_ELF ( ObjectCode* oc ) 768{ 769 Elf_Shdr* shdr; 770 Elf_Sym* stab; 771 int i, j, nent, nstrtab, nsymtabs; 772 char* sh_strtab; 773 char* strtab; 774 775 char* ehdrC = (char*)(oc->image); 776 Elf_Ehdr* ehdr = (Elf_Ehdr*)ehdrC; 777 778 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 || 779 ehdr->e_ident[EI_MAG1] != ELFMAG1 || 780 ehdr->e_ident[EI_MAG2] != ELFMAG2 || 781 ehdr->e_ident[EI_MAG3] != ELFMAG3) { 782 fprintf(stderr,"%s: not an ELF object\n", oc->fileName); 783 return 0; 784 } 785 786 if (ehdr->e_ident[EI_CLASS] != ELFCLASS) { 787 fprintf(stderr,"%s: unsupported ELF format\n", oc->fileName); 788 return 0; 789 } 790 791 if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) { 792 if (debug_linker) 793 fprintf(stderr, "Is little-endian\n" ); 794 } else 795 if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) { 796 if (debug_linker) 797 fprintf(stderr, "Is big-endian\n" ); 798 } else { 799 fprintf(stderr,"%s: unknown endiannness\n", oc->fileName); 800 return 0; 801 } 802 803 if (ehdr->e_type != ET_REL) { 804 fprintf(stderr,"%s: not a relocatable object (.o) file\n", oc->fileName); 805 return 0; 806 } 807 if (debug_linker) 808 fprintf(stderr, "Is a relocatable object (.o) file\n" ); 809 810 if (debug_linker) 811 fprintf(stderr, "Architecture is " ); 812 switch (ehdr->e_machine) { 813 case EM_386: if (debug_linker) fprintf(stderr, "x86\n" ); break; 814 case EM_SPARC: if (debug_linker) fprintf(stderr, "sparc\n" ); break; 815 case EM_ARM: if (debug_linker) fprintf(stderr, "arm\n" ); break; 816#ifdef EM_IA_64 817 case EM_IA_64: if (debug_linker) fprintf(stderr, "ia64\n" ); break; 818#endif 819 default: if (debug_linker) fprintf(stderr, "unknown\n" ); 820 fprintf(stderr,"%s: unknown architecture\n", oc->fileName); 821 return 0; 822 } 823 824 if (debug_linker>1) fprintf(stderr, 825 "\nSection header table: start %d, n_entries %d, ent_size %d\n", 826 ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize ); 827 828 assert (ehdr->e_shentsize == sizeof(Elf_Shdr)); 829 830 shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff); 831 832 if (ehdr->e_shstrndx == SHN_UNDEF) { 833 fprintf(stderr,"%s: no section header string table\n", oc->fileName); 834 return 0; 835 } else { 836 if (debug_linker>1) 837 fprintf(stderr, "Section header string table is section %d\n", 838 ehdr->e_shstrndx); 839 sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset; 840 } 841 842 for (i = 0; i < ehdr->e_shnum; i++) { 843 if (debug_linker>1) fprintf(stderr, "%2d: ", i ); 844 if (debug_linker>1) fprintf(stderr, "type=%2d ", (int)shdr[i].sh_type ); 845 if (debug_linker>1) fprintf(stderr, "size=%4d ", (int)shdr[i].sh_size ); 846 if (debug_linker>1) fprintf(stderr, "offs=%4d ", (int)shdr[i].sh_offset ); 847 if (debug_linker>1) fprintf(stderr, " (%p .. %p) ", 848 ehdrC + shdr[i].sh_offset, 849 ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1); 850 851 if (shdr[i].sh_type == SHT_REL) { 852 if (debug_linker>1) fprintf(stderr, "Rel " ); 853 } else if (shdr[i].sh_type == SHT_RELA) { 854 if (debug_linker>1) fprintf(stderr, "RelA " ); 855 } else { 856 if (debug_linker>1) fprintf(stderr," "); 857 } 858 if (sh_strtab) { 859 if (debug_linker>1) fprintf(stderr, "sname=%s\n", 860 sh_strtab + shdr[i].sh_name ); 861 } 862 } 863 864 if (debug_linker>1) fprintf(stderr, "\nString tables\n" ); 865 strtab = NULL; 866 nstrtab = 0; 867 for (i = 0; i < ehdr->e_shnum; i++) { 868 if (shdr[i].sh_type == SHT_STRTAB 869 /* Ignore the section header's string table. */ 870 && i != ehdr->e_shstrndx 871 /* Ignore string tables named .stabstr, as they contain 872 debugging info. */ 873 && 0 != memcmp(".stabstr", sh_strtab + shdr[i].sh_name, 8) 874 ) { 875 if (debug_linker>1) 876 fprintf(stderr," section %d is a normal string table\n", i ); 877 strtab = ehdrC + shdr[i].sh_offset; 878 nstrtab++; 879 } 880 } 881 if (nstrtab != 1) { 882 fprintf(stderr,"%s: no string tables, or too many\n", oc->fileName); 883 return 0; 884 } 885 886 nsymtabs = 0; 887 if (debug_linker>1) fprintf(stderr, "\nSymbol tables\n" ); 888 for (i = 0; i < ehdr->e_shnum; i++) { 889 if (shdr[i].sh_type != SHT_SYMTAB) continue; 890 if (debug_linker>1) fprintf(stderr, "section %d is a symbol table\n", i ); 891 nsymtabs++; 892 stab = (Elf_Sym*) (ehdrC + shdr[i].sh_offset); 893 nent = shdr[i].sh_size / sizeof(Elf_Sym); 894 if (debug_linker>1) fprintf(stderr, 895 " number of entries is apparently %d (%d rem)\n", 896 nent, 897 shdr[i].sh_size % sizeof(Elf_Sym) 898 ); 899 if (0 != shdr[i].sh_size % sizeof(Elf_Sym)) { 900 fprintf(stderr,"%s: non-integral number of symbol table entries\n", 901 oc->fileName); 902 return 0; 903 } 904 for (j = 0; j < nent; j++) { 905 if (debug_linker>1) fprintf(stderr, " %2d ", j ); 906 if (debug_linker>1) fprintf(stderr, " sec=%-5d size=%-3d val=%5p ", 907 (int)stab[j].st_shndx, 908 (int)stab[j].st_size, 909 (char*)stab[j].st_value ); 910 911 if (debug_linker>1) fprintf(stderr, "type=" ); 912 switch (ELF_ST_TYPE(stab[j].st_info)) { 913 case STT_NOTYPE: if (debug_linker>1) fprintf(stderr, "notype " ); break; 914 case STT_OBJECT: if (debug_linker>1) fprintf(stderr, "object " ); break; 915 case STT_FUNC : if (debug_linker>1) fprintf(stderr, "func " ); break; 916 case STT_SECTION: if (debug_linker>1) fprintf(stderr, "section" ); break; 917 case STT_FILE: if (debug_linker>1) fprintf(stderr, "file " ); break; 918 default: if (debug_linker>1) fprintf(stderr, "? " ); break; 919 } 920 if (debug_linker>1) fprintf(stderr, " " ); 921 922 if (debug_linker>1) fprintf(stderr, "bind=" ); 923 switch (ELF_ST_BIND(stab[j].st_info)) { 924 case STB_LOCAL : if (debug_linker>1) fprintf(stderr, "local " ); break; 925 case STB_GLOBAL: if (debug_linker>1) fprintf(stderr, "global" ); break; 926 case STB_WEAK : if (debug_linker>1) fprintf(stderr, "weak " ); break; 927 default: if (debug_linker>1) fprintf(stderr, "? " ); break; 928 } 929 if (debug_linker>1) fprintf(stderr, " " ); 930 931 if (debug_linker>1) fprintf(stderr, "name=%s\n", strtab + stab[j].st_name ); 932 } 933 } 934 935 if (nsymtabs == 0) { 936 fprintf(stderr,"%s: didn't find any symbol tables\n", oc->fileName); 937 return 0; 938 } 939 940 return 1; 941} 942 943 944/////////////////////////////////////////////////////////////////// 945/////////////////////////////////////////////////////////////////// 946/////////////////////////////////////////////////////////////////// 947// 948// GETNAMES 949 950static int 951ocGetNames_ELF ( ObjectCode* oc ) 952{ 953 int i, j, k, nent; 954 Elf_Sym* stab; 955 956 char* ehdrC = (char*)(oc->image); 957 Elf_Ehdr* ehdr = (Elf_Ehdr*)ehdrC; 958 char* strtab = findElfSection ( ehdrC, SHT_STRTAB ); 959 Elf_Shdr* shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff); 960 961 char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset; 962 char* sec_name; 963 964 assert(global_symbol_table != NULL); 965 966 if (!strtab) { 967 fprintf(stderr,"%s: no strtab\n", oc->fileName); 968 return 0; 969 } 970 971 k = 0; 972 for (i = 0; i < ehdr->e_shnum; i++) { 973 /* Figure out what kind of section it is. Logic derived from 974 Figure 1.14 ("Special Sections") of the ELF document 975 ("Portable Formats Specification, Version 1.1"). */ 976 Elf_Shdr hdr = shdr[i]; 977 SectionKind kind = SECTIONKIND_OTHER; 978 int is_bss = FALSE; 979 980 if (hdr.sh_type == SHT_PROGBITS 981 && (hdr.sh_flags & SHF_ALLOC) && (hdr.sh_flags & SHF_EXECINSTR)) { 982 /* .text-style section */ 983 kind = SECTIONKIND_CODE_OR_RODATA; 984 } 985 else 986 if (hdr.sh_type == SHT_PROGBITS 987 && (hdr.sh_flags & SHF_ALLOC) && (hdr.sh_flags & SHF_WRITE)) { 988 /* .data-style section */ 989 kind = SECTIONKIND_RWDATA; 990 } 991 else 992 if (hdr.sh_type == SHT_PROGBITS 993 && (hdr.sh_flags & SHF_ALLOC) && !(hdr.sh_flags & SHF_WRITE)) { 994 /* .rodata-style section */ 995 kind = SECTIONKIND_CODE_OR_RODATA; 996 } 997 else 998 if (hdr.sh_type == SHT_NOBITS 999 && (hdr.sh_flags & SHF_ALLOC) && (hdr.sh_flags & SHF_WRITE)) { 1000 /* .bss-style section */ 1001 kind = SECTIONKIND_RWDATA; 1002 is_bss = TRUE; 1003 } 1004 1005 if (is_bss && shdr[i].sh_size > 0) { 1006 /* This is a non-empty .bss section. Allocate zeroed space for 1007 it, and set its .sh_offset field such that 1008 ehdrC + .sh_offset == addr_of_zeroed_space. */ 1009 char* zspace = calloc(1, shdr[i].sh_size); 1010 shdr[i].sh_offset = ((char*)zspace) - ((char*)ehdrC); 1011 /* 1012 fprintf(stderr, "BSS section at 0x%x, size %d\n", 1013 zspace, shdr[i].sh_size); 1014 */ 1015 } 1016 1017 /* When loading objects compiled with -g, it seems there are 1018 relocations in various debug-info sections. So we'd better 1019 tell addProddableBlock to allow those bits to be prodded. */ 1020 //fprintf(stderr, "ZZZZZZZZZZ %s\n", sh_strtab + hdr.sh_name); 1021 sec_name = sh_strtab + shdr[i].sh_name; 1022 if (kind == SECTIONKIND_OTHER 1023 && (0 == strcmp(".debug_info", sec_name) 1024 || 0 == strcmp(".debug_line", sec_name) 1025 || 0 == strcmp(".debug_pubnames", sec_name) 1026 || 0 == strcmp(".debug_aranges", sec_name) 1027 || 0 == strcmp(".debug_frame", sec_name))) { 1028 kind = SECTIONKIND_CODE_OR_RODATA; 1029 } 1030 1031 /* fill in the section info */ 1032 if (kind != SECTIONKIND_OTHER && shdr[i].sh_size > 0) { 1033 addProddableBlock(oc, ehdrC + shdr[i].sh_offset, shdr[i].sh_size); 1034 //addSection(oc, kind, ehdrC + shdr[i].sh_offset, 1035 // ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1); 1036 } 1037 1038 if (shdr[i].sh_type != SHT_SYMTAB) continue; 1039 1040 /* copy stuff into this module's object symbol table */ 1041 stab = (Elf_Sym*) (ehdrC + shdr[i].sh_offset); 1042 nent = shdr[i].sh_size / sizeof(Elf_Sym); 1043 1044 oc->n_symbols = nent; 1045 oc->symbols = malloc(oc->n_symbols * sizeof(char*)); 1046 1047 for (j = 0; j < nent; j++) { 1048 1049 char isLocal = FALSE; /* avoids uninit-var warning */ 1050 char* ad = NULL; 1051 char* nm = strtab + stab[j].st_name; 1052 int secno = stab[j].st_shndx; 1053 1054 /* Figure out if we want to add it; if so, set ad to its 1055 address. Otherwise leave ad == NULL. */ 1056 1057 if (secno == SHN_COMMON) { 1058 isLocal = FALSE; 1059 ad = calloc(1, stab[j].st_size); 1060 /* 1061 fprintf(stderr, "COMMON symbol, size %d name %s\n", 1062 stab[j].st_size, nm); 1063 */ 1064 /* Pointless to do addProddableBlock() for this area, 1065 since the linker should never poke around in it. */ 1066 } 1067 else 1068 if ( ( ELF_ST_BIND(stab[j].st_info)==STB_GLOBAL 1069 || ELF_ST_BIND(stab[j].st_info)==STB_LOCAL 1070 ) 1071 /* and not an undefined symbol */ 1072 && stab[j].st_shndx != SHN_UNDEF 1073 /* and not in a "special section" */ 1074 && stab[j].st_shndx < SHN_LORESERVE 1075 && 1076 /* and it's a not a section or string table or anything silly */ 1077 ( ELF_ST_TYPE(stab[j].st_info)==STT_FUNC || 1078 ELF_ST_TYPE(stab[j].st_info)==STT_OBJECT || 1079 ELF_ST_TYPE(stab[j].st_info)==STT_NOTYPE 1080 ) 1081 ) { 1082 /* Section 0 is the undefined section, hence > and not >=. */ 1083 assert(secno > 0 && secno < ehdr->e_shnum); 1084 /* 1085 if (shdr[secno].sh_type == SHT_NOBITS) { 1086 fprintf(stderr, " BSS symbol, size %d off %d name %s\n", 1087 stab[j].st_size, stab[j].st_value, nm); 1088 } 1089 */ 1090 ad = ehdrC + shdr[ secno ].sh_offset + stab[j].st_value; 1091 if (ELF_ST_BIND(stab[j].st_info)==STB_LOCAL) { 1092 isLocal = TRUE; 1093 } else { 1094#ifdef ELF_FUNCTION_DESC 1095 /* dlsym() and the initialisation table both give us function 1096 * descriptors, so to be consistent we store function descriptors 1097 * in the symbol table */ 1098 if (ELF_ST_TYPE(stab[j].st_info) == STT_FUNC) 1099 ad = (char *)allocateFunctionDesc((Elf_Addr)ad); 1100#endif 1101 if (debug_linker) 1102 fprintf(stderr, "addOTabName(GLOB): %10p %s %s\n", 1103 ad, oc->fileName, nm ); 1104 isLocal = FALSE; 1105 } 1106 } 1107 1108 /* And the decision is ... */ 1109 1110 if (ad != NULL) { 1111 assert(nm != NULL); 1112 oc->symbols[j] = nm; 1113 /* Acquire! */ 1114 if (isLocal) { 1115 /* Ignore entirely. */ 1116 } else { 1117 //ghciInsertStrHashTable(oc->fileName, global_symbol_table, nm, ad); 1118 paranoid_addto_StringMap(global_symbol_table, nm, ad); 1119 } 1120 } else { 1121 /* Skip. */ 1122 if (debug_linker>1) fprintf(stderr, "skipping `%s'\n", 1123 strtab + stab[j].st_name ); 1124 /* 1125 fprintf(stderr, 1126 "skipping bind = %d, type = %d, shndx = %d `%s'\n", 1127 (int)ELF_ST_BIND(stab[j].st_info), 1128 (int)ELF_ST_TYPE(stab[j].st_info), 1129 (int)stab[j].st_shndx, 1130 strtab + stab[j].st_name 1131 ); 1132 */ 1133 oc->symbols[j] = NULL; 1134 } 1135 1136 } 1137 } 1138 1139 return 1; 1140} 1141 1142 1143/////////////////////////////////////////////////////////////////// 1144/////////////////////////////////////////////////////////////////// 1145/////////////////////////////////////////////////////////////////// 1146// 1147// TOP-LEVEL CONTROL OF THE LINKER 1148 1149 1150/* --------------------------------------------------------------------- 1151 * Load an obj (populate the global symbol table, but don't resolve yet) 1152 * 1153 * Returns: 1 if ok, 0 on error. 1154 */ 1155static 1156int loadObj( char *path ) 1157{ 1158 ObjectCode* oc; 1159 struct stat st; 1160 int r; 1161 int fd, pagesize; 1162 char* p; 1163 1164 initLinker(); 1165 1166 fprintf(stderr, "==== loadObj %s ====\n", path ); 1167 1168 /* Check that we haven't already loaded this object. */ 1169 { 1170 ObjectCode *o; 1171 int is_dup = 0; 1172 for (o = global_object_list; o; o = o->next) { 1173 if (0 == strcmp(o->fileName, path)) 1174 is_dup = 1; 1175 } 1176 if (is_dup) { 1177 fprintf(stderr, 1178 "\n\n" 1179 "GHCi runtime linker: warning: looks like you're trying to load the\n" 1180 "same object file twice:\n" 1181 " %s\n" 1182 , path); 1183 exit(1); 1184 } 1185 } 1186 1187 oc = malloc(sizeof(ObjectCode)); 1188 1189 oc->formatName = "ELF"; 1190 1191 r = stat(path, &st); 1192 if (r == -1) { return 0; } 1193 1194 /* sigh, strdup() isn't a POSIX function, so do it the long way */ 1195 oc->fileName = malloc( strlen(path)+1 ); 1196 strcpy(oc->fileName, path); 1197 1198 oc->fileSize = st.st_size; 1199 oc->symbols = NULL; 1200 oc->sections = NULL; 1201 oc->lochash = new_StringMap(); 1202 oc->proddables = NULL; 1203 oc->fixup = NULL; 1204 oc->fixup_used = 0; 1205 oc->fixup_size = 0; 1206 1207 /* chain it onto the list of objects */ 1208 oc->next = global_object_list; 1209 global_object_list = oc; 1210 1211 fd = open(path, O_RDONLY); 1212 if (fd == -1) { 1213 fprintf(stderr,"loadObj: can't open `%s'\n", path); 1214 exit(1); 1215 } 1216 1217 /* Allocate a 1-page area just prior to the image, so we can put 1218 fixup code fragments there. Used for doing R_ARM_PC24 1219 relocations for jump distances > 64M. */ 1220 1221 pagesize = getpagesize(); 1222 p = memalign(pagesize, N_FIXUP_PAGES * pagesize 1223 + oc->fileSize); 1224 1225 if (p == NULL) { 1226 fprintf(stderr,"loadObj: failed to allocate space for `%s'\n", path); 1227 exit(1); 1228 } 1229 1230 oc->fixup = p; 1231 oc->fixup_size = N_FIXUP_PAGES * pagesize; 1232 oc->fixup_used = 0; 1233 oc->image = &(p[ oc->fixup_size ]); 1234 1235 r = read(fd, oc->image, oc->fileSize); 1236 if (r != oc->fileSize) { 1237 fprintf(stderr,"loadObj: failed to read `%s'\n", path); 1238 exit(1); 1239 } 1240 1241 fprintf(stderr, "loaded %s at %p (fixup = %p)\n", 1242 oc->fileName, oc->image, oc->fixup ); 1243 1244 close(fd); 1245 1246 /* verify the in-memory image */ 1247 r = ocVerifyImage_ELF ( oc ); 1248 if (!r) { return r; } 1249 1250 /* build the symbol list for this image */ 1251 r = ocGetNames_ELF ( oc ); 1252 if (!r) { return r; } 1253 1254 /* loaded, but not resolved yet */ 1255 oc->status = OBJECT_LOADED; 1256 1257 return 1; 1258} 1259 1260 1261 1262/* --------------------------------------------------------------------------- 1263 * resolve all the currently unlinked objects in memory 1264 * 1265 * Returns: 1 if ok, 0 on error. 1266 */ 1267static 1268int resolveObjs( void ) 1269{ 1270 ObjectCode *oc; 1271 int r; 1272 1273 initLinker(); 1274 1275 for (oc = global_object_list; oc; oc = oc->next) { 1276 if (oc->status != OBJECT_RESOLVED) { 1277 r = ocResolve_ELF ( oc ); 1278 if (!r) { return r; } 1279 oc->status = OBJECT_RESOLVED; 1280 } 1281 } 1282 return 1; 1283} 1284 1285 1286/* --------------------------------------------------------------------------- 1287 * Top-level linker. 1288 */ 1289 1290/* Load and link a bunch of .o's, and return the address of 1291 'main'. Or NULL if something borks. 1292*/ 1293void* linker_top_level_LINK ( int n_object_names, char** object_names ) 1294{ 1295 int r, i; 1296 void* mainp; 1297 1298 initLinker(); 1299 for (i = 0; i < n_object_names; i++) { 1300 //fprintf(stderr, "linkloop %d %s\n", i, object_names[i] ); 1301 r = loadObj( object_names[i] ); 1302 if (r != 1) return NULL; 1303 } 1304 r = resolveObjs(); 1305 if (r != 1) return NULL; 1306 mainp = search_StringMap ( global_symbol_table, "main" ); 1307 if (mainp == NULL) return NULL; 1308 printf("Linker: success!\n"); 1309 return mainp; 1310} 1311 1312 1313#if 1 1314int main ( int argc, char** argv ) 1315{ 1316 void* mainp; 1317 linker_top_level_LINK( argc - 1 , &argv[1]); 1318 /* find and run "main" */ 1319 1320 mainp = search_StringMap ( global_symbol_table, "main" ); 1321 if (mainp == NULL) { 1322 fprintf(stderr, "no binding for main\n"); 1323 exit(1); 1324 } 1325 1326 printf("\nSTARTING PROGRAM\n"); 1327 ( (int(*)(int,char**)) mainp ) (argc,argv); 1328 printf("FINISHED\n"); 1329 1330 return 0; 1331} 1332#endif 1333 1334//////////////////////////////////////////////////////////////////////////// 1335//////////////////////////////////////////////////////////////////////////// 1336//////////////////////////////////////////////////////////////////////////// 1337//////////////////////////////////////////////////////////////////////////// 1338//////////////////////////////////////////////////////////////////////////// 1339//////////////////////////////////////////////////////////////////////////// 1340// 1341// VIRTUAL MACHINE ... 1342 1343/* --------------------------------------------------------- */ 1344/* SIMULATED STATE */ 1345/* --------------------------------------------------------- */ 1346 1347typedef unsigned int Word; 1348 1349/* Stack for the simulation */ 1350Word* sim_stack; 1351 1352/* Stop when we get a jump to here. */ 1353char* stop_at; 1354 1355 1356/* ARM state */ 1357/* r0 .. r15, flags */ 1358Word regs_arm[16+1]; 1359 1360#define REG_PC 15 1361#define REG_SP 14 1362 1363 1364//--------------------------------------------- 1365 1366/* Calling convention: enter the translation with r0 pointing at 1367 regs_arm. Translation may trash r1 .. r12 inclusive. Translation 1368 should update all regs in regs_arm, and put the next pc value 1369 in regs_arm[REG_PC]. */ 1370 1371static 1372void run_translation ( char* trans, char* baseblock ) 1373{ 1374 /* r0 holds trans */ 1375 __asm __volatile 1376 ("stmfd sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13}\n\t" 1377 "mov r12, %0\n\t" 1378 "mov r0, %1\n\t" 1379 "bl r12\n\t" 1380 "ldmea sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13}\n\t" 1381 : 1382 : "ir" (trans), "ir" (baseblock) ); 1383} 1384 1385 1386 1387 1388/* Called by Haskell to initialise the simulated machine. The 1389 supplied address is the entry point of some procedure to call. */ 1390 1391/* EXPORTED */ 1392void initialise_machine ( char* first_pc ) 1393{ 1394 static char start[12]; 1395 Word w = (Word)first_pc; 1396 1397 n_transtab_used = 0; 1398 1399 sim_stack = malloc(10000 * sizeof(Word)); 1400 regs_arm[REG_SP] = (Word)(&sim_stack[9999]); 1401 1402 regs_arm[REG_PC] = (Word)first_pc; 1403 1404 /* Generate this. Note, we'll be returning directly to the 1405 data, so the JIT must stop at this point! */ 1406 /* 1407 3 0000 00C09FE5 ldr ip, value 1408 4 0004 FEFFFFEB bl ip 1409 5 value: 1410 6 0008 44332211 .word 0x11223344 1411 */ 1412 start[0] = 0x00; start[1] = 0xC0; start[2] = 0x9F; start[3] = 0xE5; 1413 start[4] = 0xFE; start[5] = 0xFF; start[6] = 0xFF; start[7] = 0xEB; 1414 start[8] = w & 0xFF; w >>= 8; 1415 start[9] = w & 0xFF; w >>= 8; 1416 start[10] = w & 0xFF; w >>= 8; 1417 start[11] = w & 0xFF; w >>= 8; 1418 1419 stop_at = &start[8]; 1420 arm_notify_new_code(stop_at, 12); 1421} 1422 1423