1/*
2 * Copyright (c) 2013-2018, Intel Corporation
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 *  * Redistributions of source code must retain the above copyright notice,
8 *    this list of conditions and the following disclaimer.
9 *  * Redistributions in binary form must reproduce the above copyright notice,
10 *    this list of conditions and the following disclaimer in the documentation
11 *    and/or other materials provided with the distribution.
12 *  * Neither the name of Intel Corporation nor the names of its contributors
13 *    may be used to endorse or promote products derived from this software
14 *    without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef PT_RETSTACK_H
30#define PT_RETSTACK_H
31
32#include <stdint.h>
33
34
35/* The size of the call/return stack in number of entries. */
36enum {
37	pt_retstack_size	= 64
38};
39
40/* A stack of return addresses used for return compression. */
41struct pt_retstack {
42	/* The stack of return addresses.
43	 *
44	 * We use one additional entry in order to distinguish a full from
45	 * an empty stack.
46	 */
47	uint64_t stack[pt_retstack_size + 1];
48
49	/* The top of the stack. */
50	uint8_t top;
51
52	/* The bottom of the stack. */
53	uint8_t bottom;
54};
55
56/* Initialize (or reset) a call/return stack. */
57extern void pt_retstack_init(struct pt_retstack *);
58
59/* Test a call/return stack for emptiness.
60 *
61 * Returns zero if @retstack contains at least one element.
62 * Returns a positive integer if @retstack is empty.
63 * Returns -pte_invalid if @retstack is NULL.
64 */
65extern int pt_retstack_is_empty(const struct pt_retstack *retstack);
66
67/* Pop and return the topmost IP.
68 *
69 * If @ip is not NULL, provides the topmost return address on success.
70 * If @retstack is not empty, pops the topmost return address on success.
71 *
72 * Returns zero on success.
73 * Returns -pte_invalid if @retstack is NULL.
74 * Returns -pte_noip if @retstack is empty.
75 */
76extern int pt_retstack_pop(struct pt_retstack *retstack, uint64_t *ip);
77
78/* Push a return address onto the stack.
79 *
80 * Pushes @ip onto @retstack.
81 * If @retstack is full, drops the oldest return address.
82 *
83 * Returns zero on success.
84 */
85extern int pt_retstack_push(struct pt_retstack *retstack, uint64_t ip);
86
87#endif /* PT_RETSTACK_H */
88