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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2006 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 #include <sys/sysmacros.h> 34 35 #include <unistd.h> 36 #include <strings.h> 37 #include <alloca.h> 38 #include <limits.h> 39 #include <stddef.h> 40 #include <stdlib.h> 41 #include <stdio.h> 42 #include <fcntl.h> 43 #include <errno.h> 44 #include <wait.h> 45 #include <assert.h> 46 #include <sys/ipc.h> 47 48 #include <dt_impl.h> 49 #include <dt_provider.h> 50 #include <dt_string.h> 51 52 #define ESHDR_NULL 0 53 #define ESHDR_SHSTRTAB 1 54 #define ESHDR_DOF 2 55 #define ESHDR_STRTAB 3 56 #define ESHDR_SYMTAB 4 57 #define ESHDR_REL 5 58 #define ESHDR_NUM 6 59 60 #define PWRITE_SCN(index, data) \ 61 (lseek64(fd, (off64_t)elf_file.shdr[(index)].sh_offset, SEEK_SET) != \ 62 (off64_t)elf_file.shdr[(index)].sh_offset || \ 63 dt_write(dtp, fd, (data), elf_file.shdr[(index)].sh_size) != \ 64 elf_file.shdr[(index)].sh_size) 65 66 static const char DTRACE_SHSTRTAB32[] = "\0" 67 ".shstrtab\0" /* 1 */ 68 ".SUNW_dof\0" /* 11 */ 69 ".strtab\0" /* 21 */ 70 ".symtab\0" /* 29 */ 71 #ifdef __sparc 72 ".rela.SUNW_dof"; /* 37 */ 73 #else 74 ".rel.SUNW_dof"; /* 37 */ 75 #endif 76 77 static const char DTRACE_SHSTRTAB64[] = "\0" 78 ".shstrtab\0" /* 1 */ 79 ".SUNW_dof\0" /* 11 */ 80 ".strtab\0" /* 21 */ 81 ".symtab\0" /* 29 */ 82 ".rela.SUNW_dof"; /* 37 */ 83 84 static const char DOFSTR[] = "__SUNW_dof"; 85 static const char DOFLAZYSTR[] = "___SUNW_dof"; 86 87 typedef struct dt_link_pair { 88 struct dt_link_pair *dlp_next; /* next pair in linked list */ 89 void *dlp_str; /* buffer for string table */ 90 void *dlp_sym; /* buffer for symbol table */ 91 } dt_link_pair_t; 92 93 typedef struct dof_elf32 { 94 uint32_t de_nrel; /* relocation count */ 95 #ifdef __sparc 96 Elf32_Rela *de_rel; /* array of relocations for sparc */ 97 #else 98 Elf32_Rel *de_rel; /* array of relocations for x86 */ 99 #endif 100 uint32_t de_nsym; /* symbol count */ 101 Elf32_Sym *de_sym; /* array of symbols */ 102 uint32_t de_strlen; /* size of of string table */ 103 char *de_strtab; /* string table */ 104 uint32_t de_global; /* index of the first global symbol */ 105 } dof_elf32_t; 106 107 static int 108 prepare_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf32_t *dep) 109 { 110 dof_sec_t *dofs, *s; 111 dof_relohdr_t *dofrh; 112 dof_relodesc_t *dofr; 113 char *strtab; 114 int i, j, nrel; 115 size_t strtabsz = 1; 116 uint32_t count = 0; 117 size_t base; 118 Elf32_Sym *sym; 119 #ifdef __sparc 120 Elf32_Rela *rel; 121 #else 122 Elf32_Rel *rel; 123 #endif 124 125 /*LINTED*/ 126 dofs = (dof_sec_t *)((char *)dof + dof->dofh_secoff); 127 128 /* 129 * First compute the size of the string table and the number of 130 * relocations present in the DOF. 131 */ 132 for (i = 0; i < dof->dofh_secnum; i++) { 133 if (dofs[i].dofs_type != DOF_SECT_URELHDR) 134 continue; 135 136 /*LINTED*/ 137 dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset); 138 139 s = &dofs[dofrh->dofr_strtab]; 140 strtab = (char *)dof + s->dofs_offset; 141 assert(strtab[0] == '\0'); 142 strtabsz += s->dofs_size - 1; 143 144 s = &dofs[dofrh->dofr_relsec]; 145 /*LINTED*/ 146 dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); 147 count += s->dofs_size / s->dofs_entsize; 148 } 149 150 dep->de_strlen = strtabsz; 151 dep->de_nrel = count; 152 dep->de_nsym = count + 1; /* the first symbol is always null */ 153 154 if (dtp->dt_lazyload) { 155 dep->de_strlen += sizeof (DOFLAZYSTR); 156 dep->de_nsym++; 157 } else { 158 dep->de_strlen += sizeof (DOFSTR); 159 dep->de_nsym++; 160 } 161 162 if ((dep->de_rel = calloc(dep->de_nrel, 163 sizeof (dep->de_rel[0]))) == NULL) { 164 return (dt_set_errno(dtp, EDT_NOMEM)); 165 } 166 167 if ((dep->de_sym = calloc(dep->de_nsym, sizeof (Elf32_Sym))) == NULL) { 168 free(dep->de_rel); 169 return (dt_set_errno(dtp, EDT_NOMEM)); 170 } 171 172 if ((dep->de_strtab = calloc(dep->de_strlen, 1)) == NULL) { 173 free(dep->de_rel); 174 free(dep->de_sym); 175 return (dt_set_errno(dtp, EDT_NOMEM)); 176 } 177 178 count = 0; 179 strtabsz = 1; 180 dep->de_strtab[0] = '\0'; 181 rel = dep->de_rel; 182 sym = dep->de_sym; 183 dep->de_global = 1; 184 185 /* 186 * The first symbol table entry must be zeroed and is always ignored. 187 */ 188 bzero(sym, sizeof (Elf32_Sym)); 189 sym++; 190 191 /* 192 * Take a second pass through the DOF sections filling in the 193 * memory we allocated. 194 */ 195 for (i = 0; i < dof->dofh_secnum; i++) { 196 if (dofs[i].dofs_type != DOF_SECT_URELHDR) 197 continue; 198 199 /*LINTED*/ 200 dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset); 201 202 s = &dofs[dofrh->dofr_strtab]; 203 strtab = (char *)dof + s->dofs_offset; 204 bcopy(strtab + 1, dep->de_strtab + strtabsz, s->dofs_size); 205 base = strtabsz; 206 strtabsz += s->dofs_size - 1; 207 208 s = &dofs[dofrh->dofr_relsec]; 209 /*LINTED*/ 210 dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); 211 nrel = s->dofs_size / s->dofs_entsize; 212 213 s = &dofs[dofrh->dofr_tgtsec]; 214 215 for (j = 0; j < nrel; j++) { 216 #if defined(__i386) || defined(__amd64) 217 rel->r_offset = s->dofs_offset + 218 dofr[j].dofr_offset; 219 rel->r_info = ELF32_R_INFO(count + dep->de_global, 220 R_386_32); 221 #elif defined(__sparc) 222 /* 223 * Add 4 bytes to hit the low half of this 64-bit 224 * big-endian address. 225 */ 226 rel->r_offset = s->dofs_offset + 227 dofr[j].dofr_offset + 4; 228 rel->r_info = ELF32_R_INFO(count + dep->de_global, 229 R_SPARC_32); 230 #else 231 #error unknown ISA 232 #endif 233 234 sym->st_name = base + dofr[j].dofr_name - 1; 235 sym->st_value = 0; 236 sym->st_size = 0; 237 sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_FUNC); 238 sym->st_other = 0; 239 sym->st_shndx = SHN_UNDEF; 240 241 rel++; 242 sym++; 243 count++; 244 } 245 } 246 247 /* 248 * Add a symbol for the DOF itself. We use a different symbol for 249 * lazily and actively loaded DOF to make them easy to distinguish. 250 */ 251 sym->st_name = strtabsz; 252 sym->st_value = 0; 253 sym->st_size = dof->dofh_filesz; 254 sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT); 255 sym->st_other = 0; 256 sym->st_shndx = ESHDR_DOF; 257 sym++; 258 259 if (dtp->dt_lazyload) { 260 bcopy(DOFLAZYSTR, dep->de_strtab + strtabsz, 261 sizeof (DOFLAZYSTR)); 262 strtabsz += sizeof (DOFLAZYSTR); 263 } else { 264 bcopy(DOFSTR, dep->de_strtab + strtabsz, sizeof (DOFSTR)); 265 strtabsz += sizeof (DOFSTR); 266 } 267 268 assert(count == dep->de_nrel); 269 assert(strtabsz == dep->de_strlen); 270 271 return (0); 272 } 273 274 275 typedef struct dof_elf64 { 276 uint32_t de_nrel; 277 Elf64_Rela *de_rel; 278 uint32_t de_nsym; 279 Elf64_Sym *de_sym; 280 281 uint32_t de_strlen; 282 char *de_strtab; 283 284 uint32_t de_global; 285 } dof_elf64_t; 286 287 static int 288 prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep) 289 { 290 dof_sec_t *dofs, *s; 291 dof_relohdr_t *dofrh; 292 dof_relodesc_t *dofr; 293 char *strtab; 294 int i, j, nrel; 295 size_t strtabsz = 1; 296 uint32_t count = 0; 297 size_t base; 298 Elf64_Sym *sym; 299 Elf64_Rela *rel; 300 301 /*LINTED*/ 302 dofs = (dof_sec_t *)((char *)dof + dof->dofh_secoff); 303 304 /* 305 * First compute the size of the string table and the number of 306 * relocations present in the DOF. 307 */ 308 for (i = 0; i < dof->dofh_secnum; i++) { 309 if (dofs[i].dofs_type != DOF_SECT_URELHDR) 310 continue; 311 312 /*LINTED*/ 313 dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset); 314 315 s = &dofs[dofrh->dofr_strtab]; 316 strtab = (char *)dof + s->dofs_offset; 317 assert(strtab[0] == '\0'); 318 strtabsz += s->dofs_size - 1; 319 320 s = &dofs[dofrh->dofr_relsec]; 321 /*LINTED*/ 322 dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); 323 count += s->dofs_size / s->dofs_entsize; 324 } 325 326 dep->de_strlen = strtabsz; 327 dep->de_nrel = count; 328 dep->de_nsym = count + 1; /* the first symbol is always null */ 329 330 if (dtp->dt_lazyload) { 331 dep->de_strlen += sizeof (DOFLAZYSTR); 332 dep->de_nsym++; 333 } else { 334 dep->de_strlen += sizeof (DOFSTR); 335 dep->de_nsym++; 336 } 337 338 if ((dep->de_rel = calloc(dep->de_nrel, 339 sizeof (dep->de_rel[0]))) == NULL) { 340 return (dt_set_errno(dtp, EDT_NOMEM)); 341 } 342 343 if ((dep->de_sym = calloc(dep->de_nsym, sizeof (Elf64_Sym))) == NULL) { 344 free(dep->de_rel); 345 return (dt_set_errno(dtp, EDT_NOMEM)); 346 } 347 348 if ((dep->de_strtab = calloc(dep->de_strlen, 1)) == NULL) { 349 free(dep->de_rel); 350 free(dep->de_sym); 351 return (dt_set_errno(dtp, EDT_NOMEM)); 352 } 353 354 count = 0; 355 strtabsz = 1; 356 dep->de_strtab[0] = '\0'; 357 rel = dep->de_rel; 358 sym = dep->de_sym; 359 dep->de_global = 1; 360 361 /* 362 * The first symbol table entry must be zeroed and is always ignored. 363 */ 364 bzero(sym, sizeof (Elf64_Sym)); 365 sym++; 366 367 /* 368 * Take a second pass through the DOF sections filling in the 369 * memory we allocated. 370 */ 371 for (i = 0; i < dof->dofh_secnum; i++) { 372 if (dofs[i].dofs_type != DOF_SECT_URELHDR) 373 continue; 374 375 /*LINTED*/ 376 dofrh = (dof_relohdr_t *)((char *)dof + dofs[i].dofs_offset); 377 378 s = &dofs[dofrh->dofr_strtab]; 379 strtab = (char *)dof + s->dofs_offset; 380 bcopy(strtab + 1, dep->de_strtab + strtabsz, s->dofs_size); 381 base = strtabsz; 382 strtabsz += s->dofs_size - 1; 383 384 s = &dofs[dofrh->dofr_relsec]; 385 /*LINTED*/ 386 dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); 387 nrel = s->dofs_size / s->dofs_entsize; 388 389 s = &dofs[dofrh->dofr_tgtsec]; 390 391 for (j = 0; j < nrel; j++) { 392 #if defined(__i386) || defined(__amd64) 393 rel->r_offset = s->dofs_offset + 394 dofr[j].dofr_offset; 395 rel->r_info = ELF64_R_INFO(count + dep->de_global, 396 R_AMD64_64); 397 #elif defined(__sparc) 398 rel->r_offset = s->dofs_offset + 399 dofr[j].dofr_offset; 400 rel->r_info = ELF64_R_INFO(count + dep->de_global, 401 R_SPARC_64); 402 #else 403 #error unknown ISA 404 #endif 405 406 sym->st_name = base + dofr[j].dofr_name - 1; 407 sym->st_value = 0; 408 sym->st_size = 0; 409 sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_FUNC); 410 sym->st_other = 0; 411 sym->st_shndx = SHN_UNDEF; 412 413 rel++; 414 sym++; 415 count++; 416 } 417 } 418 419 /* 420 * Add a symbol for the DOF itself. We use a different symbol for 421 * lazily and actively loaded DOF to make them easy to distinguish. 422 */ 423 sym->st_name = strtabsz; 424 sym->st_value = 0; 425 sym->st_size = dof->dofh_filesz; 426 sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_OBJECT); 427 sym->st_other = 0; 428 sym->st_shndx = ESHDR_DOF; 429 sym++; 430 431 if (dtp->dt_lazyload) { 432 bcopy(DOFLAZYSTR, dep->de_strtab + strtabsz, 433 sizeof (DOFLAZYSTR)); 434 strtabsz += sizeof (DOFLAZYSTR); 435 } else { 436 bcopy(DOFSTR, dep->de_strtab + strtabsz, sizeof (DOFSTR)); 437 strtabsz += sizeof (DOFSTR); 438 } 439 440 assert(count == dep->de_nrel); 441 assert(strtabsz == dep->de_strlen); 442 443 return (0); 444 } 445 446 /* 447 * Write out an ELF32 file prologue consisting of a header, section headers, 448 * and a section header string table. The DOF data will follow this prologue 449 * and complete the contents of the given ELF file. 450 */ 451 static int 452 dump_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd) 453 { 454 struct { 455 Elf32_Ehdr ehdr; 456 Elf32_Shdr shdr[ESHDR_NUM]; 457 } elf_file; 458 459 Elf32_Shdr *shp; 460 Elf32_Off off; 461 dof_elf32_t de; 462 int ret = 0; 463 uint_t nshdr; 464 465 if (prepare_elf32(dtp, dof, &de) != 0) 466 return (-1); /* errno is set for us */ 467 468 /* 469 * If there are no relocations, we only need enough sections for 470 * the shstrtab and the DOF. 471 */ 472 nshdr = de.de_nrel == 0 ? ESHDR_SYMTAB + 1 : ESHDR_NUM; 473 474 bzero(&elf_file, sizeof (elf_file)); 475 476 elf_file.ehdr.e_ident[EI_MAG0] = ELFMAG0; 477 elf_file.ehdr.e_ident[EI_MAG1] = ELFMAG1; 478 elf_file.ehdr.e_ident[EI_MAG2] = ELFMAG2; 479 elf_file.ehdr.e_ident[EI_MAG3] = ELFMAG3; 480 elf_file.ehdr.e_ident[EI_VERSION] = EV_CURRENT; 481 elf_file.ehdr.e_ident[EI_CLASS] = ELFCLASS32; 482 #if defined(_BIG_ENDIAN) 483 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2MSB; 484 #elif defined(_LITTLE_ENDIAN) 485 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2LSB; 486 #endif 487 elf_file.ehdr.e_type = ET_REL; 488 #if defined(__sparc) 489 elf_file.ehdr.e_machine = EM_SPARC; 490 #elif defined(__i386) || defined(__amd64) 491 elf_file.ehdr.e_machine = EM_386; 492 #endif 493 elf_file.ehdr.e_version = EV_CURRENT; 494 elf_file.ehdr.e_shoff = sizeof (Elf32_Ehdr); 495 elf_file.ehdr.e_ehsize = sizeof (Elf32_Ehdr); 496 elf_file.ehdr.e_phentsize = sizeof (Elf32_Phdr); 497 elf_file.ehdr.e_shentsize = sizeof (Elf32_Shdr); 498 elf_file.ehdr.e_shnum = nshdr; 499 elf_file.ehdr.e_shstrndx = ESHDR_SHSTRTAB; 500 off = sizeof (elf_file) + nshdr * sizeof (Elf32_Shdr); 501 502 shp = &elf_file.shdr[ESHDR_SHSTRTAB]; 503 shp->sh_name = 1; /* DTRACE_SHSTRTAB32[1] = ".shstrtab" */ 504 shp->sh_type = SHT_STRTAB; 505 shp->sh_offset = off; 506 shp->sh_size = sizeof (DTRACE_SHSTRTAB32); 507 shp->sh_addralign = sizeof (char); 508 off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8); 509 510 shp = &elf_file.shdr[ESHDR_DOF]; 511 shp->sh_name = 11; /* DTRACE_SHSTRTAB32[11] = ".SUNW_dof" */ 512 shp->sh_flags = SHF_ALLOC; 513 shp->sh_type = SHT_SUNW_dof; 514 shp->sh_offset = off; 515 shp->sh_size = dof->dofh_filesz; 516 shp->sh_addralign = 8; 517 off = shp->sh_offset + shp->sh_size; 518 519 shp = &elf_file.shdr[ESHDR_STRTAB]; 520 shp->sh_name = 21; /* DTRACE_SHSTRTAB32[21] = ".strtab" */ 521 shp->sh_flags = SHF_ALLOC; 522 shp->sh_type = SHT_STRTAB; 523 shp->sh_offset = off; 524 shp->sh_size = de.de_strlen; 525 shp->sh_addralign = sizeof (char); 526 off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 4); 527 528 shp = &elf_file.shdr[ESHDR_SYMTAB]; 529 shp->sh_name = 29; /* DTRACE_SHSTRTAB32[29] = ".symtab" */ 530 shp->sh_flags = SHF_ALLOC; 531 shp->sh_type = SHT_SYMTAB; 532 shp->sh_entsize = sizeof (Elf32_Sym); 533 shp->sh_link = ESHDR_STRTAB; 534 shp->sh_offset = off; 535 shp->sh_info = de.de_global; 536 shp->sh_size = de.de_nsym * sizeof (Elf32_Sym); 537 shp->sh_addralign = 4; 538 off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 4); 539 540 if (de.de_nrel == 0) { 541 if (dt_write(dtp, fd, &elf_file, 542 sizeof (elf_file)) != sizeof (elf_file) || 543 PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB32) || 544 PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) || 545 PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) || 546 PWRITE_SCN(ESHDR_DOF, dof)) { 547 ret = dt_set_errno(dtp, errno); 548 } 549 } else { 550 shp = &elf_file.shdr[ESHDR_REL]; 551 shp->sh_name = 37; /* DTRACE_SHSTRTAB32[37] = ".rel.SUNW_dof" */ 552 shp->sh_flags = SHF_ALLOC; 553 #ifdef __sparc 554 shp->sh_type = SHT_RELA; 555 #else 556 shp->sh_type = SHT_REL; 557 #endif 558 shp->sh_entsize = sizeof (de.de_rel[0]); 559 shp->sh_link = ESHDR_SYMTAB; 560 shp->sh_info = ESHDR_DOF; 561 shp->sh_offset = off; 562 shp->sh_size = de.de_nrel * sizeof (de.de_rel[0]); 563 shp->sh_addralign = 4; 564 565 if (dt_write(dtp, fd, &elf_file, 566 sizeof (elf_file)) != sizeof (elf_file) || 567 PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB32) || 568 PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) || 569 PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) || 570 PWRITE_SCN(ESHDR_REL, de.de_rel) || 571 PWRITE_SCN(ESHDR_DOF, dof)) { 572 ret = dt_set_errno(dtp, errno); 573 } 574 } 575 576 free(de.de_strtab); 577 free(de.de_sym); 578 free(de.de_rel); 579 580 return (ret); 581 } 582 583 /* 584 * Write out an ELF64 file prologue consisting of a header, section headers, 585 * and a section header string table. The DOF data will follow this prologue 586 * and complete the contents of the given ELF file. 587 */ 588 static int 589 dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd) 590 { 591 struct { 592 Elf64_Ehdr ehdr; 593 Elf64_Shdr shdr[ESHDR_NUM]; 594 } elf_file; 595 596 Elf64_Shdr *shp; 597 Elf64_Off off; 598 dof_elf64_t de; 599 int ret = 0; 600 uint_t nshdr; 601 602 if (prepare_elf64(dtp, dof, &de) != 0) 603 return (-1); /* errno is set for us */ 604 605 /* 606 * If there are no relocations, we only need enough sections for 607 * the shstrtab and the DOF. 608 */ 609 nshdr = de.de_nrel == 0 ? ESHDR_SYMTAB + 1 : ESHDR_NUM; 610 611 bzero(&elf_file, sizeof (elf_file)); 612 613 elf_file.ehdr.e_ident[EI_MAG0] = ELFMAG0; 614 elf_file.ehdr.e_ident[EI_MAG1] = ELFMAG1; 615 elf_file.ehdr.e_ident[EI_MAG2] = ELFMAG2; 616 elf_file.ehdr.e_ident[EI_MAG3] = ELFMAG3; 617 elf_file.ehdr.e_ident[EI_VERSION] = EV_CURRENT; 618 elf_file.ehdr.e_ident[EI_CLASS] = ELFCLASS64; 619 #if defined(_BIG_ENDIAN) 620 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2MSB; 621 #elif defined(_LITTLE_ENDIAN) 622 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2LSB; 623 #endif 624 elf_file.ehdr.e_type = ET_REL; 625 #if defined(__sparc) 626 elf_file.ehdr.e_machine = EM_SPARCV9; 627 #elif defined(__i386) || defined(__amd64) 628 elf_file.ehdr.e_machine = EM_AMD64; 629 #endif 630 elf_file.ehdr.e_version = EV_CURRENT; 631 elf_file.ehdr.e_shoff = sizeof (Elf64_Ehdr); 632 elf_file.ehdr.e_ehsize = sizeof (Elf64_Ehdr); 633 elf_file.ehdr.e_phentsize = sizeof (Elf64_Phdr); 634 elf_file.ehdr.e_shentsize = sizeof (Elf64_Shdr); 635 elf_file.ehdr.e_shnum = nshdr; 636 elf_file.ehdr.e_shstrndx = ESHDR_SHSTRTAB; 637 off = sizeof (elf_file) + nshdr * sizeof (Elf64_Shdr); 638 639 shp = &elf_file.shdr[ESHDR_SHSTRTAB]; 640 shp->sh_name = 1; /* DTRACE_SHSTRTAB64[1] = ".shstrtab" */ 641 shp->sh_type = SHT_STRTAB; 642 shp->sh_offset = off; 643 shp->sh_size = sizeof (DTRACE_SHSTRTAB64); 644 shp->sh_addralign = sizeof (char); 645 off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8); 646 647 shp = &elf_file.shdr[ESHDR_DOF]; 648 shp->sh_name = 11; /* DTRACE_SHSTRTAB64[11] = ".SUNW_dof" */ 649 shp->sh_flags = SHF_ALLOC; 650 shp->sh_type = SHT_SUNW_dof; 651 shp->sh_offset = off; 652 shp->sh_size = dof->dofh_filesz; 653 shp->sh_addralign = 8; 654 off = shp->sh_offset + shp->sh_size; 655 656 shp = &elf_file.shdr[ESHDR_STRTAB]; 657 shp->sh_name = 21; /* DTRACE_SHSTRTAB64[21] = ".strtab" */ 658 shp->sh_flags = SHF_ALLOC; 659 shp->sh_type = SHT_STRTAB; 660 shp->sh_offset = off; 661 shp->sh_size = de.de_strlen; 662 shp->sh_addralign = sizeof (char); 663 off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8); 664 665 shp = &elf_file.shdr[ESHDR_SYMTAB]; 666 shp->sh_name = 29; /* DTRACE_SHSTRTAB64[29] = ".symtab" */ 667 shp->sh_flags = SHF_ALLOC; 668 shp->sh_type = SHT_SYMTAB; 669 shp->sh_entsize = sizeof (Elf64_Sym); 670 shp->sh_link = ESHDR_STRTAB; 671 shp->sh_offset = off; 672 shp->sh_info = de.de_global; 673 shp->sh_size = de.de_nsym * sizeof (Elf64_Sym); 674 shp->sh_addralign = 8; 675 off = P2ROUNDUP(shp->sh_offset + shp->sh_size, 8); 676 677 if (de.de_nrel == 0) { 678 if (dt_write(dtp, fd, &elf_file, 679 sizeof (elf_file)) != sizeof (elf_file) || 680 PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB64) || 681 PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) || 682 PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) || 683 PWRITE_SCN(ESHDR_DOF, dof)) { 684 ret = dt_set_errno(dtp, errno); 685 } 686 } else { 687 shp = &elf_file.shdr[ESHDR_REL]; 688 shp->sh_name = 37; /* DTRACE_SHSTRTAB64[37] = ".rel.SUNW_dof" */ 689 shp->sh_flags = SHF_ALLOC; 690 shp->sh_type = SHT_RELA; 691 shp->sh_entsize = sizeof (de.de_rel[0]); 692 shp->sh_link = ESHDR_SYMTAB; 693 shp->sh_info = ESHDR_DOF; 694 shp->sh_offset = off; 695 shp->sh_size = de.de_nrel * sizeof (de.de_rel[0]); 696 shp->sh_addralign = 8; 697 698 if (dt_write(dtp, fd, &elf_file, 699 sizeof (elf_file)) != sizeof (elf_file) || 700 PWRITE_SCN(ESHDR_SHSTRTAB, DTRACE_SHSTRTAB64) || 701 PWRITE_SCN(ESHDR_STRTAB, de.de_strtab) || 702 PWRITE_SCN(ESHDR_SYMTAB, de.de_sym) || 703 PWRITE_SCN(ESHDR_REL, de.de_rel) || 704 PWRITE_SCN(ESHDR_DOF, dof)) { 705 ret = dt_set_errno(dtp, errno); 706 } 707 } 708 709 free(de.de_strtab); 710 free(de.de_sym); 711 free(de.de_rel); 712 713 return (ret); 714 } 715 716 static int 717 dt_symtab_lookup(Elf_Data *data_sym, uintptr_t addr, uint_t shn, GElf_Sym *sym) 718 { 719 int i, ret = -1; 720 GElf_Sym s; 721 722 for (i = 0; gelf_getsym(data_sym, i, sym) != NULL; i++) { 723 if (GELF_ST_TYPE(sym->st_info) == STT_FUNC && 724 shn == sym->st_shndx && 725 sym->st_value <= addr && 726 addr < sym->st_value + sym->st_size) { 727 if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL) 728 return (0); 729 730 ret = 0; 731 s = *sym; 732 } 733 } 734 735 if (ret == 0) 736 *sym = s; 737 return (ret); 738 } 739 740 #if defined(__sparc) 741 742 #define DT_OP_RET 0x81c7e008 743 #define DT_OP_NOP 0x01000000 744 #define DT_OP_CALL 0x40000000 745 746 #define DT_IS_MOV_O7(inst) (((inst) & 0xffffe000) == 0x9e100000) 747 #define DT_IS_RESTORE(inst) (((inst) & 0xc1f80000) == 0x81e80000) 748 #define DT_IS_RETL(inst) (((inst) & 0xfff83fff) == 0x81c02008) 749 750 #define DT_RS2(inst) ((inst) & 0x1f) 751 #define DT_MAKE_RETL(reg) (0x81c02008 | ((reg) << 14)) 752 753 static int 754 dt_modtext(char *p, GElf_Rela *rela, uint32_t *off) 755 { 756 uint32_t *ip; 757 758 if ((rela->r_offset & (sizeof (uint32_t) - 1)) != 0) 759 return (-1); 760 761 /*LINTED*/ 762 ip = (uint32_t *)(p + rela->r_offset); 763 764 /* 765 * We only know about some specific relocation types. 766 */ 767 if (GELF_R_TYPE(rela->r_info) != R_SPARC_WDISP30 && 768 GELF_R_TYPE(rela->r_info) != R_SPARC_WPLT30) 769 return (-1); 770 771 /* 772 * We may have already processed this object file in an earlier 773 * linker invocation in which case we'd expect to see a ret/restore 774 * pair, a retl-like/mov pair or a nop; return success in that case. 775 */ 776 if (DT_IS_RESTORE(ip[1])) { 777 if (ip[0] == DT_OP_RET) { 778 return (0); 779 } 780 } else if (DT_IS_MOV_O7(ip[1])) { 781 if (DT_IS_RETL(ip[0])) { 782 return (0); 783 } 784 } else { 785 if (ip[0] == DT_OP_NOP) { 786 (*off) += sizeof (ip[0]); 787 return (0); 788 } 789 } 790 791 /* 792 * We only expect call instructions with a displacement of 0. 793 */ 794 if (ip[0] != DT_OP_CALL) { 795 dt_dprintf("found %x instead of a call instruction at %llx\n", 796 ip[0], (u_longlong_t)rela->r_offset); 797 return (-1); 798 } 799 800 /* 801 * If the call is followed by a restore, it's a tail call so change 802 * the call to a ret. If the call if followed by a mov of a register 803 * into %o7, it's a tail call in leaf context so change the call to 804 * a retl-like instruction that returns to that register value + 8 805 * (rather than the typical %o7 + 8). Otherwise we adjust the offset 806 * to land on what was once the delay slot of the call so we 807 * correctly get all the arguments. 808 */ 809 if (DT_IS_RESTORE(ip[1])) { 810 ip[0] = DT_OP_RET; 811 } else if (DT_IS_MOV_O7(ip[1])) { 812 ip[0] = DT_MAKE_RETL(DT_RS2(ip[1])); 813 } else { 814 ip[0] = DT_OP_NOP; 815 (*off) += sizeof (ip[0]); 816 } 817 818 return (0); 819 } 820 821 #elif defined(__i386) || defined(__amd64) 822 823 #define DT_OP_NOP 0x90 824 #define DT_OP_CALL 0xe8 825 826 static int 827 dt_modtext(char *p, GElf_Rela *rela, uint32_t *off) 828 { 829 uint8_t *ip = (uint8_t *)(p + rela->r_offset - 1); 830 831 /* 832 * On x86, the first byte of the instruction is the call opcode and 833 * the next four bytes are the 32-bit address; the relocation is for 834 * the address so we back up one byte to land on the opcode. 835 */ 836 (*off) -= 1; 837 838 /* 839 * We only know about some specific relocation types. Luckily 840 * these types have the same values on both 32-bit and 64-bit 841 * x86 architectures. 842 */ 843 if (GELF_R_TYPE(rela->r_info) != R_386_PC32 && 844 GELF_R_TYPE(rela->r_info) != R_386_PLT32) 845 return (-1); 846 847 /* 848 * We may have already processed this object file in an earlier 849 * linker invocation in which case we'd expect to see a bunch 850 * of nops; return success in that case. 851 */ 852 if (ip[0] == DT_OP_NOP && ip[1] == DT_OP_NOP && ip[2] == DT_OP_NOP && 853 ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP) 854 return (0); 855 856 /* 857 * We only expect a call instrution with a 32-bit displacement. 858 */ 859 if (ip[0] != DT_OP_CALL) { 860 dt_dprintf("found %x instead of a call instruction at %llx\n", 861 ip[0], (u_longlong_t)rela->r_offset); 862 return (-1); 863 } 864 865 ip[0] = DT_OP_NOP; 866 ip[1] = DT_OP_NOP; 867 ip[2] = DT_OP_NOP; 868 ip[3] = DT_OP_NOP; 869 ip[4] = DT_OP_NOP; 870 871 return (0); 872 } 873 874 #else 875 #error unknown ISA 876 #endif 877 878 /*PRINTFLIKE5*/ 879 static int 880 dt_link_error(dtrace_hdl_t *dtp, Elf *elf, int fd, dt_link_pair_t *bufs, 881 const char *format, ...) 882 { 883 va_list ap; 884 dt_link_pair_t *pair; 885 886 va_start(ap, format); 887 dt_set_errmsg(dtp, NULL, NULL, NULL, 0, format, ap); 888 va_end(ap); 889 890 if (elf != NULL) 891 (void) elf_end(elf); 892 893 if (fd >= 0) 894 (void) close(fd); 895 896 while ((pair = bufs) != NULL) { 897 bufs = pair->dlp_next; 898 dt_free(dtp, pair->dlp_str); 899 dt_free(dtp, pair->dlp_sym); 900 dt_free(dtp, pair); 901 } 902 903 return (dt_set_errno(dtp, EDT_COMPILER)); 904 } 905 906 static int 907 process_obj(dtrace_hdl_t *dtp, const char *obj) 908 { 909 static const char dt_prefix[] = "__dtrace_"; 910 static const char dt_symprefix[] = "$dtrace"; 911 static const char dt_symfmt[] = "%s%d.%s"; 912 int fd, i, ndx, mod = 0; 913 Elf *elf = NULL; 914 GElf_Ehdr ehdr; 915 Elf_Scn *scn_rel, *scn_sym, *scn_str, *scn_tgt; 916 Elf_Data *data_rel, *data_sym, *data_str, *data_tgt; 917 GElf_Shdr shdr_rel, shdr_sym, shdr_str, shdr_tgt; 918 GElf_Sym rsym, fsym, dsym; 919 GElf_Rela rela; 920 char *s, *p, *r; 921 char pname[DTRACE_PROVNAMELEN]; 922 dt_provider_t *pvp; 923 dt_probe_t *prp; 924 uint32_t off, eclass, emachine1, emachine2; 925 size_t count_sym, count_str, symsize; 926 key_t objkey; 927 dt_link_pair_t *pair, *bufs = NULL; 928 929 if ((fd = open64(obj, O_RDWR)) == -1) { 930 return (dt_link_error(dtp, elf, fd, bufs, 931 "failed to open %s: %s", obj, strerror(errno))); 932 } 933 934 if ((elf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) { 935 return (dt_link_error(dtp, elf, fd, bufs, 936 "failed to process %s: %s", obj, elf_errmsg(elf_errno()))); 937 } 938 939 switch (elf_kind(elf)) { 940 case ELF_K_ELF: 941 break; 942 case ELF_K_AR: 943 return (dt_link_error(dtp, elf, fd, bufs, "archives are not " 944 "permitted; use the contents of the archive instead: %s", 945 obj)); 946 default: 947 return (dt_link_error(dtp, elf, fd, bufs, 948 "invalid file type: %s", obj)); 949 } 950 951 if (gelf_getehdr(elf, &ehdr) == NULL) { 952 return (dt_link_error(dtp, elf, fd, bufs, "corrupt file: %s", 953 obj)); 954 } 955 956 if (dtp->dt_oflags & DTRACE_O_LP64) { 957 eclass = ELFCLASS64; 958 #if defined(__sparc) 959 emachine1 = emachine2 = EM_SPARCV9; 960 #elif defined(__i386) || defined(__amd64) 961 emachine1 = emachine2 = EM_AMD64; 962 #endif 963 symsize = sizeof (Elf64_Sym); 964 } else { 965 eclass = ELFCLASS32; 966 #if defined(__sparc) 967 emachine1 = EM_SPARC; 968 emachine2 = EM_SPARC32PLUS; 969 #elif defined(__i386) || defined(__amd64) 970 emachine1 = emachine2 = EM_386; 971 #endif 972 symsize = sizeof (Elf32_Sym); 973 } 974 975 if (ehdr.e_ident[EI_CLASS] != eclass) { 976 return (dt_link_error(dtp, elf, fd, bufs, 977 "incorrect ELF class for object file: %s", obj)); 978 } 979 980 if (ehdr.e_machine != emachine1 && ehdr.e_machine != emachine2) { 981 return (dt_link_error(dtp, elf, fd, bufs, 982 "incorrect ELF machine type for object file: %s", obj)); 983 } 984 985 /* 986 * We use this token as a relatively unique handle for this file on the 987 * system in order to disambiguate potential conflicts between files of 988 * the same name which contain identially named local symbols. 989 */ 990 if ((objkey = ftok(obj, 0)) == (key_t)-1) { 991 return (dt_link_error(dtp, elf, fd, bufs, 992 "failed to generate unique key for object file: %s", obj)); 993 } 994 995 scn_rel = NULL; 996 while ((scn_rel = elf_nextscn(elf, scn_rel)) != NULL) { 997 if (gelf_getshdr(scn_rel, &shdr_rel) == NULL) 998 goto err; 999 1000 /* 1001 * Skip any non-relocation sections. 1002 */ 1003 if (shdr_rel.sh_type != SHT_RELA && shdr_rel.sh_type != SHT_REL) 1004 continue; 1005 1006 if ((data_rel = elf_getdata(scn_rel, NULL)) == NULL) 1007 goto err; 1008 1009 /* 1010 * Grab the section, section header and section data for the 1011 * symbol table that this relocation section references. 1012 */ 1013 if ((scn_sym = elf_getscn(elf, shdr_rel.sh_link)) == NULL || 1014 gelf_getshdr(scn_sym, &shdr_sym) == NULL || 1015 (data_sym = elf_getdata(scn_sym, NULL)) == NULL) 1016 goto err; 1017 1018 /* 1019 * Ditto for that symbol table's string table. 1020 */ 1021 if ((scn_str = elf_getscn(elf, shdr_sym.sh_link)) == NULL || 1022 gelf_getshdr(scn_str, &shdr_str) == NULL || 1023 (data_str = elf_getdata(scn_str, NULL)) == NULL) 1024 goto err; 1025 1026 /* 1027 * Grab the section, section header and section data for the 1028 * target section for the relocations. For the relocations 1029 * we're looking for -- this will typically be the text of the 1030 * object file. 1031 */ 1032 if ((scn_tgt = elf_getscn(elf, shdr_rel.sh_info)) == NULL || 1033 gelf_getshdr(scn_tgt, &shdr_tgt) == NULL || 1034 (data_tgt = elf_getdata(scn_tgt, NULL)) == NULL) 1035 goto err; 1036 1037 /* 1038 * We're looking for relocations to symbols matching this form: 1039 * 1040 * __dtrace_<prov>___<probe> 1041 * 1042 * For the generated object, we need to record the location 1043 * identified by the relocation, and create a new relocation 1044 * in the generated object that will be resolved at link time 1045 * to the location of the function in which the probe is 1046 * embedded. In the target object, we change the matched symbol 1047 * so that it will be ignored at link time, and we modify the 1048 * target (text) section to replace the call instruction with 1049 * one or more nops. 1050 * 1051 * If the function containing the probe is locally scoped 1052 * (static), we create an alias used by the relocation in the 1053 * generated object. The alias, a new symbol, will be global 1054 * (so that the relocation from the generated object can be 1055 * resolved), and hidden (so that it is converted to a local 1056 * symbol at link time). Such aliases have this form: 1057 * 1058 * $dtrace<key>.<function> 1059 * 1060 * We take a first pass through all the relocations to 1061 * calculate an upper bound on the number of symbols we may 1062 * need to add as well as the size of the strings we may need 1063 * to add to the string table for those symbols. 1064 */ 1065 count_sym = count_str = 0; 1066 for (i = 0; i < shdr_rel.sh_size / shdr_rel.sh_entsize; i++) { 1067 1068 if (shdr_rel.sh_type == SHT_RELA) { 1069 if (gelf_getrela(data_rel, i, &rela) == NULL) 1070 continue; 1071 } else { 1072 GElf_Rel rel; 1073 if (gelf_getrel(data_rel, i, &rel) == NULL) 1074 continue; 1075 rela.r_offset = rel.r_offset; 1076 rela.r_info = rel.r_info; 1077 rela.r_addend = 0; 1078 } 1079 1080 if (gelf_getsym(data_sym, GELF_R_SYM(rela.r_info), 1081 &rsym) == NULL) 1082 goto err; 1083 1084 s = (char *)data_str->d_buf + rsym.st_name; 1085 1086 if (strncmp(s, dt_prefix, sizeof (dt_prefix) - 1) != 0) 1087 continue; 1088 1089 if (dt_symtab_lookup(data_sym, rela.r_offset, 1090 shdr_rel.sh_info, &fsym) != 0) 1091 goto err; 1092 1093 if (GELF_ST_BIND(fsym.st_info) != STB_LOCAL) 1094 continue; 1095 1096 if (fsym.st_name > data_str->d_size) 1097 goto err; 1098 1099 s = (char *)data_str->d_buf + fsym.st_name; 1100 1101 /* 1102 * If this symbol isn't of type function, we've really 1103 * driven off the rails or the object file is corrupt. 1104 */ 1105 if (GELF_ST_TYPE(fsym.st_info) != STT_FUNC) { 1106 return (dt_link_error(dtp, elf, fd, bufs, 1107 "expected %s to be of type function", s)); 1108 } 1109 1110 count_sym++; 1111 count_str += 1 + snprintf(NULL, 0, dt_symfmt, 1112 dt_symprefix, objkey, s); 1113 } 1114 1115 /* 1116 * If needed, allocate the additional space for the symbol 1117 * table and string table copying the old data into the new 1118 * buffers, and marking the buffers as dirty. We inject those 1119 * newly allocated buffers into the libelf data structures, but 1120 * are still responsible for freeing them once we're done with 1121 * the elf handle. 1122 */ 1123 if (count_sym > 0) { 1124 assert(count_str > 0); 1125 1126 if ((pair = dt_alloc(dtp, sizeof (*pair))) == NULL) 1127 goto err; 1128 1129 if ((pair->dlp_str = dt_alloc(dtp, data_str->d_size + 1130 count_str)) == NULL) { 1131 dt_free(dtp, pair); 1132 goto err; 1133 } 1134 1135 if ((pair->dlp_sym = dt_alloc(dtp, data_sym->d_size + 1136 count_sym * symsize)) == NULL) { 1137 dt_free(dtp, pair->dlp_str); 1138 dt_free(dtp, pair); 1139 goto err; 1140 } 1141 1142 pair->dlp_next = bufs; 1143 bufs = pair; 1144 1145 bcopy(data_str->d_buf, pair->dlp_str, data_str->d_size); 1146 data_str->d_buf = pair->dlp_str; 1147 data_str->d_size += count_str; 1148 (void) elf_flagdata(data_str, ELF_C_SET, ELF_F_DIRTY); 1149 1150 shdr_str.sh_size += count_str; 1151 (void) gelf_update_shdr(scn_str, &shdr_str); 1152 1153 bcopy(data_sym->d_buf, pair->dlp_sym, data_sym->d_size); 1154 data_sym->d_buf = pair->dlp_sym; 1155 data_sym->d_size += count_sym * symsize; 1156 (void) elf_flagdata(data_sym, ELF_C_SET, ELF_F_DIRTY); 1157 1158 shdr_sym.sh_size += count_sym * symsize; 1159 (void) gelf_update_shdr(scn_sym, &shdr_sym); 1160 } 1161 1162 count_str = shdr_str.sh_size - count_str; 1163 count_sym = data_sym->d_size / symsize - count_sym; 1164 1165 /* 1166 * Now that the tables have been allocated, perform the 1167 * modifications described above. 1168 */ 1169 for (i = 0; i < shdr_rel.sh_size / shdr_rel.sh_entsize; i++) { 1170 1171 if (shdr_rel.sh_type == SHT_RELA) { 1172 if (gelf_getrela(data_rel, i, &rela) == NULL) 1173 continue; 1174 } else { 1175 GElf_Rel rel; 1176 if (gelf_getrel(data_rel, i, &rel) == NULL) 1177 continue; 1178 rela.r_offset = rel.r_offset; 1179 rela.r_info = rel.r_info; 1180 rela.r_addend = 0; 1181 } 1182 1183 ndx = GELF_R_SYM(rela.r_info); 1184 1185 if (gelf_getsym(data_sym, ndx, &rsym) == NULL || 1186 rsym.st_name > data_str->d_size) 1187 goto err; 1188 1189 s = (char *)data_str->d_buf + rsym.st_name; 1190 1191 if (strncmp(s, dt_prefix, sizeof (dt_prefix) - 1) != 0) 1192 continue; 1193 1194 s += sizeof (dt_prefix) - 1; 1195 if ((p = strstr(s, "___")) == NULL || 1196 p - s >= sizeof (pname)) 1197 goto err; 1198 1199 bcopy(s, pname, p - s); 1200 pname[p - s] = '\0'; 1201 1202 p = strhyphenate(p + 3); /* strlen("___") */ 1203 1204 if (dt_symtab_lookup(data_sym, rela.r_offset, 1205 shdr_rel.sh_info, &fsym) != 0) 1206 goto err; 1207 1208 if (fsym.st_name > data_str->d_size) 1209 goto err; 1210 1211 assert(GELF_ST_TYPE(fsym.st_info) == STT_FUNC); 1212 1213 /* 1214 * If a NULL relocation name is passed to 1215 * dt_probe_define(), the function name is used for the 1216 * relocation. The relocation needs to use a mangled 1217 * name if the symbol is locally scoped; the function 1218 * name may need to change if we've found the global 1219 * alias for the locally scoped symbol (we prefer 1220 * global symbols to locals in dt_symtab_lookup()). 1221 */ 1222 s = (char *)data_str->d_buf + fsym.st_name; 1223 r = NULL; 1224 1225 if (GELF_ST_BIND(fsym.st_info) == STB_LOCAL) { 1226 dsym = fsym; 1227 dsym.st_name = count_str; 1228 dsym.st_info = GELF_ST_INFO(STB_GLOBAL, 1229 STT_FUNC); 1230 dsym.st_other = ELF64_ST_VISIBILITY(STV_HIDDEN); 1231 (void) gelf_update_sym(data_sym, count_sym, 1232 &dsym); 1233 1234 r = (char *)data_str->d_buf + count_str; 1235 count_str += 1 + sprintf(r, dt_symfmt, 1236 dt_symprefix, objkey, s); 1237 count_sym++; 1238 1239 } else if (strncmp(s, dt_symprefix, 1240 strlen(dt_symprefix)) == 0) { 1241 r = s; 1242 if ((s = strchr(s, '.')) == NULL) 1243 goto err; 1244 s++; 1245 } 1246 1247 if ((pvp = dt_provider_lookup(dtp, pname)) == NULL) { 1248 return (dt_link_error(dtp, elf, fd, bufs, 1249 "no such provider %s", pname)); 1250 } 1251 1252 if ((prp = dt_probe_lookup(pvp, p)) == NULL) { 1253 return (dt_link_error(dtp, elf, fd, bufs, 1254 "no such probe %s", p)); 1255 } 1256 1257 assert(fsym.st_value <= rela.r_offset); 1258 1259 off = rela.r_offset - fsym.st_value; 1260 if (dt_modtext(data_tgt->d_buf, &rela, &off) != 0) 1261 goto err; 1262 1263 if (dt_probe_define(pvp, prp, s, r, off) != 0) { 1264 return (dt_link_error(dtp, elf, fd, bufs, 1265 "failed to allocate space for probe")); 1266 } 1267 1268 mod = 1; 1269 (void) elf_flagdata(data_tgt, ELF_C_SET, ELF_F_DIRTY); 1270 1271 /* 1272 * This symbol may already have been marked to 1273 * be ignored by another relocation referencing 1274 * the same symbol or if this object file has 1275 * already been processed by an earlier link 1276 * invocation. 1277 */ 1278 if (rsym.st_shndx != SHN_SUNW_IGNORE) { 1279 rsym.st_shndx = SHN_SUNW_IGNORE; 1280 (void) gelf_update_sym(data_sym, ndx, &rsym); 1281 } 1282 } 1283 1284 /* 1285 * The full buffer may not have been used so shrink them here 1286 * to match the sizes actually used. 1287 */ 1288 data_str->d_size = count_str; 1289 data_sym->d_size = count_sym * symsize; 1290 } 1291 1292 if (mod && elf_update(elf, ELF_C_WRITE) == -1) 1293 goto err; 1294 1295 (void) elf_end(elf); 1296 (void) close(fd); 1297 1298 while ((pair = bufs) != NULL) { 1299 bufs = pair->dlp_next; 1300 dt_free(dtp, pair->dlp_str); 1301 dt_free(dtp, pair->dlp_sym); 1302 dt_free(dtp, pair); 1303 } 1304 1305 return (0); 1306 1307 err: 1308 return (dt_link_error(dtp, elf, fd, bufs, 1309 "an error was encountered while processing %s", obj)); 1310 } 1311 1312 int 1313 dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, 1314 const char *file, int objc, char *const objv[]) 1315 { 1316 char drti[PATH_MAX]; 1317 dof_hdr_t *dof; 1318 int fd, status, i, cur; 1319 char *cmd, tmp; 1320 size_t len; 1321 int ret = 0; 1322 1323 /* 1324 * A NULL program indicates a special use in which we just link 1325 * together a bunch of object files specified in objv and then 1326 * unlink(2) those object files. 1327 */ 1328 if (pgp == NULL) { 1329 const char *fmt = "%s -o %s -r"; 1330 1331 len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file) + 1; 1332 1333 for (i = 0; i < objc; i++) 1334 len += strlen(objv[i]) + 1; 1335 1336 cmd = alloca(len); 1337 1338 cur = snprintf(cmd, len, fmt, dtp->dt_ld_path, file); 1339 1340 for (i = 0; i < objc; i++) 1341 cur += snprintf(cmd + cur, len - cur, " %s", objv[i]); 1342 1343 if ((status = system(cmd)) == -1) { 1344 return (dt_link_error(dtp, NULL, -1, NULL, 1345 "failed to run %s: %s", dtp->dt_ld_path, 1346 strerror(errno))); 1347 } 1348 1349 if (WIFSIGNALED(status)) { 1350 return (dt_link_error(dtp, NULL, -1, NULL, 1351 "failed to link %s: %s failed due to signal %d", 1352 file, dtp->dt_ld_path, WTERMSIG(status))); 1353 } 1354 1355 if (WEXITSTATUS(status) != 0) { 1356 return (dt_link_error(dtp, NULL, -1, NULL, 1357 "failed to link %s: %s exited with status %d\n", 1358 file, dtp->dt_ld_path, WEXITSTATUS(status))); 1359 } 1360 1361 for (i = 0; i < objc; i++) { 1362 if (strcmp(objv[i], file) != 0) 1363 (void) unlink(objv[i]); 1364 } 1365 1366 return (0); 1367 } 1368 1369 for (i = 0; i < objc; i++) { 1370 if (process_obj(dtp, objv[i]) != 0) 1371 return (-1); /* errno is set for us */ 1372 } 1373 1374 if ((dof = dtrace_dof_create(dtp, pgp, dflags)) == NULL) 1375 return (-1); /* errno is set for us */ 1376 1377 /* 1378 * Create a temporary file and then unlink it if we're going to 1379 * combine it with drti.o later. We can still refer to it in child 1380 * processes as /dev/fd/<fd>. 1381 */ 1382 if ((fd = open64(file, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) { 1383 return (dt_link_error(dtp, NULL, -1, NULL, 1384 "failed to open %s: %s", file, strerror(errno))); 1385 } 1386 1387 /* 1388 * If -xlinktype=DOF has been selected, just write out the DOF. 1389 * Otherwise proceed to the default of generating and linking ELF. 1390 */ 1391 switch (dtp->dt_linktype) { 1392 case DT_LTYP_DOF: 1393 if (dt_write(dtp, fd, dof, dof->dofh_filesz) < dof->dofh_filesz) 1394 ret = errno; 1395 1396 if (close(fd) != 0 && ret == 0) 1397 ret = errno; 1398 1399 if (ret != 0) { 1400 return (dt_link_error(dtp, NULL, -1, NULL, 1401 "failed to write %s: %s", file, strerror(ret))); 1402 } 1403 1404 return (0); 1405 1406 case DT_LTYP_ELF: 1407 break; /* fall through to the rest of dtrace_program_link() */ 1408 1409 default: 1410 return (dt_link_error(dtp, NULL, -1, NULL, 1411 "invalid link type %u\n", dtp->dt_linktype)); 1412 } 1413 1414 1415 if (!dtp->dt_lazyload) 1416 (void) unlink(file); 1417 1418 if (dtp->dt_oflags & DTRACE_O_LP64) 1419 status = dump_elf64(dtp, dof, fd); 1420 else 1421 status = dump_elf32(dtp, dof, fd); 1422 1423 if (status != 0 || lseek(fd, 0, SEEK_SET) != 0) { 1424 return (dt_link_error(dtp, NULL, -1, NULL, 1425 "failed to write %s: %s", file, strerror(errno))); 1426 } 1427 1428 if (!dtp->dt_lazyload) { 1429 const char *fmt = "%s -o %s -r -Blocal -Breduce /dev/fd/%d %s"; 1430 1431 if (dtp->dt_oflags & DTRACE_O_LP64) { 1432 (void) snprintf(drti, sizeof (drti), 1433 "%s/64/drti.o", _dtrace_libdir); 1434 } else { 1435 (void) snprintf(drti, sizeof (drti), 1436 "%s/drti.o", _dtrace_libdir); 1437 } 1438 1439 len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, fd, 1440 drti) + 1; 1441 1442 cmd = alloca(len); 1443 1444 (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, fd, drti); 1445 1446 if ((status = system(cmd)) == -1) { 1447 ret = dt_link_error(dtp, NULL, -1, NULL, 1448 "failed to run %s: %s", dtp->dt_ld_path, 1449 strerror(errno)); 1450 goto done; 1451 } 1452 1453 (void) close(fd); /* release temporary file */ 1454 1455 if (WIFSIGNALED(status)) { 1456 ret = dt_link_error(dtp, NULL, -1, NULL, 1457 "failed to link %s: %s failed due to signal %d", 1458 file, dtp->dt_ld_path, WTERMSIG(status)); 1459 goto done; 1460 } 1461 1462 if (WEXITSTATUS(status) != 0) { 1463 ret = dt_link_error(dtp, NULL, -1, NULL, 1464 "failed to link %s: %s exited with status %d\n", 1465 file, dtp->dt_ld_path, WEXITSTATUS(status)); 1466 goto done; 1467 } 1468 } else { 1469 (void) close(fd); 1470 } 1471 1472 done: 1473 dtrace_dof_destroy(dtp, dof); 1474 return (ret); 1475 } 1476