Bitdefender Hypervisor Memory Introspection
introlists.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #ifndef _INTRO_LISTS_H_
6 #define _INTRO_LISTS_H_
7 
8 #include "introtypes.h"
9 
10 //
11 // Exported convenient versions.
12 // These could be a lot easier if MSVC supported typeof(), but each file could define
13 // a generic macro around them (see lixprocess.c)
14 //
15 
16 typedef struct _LIST_ENTRY
17 {
18  union
19  {
20  struct _LIST_ENTRY *Flink;
21  struct _LIST_ENTRY *Head;
22  };
23  union
24  {
25  struct _LIST_ENTRY *Blink;
26  struct _LIST_ENTRY *Tail;
27  };
29 
30 #ifdef INT_COMPILER_MSVC
31 # define OFFSET_OF(Type, Member) ((size_t) &((Type *)0)->Member)
32 #else
33 # define OFFSET_OF(Type, Member) __builtin_offsetof(Type, Member)
34 #endif // INT_COMPILER_MSVC
35 
36 #define CONTAINING_RECORD(List, Type, Member) (Type *)((size_t)(List) - OFFSET_OF(Type, Member))
37 
38 // Our list implementation requires { } around name too, since that is an union
39 #define LIST_HEAD_INIT(Name) { { .Head = &(Name) }, { .Tail = &(Name) } }
40 
41 #define list_for_each(_head, _struct_type, _var) _list_for_each(_head, _struct_type, Link, _var)
42 #define list_for_next(_start, _head, _type, _var) _list_for_next(_start, _head, _type, Link, _var)
43 #define list_for_each_link(_head, _struct_type, _member, _var) _list_for_each(_head, _struct_type, _member, _var)
44 
45 //
46 // RAW versions, use only if really needed
47 //
48 #define _next(_var, _member) _var->_member.Flink
49 #define _next_entry(_var, _member, _type) CONTAINING_RECORD(_next(_var, _member), _type, _member)
50 
51 #define PREPROC_CONCAT(a, b) PREPROC_CONCAT_1(a, b)
52 #define PREPROC_CONCAT_1(a, b) PREPROC_CONCAT_2(~, a ## b)
53 #define PREPROC_CONCAT_2(p, res) res
54 
55 #define UNIQUE_NAME(base) PREPROC_CONCAT(base, __LINE__)
56 
57 #define _list_for_each(_head, _type, _member, _var) \
58  for (_type *_var = CONTAINING_RECORD(_head.Flink, _type, _member), *UNIQUE_NAME(_n) = _next_entry(_var, _member, _type); \
59  &_var->_member != &_head; \
60  _var = UNIQUE_NAME(_n), UNIQUE_NAME(_n) = _next_entry(_var, _member, _type))
61 
62 #define _list_for_next(_start, _head, _type, _member, _var) \
63  for (_type *_var = _next_entry(_start, _member, _type), *UNIQUE_NAME(_n) = _next_entry(_var, _member, _type); \
64  &_var->_member != &_head; \
65  _var = UNIQUE_NAME(_n), UNIQUE_NAME(_n) = _next_entry(_var, _member, _type))
66 
67 
68 static inline void
70  LIST_ENTRY *ListHead
71  )
72 {
73  ListHead->Flink = ListHead->Blink = ListHead;
74 }
75 
76 
77 static inline BOOLEAN
79  const LIST_ENTRY *ListHead
80  )
81 {
82  return (BOOLEAN)(ListHead->Flink == ListHead);
83 }
84 
85 
86 static inline BOOLEAN
88  LIST_ENTRY *Entry
89  )
90 {
91  LIST_ENTRY *blink = Entry->Blink;
92  LIST_ENTRY *flink = Entry->Flink;
93 
94  blink->Flink = flink;
95  flink->Blink = blink;
96 
97  Entry->Flink = NULL;
98  Entry->Blink = NULL;
99 
100  return (BOOLEAN)(flink == blink);
101 }
102 
103 
104 static inline LIST_ENTRY *
106  LIST_ENTRY *ListHead
107  )
108 {
109  LIST_ENTRY *entry = ListHead->Flink;
110  LIST_ENTRY *flink = entry->Flink;
111 
112  ListHead->Flink = flink;
113  flink->Blink = ListHead;
114 
115  return entry;
116 }
117 
118 
119 static inline LIST_ENTRY *
121  LIST_ENTRY *ListHead
122  )
123 {
124  LIST_ENTRY *entry = ListHead->Blink;
125  LIST_ENTRY *blink = entry->Blink;
126 
127  ListHead->Blink = blink;
128  blink->Flink = ListHead;
129 
130  return entry;
131 }
132 
133 
134 static inline void
136  LIST_ENTRY *ListHead,
137  LIST_ENTRY *Entry
138  )
139 {
140  LIST_ENTRY *blink = ListHead->Blink;
141 
142  Entry->Flink = ListHead;
143  Entry->Blink = blink;
144 
145  blink->Flink = Entry;
146 
147  ListHead->Blink = Entry;
148 }
149 
150 
151 static inline void
153  LIST_ENTRY *ListHead,
154  LIST_ENTRY *Entry
155  )
156 {
157  LIST_ENTRY *Flink = ListHead->Flink;
158 
159  Entry->Flink = Flink;
160  Entry->Blink = ListHead;
161 
162  Flink->Blink = Entry;
163 
164  ListHead->Flink = Entry;
165 }
166 
167 
168 static inline void
170  LIST_ENTRY *Pivot,
171  LIST_ENTRY *Item
172  )
173 {
174  Pivot->Flink->Blink = Item;
175  Item->Flink = Pivot->Flink;
176  Pivot->Flink = Item;
177  Item->Blink = Pivot;
178 }
179 
180 
181 #endif // _INTRO_LISTS_H_
_Bool BOOLEAN
Definition: intro_types.h:58
static void InsertHeadList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
Definition: introlists.h:152
struct _LIST_ENTRY * Flink
Definition: introlists.h:20
static BOOLEAN IsListEmpty(const LIST_ENTRY *ListHead)
Definition: introlists.h:78
struct _LIST_ENTRY * Head
Definition: introlists.h:21
static LIST_ENTRY * RemoveHeadList(LIST_ENTRY *ListHead)
Definition: introlists.h:105
struct _LIST_ENTRY * PLIST_HEAD
static BOOLEAN RemoveEntryList(LIST_ENTRY *Entry)
Definition: introlists.h:87
struct _LIST_ENTRY LIST_HEAD
static void InsertAfterList(LIST_ENTRY *Pivot, LIST_ENTRY *Item)
Definition: introlists.h:169
static void InsertTailList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
Definition: introlists.h:135
struct _LIST_ENTRY LIST_ENTRY
static void InitializeListHead(LIST_ENTRY *ListHead)
Definition: introlists.h:69
struct _LIST_ENTRY * PLIST_ENTRY
struct _LIST_ENTRY * Tail
Definition: introlists.h:26
struct _LIST_ENTRY * Blink
Definition: introlists.h:25
static LIST_ENTRY * RemoveTailList(LIST_ENTRY *ListHead)
Definition: introlists.h:120