1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * 26 * Binary compatibility ld.so. Intercepts the reference of a pre-SVR4 27 * SunOS executable to the dynamic linker, and then redirects to the 28 * "real" post-SVR4 SunOS ld.so. 29 */ 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /* 33 * Import data structures (N.B.: from 5.x). 34 */ 35 #include <sys/types.h> 36 #include <sys/mman.h> 37 #include <sys/fcntl.h> 38 #include <sys/stat.h> 39 #include <sys/sysconfig.h> 40 #include <sys/auxv.h> 41 #include <sys/archsystm.h> 42 #include <elf.h> 43 #include <link.h> 44 45 /* 46 * Relocation manifest constants and macros. 47 */ 48 #define ALIGN(x, a) ((int)(x) & ~((int)(a) - 1)) 49 #define ROUND(x, a) (((int)(x) + ((int)(a) - 1)) & \ 50 ~((int)(a) - 1)) 51 #define DYNAMIC_VERSION2 2 52 #define RELOC_SIZE (sizeof (struct relocation_info)) 53 #define RELOCOFF(x) (x)->v2->ld_rel 54 #define MASK(n) ((1<<(n))-1) 55 #define IN_RANGE(v, n) ((-(1<<((n)-1))) <= (v) && (v) < (1<<((n)-1))) 56 57 void aout_reloc_write(); 58 59 /* 60 * 4.x SunOS Dynamic Link Editor public definitions (much derived from 61 * SunOS 4.x <link.h>.) 62 */ 63 64 /* 65 * Dynamic linking information. With the exception of 66 * ld_loaded (determined at execution time) and ld_stab_hash (a special 67 * case of relocation handled at execution time), the values in this 68 * structure reflect offsets from the containing link_dynamic structure. 69 */ 70 struct link_dynamic_1 { 71 struct link_map *ld_loaded; /* list of loaded objects */ 72 long ld_need; /* list of needed objects */ 73 long ld_rules; /* search rules for library objects */ 74 long ld_got; /* global offset table */ 75 long ld_plt; /* procedure linkage table */ 76 long ld_rel; /* relocation table */ 77 long ld_hash; /* symbol hash table */ 78 long ld_stab; /* symbol table itself */ 79 long (*ld_stab_hash)(); /* "pointer" to symbol hash function */ 80 long ld_buckets; /* number of hash buckets */ 81 long ld_symbols; /* symbol strings */ 82 long ld_symb_size; /* size of symbol strings */ 83 long ld_text; /* size of text area */ 84 }; 85 86 struct link_dynamic_2 { 87 struct link_map *ld_loaded; /* list of loaded objects */ 88 long ld_need; /* list of needed objects */ 89 long ld_rules; /* search rules for library objects */ 90 long ld_got; /* global offset table */ 91 long ld_plt; /* procedure linkage table */ 92 long ld_rel; /* relocation table */ 93 long ld_hash; /* symbol hash table */ 94 long ld_stab; /* symbol table itself */ 95 long (*ld_stab_hash)(); /* "pointer" to symbol hash function */ 96 long ld_buckets; /* number of hash buckets */ 97 long ld_symbols; /* symbol strings */ 98 long ld_symb_size; /* size of symbol strings */ 99 long ld_text; /* size of text area */ 100 long ld_plt_sz; /* size of procedure linkage table */ 101 }; 102 103 /* 104 * Debugger interface structure. 105 */ 106 struct ld_debug { 107 int ldd_version; /* version # of interface */ 108 int ldd_in_debugger; /* a debugger is running us */ 109 int ldd_sym_loaded; /* we loaded some symbols */ 110 char *ldd_bp_addr; /* place for ld-generated bpt */ 111 int ldd_bp_inst; /* instruction which was there */ 112 struct rtc_symb *ldd_cp; /* commons we built */ 113 }; 114 115 /* 116 * Structure associated with each object which may be or which requires 117 * execution-time link editing. Used by the run-time linkage editor to 118 * identify needed objects and symbol definitions and references. 119 */ 120 struct link_dynamic { 121 int ld_version; 122 struct ld_debug *ldd; 123 union { 124 struct link_dynamic_1 *ld_1; 125 struct link_dynamic_2 *ld_2; 126 } ld_un; 127 }; 128 129 struct old_link_dynamic { 130 int ld_version; /* version # of this structure */ 131 union { 132 struct link_dynamic_1 ld_1; 133 } ld_un; 134 135 int in_debugging; 136 int sym_loaded; 137 char *bp_addr; 138 int bp_inst; 139 struct rtc_symb *cp; /* pointer to an array of runtime */ 140 /* allocated common symbols. */ 141 }; 142 143 #define v2 ld_un.ld_2 /* short hands */ 144 #define v1 ld_un.ld_1 145 146 /* 147 * SunOS 4.x SPARC relocation types and relocation record. Note that 148 * these, among other things, make this program not portable to things 149 * other than SPARC. 150 */ 151 enum reloc_type { 152 RELOC_8, RELOC_16, RELOC_32, /* simplest relocs */ 153 RELOC_DISP8, RELOC_DISP16, RELOC_DISP32, 154 /* Disp's (pc-rel) */ 155 RELOC_WDISP30, RELOC_WDISP22, /* SR word disp's */ 156 RELOC_HI22, RELOC_22, /* SR 22-bit relocs */ 157 RELOC_13, RELOC_LO10, /* SR 13&10-bit relocs */ 158 RELOC_SFA_BASE, RELOC_SFA_OFF13, /* SR S.F.A. relocs */ 159 RELOC_BASE10, RELOC_BASE13, RELOC_BASE22, 160 /* PIC GOT references */ 161 RELOC_PC10, RELOC_PC22, /* PIC reference to GOT */ 162 RELOC_JMP_TBL, /* PIC call */ 163 RELOC_SEGOFF16, /* .so offset-in-segment */ 164 RELOC_GLOB_DAT, RELOC_JMP_SLOT, RELOC_RELATIVE, 165 /* ld.so relocation types */ 166 }; 167 168 struct relocation_info { 169 unsigned long int r_address; /* relocation addr */ 170 unsigned int r_index :24; /* segment index or symbol index */ 171 unsigned int r_extern : 1; /* if F, r_index==SEG#; if T, SYM idx */ 172 int : 2; /* <unused> */ 173 enum reloc_type r_type : 5; /* type of relocation to perform */ 174 long int r_addend; /* addend for relocation value */ 175 }; 176 177 /* 178 * Size of relocations. 179 */ 180 #define GETRELSZ(x) \ 181 (x->ld_version < 2 ? \ 182 ((struct old_link_dynamic *)x)->v1.ld_hash - \ 183 ((struct old_link_dynamic *)x)->v1.ld_rel : \ 184 (x)->v2->ld_hash - (x)->v2->ld_rel) 185 186 /* 187 * Interface between crt0 & ld.so. 188 */ 189 struct crt_i1 { 190 int crt_baseaddr; /* Address ld.so is at */ 191 int crt_dzfd; /* /dev/zero file descriptor */ 192 int crt_rlfd; /* ld.so file descriptor */ 193 struct link_dynamic *crt_udp; /* "main_" dynamic */ 194 char **crt_ep; /* environment strings */ 195 caddr_t crt_breakp; /* place to put initial breakpoint */ 196 }; 197 198 /* 199 * Structure we provide to ELF ld.so upon entry. 200 */ 201 Elf32_Boot eb[EB_MAX]; 202 203 /* 204 * Global data. 205 */ 206 char *program_name; /* used in messages */ 207 208 /* 209 * 4.0 ld.so main entry point. 210 */ 211 rtld(version, ip, dp, argp) 212 int version; /* interface version */ 213 struct crt_i1 *ip; /* interface passed from program */ 214 register struct link_dynamic *dp; /* ld.so dynamic pointer */ 215 caddr_t argp; /* pointer to begining of args */ 216 { 217 char *ldso; /* name of what we really want to be */ 218 int i, p; /* working */ 219 int r; /* working (# of *our* relocations */ 220 int page_size = 0; /* size of a page */ 221 struct relocation_info *rp; /* working pointer to our relocs */ 222 int fd; /* fd assigned to ld.so */ 223 Elf32_Ehdr *ehdr; /* ELF header of ld.so */ 224 Elf32_Phdr *phdr; /* first Phdr in file */ 225 Elf32_Phdr *pptr; /* working Phdr */ 226 Elf32_Phdr *lph; /* last loadable Phdr */ 227 Elf32_Phdr *fph = 0; /* first loadable Phdr */ 228 caddr_t maddr; /* pointer to mapping claim */ 229 Elf32_Off mlen; /* total mapping claim */ 230 caddr_t faddr; /* first program mapping of ld.so */ 231 Elf32_Off foff; /* file offset for segment mapping */ 232 Elf32_Off flen; /* file length for segment mapping */ 233 caddr_t addr; /* working mapping address */ 234 caddr_t zaddr; /* /dev/zero working mapping addr */ 235 Elf32_Boot *ebp; /* communication with ld.so */ 236 struct stat sb; /* stat buffer for sizing */ 237 auxv_t *ap; /* working aux pointer */ 238 void (* wrt)(); /* address of write/iflush routine */ 239 240 /* 241 * ld.so must itself be relocated, take care of this now. 242 * We can not refer to global data before this step is 243 * complete. Perform the relocation by stepping over all 244 * entries in the relocation table and turn them into 245 * absolute addresses. Note that, in order to avoid invoking 246 * as yet unrelocated items, we perform the relocation count 247 * by counting rather than risk invoking subroutine calls 248 * to intrinsic .div or .mul routines. Note also that we 249 * assume that there are no symbolic relocations to be 250 * performed here. 251 */ 252 dp->v2 = (struct link_dynamic_2 *) 253 ((caddr_t)dp->v2 + ip->crt_baseaddr); 254 r = 0; 255 i = GETRELSZ(dp); 256 while (i != 0) { 257 i -= RELOC_SIZE; 258 r++; 259 } 260 rp = (struct relocation_info *)(RELOCOFF(dp) + 261 (dp->ld_version < DYNAMIC_VERSION2 ? 262 (int)dp : ip->crt_baseaddr)); 263 264 /* 265 * Determine the location of the routine that will write the relocation. 266 * This hasn't yet been relocated so determine the real address using 267 * our base address. 268 */ 269 wrt = (void (*)())((caddr_t)aout_reloc_write + ip->crt_baseaddr); 270 271 /* 272 * Relocate ourselves - we only need RELOC_RELATIVE and RELOC_32. 273 * Note, if panic() was called its probable that it will barf as the 274 * corresponding plt wouldn't have been relocated yet. 275 */ 276 for (i = 0; i < r; i++) { 277 long *where = (long *)((caddr_t)rp->r_address + ip->crt_baseaddr); 278 long what = ip->crt_baseaddr; 279 long value; 280 281 switch (rp->r_type) { 282 case RELOC_RELATIVE: 283 what += *where << (32-22); 284 value = (*where & ~MASK(22)) | ((what >> (32-22)) & MASK(22)); 285 wrt(where, value); 286 where++; 287 what += (*where & MASK(10)); 288 value = (*where & ~MASK(10)) | (what & MASK(10)); 289 wrt(where, value); 290 break; 291 292 case RELOC_32: 293 what += *where; 294 wrt(where, what); 295 break; 296 297 default: 298 panic("unknown relocation type %d\n", rp->r_type); 299 break; 300 } 301 rp++; 302 } 303 304 /* 305 * We're relocated, we can now initialize things referencing 306 * static storage. 307 */ 308 ldso = "/usr/lib/ld.so.1"; 309 310 /* 311 * Close off the file descriptor used to get us here -- let it 312 * be available for the next (probable) use below. 313 */ 314 (void) close(ip->crt_rlfd); 315 316 /* 317 * Discover things about our environment: auxiliary vector (if 318 * any), arguments, program name, and the like. 319 */ 320 ebp = eb; 321 program_name = (char *)(argp + sizeof (int)); 322 if (version != 1) 323 panic("bad startup interface version of %d", 324 version); 325 ebp->eb_tag = EB_DYNAMIC, 326 (ebp++)->eb_un.eb_ptr = (Elf32_Addr)ip->crt_udp; 327 ebp->eb_tag = EB_ARGV, (ebp++)->eb_un.eb_ptr = (Elf32_Addr)program_name; 328 ebp->eb_tag = EB_ENVP, (ebp++)->eb_un.eb_ptr = (Elf32_Addr)ip->crt_ep; 329 ebp->eb_tag = EB_DEVZERO, 330 (ebp++)->eb_un.eb_val = (Elf32_Word)ip->crt_dzfd; 331 for (addr = (caddr_t)ip->crt_ep; *addr; addr += sizeof (char *)) 332 ; 333 addr += sizeof (char *); 334 335 /* 336 * The kernel sends us an abbreviated aux vector with some 337 * potentially handy stuff that saves us on syscalls. 338 * 339 * Notes on 1226113 340 * 341 * The f77 compiler shipped as part of SC1.0 on 4.x creates binaries 342 * that use the _fix_libc_ feature of acc. This makes the resulting 343 * executable object dependent on the undocumented behaviour of 344 * libc's .rem and .div routines e.g. that .div returns the 345 * remainder in %o3 (and similarly .rem returns the division in %o3). 346 * 347 * The only simple solution is to disable hardware divide for 348 * all 4.x applications so that the old software routines that have 349 * this "support" in them are used instead. And we do that by 350 * clearing the divide-in-hardware flag from the aux vector before 351 * libc's .init routine gets to see it. Awful isn't it. 352 */ 353 ebp->eb_tag = EB_AUXV, (ebp++)->eb_un.eb_ptr = (Elf32_Addr)addr; 354 for (ap = (auxv_t *)addr; ap->a_type != AT_NULL; ap++) 355 if (ap->a_type == AT_PAGESZ) { 356 page_size = ap->a_un.a_val; 357 ebp->eb_tag = EB_PAGESIZE, (ebp++)->eb_un.eb_val = 358 (Elf32_Word)page_size; 359 } else if (ap->a_type == AT_SUN_HWCAP) 360 ap->a_un.a_val &= ~AV_SPARC_HWDIV_32x32; 361 362 /* 363 * If we didn't get a page size from looking in the auxiliary 364 * vector, we need to get one now. 365 */ 366 if (page_size == 0) { 367 page_size = sysconfig(_CONFIG_PAGESIZE); 368 ebp->eb_tag = EB_PAGESIZE, (ebp++)->eb_un.eb_val = 369 (Elf32_Word)page_size; 370 } 371 372 /* 373 * Map in the ELF-based ld.so. Note that we're mapping it as 374 * an ELF database, not as a program -- we just want to walk it's 375 * data structures. Further mappings will actually establish the 376 * program in the address space. 377 */ 378 if ((fd = open(ldso, O_RDONLY)) == -1) 379 panic("unable to open %s", ldso); 380 if (fstat(fd, &sb) == -1) 381 panic("unable to find size of %s", ldso); 382 ehdr = (Elf32_Ehdr *)mmap(0, sb.st_size, PROT_READ | PROT_EXEC, 383 MAP_SHARED, fd, 0); 384 if (ehdr == (Elf32_Ehdr *)-1) 385 panic("unable to map %s", ldso); 386 387 /* 388 * Validate the file we're looking at, ensure it has the correct 389 * ELF structures, such as: ELF magic numbers, coded for SPARC, 390 * is a ".so", etc. 391 */ 392 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 || 393 ehdr->e_ident[EI_MAG1] != ELFMAG1 || 394 ehdr->e_ident[EI_MAG2] != ELFMAG2 || 395 ehdr->e_ident[EI_MAG3] != ELFMAG3) 396 panic("%s is not an ELF file", ldso); 397 if (ehdr->e_ident[EI_CLASS] != ELFCLASS32 || 398 ehdr->e_ident[EI_DATA] != ELFDATA2MSB) 399 panic("%s has wrong class or data encoding", ldso); 400 if (ehdr->e_type != ET_DYN) 401 panic("%s is not a shared object", ldso); 402 if ((ehdr->e_machine != EM_SPARC) && 403 (ehdr->e_machine != EM_SPARC32PLUS)) 404 panic("%s is not a valid SPARC object: e_machine: %x", 405 ldso, ehdr->e_machine); 406 if (ehdr->e_version > EV_CURRENT) 407 panic("%s has bad ELF version of %d", ldso, ehdr->e_version); 408 409 /* 410 * Point at program headers and start figuring out what to load. 411 */ 412 phdr = (Elf32_Phdr *)((caddr_t)ehdr + ehdr->e_phoff); 413 for (p = 0, pptr = phdr; p < (int)ehdr->e_phnum; p++, 414 pptr = (Elf32_Phdr *)((caddr_t)pptr + ehdr->e_phentsize)) 415 if (pptr->p_type == PT_LOAD) { 416 if (fph == 0) { 417 fph = pptr; 418 } else if (pptr->p_vaddr <= lph->p_vaddr) 419 panic( 420 "%s invalid program header - segments out of order", ldso); 421 lph = pptr; 422 } 423 424 /* 425 * We'd better have at least one loadable segment. 426 */ 427 if (fph == 0) 428 panic("%s has no loadable segments", ldso); 429 430 /* 431 * Map enough address space to hold the program (as opposed to the 432 * file) represented by ld.so. The amount to be assigned is the 433 * range between the end of the last loadable segment and the 434 * beginning of the first PLUS the alignment of the first segment. 435 * mmap() can assign us any page-aligned address, but the relocations 436 * assume the alignments included in the program header. As an 437 * optimization, however, let's assume that mmap() will actually 438 * give us an aligned address -- since if it does, we can save 439 * an munmap() later on. If it doesn't -- then go try it again. 440 */ 441 mlen = ROUND((lph->p_vaddr + lph->p_memsz) - 442 ALIGN(fph->p_vaddr, page_size), page_size); 443 maddr = (caddr_t)mmap(0, mlen, PROT_READ | PROT_EXEC, 444 MAP_SHARED, fd, 0); 445 if (maddr == (caddr_t)-1) 446 panic("unable to reserve space for %s", ldso); 447 faddr = (caddr_t)ROUND(maddr, fph->p_align); 448 449 /* 450 * Check to see whether alignment skew was really needed. 451 */ 452 if (faddr != maddr) { 453 (void) munmap(maddr, mlen); 454 mlen = ROUND((lph->p_vaddr + lph->p_memsz) - 455 ALIGN(fph->p_vaddr, fph->p_align) + fph->p_align, 456 page_size); 457 maddr = (caddr_t)mmap(0, mlen, PROT_READ | PROT_EXEC, 458 MAP_SHARED, fd, 0); 459 if (maddr == (caddr_t)-1) 460 panic("unable to reserve space for %s", ldso); 461 faddr = (caddr_t)ROUND(maddr, fph->p_align); 462 } 463 ebp->eb_tag = EB_LDSO_BASE, (ebp++)->eb_un.eb_ptr = (Elf32_Addr)faddr; 464 465 /* 466 * We have the address space reserved, so map each loadable segment. 467 */ 468 for (pptr = phdr; (pptr - phdr) < (int)ehdr->e_phnum; pptr++) { 469 470 /* 471 * Skip non-loadable segments or segments that don't occupy 472 * any memory. 473 */ 474 if ((pptr->p_type != PT_LOAD) || (pptr->p_memsz == 0)) 475 continue; 476 477 /* 478 * Determine the file offset to which the mapping will 479 * directed (must be aligned) and how much to map (might 480 * be more than the file in the case of .bss.) 481 */ 482 foff = ALIGN(pptr->p_offset, page_size); 483 flen = pptr->p_memsz + (pptr->p_offset - foff); 484 485 /* 486 * Set address of this segment relative to our base. 487 */ 488 addr = (caddr_t)ALIGN(faddr + pptr->p_vaddr, page_size); 489 490 /* 491 * Unmap anything form the last mapping address to this 492 * one. 493 */ 494 if (addr - maddr) { 495 (void) munmap(maddr, addr - maddr); 496 mlen -= addr - maddr; 497 } 498 499 /* 500 * Determine the mapping protection from the section 501 * attributes. 502 */ 503 i = 0; 504 if (pptr->p_flags & PF_R) 505 i |= PROT_READ; 506 if (pptr->p_flags & PF_W) 507 i |= PROT_WRITE; 508 if (pptr->p_flags & PF_X) 509 i |= PROT_EXEC; 510 if ((caddr_t)mmap((caddr_t)addr, flen, i, 511 MAP_FIXED | MAP_PRIVATE, fd, foff) == (caddr_t)-1) 512 panic("unable to map a segment from %s", ldso); 513 514 /* 515 * If the memory occupancy of the segment overflows the 516 * definition in the file, we need to "zero out" the 517 * end of the mapping we've established, and if necessary, 518 * map some more space from /dev/zero. 519 */ 520 if (pptr->p_memsz > pptr->p_filesz) { 521 foff = (int)faddr + pptr->p_vaddr + pptr->p_filesz; 522 zaddr = (caddr_t)ROUND(foff, page_size); 523 _zero(foff, zaddr - foff); 524 r = (faddr + pptr->p_vaddr + pptr->p_memsz) - zaddr; 525 if (r > 0) 526 if ((caddr_t)mmap((caddr_t)zaddr, r, i, 527 MAP_FIXED | MAP_PRIVATE, ip->crt_dzfd, 528 0) == (caddr_t)-1) 529 panic( 530 "unable to map .bss /dev/zero for %s", 531 ldso); 532 } 533 534 /* 535 * Update the mapping claim pointer. 536 */ 537 maddr = addr + ROUND(flen, page_size); 538 mlen -= maddr - addr; 539 } 540 541 /* 542 * Unmap any final reservation. 543 */ 544 if (mlen > 0) 545 (void) munmap(maddr, mlen); 546 547 /* 548 * Clean up file descriptor space we've consumed. Pass along 549 * the /dev/zero file descriptor we got -- every cycle counts. 550 */ 551 (void) close(fd); 552 553 /* 554 * The call itself. Note that we start 1 instruction word in. 555 * The ELF ld.so contains an "entry vector" of branch instructions, 556 * which, for our interest are: 557 * +0: ba, a <normal startup> 558 * +4: ba, a <compatibility startup> 559 * By starting at the compatibility startup, the ELF ld.so knows 560 * that a pointer to "eb" is available to it and further knows 561 * how to calculate the offset to the program's arguments and 562 * other structures. 563 */ 564 ebp->eb_tag = EB_NULL, ebp->eb_un.eb_val = 0; 565 (*((void (*)())(ehdr->e_entry + faddr + sizeof (long))))(eb); 566 return (0); 567 } 568