xref: /src/contrib/processor-trace/libipt/internal/include/pt_image_section_cache.h (revision 85f87cf491bec6f90948a85b10f5523ea24db9e3)
1766f5c51SRuslan Bukin /*
285f87cf4SRuslan Bukin  * Copyright (c) 2016-2019, Intel Corporation
3766f5c51SRuslan Bukin  *
4766f5c51SRuslan Bukin  * Redistribution and use in source and binary forms, with or without
5766f5c51SRuslan Bukin  * modification, are permitted provided that the following conditions are met:
6766f5c51SRuslan Bukin  *
7766f5c51SRuslan Bukin  *  * Redistributions of source code must retain the above copyright notice,
8766f5c51SRuslan Bukin  *    this list of conditions and the following disclaimer.
9766f5c51SRuslan Bukin  *  * Redistributions in binary form must reproduce the above copyright notice,
10766f5c51SRuslan Bukin  *    this list of conditions and the following disclaimer in the documentation
11766f5c51SRuslan Bukin  *    and/or other materials provided with the distribution.
12766f5c51SRuslan Bukin  *  * Neither the name of Intel Corporation nor the names of its contributors
13766f5c51SRuslan Bukin  *    may be used to endorse or promote products derived from this software
14766f5c51SRuslan Bukin  *    without specific prior written permission.
15766f5c51SRuslan Bukin  *
16766f5c51SRuslan Bukin  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17766f5c51SRuslan Bukin  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18766f5c51SRuslan Bukin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19766f5c51SRuslan Bukin  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20766f5c51SRuslan Bukin  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21766f5c51SRuslan Bukin  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22766f5c51SRuslan Bukin  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23766f5c51SRuslan Bukin  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24766f5c51SRuslan Bukin  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25766f5c51SRuslan Bukin  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26766f5c51SRuslan Bukin  * POSSIBILITY OF SUCH DAMAGE.
27766f5c51SRuslan Bukin  */
28766f5c51SRuslan Bukin 
29766f5c51SRuslan Bukin #ifndef PT_IMAGE_SECTION_CACHE_H
30766f5c51SRuslan Bukin #define PT_IMAGE_SECTION_CACHE_H
31766f5c51SRuslan Bukin 
32766f5c51SRuslan Bukin #include <stdint.h>
33766f5c51SRuslan Bukin 
34766f5c51SRuslan Bukin #if defined(FEATURE_THREADS)
35766f5c51SRuslan Bukin #  include <threads.h>
36766f5c51SRuslan Bukin #endif /* defined(FEATURE_THREADS) */
37766f5c51SRuslan Bukin 
38766f5c51SRuslan Bukin struct pt_section;
39766f5c51SRuslan Bukin 
40766f5c51SRuslan Bukin 
41766f5c51SRuslan Bukin /* An image section cache entry. */
42766f5c51SRuslan Bukin struct pt_iscache_entry {
43766f5c51SRuslan Bukin 	/* The section object.
44766f5c51SRuslan Bukin 	 *
45766f5c51SRuslan Bukin 	 * We hold a reference to the section - put it when the section is
46766f5c51SRuslan Bukin 	 * removed from the cache.
47766f5c51SRuslan Bukin 	 */
48766f5c51SRuslan Bukin 	struct pt_section *section;
49766f5c51SRuslan Bukin 
50766f5c51SRuslan Bukin 	/* The base address at which @section has been loaded. */
51766f5c51SRuslan Bukin 	uint64_t laddr;
52766f5c51SRuslan Bukin };
53766f5c51SRuslan Bukin 
54766f5c51SRuslan Bukin /* An image section cache least recently used cache entry. */
55766f5c51SRuslan Bukin struct pt_iscache_lru_entry {
56766f5c51SRuslan Bukin 	/* The next entry in a list ordered by recent use. */
57766f5c51SRuslan Bukin 	struct pt_iscache_lru_entry *next;
58766f5c51SRuslan Bukin 
59766f5c51SRuslan Bukin 	/* The section mapped by the image section cache. */
60766f5c51SRuslan Bukin 	struct pt_section *section;
61766f5c51SRuslan Bukin 
62766f5c51SRuslan Bukin 	/* The amount of memory used by mapping @section in bytes. */
63766f5c51SRuslan Bukin 	uint64_t size;
64766f5c51SRuslan Bukin };
65766f5c51SRuslan Bukin 
66766f5c51SRuslan Bukin /* A cache of image sections and their load addresses.
67766f5c51SRuslan Bukin  *
68766f5c51SRuslan Bukin  * We combine the section with its load address to reduce the amount of
69766f5c51SRuslan Bukin  * information we need to store in order to read from a cached section by
70766f5c51SRuslan Bukin  * virtual address.
71766f5c51SRuslan Bukin  *
72766f5c51SRuslan Bukin  * Internally, the section object will be shared if it is loaded at different
73766f5c51SRuslan Bukin  * addresses in the cache.
74766f5c51SRuslan Bukin  *
75766f5c51SRuslan Bukin  * The cache does not consider the address-space the section is mapped into.
76766f5c51SRuslan Bukin  * This is not relevant for reading from the section.
77766f5c51SRuslan Bukin  */
78766f5c51SRuslan Bukin struct pt_image_section_cache {
79766f5c51SRuslan Bukin 	/* The optional name of the cache; NULL if not named. */
80766f5c51SRuslan Bukin 	char *name;
81766f5c51SRuslan Bukin 
82766f5c51SRuslan Bukin 	/* An array of @nentries cached sections. */
83766f5c51SRuslan Bukin 	struct pt_iscache_entry *entries;
84766f5c51SRuslan Bukin 
85766f5c51SRuslan Bukin 	/* A list of mapped sections ordered by time of last access. */
86766f5c51SRuslan Bukin 	struct pt_iscache_lru_entry *lru;
87766f5c51SRuslan Bukin 
88766f5c51SRuslan Bukin 	/* The memory limit for our LRU cache. */
89766f5c51SRuslan Bukin 	uint64_t limit;
90766f5c51SRuslan Bukin 
91766f5c51SRuslan Bukin 	/* The current size of our LRU cache. */
92766f5c51SRuslan Bukin 	uint64_t used;
93766f5c51SRuslan Bukin 
94766f5c51SRuslan Bukin #if defined(FEATURE_THREADS)
95766f5c51SRuslan Bukin 	/* A lock protecting this image section cache. */
96766f5c51SRuslan Bukin 	mtx_t lock;
97766f5c51SRuslan Bukin #endif /* defined(FEATURE_THREADS) */
98766f5c51SRuslan Bukin 
99766f5c51SRuslan Bukin 	/* The capacity of the @entries array.
100766f5c51SRuslan Bukin 	 *
101766f5c51SRuslan Bukin 	 * Cached sections are identified by a positive integer, the image
102766f5c51SRuslan Bukin 	 * section identifier (isid), which is derived from their index into the
103766f5c51SRuslan Bukin 	 * @entries array.
104766f5c51SRuslan Bukin 	 *
105766f5c51SRuslan Bukin 	 * We can't expand the section cache capacity beyond INT_MAX.
106766f5c51SRuslan Bukin 	 */
107766f5c51SRuslan Bukin 	uint16_t capacity;
108766f5c51SRuslan Bukin 
109766f5c51SRuslan Bukin 	/* The current size of the cache in number of entries.
110766f5c51SRuslan Bukin 	 *
111766f5c51SRuslan Bukin 	 * This is smaller than @capacity if there is still room in the @entries
112766f5c51SRuslan Bukin 	 * array; equal to @capacity if the @entries array is full and needs to
113766f5c51SRuslan Bukin 	 * be reallocated.
114766f5c51SRuslan Bukin 	 */
115766f5c51SRuslan Bukin 	uint16_t size;
116766f5c51SRuslan Bukin };
117766f5c51SRuslan Bukin 
118766f5c51SRuslan Bukin 
119766f5c51SRuslan Bukin /* Initialize an image section cache. */
120766f5c51SRuslan Bukin extern int pt_iscache_init(struct pt_image_section_cache *iscache,
121766f5c51SRuslan Bukin 			   const char *name);
122766f5c51SRuslan Bukin 
123766f5c51SRuslan Bukin /* Finalize an image section cache. */
124766f5c51SRuslan Bukin extern void pt_iscache_fini(struct pt_image_section_cache *iscache);
125766f5c51SRuslan Bukin 
126766f5c51SRuslan Bukin /* Add a section to the cache.
127766f5c51SRuslan Bukin  *
128766f5c51SRuslan Bukin  * Adds @section at @laddr to @iscache and returns its isid.  If a similar
129766f5c51SRuslan Bukin  * section is already cached, returns that section's isid, instead.
130766f5c51SRuslan Bukin  *
131766f5c51SRuslan Bukin  * We take a full section rather than its filename and range in that file to
132766f5c51SRuslan Bukin  * avoid the dependency to pt_section.h.  Callers are expected to query the
133766f5c51SRuslan Bukin  * cache before creating the section, so we should only see unnecessary section
134766f5c51SRuslan Bukin  * creation/destruction on insertion races.
135766f5c51SRuslan Bukin  *
136766f5c51SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
137766f5c51SRuslan Bukin  * Returns -pte_internal if @iscache or @section is NULL.
138766f5c51SRuslan Bukin  * Returns -pte_internal if @section's filename is NULL.
139766f5c51SRuslan Bukin  */
140766f5c51SRuslan Bukin extern int pt_iscache_add(struct pt_image_section_cache *iscache,
141766f5c51SRuslan Bukin 			  struct pt_section *section, uint64_t laddr);
142766f5c51SRuslan Bukin 
143766f5c51SRuslan Bukin /* Find a section in the cache.
144766f5c51SRuslan Bukin  *
145766f5c51SRuslan Bukin  * Returns a positive isid if a section matching @filename, @offset, @size
146766f5c51SRuslan Bukin  * loaded at @laddr is found in @iscache.
147766f5c51SRuslan Bukin  * Returns zero if no such section is found.
148766f5c51SRuslan Bukin  * Returns a negative error code otherwise.
149766f5c51SRuslan Bukin  * Returns -pte_internal if @iscache or @filename is NULL.
150766f5c51SRuslan Bukin  */
151766f5c51SRuslan Bukin extern int pt_iscache_find(struct pt_image_section_cache *iscache,
152766f5c51SRuslan Bukin 			   const char *filename, uint64_t offset,
153766f5c51SRuslan Bukin 			   uint64_t size, uint64_t laddr);
154766f5c51SRuslan Bukin 
155766f5c51SRuslan Bukin /* Lookup the section identified by its isid.
156766f5c51SRuslan Bukin  *
157766f5c51SRuslan Bukin  * Provides a reference to the section in @section and its load address in
158766f5c51SRuslan Bukin  * @laddr on success.  The caller is expected to put the returned section after
159766f5c51SRuslan Bukin  * use.
160766f5c51SRuslan Bukin  *
161766f5c51SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
162766f5c51SRuslan Bukin  * Returns -pte_internal if @iscache, @section, or @laddr is NULL.
163766f5c51SRuslan Bukin  * Returns -pte_bad_image if @iscache does not contain @isid.
164766f5c51SRuslan Bukin  */
165766f5c51SRuslan Bukin extern int pt_iscache_lookup(struct pt_image_section_cache *iscache,
166766f5c51SRuslan Bukin 			     struct pt_section **section, uint64_t *laddr,
167766f5c51SRuslan Bukin 			     int isid);
168766f5c51SRuslan Bukin 
169766f5c51SRuslan Bukin /* Clear an image section cache. */
170766f5c51SRuslan Bukin extern int pt_iscache_clear(struct pt_image_section_cache *iscache);
171766f5c51SRuslan Bukin 
172766f5c51SRuslan Bukin /* Notify about the mapping of a cached section.
173766f5c51SRuslan Bukin  *
174766f5c51SRuslan Bukin  * Notifies @iscache that @section has been mapped.
175766f5c51SRuslan Bukin  *
176766f5c51SRuslan Bukin  * The caller guarantees that @iscache contains @section (by using @section's
177766f5c51SRuslan Bukin  * iscache pointer) and prevents @iscache from detaching.
178766f5c51SRuslan Bukin  *
179766f5c51SRuslan Bukin  * The caller must not lock @section to allow @iscache to map it.  This function
180766f5c51SRuslan Bukin  * must not try to detach from @section.
181766f5c51SRuslan Bukin  *
182766f5c51SRuslan Bukin  * Returns zero on success, a negative pt_error_code otherwise.
183766f5c51SRuslan Bukin  * Returns -pte_internal if @iscache or @section is NULL.
184766f5c51SRuslan Bukin  * Returns -pte_bad_lock on any locking error.
185766f5c51SRuslan Bukin  */
186766f5c51SRuslan Bukin extern int pt_iscache_notify_map(struct pt_image_section_cache *iscache,
187766f5c51SRuslan Bukin 				 struct pt_section *section);
188766f5c51SRuslan Bukin 
189766f5c51SRuslan Bukin /* Notify about a size change of a mapped section.
190766f5c51SRuslan Bukin  *
191766f5c51SRuslan Bukin  * Notifies @iscache that @section's size has changed while it was mapped.
192766f5c51SRuslan Bukin  *
193766f5c51SRuslan Bukin  * The caller guarantees that @iscache contains @section (by using @section's
194766f5c51SRuslan Bukin  * iscache pointer) and prevents @iscache from detaching.
195766f5c51SRuslan Bukin  *
196766f5c51SRuslan Bukin  * The caller must not lock @section to allow @iscache to map it.  This function
197766f5c51SRuslan Bukin  * must not try to detach from @section.
198766f5c51SRuslan Bukin  *
199766f5c51SRuslan Bukin  * Returns zero on success, a negative pt_error_code otherwise.
200766f5c51SRuslan Bukin  * Returns -pte_internal if @iscache or @section is NULL.
201766f5c51SRuslan Bukin  * Returns -pte_bad_lock on any locking error.
202766f5c51SRuslan Bukin  */
203766f5c51SRuslan Bukin extern int pt_iscache_notify_resize(struct pt_image_section_cache *iscache,
204766f5c51SRuslan Bukin 				    struct pt_section *section, uint64_t size);
205766f5c51SRuslan Bukin 
206766f5c51SRuslan Bukin #endif /* PT_IMAGE_SECTION_CACHE_H */
207