]>
git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - tools/perf/util/srccode.c
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Manage printing of source lines
4 * Copyright (c) 2017, Intel Corporation.
7 #include "linux/list.h"
19 #define MAXSRCCACHE (32*1024*1024)
20 #define MAXSRCFILES 64
21 #define SRC_HTAB_SZ 64
24 struct hlist_node hash_nd
;
33 static struct hlist_head srcfile_htab
[SRC_HTAB_SZ
];
34 static LIST_HEAD(srcfile_list
);
35 static long map_total_sz
;
36 static int num_srcfiles
;
38 static unsigned shash(unsigned char *s
)
46 static int countlines(char *map
, int maplen
)
49 char *end
= map
+ maplen
;
55 while (p
< end
&& (p
= memchr(p
, '\n', end
- p
)) != NULL
) {
64 static void fill_lines(char **lines
, int maxline
, char *map
, int maplen
)
67 char *end
= map
+ maplen
;
70 if (maplen
== 0 || maxline
== 0)
74 while (p
< end
&& (p
= memchr(p
, '\n', end
- p
)) != NULL
) {
83 static void free_srcfile(struct srcfile
*sf
)
86 hlist_del(&sf
->hash_nd
);
87 map_total_sz
-= sf
->maplen
;
88 munmap(sf
->map
, sf
->maplen
);
95 static struct srcfile
*find_srcfile(char *fn
)
101 unsigned hval
= shash((unsigned char *)fn
) % SRC_HTAB_SZ
;
103 hlist_for_each_entry (h
, &srcfile_htab
[hval
], hash_nd
) {
104 if (!strcmp(fn
, h
->fn
)) {
107 list_add(&h
->nd
, &srcfile_list
);
112 /* Only prune if there is more than one entry */
113 while ((num_srcfiles
> MAXSRCFILES
|| map_total_sz
> MAXSRCCACHE
) &&
114 srcfile_list
.next
!= &srcfile_list
) {
115 assert(!list_empty(&srcfile_list
));
116 h
= list_entry(srcfile_list
.prev
, struct srcfile
, nd
);
120 fd
= open(fn
, O_RDONLY
);
121 if (fd
< 0 || fstat(fd
, &st
) < 0) {
122 pr_debug("cannot open source file %s\n", fn
);
126 h
= malloc(sizeof(struct srcfile
));
134 h
->maplen
= st
.st_size
;
135 sz
= (h
->maplen
+ page_size
- 1) & ~(page_size
- 1);
136 h
->map
= mmap(NULL
, sz
, PROT_READ
, MAP_SHARED
, fd
, 0);
138 if (h
->map
== (char *)-1) {
139 pr_debug("cannot mmap source file %s\n", fn
);
142 h
->numlines
= countlines(h
->map
, h
->maplen
);
143 h
->lines
= calloc(h
->numlines
, sizeof(char *));
146 fill_lines(h
->lines
, h
->numlines
, h
->map
, h
->maplen
);
147 list_add(&h
->nd
, &srcfile_list
);
148 hlist_add_head(&h
->hash_nd
, &srcfile_htab
[hval
]);
149 map_total_sz
+= h
->maplen
;
162 /* Result is not 0 terminated */
163 char *find_sourceline(char *fn
, unsigned line
, int *lenp
)
166 struct srcfile
*sf
= find_srcfile(fn
);
170 if (line
>= sf
->numlines
)
175 p
= memchr(l
, '\n', sf
->map
+ sf
->maplen
- l
);