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