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