diff options
author | jb <jb@FreeBSD.org> | 2008-04-26 00:54:52 +0000 |
---|---|---|
committer | jb <jb@FreeBSD.org> | 2008-04-26 00:54:52 +0000 |
commit | 52c14c7a3f5fbfa9c707a6206668a1eaa6c77a50 (patch) | |
tree | c98db398653c7c531756a3578af91819cb574281 /cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c | |
parent | cb8ce777270daa16660da8e87ef6a11d5bc5408f (diff) | |
download | FreeBSD-src-52c14c7a3f5fbfa9c707a6206668a1eaa6c77a50.zip FreeBSD-src-52c14c7a3f5fbfa9c707a6206668a1eaa6c77a50.tar.gz |
Vendor import of the full userland contrib part of DTrace support from
OpenSolaris. This commit resets files to match the versions in the
OpenSolaris tree as of 2008/04/10.
The changes in this import from the previous import are the ones that
will subsequently re-applied to take files off the vendor branch. This
is unfortunately necessary because the Solaris developers won't allow
FreeBSD support #ifdefs in their source code because that creates
'dead code' (stuff that they never compile).
Diffstat (limited to 'cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c')
-rw-r--r-- | cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c | 221 |
1 files changed, 27 insertions, 194 deletions
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c index bc46df5..957d8f8 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,28 +30,18 @@ #include <elf.h> #include <sys/types.h> -#if defined(sun) #include <sys/sysmacros.h> -#else -#define P2ROUNDUP(x, align) (-(-(x) & -(align))) -#endif #include <unistd.h> #include <strings.h> -#if defined(sun) #include <alloca.h> -#endif #include <limits.h> #include <stddef.h> #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <errno.h> -#if defined(sun) #include <wait.h> -#else -#include <sys/wait.h> -#endif #include <assert.h> #include <sys/ipc.h> @@ -224,23 +214,11 @@ prepare_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf32_t *dep) s = &dofs[dofrh->dofr_tgtsec]; for (j = 0; j < nrel; j++) { -#if defined(__arm__) -/* XXX */ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); -#elif defined(__ia64__) -/* XXX */ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); -#elif defined(__i386) || defined(__amd64) +#if defined(__i386) || defined(__amd64) rel->r_offset = s->dofs_offset + dofr[j].dofr_offset; rel->r_info = ELF32_R_INFO(count + dep->de_global, R_386_32); -#elif defined(__mips__) -/* XXX */ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); -#elif defined(__powerpc__) -/* XXX */ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); #elif defined(__sparc) /* * Add 4 bytes to hit the low half of this 64-bit @@ -412,17 +390,7 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep) s = &dofs[dofrh->dofr_tgtsec]; for (j = 0; j < nrel; j++) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); -#ifdef DOODAD -#if defined(__arm__) -/* XXX */ -#elif defined(__ia64__) -/* XXX */ -#elif defined(__mips__) -/* XXX */ -#elif defined(__powerpc__) -/* XXX */ -#elif defined(__i386) || defined(__amd64) +#if defined(__i386) || defined(__amd64) rel->r_offset = s->dofs_offset + dofr[j].dofr_offset; rel->r_info = ELF64_R_INFO(count + dep->de_global, @@ -435,7 +403,6 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); #else #error unknown ISA #endif -#endif sym->st_name = base + dofr[j].dofr_name - 1; sym->st_value = 0; @@ -513,24 +480,13 @@ dump_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd) elf_file.ehdr.e_ident[EI_MAG3] = ELFMAG3; elf_file.ehdr.e_ident[EI_VERSION] = EV_CURRENT; elf_file.ehdr.e_ident[EI_CLASS] = ELFCLASS32; -#if BYTE_ORDER == _BIG_ENDIAN +#if defined(_BIG_ENDIAN) elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2MSB; -#else +#elif defined(_LITTLE_ENDIAN) elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2LSB; #endif -#if defined(__FreeBSD__) - elf_file.ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; -#endif elf_file.ehdr.e_type = ET_REL; -#if defined(__arm__) - elf_file.ehdr.e_machine = EM_ARM; -#elif defined(__ia64__) - elf_file.ehdr.e_machine = EM_IA_64; -#elif defined(__mips__) - elf_file.ehdr.e_machine = EM_MIPS; -#elif defined(__powerpc__) - elf_file.ehdr.e_machine = EM_PPC; -#elif defined(__sparc) +#if defined(__sparc) elf_file.ehdr.e_machine = EM_SPARC; #elif defined(__i386) || defined(__amd64) elf_file.ehdr.e_machine = EM_386; @@ -661,24 +617,13 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd) elf_file.ehdr.e_ident[EI_MAG3] = ELFMAG3; elf_file.ehdr.e_ident[EI_VERSION] = EV_CURRENT; elf_file.ehdr.e_ident[EI_CLASS] = ELFCLASS64; -#if BYTE_ORDER == _BIG_ENDIAN +#if defined(_BIG_ENDIAN) elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2MSB; -#else +#elif defined(_LITTLE_ENDIAN) elf_file.ehdr.e_ident[EI_DATA] = ELFDATA2LSB; #endif -#if defined(__FreeBSD__) - elf_file.ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; -#endif elf_file.ehdr.e_type = ET_REL; -#if defined(__arm__) - elf_file.ehdr.e_machine = EM_ARM; -#elif defined(__ia64__) - elf_file.ehdr.e_machine = EM_IA_64; -#elif defined(__mips__) - elf_file.ehdr.e_machine = EM_MIPS; -#elif defined(__powerpc__) - elf_file.ehdr.e_machine = EM_PPC; -#elif defined(__sparc) +#if defined(__sparc) elf_file.ehdr.e_machine = EM_SPARCV9; #elif defined(__i386) || defined(__amd64) elf_file.ehdr.e_machine = EM_AMD64; @@ -794,44 +739,7 @@ dt_symtab_lookup(Elf_Data *data_sym, int nsym, uintptr_t addr, uint_t shn, return (ret); } -#if defined(__arm__) -/* XXX */ -static int -dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, - uint32_t *off) -{ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); - return (0); -} -#elif defined(__ia64__) -/* XXX */ -static int -dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, - uint32_t *off) -{ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); - return (0); -} -#elif defined(__mips__) -/* XXX */ -static int -dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, - uint32_t *off) -{ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); - return (0); -} -#elif defined(__powerpc__) -/* XXX */ -static int -dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, - uint32_t *off) -{ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); - return (0); -} - -#elif defined(__sparc) +#if defined(__sparc) #define DT_OP_RET 0x81c7e008 #define DT_OP_NOP 0x01000000 @@ -942,9 +850,7 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, #elif defined(__i386) || defined(__amd64) #define DT_OP_NOP 0x90 -#define DT_OP_RET 0xc3 #define DT_OP_CALL 0xe8 -#define DT_OP_JMP32 0xe9 #define DT_OP_REX_RAX 0x48 #define DT_OP_XOR_EAX_0 0x33 #define DT_OP_XOR_EAX_1 0xc0 @@ -954,7 +860,6 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, uint32_t *off) { uint8_t *ip = (uint8_t *)(p + rela->r_offset - 1); - uint8_t ret; /* * On x86, the first byte of the instruction is the call opcode and @@ -978,43 +883,38 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, * We may have already processed this object file in an earlier linker * invocation. Check to see if the present instruction sequence matches * the one we would install. For is-enabled probes, we advance the - * offset to the first nop instruction in the sequence to match the - * text modification code below. + * offset to the first nop instruction in the sequence. */ if (!isenabled) { - if ((ip[0] == DT_OP_NOP || ip[0] == DT_OP_RET) && - ip[1] == DT_OP_NOP && ip[2] == DT_OP_NOP && - ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP) + if (ip[0] == DT_OP_NOP && ip[1] == DT_OP_NOP && + ip[2] == DT_OP_NOP && ip[3] == DT_OP_NOP && + ip[4] == DT_OP_NOP) return (0); } else if (dtp->dt_oflags & DTRACE_O_LP64) { if (ip[0] == DT_OP_REX_RAX && ip[1] == DT_OP_XOR_EAX_0 && ip[2] == DT_OP_XOR_EAX_1 && - (ip[3] == DT_OP_NOP || ip[3] == DT_OP_RET) && - ip[4] == DT_OP_NOP) { + ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP) { (*off) += 3; return (0); } } else { if (ip[0] == DT_OP_XOR_EAX_0 && ip[1] == DT_OP_XOR_EAX_1 && - (ip[2] == DT_OP_NOP || ip[2] == DT_OP_RET) && - ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP) { + ip[2] == DT_OP_NOP && ip[3] == DT_OP_NOP && + ip[4] == DT_OP_NOP) { (*off) += 2; return (0); } } /* - * We expect either a call instrution with a 32-bit displacement or a - * jmp instruction with a 32-bit displacement acting as a tail-call. + * We only expect a call instrution with a 32-bit displacement. */ - if (ip[0] != DT_OP_CALL && ip[0] != DT_OP_JMP32) { - dt_dprintf("found %x instead of a call or jmp instruction at " - "%llx\n", ip[0], (u_longlong_t)rela->r_offset); + if (ip[0] != DT_OP_CALL) { + dt_dprintf("found %x instead of a call instruction at %llx\n", + ip[0], (u_longlong_t)rela->r_offset); return (-1); } - ret = (ip[0] == DT_OP_JMP32) ? DT_OP_RET : DT_OP_NOP; - /* * Establish the instruction sequence -- all nops for probes, and an * instruction to clear the return value register (%eax/%rax) followed @@ -1023,7 +923,7 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, * for more readable disassembly when the probe is enabled. */ if (!isenabled) { - ip[0] = ret; + ip[0] = DT_OP_NOP; ip[1] = DT_OP_NOP; ip[2] = DT_OP_NOP; ip[3] = DT_OP_NOP; @@ -1032,13 +932,13 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela, ip[0] = DT_OP_REX_RAX; ip[1] = DT_OP_XOR_EAX_0; ip[2] = DT_OP_XOR_EAX_1; - ip[3] = ret; + ip[3] = DT_OP_NOP; ip[4] = DT_OP_NOP; (*off) += 3; } else { ip[0] = DT_OP_XOR_EAX_0; ip[1] = DT_OP_XOR_EAX_1; - ip[2] = ret; + ip[2] = DT_OP_NOP; ip[3] = DT_OP_NOP; ip[4] = DT_OP_NOP; (*off) += 2; @@ -1133,13 +1033,7 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) if (dtp->dt_oflags & DTRACE_O_LP64) { eclass = ELFCLASS64; -#if defined(__ia64__) - emachine1 = emachine2 = EM_IA_64; -#elif defined(__mips__) - emachine1 = emachine2 = EM_MIPS; -#elif defined(__powerpc__) - emachine1 = emachine2 = EM_PPC64; -#elif defined(__sparc) +#if defined(__sparc) emachine1 = emachine2 = EM_SPARCV9; #elif defined(__i386) || defined(__amd64) emachine1 = emachine2 = EM_AMD64; @@ -1147,16 +1041,10 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) symsize = sizeof (Elf64_Sym); } else { eclass = ELFCLASS32; -#if defined(__arm__) - emachine1 = emachine2 = EM_ARM; -#elif defined(__mips__) - emachine1 = emachine2 = EM_MIPS; -#elif defined(__powerpc__) - emachine1 = emachine2 = EM_PPC; -#elif defined(__sparc) +#if defined(__sparc) emachine1 = EM_SPARC; emachine2 = EM_SPARC32PLUS; -#elif defined(__i386) || defined(__amd64) || defined(__ia64__) +#elif defined(__i386) || defined(__amd64) emachine1 = emachine2 = EM_386; #endif symsize = sizeof (Elf32_Sym); @@ -1519,13 +1407,10 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) * already been processed by an earlier link * invocation. */ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); -#ifdef DOODAD if (rsym.st_shndx != SHN_SUNW_IGNORE) { rsym.st_shndx = SHN_SUNW_IGNORE; (void) gelf_update_sym(data_sym, ndx, &rsym); } -#endif } } @@ -1553,9 +1438,6 @@ int dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, const char *file, int objc, char *const objv[]) { -#if !defined(sun) - char tfile[PATH_MAX]; -#endif char drti[PATH_MAX]; dof_hdr_t *dof; int fd, status, i, cur; @@ -1563,11 +1445,6 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, size_t len; int eprobes = 0, ret = 0; -#if !defined(sun) - /* XXX Should get a temp file name here. */ - snprintf(tfile, sizeof(tfile), "%s.tmp", file); -#endif - /* * A NULL program indicates a special use in which we just link * together a bunch of object files specified in objv and then @@ -1629,7 +1506,6 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, if ((dof = dtrace_dof_create(dtp, pgp, dflags)) == NULL) return (-1); /* errno is set for us */ -#if defined(sun) /* * Create a temporary file and then unlink it if we're going to * combine it with drti.o later. We can still refer to it in child @@ -1639,11 +1515,6 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, return (dt_link_error(dtp, NULL, -1, NULL, "failed to open %s: %s", file, strerror(errno))); } -#else - if ((fd = open(tfile, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) - return (dt_link_error(dtp, NULL, -1, NULL, - "failed to open %s: %s", tfile, strerror(errno))); -#endif /* * If -xlinktype=DOF has been selected, just write out the DOF. @@ -1673,10 +1544,8 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, } -#if defined(sun) if (!dtp->dt_lazyload) (void) unlink(file); -#endif if (dtp->dt_oflags & DTRACE_O_LP64) status = dump_elf64(dtp, dof, fd); @@ -1689,7 +1558,6 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, } if (!dtp->dt_lazyload) { -#if defined(sun) const char *fmt = "%s -o %s -r -Blocal -Breduce /dev/fd/%d %s"; if (dtp->dt_oflags & DTRACE_O_LP64) { @@ -1706,37 +1574,6 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, cmd = alloca(len); (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, fd, drti); -#else - const char *fmt = "%s -o %s -r %s %s"; - -#if defined(__amd64__) - /* - * Arches which default to 64-bit need to explicitly use - * the 32-bit library path. - */ - int use_32 = !(dtp->dt_oflags & DTRACE_O_LP64); -#else - /* - * Arches which are 32-bit only just use the normal - * library path. - */ -#if defined(__i386__) - int use_32 = 1; /* use /usr/lib/... -sson */ -#else - int use_32 = 0; -#endif -#endif - - (void) snprintf(drti, sizeof (drti), "/usr/lib%s/dtrace/drti.o", - use_32 ? "":"32"); - - len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, tfile, - drti) + 1; - - cmd = alloca(len); - - (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, tfile, drti); -#endif if ((status = system(cmd)) == -1) { ret = dt_link_error(dtp, NULL, -1, NULL, @@ -1766,9 +1603,5 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, done: dtrace_dof_destroy(dtp, dof); - -#if !defined(sun) - unlink(tfile); -#endif return (ret); } |