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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #define ELF_TARGET_ALL 30 #ifdef __NetBSD__ 31 #ifdef __x86_64__ 32 #include <i386/elf_machdep.h> 33 #undef ELF32_MACHDEP_ID_CASES 34 #undef ELF64_MACHDEP_ID_CASES 35 #undef ELF64_MACHDEP_ENDIANNESS 36 #undef KERN_ELFSIZE 37 #undef ARCH_ELFSIZE 38 #undef R_TYPE 39 #endif 40 #endif 41 #include <elf.h> 42 43 #include <sys/types.h> 44 #ifdef illumos 45 #include <sys/sysmacros.h> 46 #else 47 #define P2ROUNDUP(x, align) (-(-(x) & -(align))) 48 #endif 49 50 #include <unistd.h> 51 #include <strings.h> 52 #ifdef illumos 53 #include <alloca.h> 54 #endif 55 #include <limits.h> 56 #include <stddef.h> 57 #include <stdlib.h> 58 #include <stdio.h> 59 #include <fcntl.h> 60 #include <errno.h> 61 #ifdef illumos 62 #include <wait.h> 63 #else 64 #include <sys/wait.h> 65 #include <libelf.h> 66 #include <gelf.h> 67 #include <sys/mman.h> 68 #endif 69 #include <assert.h> 70 #include <sys/ipc.h> 71 72 #include <dt_impl.h> 73 #include <dt_provider.h> 74 #include <dt_program.h> 75 #include <dt_string.h> 76 77 #define ESHDR_NULL 0 78 #define ESHDR_SHSTRTAB 1 79 #define ESHDR_DOF 2 80 #define ESHDR_STRTAB 3 81 #define ESHDR_SYMTAB 4 82 #define ESHDR_REL 5 83 #define ESHDR_NUM 6 84 85 #define PWRITE_SCN(index, data) \ 86 (lseek64(fd, (off64_t)elf_file.shdr[(index)].sh_offset, SEEK_SET) != \ 87 (off64_t)elf_file.shdr[(index)].sh_offset || \ 88 dt_write(dtp, fd, (data), elf_file.shdr[(index)].sh_size) != \ 89 elf_file.shdr[(index)].sh_size) 90 91 static const char DTRACE_SHSTRTAB32[] = "\0" 92 ".shstrtab\0" /* 1 */ 93 ".SUNW_dof\0" /* 11 */ 94 ".strtab\0" /* 21 */ 95 ".symtab\0" /* 29 */ 96 #ifdef __sparc 97 ".rela.SUNW_dof"; /* 37 */ 98 #else 99 ".rel.SUNW_dof"; /* 37 */ 100 #endif 101 102 static const char DTRACE_SHSTRTAB64[] = "\0" 103 ".shstrtab\0" /* 1 */ 104 ".SUNW_dof\0" /* 11 */ 105 ".strtab\0" /* 21 */ 106 ".symtab\0" /* 29 */ 107 ".rela.SUNW_dof"; /* 37 */ 108 109 static const char DOFSTR[] = "__SUNW_dof"; 110 static const char DOFLAZYSTR[] = "___SUNW_dof"; 111 112 typedef struct dt_link_pair { 113 struct dt_link_pair *dlp_next; /* next pair in linked list */ 114 void *dlp_str; /* buffer for string table */ 115 void *dlp_sym; /* buffer for symbol table */ 116 } dt_link_pair_t; 117 118 typedef struct dof_elf32 { 119 uint32_t de_nrel; /* relocation count */ 120 #ifdef __sparc 121 Elf32_Rela *de_rel; /* array of relocations for sparc */ 122 #else 123 Elf32_Rel *de_rel; /* array of relocations for x86 */ 124 #endif 125 uint32_t de_nsym; /* symbol count */ 126 Elf32_Sym *de_sym; /* array of symbols */ 127 uint32_t de_strlen; /* size of of string table */ 128 char *de_strtab; /* string table */ 129 uint32_t de_global; /* index of the first global symbol */ 130 } dof_elf32_t; 131 132 static int 133 prepare_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf32_t *dep) 134 { 135 dof_sec_t *dofs, *s; 136 dof_relohdr_t *dofrh; 137 dof_relodesc_t *dofr; 138 char *strtab; 139 int i, j, nrel; 140 size_t strtabsz = 1; 141 uint32_t count = 0; 142 size_t base; 143 Elf32_Sym *sym; 144 #ifdef __sparc 145 Elf32_Rela *rel; 146 #else 147 Elf32_Rel *rel; 148 #endif 149 150 /*LINTED*/ 151 dofs = (dof_sec_t *)((char *)dof + dof->dofh_secoff); 152 153 /* 154 * First compute the size of the string table and the number of 155 * relocations present in the DOF. 156 */ 157 for (i = 0; i < dof->dofh_secnum; i++) { 158 if (dofs[i].dofs_type != DOF_SECT_URELHDR) 159 continue; 160 161 /*LINTED*/ 162 dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset); 163 164 s = &dofs[dofrh->dofr_strtab]; 165 strtab = (char *)dof + s->dofs_offset; 166 assert(strtab[0] == '\0'); 167 strtabsz += s->dofs_size - 1; 168 169 s = &dofs[dofrh->dofr_relsec]; 170 /*LINTED*/ 171 dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); 172 count += s->dofs_size / s->dofs_entsize; 173 } 174 175 dep->de_strlen = strtabsz; 176 dep->de_nrel = count; 177 dep->de_nsym = count + 1; /* the first symbol is always null */ 178 179 if (dtp->dt_lazyload) { 180 dep->de_strlen += sizeof (DOFLAZYSTR); 181 dep->de_nsym++; 182 } else { 183 dep->de_strlen += sizeof (DOFSTR); 184 dep->de_nsym++; 185 } 186 187 if ((dep->de_rel = calloc(dep->de_nrel, 188 sizeof (dep->de_rel[0]))) == NULL) { 189 return (dt_set_errno(dtp, EDT_NOMEM)); 190 } 191 192 if ((dep->de_sym = calloc(dep->de_nsym, sizeof (Elf32_Sym))) == NULL) { 193 free(dep->de_rel); 194 return (dt_set_errno(dtp, EDT_NOMEM)); 195 } 196 197 if ((dep->de_strtab = calloc(dep->de_strlen, 1)) == NULL) { 198 free(dep->de_rel); 199 free(dep->de_sym); 200 return (dt_set_errno(dtp, EDT_NOMEM)); 201 } 202 203 count = 0; 204 strtabsz = 1; 205 dep->de_strtab[0] = '\0'; 206 rel = dep->de_rel; 207 sym = dep->de_sym; 208 dep->de_global = 1; 209 210 /* 211 * The first symbol table entry must be zeroed and is always ignored. 212 */ 213 bzero(sym, sizeof (Elf32_Sym)); 214 sym++; 215 216 /* 217 * Take a second pass through the DOF sections filling in the 218 * memory we allocated. 219 */ 220 for (i = 0; i < dof->dofh_secnum; i++) { 221 if (dofs[i].dofs_type != DOF_SECT_URELHDR) 222 continue; 223 224 /*LINTED*/ 225 dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset); 226 227 s = &dofs[dofrh->dofr_strtab]; 228 strtab = (char *)dof + s->dofs_offset; 229 bcopy(strtab + 1, dep->de_strtab + strtabsz, s->dofs_size); 230 base = strtabsz; 231 strtabsz += s->dofs_size - 1; 232 233 s = &dofs[dofrh->dofr_relsec]; 234 /*LINTED*/ 235 dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); 236 nrel = s->dofs_size / s->dofs_entsize; 237 238 s = &dofs[dofrh->dofr_tgtsec]; 239 240 for (j = 0; j < nrel; j++) { 241 #if defined(__aarch64__) 242 /* XXX */ 243 printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 244 #elif defined(__arm__) 245 /* XXX */ 246 printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 247 #elif defined(__i386) || defined(__amd64) 248 rel->r_offset = s->dofs_offset + 249 dofr[j].dofr_offset; 250 rel->r_info = ELF32_R_INFO(count + dep->de_global, 251 R_386_32); 252 #elif defined(__mips__) 253 /* XXX */ 254 printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 255 #elif defined(__powerpc__) 256 /* 257 * Add 4 bytes to hit the low half of this 64-bit 258 * big-endian address. 259 */ 260 rel->r_offset = s->dofs_offset + 261 dofr[j].dofr_offset + 4; 262 rel->r_info = ELF32_R_INFO(count + dep->de_global, 263 R_PPC_REL32); 264 #elif defined(__sparc) 265 /* 266 * Add 4 bytes to hit the low half of this 64-bit 267 * big-endian address. 268 */ 269 rel->r_offset = s->dofs_offset + 270 dofr[j].dofr_offset + 4; 271 rel->r_info = ELF32_R_INFO(count + dep->de_global, 272 R_SPARC_32); 273 #else 274 #error unknown ISA 275 #endif 276 277 sym->st_name = base + dofr[j].dofr_name - 1; 278 sym->st_value = 0; 279 sym->st_size = 0; 280 sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_FUNC); 281 sym->st_other = 0; 282 sym->st_shndx = SHN_UNDEF; 283 284 rel++; 285 sym++; 286 count++; 287 } 288 } 289 290 /* 291 * Add a symbol for the DOF itself. We use a different symbol for 292 * lazily and actively loaded DOF to make them easy to distinguish. 293 */ 294 sym->st_name = strtabsz; 295 sym->st_value = 0; 296 sym->st_size = dof->dofh_filesz; 297 sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT); 298 #ifdef illumos 299 sym->st_other = 0; 300 #else 301 sym->st_other = ELF32_ST_VISIBILITY(STV_HIDDEN); 302 #endif 303 sym->st_shndx = ESHDR_DOF; 304 sym++; 305 306 if (dtp->dt_lazyload) { 307 bcopy(DOFLAZYSTR, dep->de_strtab + strtabsz, 308 sizeof (DOFLAZYSTR)); 309 strtabsz += sizeof (DOFLAZYSTR); 310 } else { 311 bcopy(DOFSTR, dep->de_strtab + strtabsz, sizeof (DOFSTR)); 312 strtabsz += sizeof (DOFSTR); 313 } 314 315 assert(count == dep->de_nrel); 316 assert(strtabsz == dep->de_strlen); 317 318 return (0); 319 } 320 321 322 typedef struct dof_elf64 { 323 uint32_t de_nrel; 324 Elf64_Rela *de_rel; 325 uint32_t de_nsym; 326 Elf64_Sym *de_sym; 327 328 uint32_t de_strlen; 329 char *de_strtab; 330 331 uint32_t de_global; 332 } dof_elf64_t; 333 334 static int 335 prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep) 336 { 337 dof_sec_t *dofs, *s; 338 dof_relohdr_t *dofrh; 339 dof_relodesc_t *dofr; 340 char *strtab; 341 int i, j, nrel; 342 size_t strtabsz = 1; 343 #ifdef illumos 344 uint32_t count = 0; 345 #else 346 uint64_t count = 0; 347 #endif 348 size_t base; 349 Elf64_Sym *sym; 350 Elf64_Rela *rel; 351 352 /*LINTED*/ 353 dofs = (dof_sec_t *)((char *)dof + dof->dofh_secoff); 354 355 /* 356 * First compute the size of the string table and the number of 357 * relocations present in the DOF. 358 */ 359 for (i = 0; i < dof->dofh_secnum; i++) { 360 if (dofs[i].dofs_type != DOF_SECT_URELHDR) 361 continue; 362 363 /*LINTED*/ 364 dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset); 365 366 s = &dofs[dofrh->dofr_strtab]; 367 strtab = (char *)dof + s->dofs_offset; 368 assert(strtab[0] == '\0'); 369 strtabsz += s->dofs_size - 1; 370 371 s = &dofs[dofrh->dofr_relsec]; 372 /*LINTED*/ 373 dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); 374 count += s->dofs_size / s->dofs_entsize; 375 } 376 377 dep->de_strlen = strtabsz; 378 dep->de_nrel = count; 379 dep->de_nsym = count + 1; /* the first symbol is always null */ 380 381 if (dtp->dt_lazyload) { 382 dep->de_strlen += sizeof (DOFLAZYSTR); 383 dep->de_nsym++; 384 } else { 385 dep->de_strlen += sizeof (DOFSTR); 386 dep->de_nsym++; 387 } 388 389 if ((dep->de_rel = calloc(dep->de_nrel, 390 sizeof (dep->de_rel[0]))) == NULL) { 391 return (dt_set_errno(dtp, EDT_NOMEM)); 392 } 393 394 if ((dep->de_sym = calloc(dep->de_nsym, sizeof (Elf64_Sym))) == NULL) { 395 free(dep->de_rel); 396 return (dt_set_errno(dtp, EDT_NOMEM)); 397 } 398 399 if ((dep->de_strtab = calloc(dep->de_strlen, 1)) == NULL) { 400 free(dep->de_rel); 401 free(dep->de_sym); 402 return (dt_set_errno(dtp, EDT_NOMEM)); 403 } 404 405 count = 0; 406 strtabsz = 1; 407 dep->de_strtab[0] = '\0'; 408 rel = dep->de_rel; 409 sym = dep->de_sym; 410 dep->de_global = 1; 411 412 /* 413 * The first symbol table entry must be zeroed and is always ignored. 414 */ 415 bzero(sym, sizeof (Elf64_Sym)); 416 sym++; 417 418 /* 419 * Take a second pass through the DOF sections filling in the 420 * memory we allocated. 421 */ 422 for (i = 0; i < dof->dofh_secnum; i++) { 423 if (dofs[i].dofs_type != DOF_SECT_URELHDR) 424 continue; 425 426 /*LINTED*/ 427 dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset); 428 429 s = &dofs[dofrh->dofr_strtab]; 430 strtab = (char *)dof + s->dofs_offset; 431 bcopy(strtab + 1, dep->de_strtab + strtabsz, s->dofs_size); 432 base = strtabsz; 433 strtabsz += s->dofs_size - 1; 434 435 s = &dofs[dofrh->dofr_relsec]; 436 /*LINTED*/ 437 dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); 438 nrel = s->dofs_size / s->dofs_entsize; 439 440 s = &dofs[dofrh->dofr_tgtsec]; 441 442 for (j = 0; j < nrel; j++) { 443 #if defined(__aarch64__) 444 /* XXX */ 445 #elif defined(__arm__) 446 /* XXX */ 447 #elif defined(__mips__) 448 /* XXX */ 449 #elif defined(__powerpc__) 450 rel->r_offset = s->dofs_offset + 451 dofr[j].dofr_offset; 452 rel->r_info = ELF64_R_INFO(count + dep->de_global, 453 R_PPC64_REL64); 454 #elif defined(__i386) || defined(__amd64) 455 rel->r_offset = s->dofs_offset + 456 dofr[j].dofr_offset; 457 #ifdef illumos 458 rel->r_info = ELF64_R_INFO(count + dep->de_global, 459 R_AMD64_64); 460 #else 461 #if defined(__amd64) 462 rel->r_info = ELF64_R_INFO(count + dep->de_global, 463 R_X86_64_RELATIVE); 464 #endif 465 #endif 466 #elif defined(__sparc) 467 rel->r_offset = s->dofs_offset + 468 dofr[j].dofr_offset; 469 rel->r_info = ELF64_R_INFO(count + dep->de_global, 470 R_SPARC_64); 471 #else 472 #error unknown ISA 473 #endif 474 475 sym->st_name = base + dofr[j].dofr_name - 1; 476 sym->st_value = 0; 477 sym->st_size = 0; 478 sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_FUNC); 479 sym->st_other = 0; 480 sym->st_shndx = SHN_UNDEF; 481 482 rel++; 483 sym++; 484 count++; 485 } 486 } 487 488 /* 489 * Add a symbol for the DOF itself. We use a different symbol for 490 * lazily and actively loaded DOF to make them easy to distinguish. 491 */ 492 sym->st_name = strtabsz; 493 sym->st_value = 0; 494 sym->st_size = dof->dofh_filesz; 495 sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_OBJECT); 496 #ifdef illumos 497 sym->st_other = 0; 498 #else 499 sym->st_other = ELF64_ST_VISIBILITY(STV_HIDDEN); 500 #endif 501 sym->st_shndx = ESHDR_DOF; 502 sym++; 503 504 if (dtp->dt_lazyload) { 505 bcopy(DOFLAZYSTR, dep->de_strtab + strtabsz, 506 sizeof (DOFLAZYSTR)); 507 strtabsz += sizeof (DOFLAZYSTR); 508 } else { 509 bcopy(DOFSTR, dep->de_strtab + strtabsz, sizeof (DOFSTR)); 510 strtabsz += sizeof (DOFSTR); 511 } 512 513 assert(count == dep->de_nrel); 514 assert(strtabsz == dep->de_strlen); 515 516 return (0); 517 } 518 519 /* 520 * Write out an ELF32 file prologue consisting of a header, section headers, 521 * and a section header string table. The DOF data will follow this prologue 522 * and complete the contents of the given ELF file. 523 */ 524 static int 525 dump_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd) 526 { 527 struct { 528 Elf32_Ehdr ehdr; 529 Elf32_Shdr shdr[ESHDR_NUM]; 530 } elf_file; 531 532 Elf32_Shdr *shp; 533 Elf32_Off off; 534 dof_elf32_t de; 535 int ret = 0; 536 uint_t nshdr; 537 538 memset(&de, 0, sizeof(de)); // XXX: gcc 539 if (prepare_elf32(dtp, dof, &de) != 0) 540 return (-1); /* errno is set for us */ 541 542 /* 543 * If there are no relocations, we only need enough sections for 544 * the shstrtab and the DOF. 545 */ 546 nshdr = de.de_nrel == 0 ? ESHDR_SYMTAB + 1 : ESHDR_NUM; 547 548 bzero(&elf_file, sizeof (elf_file)); 549 550 elf_file.ehdr.e_ident[EI_MAG0] = ELFMAG0; 551 elf_file.ehdr.e_ident[EI_MAG1] = ELFMAG1; 552 elf_file.ehdr.e_ident[EI_MAG2] = ELFMAG2; 553 elf_file.ehdr.e_ident[EI_MAG3] = ELFMAG3; 554 elf_file.ehdr.e_ident[EI_VERSION] = EV_CURRENT; 555 elf_file.ehdr.e_ident[EI_CLASS] = ELFCLASS32; 556 #if BYTE_ORDER == _BIG_ENDIAN 557 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2MSB; 558 #else 559 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2LSB; 560 #endif 561 #if defined(__FreeBSD__) || defined(__NetBSD__) 562 elf_file.ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; 563 #endif 564 elf_file.ehdr.e_type = ET_REL; 565 #if defined(__arm__) 566 elf_file.ehdr.e_machine = EM_ARM; 567 #elif defined(__mips__) 568 elf_file.ehdr.e_machine = EM_MIPS; 569 #elif defined(__powerpc__) 570 elf_file.ehdr.e_machine = EM_PPC; 571 #elif defined(__sparc) 572 elf_file.ehdr.e_machine = EM_SPARC; 573 #elif defined(__i386) || defined(__amd64) 574 elf_file.ehdr.e_machine = EM_386; 575 #endif 576 elf_file.ehdr.e_version = EV_CURRENT; 577 elf_file.ehdr.e_shoff = sizeof (Elf32_Ehdr); 578 elf_file.ehdr.e_ehsize = sizeof (Elf32_Ehdr); 579 elf_file.ehdr.e_phentsize = sizeof (Elf32_Phdr); 580 elf_file.ehdr.e_shentsize = sizeof (Elf32_Shdr); 581 elf_file.ehdr.e_shnum = nshdr; 582 elf_file.ehdr.e_shstrndx = ESHDR_SHSTRTAB; 583 off = sizeof (elf_file) + nshdr * sizeof (Elf32_Shdr); 584 585 shp = &elf_file.shdr[ESHDR_SHSTRTAB]; 586 shp->sh_name = 1; /* DTRACE_SHSTRTAB32[1] = ".shstrtab" */ 587 shp->sh_type = SHT_STRTAB; 588 shp->sh_offset = off; 589 shp->sh_size = sizeof (DTRACE_SHSTRTAB32); 590 shp->sh_addralign = sizeof (char); 591 off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8); 592 593 shp = &elf_file.shdr[ESHDR_DOF]; 594 shp->sh_name = 11; /* DTRACE_SHSTRTAB32[11] = ".SUNW_dof" */ 595 shp->sh_flags = SHF_ALLOC; 596 shp->sh_type = SHT_SUNW_dof; 597 shp->sh_offset = off; 598 shp->sh_size = dof->dofh_filesz; 599 shp->sh_addralign = 8; 600 off = shp->sh_offset + shp->sh_size; 601 602 shp = &elf_file.shdr[ESHDR_STRTAB]; 603 shp->sh_name = 21; /* DTRACE_SHSTRTAB32[21] = ".strtab" */ 604 shp->sh_flags = SHF_ALLOC; 605 shp->sh_type = SHT_STRTAB; 606 shp->sh_offset = off; 607 shp->sh_size = de.de_strlen; 608 shp->sh_addralign = sizeof (char); 609 off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 4); 610 611 shp = &elf_file.shdr[ESHDR_SYMTAB]; 612 shp->sh_name = 29; /* DTRACE_SHSTRTAB32[29] = ".symtab" */ 613 shp->sh_flags = SHF_ALLOC; 614 shp->sh_type = SHT_SYMTAB; 615 shp->sh_entsize = sizeof (Elf32_Sym); 616 shp->sh_link = ESHDR_STRTAB; 617 shp->sh_offset = off; 618 shp->sh_info = de.de_global; 619 shp->sh_size = de.de_nsym * sizeof (Elf32_Sym); 620 shp->sh_addralign = 4; 621 off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 4); 622 623 if (de.de_nrel == 0) { 624 if (dt_write(dtp, fd, &elf_file, 625 sizeof (elf_file)) != sizeof (elf_file) || 626 PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB32) || 627 PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) || 628 PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) || 629 PWRITE_SCN(ESHDR_DOF, dof)) { 630 ret = dt_set_errno(dtp, errno); 631 } 632 } else { 633 shp = &elf_file.shdr[ESHDR_REL]; 634 shp->sh_name = 37; /* DTRACE_SHSTRTAB32[37] = ".rel.SUNW_dof" */ 635 shp->sh_flags = SHF_ALLOC; 636 #ifdef __sparc 637 shp->sh_type = SHT_RELA; 638 #else 639 shp->sh_type = SHT_REL; 640 #endif 641 shp->sh_entsize = sizeof (de.de_rel[0]); 642 shp->sh_link = ESHDR_SYMTAB; 643 shp->sh_info = ESHDR_DOF; 644 shp->sh_offset = off; 645 shp->sh_size = de.de_nrel * sizeof (de.de_rel[0]); 646 shp->sh_addralign = 4; 647 648 if (dt_write(dtp, fd, &elf_file, 649 sizeof (elf_file)) != sizeof (elf_file) || 650 PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB32) || 651 PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) || 652 PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) || 653 PWRITE_SCN(ESHDR_REL, de.de_rel) || 654 PWRITE_SCN(ESHDR_DOF, dof)) { 655 ret = dt_set_errno(dtp, errno); 656 } 657 } 658 659 free(de.de_strtab); 660 free(de.de_sym); 661 free(de.de_rel); 662 663 return (ret); 664 } 665 666 /* 667 * Write out an ELF64 file prologue consisting of a header, section headers, 668 * and a section header string table. The DOF data will follow this prologue 669 * and complete the contents of the given ELF file. 670 */ 671 static int 672 dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd) 673 { 674 struct { 675 Elf64_Ehdr ehdr; 676 Elf64_Shdr shdr[ESHDR_NUM]; 677 } elf_file; 678 679 Elf64_Shdr *shp; 680 Elf64_Off off; 681 dof_elf64_t de; 682 int ret = 0; 683 uint_t nshdr; 684 685 memset(&de, 0, sizeof(de)); // XXX: gcc 686 if (prepare_elf64(dtp, dof, &de) != 0) 687 return (-1); /* errno is set for us */ 688 689 /* 690 * If there are no relocations, we only need enough sections for 691 * the shstrtab and the DOF. 692 */ 693 nshdr = de.de_nrel == 0 ? ESHDR_SYMTAB + 1 : ESHDR_NUM; 694 695 bzero(&elf_file, sizeof (elf_file)); 696 697 elf_file.ehdr.e_ident[EI_MAG0] = ELFMAG0; 698 elf_file.ehdr.e_ident[EI_MAG1] = ELFMAG1; 699 elf_file.ehdr.e_ident[EI_MAG2] = ELFMAG2; 700 elf_file.ehdr.e_ident[EI_MAG3] = ELFMAG3; 701 elf_file.ehdr.e_ident[EI_VERSION] = EV_CURRENT; 702 elf_file.ehdr.e_ident[EI_CLASS] = ELFCLASS64; 703 #if BYTE_ORDER == _BIG_ENDIAN 704 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2MSB; 705 #else 706 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2LSB; 707 #endif 708 #if defined(__FreeBSD__) || defined(__NetBSD__) 709 elf_file.ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; 710 #endif 711 elf_file.ehdr.e_type = ET_REL; 712 #if defined(__arm__) 713 elf_file.ehdr.e_machine = EM_ARM; 714 #elif defined(__mips__) 715 elf_file.ehdr.e_machine = EM_MIPS; 716 #elif defined(__powerpc64__) 717 elf_file.ehdr.e_machine = EM_PPC64; 718 #elif defined(__sparc) 719 elf_file.ehdr.e_machine = EM_SPARCV9; 720 #elif defined(__i386) || defined(__amd64) 721 elf_file.ehdr.e_machine = EM_AMD64; 722 #endif 723 elf_file.ehdr.e_version = EV_CURRENT; 724 elf_file.ehdr.e_shoff = sizeof (Elf64_Ehdr); 725 elf_file.ehdr.e_ehsize = sizeof (Elf64_Ehdr); 726 elf_file.ehdr.e_phentsize = sizeof (Elf64_Phdr); 727 elf_file.ehdr.e_shentsize = sizeof (Elf64_Shdr); 728 elf_file.ehdr.e_shnum = nshdr; 729 elf_file.ehdr.e_shstrndx = ESHDR_SHSTRTAB; 730 off = sizeof (elf_file) + nshdr * sizeof (Elf64_Shdr); 731 732 shp = &elf_file.shdr[ESHDR_SHSTRTAB]; 733 shp->sh_name = 1; /* DTRACE_SHSTRTAB64[1] = ".shstrtab" */ 734 shp->sh_type = SHT_STRTAB; 735 shp->sh_offset = off; 736 shp->sh_size = sizeof (DTRACE_SHSTRTAB64); 737 shp->sh_addralign = sizeof (char); 738 off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8); 739 740 shp = &elf_file.shdr[ESHDR_DOF]; 741 shp->sh_name = 11; /* DTRACE_SHSTRTAB64[11] = ".SUNW_dof" */ 742 shp->sh_flags = SHF_ALLOC; 743 shp->sh_type = SHT_SUNW_dof; 744 shp->sh_offset = off; 745 shp->sh_size = dof->dofh_filesz; 746 shp->sh_addralign = 8; 747 off = shp->sh_offset + shp->sh_size; 748 749 shp = &elf_file.shdr[ESHDR_STRTAB]; 750 shp->sh_name = 21; /* DTRACE_SHSTRTAB64[21] = ".strtab" */ 751 shp->sh_flags = SHF_ALLOC; 752 shp->sh_type = SHT_STRTAB; 753 shp->sh_offset = off; 754 shp->sh_size = de.de_strlen; 755 shp->sh_addralign = sizeof (char); 756 off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8); 757 758 shp = &elf_file.shdr[ESHDR_SYMTAB]; 759 shp->sh_name = 29; /* DTRACE_SHSTRTAB64[29] = ".symtab" */ 760 shp->sh_flags = SHF_ALLOC; 761 shp->sh_type = SHT_SYMTAB; 762 shp->sh_entsize = sizeof (Elf64_Sym); 763 shp->sh_link = ESHDR_STRTAB; 764 shp->sh_offset = off; 765 shp->sh_info = de.de_global; 766 shp->sh_size = de.de_nsym * sizeof (Elf64_Sym); 767 shp->sh_addralign = 8; 768 off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8); 769 770 if (de.de_nrel == 0) { 771 if (dt_write(dtp, fd, &elf_file, 772 sizeof (elf_file)) != sizeof (elf_file) || 773 PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB64) || 774 PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) || 775 PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) || 776 PWRITE_SCN(ESHDR_DOF, dof)) { 777 ret = dt_set_errno(dtp, errno); 778 } 779 } else { 780 shp = &elf_file.shdr[ESHDR_REL]; 781 shp->sh_name = 37; /* DTRACE_SHSTRTAB64[37] = ".rel.SUNW_dof" */ 782 shp->sh_flags = SHF_ALLOC; 783 shp->sh_type = SHT_RELA; 784 shp->sh_entsize = sizeof (de.de_rel[0]); 785 shp->sh_link = ESHDR_SYMTAB; 786 shp->sh_info = ESHDR_DOF; 787 shp->sh_offset = off; 788 shp->sh_size = de.de_nrel * sizeof (de.de_rel[0]); 789 shp->sh_addralign = 8; 790 791 if (dt_write(dtp, fd, &elf_file, 792 sizeof (elf_file)) != sizeof (elf_file) || 793 PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB64) || 794 PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) || 795 PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) || 796 PWRITE_SCN(ESHDR_REL, de.de_rel) || 797 PWRITE_SCN(ESHDR_DOF, dof)) { 798 ret = dt_set_errno(dtp, errno); 799 } 800 } 801 802 free(de.de_strtab); 803 free(de.de_sym); 804 free(de.de_rel); 805 806 return (ret); 807 } 808 809 static int 810 dt_symtab_lookup(Elf_Data *data_sym, int nsym, uintptr_t addr, uint_t shn, 811 GElf_Sym *sym, int uses_funcdesc, Elf *elf) 812 { 813 int i, ret = -1; 814 Elf64_Addr symval; 815 Elf_Scn *opd_scn; 816 Elf_Data *opd_desc; 817 GElf_Sym s; 818 819 for (i = 0; i < nsym && gelf_getsym(data_sym, i, sym) != NULL; i++) { 820 if (GELF_ST_TYPE(sym->st_info) == STT_FUNC) { 821 symval = sym->st_value; 822 if (uses_funcdesc) { 823 opd_scn = elf_getscn(elf, sym->st_shndx); 824 opd_desc = elf_rawdata(opd_scn, NULL); 825 symval = 826 *(uint64_t*)((char *)opd_desc->d_buf + symval); 827 } 828 if ((uses_funcdesc || shn == sym->st_shndx) && 829 symval <= addr && 830 addr < symval + sym->st_size) { 831 if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL) 832 return (0); 833 834 ret = 0; 835 s = *sym; 836 } 837 } 838 } 839 840 if (ret == 0) 841 *sym = s; 842 return (ret); 843 } 844 845 #if defined(__aarch64__) 846 /* XXX */ 847 static int 848 dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, 849 uint32_t *off) 850 { 851 printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 852 return (0); 853 } 854 #elif defined(__arm__) 855 /* XXX */ 856 static int 857 dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, 858 uint32_t *off) 859 { 860 printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 861 return (0); 862 } 863 #elif defined(__mips__) 864 /* XXX */ 865 static int 866 dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, 867 uint32_t *off) 868 { 869 printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 870 return (0); 871 } 872 #elif defined(__powerpc__) 873 /* The sentinel is 'xor r3,r3,r3'. */ 874 #define DT_OP_XOR_R3 0x7c631a78 875 876 #define DT_OP_NOP 0x60000000 877 #define DT_OP_BLR 0x4e800020 878 879 /* This captures all forms of branching to address. */ 880 #define DT_IS_BRANCH(inst) ((inst & 0xfc000000) == 0x48000000) 881 #define DT_IS_BL(inst) (DT_IS_BRANCH(inst) && (inst & 0x01)) 882 883 /* XXX */ 884 static int 885 dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, 886 uint32_t *off) 887 { 888 uint32_t *ip; 889 890 if ((rela->r_offset & (sizeof (uint32_t) - 1)) != 0) 891 return (-1); 892 893 /*LINTED*/ 894 ip = (uint32_t *)(p + rela->r_offset); 895 896 /* 897 * We only know about some specific relocation types. 898 */ 899 if (GELF_R_TYPE(rela->r_info) != R_PPC_REL24 && 900 GELF_R_TYPE(rela->r_info) != R_PPC_PLTREL24) 901 return (-1); 902 903 /* 904 * We may have already processed this object file in an earlier linker 905 * invocation. Check to see if the present instruction sequence matches 906 * the one we would install below. 907 */ 908 if (isenabled) { 909 if (ip[0] == DT_OP_XOR_R3) { 910 (*off) += sizeof (ip[0]); 911 return (0); 912 } 913 } else { 914 if (ip[0] == DT_OP_NOP) { 915 (*off) += sizeof (ip[0]); 916 return (0); 917 } 918 } 919 920 /* 921 * We only expect branch to address instructions. 922 */ 923 if (!DT_IS_BRANCH(ip[0])) { 924 dt_dprintf("found %x instead of a branch instruction at %llx\n", 925 ip[0], (u_longlong_t)rela->r_offset); 926 return (-1); 927 } 928 929 if (isenabled) { 930 /* 931 * It would necessarily indicate incorrect usage if an is- 932 * enabled probe were tail-called so flag that as an error. 933 * It's also potentially (very) tricky to handle gracefully, 934 * but could be done if this were a desired use scenario. 935 */ 936 if (!DT_IS_BL(ip[0])) { 937 dt_dprintf("tail call to is-enabled probe at %llx\n", 938 (u_longlong_t)rela->r_offset); 939 return (-1); 940 } 941 942 ip[0] = DT_OP_XOR_R3; 943 (*off) += sizeof (ip[0]); 944 } else { 945 if (DT_IS_BL(ip[0])) 946 ip[0] = DT_OP_NOP; 947 else 948 ip[0] = DT_OP_BLR; 949 } 950 951 return (0); 952 } 953 954 #elif defined(__sparc) 955 956 #define DT_OP_RET 0x81c7e008 957 #define DT_OP_NOP 0x01000000 958 #define DT_OP_CALL 0x40000000 959 #define DT_OP_CLR_O0 0x90102000 960 961 #define DT_IS_MOV_O7(inst) (((inst) & 0xffffe000) == 0x9e100000) 962 #define DT_IS_RESTORE(inst) (((inst) & 0xc1f80000) == 0x81e80000) 963 #define DT_IS_RETL(inst) (((inst) & 0xfff83fff) == 0x81c02008) 964 965 #define DT_RS2(inst) ((inst) & 0x1f) 966 #define DT_MAKE_RETL(reg) (0x81c02008 | ((reg) << 14)) 967 968 /*ARGSUSED*/ 969 static int 970 dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, 971 uint32_t *off) 972 { 973 uint32_t *ip; 974 975 if ((rela->r_offset & (sizeof (uint32_t) - 1)) != 0) 976 return (-1); 977 978 /*LINTED*/ 979 ip = (uint32_t *)(p + rela->r_offset); 980 981 /* 982 * We only know about some specific relocation types. 983 */ 984 if (GELF_R_TYPE(rela->r_info) != R_SPARC_WDISP30 && 985 GELF_R_TYPE(rela->r_info) != R_SPARC_WPLT30) 986 return (-1); 987 988 /* 989 * We may have already processed this object file in an earlier linker 990 * invocation. Check to see if the present instruction sequence matches 991 * the one we would install below. 992 */ 993 if (isenabled) { 994 if (ip[0] == DT_OP_NOP) { 995 (*off) += sizeof (ip[0]); 996 return (0); 997 } 998 } else { 999 if (DT_IS_RESTORE(ip[1])) { 1000 if (ip[0] == DT_OP_RET) { 1001 (*off) += sizeof (ip[0]); 1002 return (0); 1003 } 1004 } else if (DT_IS_MOV_O7(ip[1])) { 1005 if (DT_IS_RETL(ip[0])) 1006 return (0); 1007 } else { 1008 if (ip[0] == DT_OP_NOP) { 1009 (*off) += sizeof (ip[0]); 1010 return (0); 1011 } 1012 } 1013 } 1014 1015 /* 1016 * We only expect call instructions with a displacement of 0. 1017 */ 1018 if (ip[0] != DT_OP_CALL) { 1019 dt_dprintf("found %x instead of a call instruction at %llx\n", 1020 ip[0], (u_longlong_t)rela->r_offset); 1021 return (-1); 1022 } 1023 1024 if (isenabled) { 1025 /* 1026 * It would necessarily indicate incorrect usage if an is- 1027 * enabled probe were tail-called so flag that as an error. 1028 * It's also potentially (very) tricky to handle gracefully, 1029 * but could be done if this were a desired use scenario. 1030 */ 1031 if (DT_IS_RESTORE(ip[1]) || DT_IS_MOV_O7(ip[1])) { 1032 dt_dprintf("tail call to is-enabled probe at %llx\n", 1033 (u_longlong_t)rela->r_offset); 1034 return (-1); 1035 } 1036 1037 1038 /* 1039 * On SPARC, we take advantage of the fact that the first 1040 * argument shares the same register as for the return value. 1041 * The macro handles the work of zeroing that register so we 1042 * don't need to do anything special here. We instrument the 1043 * instruction in the delay slot as we'll need to modify the 1044 * return register after that instruction has been emulated. 1045 */ 1046 ip[0] = DT_OP_NOP; 1047 (*off) += sizeof (ip[0]); 1048 } else { 1049 /* 1050 * If the call is followed by a restore, it's a tail call so 1051 * change the call to a ret. If the call if followed by a mov 1052 * of a register into %o7, it's a tail call in leaf context 1053 * so change the call to a retl-like instruction that returns 1054 * to that register value + 8 (rather than the typical %o7 + 1055 * 8); the delay slot instruction is left, but should have no 1056 * effect. Otherwise we change the call to be a nop. We 1057 * identify the subsequent instruction as the probe point in 1058 * all but the leaf tail-call case to ensure that arguments to 1059 * the probe are complete and consistent. An astute, though 1060 * largely hypothetical, observer would note that there is the 1061 * possibility of a false-positive probe firing if the function 1062 * contained a branch to the instruction in the delay slot of 1063 * the call. Fixing this would require significant in-kernel 1064 * modifications, and isn't worth doing until we see it in the 1065 * wild. 1066 */ 1067 if (DT_IS_RESTORE(ip[1])) { 1068 ip[0] = DT_OP_RET; 1069 (*off) += sizeof (ip[0]); 1070 } else if (DT_IS_MOV_O7(ip[1])) { 1071 ip[0] = DT_MAKE_RETL(DT_RS2(ip[1])); 1072 } else { 1073 ip[0] = DT_OP_NOP; 1074 (*off) += sizeof (ip[0]); 1075 } 1076 } 1077 1078 return (0); 1079 } 1080 1081 #elif defined(__i386) || defined(__amd64) 1082 1083 #define DT_OP_NOP 0x90 1084 #define DT_OP_RET 0xc3 1085 #define DT_OP_CALL 0xe8 1086 #define DT_OP_JMP32 0xe9 1087 #define DT_OP_REX_RAX 0x48 1088 #define DT_OP_XOR_EAX_0 0x33 1089 #define DT_OP_XOR_EAX_1 0xc0 1090 1091 static int 1092 dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, 1093 uint32_t *off) 1094 { 1095 uint8_t *ip = (uint8_t *)(p + rela->r_offset - 1); 1096 uint8_t ret; 1097 1098 /* 1099 * On x86, the first byte of the instruction is the call opcode and 1100 * the next four bytes are the 32-bit address; the relocation is for 1101 * the address operand. We back up the offset to the first byte of 1102 * the instruction. For is-enabled probes, we later advance the offset 1103 * so that it hits the first nop in the instruction sequence. 1104 */ 1105 (*off) -= 1; 1106 1107 /* 1108 * We only know about some specific relocation types. Luckily 1109 * these types have the same values on both 32-bit and 64-bit 1110 * x86 architectures. 1111 */ 1112 if (GELF_R_TYPE(rela->r_info) != R_386_PC32 && 1113 GELF_R_TYPE(rela->r_info) != R_386_PLT32) 1114 return (-1); 1115 1116 /* 1117 * We may have already processed this object file in an earlier linker 1118 * invocation. Check to see if the present instruction sequence matches 1119 * the one we would install. For is-enabled probes, we advance the 1120 * offset to the first nop instruction in the sequence to match the 1121 * text modification code below. 1122 */ 1123 if (!isenabled) { 1124 if ((ip[0] == DT_OP_NOP || ip[0] == DT_OP_RET) && 1125 ip[1] == DT_OP_NOP && ip[2] == DT_OP_NOP && 1126 ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP) 1127 return (0); 1128 } else if (dtp->dt_oflags & DTRACE_O_LP64) { 1129 if (ip[0] == DT_OP_REX_RAX && 1130 ip[1] == DT_OP_XOR_EAX_0 && ip[2] == DT_OP_XOR_EAX_1 && 1131 (ip[3] == DT_OP_NOP || ip[3] == DT_OP_RET) && 1132 ip[4] == DT_OP_NOP) { 1133 (*off) += 3; 1134 return (0); 1135 } 1136 } else { 1137 if (ip[0] == DT_OP_XOR_EAX_0 && ip[1] == DT_OP_XOR_EAX_1 && 1138 (ip[2] == DT_OP_NOP || ip[2] == DT_OP_RET) && 1139 ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP) { 1140 (*off) += 2; 1141 return (0); 1142 } 1143 } 1144 1145 /* 1146 * We expect either a call instrution with a 32-bit displacement or a 1147 * jmp instruction with a 32-bit displacement acting as a tail-call. 1148 */ 1149 if (ip[0] != DT_OP_CALL && ip[0] != DT_OP_JMP32) { 1150 dt_dprintf("found %x instead of a call or jmp instruction at " 1151 "%llx\n", ip[0], (u_longlong_t)rela->r_offset); 1152 return (-1); 1153 } 1154 1155 ret = (ip[0] == DT_OP_JMP32) ? DT_OP_RET : DT_OP_NOP; 1156 1157 /* 1158 * Establish the instruction sequence -- all nops for probes, and an 1159 * instruction to clear the return value register (%eax/%rax) followed 1160 * by nops for is-enabled probes. For is-enabled probes, we advance 1161 * the offset to the first nop. This isn't stricly necessary but makes 1162 * for more readable disassembly when the probe is enabled. 1163 */ 1164 if (!isenabled) { 1165 ip[0] = ret; 1166 ip[1] = DT_OP_NOP; 1167 ip[2] = DT_OP_NOP; 1168 ip[3] = DT_OP_NOP; 1169 ip[4] = DT_OP_NOP; 1170 } else if (dtp->dt_oflags & DTRACE_O_LP64) { 1171 ip[0] = DT_OP_REX_RAX; 1172 ip[1] = DT_OP_XOR_EAX_0; 1173 ip[2] = DT_OP_XOR_EAX_1; 1174 ip[3] = ret; 1175 ip[4] = DT_OP_NOP; 1176 (*off) += 3; 1177 } else { 1178 ip[0] = DT_OP_XOR_EAX_0; 1179 ip[1] = DT_OP_XOR_EAX_1; 1180 ip[2] = ret; 1181 ip[3] = DT_OP_NOP; 1182 ip[4] = DT_OP_NOP; 1183 (*off) += 2; 1184 } 1185 1186 return (0); 1187 } 1188 1189 #else 1190 #error unknown ISA 1191 #endif 1192 1193 /*PRINTFLIKE5*/ 1194 static int 1195 dt_link_error(dtrace_hdl_t *dtp, Elf *elf, int fd, dt_link_pair_t *bufs, 1196 const char *format, ...) 1197 { 1198 va_list ap; 1199 dt_link_pair_t *pair; 1200 1201 va_start(ap, format); 1202 dt_set_errmsg(dtp, NULL, NULL, NULL, 0, format, ap); 1203 va_end(ap); 1204 1205 if (elf != NULL) 1206 (void) elf_end(elf); 1207 1208 if (fd >= 0) 1209 (void) close(fd); 1210 1211 while ((pair = bufs) != NULL) { 1212 bufs = pair->dlp_next; 1213 dt_free(dtp, pair->dlp_str); 1214 dt_free(dtp, pair->dlp_sym); 1215 dt_free(dtp, pair); 1216 } 1217 1218 return (dt_set_errno(dtp, EDT_COMPILER)); 1219 } 1220 1221 static int 1222 process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) 1223 { 1224 static const char dt_prefix[] = "__dtrace"; 1225 static const char dt_enabled[] = "enabled"; 1226 static const char dt_symprefix[] = "$dtrace"; 1227 static const char dt_symfmt[] = "%s%ld.%s"; 1228 int fd, i, ndx, eprobe, mod = 0; 1229 Elf *elf = NULL; 1230 GElf_Ehdr ehdr; 1231 Elf_Scn *scn_rel, *scn_sym, *scn_str, *scn_tgt; 1232 Elf_Data *data_rel, *data_sym, *data_str, *data_tgt; 1233 GElf_Shdr shdr_rel, shdr_sym, shdr_str, shdr_tgt; 1234 GElf_Sym rsym, fsym, dsym; 1235 GElf_Rela rela; 1236 char *s, *p, *r; 1237 char pname[DTRACE_PROVNAMELEN]; 1238 dt_provider_t *pvp; 1239 dt_probe_t *prp; 1240 uint32_t off, eclass, emachine1, emachine2; 1241 size_t symsize, nsym = 0, isym, istr, len; 1242 key_t objkey; 1243 dt_link_pair_t *pair, *bufs = NULL; 1244 dt_strtab_t *strtab; 1245 1246 if ((fd = open64(obj, O_RDWR)) == -1) { 1247 return (dt_link_error(dtp, elf, fd, bufs, 1248 "failed to open %s: %s", obj, strerror(errno))); 1249 } 1250 1251 if ((elf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) { 1252 return (dt_link_error(dtp, elf, fd, bufs, 1253 "failed to process %s: %s", obj, elf_errmsg(elf_errno()))); 1254 } 1255 1256 switch (elf_kind(elf)) { 1257 case ELF_K_ELF: 1258 break; 1259 case ELF_K_AR: 1260 return (dt_link_error(dtp, elf, fd, bufs, "archives are not " 1261 "permitted; use the contents of the archive instead: %s", 1262 obj)); 1263 default: 1264 return (dt_link_error(dtp, elf, fd, bufs, 1265 "invalid file type: %s", obj)); 1266 } 1267 1268 if (gelf_getehdr(elf, &ehdr) == NULL) { 1269 return (dt_link_error(dtp, elf, fd, bufs, "corrupt file: %s", 1270 obj)); 1271 } 1272 1273 if (dtp->dt_oflags & DTRACE_O_LP64) { 1274 eclass = ELFCLASS64; 1275 #if defined(__mips__) 1276 emachine1 = emachine2 = EM_MIPS; 1277 #elif defined(__powerpc__) 1278 emachine1 = emachine2 = EM_PPC64; 1279 #elif defined(__sparc) 1280 emachine1 = emachine2 = EM_SPARCV9; 1281 #elif defined(__i386) || defined(__amd64) 1282 emachine1 = emachine2 = EM_AMD64; 1283 #endif 1284 symsize = sizeof (Elf64_Sym); 1285 } else { 1286 eclass = ELFCLASS32; 1287 #if defined(__arm__) 1288 emachine1 = emachine2 = EM_ARM; 1289 #elif defined(__mips__) 1290 emachine1 = emachine2 = EM_MIPS; 1291 #elif defined(__powerpc__) 1292 emachine1 = emachine2 = EM_PPC; 1293 #elif defined(__sparc) 1294 emachine1 = EM_SPARC; 1295 emachine2 = EM_SPARC32PLUS; 1296 #elif defined(__i386) || defined(__amd64) 1297 emachine1 = emachine2 = EM_386; 1298 #endif 1299 symsize = sizeof (Elf32_Sym); 1300 } 1301 1302 if (ehdr.e_ident[EI_CLASS] != eclass) { 1303 return (dt_link_error(dtp, elf, fd, bufs, 1304 "incorrect ELF class for object file: %s", obj)); 1305 } 1306 1307 if (ehdr.e_machine != emachine1 && ehdr.e_machine != emachine2) { 1308 return (dt_link_error(dtp, elf, fd, bufs, 1309 "incorrect ELF machine type for object file: %s", obj)); 1310 } 1311 1312 /* 1313 * We use this token as a relatively unique handle for this file on the 1314 * system in order to disambiguate potential conflicts between files of 1315 * the same name which contain identially named local symbols. 1316 */ 1317 if ((objkey = ftok(obj, 0)) == (key_t)-1) { 1318 return (dt_link_error(dtp, elf, fd, bufs, 1319 "failed to generate unique key for object file: %s", obj)); 1320 } 1321 1322 scn_rel = NULL; 1323 while ((scn_rel = elf_nextscn(elf, scn_rel)) != NULL) { 1324 if (gelf_getshdr(scn_rel, &shdr_rel) == NULL) 1325 goto err; 1326 1327 /* 1328 * Skip any non-relocation sections. 1329 */ 1330 if (shdr_rel.sh_type != SHT_RELA && shdr_rel.sh_type != SHT_REL) 1331 continue; 1332 1333 if ((data_rel = elf_getdata(scn_rel, NULL)) == NULL) 1334 goto err; 1335 1336 /* 1337 * Grab the section, section header and section data for the 1338 * symbol table that this relocation section references. 1339 */ 1340 if ((scn_sym = elf_getscn(elf, shdr_rel.sh_link)) == NULL || 1341 gelf_getshdr(scn_sym, &shdr_sym) == NULL || 1342 (data_sym = elf_getdata(scn_sym, NULL)) == NULL) 1343 goto err; 1344 1345 /* 1346 * Ditto for that symbol table's string table. 1347 */ 1348 if ((scn_str = elf_getscn(elf, shdr_sym.sh_link)) == NULL || 1349 gelf_getshdr(scn_str, &shdr_str) == NULL || 1350 (data_str = elf_getdata(scn_str, NULL)) == NULL) 1351 goto err; 1352 1353 /* 1354 * Grab the section, section header and section data for the 1355 * target section for the relocations. For the relocations 1356 * we're looking for -- this will typically be the text of the 1357 * object file. 1358 */ 1359 if ((scn_tgt = elf_getscn(elf, shdr_rel.sh_info)) == NULL || 1360 gelf_getshdr(scn_tgt, &shdr_tgt) == NULL || 1361 (data_tgt = elf_getdata(scn_tgt, NULL)) == NULL) 1362 goto err; 1363 1364 /* 1365 * We're looking for relocations to symbols matching this form: 1366 * 1367 * __dtrace[enabled]_<prov>___<probe> 1368 * 1369 * For the generated object, we need to record the location 1370 * identified by the relocation, and create a new relocation 1371 * in the generated object that will be resolved at link time 1372 * to the location of the function in which the probe is 1373 * embedded. In the target object, we change the matched symbol 1374 * so that it will be ignored at link time, and we modify the 1375 * target (text) section to replace the call instruction with 1376 * one or more nops. 1377 * 1378 * If the function containing the probe is locally scoped 1379 * (static), we create an alias used by the relocation in the 1380 * generated object. The alias, a new symbol, will be global 1381 * (so that the relocation from the generated object can be 1382 * resolved), and hidden (so that it is converted to a local 1383 * symbol at link time). Such aliases have this form: 1384 * 1385 * $dtrace<key>.<function> 1386 * 1387 * We take a first pass through all the relocations to 1388 * populate our string table and count the number of extra 1389 * symbols we'll require. 1390 */ 1391 strtab = dt_strtab_create(1); 1392 nsym = 0; 1393 isym = data_sym->d_size / symsize; 1394 istr = data_str->d_size; 1395 1396 for (i = 0; i < shdr_rel.sh_size / shdr_rel.sh_entsize; i++) { 1397 1398 if (shdr_rel.sh_type == SHT_RELA) { 1399 if (gelf_getrela(data_rel, i, &rela) == NULL) 1400 continue; 1401 } else { 1402 GElf_Rel rel; 1403 if (gelf_getrel(data_rel, i, &rel) == NULL) 1404 continue; 1405 rela.r_offset = rel.r_offset; 1406 rela.r_info = rel.r_info; 1407 rela.r_addend = 0; 1408 } 1409 1410 if (gelf_getsym(data_sym, GELF_R_SYM(rela.r_info), 1411 &rsym) == NULL) { 1412 dt_strtab_destroy(strtab); 1413 goto err; 1414 } 1415 1416 s = (char *)data_str->d_buf + rsym.st_name; 1417 1418 if (strncmp(s, dt_prefix, sizeof (dt_prefix) - 1) != 0) 1419 continue; 1420 1421 if (dt_symtab_lookup(data_sym, isym, rela.r_offset, 1422 shdr_rel.sh_info, &fsym, 1423 (emachine1 == EM_PPC64), elf) != 0) { 1424 dt_strtab_destroy(strtab); 1425 goto err; 1426 } 1427 1428 if (GELF_ST_BIND(fsym.st_info) != STB_LOCAL) 1429 continue; 1430 1431 if (fsym.st_name > data_str->d_size) { 1432 dt_strtab_destroy(strtab); 1433 goto err; 1434 } 1435 1436 s = (char *)data_str->d_buf + fsym.st_name; 1437 1438 /* 1439 * If this symbol isn't of type function, we've really 1440 * driven off the rails or the object file is corrupt. 1441 */ 1442 if (GELF_ST_TYPE(fsym.st_info) != STT_FUNC) { 1443 dt_strtab_destroy(strtab); 1444 return (dt_link_error(dtp, elf, fd, bufs, 1445 "expected %s to be of type function", s)); 1446 } 1447 1448 len = snprintf(NULL, 0, dt_symfmt, dt_symprefix, 1449 objkey, s) + 1; 1450 if ((p = dt_alloc(dtp, len)) == NULL) { 1451 dt_strtab_destroy(strtab); 1452 goto err; 1453 } 1454 (void) snprintf(p, len, dt_symfmt, dt_symprefix, 1455 objkey, s); 1456 1457 if (dt_strtab_index(strtab, p) == -1) { 1458 nsym++; 1459 (void) dt_strtab_insert(strtab, p); 1460 } 1461 1462 dt_free(dtp, p); 1463 } 1464 1465 /* 1466 * If needed, allocate the additional space for the symbol 1467 * table and string table copying the old data into the new 1468 * buffers, and marking the buffers as dirty. We inject those 1469 * newly allocated buffers into the libelf data structures, but 1470 * are still responsible for freeing them once we're done with 1471 * the elf handle. 1472 */ 1473 if (nsym > 0) { 1474 /* 1475 * The first byte of the string table is reserved for 1476 * the \0 entry. 1477 */ 1478 len = dt_strtab_size(strtab) - 1; 1479 1480 assert(len > 0); 1481 assert(dt_strtab_index(strtab, "") == 0); 1482 1483 dt_strtab_destroy(strtab); 1484 1485 if ((pair = dt_alloc(dtp, sizeof (*pair))) == NULL) 1486 goto err; 1487 1488 if ((pair->dlp_str = dt_alloc(dtp, data_str->d_size + 1489 len)) == NULL) { 1490 dt_free(dtp, pair); 1491 goto err; 1492 } 1493 1494 if ((pair->dlp_sym = dt_alloc(dtp, data_sym->d_size + 1495 nsym * symsize)) == NULL) { 1496 dt_free(dtp, pair->dlp_str); 1497 dt_free(dtp, pair); 1498 goto err; 1499 } 1500 1501 pair->dlp_next = bufs; 1502 bufs = pair; 1503 1504 bcopy(data_str->d_buf, pair->dlp_str, data_str->d_size); 1505 data_str->d_buf = pair->dlp_str; 1506 data_str->d_size += len; 1507 (void) elf_flagdata(data_str, ELF_C_SET, ELF_F_DIRTY); 1508 1509 shdr_str.sh_size += len; 1510 (void) gelf_update_shdr(scn_str, &shdr_str); 1511 1512 bcopy(data_sym->d_buf, pair->dlp_sym, data_sym->d_size); 1513 data_sym->d_buf = pair->dlp_sym; 1514 data_sym->d_size += nsym * symsize; 1515 (void) elf_flagdata(data_sym, ELF_C_SET, ELF_F_DIRTY); 1516 1517 shdr_sym.sh_size += nsym * symsize; 1518 (void) gelf_update_shdr(scn_sym, &shdr_sym); 1519 1520 nsym += isym; 1521 } else { 1522 dt_strtab_destroy(strtab); 1523 } 1524 1525 /* 1526 * Now that the tables have been allocated, perform the 1527 * modifications described above. 1528 */ 1529 for (i = 0; i < shdr_rel.sh_size / shdr_rel.sh_entsize; i++) { 1530 1531 if (shdr_rel.sh_type == SHT_RELA) { 1532 if (gelf_getrela(data_rel, i, &rela) == NULL) 1533 continue; 1534 } else { 1535 GElf_Rel rel; 1536 if (gelf_getrel(data_rel, i, &rel) == NULL) 1537 continue; 1538 rela.r_offset = rel.r_offset; 1539 rela.r_info = rel.r_info; 1540 rela.r_addend = 0; 1541 } 1542 1543 ndx = GELF_R_SYM(rela.r_info); 1544 1545 if (gelf_getsym(data_sym, ndx, &rsym) == NULL || 1546 rsym.st_name > data_str->d_size) 1547 goto err; 1548 1549 s = (char *)data_str->d_buf + rsym.st_name; 1550 1551 if (strncmp(s, dt_prefix, sizeof (dt_prefix) - 1) != 0) 1552 continue; 1553 1554 s += sizeof (dt_prefix) - 1; 1555 1556 /* 1557 * Check to see if this is an 'is-enabled' check as 1558 * opposed to a normal probe. 1559 */ 1560 if (strncmp(s, dt_enabled, 1561 sizeof (dt_enabled) - 1) == 0) { 1562 s += sizeof (dt_enabled) - 1; 1563 eprobe = 1; 1564 *eprobesp = 1; 1565 dt_dprintf("is-enabled probe\n"); 1566 } else { 1567 eprobe = 0; 1568 dt_dprintf("normal probe\n"); 1569 } 1570 1571 if (*s++ != '_') 1572 goto err; 1573 1574 if ((p = strstr(s, "___")) == NULL || 1575 p - s >= sizeof (pname)) 1576 goto err; 1577 1578 bcopy(s, pname, p - s); 1579 pname[p - s] = '\0'; 1580 1581 p = strhyphenate(p + 3); /* strlen("___") */ 1582 1583 if (dt_symtab_lookup(data_sym, isym, rela.r_offset, 1584 shdr_rel.sh_info, &fsym, 1585 (emachine1 == EM_PPC64), elf) != 0) 1586 goto err; 1587 1588 if (fsym.st_name > data_str->d_size) 1589 goto err; 1590 1591 assert(GELF_ST_TYPE(fsym.st_info) == STT_FUNC); 1592 1593 /* 1594 * If a NULL relocation name is passed to 1595 * dt_probe_define(), the function name is used for the 1596 * relocation. The relocation needs to use a mangled 1597 * name if the symbol is locally scoped; the function 1598 * name may need to change if we've found the global 1599 * alias for the locally scoped symbol (we prefer 1600 * global symbols to locals in dt_symtab_lookup()). 1601 */ 1602 s = (char *)data_str->d_buf + fsym.st_name; 1603 r = NULL; 1604 1605 if (GELF_ST_BIND(fsym.st_info) == STB_LOCAL) { 1606 dsym = fsym; 1607 dsym.st_name = istr; 1608 dsym.st_info = GELF_ST_INFO(STB_GLOBAL, 1609 STT_FUNC); 1610 dsym.st_other = 1611 ELF64_ST_VISIBILITY(STV_ELIMINATE); 1612 (void) gelf_update_sym(data_sym, isym, &dsym); 1613 1614 r = (char *)data_str->d_buf + istr; 1615 istr += 1 + sprintf(r, dt_symfmt, 1616 dt_symprefix, objkey, s); 1617 isym++; 1618 assert(isym <= nsym); 1619 1620 } else if (strncmp(s, dt_symprefix, 1621 strlen(dt_symprefix)) == 0) { 1622 r = s; 1623 if ((s = strchr(s, '.')) == NULL) 1624 goto err; 1625 s++; 1626 } 1627 1628 if ((pvp = dt_provider_lookup(dtp, pname)) == NULL) { 1629 return (dt_link_error(dtp, elf, fd, bufs, 1630 "no such provider %s", pname)); 1631 } 1632 1633 if ((prp = dt_probe_lookup(pvp, p)) == NULL) { 1634 return (dt_link_error(dtp, elf, fd, bufs, 1635 "no such probe %s", p)); 1636 } 1637 1638 assert(fsym.st_value <= rela.r_offset); 1639 1640 off = rela.r_offset - fsym.st_value; 1641 if (dt_modtext(dtp, data_tgt->d_buf, eprobe, 1642 &rela, &off) != 0) 1643 goto err; 1644 1645 if (dt_probe_define(pvp, prp, s, r, off, eprobe) != 0) { 1646 return (dt_link_error(dtp, elf, fd, bufs, 1647 "failed to allocate space for probe")); 1648 } 1649 #ifndef illumos 1650 /* 1651 * Our linker doesn't understand the SUNW_IGNORE ndx and 1652 * will try to use this relocation when we build the 1653 * final executable. Since we are done processing this 1654 * relocation, mark it as inexistant and let libelf 1655 * remove it from the file. 1656 * If this wasn't done, we would have garbage added to 1657 * the executable file as the symbol is going to be 1658 * change from UND to ABS. 1659 */ 1660 if (shdr_rel.sh_type == SHT_RELA) { 1661 rela.r_offset = 0; 1662 rela.r_info = 0; 1663 rela.r_addend = 0; 1664 (void) gelf_update_rela(data_rel, i, &rela); 1665 } else { 1666 GElf_Rel rel; 1667 rel.r_offset = 0; 1668 rel.r_info = 0; 1669 (void) gelf_update_rel(data_rel, i, &rel); 1670 } 1671 #endif 1672 1673 mod = 1; 1674 (void) elf_flagdata(data_tgt, ELF_C_SET, ELF_F_DIRTY); 1675 1676 /* 1677 * This symbol may already have been marked to 1678 * be ignored by another relocation referencing 1679 * the same symbol or if this object file has 1680 * already been processed by an earlier link 1681 * invocation. 1682 */ 1683 #ifndef illumos 1684 #define SHN_SUNW_IGNORE SHN_ABS 1685 #endif 1686 if (rsym.st_shndx != SHN_SUNW_IGNORE) { 1687 rsym.st_shndx = SHN_SUNW_IGNORE; 1688 (void) gelf_update_sym(data_sym, ndx, &rsym); 1689 } 1690 } 1691 } 1692 1693 if (mod && elf_update(elf, ELF_C_WRITE) == -1) 1694 goto err; 1695 1696 (void) elf_end(elf); 1697 (void) close(fd); 1698 1699 #ifndef illumos 1700 if (nsym > 0) 1701 #endif 1702 while ((pair = bufs) != NULL) { 1703 bufs = pair->dlp_next; 1704 dt_free(dtp, pair->dlp_str); 1705 dt_free(dtp, pair->dlp_sym); 1706 dt_free(dtp, pair); 1707 } 1708 1709 return (0); 1710 1711 err: 1712 return (dt_link_error(dtp, elf, fd, bufs, 1713 "an error was encountered while processing %s", obj)); 1714 } 1715 1716 int 1717 dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, 1718 const char *file, int objc, char *const objv[]) 1719 { 1720 #ifndef illumos 1721 char tfile[PATH_MAX]; 1722 #endif 1723 char drti[PATH_MAX]; 1724 dof_hdr_t *dof; 1725 int fd, status, i, cur; 1726 char *cmd, tmp; 1727 size_t len; 1728 int eprobes = 0, ret = 0; 1729 1730 #ifndef illumos 1731 if (access(file, R_OK) == 0) { 1732 fprintf(stderr, "dtrace: target object (%s) already exists. " 1733 "Please remove the target\ndtrace: object and rebuild all " 1734 "the source objects if you wish to run the DTrace\n" 1735 "dtrace: linking process again\n", file); 1736 /* 1737 * Several build infrastructures run DTrace twice (e.g. 1738 * postgres) and we don't want the build to fail. Return 1739 * 0 here since this isn't really a fatal error. 1740 */ 1741 return (0); 1742 } 1743 #endif 1744 1745 /* 1746 * A NULL program indicates a special use in which we just link 1747 * together a bunch of object files specified in objv and then 1748 * unlink(2) those object files. 1749 */ 1750 if (pgp == NULL) { 1751 const char *fmt = "%s -o %s -r"; 1752 1753 len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file) + 1; 1754 1755 for (i = 0; i < objc; i++) 1756 len += strlen(objv[i]) + 1; 1757 1758 cmd = alloca(len); 1759 1760 cur = snprintf(cmd, len, fmt, dtp->dt_ld_path, file); 1761 1762 for (i = 0; i < objc; i++) 1763 cur += snprintf(cmd + cur, len - cur, " %s", objv[i]); 1764 1765 if ((status = system(cmd)) == -1) { 1766 return (dt_link_error(dtp, NULL, -1, NULL, 1767 "failed to run %s: %s", dtp->dt_ld_path, 1768 strerror(errno))); 1769 } 1770 1771 if (WIFSIGNALED(status)) { 1772 return (dt_link_error(dtp, NULL, -1, NULL, 1773 "failed to link %s: %s failed due to signal %d", 1774 file, dtp->dt_ld_path, WTERMSIG(status))); 1775 } 1776 1777 if (WEXITSTATUS(status) != 0) { 1778 return (dt_link_error(dtp, NULL, -1, NULL, 1779 "failed to link %s: %s exited with status %d\n", 1780 file, dtp->dt_ld_path, WEXITSTATUS(status))); 1781 } 1782 1783 for (i = 0; i < objc; i++) { 1784 if (strcmp(objv[i], file) != 0) 1785 (void) unlink(objv[i]); 1786 } 1787 1788 return (0); 1789 } 1790 1791 for (i = 0; i < objc; i++) { 1792 if (process_obj(dtp, objv[i], &eprobes) != 0) 1793 return (-1); /* errno is set for us */ 1794 } 1795 1796 /* 1797 * If there are is-enabled probes then we need to force use of DOF 1798 * version 2. 1799 */ 1800 if (eprobes && pgp->dp_dofversion < DOF_VERSION_2) 1801 pgp->dp_dofversion = DOF_VERSION_2; 1802 1803 if ((dof = dtrace_dof_create(dtp, pgp, dflags)) == NULL) 1804 return (-1); /* errno is set for us */ 1805 1806 #ifdef illumos 1807 /* 1808 * Create a temporary file and then unlink it if we're going to 1809 * combine it with drti.o later. We can still refer to it in child 1810 * processes as /dev/fd/<fd>. 1811 */ 1812 if ((fd = open64(file, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) { 1813 return (dt_link_error(dtp, NULL, -1, NULL, 1814 "failed to open %s: %s", file, strerror(errno))); 1815 } 1816 #else 1817 snprintf(tfile, sizeof(tfile), "%s.XXXXXX", file); 1818 if ((fd = mkostemp(tfile, O_CLOEXEC)) == -1) 1819 return (dt_link_error(dtp, NULL, -1, NULL, 1820 "failed to create temporary file %s: %s", 1821 tfile, strerror(errno))); 1822 #endif 1823 1824 /* 1825 * If -xlinktype=DOF has been selected, just write out the DOF. 1826 * Otherwise proceed to the default of generating and linking ELF. 1827 */ 1828 switch (dtp->dt_linktype) { 1829 case DT_LTYP_DOF: 1830 if (dt_write(dtp, fd, dof, dof->dofh_filesz) < dof->dofh_filesz) 1831 ret = errno; 1832 1833 if (close(fd) != 0 && ret == 0) 1834 ret = errno; 1835 1836 if (ret != 0) { 1837 return (dt_link_error(dtp, NULL, -1, NULL, 1838 "failed to write %s: %s", file, strerror(ret))); 1839 } 1840 1841 return (0); 1842 1843 case DT_LTYP_ELF: 1844 break; /* fall through to the rest of dtrace_program_link() */ 1845 1846 default: 1847 return (dt_link_error(dtp, NULL, -1, NULL, 1848 "invalid link type %u\n", dtp->dt_linktype)); 1849 } 1850 1851 1852 #ifdef illumos 1853 if (!dtp->dt_lazyload) 1854 (void) unlink(file); 1855 #endif 1856 1857 if (dtp->dt_oflags & DTRACE_O_LP64) 1858 status = dump_elf64(dtp, dof, fd); 1859 else 1860 status = dump_elf32(dtp, dof, fd); 1861 1862 #ifdef illumos 1863 if (status != 0 || lseek(fd, 0, SEEK_SET) != 0) { 1864 return (dt_link_error(dtp, NULL, -1, NULL, 1865 "failed to write %s: %s", file, strerror(errno))); 1866 } 1867 #else 1868 if (status != 0) 1869 return (dt_link_error(dtp, NULL, -1, NULL, 1870 "failed to write %s: %s", tfile, 1871 strerror(dtrace_errno(dtp)))); 1872 #endif 1873 1874 if (!dtp->dt_lazyload) { 1875 #ifdef illumos 1876 const char *fmt = "%s -o %s -r -Blocal -Breduce /dev/fd/%d %s"; 1877 1878 if (dtp->dt_oflags & DTRACE_O_LP64) { 1879 (void) snprintf(drti, sizeof (drti), 1880 "%s/64/drti.o", _dtrace_libdir); 1881 } else { 1882 (void) snprintf(drti, sizeof (drti), 1883 "%s/drti.o", _dtrace_libdir); 1884 } 1885 1886 len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, fd, 1887 drti) + 1; 1888 1889 cmd = alloca(len); 1890 1891 (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, fd, drti); 1892 #else 1893 const char *fmt = "%s -o %s -r %s %s"; 1894 dt_dirpath_t *dp = dt_list_next(&dtp->dt_lib_path); 1895 1896 (void) snprintf(drti, sizeof (drti), "%s/drti.o", dp->dir_path); 1897 1898 len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, tfile, 1899 drti) + 1; 1900 1901 cmd = alloca(len); 1902 1903 (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, tfile, 1904 drti); 1905 #endif 1906 if ((status = system(cmd)) == -1) { 1907 ret = dt_link_error(dtp, NULL, fd, NULL, 1908 "failed to run %s: %s", dtp->dt_ld_path, 1909 strerror(errno)); 1910 goto done; 1911 } 1912 1913 if (WIFSIGNALED(status)) { 1914 ret = dt_link_error(dtp, NULL, fd, NULL, 1915 "failed to link %s: %s failed due to signal %d", 1916 file, dtp->dt_ld_path, WTERMSIG(status)); 1917 goto done; 1918 } 1919 1920 if (WEXITSTATUS(status) != 0) { 1921 ret = dt_link_error(dtp, NULL, fd, NULL, 1922 "failed to link %s: %s exited with status %d\n", 1923 file, dtp->dt_ld_path, WEXITSTATUS(status)); 1924 goto done; 1925 } 1926 (void) close(fd); /* release temporary file */ 1927 1928 #if defined(__FreeBSD__) || defined(__NetBSD__) 1929 /* 1930 * Now that we've linked drti.o, reduce the global __SUNW_dof 1931 * symbol to a local symbol. This is needed to so that multiple 1932 * generated object files (for different providers, for 1933 * instance) can be linked together. This is accomplished using 1934 * the -Blocal flag with Sun's linker, but GNU ld doesn't appear 1935 * to have an equivalent option. 1936 */ 1937 asprintf(&cmd, "%s --localize-hidden %s", dtp->dt_objcopy_path, 1938 file); 1939 if ((status = system(cmd)) == -1) { 1940 ret = dt_link_error(dtp, NULL, -1, NULL, 1941 "failed to run %s: %s", dtp->dt_objcopy_path, 1942 strerror(errno)); 1943 free(cmd); 1944 goto done; 1945 } 1946 free(cmd); 1947 1948 if (WIFSIGNALED(status)) { 1949 ret = dt_link_error(dtp, NULL, -1, NULL, 1950 "failed to link %s: %s failed due to signal %d", 1951 file, dtp->dt_objcopy_path, WTERMSIG(status)); 1952 goto done; 1953 } 1954 1955 if (WEXITSTATUS(status) != 0) { 1956 ret = dt_link_error(dtp, NULL, -1, NULL, 1957 "failed to link %s: %s exited with status %d\n", 1958 file, dtp->dt_objcopy_path, WEXITSTATUS(status)); 1959 goto done; 1960 } 1961 #endif 1962 } else { 1963 #if defined(__FreeBSD__) || defined(__NetBSD__) 1964 if (rename(tfile, file) != 0) { 1965 ret = dt_link_error(dtp, NULL, fd, NULL, 1966 "failed to rename %s to %s: %s", tfile, file, 1967 strerror(errno)); 1968 goto done; 1969 } 1970 #endif 1971 (void) close(fd); 1972 } 1973 1974 done: 1975 dtrace_dof_destroy(dtp, dof); 1976 1977 #if defined(__FreeBSD__) || defined(__NetBSD__) 1978 if (!dtp->dt_lazyload) 1979 (void) unlink(tfile); 1980 #endif 1981 return (ret); 1982 } 1983