|
1 /* |
|
2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 package com.nokia.s60tools.crashanalyser.containers; |
|
19 |
|
20 import org.w3c.dom.Element; |
|
21 import org.w3c.dom.NodeList; |
|
22 import com.nokia.s60tools.crashanalyser.model.XmlUtils; |
|
23 import java.io.BufferedWriter; |
|
24 import java.io.IOException; |
|
25 import java.util.*; |
|
26 |
|
27 /** |
|
28 * A register set contains all registers. |
|
29 * |
|
30 */ |
|
31 public final class RegisterSet { |
|
32 |
|
33 // XML tags |
|
34 public static final String TAG_ID = "id"; |
|
35 public static final String TAG_TYPE = "type"; |
|
36 public static final String TAG_NAME = "name"; |
|
37 public static final String TAG_REGISTER = "register"; |
|
38 |
|
39 // data |
|
40 private final int setId; |
|
41 private final String setType; |
|
42 private final String setName; |
|
43 private final boolean setContainsCPSR; |
|
44 private final String linkRegisterValue; |
|
45 private final String stackPointerValue; |
|
46 private final String programCounterValue; |
|
47 private final List<Register> setRegisters; |
|
48 |
|
49 /** |
|
50 * Constructor |
|
51 * @param id register set id |
|
52 * @param type register set type |
|
53 * @param name register set name |
|
54 * @param registers list of registers for this register set |
|
55 * @param containsCPSR does this register set contain CPSR register |
|
56 * @param linkRegister link register value |
|
57 * @param stackPointer stack pointer value |
|
58 * @param programCounter program counter value |
|
59 */ |
|
60 private RegisterSet(int id, String type, String name, List<Register> registers, boolean containsCPSR, |
|
61 String linkRegister, String stackPointer, String programCounter) { |
|
62 setId = id; |
|
63 setType = type; |
|
64 setName = name; |
|
65 setRegisters = registers; |
|
66 setContainsCPSR = containsCPSR; |
|
67 linkRegisterValue = linkRegister; |
|
68 stackPointerValue = stackPointer; |
|
69 programCounterValue = programCounter; |
|
70 } |
|
71 |
|
72 public int getId() { |
|
73 return setId; |
|
74 } |
|
75 |
|
76 public String getType() { |
|
77 return setType; |
|
78 } |
|
79 |
|
80 public String getName() { |
|
81 return setName; |
|
82 } |
|
83 |
|
84 public List<Register> getRegisters() { |
|
85 return setRegisters; |
|
86 } |
|
87 |
|
88 public boolean containsCPSR() { |
|
89 return setContainsCPSR; |
|
90 } |
|
91 |
|
92 public String getLinkRegister() { |
|
93 return linkRegisterValue; |
|
94 } |
|
95 |
|
96 public String getStackPointer() { |
|
97 return stackPointerValue; |
|
98 } |
|
99 |
|
100 public String getProgramCounter() { |
|
101 return programCounterValue; |
|
102 } |
|
103 |
|
104 /** |
|
105 * Writes registers into give buffer (i.e. text file) |
|
106 * @param out buffer to write to |
|
107 * @throws IOException |
|
108 */ |
|
109 public void writeTo(BufferedWriter out) throws IOException { |
|
110 if (!"".equals(setName)) { |
|
111 writeLine(out, "Register Name : " + setName); |
|
112 if (setRegisters != null && !setRegisters.isEmpty()) { |
|
113 for (int i = 0; i < setRegisters.size(); i++) { |
|
114 Register register = setRegisters.get(i); |
|
115 register.writeTo(out); |
|
116 } |
|
117 } |
|
118 } |
|
119 } |
|
120 |
|
121 void writeLine(BufferedWriter out, String line) throws IOException { |
|
122 out.write(line); |
|
123 out.newLine(); |
|
124 } |
|
125 |
|
126 /** |
|
127 * Reads and creates a register set from register set xml element |
|
128 * @param elementRegisterSet |
|
129 * @param symbols |
|
130 * @param messages |
|
131 * @return created register set |
|
132 */ |
|
133 public static RegisterSet read(Element elementRegisterSet, |
|
134 Map<Integer, Symbol> symbols, |
|
135 Map<Integer, Message> messages) { |
|
136 try { |
|
137 // read register set id |
|
138 String setId = XmlUtils.getTextValue(elementRegisterSet, TAG_ID); |
|
139 if (setId == null) |
|
140 return null; |
|
141 |
|
142 // convert id to integer |
|
143 int id; |
|
144 try { |
|
145 id = Integer.parseInt(setId); |
|
146 } catch (Exception e) { |
|
147 return null; |
|
148 } |
|
149 |
|
150 // read register set type |
|
151 String type = XmlUtils.getTextValue(elementRegisterSet, TAG_TYPE); |
|
152 if (type == null) |
|
153 type = ""; |
|
154 |
|
155 // read register set name |
|
156 String name = XmlUtils.getTextValue(elementRegisterSet, TAG_NAME); |
|
157 if (name == null) |
|
158 return null; |
|
159 |
|
160 List<Register> registers = new ArrayList<Register>(); |
|
161 |
|
162 boolean containsCPSR = false; |
|
163 |
|
164 String stackPointer = ""; |
|
165 String linkRegister = ""; |
|
166 String programCounter = ""; |
|
167 |
|
168 // get register nodes |
|
169 NodeList registerNodes = elementRegisterSet.getElementsByTagName(TAG_REGISTER); |
|
170 if (registerNodes != null && registerNodes.getLength() > 0) { |
|
171 // go through all registers |
|
172 for (int i = 0; i < registerNodes.getLength(); i++) { |
|
173 Element registerElement = (Element)registerNodes.item(i); |
|
174 Register register = Register.read(registerElement, symbols, messages); |
|
175 if (register != null) { |
|
176 registers.add(register); |
|
177 containsCPSR = "CPSR".equals(register.getName()); |
|
178 // try to read stack pointer value |
|
179 if (register.getName().contains("R13")) { |
|
180 stackPointer = register.getValue() + " " + register.getSymbol(); |
|
181 // try to read link register value |
|
182 } else if (register.getName().contains("R14")) { |
|
183 linkRegister = register.getValue() + " " + register.getSymbol(); |
|
184 // try to read program counter value |
|
185 } else if (register.getName().contains("R15")) { |
|
186 programCounter = register.getValue() + " " + register.getSymbol(); |
|
187 } |
|
188 } |
|
189 } |
|
190 } |
|
191 |
|
192 return new RegisterSet(id, type, name, registers, containsCPSR, |
|
193 linkRegister, stackPointer, programCounter); |
|
194 } catch (Exception e) { |
|
195 return null; |
|
196 } |
|
197 } |
|
198 } |