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