xref: /freebsd-src/contrib/processor-trace/libipt/internal/include/pt_image_section_cache.h (revision 85f87cf491bec6f90948a85b10f5523ea24db9e3)
174fe6c29SRuslan Bukin /*
2*85f87cf4SRuslan Bukin  * Copyright (c) 2016-2019, Intel Corporation
374fe6c29SRuslan Bukin  *
474fe6c29SRuslan Bukin  * Redistribution and use in source and binary forms, with or without
574fe6c29SRuslan Bukin  * modification, are permitted provided that the following conditions are met:
674fe6c29SRuslan Bukin  *
774fe6c29SRuslan Bukin  *  * Redistributions of source code must retain the above copyright notice,
874fe6c29SRuslan Bukin  *    this list of conditions and the following disclaimer.
974fe6c29SRuslan Bukin  *  * Redistributions in binary form must reproduce the above copyright notice,
1074fe6c29SRuslan Bukin  *    this list of conditions and the following disclaimer in the documentation
1174fe6c29SRuslan Bukin  *    and/or other materials provided with the distribution.
1274fe6c29SRuslan Bukin  *  * Neither the name of Intel Corporation nor the names of its contributors
1374fe6c29SRuslan Bukin  *    may be used to endorse or promote products derived from this software
1474fe6c29SRuslan Bukin  *    without specific prior written permission.
1574fe6c29SRuslan Bukin  *
1674fe6c29SRuslan Bukin  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1774fe6c29SRuslan Bukin  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1874fe6c29SRuslan Bukin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1974fe6c29SRuslan Bukin  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2074fe6c29SRuslan Bukin  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2174fe6c29SRuslan Bukin  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2274fe6c29SRuslan Bukin  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2374fe6c29SRuslan Bukin  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2474fe6c29SRuslan Bukin  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2574fe6c29SRuslan Bukin  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2674fe6c29SRuslan Bukin  * POSSIBILITY OF SUCH DAMAGE.
2774fe6c29SRuslan Bukin  */
2874fe6c29SRuslan Bukin 
2974fe6c29SRuslan Bukin #ifndef PT_IMAGE_SECTION_CACHE_H
3074fe6c29SRuslan Bukin #define PT_IMAGE_SECTION_CACHE_H
3174fe6c29SRuslan Bukin 
3274fe6c29SRuslan Bukin #include <stdint.h>
3374fe6c29SRuslan Bukin 
3474fe6c29SRuslan Bukin #if defined(FEATURE_THREADS)
3574fe6c29SRuslan Bukin #  include <threads.h>
3674fe6c29SRuslan Bukin #endif /* defined(FEATURE_THREADS) */
3774fe6c29SRuslan Bukin 
3874fe6c29SRuslan Bukin struct pt_section;
3974fe6c29SRuslan Bukin 
4074fe6c29SRuslan Bukin 
4174fe6c29SRuslan Bukin /* An image section cache entry. */
4274fe6c29SRuslan Bukin struct pt_iscache_entry {
4374fe6c29SRuslan Bukin 	/* The section object.
4474fe6c29SRuslan Bukin 	 *
4574fe6c29SRuslan Bukin 	 * We hold a reference to the section - put it when the section is
4674fe6c29SRuslan Bukin 	 * removed from the cache.
4774fe6c29SRuslan Bukin 	 */
4874fe6c29SRuslan Bukin 	struct pt_section *section;
4974fe6c29SRuslan Bukin 
5074fe6c29SRuslan Bukin 	/* The base address at which @section has been loaded. */
5174fe6c29SRuslan Bukin 	uint64_t laddr;
5274fe6c29SRuslan Bukin };
5374fe6c29SRuslan Bukin 
5474fe6c29SRuslan Bukin /* An image section cache least recently used cache entry. */
5574fe6c29SRuslan Bukin struct pt_iscache_lru_entry {
5674fe6c29SRuslan Bukin 	/* The next entry in a list ordered by recent use. */
5774fe6c29SRuslan Bukin 	struct pt_iscache_lru_entry *next;
5874fe6c29SRuslan Bukin 
5974fe6c29SRuslan Bukin 	/* The section mapped by the image section cache. */
6074fe6c29SRuslan Bukin 	struct pt_section *section;
6174fe6c29SRuslan Bukin 
6274fe6c29SRuslan Bukin 	/* The amount of memory used by mapping @section in bytes. */
6374fe6c29SRuslan Bukin 	uint64_t size;
6474fe6c29SRuslan Bukin };
6574fe6c29SRuslan Bukin 
6674fe6c29SRuslan Bukin /* A cache of image sections and their load addresses.
6774fe6c29SRuslan Bukin  *
6874fe6c29SRuslan Bukin  * We combine the section with its load address to reduce the amount of
6974fe6c29SRuslan Bukin  * information we need to store in order to read from a cached section by
7074fe6c29SRuslan Bukin  * virtual address.
7174fe6c29SRuslan Bukin  *
7274fe6c29SRuslan Bukin  * Internally, the section object will be shared if it is loaded at different
7374fe6c29SRuslan Bukin  * addresses in the cache.
7474fe6c29SRuslan Bukin  *
7574fe6c29SRuslan Bukin  * The cache does not consider the address-space the section is mapped into.
7674fe6c29SRuslan Bukin  * This is not relevant for reading from the section.
7774fe6c29SRuslan Bukin  */
7874fe6c29SRuslan Bukin struct pt_image_section_cache {
7974fe6c29SRuslan Bukin 	/* The optional name of the cache; NULL if not named. */
8074fe6c29SRuslan Bukin 	char *name;
8174fe6c29SRuslan Bukin 
8274fe6c29SRuslan Bukin 	/* An array of @nentries cached sections. */
8374fe6c29SRuslan Bukin 	struct pt_iscache_entry *entries;
8474fe6c29SRuslan Bukin 
8574fe6c29SRuslan Bukin 	/* A list of mapped sections ordered by time of last access. */
8674fe6c29SRuslan Bukin 	struct pt_iscache_lru_entry *lru;
8774fe6c29SRuslan Bukin 
8874fe6c29SRuslan Bukin 	/* The memory limit for our LRU cache. */
8974fe6c29SRuslan Bukin 	uint64_t limit;
9074fe6c29SRuslan Bukin 
9174fe6c29SRuslan Bukin 	/* The current size of our LRU cache. */
9274fe6c29SRuslan Bukin 	uint64_t used;
9374fe6c29SRuslan Bukin 
9474fe6c29SRuslan Bukin #if defined(FEATURE_THREADS)
9574fe6c29SRuslan Bukin 	/* A lock protecting this image section cache. */
9674fe6c29SRuslan Bukin 	mtx_t lock;
9774fe6c29SRuslan Bukin #endif /* defined(FEATURE_THREADS) */
9874fe6c29SRuslan Bukin 
9974fe6c29SRuslan Bukin 	/* The capacity of the @entries array.
10074fe6c29SRuslan Bukin 	 *
10174fe6c29SRuslan Bukin 	 * Cached sections are identified by a positive integer, the image
10274fe6c29SRuslan Bukin 	 * section identifier (isid), which is derived from their index into the
10374fe6c29SRuslan Bukin 	 * @entries array.
10474fe6c29SRuslan Bukin 	 *
10574fe6c29SRuslan Bukin 	 * We can't expand the section cache capacity beyond INT_MAX.
10674fe6c29SRuslan Bukin 	 */
10774fe6c29SRuslan Bukin 	uint16_t capacity;
10874fe6c29SRuslan Bukin 
10974fe6c29SRuslan Bukin 	/* The current size of the cache in number of entries.
11074fe6c29SRuslan Bukin 	 *
11174fe6c29SRuslan Bukin 	 * This is smaller than @capacity if there is still room in the @entries
11274fe6c29SRuslan Bukin 	 * array; equal to @capacity if the @entries array is full and needs to
11374fe6c29SRuslan Bukin 	 * be reallocated.
11474fe6c29SRuslan Bukin 	 */
11574fe6c29SRuslan Bukin 	uint16_t size;
11674fe6c29SRuslan Bukin };
11774fe6c29SRuslan Bukin 
11874fe6c29SRuslan Bukin 
11974fe6c29SRuslan Bukin /* Initialize an image section cache. */
12074fe6c29SRuslan Bukin extern int pt_iscache_init(struct pt_image_section_cache *iscache,
12174fe6c29SRuslan Bukin 			   const char *name);
12274fe6c29SRuslan Bukin 
12374fe6c29SRuslan Bukin /* Finalize an image section cache. */
12474fe6c29SRuslan Bukin extern void pt_iscache_fini(struct pt_image_section_cache *iscache);
12574fe6c29SRuslan Bukin 
12674fe6c29SRuslan Bukin /* Add a section to the cache.
12774fe6c29SRuslan Bukin  *
12874fe6c29SRuslan Bukin  * Adds @section at @laddr to @iscache and returns its isid.  If a similar
12974fe6c29SRuslan Bukin  * section is already cached, returns that section's isid, instead.
13074fe6c29SRuslan Bukin  *
13174fe6c29SRuslan Bukin  * We take a full section rather than its filename and range in that file to
13274fe6c29SRuslan Bukin  * avoid the dependency to pt_section.h.  Callers are expected to query the
13374fe6c29SRuslan Bukin  * cache before creating the section, so we should only see unnecessary section
13474fe6c29SRuslan Bukin  * creation/destruction on insertion races.
13574fe6c29SRuslan Bukin  *
13674fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
13774fe6c29SRuslan Bukin  * Returns -pte_internal if @iscache or @section is NULL.
13874fe6c29SRuslan Bukin  * Returns -pte_internal if @section's filename is NULL.
13974fe6c29SRuslan Bukin  */
14074fe6c29SRuslan Bukin extern int pt_iscache_add(struct pt_image_section_cache *iscache,
14174fe6c29SRuslan Bukin 			  struct pt_section *section, uint64_t laddr);
14274fe6c29SRuslan Bukin 
14374fe6c29SRuslan Bukin /* Find a section in the cache.
14474fe6c29SRuslan Bukin  *
14574fe6c29SRuslan Bukin  * Returns a positive isid if a section matching @filename, @offset, @size
14674fe6c29SRuslan Bukin  * loaded at @laddr is found in @iscache.
14774fe6c29SRuslan Bukin  * Returns zero if no such section is found.
14874fe6c29SRuslan Bukin  * Returns a negative error code otherwise.
14974fe6c29SRuslan Bukin  * Returns -pte_internal if @iscache or @filename is NULL.
15074fe6c29SRuslan Bukin  */
15174fe6c29SRuslan Bukin extern int pt_iscache_find(struct pt_image_section_cache *iscache,
15274fe6c29SRuslan Bukin 			   const char *filename, uint64_t offset,
15374fe6c29SRuslan Bukin 			   uint64_t size, uint64_t laddr);
15474fe6c29SRuslan Bukin 
15574fe6c29SRuslan Bukin /* Lookup the section identified by its isid.
15674fe6c29SRuslan Bukin  *
15774fe6c29SRuslan Bukin  * Provides a reference to the section in @section and its load address in
15874fe6c29SRuslan Bukin  * @laddr on success.  The caller is expected to put the returned section after
15974fe6c29SRuslan Bukin  * use.
16074fe6c29SRuslan Bukin  *
16174fe6c29SRuslan Bukin  * Returns zero on success, a negative error code otherwise.
16274fe6c29SRuslan Bukin  * Returns -pte_internal if @iscache, @section, or @laddr is NULL.
16374fe6c29SRuslan Bukin  * Returns -pte_bad_image if @iscache does not contain @isid.
16474fe6c29SRuslan Bukin  */
16574fe6c29SRuslan Bukin extern int pt_iscache_lookup(struct pt_image_section_cache *iscache,
16674fe6c29SRuslan Bukin 			     struct pt_section **section, uint64_t *laddr,
16774fe6c29SRuslan Bukin 			     int isid);
16874fe6c29SRuslan Bukin 
16974fe6c29SRuslan Bukin /* Clear an image section cache. */
17074fe6c29SRuslan Bukin extern int pt_iscache_clear(struct pt_image_section_cache *iscache);
17174fe6c29SRuslan Bukin 
17274fe6c29SRuslan Bukin /* Notify about the mapping of a cached section.
17374fe6c29SRuslan Bukin  *
17474fe6c29SRuslan Bukin  * Notifies @iscache that @section has been mapped.
17574fe6c29SRuslan Bukin  *
17674fe6c29SRuslan Bukin  * The caller guarantees that @iscache contains @section (by using @section's
17774fe6c29SRuslan Bukin  * iscache pointer) and prevents @iscache from detaching.
17874fe6c29SRuslan Bukin  *
17974fe6c29SRuslan Bukin  * The caller must not lock @section to allow @iscache to map it.  This function
18074fe6c29SRuslan Bukin  * must not try to detach from @section.
18174fe6c29SRuslan Bukin  *
18274fe6c29SRuslan Bukin  * Returns zero on success, a negative pt_error_code otherwise.
18374fe6c29SRuslan Bukin  * Returns -pte_internal if @iscache or @section is NULL.
18474fe6c29SRuslan Bukin  * Returns -pte_bad_lock on any locking error.
18574fe6c29SRuslan Bukin  */
18674fe6c29SRuslan Bukin extern int pt_iscache_notify_map(struct pt_image_section_cache *iscache,
18774fe6c29SRuslan Bukin 				 struct pt_section *section);
18874fe6c29SRuslan Bukin 
18974fe6c29SRuslan Bukin /* Notify about a size change of a mapped section.
19074fe6c29SRuslan Bukin  *
19174fe6c29SRuslan Bukin  * Notifies @iscache that @section's size has changed while it was mapped.
19274fe6c29SRuslan Bukin  *
19374fe6c29SRuslan Bukin  * The caller guarantees that @iscache contains @section (by using @section's
19474fe6c29SRuslan Bukin  * iscache pointer) and prevents @iscache from detaching.
19574fe6c29SRuslan Bukin  *
19674fe6c29SRuslan Bukin  * The caller must not lock @section to allow @iscache to map it.  This function
19774fe6c29SRuslan Bukin  * must not try to detach from @section.
19874fe6c29SRuslan Bukin  *
19974fe6c29SRuslan Bukin  * Returns zero on success, a negative pt_error_code otherwise.
20074fe6c29SRuslan Bukin  * Returns -pte_internal if @iscache or @section is NULL.
20174fe6c29SRuslan Bukin  * Returns -pte_bad_lock on any locking error.
20274fe6c29SRuslan Bukin  */
20374fe6c29SRuslan Bukin extern int pt_iscache_notify_resize(struct pt_image_section_cache *iscache,
20474fe6c29SRuslan Bukin 				    struct pt_section *section, uint64_t size);
20574fe6c29SRuslan Bukin 
20674fe6c29SRuslan Bukin #endif /* PT_IMAGE_SECTION_CACHE_H */
207