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