dt_link.c (178529) | dt_link.c (178573) |
---|---|
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 --- 6 unchanged lines hidden (view full) --- 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/* | 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 --- 6 unchanged lines hidden (view full) --- 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 2007 Sun Microsystems, Inc. All rights reserved. | 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> | 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29#define ELF_TARGET_ALL 30#include <elf.h> 31 32#include <sys/types.h> |
33#if defined(sun) |
|
33#include <sys/sysmacros.h> | 34#include <sys/sysmacros.h> |
35#else 36#define P2ROUNDUP(x, align) (-(-(x) & -(align))) 37#endif |
|
34 35#include <unistd.h> 36#include <strings.h> | 38 39#include <unistd.h> 40#include <strings.h> |
41#if defined(sun) |
|
37#include <alloca.h> | 42#include <alloca.h> |
43#endif |
|
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 <limits.h> 45#include <stddef.h> 46#include <stdlib.h> 47#include <stdio.h> 48#include <fcntl.h> 49#include <errno.h> |
50#if defined(sun) |
|
44#include <wait.h> | 51#include <wait.h> |
52#else 53#include <sys/wait.h> 54#endif |
|
45#include <assert.h> 46#include <sys/ipc.h> 47 48#include <dt_impl.h> 49#include <dt_provider.h> 50#include <dt_program.h> 51#include <dt_string.h> 52 --- 156 unchanged lines hidden (view full) --- 209 s = &dofs[dofrh->dofr_relsec]; 210 /*LINTED*/ 211 dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); 212 nrel = s->dofs_size / s->dofs_entsize; 213 214 s = &dofs[dofrh->dofr_tgtsec]; 215 216 for (j = 0; j < nrel; j++) { | 55#include <assert.h> 56#include <sys/ipc.h> 57 58#include <dt_impl.h> 59#include <dt_provider.h> 60#include <dt_program.h> 61#include <dt_string.h> 62 --- 156 unchanged lines hidden (view full) --- 219 s = &dofs[dofrh->dofr_relsec]; 220 /*LINTED*/ 221 dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); 222 nrel = s->dofs_size / s->dofs_entsize; 223 224 s = &dofs[dofrh->dofr_tgtsec]; 225 226 for (j = 0; j < nrel; j++) { |
217#if defined(__i386) || defined(__amd64) | 227#if defined(__arm__) 228/* XXX */ 229printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 230#elif defined(__ia64__) 231/* XXX */ 232printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 233#elif defined(__i386) || defined(__amd64) |
218 rel->r_offset = s->dofs_offset + 219 dofr[j].dofr_offset; 220 rel->r_info = ELF32_R_INFO(count + dep->de_global, 221 R_386_32); | 234 rel->r_offset = s->dofs_offset + 235 dofr[j].dofr_offset; 236 rel->r_info = ELF32_R_INFO(count + dep->de_global, 237 R_386_32); |
238#elif defined(__mips__) 239/* XXX */ 240printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 241#elif defined(__powerpc__) 242/* XXX */ 243printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); |
|
222#elif defined(__sparc) 223 /* 224 * Add 4 bytes to hit the low half of this 64-bit 225 * big-endian address. 226 */ 227 rel->r_offset = s->dofs_offset + 228 dofr[j].dofr_offset + 4; 229 rel->r_info = ELF32_R_INFO(count + dep->de_global, --- 155 unchanged lines hidden (view full) --- 385 s = &dofs[dofrh->dofr_relsec]; 386 /*LINTED*/ 387 dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); 388 nrel = s->dofs_size / s->dofs_entsize; 389 390 s = &dofs[dofrh->dofr_tgtsec]; 391 392 for (j = 0; j < nrel; j++) { | 244#elif defined(__sparc) 245 /* 246 * Add 4 bytes to hit the low half of this 64-bit 247 * big-endian address. 248 */ 249 rel->r_offset = s->dofs_offset + 250 dofr[j].dofr_offset + 4; 251 rel->r_info = ELF32_R_INFO(count + dep->de_global, --- 155 unchanged lines hidden (view full) --- 407 s = &dofs[dofrh->dofr_relsec]; 408 /*LINTED*/ 409 dofr = (dof_relodesc_t *)((char *)dof + s->dofs_offset); 410 nrel = s->dofs_size / s->dofs_entsize; 411 412 s = &dofs[dofrh->dofr_tgtsec]; 413 414 for (j = 0; j < nrel; j++) { |
393#if defined(__i386) || defined(__amd64) | 415printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 416#ifdef DOODAD 417#if defined(__arm__) 418/* XXX */ 419#elif defined(__ia64__) 420/* XXX */ 421#elif defined(__mips__) 422/* XXX */ 423#elif defined(__powerpc__) 424/* XXX */ 425#elif defined(__i386) || defined(__amd64) |
394 rel->r_offset = s->dofs_offset + 395 dofr[j].dofr_offset; 396 rel->r_info = ELF64_R_INFO(count + dep->de_global, 397 R_AMD64_64); 398#elif defined(__sparc) 399 rel->r_offset = s->dofs_offset + 400 dofr[j].dofr_offset; 401 rel->r_info = ELF64_R_INFO(count + dep->de_global, 402 R_SPARC_64); 403#else 404#error unknown ISA 405#endif | 426 rel->r_offset = s->dofs_offset + 427 dofr[j].dofr_offset; 428 rel->r_info = ELF64_R_INFO(count + dep->de_global, 429 R_AMD64_64); 430#elif defined(__sparc) 431 rel->r_offset = s->dofs_offset + 432 dofr[j].dofr_offset; 433 rel->r_info = ELF64_R_INFO(count + dep->de_global, 434 R_SPARC_64); 435#else 436#error unknown ISA 437#endif |
438#endif |
|
406 407 sym->st_name = base + dofr[j].dofr_name - 1; 408 sym->st_value = 0; 409 sym->st_size = 0; 410 sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_FUNC); 411 sym->st_other = 0; 412 sym->st_shndx = SHN_UNDEF; 413 --- 61 unchanged lines hidden (view full) --- 475 bzero(&elf_file, sizeof (elf_file)); 476 477 elf_file.ehdr.e_ident[EI_MAG0] = ELFMAG0; 478 elf_file.ehdr.e_ident[EI_MAG1] = ELFMAG1; 479 elf_file.ehdr.e_ident[EI_MAG2] = ELFMAG2; 480 elf_file.ehdr.e_ident[EI_MAG3] = ELFMAG3; 481 elf_file.ehdr.e_ident[EI_VERSION] = EV_CURRENT; 482 elf_file.ehdr.e_ident[EI_CLASS] = ELFCLASS32; | 439 440 sym->st_name = base + dofr[j].dofr_name - 1; 441 sym->st_value = 0; 442 sym->st_size = 0; 443 sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_FUNC); 444 sym->st_other = 0; 445 sym->st_shndx = SHN_UNDEF; 446 --- 61 unchanged lines hidden (view full) --- 508 bzero(&elf_file, sizeof (elf_file)); 509 510 elf_file.ehdr.e_ident[EI_MAG0] = ELFMAG0; 511 elf_file.ehdr.e_ident[EI_MAG1] = ELFMAG1; 512 elf_file.ehdr.e_ident[EI_MAG2] = ELFMAG2; 513 elf_file.ehdr.e_ident[EI_MAG3] = ELFMAG3; 514 elf_file.ehdr.e_ident[EI_VERSION] = EV_CURRENT; 515 elf_file.ehdr.e_ident[EI_CLASS] = ELFCLASS32; |
483#if defined(_BIG_ENDIAN) | 516#if BYTE_ORDER == _BIG_ENDIAN |
484 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2MSB; | 517 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2MSB; |
485#elif defined(_LITTLE_ENDIAN) | 518#else |
486 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2LSB; 487#endif | 519 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2LSB; 520#endif |
521#if defined(__FreeBSD__) 522 elf_file.ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; 523#endif |
|
488 elf_file.ehdr.e_type = ET_REL; | 524 elf_file.ehdr.e_type = ET_REL; |
489#if defined(__sparc) | 525#if defined(__arm__) 526 elf_file.ehdr.e_machine = EM_ARM; 527#elif defined(__ia64__) 528 elf_file.ehdr.e_machine = EM_IA_64; 529#elif defined(__mips__) 530 elf_file.ehdr.e_machine = EM_MIPS; 531#elif defined(__powerpc__) 532 elf_file.ehdr.e_machine = EM_PPC; 533#elif defined(__sparc) |
490 elf_file.ehdr.e_machine = EM_SPARC; 491#elif defined(__i386) || defined(__amd64) 492 elf_file.ehdr.e_machine = EM_386; 493#endif 494 elf_file.ehdr.e_version = EV_CURRENT; 495 elf_file.ehdr.e_shoff = sizeof (Elf32_Ehdr); 496 elf_file.ehdr.e_ehsize = sizeof (Elf32_Ehdr); 497 elf_file.ehdr.e_phentsize = sizeof (Elf32_Phdr); --- 114 unchanged lines hidden (view full) --- 612 bzero(&elf_file, sizeof (elf_file)); 613 614 elf_file.ehdr.e_ident[EI_MAG0] = ELFMAG0; 615 elf_file.ehdr.e_ident[EI_MAG1] = ELFMAG1; 616 elf_file.ehdr.e_ident[EI_MAG2] = ELFMAG2; 617 elf_file.ehdr.e_ident[EI_MAG3] = ELFMAG3; 618 elf_file.ehdr.e_ident[EI_VERSION] = EV_CURRENT; 619 elf_file.ehdr.e_ident[EI_CLASS] = ELFCLASS64; | 534 elf_file.ehdr.e_machine = EM_SPARC; 535#elif defined(__i386) || defined(__amd64) 536 elf_file.ehdr.e_machine = EM_386; 537#endif 538 elf_file.ehdr.e_version = EV_CURRENT; 539 elf_file.ehdr.e_shoff = sizeof (Elf32_Ehdr); 540 elf_file.ehdr.e_ehsize = sizeof (Elf32_Ehdr); 541 elf_file.ehdr.e_phentsize = sizeof (Elf32_Phdr); --- 114 unchanged lines hidden (view full) --- 656 bzero(&elf_file, sizeof (elf_file)); 657 658 elf_file.ehdr.e_ident[EI_MAG0] = ELFMAG0; 659 elf_file.ehdr.e_ident[EI_MAG1] = ELFMAG1; 660 elf_file.ehdr.e_ident[EI_MAG2] = ELFMAG2; 661 elf_file.ehdr.e_ident[EI_MAG3] = ELFMAG3; 662 elf_file.ehdr.e_ident[EI_VERSION] = EV_CURRENT; 663 elf_file.ehdr.e_ident[EI_CLASS] = ELFCLASS64; |
620#if defined(_BIG_ENDIAN) | 664#if BYTE_ORDER == _BIG_ENDIAN |
621 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2MSB; | 665 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2MSB; |
622#elif defined(_LITTLE_ENDIAN) | 666#else |
623 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2LSB; 624#endif | 667 elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2LSB; 668#endif |
669#if defined(__FreeBSD__) 670 elf_file.ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; 671#endif |
|
625 elf_file.ehdr.e_type = ET_REL; | 672 elf_file.ehdr.e_type = ET_REL; |
626#if defined(__sparc) | 673#if defined(__arm__) 674 elf_file.ehdr.e_machine = EM_ARM; 675#elif defined(__ia64__) 676 elf_file.ehdr.e_machine = EM_IA_64; 677#elif defined(__mips__) 678 elf_file.ehdr.e_machine = EM_MIPS; 679#elif defined(__powerpc__) 680 elf_file.ehdr.e_machine = EM_PPC; 681#elif defined(__sparc) |
627 elf_file.ehdr.e_machine = EM_SPARCV9; 628#elif defined(__i386) || defined(__amd64) 629 elf_file.ehdr.e_machine = EM_AMD64; 630#endif 631 elf_file.ehdr.e_version = EV_CURRENT; 632 elf_file.ehdr.e_shoff = sizeof (Elf64_Ehdr); 633 elf_file.ehdr.e_ehsize = sizeof (Elf64_Ehdr); 634 elf_file.ehdr.e_phentsize = sizeof (Elf64_Phdr); --- 99 unchanged lines hidden (view full) --- 734 } 735 } 736 737 if (ret == 0) 738 *sym = s; 739 return (ret); 740} 741 | 682 elf_file.ehdr.e_machine = EM_SPARCV9; 683#elif defined(__i386) || defined(__amd64) 684 elf_file.ehdr.e_machine = EM_AMD64; 685#endif 686 elf_file.ehdr.e_version = EV_CURRENT; 687 elf_file.ehdr.e_shoff = sizeof (Elf64_Ehdr); 688 elf_file.ehdr.e_ehsize = sizeof (Elf64_Ehdr); 689 elf_file.ehdr.e_phentsize = sizeof (Elf64_Phdr); --- 99 unchanged lines hidden (view full) --- 789 } 790 } 791 792 if (ret == 0) 793 *sym = s; 794 return (ret); 795} 796 |
742#if defined(__sparc) | 797#if defined(__arm__) 798/* XXX */ 799static int 800dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, 801 uint32_t *off) 802{ 803printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 804 return (0); 805} 806#elif defined(__ia64__) 807/* XXX */ 808static int 809dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, 810 uint32_t *off) 811{ 812printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 813 return (0); 814} 815#elif defined(__mips__) 816/* XXX */ 817static int 818dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, 819 uint32_t *off) 820{ 821printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 822 return (0); 823} 824#elif defined(__powerpc__) 825/* XXX */ 826static int 827dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, 828 uint32_t *off) 829{ 830printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 831 return (0); 832} |
743 | 833 |
834#elif defined(__sparc) 835 |
|
744#define DT_OP_RET 0x81c7e008 745#define DT_OP_NOP 0x01000000 746#define DT_OP_CALL 0x40000000 747#define DT_OP_CLR_O0 0x90102000 748 749#define DT_IS_MOV_O7(inst) (((inst) & 0xffffe000) == 0x9e100000) 750#define DT_IS_RESTORE(inst) (((inst) & 0xc1f80000) == 0x81e80000) 751#define DT_IS_RETL(inst) (((inst) & 0xfff83fff) == 0x81c02008) --- 93 unchanged lines hidden (view full) --- 845 } 846 847 return (0); 848} 849 850#elif defined(__i386) || defined(__amd64) 851 852#define DT_OP_NOP 0x90 | 836#define DT_OP_RET 0x81c7e008 837#define DT_OP_NOP 0x01000000 838#define DT_OP_CALL 0x40000000 839#define DT_OP_CLR_O0 0x90102000 840 841#define DT_IS_MOV_O7(inst) (((inst) & 0xffffe000) == 0x9e100000) 842#define DT_IS_RESTORE(inst) (((inst) & 0xc1f80000) == 0x81e80000) 843#define DT_IS_RETL(inst) (((inst) & 0xfff83fff) == 0x81c02008) --- 93 unchanged lines hidden (view full) --- 937 } 938 939 return (0); 940} 941 942#elif defined(__i386) || defined(__amd64) 943 944#define DT_OP_NOP 0x90 |
945#define DT_OP_RET 0xc3 |
|
853#define DT_OP_CALL 0xe8 | 946#define DT_OP_CALL 0xe8 |
947#define DT_OP_JMP32 0xe9 |
|
854#define DT_OP_REX_RAX 0x48 855#define DT_OP_XOR_EAX_0 0x33 856#define DT_OP_XOR_EAX_1 0xc0 857 858static int 859dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, 860 uint32_t *off) 861{ 862 uint8_t *ip = (uint8_t *)(p + rela->r_offset - 1); | 948#define DT_OP_REX_RAX 0x48 949#define DT_OP_XOR_EAX_0 0x33 950#define DT_OP_XOR_EAX_1 0xc0 951 952static int 953dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, 954 uint32_t *off) 955{ 956 uint8_t *ip = (uint8_t *)(p + rela->r_offset - 1); |
957 uint8_t ret; |
|
863 864 /* 865 * On x86, the first byte of the instruction is the call opcode and 866 * the next four bytes are the 32-bit address; the relocation is for 867 * the address operand. We back up the offset to the first byte of 868 * the instruction. For is-enabled probes, we later advance the offset 869 * so that it hits the first nop in the instruction sequence. 870 */ --- 7 unchanged lines hidden (view full) --- 878 if (GELF_R_TYPE(rela->r_info) != R_386_PC32 && 879 GELF_R_TYPE(rela->r_info) != R_386_PLT32) 880 return (-1); 881 882 /* 883 * We may have already processed this object file in an earlier linker 884 * invocation. Check to see if the present instruction sequence matches 885 * the one we would install. For is-enabled probes, we advance the | 958 959 /* 960 * On x86, the first byte of the instruction is the call opcode and 961 * the next four bytes are the 32-bit address; the relocation is for 962 * the address operand. We back up the offset to the first byte of 963 * the instruction. For is-enabled probes, we later advance the offset 964 * so that it hits the first nop in the instruction sequence. 965 */ --- 7 unchanged lines hidden (view full) --- 973 if (GELF_R_TYPE(rela->r_info) != R_386_PC32 && 974 GELF_R_TYPE(rela->r_info) != R_386_PLT32) 975 return (-1); 976 977 /* 978 * We may have already processed this object file in an earlier linker 979 * invocation. Check to see if the present instruction sequence matches 980 * the one we would install. For is-enabled probes, we advance the |
886 * offset to the first nop instruction in the sequence. | 981 * offset to the first nop instruction in the sequence to match the 982 * text modification code below. |
887 */ 888 if (!isenabled) { | 983 */ 984 if (!isenabled) { |
889 if (ip[0] == DT_OP_NOP && ip[1] == DT_OP_NOP && 890 ip[2] == DT_OP_NOP && ip[3] == DT_OP_NOP && 891 ip[4] == DT_OP_NOP) | 985 if ((ip[0] == DT_OP_NOP || ip[0] == DT_OP_RET) && 986 ip[1] == DT_OP_NOP && ip[2] == DT_OP_NOP && 987 ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP) |
892 return (0); 893 } else if (dtp->dt_oflags & DTRACE_O_LP64) { 894 if (ip[0] == DT_OP_REX_RAX && 895 ip[1] == DT_OP_XOR_EAX_0 && ip[2] == DT_OP_XOR_EAX_1 && | 988 return (0); 989 } else if (dtp->dt_oflags & DTRACE_O_LP64) { 990 if (ip[0] == DT_OP_REX_RAX && 991 ip[1] == DT_OP_XOR_EAX_0 && ip[2] == DT_OP_XOR_EAX_1 && |
896 ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP) { | 992 (ip[3] == DT_OP_NOP || ip[3] == DT_OP_RET) && 993 ip[4] == DT_OP_NOP) { |
897 (*off) += 3; 898 return (0); 899 } 900 } else { 901 if (ip[0] == DT_OP_XOR_EAX_0 && ip[1] == DT_OP_XOR_EAX_1 && | 994 (*off) += 3; 995 return (0); 996 } 997 } else { 998 if (ip[0] == DT_OP_XOR_EAX_0 && ip[1] == DT_OP_XOR_EAX_1 && |
902 ip[2] == DT_OP_NOP && ip[3] == DT_OP_NOP && 903 ip[4] == DT_OP_NOP) { | 999 (ip[2] == DT_OP_NOP || ip[2] == DT_OP_RET) && 1000 ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP) { |
904 (*off) += 2; 905 return (0); 906 } 907 } 908 909 /* | 1001 (*off) += 2; 1002 return (0); 1003 } 1004 } 1005 1006 /* |
910 * We only expect a call instrution with a 32-bit displacement. | 1007 * We expect either a call instrution with a 32-bit displacement or a 1008 * jmp instruction with a 32-bit displacement acting as a tail-call. |
911 */ | 1009 */ |
912 if (ip[0] != DT_OP_CALL) { 913 dt_dprintf("found %x instead of a call instruction at %llx\n", 914 ip[0], (u_longlong_t)rela->r_offset); | 1010 if (ip[0] != DT_OP_CALL && ip[0] != DT_OP_JMP32) { 1011 dt_dprintf("found %x instead of a call or jmp instruction at " 1012 "%llx\n", ip[0], (u_longlong_t)rela->r_offset); |
915 return (-1); 916 } 917 | 1013 return (-1); 1014 } 1015 |
1016 ret = (ip[0] == DT_OP_JMP32) ? DT_OP_RET : DT_OP_NOP; 1017 |
|
918 /* 919 * Establish the instruction sequence -- all nops for probes, and an 920 * instruction to clear the return value register (%eax/%rax) followed 921 * by nops for is-enabled probes. For is-enabled probes, we advance 922 * the offset to the first nop. This isn't stricly necessary but makes 923 * for more readable disassembly when the probe is enabled. 924 */ 925 if (!isenabled) { | 1018 /* 1019 * Establish the instruction sequence -- all nops for probes, and an 1020 * instruction to clear the return value register (%eax/%rax) followed 1021 * by nops for is-enabled probes. For is-enabled probes, we advance 1022 * the offset to the first nop. This isn't stricly necessary but makes 1023 * for more readable disassembly when the probe is enabled. 1024 */ 1025 if (!isenabled) { |
926 ip[0] = DT_OP_NOP; | 1026 ip[0] = ret; |
927 ip[1] = DT_OP_NOP; 928 ip[2] = DT_OP_NOP; 929 ip[3] = DT_OP_NOP; 930 ip[4] = DT_OP_NOP; 931 } else if (dtp->dt_oflags & DTRACE_O_LP64) { 932 ip[0] = DT_OP_REX_RAX; 933 ip[1] = DT_OP_XOR_EAX_0; 934 ip[2] = DT_OP_XOR_EAX_1; | 1027 ip[1] = DT_OP_NOP; 1028 ip[2] = DT_OP_NOP; 1029 ip[3] = DT_OP_NOP; 1030 ip[4] = DT_OP_NOP; 1031 } else if (dtp->dt_oflags & DTRACE_O_LP64) { 1032 ip[0] = DT_OP_REX_RAX; 1033 ip[1] = DT_OP_XOR_EAX_0; 1034 ip[2] = DT_OP_XOR_EAX_1; |
935 ip[3] = DT_OP_NOP; | 1035 ip[3] = ret; |
936 ip[4] = DT_OP_NOP; 937 (*off) += 3; 938 } else { 939 ip[0] = DT_OP_XOR_EAX_0; 940 ip[1] = DT_OP_XOR_EAX_1; | 1036 ip[4] = DT_OP_NOP; 1037 (*off) += 3; 1038 } else { 1039 ip[0] = DT_OP_XOR_EAX_0; 1040 ip[1] = DT_OP_XOR_EAX_1; |
941 ip[2] = DT_OP_NOP; | 1041 ip[2] = ret; |
942 ip[3] = DT_OP_NOP; 943 ip[4] = DT_OP_NOP; 944 (*off) += 2; 945 } 946 947 return (0); 948} 949 --- 78 unchanged lines hidden (view full) --- 1028 1029 if (gelf_getehdr(elf, &ehdr) == NULL) { 1030 return (dt_link_error(dtp, elf, fd, bufs, "corrupt file: %s", 1031 obj)); 1032 } 1033 1034 if (dtp->dt_oflags & DTRACE_O_LP64) { 1035 eclass = ELFCLASS64; | 1042 ip[3] = DT_OP_NOP; 1043 ip[4] = DT_OP_NOP; 1044 (*off) += 2; 1045 } 1046 1047 return (0); 1048} 1049 --- 78 unchanged lines hidden (view full) --- 1128 1129 if (gelf_getehdr(elf, &ehdr) == NULL) { 1130 return (dt_link_error(dtp, elf, fd, bufs, "corrupt file: %s", 1131 obj)); 1132 } 1133 1134 if (dtp->dt_oflags & DTRACE_O_LP64) { 1135 eclass = ELFCLASS64; |
1036#if defined(__sparc) | 1136#if defined(__ia64__) 1137 emachine1 = emachine2 = EM_IA_64; 1138#elif defined(__mips__) 1139 emachine1 = emachine2 = EM_MIPS; 1140#elif defined(__powerpc__) 1141 emachine1 = emachine2 = EM_PPC64; 1142#elif defined(__sparc) |
1037 emachine1 = emachine2 = EM_SPARCV9; 1038#elif defined(__i386) || defined(__amd64) 1039 emachine1 = emachine2 = EM_AMD64; 1040#endif 1041 symsize = sizeof (Elf64_Sym); 1042 } else { 1043 eclass = ELFCLASS32; | 1143 emachine1 = emachine2 = EM_SPARCV9; 1144#elif defined(__i386) || defined(__amd64) 1145 emachine1 = emachine2 = EM_AMD64; 1146#endif 1147 symsize = sizeof (Elf64_Sym); 1148 } else { 1149 eclass = ELFCLASS32; |
1044#if defined(__sparc) | 1150#if defined(__arm__) 1151 emachine1 = emachine2 = EM_ARM; 1152#elif defined(__mips__) 1153 emachine1 = emachine2 = EM_MIPS; 1154#elif defined(__powerpc__) 1155 emachine1 = emachine2 = EM_PPC; 1156#elif defined(__sparc) |
1045 emachine1 = EM_SPARC; 1046 emachine2 = EM_SPARC32PLUS; | 1157 emachine1 = EM_SPARC; 1158 emachine2 = EM_SPARC32PLUS; |
1047#elif defined(__i386) || defined(__amd64) | 1159#elif defined(__i386) || defined(__amd64) || defined(__ia64__) |
1048 emachine1 = emachine2 = EM_386; 1049#endif 1050 symsize = sizeof (Elf32_Sym); 1051 } 1052 1053 if (ehdr.e_ident[EI_CLASS] != eclass) { 1054 return (dt_link_error(dtp, elf, fd, bufs, 1055 "incorrect ELF class for object file: %s", obj)); --- 346 unchanged lines hidden (view full) --- 1402 1403 /* 1404 * This symbol may already have been marked to 1405 * be ignored by another relocation referencing 1406 * the same symbol or if this object file has 1407 * already been processed by an earlier link 1408 * invocation. 1409 */ | 1160 emachine1 = emachine2 = EM_386; 1161#endif 1162 symsize = sizeof (Elf32_Sym); 1163 } 1164 1165 if (ehdr.e_ident[EI_CLASS] != eclass) { 1166 return (dt_link_error(dtp, elf, fd, bufs, 1167 "incorrect ELF class for object file: %s", obj)); --- 346 unchanged lines hidden (view full) --- 1514 1515 /* 1516 * This symbol may already have been marked to 1517 * be ignored by another relocation referencing 1518 * the same symbol or if this object file has 1519 * already been processed by an earlier link 1520 * invocation. 1521 */ |
1522printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); 1523#ifdef DOODAD |
|
1410 if (rsym.st_shndx != SHN_SUNW_IGNORE) { 1411 rsym.st_shndx = SHN_SUNW_IGNORE; 1412 (void) gelf_update_sym(data_sym, ndx, &rsym); 1413 } | 1524 if (rsym.st_shndx != SHN_SUNW_IGNORE) { 1525 rsym.st_shndx = SHN_SUNW_IGNORE; 1526 (void) gelf_update_sym(data_sym, ndx, &rsym); 1527 } |
1528#endif |
|
1414 } 1415 } 1416 1417 if (mod && elf_update(elf, ELF_C_WRITE) == -1) 1418 goto err; 1419 1420 (void) elf_end(elf); 1421 (void) close(fd); --- 11 unchanged lines hidden (view full) --- 1433 return (dt_link_error(dtp, elf, fd, bufs, 1434 "an error was encountered while processing %s", obj)); 1435} 1436 1437int 1438dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, 1439 const char *file, int objc, char *const objv[]) 1440{ | 1529 } 1530 } 1531 1532 if (mod && elf_update(elf, ELF_C_WRITE) == -1) 1533 goto err; 1534 1535 (void) elf_end(elf); 1536 (void) close(fd); --- 11 unchanged lines hidden (view full) --- 1548 return (dt_link_error(dtp, elf, fd, bufs, 1549 "an error was encountered while processing %s", obj)); 1550} 1551 1552int 1553dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, 1554 const char *file, int objc, char *const objv[]) 1555{ |
1556#if !defined(sun) 1557 char tfile[PATH_MAX]; 1558#endif |
|
1441 char drti[PATH_MAX]; 1442 dof_hdr_t *dof; 1443 int fd, status, i, cur; 1444 char *cmd, tmp; 1445 size_t len; 1446 int eprobes = 0, ret = 0; 1447 | 1559 char drti[PATH_MAX]; 1560 dof_hdr_t *dof; 1561 int fd, status, i, cur; 1562 char *cmd, tmp; 1563 size_t len; 1564 int eprobes = 0, ret = 0; 1565 |
1566#if !defined(sun) 1567 /* XXX Should get a temp file name here. */ 1568 snprintf(tfile, sizeof(tfile), "%s.tmp", file); 1569#endif 1570 |
|
1448 /* 1449 * A NULL program indicates a special use in which we just link 1450 * together a bunch of object files specified in objv and then 1451 * unlink(2) those object files. 1452 */ 1453 if (pgp == NULL) { 1454 const char *fmt = "%s -o %s -r"; 1455 --- 45 unchanged lines hidden (view full) --- 1501 * version 2. 1502 */ 1503 if (eprobes && pgp->dp_dofversion < DOF_VERSION_2) 1504 pgp->dp_dofversion = DOF_VERSION_2; 1505 1506 if ((dof = dtrace_dof_create(dtp, pgp, dflags)) == NULL) 1507 return (-1); /* errno is set for us */ 1508 | 1571 /* 1572 * A NULL program indicates a special use in which we just link 1573 * together a bunch of object files specified in objv and then 1574 * unlink(2) those object files. 1575 */ 1576 if (pgp == NULL) { 1577 const char *fmt = "%s -o %s -r"; 1578 --- 45 unchanged lines hidden (view full) --- 1624 * version 2. 1625 */ 1626 if (eprobes && pgp->dp_dofversion < DOF_VERSION_2) 1627 pgp->dp_dofversion = DOF_VERSION_2; 1628 1629 if ((dof = dtrace_dof_create(dtp, pgp, dflags)) == NULL) 1630 return (-1); /* errno is set for us */ 1631 |
1632#if defined(sun) |
|
1509 /* 1510 * Create a temporary file and then unlink it if we're going to 1511 * combine it with drti.o later. We can still refer to it in child 1512 * processes as /dev/fd/<fd>. 1513 */ 1514 if ((fd = open64(file, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) { 1515 return (dt_link_error(dtp, NULL, -1, NULL, 1516 "failed to open %s: %s", file, strerror(errno))); 1517 } | 1633 /* 1634 * Create a temporary file and then unlink it if we're going to 1635 * combine it with drti.o later. We can still refer to it in child 1636 * processes as /dev/fd/<fd>. 1637 */ 1638 if ((fd = open64(file, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) { 1639 return (dt_link_error(dtp, NULL, -1, NULL, 1640 "failed to open %s: %s", file, strerror(errno))); 1641 } |
1642#else 1643 if ((fd = open(tfile, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) 1644 return (dt_link_error(dtp, NULL, -1, NULL, 1645 "failed to open %s: %s", tfile, strerror(errno))); 1646#endif |
|
1518 1519 /* 1520 * If -xlinktype=DOF has been selected, just write out the DOF. 1521 * Otherwise proceed to the default of generating and linking ELF. 1522 */ 1523 switch (dtp->dt_linktype) { 1524 case DT_LTYP_DOF: 1525 if (dt_write(dtp, fd, dof, dof->dofh_filesz) < dof->dofh_filesz) --- 13 unchanged lines hidden (view full) --- 1539 break; /* fall through to the rest of dtrace_program_link() */ 1540 1541 default: 1542 return (dt_link_error(dtp, NULL, -1, NULL, 1543 "invalid link type %u\n", dtp->dt_linktype)); 1544 } 1545 1546 | 1647 1648 /* 1649 * If -xlinktype=DOF has been selected, just write out the DOF. 1650 * Otherwise proceed to the default of generating and linking ELF. 1651 */ 1652 switch (dtp->dt_linktype) { 1653 case DT_LTYP_DOF: 1654 if (dt_write(dtp, fd, dof, dof->dofh_filesz) < dof->dofh_filesz) --- 13 unchanged lines hidden (view full) --- 1668 break; /* fall through to the rest of dtrace_program_link() */ 1669 1670 default: 1671 return (dt_link_error(dtp, NULL, -1, NULL, 1672 "invalid link type %u\n", dtp->dt_linktype)); 1673 } 1674 1675 |
1676#if defined(sun) |
|
1547 if (!dtp->dt_lazyload) 1548 (void) unlink(file); | 1677 if (!dtp->dt_lazyload) 1678 (void) unlink(file); |
1679#endif |
|
1549 1550 if (dtp->dt_oflags & DTRACE_O_LP64) 1551 status = dump_elf64(dtp, dof, fd); 1552 else 1553 status = dump_elf32(dtp, dof, fd); 1554 1555 if (status != 0 || lseek(fd, 0, SEEK_SET) != 0) { 1556 return (dt_link_error(dtp, NULL, -1, NULL, 1557 "failed to write %s: %s", file, strerror(errno))); 1558 } 1559 1560 if (!dtp->dt_lazyload) { | 1680 1681 if (dtp->dt_oflags & DTRACE_O_LP64) 1682 status = dump_elf64(dtp, dof, fd); 1683 else 1684 status = dump_elf32(dtp, dof, fd); 1685 1686 if (status != 0 || lseek(fd, 0, SEEK_SET) != 0) { 1687 return (dt_link_error(dtp, NULL, -1, NULL, 1688 "failed to write %s: %s", file, strerror(errno))); 1689 } 1690 1691 if (!dtp->dt_lazyload) { |
1692#if defined(sun) |
|
1561 const char *fmt = "%s -o %s -r -Blocal -Breduce /dev/fd/%d %s"; 1562 1563 if (dtp->dt_oflags & DTRACE_O_LP64) { 1564 (void) snprintf(drti, sizeof (drti), 1565 "%s/64/drti.o", _dtrace_libdir); 1566 } else { 1567 (void) snprintf(drti, sizeof (drti), 1568 "%s/drti.o", _dtrace_libdir); 1569 } 1570 1571 len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, fd, 1572 drti) + 1; 1573 1574 cmd = alloca(len); 1575 1576 (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, fd, drti); | 1693 const char *fmt = "%s -o %s -r -Blocal -Breduce /dev/fd/%d %s"; 1694 1695 if (dtp->dt_oflags & DTRACE_O_LP64) { 1696 (void) snprintf(drti, sizeof (drti), 1697 "%s/64/drti.o", _dtrace_libdir); 1698 } else { 1699 (void) snprintf(drti, sizeof (drti), 1700 "%s/drti.o", _dtrace_libdir); 1701 } 1702 1703 len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, fd, 1704 drti) + 1; 1705 1706 cmd = alloca(len); 1707 1708 (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, fd, drti); |
1709#else 1710 const char *fmt = "%s -o %s -r %s %s"; |
|
1577 | 1711 |
1712#if defined(__amd64__) 1713 /* 1714 * Arches which default to 64-bit need to explicitly use 1715 * the 32-bit library path. 1716 */ 1717 int use_32 = !(dtp->dt_oflags & DTRACE_O_LP64); 1718#else 1719 /* 1720 * Arches which are 32-bit only just use the normal 1721 * library path. 1722 */ 1723#if defined(__i386__) 1724 int use_32 = 1; /* use /usr/lib/... -sson */ 1725#else 1726 int use_32 = 0; 1727#endif 1728#endif 1729 1730 (void) snprintf(drti, sizeof (drti), "/usr/lib%s/dtrace/drti.o", 1731 use_32 ? "":"32"); 1732 1733 len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, tfile, 1734 drti) + 1; 1735 1736 cmd = alloca(len); 1737 1738 (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, tfile, drti); 1739#endif 1740 |
|
1578 if ((status = system(cmd)) == -1) { 1579 ret = dt_link_error(dtp, NULL, -1, NULL, 1580 "failed to run %s: %s", dtp->dt_ld_path, 1581 strerror(errno)); 1582 goto done; 1583 } 1584 1585 (void) close(fd); /* release temporary file */ --- 12 unchanged lines hidden (view full) --- 1598 goto done; 1599 } 1600 } else { 1601 (void) close(fd); 1602 } 1603 1604done: 1605 dtrace_dof_destroy(dtp, dof); | 1741 if ((status = system(cmd)) == -1) { 1742 ret = dt_link_error(dtp, NULL, -1, NULL, 1743 "failed to run %s: %s", dtp->dt_ld_path, 1744 strerror(errno)); 1745 goto done; 1746 } 1747 1748 (void) close(fd); /* release temporary file */ --- 12 unchanged lines hidden (view full) --- 1761 goto done; 1762 } 1763 } else { 1764 (void) close(fd); 1765 } 1766 1767done: 1768 dtrace_dof_destroy(dtp, dof); |
1769 1770#if !defined(sun) 1771 unlink(tfile); 1772#endif |
|
1606 return (ret); 1607} | 1773 return (ret); 1774} |