LLVM: lib/CodeGen/AsmPrinter/DIEHash.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

23

24using namespace llvm;

25

26#define DEBUG_TYPE "dwarfdebug"

27

28

29

31

32

33 for (const auto &V : Die.values())

34 if (V.getAttribute() == Attr)

35 return V.getDIEString().getString();

36

38}

39

40

41

42void DIEHash::addString(StringRef Str) {

43 LLVM_DEBUG(dbgs() << "Adding string " << Str << " to hash.\n");

44 Hash.update(Str);

45 Hash.update(ArrayRef((uint8_t)'\0'));

46}

47

48

49

50

51

54 do {

58 Byte |= 0x80;

59 Hash.update(Byte);

60 } while (Value != 0);

61}

62

65 bool More;

66 do {

69 More = !((((Value == 0) && ((Byte & 0x40) == 0)) ||

70 ((Value == -1) && ((Byte & 0x40) != 0))));

71 if (More)

72 Byte |= 0x80;

73 Hash.update(Byte);

74 } while (More);

75}

76

77

78void DIEHash::addParentContext(const DIE &Parent) {

79

80 LLVM_DEBUG(dbgs() << "Adding parent context to hash...\n");

81

82

83

85 const DIE *Cur = &Parent;

87 Parents.push_back(Cur);

89 }

90 assert(Cur->getTag() == dwarf::DW_TAG_compile_unit ||

91 Cur->getTag() == dwarf::DW_TAG_type_unit);

92

93

94

96

98

99

101

102

104 LLVM_DEBUG(dbgs() << "... adding context: " << Name << "\n");

105 if (!Name.empty())

106 addString(Name);

107 }

108}

109

110

111void DIEHash::collectAttributes(const DIE &Die, DIEAttrs &Attrs) {

112

113 for (const auto &V : Die.values()) {

116 << " added.\n");

117 switch (V.getAttribute()) {

118#define HANDLE_DIE_HASH_ATTR(NAME) \

119 case dwarf::NAME: \

120 Attrs.NAME = V; \

121 break;

122#include "DIEHashAttributes.def"

123 default:

124 break;

125 }

126 }

127}

128

131

133

134

136

137

138 if (const DIE *Parent = Entry.getParent())

139 addParentContext(*Parent);

140

141

143

144

145 addString(Name);

146

147

148

149

150

151

152

153}

154

156 unsigned DieNumber) {

157

158

160

162

163

164

166}

167

169 const DIE &Entry) {

170 assert(Tag != dwarf::DW_TAG_friend && "No current LLVM clients emit friend "

171 "tags. Add support here when there's "

172 "a use case");

173

174

175 if ((Tag == dwarf::DW_TAG_pointer_type ||

176 Tag == dwarf::DW_TAG_reference_type ||

177 Tag == dwarf::DW_TAG_rvalue_reference_type ||

178 Tag == dwarf::DW_TAG_ptr_to_member_type) &&

179

180

181

182

183 Attribute == dwarf::DW_AT_type) {

184

186 if (Name.empty()) {

187 hashShallowTypeReference(Attribute, Entry, Name);

188 return;

189 }

190 }

191

192 unsigned &DieNumber = Numbering[&Entry];

193 if (DieNumber) {

194 hashRepeatedTypeReference(Attribute, DieNumber);

195 return;

196 }

197

198

200

202

203

204

205 DieNumber = Numbering.size();

206 computeHash(Entry);

207}

208

210 unsigned &DieNumber = Numbering[&Entry];

211 if (DieNumber) {

214 return;

215 }

216 DieNumber = Numbering.size();

218 computeHash(Entry);

219}

220

221

222

224 for (const auto &V : Values)

225 if (V.getType() == DIEValue::isBaseTypeRef) {

226 const DIE &C =

227 *CU->ExprRefedBaseTypes[V.getDIEBaseTypeRef().getIndex()].Die;

229 assert(!Name.empty() &&

230 "Base types referenced from DW_OP_convert should have a name");

231 hashNestedType(C, Name);

232 } else

233 Hash.update(V.getDIEInteger().getValue());

234}

235

236

237void DIEHash::hashLocList(const DIELocList &LocList) {

238 HashingByteStreamer Streamer(*this);

239 DwarfDebug &DD = *AP->getDwarfDebug();

240 const DebugLocStream &Locs = DD.getDebugLocs();

242 for (const DebugLocStream::Entry &Entry : Locs.getEntries(List))

244}

245

246

247

250

251

252

253

254

255

256

257

258 switch (Value.getType()) {

261

262

263

264

265 case DIEValue::isEntry:

267 break;

268 case DIEValue::isInteger: {

271 switch (Value.getForm()) {

272 case dwarf::DW_FORM_data1:

273 case dwarf::DW_FORM_data2:

274 case dwarf::DW_FORM_data4:

275 case dwarf::DW_FORM_data8:

276 case dwarf::DW_FORM_udata:

277 case dwarf::DW_FORM_sdata:

280 break;

281

282

283 case dwarf::DW_FORM_flag_present:

284 case dwarf::DW_FORM_flag:

287 break;

288 default:

290 }

291 break;

292 }

293 case DIEValue::isString:

297 addString(Value.getDIEString().getString());

298 break;

299 case DIEValue::isInlineString:

303 addString(Value.getDIEInlineString().getString());

304 break;

305 case DIEValue::isBlock:

306 case DIEValue::isLoc:

307 case DIEValue::isLocList:

311 if (Value.getType() == DIEValue::isBlock) {

312 addULEB128(Value.getDIEBlock().computeSize(AP->getDwarfFormParams()));

313 hashBlockData(Value.getDIEBlock().values());

314 } else if (Value.getType() == DIEValue::isLoc) {

315 addULEB128(Value.getDIELoc().computeSize(AP->getDwarfFormParams()));

316 hashBlockData(Value.getDIELoc().values());

317 } else {

318

319

320

321 hashLocList(Value.getDIELocList());

322 }

323 break;

324

325 case DIEValue::isExpr:

326 case DIEValue::isLabel:

327 case DIEValue::isBaseTypeRef:

328 case DIEValue::isDelta:

329 case DIEValue::isAddrOffset:

331 }

332}

333

334

335

336void DIEHash::hashAttributes(const DIEAttrs &Attrs, dwarf::Tag Tag) {

337#define HANDLE_DIE_HASH_ATTR(NAME) \

338 { \

339 if (Attrs.NAME) \

340 hashAttribute(Attrs.NAME, Tag); \

341 }

342#include "DIEHashAttributes.def"

343

344}

345

346

347void DIEHash::addAttributes(const DIE &Die) {

348 DIEAttrs Attrs = {};

349 collectAttributes(Die, Attrs);

350 hashAttributes(Attrs, Die.getTag());

351}

352

353void DIEHash::hashNestedType(const DIE &Die, StringRef Name) {

354

355

357

358

360

361

362 addString(Name);

363}

364

365

366

367

368void DIEHash::computeHash(const DIE &Die) {

369

372

373

374 addAttributes(Die);

375

376

377 for (const auto &C : Die.children()) {

378

379

380 if (isType(C.getTag()) || (C.getTag() == dwarf::DW_TAG_subprogram && isType(C.getParent()->getTag()))) {

382

383 if (Name.empty()) {

384 hashNestedType(C, Name);

385 continue;

386 }

387 }

388 computeHash(C);

389 }

390

391

392 Hash.update(ArrayRef((uint8_t)'\0'));

393}

394

395

396

397

398

400 Numbering.clear();

401 Numbering[&Die] = 1;

402

403 if (!DWOName.empty())

404 Hash.update(DWOName);

405

406 computeHash(Die);

407

408

410 Hash.final(Result);

411

412

413

414

415 return Result.high();

416}

417

418

419

420

421

423 Numbering.clear();

424 Numbering[&Die] = 1;

425

427 addParentContext(*Parent);

428

429

430 computeHash(Die);

431

432

434 Hash.final(Result);

435

436

437

438

439 return Result.high();

440}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static StringRef getDIEStringAttr(const DIE &Die, uint16_t Attr)

Grabs the string in whichever attribute is passed in and returns a reference to it.

Definition DIEHash.cpp:30

This file contains constants used for implementing Dwarf debug support.

static bool isType(const Metadata *MD)

Functions, function parameters, and return types can have attributes to indicate how they should be t...

void hashRawTypeReference(const DIE &Entry)

Definition DIEHash.cpp:209

LLVM_ABI_FOR_TEST uint64_t computeTypeSignature(const DIE &Die)

Computes the type signature.

Definition DIEHash.cpp:422

void addSLEB128(int64_t Value)

Encodes and adds.

Definition DIEHash.cpp:63

uint64_t computeCUSignature(StringRef DWOName, const DIE &Die)

Computes the CU signature.

Definition DIEHash.cpp:399

void addULEB128(uint64_t Value)

Encodes and adds.

Definition DIEHash.cpp:52

Represents a pointer to a location list in the debug_loc section.

size_t getValue() const

Grab the current index out.

iterator_range< const_value_iterator > const_value_range

A structured debug information entry.

dwarf::Tag getTag() const

LLVM_ABI DIE * getParent() const

const List & getList(size_t LI) const

ArrayRef< Entry > getEntries(const List &L) const

void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)

Emit an entry for the debug loc section.

const DebugLocStream & getDebugLocs() const

Returns the entries for the .debug_loc section.

LLVM_ABI void update(ArrayRef< uint8_t > Data)

Updates the hash for the byte stream provided.

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

constexpr bool empty() const

empty - Check if the string is empty.

LLVM Value Representation.

LLVM_ABI StringRef AttributeString(unsigned Attribute)

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char Attrs[]

Key for Kernel::Metadata::mAttrs.

@ C

The default llvm calling convention, compatible with C.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

auto reverse(ContainerTy &&C)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

ArrayRef(const T &OneElt) -> ArrayRef< T >