dt_link.c (178573) | dt_link.c (184696) |
---|---|
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 --- 854 unchanged lines hidden (view full) --- 863 */ 864 if (GELF_R_TYPE(rela->r_info) != R_SPARC_WDISP30 && 865 GELF_R_TYPE(rela->r_info) != R_SPARC_WPLT30) 866 return (-1); 867 868 /* 869 * We may have already processed this object file in an earlier linker 870 * invocation. Check to see if the present instruction sequence matches | 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 --- 854 unchanged lines hidden (view full) --- 863 */ 864 if (GELF_R_TYPE(rela->r_info) != R_SPARC_WDISP30 && 865 GELF_R_TYPE(rela->r_info) != R_SPARC_WPLT30) 866 return (-1); 867 868 /* 869 * We may have already processed this object file in an earlier linker 870 * invocation. Check to see if the present instruction sequence matches |
871 * the one we would install. | 871 * the one we would install below. |
872 */ 873 if (isenabled) { | 872 */ 873 if (isenabled) { |
874 if (ip[0] == DT_OP_CLR_O0) | 874 if (ip[0] == DT_OP_NOP) { 875 (*off) += sizeof (ip[0]); |
875 return (0); | 876 return (0); |
877 } |
|
876 } else { 877 if (DT_IS_RESTORE(ip[1])) { | 878 } else { 879 if (DT_IS_RESTORE(ip[1])) { |
878 if (ip[0] == DT_OP_RET) | 880 if (ip[0] == DT_OP_RET) { 881 (*off) += sizeof (ip[0]); |
879 return (0); | 882 return (0); |
883 } |
|
880 } else if (DT_IS_MOV_O7(ip[1])) { 881 if (DT_IS_RETL(ip[0])) 882 return (0); 883 } else { 884 if (ip[0] == DT_OP_NOP) { 885 (*off) += sizeof (ip[0]); 886 return (0); 887 } --- 17 unchanged lines hidden (view full) --- 905 * but could be done if this were a desired use scenario. 906 */ 907 if (DT_IS_RESTORE(ip[1]) || DT_IS_MOV_O7(ip[1])) { 908 dt_dprintf("tail call to is-enabled probe at %llx\n", 909 (u_longlong_t)rela->r_offset); 910 return (-1); 911 } 912 | 884 } else if (DT_IS_MOV_O7(ip[1])) { 885 if (DT_IS_RETL(ip[0])) 886 return (0); 887 } else { 888 if (ip[0] == DT_OP_NOP) { 889 (*off) += sizeof (ip[0]); 890 return (0); 891 } --- 17 unchanged lines hidden (view full) --- 909 * but could be done if this were a desired use scenario. 910 */ 911 if (DT_IS_RESTORE(ip[1]) || DT_IS_MOV_O7(ip[1])) { 912 dt_dprintf("tail call to is-enabled probe at %llx\n", 913 (u_longlong_t)rela->r_offset); 914 return (-1); 915 } 916 |
913 ip[0] = DT_OP_CLR_O0; | 917 918 /* 919 * On SPARC, we take advantage of the fact that the first 920 * argument shares the same register as for the return value. 921 * The macro handles the work of zeroing that register so we 922 * don't need to do anything special here. We instrument the 923 * instruction in the delay slot as we'll need to modify the 924 * return register after that instruction has been emulated. 925 */ 926 ip[0] = DT_OP_NOP; 927 (*off) += sizeof (ip[0]); |
914 } else { 915 /* 916 * If the call is followed by a restore, it's a tail call so 917 * change the call to a ret. If the call if followed by a mov 918 * of a register into %o7, it's a tail call in leaf context 919 * so change the call to a retl-like instruction that returns 920 * to that register value + 8 (rather than the typical %o7 + 921 * 8); the delay slot instruction is left, but should have no | 928 } else { 929 /* 930 * If the call is followed by a restore, it's a tail call so 931 * change the call to a ret. If the call if followed by a mov 932 * of a register into %o7, it's a tail call in leaf context 933 * so change the call to a retl-like instruction that returns 934 * to that register value + 8 (rather than the typical %o7 + 935 * 8); the delay slot instruction is left, but should have no |
922 * effect. Otherwise we change the call to be a nop. In the 923 * first and the last case we adjust the offset to land on what 924 * was once the delay slot of the call so we correctly get all 925 * the arguments as they would have been passed in a normal 926 * function call. | 936 * effect. Otherwise we change the call to be a nop. We 937 * identify the subsequent instruction as the probe point in 938 * all but the leaf tail-call case to ensure that arguments to 939 * the probe are complete and consistent. An astute, though 940 * largely hypothetical, observer would note that there is the 941 * possibility of a false-positive probe firing if the function 942 * contained a branch to the instruction in the delay slot of 943 * the call. Fixing this would require significant in-kernel 944 * modifications, and isn't worth doing until we see it in the 945 * wild. |
927 */ 928 if (DT_IS_RESTORE(ip[1])) { 929 ip[0] = DT_OP_RET; 930 (*off) += sizeof (ip[0]); 931 } else if (DT_IS_MOV_O7(ip[1])) { 932 ip[0] = DT_MAKE_RETL(DT_RS2(ip[1])); 933 } else { 934 ip[0] = DT_OP_NOP; --- 840 unchanged lines hidden --- | 946 */ 947 if (DT_IS_RESTORE(ip[1])) { 948 ip[0] = DT_OP_RET; 949 (*off) += sizeof (ip[0]); 950 } else if (DT_IS_MOV_O7(ip[1])) { 951 ip[0] = DT_MAKE_RETL(DT_RS2(ip[1])); 952 } else { 953 ip[0] = DT_OP_NOP; --- 840 unchanged lines hidden --- |