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 }