link_elf.c revision 193511
1/*- 2 * Copyright (c) 1998-2000 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/sys/kern/link_elf.c 193511 2009-06-05 14:55:22Z rwatson $"); 29 30#include "opt_ddb.h" 31#include "opt_gdb.h" 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#ifdef GPROF 36#include <sys/gmon.h> 37#endif 38#include <sys/kernel.h> 39#include <sys/lock.h> 40#include <sys/malloc.h> 41#include <sys/mutex.h> 42#include <sys/mount.h> 43#include <sys/proc.h> 44#include <sys/namei.h> 45#include <sys/fcntl.h> 46#include <sys/vnode.h> 47#include <sys/linker.h> 48 49#include <machine/elf.h> 50 51#include <security/mac/mac_framework.h> 52 53#include <vm/vm.h> 54#include <vm/vm_param.h> 55#ifdef SPARSE_MAPPING 56#include <vm/vm_object.h> 57#include <vm/vm_kern.h> 58#include <vm/vm_extern.h> 59#endif 60#include <vm/pmap.h> 61#include <vm/vm_map.h> 62 63#include <sys/link_elf.h> 64 65#ifdef DDB_CTF 66#include <net/zlib.h> 67#endif 68 69#include "linker_if.h" 70 71#define MAXSEGS 4 72 73typedef struct elf_file { 74 struct linker_file lf; /* Common fields */ 75 int preloaded; /* Was file pre-loaded */ 76 caddr_t address; /* Relocation address */ 77#ifdef SPARSE_MAPPING 78 vm_object_t object; /* VM object to hold file pages */ 79#endif 80 Elf_Dyn* dynamic; /* Symbol table etc. */ 81 Elf_Hashelt nbuckets; /* DT_HASH info */ 82 Elf_Hashelt nchains; 83 const Elf_Hashelt* buckets; 84 const Elf_Hashelt* chains; 85 caddr_t hash; 86 caddr_t strtab; /* DT_STRTAB */ 87 int strsz; /* DT_STRSZ */ 88 const Elf_Sym* symtab; /* DT_SYMTAB */ 89 Elf_Addr* got; /* DT_PLTGOT */ 90 const Elf_Rel* pltrel; /* DT_JMPREL */ 91 int pltrelsize; /* DT_PLTRELSZ */ 92 const Elf_Rela* pltrela; /* DT_JMPREL */ 93 int pltrelasize; /* DT_PLTRELSZ */ 94 const Elf_Rel* rel; /* DT_REL */ 95 int relsize; /* DT_RELSZ */ 96 const Elf_Rela* rela; /* DT_RELA */ 97 int relasize; /* DT_RELASZ */ 98 caddr_t modptr; 99 const Elf_Sym* ddbsymtab; /* The symbol table we are using */ 100 long ddbsymcnt; /* Number of symbols */ 101 caddr_t ddbstrtab; /* String table */ 102 long ddbstrcnt; /* number of bytes in string table */ 103 caddr_t symbase; /* malloc'ed symbold base */ 104 caddr_t strbase; /* malloc'ed string base */ 105 caddr_t ctftab; /* CTF table */ 106 long ctfcnt; /* number of bytes in CTF table */ 107 caddr_t ctfoff; /* CTF offset table */ 108 caddr_t typoff; /* Type offset table */ 109 long typlen; /* Number of type entries. */ 110#ifdef GDB 111 struct link_map gdb; /* hooks for gdb */ 112#endif 113} *elf_file_t; 114 115#include <kern/kern_ctf.c> 116 117static int link_elf_link_common_finish(linker_file_t); 118static int link_elf_link_preload(linker_class_t cls, 119 const char*, linker_file_t*); 120static int link_elf_link_preload_finish(linker_file_t); 121static int link_elf_load_file(linker_class_t, const char*, linker_file_t*); 122static int link_elf_lookup_symbol(linker_file_t, const char*, 123 c_linker_sym_t*); 124static int link_elf_symbol_values(linker_file_t, c_linker_sym_t, linker_symval_t*); 125static int link_elf_search_symbol(linker_file_t, caddr_t value, 126 c_linker_sym_t* sym, long* diffp); 127 128static void link_elf_unload_file(linker_file_t); 129static void link_elf_unload_preload(linker_file_t); 130static int link_elf_lookup_set(linker_file_t, const char *, 131 void ***, void ***, int *); 132static int link_elf_each_function_name(linker_file_t, 133 int (*)(const char *, void *), 134 void *); 135static int link_elf_each_function_nameval(linker_file_t, 136 linker_function_nameval_callback_t, 137 void *); 138static void link_elf_reloc_local(linker_file_t); 139static long link_elf_symtab_get(linker_file_t, const Elf_Sym **); 140static long link_elf_strtab_get(linker_file_t, caddr_t *); 141static Elf_Addr elf_lookup(linker_file_t lf, Elf_Size symidx, int deps); 142 143static kobj_method_t link_elf_methods[] = { 144 KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol), 145 KOBJMETHOD(linker_symbol_values, link_elf_symbol_values), 146 KOBJMETHOD(linker_search_symbol, link_elf_search_symbol), 147 KOBJMETHOD(linker_unload, link_elf_unload_file), 148 KOBJMETHOD(linker_load_file, link_elf_load_file), 149 KOBJMETHOD(linker_link_preload, link_elf_link_preload), 150 KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish), 151 KOBJMETHOD(linker_lookup_set, link_elf_lookup_set), 152 KOBJMETHOD(linker_each_function_name, link_elf_each_function_name), 153 KOBJMETHOD(linker_each_function_nameval, link_elf_each_function_nameval), 154 KOBJMETHOD(linker_ctf_get, link_elf_ctf_get), 155 KOBJMETHOD(linker_symtab_get, link_elf_symtab_get), 156 KOBJMETHOD(linker_strtab_get, link_elf_strtab_get), 157 { 0, 0 } 158}; 159 160static struct linker_class link_elf_class = { 161#if ELF_TARG_CLASS == ELFCLASS32 162 "elf32", 163#else 164 "elf64", 165#endif 166 link_elf_methods, sizeof(struct elf_file) 167}; 168 169static int parse_dynamic(elf_file_t ef); 170static int relocate_file(elf_file_t ef); 171static int link_elf_preload_parse_symbols(elf_file_t ef); 172 173#ifdef GDB 174static void r_debug_state(struct r_debug *dummy_one, 175 struct link_map *dummy_two); 176 177/* 178 * A list of loaded modules for GDB to use for loading symbols. 179 */ 180struct r_debug r_debug; 181 182#define GDB_STATE(s) r_debug.r_state = s; r_debug_state(NULL, NULL); 183 184/* 185 * Function for the debugger to set a breakpoint on to gain control. 186 */ 187static void 188r_debug_state(struct r_debug *dummy_one __unused, 189 struct link_map *dummy_two __unused) 190{ 191} 192 193static void 194link_elf_add_gdb(struct link_map *l) 195{ 196 struct link_map *prev; 197 198 l->l_next = NULL; 199 200 if (r_debug.r_map == NULL) { 201 /* Add first. */ 202 l->l_prev = NULL; 203 r_debug.r_map = l; 204 } else { 205 /* Append to list. */ 206 for (prev = r_debug.r_map; prev->l_next != NULL; prev = prev->l_next) 207 ; 208 l->l_prev = prev; 209 prev->l_next = l; 210 } 211} 212 213static void 214link_elf_delete_gdb(struct link_map *l) 215{ 216 if (l->l_prev == NULL) { 217 /* Remove first. */ 218 if ((r_debug.r_map = l->l_next) != NULL) 219 l->l_next->l_prev = NULL; 220 } else { 221 /* Remove any but first. */ 222 if ((l->l_prev->l_next = l->l_next) != NULL) 223 l->l_next->l_prev = l->l_prev; 224 } 225} 226#endif /* GDB */ 227 228#ifdef __ia64__ 229Elf_Addr link_elf_get_gp(linker_file_t); 230#endif 231 232/* 233 * The kernel symbol table starts here. 234 */ 235extern struct _dynamic _DYNAMIC; 236 237static void 238link_elf_error(const char *filename, const char *s) 239{ 240 if (filename == NULL) 241 printf("kldload: %s\n", s); 242 else 243 printf("kldload: %s: %s\n", filename, s); 244} 245 246/* 247 * Actions performed after linking/loading both the preloaded kernel and any 248 * modules; whether preloaded or dynamicly loaded. 249 */ 250static int 251link_elf_link_common_finish(linker_file_t lf) 252{ 253#ifdef GDB 254 elf_file_t ef = (elf_file_t)lf; 255 char *newfilename; 256#endif 257 int error; 258 259 /* Notify MD code that a module is being loaded. */ 260 error = elf_cpu_load_file(lf); 261 if (error) 262 return (error); 263 264#ifdef GDB 265 GDB_STATE(RT_ADD); 266 ef->gdb.l_addr = lf->address; 267 newfilename = malloc(strlen(lf->filename) + 1, M_LINKER, M_WAITOK); 268 strcpy(newfilename, lf->filename); 269 ef->gdb.l_name = newfilename; 270 ef->gdb.l_ld = ef->dynamic; 271 link_elf_add_gdb(&ef->gdb); 272 GDB_STATE(RT_CONSISTENT); 273#endif 274 275 return (0); 276} 277 278static void 279link_elf_init(void* arg) 280{ 281 Elf_Dyn *dp; 282 caddr_t modptr, baseptr, sizeptr; 283 elf_file_t ef; 284 char *modname; 285 286 linker_add_class(&link_elf_class); 287 288 dp = (Elf_Dyn*) &_DYNAMIC; 289 modname = NULL; 290 modptr = preload_search_by_type("elf" __XSTRING(__ELF_WORD_SIZE) " kernel"); 291 if (modptr == NULL) 292 modptr = preload_search_by_type("elf kernel"); 293 if (modptr) 294 modname = (char *)preload_search_info(modptr, MODINFO_NAME); 295 if (modname == NULL) 296 modname = "kernel"; 297 linker_kernel_file = linker_make_file(modname, &link_elf_class); 298 if (linker_kernel_file == NULL) 299 panic("link_elf_init: Can't create linker structures for kernel"); 300 301 ef = (elf_file_t) linker_kernel_file; 302 ef->preloaded = 1; 303 ef->address = 0; 304#ifdef SPARSE_MAPPING 305 ef->object = 0; 306#endif 307 ef->dynamic = dp; 308 309 if (dp) 310 parse_dynamic(ef); 311 linker_kernel_file->address = (caddr_t) KERNBASE; 312 linker_kernel_file->size = -(intptr_t)linker_kernel_file->address; 313 314 if (modptr) { 315 ef->modptr = modptr; 316 baseptr = preload_search_info(modptr, MODINFO_ADDR); 317 if (baseptr) 318 linker_kernel_file->address = *(caddr_t *)baseptr; 319 sizeptr = preload_search_info(modptr, MODINFO_SIZE); 320 if (sizeptr) 321 linker_kernel_file->size = *(size_t *)sizeptr; 322 } 323 (void)link_elf_preload_parse_symbols(ef); 324 325#ifdef GDB 326 r_debug.r_map = NULL; 327 r_debug.r_brk = r_debug_state; 328 r_debug.r_state = RT_CONSISTENT; 329#endif 330 331 (void)link_elf_link_common_finish(linker_kernel_file); 332 linker_kernel_file->flags |= LINKER_FILE_LINKED; 333} 334 335SYSINIT(link_elf, SI_SUB_KLD, SI_ORDER_THIRD, link_elf_init, 0); 336 337static int 338link_elf_preload_parse_symbols(elf_file_t ef) 339{ 340 caddr_t pointer; 341 caddr_t ssym, esym, base; 342 caddr_t strtab; 343 int strcnt; 344 Elf_Sym* symtab; 345 int symcnt; 346 347 if (ef->modptr == NULL) 348 return 0; 349 pointer = preload_search_info(ef->modptr, MODINFO_METADATA|MODINFOMD_SSYM); 350 if (pointer == NULL) 351 return 0; 352 ssym = *(caddr_t *)pointer; 353 pointer = preload_search_info(ef->modptr, MODINFO_METADATA|MODINFOMD_ESYM); 354 if (pointer == NULL) 355 return 0; 356 esym = *(caddr_t *)pointer; 357 358 base = ssym; 359 360 symcnt = *(long *)base; 361 base += sizeof(long); 362 symtab = (Elf_Sym *)base; 363 base += roundup(symcnt, sizeof(long)); 364 365 if (base > esym || base < ssym) { 366 printf("Symbols are corrupt!\n"); 367 return EINVAL; 368 } 369 370 strcnt = *(long *)base; 371 base += sizeof(long); 372 strtab = base; 373 base += roundup(strcnt, sizeof(long)); 374 375 if (base > esym || base < ssym) { 376 printf("Symbols are corrupt!\n"); 377 return EINVAL; 378 } 379 380 ef->ddbsymtab = symtab; 381 ef->ddbsymcnt = symcnt / sizeof(Elf_Sym); 382 ef->ddbstrtab = strtab; 383 ef->ddbstrcnt = strcnt; 384 385 return 0; 386} 387 388static int 389parse_dynamic(elf_file_t ef) 390{ 391 Elf_Dyn *dp; 392 int plttype = DT_REL; 393 394 for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) { 395 switch (dp->d_tag) { 396 case DT_HASH: 397 { 398 /* From src/libexec/rtld-elf/rtld.c */ 399 const Elf_Hashelt *hashtab = (const Elf_Hashelt *) 400 (ef->address + dp->d_un.d_ptr); 401 ef->nbuckets = hashtab[0]; 402 ef->nchains = hashtab[1]; 403 ef->buckets = hashtab + 2; 404 ef->chains = ef->buckets + ef->nbuckets; 405 break; 406 } 407 case DT_STRTAB: 408 ef->strtab = (caddr_t) (ef->address + dp->d_un.d_ptr); 409 break; 410 case DT_STRSZ: 411 ef->strsz = dp->d_un.d_val; 412 break; 413 case DT_SYMTAB: 414 ef->symtab = (Elf_Sym*) (ef->address + dp->d_un.d_ptr); 415 break; 416 case DT_SYMENT: 417 if (dp->d_un.d_val != sizeof(Elf_Sym)) 418 return ENOEXEC; 419 break; 420 case DT_PLTGOT: 421 ef->got = (Elf_Addr *) (ef->address + dp->d_un.d_ptr); 422 break; 423 case DT_REL: 424 ef->rel = (const Elf_Rel *) (ef->address + dp->d_un.d_ptr); 425 break; 426 case DT_RELSZ: 427 ef->relsize = dp->d_un.d_val; 428 break; 429 case DT_RELENT: 430 if (dp->d_un.d_val != sizeof(Elf_Rel)) 431 return ENOEXEC; 432 break; 433 case DT_JMPREL: 434 ef->pltrel = (const Elf_Rel *) (ef->address + dp->d_un.d_ptr); 435 break; 436 case DT_PLTRELSZ: 437 ef->pltrelsize = dp->d_un.d_val; 438 break; 439 case DT_RELA: 440 ef->rela = (const Elf_Rela *) (ef->address + dp->d_un.d_ptr); 441 break; 442 case DT_RELASZ: 443 ef->relasize = dp->d_un.d_val; 444 break; 445 case DT_RELAENT: 446 if (dp->d_un.d_val != sizeof(Elf_Rela)) 447 return ENOEXEC; 448 break; 449 case DT_PLTREL: 450 plttype = dp->d_un.d_val; 451 if (plttype != DT_REL && plttype != DT_RELA) 452 return ENOEXEC; 453 break; 454#ifdef GDB 455 case DT_DEBUG: 456 dp->d_un.d_ptr = (Elf_Addr) &r_debug; 457 break; 458#endif 459 } 460 } 461 462 if (plttype == DT_RELA) { 463 ef->pltrela = (const Elf_Rela *) ef->pltrel; 464 ef->pltrel = NULL; 465 ef->pltrelasize = ef->pltrelsize; 466 ef->pltrelsize = 0; 467 } 468 469 ef->ddbsymtab = ef->symtab; 470 ef->ddbsymcnt = ef->nchains; 471 ef->ddbstrtab = ef->strtab; 472 ef->ddbstrcnt = ef->strsz; 473 474 return 0; 475} 476 477static int 478link_elf_link_preload(linker_class_t cls, 479 const char* filename, linker_file_t *result) 480{ 481 caddr_t modptr, baseptr, sizeptr, dynptr; 482 char *type; 483 elf_file_t ef; 484 linker_file_t lf; 485 int error; 486 vm_offset_t dp; 487 488 /* Look to see if we have the file preloaded */ 489 modptr = preload_search_by_name(filename); 490 if (modptr == NULL) 491 return ENOENT; 492 493 type = (char *)preload_search_info(modptr, MODINFO_TYPE); 494 baseptr = preload_search_info(modptr, MODINFO_ADDR); 495 sizeptr = preload_search_info(modptr, MODINFO_SIZE); 496 dynptr = preload_search_info(modptr, MODINFO_METADATA|MODINFOMD_DYNAMIC); 497 if (type == NULL || 498 (strcmp(type, "elf" __XSTRING(__ELF_WORD_SIZE) " module") != 0 && 499 strcmp(type, "elf module") != 0)) 500 return (EFTYPE); 501 if (baseptr == NULL || sizeptr == NULL || dynptr == NULL) 502 return (EINVAL); 503 504 lf = linker_make_file(filename, &link_elf_class); 505 if (lf == NULL) { 506 return ENOMEM; 507 } 508 509 ef = (elf_file_t) lf; 510 ef->preloaded = 1; 511 ef->modptr = modptr; 512 ef->address = *(caddr_t *)baseptr; 513#ifdef SPARSE_MAPPING 514 ef->object = 0; 515#endif 516 dp = (vm_offset_t)ef->address + *(vm_offset_t *)dynptr; 517 ef->dynamic = (Elf_Dyn *)dp; 518 lf->address = ef->address; 519 lf->size = *(size_t *)sizeptr; 520 521 error = parse_dynamic(ef); 522 if (error) { 523 linker_file_unload(lf, LINKER_UNLOAD_FORCE); 524 return error; 525 } 526 link_elf_reloc_local(lf); 527 *result = lf; 528 return (0); 529} 530 531static int 532link_elf_link_preload_finish(linker_file_t lf) 533{ 534 elf_file_t ef; 535 int error; 536 537 ef = (elf_file_t) lf; 538#if 0 /* this will be more trouble than it's worth for now */ 539 for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) { 540 if (dp->d_tag != DT_NEEDED) 541 continue; 542 modname = ef->strtab + dp->d_un.d_val; 543 error = linker_load_module(modname, lf); 544 if (error) 545 goto out; 546 } 547#endif 548 error = relocate_file(ef); 549 if (error) 550 return error; 551 (void)link_elf_preload_parse_symbols(ef); 552 553 return (link_elf_link_common_finish(lf)); 554} 555 556static int 557link_elf_load_file(linker_class_t cls, const char* filename, 558 linker_file_t* result) 559{ 560 struct nameidata nd; 561 struct thread* td = curthread; /* XXX */ 562 Elf_Ehdr *hdr; 563 caddr_t firstpage; 564 int nbytes, i; 565 Elf_Phdr *phdr; 566 Elf_Phdr *phlimit; 567 Elf_Phdr *segs[MAXSEGS]; 568 int nsegs; 569 Elf_Phdr *phdyn; 570 Elf_Phdr *phphdr; 571 caddr_t mapbase; 572 size_t mapsize; 573 Elf_Off base_offset; 574 Elf_Addr base_vaddr; 575 Elf_Addr base_vlimit; 576 int error = 0; 577 int resid, flags; 578 elf_file_t ef; 579 linker_file_t lf; 580 Elf_Shdr *shdr; 581 int symtabindex; 582 int symstrindex; 583 int symcnt; 584 int strcnt; 585 int vfslocked; 586 587 shdr = NULL; 588 lf = NULL; 589 590 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, filename, td); 591 flags = FREAD; 592 error = vn_open(&nd, &flags, 0, NULL); 593 if (error) 594 return error; 595 vfslocked = NDHASGIANT(&nd); 596 NDFREE(&nd, NDF_ONLY_PNBUF); 597 if (nd.ni_vp->v_type != VREG) { 598 error = ENOEXEC; 599 firstpage = NULL; 600 goto out; 601 } 602#ifdef MAC 603 error = mac_kld_check_load(curthread->td_ucred, nd.ni_vp); 604 if (error) { 605 firstpage = NULL; 606 goto out; 607 } 608#endif 609 610 /* 611 * Read the elf header from the file. 612 */ 613 firstpage = malloc(PAGE_SIZE, M_LINKER, M_WAITOK); 614 if (firstpage == NULL) { 615 error = ENOMEM; 616 goto out; 617 } 618 hdr = (Elf_Ehdr *)firstpage; 619 error = vn_rdwr(UIO_READ, nd.ni_vp, firstpage, PAGE_SIZE, 0, 620 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 621 &resid, td); 622 nbytes = PAGE_SIZE - resid; 623 if (error) 624 goto out; 625 626 if (!IS_ELF(*hdr)) { 627 error = ENOEXEC; 628 goto out; 629 } 630 631 if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS 632 || hdr->e_ident[EI_DATA] != ELF_TARG_DATA) { 633 link_elf_error(filename, "Unsupported file layout"); 634 error = ENOEXEC; 635 goto out; 636 } 637 if (hdr->e_ident[EI_VERSION] != EV_CURRENT 638 || hdr->e_version != EV_CURRENT) { 639 link_elf_error(filename, "Unsupported file version"); 640 error = ENOEXEC; 641 goto out; 642 } 643 if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN) { 644 error = ENOSYS; 645 goto out; 646 } 647 if (hdr->e_machine != ELF_TARG_MACH) { 648 link_elf_error(filename, "Unsupported machine"); 649 error = ENOEXEC; 650 goto out; 651 } 652 653 /* 654 * We rely on the program header being in the first page. This is 655 * not strictly required by the ABI specification, but it seems to 656 * always true in practice. And, it simplifies things considerably. 657 */ 658 if (!((hdr->e_phentsize == sizeof(Elf_Phdr)) && 659 (hdr->e_phoff + hdr->e_phnum*sizeof(Elf_Phdr) <= PAGE_SIZE) && 660 (hdr->e_phoff + hdr->e_phnum*sizeof(Elf_Phdr) <= nbytes))) 661 link_elf_error(filename, "Unreadable program headers"); 662 663 /* 664 * Scan the program header entries, and save key information. 665 * 666 * We rely on there being exactly two load segments, text and data, 667 * in that order. 668 */ 669 phdr = (Elf_Phdr *) (firstpage + hdr->e_phoff); 670 phlimit = phdr + hdr->e_phnum; 671 nsegs = 0; 672 phdyn = NULL; 673 phphdr = NULL; 674 while (phdr < phlimit) { 675 switch (phdr->p_type) { 676 677 case PT_LOAD: 678 if (nsegs == MAXSEGS) { 679 link_elf_error(filename, "Too many sections"); 680 error = ENOEXEC; 681 goto out; 682 } 683 /* 684 * XXX: We just trust they come in right order ?? 685 */ 686 segs[nsegs] = phdr; 687 ++nsegs; 688 break; 689 690 case PT_PHDR: 691 phphdr = phdr; 692 break; 693 694 case PT_DYNAMIC: 695 phdyn = phdr; 696 break; 697 698 case PT_INTERP: 699 error = ENOSYS; 700 goto out; 701 } 702 703 ++phdr; 704 } 705 if (phdyn == NULL) { 706 link_elf_error(filename, "Object is not dynamically-linked"); 707 error = ENOEXEC; 708 goto out; 709 } 710 if (nsegs == 0) { 711 link_elf_error(filename, "No sections"); 712 error = ENOEXEC; 713 goto out; 714 } 715 716 /* 717 * Allocate the entire address space of the object, to stake out our 718 * contiguous region, and to establish the base address for relocation. 719 */ 720 base_offset = trunc_page(segs[0]->p_offset); 721 base_vaddr = trunc_page(segs[0]->p_vaddr); 722 base_vlimit = round_page(segs[nsegs - 1]->p_vaddr + 723 segs[nsegs - 1]->p_memsz); 724 mapsize = base_vlimit - base_vaddr; 725 726 lf = linker_make_file(filename, &link_elf_class); 727 if (!lf) { 728 error = ENOMEM; 729 goto out; 730 } 731 732 ef = (elf_file_t) lf; 733#ifdef SPARSE_MAPPING 734 ef->object = vm_object_allocate(OBJT_DEFAULT, mapsize >> PAGE_SHIFT); 735 if (ef->object == NULL) { 736 error = ENOMEM; 737 goto out; 738 } 739 ef->address = (caddr_t) vm_map_min(kernel_map); 740 error = vm_map_find(kernel_map, ef->object, 0, 741 (vm_offset_t *) &ef->address, 742 mapsize, 1, 743 VM_PROT_ALL, VM_PROT_ALL, 0); 744 if (error) { 745 vm_object_deallocate(ef->object); 746 ef->object = 0; 747 goto out; 748 } 749#else 750 ef->address = malloc(mapsize, M_LINKER, M_WAITOK); 751 if (!ef->address) { 752 error = ENOMEM; 753 goto out; 754 } 755#endif 756 mapbase = ef->address; 757 758 /* 759 * Read the text and data sections and zero the bss. 760 */ 761 for (i = 0; i < nsegs; i++) { 762 caddr_t segbase = mapbase + segs[i]->p_vaddr - base_vaddr; 763 error = vn_rdwr(UIO_READ, nd.ni_vp, 764 segbase, segs[i]->p_filesz, segs[i]->p_offset, 765 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 766 &resid, td); 767 if (error) { 768 goto out; 769 } 770 bzero(segbase + segs[i]->p_filesz, 771 segs[i]->p_memsz - segs[i]->p_filesz); 772 773#ifdef SPARSE_MAPPING 774 /* 775 * Wire down the pages 776 */ 777 error = vm_map_wire(kernel_map, 778 (vm_offset_t) segbase, 779 (vm_offset_t) segbase + segs[i]->p_memsz, 780 VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES); 781 if (error != KERN_SUCCESS) { 782 error = ENOMEM; 783 goto out; 784 } 785#endif 786 } 787 788#ifdef GPROF 789 /* Update profiling information with the new text segment. */ 790 mtx_lock(&Giant); 791 kmupetext((uintfptr_t)(mapbase + segs[0]->p_vaddr - base_vaddr + 792 segs[0]->p_memsz)); 793 mtx_unlock(&Giant); 794#endif 795 796 ef->dynamic = (Elf_Dyn *) (mapbase + phdyn->p_vaddr - base_vaddr); 797 798 lf->address = ef->address; 799 lf->size = mapsize; 800 801 error = parse_dynamic(ef); 802 if (error) 803 goto out; 804 link_elf_reloc_local(lf); 805 806 VOP_UNLOCK(nd.ni_vp, 0); 807 error = linker_load_dependencies(lf); 808 vn_lock(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY); 809 if (error) 810 goto out; 811#if 0 /* this will be more trouble than it's worth for now */ 812 for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) { 813 if (dp->d_tag != DT_NEEDED) 814 continue; 815 modname = ef->strtab + dp->d_un.d_val; 816 error = linker_load_module(modname, lf); 817 if (error) 818 goto out; 819 } 820#endif 821 error = relocate_file(ef); 822 if (error) 823 goto out; 824 825 /* Try and load the symbol table if it's present. (you can strip it!) */ 826 nbytes = hdr->e_shnum * hdr->e_shentsize; 827 if (nbytes == 0 || hdr->e_shoff == 0) 828 goto nosyms; 829 shdr = malloc(nbytes, M_LINKER, M_WAITOK | M_ZERO); 830 if (shdr == NULL) { 831 error = ENOMEM; 832 goto out; 833 } 834 error = vn_rdwr(UIO_READ, nd.ni_vp, 835 (caddr_t)shdr, nbytes, hdr->e_shoff, 836 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 837 &resid, td); 838 if (error) 839 goto out; 840 symtabindex = -1; 841 symstrindex = -1; 842 for (i = 0; i < hdr->e_shnum; i++) { 843 if (shdr[i].sh_type == SHT_SYMTAB) { 844 symtabindex = i; 845 symstrindex = shdr[i].sh_link; 846 } 847 } 848 if (symtabindex < 0 || symstrindex < 0) 849 goto nosyms; 850 851 symcnt = shdr[symtabindex].sh_size; 852 ef->symbase = malloc(symcnt, M_LINKER, M_WAITOK); 853 strcnt = shdr[symstrindex].sh_size; 854 ef->strbase = malloc(strcnt, M_LINKER, M_WAITOK); 855 856 if (ef->symbase == NULL || ef->strbase == NULL) { 857 error = ENOMEM; 858 goto out; 859 } 860 error = vn_rdwr(UIO_READ, nd.ni_vp, 861 ef->symbase, symcnt, shdr[symtabindex].sh_offset, 862 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 863 &resid, td); 864 if (error) 865 goto out; 866 error = vn_rdwr(UIO_READ, nd.ni_vp, 867 ef->strbase, strcnt, shdr[symstrindex].sh_offset, 868 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, 869 &resid, td); 870 if (error) 871 goto out; 872 873 ef->ddbsymcnt = symcnt / sizeof(Elf_Sym); 874 ef->ddbsymtab = (const Elf_Sym *)ef->symbase; 875 ef->ddbstrcnt = strcnt; 876 ef->ddbstrtab = ef->strbase; 877 878 error = link_elf_link_common_finish(lf); 879 if (error) 880 goto out; 881 882nosyms: 883 884 *result = lf; 885 886out: 887 if (error && lf) 888 linker_file_unload(lf, LINKER_UNLOAD_FORCE); 889 if (shdr) 890 free(shdr, M_LINKER); 891 if (firstpage) 892 free(firstpage, M_LINKER); 893 VOP_UNLOCK(nd.ni_vp, 0); 894 vn_close(nd.ni_vp, FREAD, td->td_ucred, td); 895 VFS_UNLOCK_GIANT(vfslocked); 896 897 return error; 898} 899 900static void 901link_elf_unload_file(linker_file_t file) 902{ 903 elf_file_t ef = (elf_file_t) file; 904 905#ifdef GDB 906 if (ef->gdb.l_ld) { 907 GDB_STATE(RT_DELETE); 908 free((void *)(uintptr_t)ef->gdb.l_name, M_LINKER); 909 link_elf_delete_gdb(&ef->gdb); 910 GDB_STATE(RT_CONSISTENT); 911 } 912#endif 913 914 /* Notify MD code that a module is being unloaded. */ 915 elf_cpu_unload_file(file); 916 917 if (ef->preloaded) { 918 link_elf_unload_preload(file); 919 return; 920 } 921 922#ifdef SPARSE_MAPPING 923 if (ef->object) { 924 vm_map_remove(kernel_map, (vm_offset_t) ef->address, 925 (vm_offset_t) ef->address 926 + (ef->object->size << PAGE_SHIFT)); 927 } 928#else 929 if (ef->address) 930 free(ef->address, M_LINKER); 931#endif 932 if (ef->symbase) 933 free(ef->symbase, M_LINKER); 934 if (ef->strbase) 935 free(ef->strbase, M_LINKER); 936 if (ef->ctftab) 937 free(ef->ctftab, M_LINKER); 938 if (ef->ctfoff) 939 free(ef->ctfoff, M_LINKER); 940 if (ef->typoff) 941 free(ef->typoff, M_LINKER); 942} 943 944static void 945link_elf_unload_preload(linker_file_t file) 946{ 947 if (file->filename) 948 preload_delete_name(file->filename); 949} 950 951static const char * 952symbol_name(elf_file_t ef, Elf_Size r_info) 953{ 954 const Elf_Sym *ref; 955 956 if (ELF_R_SYM(r_info)) { 957 ref = ef->symtab + ELF_R_SYM(r_info); 958 return ef->strtab + ref->st_name; 959 } else 960 return NULL; 961} 962 963static int 964relocate_file(elf_file_t ef) 965{ 966 const Elf_Rel *rellim; 967 const Elf_Rel *rel; 968 const Elf_Rela *relalim; 969 const Elf_Rela *rela; 970 const char *symname; 971 972 /* Perform relocations without addend if there are any: */ 973 rel = ef->rel; 974 if (rel) { 975 rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize); 976 while (rel < rellim) { 977 if (elf_reloc(&ef->lf, (Elf_Addr)ef->address, rel, ELF_RELOC_REL, 978 elf_lookup)) { 979 symname = symbol_name(ef, rel->r_info); 980 printf("link_elf: symbol %s undefined\n", symname); 981 return ENOENT; 982 } 983 rel++; 984 } 985 } 986 987 /* Perform relocations with addend if there are any: */ 988 rela = ef->rela; 989 if (rela) { 990 relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize); 991 while (rela < relalim) { 992 if (elf_reloc(&ef->lf, (Elf_Addr)ef->address, rela, ELF_RELOC_RELA, 993 elf_lookup)) { 994 symname = symbol_name(ef, rela->r_info); 995 printf("link_elf: symbol %s undefined\n", symname); 996 return ENOENT; 997 } 998 rela++; 999 } 1000 } 1001 1002 /* Perform PLT relocations without addend if there are any: */ 1003 rel = ef->pltrel; 1004 if (rel) { 1005 rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize); 1006 while (rel < rellim) { 1007 if (elf_reloc(&ef->lf, (Elf_Addr)ef->address, rel, ELF_RELOC_REL, 1008 elf_lookup)) { 1009 symname = symbol_name(ef, rel->r_info); 1010 printf("link_elf: symbol %s undefined\n", symname); 1011 return ENOENT; 1012 } 1013 rel++; 1014 } 1015 } 1016 1017 /* Perform relocations with addend if there are any: */ 1018 rela = ef->pltrela; 1019 if (rela) { 1020 relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize); 1021 while (rela < relalim) { 1022 if (elf_reloc(&ef->lf, (Elf_Addr)ef->address, rela, ELF_RELOC_RELA, 1023 elf_lookup)) { 1024 symname = symbol_name(ef, rela->r_info); 1025 printf("link_elf: symbol %s undefined\n", symname); 1026 return ENOENT; 1027 } 1028 rela++; 1029 } 1030 } 1031 1032 return 0; 1033} 1034 1035/* 1036 * Hash function for symbol table lookup. Don't even think about changing 1037 * this. It is specified by the System V ABI. 1038 */ 1039static unsigned long 1040elf_hash(const char *name) 1041{ 1042 const unsigned char *p = (const unsigned char *) name; 1043 unsigned long h = 0; 1044 unsigned long g; 1045 1046 while (*p != '\0') { 1047 h = (h << 4) + *p++; 1048 if ((g = h & 0xf0000000) != 0) 1049 h ^= g >> 24; 1050 h &= ~g; 1051 } 1052 return h; 1053} 1054 1055static int 1056link_elf_lookup_symbol(linker_file_t lf, const char* name, c_linker_sym_t* sym) 1057{ 1058 elf_file_t ef = (elf_file_t) lf; 1059 unsigned long symnum; 1060 const Elf_Sym* symp; 1061 const char *strp; 1062 unsigned long hash; 1063 int i; 1064 1065 /* If we don't have a hash, bail. */ 1066 if (ef->buckets == NULL || ef->nbuckets == 0) { 1067 printf("link_elf_lookup_symbol: missing symbol hash table\n"); 1068 return ENOENT; 1069 } 1070 1071 /* First, search hashed global symbols */ 1072 hash = elf_hash(name); 1073 symnum = ef->buckets[hash % ef->nbuckets]; 1074 1075 while (symnum != STN_UNDEF) { 1076 if (symnum >= ef->nchains) { 1077 printf("link_elf_lookup_symbol: corrupt symbol table\n"); 1078 return ENOENT; 1079 } 1080 1081 symp = ef->symtab + symnum; 1082 if (symp->st_name == 0) { 1083 printf("link_elf_lookup_symbol: corrupt symbol table\n"); 1084 return ENOENT; 1085 } 1086 1087 strp = ef->strtab + symp->st_name; 1088 1089 if (strcmp(name, strp) == 0) { 1090 if (symp->st_shndx != SHN_UNDEF || 1091 (symp->st_value != 0 && 1092 ELF_ST_TYPE(symp->st_info) == STT_FUNC)) { 1093 *sym = (c_linker_sym_t) symp; 1094 return 0; 1095 } else 1096 return ENOENT; 1097 } 1098 1099 symnum = ef->chains[symnum]; 1100 } 1101 1102 /* If we have not found it, look at the full table (if loaded) */ 1103 if (ef->symtab == ef->ddbsymtab) 1104 return ENOENT; 1105 1106 /* Exhaustive search */ 1107 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 1108 strp = ef->ddbstrtab + symp->st_name; 1109 if (strcmp(name, strp) == 0) { 1110 if (symp->st_shndx != SHN_UNDEF || 1111 (symp->st_value != 0 && 1112 ELF_ST_TYPE(symp->st_info) == STT_FUNC)) { 1113 *sym = (c_linker_sym_t) symp; 1114 return 0; 1115 } else 1116 return ENOENT; 1117 } 1118 } 1119 1120 return ENOENT; 1121} 1122 1123static int 1124link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, linker_symval_t* symval) 1125{ 1126 elf_file_t ef = (elf_file_t) lf; 1127 const Elf_Sym* es = (const Elf_Sym*) sym; 1128 1129 if (es >= ef->symtab && es < (ef->symtab + ef->nchains)) { 1130 symval->name = ef->strtab + es->st_name; 1131 symval->value = (caddr_t) ef->address + es->st_value; 1132 symval->size = es->st_size; 1133 return 0; 1134 } 1135 if (ef->symtab == ef->ddbsymtab) 1136 return ENOENT; 1137 if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) { 1138 symval->name = ef->ddbstrtab + es->st_name; 1139 symval->value = (caddr_t) ef->address + es->st_value; 1140 symval->size = es->st_size; 1141 return 0; 1142 } 1143 return ENOENT; 1144} 1145 1146static int 1147link_elf_search_symbol(linker_file_t lf, caddr_t value, 1148 c_linker_sym_t* sym, long* diffp) 1149{ 1150 elf_file_t ef = (elf_file_t) lf; 1151 u_long off = (uintptr_t) (void *) value; 1152 u_long diff = off; 1153 u_long st_value; 1154 const Elf_Sym* es; 1155 const Elf_Sym* best = 0; 1156 int i; 1157 1158 for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) { 1159 if (es->st_name == 0) 1160 continue; 1161 st_value = es->st_value + (uintptr_t) (void *) ef->address; 1162 if (off >= st_value) { 1163 if (off - st_value < diff) { 1164 diff = off - st_value; 1165 best = es; 1166 if (diff == 0) 1167 break; 1168 } else if (off - st_value == diff) { 1169 best = es; 1170 } 1171 } 1172 } 1173 if (best == 0) 1174 *diffp = off; 1175 else 1176 *diffp = diff; 1177 *sym = (c_linker_sym_t) best; 1178 1179 return 0; 1180} 1181 1182/* 1183 * Look up a linker set on an ELF system. 1184 */ 1185static int 1186link_elf_lookup_set(linker_file_t lf, const char *name, 1187 void ***startp, void ***stopp, int *countp) 1188{ 1189 c_linker_sym_t sym; 1190 linker_symval_t symval; 1191 char *setsym; 1192 void **start, **stop; 1193 int len, error = 0, count; 1194 1195 len = strlen(name) + sizeof("__start_set_"); /* sizeof includes \0 */ 1196 setsym = malloc(len, M_LINKER, M_WAITOK); 1197 if (setsym == NULL) 1198 return ENOMEM; 1199 1200 /* get address of first entry */ 1201 snprintf(setsym, len, "%s%s", "__start_set_", name); 1202 error = link_elf_lookup_symbol(lf, setsym, &sym); 1203 if (error) 1204 goto out; 1205 link_elf_symbol_values(lf, sym, &symval); 1206 if (symval.value == 0) { 1207 error = ESRCH; 1208 goto out; 1209 } 1210 start = (void **)symval.value; 1211 1212 /* get address of last entry */ 1213 snprintf(setsym, len, "%s%s", "__stop_set_", name); 1214 error = link_elf_lookup_symbol(lf, setsym, &sym); 1215 if (error) 1216 goto out; 1217 link_elf_symbol_values(lf, sym, &symval); 1218 if (symval.value == 0) { 1219 error = ESRCH; 1220 goto out; 1221 } 1222 stop = (void **)symval.value; 1223 1224 /* and the number of entries */ 1225 count = stop - start; 1226 1227 /* and copy out */ 1228 if (startp) 1229 *startp = start; 1230 if (stopp) 1231 *stopp = stop; 1232 if (countp) 1233 *countp = count; 1234 1235out: 1236 free(setsym, M_LINKER); 1237 return error; 1238} 1239 1240static int 1241link_elf_each_function_name(linker_file_t file, 1242 int (*callback)(const char *, void *), void *opaque) { 1243 elf_file_t ef = (elf_file_t)file; 1244 const Elf_Sym* symp; 1245 int i, error; 1246 1247 /* Exhaustive search */ 1248 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 1249 if (symp->st_value != 0 && 1250 ELF_ST_TYPE(symp->st_info) == STT_FUNC) { 1251 error = callback(ef->ddbstrtab + symp->st_name, opaque); 1252 if (error) 1253 return (error); 1254 } 1255 } 1256 return (0); 1257} 1258 1259static int 1260link_elf_each_function_nameval(linker_file_t file, 1261 linker_function_nameval_callback_t callback, void *opaque) 1262{ 1263 linker_symval_t symval; 1264 elf_file_t ef = (elf_file_t)file; 1265 const Elf_Sym* symp; 1266 int i, error; 1267 1268 /* Exhaustive search */ 1269 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 1270 if (symp->st_value != 0 && 1271 ELF_ST_TYPE(symp->st_info) == STT_FUNC) { 1272 error = link_elf_symbol_values(file, (c_linker_sym_t) symp, &symval); 1273 if (error) 1274 return (error); 1275 error = callback(file, i, &symval, opaque); 1276 if (error) 1277 return (error); 1278 } 1279 } 1280 return (0); 1281} 1282 1283#ifdef __ia64__ 1284/* 1285 * Each KLD has its own GP. The GP value for each load module is given by 1286 * DT_PLTGOT on ia64. We need GP to construct function descriptors, but 1287 * don't have direct access to the ELF file structure. The link_elf_get_gp() 1288 * function returns the GP given a pointer to a generic linker file struct. 1289 */ 1290Elf_Addr 1291link_elf_get_gp(linker_file_t lf) 1292{ 1293 elf_file_t ef = (elf_file_t)lf; 1294 return (Elf_Addr)ef->got; 1295} 1296#endif 1297 1298const Elf_Sym * 1299elf_get_sym(linker_file_t lf, Elf_Size symidx) 1300{ 1301 elf_file_t ef = (elf_file_t)lf; 1302 1303 if (symidx >= ef->nchains) 1304 return (NULL); 1305 return (ef->symtab + symidx); 1306} 1307 1308const char * 1309elf_get_symname(linker_file_t lf, Elf_Size symidx) 1310{ 1311 elf_file_t ef = (elf_file_t)lf; 1312 const Elf_Sym *sym; 1313 1314 if (symidx >= ef->nchains) 1315 return (NULL); 1316 sym = ef->symtab + symidx; 1317 return (ef->strtab + sym->st_name); 1318} 1319 1320/* 1321 * Symbol lookup function that can be used when the symbol index is known (ie 1322 * in relocations). It uses the symbol index instead of doing a fully fledged 1323 * hash table based lookup when such is valid. For example for local symbols. 1324 * This is not only more efficient, it's also more correct. It's not always 1325 * the case that the symbol can be found through the hash table. 1326 */ 1327static Elf_Addr 1328elf_lookup(linker_file_t lf, Elf_Size symidx, int deps) 1329{ 1330 elf_file_t ef = (elf_file_t)lf; 1331 const Elf_Sym *sym; 1332 const char *symbol; 1333 1334 /* Don't even try to lookup the symbol if the index is bogus. */ 1335 if (symidx >= ef->nchains) 1336 return (0); 1337 1338 sym = ef->symtab + symidx; 1339 1340 /* 1341 * Don't do a full lookup when the symbol is local. It may even 1342 * fail because it may not be found through the hash table. 1343 */ 1344 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) { 1345 /* Force lookup failure when we have an insanity. */ 1346 if (sym->st_shndx == SHN_UNDEF || sym->st_value == 0) 1347 return (0); 1348 return ((Elf_Addr)ef->address + sym->st_value); 1349 } 1350 1351 /* 1352 * XXX we can avoid doing a hash table based lookup for global 1353 * symbols as well. This however is not always valid, so we'll 1354 * just do it the hard way for now. Performance tweaks can 1355 * always be added. 1356 */ 1357 1358 symbol = ef->strtab + sym->st_name; 1359 1360 /* Force a lookup failure if the symbol name is bogus. */ 1361 if (*symbol == 0) 1362 return (0); 1363 1364 return ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps)); 1365} 1366 1367static void 1368link_elf_reloc_local(linker_file_t lf) 1369{ 1370 const Elf_Rel *rellim; 1371 const Elf_Rel *rel; 1372 const Elf_Rela *relalim; 1373 const Elf_Rela *rela; 1374 elf_file_t ef = (elf_file_t)lf; 1375 1376 /* Perform relocations without addend if there are any: */ 1377 if ((rel = ef->rel) != NULL) { 1378 rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize); 1379 while (rel < rellim) { 1380 elf_reloc_local(lf, (Elf_Addr)ef->address, rel, ELF_RELOC_REL, 1381 elf_lookup); 1382 rel++; 1383 } 1384 } 1385 1386 /* Perform relocations with addend if there are any: */ 1387 if ((rela = ef->rela) != NULL) { 1388 relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize); 1389 while (rela < relalim) { 1390 elf_reloc_local(lf, (Elf_Addr)ef->address, rela, ELF_RELOC_RELA, 1391 elf_lookup); 1392 rela++; 1393 } 1394 } 1395} 1396 1397static long 1398link_elf_symtab_get(linker_file_t lf, const Elf_Sym **symtab) 1399{ 1400 elf_file_t ef = (elf_file_t)lf; 1401 1402 *symtab = ef->ddbsymtab; 1403 1404 if (*symtab == NULL) 1405 return (0); 1406 1407 return (ef->ddbsymcnt); 1408} 1409 1410static long 1411link_elf_strtab_get(linker_file_t lf, caddr_t *strtab) 1412{ 1413 elf_file_t ef = (elf_file_t)lf; 1414 1415 *strtab = ef->ddbstrtab; 1416 1417 if (*strtab == NULL) 1418 return (0); 1419 1420 return (ef->ddbstrcnt); 1421} 1422