4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <sys/types.h>
32 #include "rcapd_mapping.h"
36 * lmapping_t is a list of non-overlapping mappings, ordered by address. These
37 * functions add, remove, and verify the existence of mappings in such a list.
38 * rcapd_scanner.c is a consumer.
41 typedef struct lmapping_find_cb_arg
{
44 lmapping_t
*lmfa_prior
;
46 } lmapping_find_cb_arg_t
;
50 * Verify a sublist is properly ordered.
53 lmapping_verify(lmapping_t
*lm
)
56 if (lm
->lm_next
!= NULL
)
57 ASSERT(lm
->lm_next
->lm_addr
> lm
->lm_addr
);
62 #define lmapping_verify(x) ((void)0)
66 * Determine the position of a mapping with the given address and size. Upon
67 * return, lmfa_ret will be set to the actual mapping, if it exists, and
68 * lmfa_prior will be set to the mapping which does or would precede one with
69 * the given characteristics.
72 lmapping_find_cb(lmapping_t
*lm
, void *arg
)
74 lmapping_find_cb_arg_t
*lmfa
= arg
;
76 if (lm
->lm_addr
>= lmfa
->lmfa_addr
) {
77 if (lmfa
->lmfa_addr
== lm
->lm_addr
&& lmfa
->lmfa_size
==
82 lmfa
->lmfa_prior
= lm
;
88 lmapping_walk(lmapping_t
*lm
, int(*lmapping_walk_cb
)(lmapping_t
*, void *),
96 if (lmapping_walk_cb(lm
, arg
) != 0) {
105 lmapping_remove(lmapping_t
**lm
, uintptr_t addr
, size_t size
)
107 lmapping_find_cb_arg_t lmfa
;
109 lmfa
.lmfa_addr
= addr
;
110 lmfa
.lmfa_size
= size
;
111 lmfa
.lmfa_prior
= lmfa
.lmfa_ret
= NULL
;
113 lmapping_verify(*lm
);
114 lmapping_walk(*lm
, lmapping_find_cb
, &lmfa
);
115 if (lmfa
.lmfa_ret
== NULL
)
118 if (lmfa
.lmfa_prior
!= NULL
)
119 lmfa
.lmfa_prior
->lm_next
= lmfa
.lmfa_ret
->lm_next
;
120 else if (*lm
== lmfa
.lmfa_ret
)
121 *lm
= lmfa
.lmfa_ret
->lm_next
;
125 lmapping_verify(*lm
);
131 lmapping_insert(lmapping_t
**lm
, uintptr_t addr
, size_t size
)
133 lmapping_find_cb_arg_t lmfa
;
136 cur
= malloc(sizeof (*cur
));
144 lmfa
.lmfa_addr
= addr
;
145 lmfa
.lmfa_size
= size
;
146 lmfa
.lmfa_prior
= lmfa
.lmfa_ret
= NULL
;
148 lmapping_verify(*lm
);
149 lmapping_walk(*lm
, lmapping_find_cb
, &lmfa
);
150 ASSERT(lmfa
.lmfa_ret
== NULL
);
151 if (lmfa
.lmfa_prior
!= NULL
) {
152 cur
->lm_next
= lmfa
.lmfa_prior
->lm_next
;
153 lmfa
.lmfa_prior
->lm_next
= cur
;
159 lmapping_verify(*lm
);
165 lmapping_contains(lmapping_t
*lm
, uintptr_t addr
, size_t size
)
167 lmapping_find_cb_arg_t lmfa
;
169 lmfa
.lmfa_addr
= addr
;
170 lmfa
.lmfa_size
= size
;
171 lmfa
.lmfa_ret
= NULL
;
173 lmapping_walk(lm
, lmapping_find_cb
, &lmfa
);
174 return (lmfa
.lmfa_ret
!= NULL
);
179 lmapping_free_cb(lmapping_t
*lm
, void *arg
)
186 lmapping_free(lmapping_t
**lm
)
188 lmapping_walk(*lm
, lmapping_free_cb
, NULL
);
194 lmapping_dump_diff(lmapping_t
*lm1
, lmapping_t
*lm2
)
199 int label_printed
= 0;
201 #define OUTPUT_LABEL() \
202 if (label_printed == 0) { \
203 debug("changes in mappings:\n"); \
207 while (lm1
!= NULL
&& lm2
!= NULL
) {
208 if ((lm1
->lm_addr
!= lm2
->lm_addr
) || (lm1
->lm_size
!=
212 if (lm1
->lm_addr
== lm2
->lm_addr
&& lm1
->lm_size
<
213 lm2
->lm_size
|| lm1
->lm_addr
< lm2
->lm_addr
) {
221 debug("%c%p+0x%llx\n", ch
, (void *)(*lmv
)->lm_addr
,
222 (long long)(*lmv
)->lm_size
);
223 *lmv
= (*lmv
)->lm_next
;
229 while (lm1
!= NULL
) {
231 debug("%c%p+0x%llx\n", '-', (void *)lm1
->lm_addr
,
232 (unsigned long long)lm1
->lm_size
);
236 while (lm2
!= NULL
) {
238 debug("%c%p+0x%llx\n", '+', (void *)lm2
->lm_addr
,
239 (long long)lm2
->lm_size
);