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