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