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