Mercurial > hg-old > index.cgi
comparison lwdisasm/range.c @ 409:cba03436c720
Checkpoint disassembler
author | lost@l-w.ca |
---|---|
date | Mon, 02 Aug 2010 18:07:04 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
408:2a94b2e64621 | 409:cba03436c720 |
---|---|
1 /* | |
2 range.c | |
3 | |
4 Copyright © 2010 William Astle | |
5 | |
6 This file is part of LWTOOLS. | |
7 | |
8 LWTOOLS is free software: you can redistribute it and/or modify it under the | |
9 terms of the GNU General Public License as published by the Free Software | |
10 Foundation, either version 3 of the License, or (at your option) any later | |
11 version. | |
12 | |
13 This program is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 more details. | |
17 | |
18 You should have received a copy of the GNU General Public License along with | |
19 this program. If not, see <http://www.gnu.org/licenses/>. | |
20 */ | |
21 | |
22 #include <config.h> | |
23 | |
24 #include <stdlib.h> | |
25 | |
26 #include <lw_alloc.h> | |
27 | |
28 #include "lwdisasm.h" | |
29 | |
30 void register_range(disasmstate_t *as, int min, int max, int type) | |
31 { | |
32 rangedata_t *nr; | |
33 rangedata_t *r; | |
34 | |
35 // first remove any complete subsets of the new range | |
36 subsetagain: | |
37 for (r = as -> rhead; r; r = r -> next) | |
38 { | |
39 // if we haven't run into an existing range yet, short circuit | |
40 if (r -> min >= min && r -> max <= max) | |
41 { | |
42 if (r -> prev) | |
43 r -> prev -> next = r -> next; | |
44 else | |
45 as -> rhead = r -> next; | |
46 if (r -> next) | |
47 r -> next -> prev = r -> prev; | |
48 else | |
49 as -> rtail = r -> prev; | |
50 goto subsetagain; | |
51 } | |
52 } | |
53 | |
54 // now shorten any subset that overlaps below or overlaps above | |
55 for (r = as -> rhead; r; r = r -> next) | |
56 { | |
57 // are we a subset of this range? | |
58 if (r -> min <= min && r -> max >= max) | |
59 { | |
60 // proper subset; split | |
61 nr = lw_alloc(sizeof(rangedata_t)); | |
62 *nr = *r; | |
63 r -> next = nr; | |
64 nr -> prev = r; | |
65 r -> max = min - 1; | |
66 nr -> min = max + 1; | |
67 break; | |
68 } | |
69 // overlap above us | |
70 if (r -> max > max && r -> min < max) | |
71 { | |
72 r -> min = max + 1; | |
73 } | |
74 // overlap on the bottom | |
75 if (r -> min < min && r -> max > min) | |
76 { | |
77 r -> max = min - 1; | |
78 } | |
79 } | |
80 | |
81 // now add new range | |
82 for (r = as -> rhead; r; r = r -> next) | |
83 { | |
84 if (r -> min < max) | |
85 { | |
86 break; | |
87 } | |
88 } | |
89 | |
90 nr = lw_alloc(sizeof(rangedata_t)); | |
91 nr -> min = min; | |
92 nr -> max = max; | |
93 nr -> type = type; | |
94 | |
95 if (r) | |
96 { | |
97 if (r -> prev) | |
98 r -> prev -> next = nr; | |
99 else | |
100 as -> rhead = nr; | |
101 nr -> prev = r -> prev; | |
102 nr -> next = r; | |
103 r -> prev = nr; | |
104 } | |
105 else | |
106 { | |
107 nr -> next = NULL; | |
108 nr -> prev = as -> rtail; | |
109 as -> rtail -> next = nr; | |
110 as -> rtail = nr; | |
111 } | |
112 } | |
113 | |
114 rangedata_t *lookup_range(disasmstate_t *as, int addr) | |
115 { | |
116 rangedata_t *r; | |
117 | |
118 for (r = as -> rhead; r; r = r -> next) | |
119 { | |
120 if (r -> min <= addr && r -> max >= addr) | |
121 return r; | |
122 } | |
123 return NULL; | |
124 } |