7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
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 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 *
26 * Copyright 2018 Jason King
27 */
28
29 #include <ctype.h>
30 #include <string.h>
31 #include <sys/param.h>
32 #include <stdlib.h>
33 #include "conv.h"
34 #include "gprof.h"
35
36 void print_demangled_name(int, nltype *);
37 void striped_name(char *, nltype **);
38
39 extern long hz;
40
41 /*
42 * Symbols that must never be printed, no matter what.
43 */
44 char *splsym[] = {
45 PRF_ETEXT,
46 PRF_EXTSYM,
47 PRF_MEMTERM,
48 NULL
49 };
50
51 static bool is_special_sym(nltype *nlp);
52
53 const char *
54 demangled_name(nltype *selfp)
55 {
56 if (!Cflag)
57 return (selfp->name);
844 }
845
846 void
847 printblurb(char *blurbname)
848 {
849 FILE *blurbfile;
850 int input;
851
852 blurbfile = fopen(blurbname, "r");
853 if (blurbfile == NULL) {
854 perror(blurbname);
855 return;
856 }
857
858 while ((input = getc(blurbfile)) != EOF)
859 (void) putchar(input);
860
861 (void) fclose(blurbfile);
862 }
863
864 char *s1, *s2;
865
866 static int
867 namecmp(const void *arg1, const void *arg2)
868 {
869 nltype **npp1 = (nltype **)arg1;
870 nltype **npp2 = (nltype **)arg2;
871
872 if (!Cflag)
873 return (strcmp((*npp1)->name, (*npp2)->name));
874 else {
875 striped_name(s1, npp1);
876 striped_name(s2, npp2);
877 return (strcmp(s1, s2));
878 }
879 }
880
881 void
882 striped_name(char *s, nltype **npp)
883 {
884 const char *name, *d;
885 char *c;
886
887 c = (char *)s;
888 name = d = demangled_name(*npp);
889
890 while ((*d != '(') && (*d != '\0')) {
891 if (*d != ':')
892 *c++ = *d++;
893 else
894 d++;
895 }
896 *c = '\0';
897
898 if ((*npp)->name != name)
899 free((void *)name);
900 }
901
902 /*
903 * Checks if the current symbol name is the same as its neighbour and
904 * returns TRUE if it is.
905 */
906 static bool
907 does_clash(nltype **nlp, int ndx, int nnames)
908 {
957
958 nnames = 0;
959 for (mi = &modules; mi; mi = mi->next) {
960 for (index = 0; index < mi->nname; index++) {
961 if (zflag == 0 && (mi->nl[index]).ncall == 0 &&
962 (mi->nl[index]).time == 0) {
963 continue;
964 }
965
966 /*
967 * Do not print certain special symbols, like
968 * PRF_EXTSYM, etc. even if zflag was on.
969 */
970 if (is_special_sym(&(mi->nl[index])))
971 continue;
972
973 namesortnlp[nnames++] = &(mi->nl[index]);
974 }
975 }
976
977 if (Cflag) {
978 s1 = malloc(500 * sizeof (char));
979 s2 = malloc(500 * sizeof (char));
980 }
981
982 qsort(namesortnlp, nnames, sizeof (nltype *), namecmp);
983
984 for (index = 1, todo = nnames; index <= ncycle; index++)
985 namesortnlp[todo++] = &cyclenl[index];
986
987 (void) printf("\f\nIndex by function name\n\n");
988
989 if (!Cflag)
990 index = (todo + 2) / 3;
991 else
992 index = todo;
993
994 for (i = 0; i < index; i++) {
995 if (!Cflag) {
996 for (j = i; j < todo; j += index) {
997 nlp = namesortnlp[j];
998
999 if (nlp->printflag) {
1000 (void) sprintf(peterbuffer,
1001 "[%d]", nlp->index);
|
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
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 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 *
26 * Copyright 2018 Jason King
27 * Copyright 2018, Joyent, Inc.
28 */
29
30 #include <ctype.h>
31 #include <string.h>
32 #include <sys/param.h>
33 #include <stdlib.h>
34 #include "conv.h"
35 #include "gprof.h"
36
37 void print_demangled_name(int, nltype *);
38 static void stripped_name(char **, size_t *, nltype **);
39
40 extern long hz;
41
42 /*
43 * Symbols that must never be printed, no matter what.
44 */
45 char *splsym[] = {
46 PRF_ETEXT,
47 PRF_EXTSYM,
48 PRF_MEMTERM,
49 NULL
50 };
51
52 static bool is_special_sym(nltype *nlp);
53
54 const char *
55 demangled_name(nltype *selfp)
56 {
57 if (!Cflag)
58 return (selfp->name);
845 }
846
847 void
848 printblurb(char *blurbname)
849 {
850 FILE *blurbfile;
851 int input;
852
853 blurbfile = fopen(blurbname, "r");
854 if (blurbfile == NULL) {
855 perror(blurbname);
856 return;
857 }
858
859 while ((input = getc(blurbfile)) != EOF)
860 (void) putchar(input);
861
862 (void) fclose(blurbfile);
863 }
864
865 static int
866 namecmp(const void *arg1, const void *arg2)
867 {
868 nltype **npp1 = (nltype **)arg1;
869 nltype **npp2 = (nltype **)arg2;
870
871 if (!Cflag)
872 return (strcmp((*npp1)->name, (*npp2)->name));
873 else {
874 static char *s1 = NULL, *s2 = NULL;
875 static size_t s1len = 0, s2len = 0;
876
877 stripped_name(&s1, &s1len, npp1);
878 stripped_name(&s2, &s2len, npp2);
879 return (strcmp(s1, s2));
880 }
881 }
882
883 #define NAME_CHUNK 512
884 #define ROUNDLEN(x) (((x) + NAME_CHUNK - 1) / NAME_CHUNK * NAME_CHUNK)
885 static void
886 adjust_size(char **pp, size_t *lenp, const char *name)
887 {
888 void *newp;
889 size_t nlen = strlen(name);
890 size_t buflen;
891
892 if (*lenp > nlen) {
893 (void) memset(*pp, '\0', *lenp);
894 return;
895 }
896
897 buflen = ROUNDLEN(nlen + 1);
898 if ((newp = realloc(*pp, buflen)) == NULL) {
899 (void) fprintf(stderr,
900 "gprof: out of memory comparing names\n");
901 exit(EXIT_FAILURE);
902 }
903 (void) memset(newp, '\0', buflen);
904
905 *lenp = buflen;
906 *pp = newp;
907 }
908
909 static void
910 stripped_name(char **sp, size_t *slenp, nltype **npp)
911 {
912 const char *name, *d;
913 char *c;
914
915 name = d = demangled_name(*npp);
916 adjust_size(sp, slenp, name);
917 c = *sp;
918
919 while ((*d != '(') && (*d != '\0')) {
920 if (*d != ':')
921 *c++ = *d++;
922 else
923 d++;
924 }
925 *c = '\0';
926
927 if ((*npp)->name != name)
928 free((void *)name);
929 }
930
931 /*
932 * Checks if the current symbol name is the same as its neighbour and
933 * returns TRUE if it is.
934 */
935 static bool
936 does_clash(nltype **nlp, int ndx, int nnames)
937 {
986
987 nnames = 0;
988 for (mi = &modules; mi; mi = mi->next) {
989 for (index = 0; index < mi->nname; index++) {
990 if (zflag == 0 && (mi->nl[index]).ncall == 0 &&
991 (mi->nl[index]).time == 0) {
992 continue;
993 }
994
995 /*
996 * Do not print certain special symbols, like
997 * PRF_EXTSYM, etc. even if zflag was on.
998 */
999 if (is_special_sym(&(mi->nl[index])))
1000 continue;
1001
1002 namesortnlp[nnames++] = &(mi->nl[index]);
1003 }
1004 }
1005
1006 qsort(namesortnlp, nnames, sizeof (nltype *), namecmp);
1007
1008 for (index = 1, todo = nnames; index <= ncycle; index++)
1009 namesortnlp[todo++] = &cyclenl[index];
1010
1011 (void) printf("\f\nIndex by function name\n\n");
1012
1013 if (!Cflag)
1014 index = (todo + 2) / 3;
1015 else
1016 index = todo;
1017
1018 for (i = 0; i < index; i++) {
1019 if (!Cflag) {
1020 for (j = i; j < todo; j += index) {
1021 nlp = namesortnlp[j];
1022
1023 if (nlp->printflag) {
1024 (void) sprintf(peterbuffer,
1025 "[%d]", nlp->index);
|