LLVM: lib/DebugInfo/DWARF/LowLevel/DWARFUnwindTable.cpp Source File (original) (raw)

41 std::optional<uint32_t> AddrSpace) {

42 return {RegPlusOffset, RegNum, Offset, AddrSpace, false};

43}

47 std::optional<uint32_t> AddrSpace) {

48 return {RegPlusOffset, RegNum, Offset, AddrSpace, true};

49}

52 return {Expr, false};

53}

56 return {Expr, true};

57}

60 if (Kind != RHS.Kind)

61 return false;

62 switch (Kind) {

66 return true;

68 return Offset == RHS.Offset && Dereference == RHS.Dereference;

70 return RegNum == RHS.RegNum && Offset == RHS.Offset &&

71 Dereference == RHS.Dereference;

73 return *Expr == *RHS.Expr && Dereference == RHS.Dereference;

75 return Offset == RHS.Offset;

76 }

77 return false;

78}

83

85

86

87 std::vector<std::pair<UnwindLocation, RegisterLocations>> States;

89 switch (Inst.Opcode) {

90 case dwarf::DW_CFA_set_loc: {

91

92

93

94

95

96

97

99 if (!NewAddress)

101 if (*NewAddress <= Row.getAddress())

104 "%s with adrress 0x%" PRIx64 " which must be greater than the "

105 "current row address 0x%" PRIx64,

107 Row.getAddress());

108 Rows.push_back(Row);

109 Row.setAddress(*NewAddress);

110 break;

111 }

112

113 case dwarf::DW_CFA_advance_loc:

114 case dwarf::DW_CFA_advance_loc1:

115 case dwarf::DW_CFA_advance_loc2:

116 case dwarf::DW_CFA_advance_loc4: {

117

118

119

120

121

122

123 Rows.push_back(Row);

126 return Offset.takeError();

127 Row.slideAddress(*Offset);

128 break;

129 }

130

131 case dwarf::DW_CFA_restore:

132 case dwarf::DW_CFA_restore_extended: {

133

134

135

136

137 if (InitialLocs == nullptr)

142 if (!RegNum)

144 if (std::optional O =

146 Row.getRegisterLocations().setRegisterLocation(*RegNum, *O);

147 else

148 Row.getRegisterLocations().removeRegisterLocation(*RegNum);

149 break;

150 }

151

152 case dwarf::DW_CFA_offset:

153 case dwarf::DW_CFA_offset_extended:

154 case dwarf::DW_CFA_offset_extended_sf: {

156 if (!RegNum)

160 return Offset.takeError();

161 Row.getRegisterLocations().setRegisterLocation(

163 break;

164 }

165

166 case dwarf::DW_CFA_nop:

167 break;

168

169 case dwarf::DW_CFA_remember_state:

170 States.push_back(

171 std::make_pair(Row.getCFAValue(), Row.getRegisterLocations()));

172 break;

173

174 case dwarf::DW_CFA_restore_state:

175 if (States.empty())

177 "DW_CFA_restore_state without a matching "

178 "previous DW_CFA_remember_state");

179 Row.getCFAValue() = States.back().first;

180 Row.getRegisterLocations() = States.back().second;

181 States.pop_back();

182 break;

183

184 case dwarf::DW_CFA_GNU_window_save:

185 switch (CFIP.triple()) {

189

190

191

192

193

194

195 constexpr uint32_t AArch64DWARFPAuthRaState = 34;

196 auto LRLoc = Row.getRegisterLocations().getRegisterLocation(

197 AArch64DWARFPAuthRaState);

198 if (LRLoc) {

200

201 LRLoc->setConstant(LRLoc->getConstant() ^ 1);

202 Row.getRegisterLocations().setRegisterLocation(

203 AArch64DWARFPAuthRaState, *LRLoc);

204 } else {

207 "%s encountered when existing rule for this register is not "

208 "a constant",

210 }

211 } else {

212 Row.getRegisterLocations().setRegisterLocation(

214 }

215 break;

216 }

217

221 for (uint32_t RegNum = 16; RegNum < 32; ++RegNum) {

222 Row.getRegisterLocations().setRegisterLocation(

224 }

225 break;

226

227 default: {

230 "DW_CFA opcode %#x is not supported for architecture %s",

232

233 break;

234 }

235 }

236 break;

237

238 case dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc: {

239 constexpr uint32_t AArch64DWARFPAuthRaState = 34;

240 auto LRLoc = Row.getRegisterLocations().getRegisterLocation(

241 AArch64DWARFPAuthRaState);

242 if (LRLoc) {

244

245 LRLoc->setConstant(LRLoc->getConstant() ^ 0x3);

246 } else {

249 "%s encountered when existing rule for this register is not "

250 "a constant",

252 }

253 } else {

254 Row.getRegisterLocations().setRegisterLocation(

256 }

257 break;

258 }

259

260 case dwarf::DW_CFA_undefined: {

262 if (!RegNum)

264 Row.getRegisterLocations().setRegisterLocation(

266 break;

267 }

268

269 case dwarf::DW_CFA_same_value: {

271 if (!RegNum)

273 Row.getRegisterLocations().setRegisterLocation(

275 break;

276 }

277

278 case dwarf::DW_CFA_GNU_args_size:

279 break;

280

281 case dwarf::DW_CFA_register: {

283 if (!RegNum)

286 if (!NewRegNum)

288 Row.getRegisterLocations().setRegisterLocation(

290 break;

291 }

292

293 case dwarf::DW_CFA_val_offset:

294 case dwarf::DW_CFA_val_offset_sf: {

296 if (!RegNum)

300 return Offset.takeError();

301 Row.getRegisterLocations().setRegisterLocation(

303 break;

304 }

305

306 case dwarf::DW_CFA_expression: {

308 if (!RegNum)

310 Row.getRegisterLocations().setRegisterLocation(

312 break;

313 }

314

315 case dwarf::DW_CFA_val_expression: {

317 if (!RegNum)

319 Row.getRegisterLocations().setRegisterLocation(

321 break;

322 }

323

324 case dwarf::DW_CFA_def_cfa_register: {

326 if (!RegNum)

329 Row.getCFAValue() =

331 else

332 Row.getCFAValue().setRegister(*RegNum);

333 break;

334 }

335

336 case dwarf::DW_CFA_def_cfa_offset:

337 case dwarf::DW_CFA_def_cfa_offset_sf: {

340 return Offset.takeError();

344 "%s found when CFA rule was not RegPlusOffset",

346 }

347 Row.getCFAValue().setOffset(*Offset);

348 break;

349 }

350

351 case dwarf::DW_CFA_def_cfa:

352 case dwarf::DW_CFA_def_cfa_sf: {

354 if (!RegNum)

358 return Offset.takeError();

359 Row.getCFAValue() =

361 break;

362 }

363

364 case dwarf::DW_CFA_LLVM_def_aspace_cfa:

365 case dwarf::DW_CFA_LLVM_def_aspace_cfa_sf: {

367 if (!RegNum)

371 return Offset.takeError();

373 Inst.getOperandAsUnsigned(CFIP, 2);

374 if (!CFAAddrSpace)

377 *RegNum, *Offset, *CFAAddrSpace);

378 break;

379 }

380

381 case dwarf::DW_CFA_def_cfa_expression:

382 Row.getCFAValue() =

384 break;

385 }

386 }

387 return Rows;

388}