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

1

2

3

4

5

6

7

8

16#include

17#include

18

19using namespace llvm;

20

21namespace {

22

23enum class DWARFSectionKindV2 {

24 DW_SECT_INFO = 1,

25 DW_SECT_TYPES = 2,

26 DW_SECT_ABBREV = 3,

27 DW_SECT_LINE = 4,

28 DW_SECT_LOC = 5,

29 DW_SECT_STR_OFFSETS = 6,

30 DW_SECT_MACINFO = 7,

31 DW_SECT_MACRO = 8,

32};

33

34}

35

36

38 return ID >= DW_SECT_INFO && ID <= DW_SECT_RNGLISTS &&

40}

41

43 unsigned IndexVersion) {

44 if (IndexVersion == 5) {

46 return static_cast<uint32_t>(Kind);

47 }

48 assert(IndexVersion == 2);

49 switch (Kind) {

50#define CASE(S,T) \

51 case DW_SECT_##S: \

52 return static_cast<uint32_t>(DWARFSectionKindV2::DW_SECT_##T)

53 CASE(INFO, INFO);

55 CASE(ABBREV, ABBREV);

56 CASE(LINE, LINE);

57 CASE(EXT_LOC, LOC);

58 CASE(STR_OFFSETS, STR_OFFSETS);

59 CASE(EXT_MACINFO, MACINFO);

60 CASE(MACRO, MACRO);

61#undef CASE

62 default:

63

65 }

66}

67

69 unsigned IndexVersion) {

70 if (IndexVersion == 5)

74 assert(IndexVersion == 2);

75 switch (static_cast<DWARFSectionKindV2>(Value)) {

76#define CASE(S,T) \

77 case DWARFSectionKindV2::DW_SECT_##S: \

78 return DW_SECT_##T

79 CASE(INFO, INFO);

81 CASE(ABBREV, ABBREV);

82 CASE(LINE, LINE);

83 CASE(LOC, EXT_LOC);

84 CASE(STR_OFFSETS, STR_OFFSETS);

85 CASE(MACINFO, EXT_MACINFO);

86 CASE(MACRO, MACRO);

87#undef CASE

88 }

90}

91

92bool DWARFUnitIndex::Header::parse(DataExtractor IndexData,

94 const uint64_t BeginOffset = *OffsetPtr;

96 return false;

97

98

99

100

101 Version = IndexData.getU32(OffsetPtr);

102 if (Version != 2) {

103 *OffsetPtr = BeginOffset;

104 Version = IndexData.getU16(OffsetPtr);

105 if (Version != 5)

106 return false;

107 *OffsetPtr += 2;

108 }

109 NumColumns = IndexData.getU32(OffsetPtr);

110 NumUnits = IndexData.getU32(OffsetPtr);

111 NumBuckets = IndexData.getU32(OffsetPtr);

112 return true;

113}

114

115void DWARFUnitIndex::Header::dump(raw_ostream &OS) const {

116 OS << format("version = %u, units = %u, slots = %u\n\n", Version, NumUnits, NumBuckets);

117}

118

120 bool b = parseImpl(IndexData);

121 if (!b) {

122

123 Header.NumBuckets = 0;

124

125 ColumnKinds.reset();

126 Rows.reset();

127 }

128 return b;

129}

130

131bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {

133 if (!Header.parse(IndexData, &Offset))

134 return false;

135

136

137 if (Header.Version == 5)

138 InfoColumnKind = DW_SECT_INFO;

139

141 Offset, Header.NumBuckets * (8 + 4) +

142 (2 * Header.NumUnits + 1) * 4 * Header.NumColumns))

143 return false;

144

145 Rows = std::make_unique<Entry[]>(Header.NumBuckets);

146 auto Contribs =

147 std::make_unique<Entry::SectionContribution *[]>(Header.NumUnits);

148 ColumnKinds = std::make_unique<DWARFSectionKind[]>(Header.NumColumns);

149 RawSectionIds = std::make_unique<uint32_t[]>(Header.NumColumns);

150

151

152 for (unsigned i = 0; i != Header.NumBuckets; ++i)

153 Rows[i].Signature = IndexData.getU64(&Offset);

154

155

156 for (unsigned i = 0; i != Header.NumBuckets; ++i) {

158 if (!Index)

159 continue;

160 Rows[i].Index = this;

161 Rows[i].Contributions =

162 std::make_uniqueEntry::SectionContribution\[\](Header.NumColumns);

163 Contribs[Index - 1] = Rows[i].Contributions.get();

164 }

165

166

167 for (unsigned i = 0; i != Header.NumColumns; ++i) {

168 RawSectionIds[i] = IndexData.getU32(&Offset);

170 if (ColumnKinds[i] == InfoColumnKind) {

171 if (InfoColumn != -1)

172 return false;

173 InfoColumn = i;

174 }

175 }

176

177 if (InfoColumn == -1)

178 return false;

179

180

181 for (unsigned i = 0; i != Header.NumUnits; ++i) {

182 auto *Contrib = Contribs[i];

183 for (unsigned i = 0; i != Header.NumColumns; ++i)

184 Contrib[i].setOffset(IndexData.getU32(&Offset));

185 }

186

187

188 for (unsigned i = 0; i != Header.NumUnits; ++i) {

189 auto *Contrib = Contribs[i];

190 for (unsigned i = 0; i != Header.NumColumns; ++i)

191 Contrib[i].setLength(IndexData.getU32(&Offset));

192 }

193

194 return true;

195}

196

197StringRef DWARFUnitIndex::getColumnHeader(DWARFSectionKind DS) {

198 switch (DS) {

199#define HANDLE_DW_SECT(ID, NAME) \

200 case DW_SECT_##NAME: \

201 return #NAME;

202#include "llvm/BinaryFormat/Dwarf.def"

204 return "TYPES";

206 return "LOC";

208 return "MACINFO";

210 return StringRef();

211 }

213}

214

216 if (!*this)

217 return;

218

219 Header.dump(OS);

220 OS << "Index Signature ";

221 for (unsigned i = 0; i != Header.NumColumns; ++i) {

223 StringRef Name = getColumnHeader(Kind);

224 if (!Name.empty())

225 OS << ' '

227 Kind == DWARFSectionKind::DW_SECT_INFO ? 40 : 24);

228 else

229 OS << format(" Unknown: %-15" PRIu32, RawSectionIds[i]);

230 }

231 OS << "\n----- ------------------";

232 for (unsigned i = 0; i != Header.NumColumns; ++i) {

234 if (Kind == DWARFSectionKind::DW_SECT_INFO ||

236 OS << " ----------------------------------------";

237 else

238 OS << " ------------------------";

239 }

240 OS << '\n';

241 for (unsigned i = 0; i != Header.NumBuckets; ++i) {

242 auto &Row = Rows[i];

243 if (auto *Contribs = Row.Contributions.get()) {

244 OS << format("%5u 0x%016" PRIx64 " ", i + 1, Row.Signature);

245 for (unsigned i = 0; i != Header.NumColumns; ++i) {

246 auto &Contrib = Contribs[i];

248 if (Kind == DWARFSectionKind::DW_SECT_INFO ||

250 OS << format("[0x%016" PRIx64 ", 0x%016" PRIx64 ") ",

251 Contrib.getOffset(),

252 Contrib.getOffset() + Contrib.getLength());

253 else

254 OS << format("[0x%08" PRIx32 ", 0x%08" PRIx32 ") ",

255 Contrib.getOffset32(),

256 Contrib.getOffset32() + Contrib.getLength32());

257 }

258 OS << '\n';

259 }

260 }

261}

262

266 for (; i != Index->Header.NumColumns; ++i)

267 if (Index->ColumnKinds[i] == Sec)

268 return &Contributions[i];

269 return nullptr;

270}

271

274 return Contributions[Index->InfoColumn];

275}

276

279 return &Contributions[Index->InfoColumn];

280}

281

284 if (OffsetLookup.empty()) {

285 for (uint32_t i = 0; i != Header.NumBuckets; ++i)

286 if (Rows[i].Contributions)

287 OffsetLookup.push_back(&Rows[i]);

289 return E1->Contributions[InfoColumn].getOffset() <

290 E2->Contributions[InfoColumn].getOffset();

291 });

292 }

294 return E2->Contributions[InfoColumn].getOffset() <= Offset;

295 });

296 if (I == OffsetLookup.begin())

297 return nullptr;

298 --I;

299 const auto *E = *I;

300 const auto &InfoContrib = E->Contributions[InfoColumn];

301 if ((InfoContrib.getOffset() + InfoContrib.getLength()) <= Offset)

302 return nullptr;

303 return E;

304}

305

307 uint64_t Mask = Header.NumBuckets - 1;

308

309 auto H = S & Mask;

310 auto HP = ((S >> 32) & Mask) | 1;

311

312

313 while (Rows[H].getSignature() != S && Rows[H].Index != nullptr)

314 H = (H + HP) & Mask;

315

316

317

318 if (Rows[H].Index == nullptr)

319 return nullptr;

320

321 return &Rows[H];

322}

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

constexpr bool isKnownV5SectionID(uint32_t ID)

Definition DWARFUnitIndex.cpp:37

static std::string getSignature(FunctionType *FTy)

LLVM_ABI const SectionContribution * getContribution() const

Definition DWARFUnitIndex.cpp:278

LLVM_ABI void dump(raw_ostream &OS) const

Definition DWARFUnitIndex.cpp:215

LLVM_ABI bool parse(DataExtractor IndexData)

Definition DWARFUnitIndex.cpp:119

LLVM_ABI const Entry * getFromHash(uint64_t Offset) const

Definition DWARFUnitIndex.cpp:306

LLVM_ABI const Entry * getFromOffset(uint64_t Offset) const

Definition DWARFUnitIndex.cpp:283

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

LLVM Value Representation.

This class implements an extremely fast bulk output stream that can only output to a stream.

#define llvm_unreachable(msg)

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

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

This is an optimization pass for GlobalISel generic memory operations.

auto partition_point(R &&Range, Predicate P)

Binary search for the first iterator in a range where a predicate is false.

LLVM_ABI DWARFSectionKind deserializeSectionKind(uint32_t Value, unsigned IndexVersion)

Convert a value read from an index section to the internal representation.

Definition DWARFUnitIndex.cpp:68

DWARFSectionKind

The enum of section identifiers to be used in internal interfaces.

@ DW_SECT_EXT_unknown

Denotes a value read from an index section that does not correspond to any of the supported standards...

LLVM_ABI uint32_t serializeSectionKind(DWARFSectionKind Kind, unsigned IndexVersion)

Convert the internal value for a section kind to an on-disk value.

Definition DWARFUnitIndex.cpp:42

FunctionAddr VTableAddr uintptr_t uintptr_t Version

void sort(IteratorTy Start, IteratorTy End)

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

FormattedString left_justify(StringRef Str, unsigned Width)

left_justify - append spaces after string so total output is Width characters.