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