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