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