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