Deleted Added
full compact
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}