29 #define DEBUG_TYPE "dwarfdebug"
36 for (
const auto &V : Die.
values())
37 if (V.getAttribute() == Attr)
38 return V.getDIEString().getString();
46 DEBUG(
dbgs() <<
"Adding string " << Str <<
" to hash.\n");
56 DEBUG(
dbgs() <<
"Adding ULEB128 " << Value <<
" to hash.\n");
58 uint8_t Byte = Value & 0x7f;
67 DEBUG(
dbgs() <<
"Adding ULEB128 " << Value <<
" to hash.\n");
70 uint8_t Byte = Value & 0x7f;
72 More = !((((Value == 0) && ((Byte & 0x40) == 0)) ||
73 ((Value == -1) && ((Byte & 0x40) != 0))));
81 void DIEHash::addParentContext(
const DIE &Parent) {
83 DEBUG(
dbgs() <<
"Adding parent context to hash...\n");
88 const DIE *Cur = &Parent;
93 assert(Cur->
getTag() == dwarf::DW_TAG_compile_unit ||
94 Cur->
getTag() == dwarf::DW_TAG_type_unit);
101 const DIE &Die = **
I;
111 DEBUG(
dbgs() <<
"... adding context: " << Name <<
"\n");
118 void DIEHash::collectAttributes(
const DIE &Die, DIEAttrs &Attrs) {
119 #define COLLECT_ATTR(NAME) \
124 for (
const auto &V : Die.
values()) {
128 switch (V.getAttribute()) {
194 addParentContext(*Parent);
211 unsigned DieNumber) {
225 assert(Tag != dwarf::DW_TAG_friend &&
"No current LLVM clients emit friend "
226 "tags. Add support here when there's "
230 if ((Tag == dwarf::DW_TAG_pointer_type ||
231 Tag == dwarf::DW_TAG_reference_type ||
232 Tag == dwarf::DW_TAG_rvalue_reference_type ||
233 Tag == dwarf::DW_TAG_ptr_to_member_type) &&
242 hashShallowTypeReference(Attribute, Entry, Name);
247 unsigned &DieNumber = Numbering[&Entry];
249 hashRepeatedTypeReference(Attribute, DieNumber);
260 DieNumber = Numbering.size();
267 for (
const auto &V : Values)
268 Hash.
update((uint64_t)V.getDIEInteger().getValue());
272 void DIEHash::hashLocList(
const DIELocList &LocList) {
299 case DIEValue::isEntry:
300 hashDIEEntry(Attribute, Tag, Value.getDIEEntry().getEntry());
302 case DIEValue::isInteger: {
313 addSLEB128((int64_t)Value.getDIEInteger().getValue());
320 addULEB128((int64_t)Value.getDIEInteger().getValue());
327 case DIEValue::isString:
331 addString(Value.getDIEString().getString());
333 case DIEValue::isBlock:
334 case DIEValue::isLoc:
335 case DIEValue::isLocList:
339 if (Value.
getType() == DIEValue::isBlock) {
340 addULEB128(Value.getDIEBlock().ComputeSize(AP));
341 hashBlockData(Value.getDIEBlock().values());
342 }
else if (Value.
getType() == DIEValue::isLoc) {
343 addULEB128(Value.getDIELoc().ComputeSize(AP));
344 hashBlockData(Value.getDIELoc().values());
349 hashLocList(Value.getDIELocList());
353 case DIEValue::isExpr:
354 case DIEValue::isLabel:
355 case DIEValue::isDelta:
356 case DIEValue::isTypeSignature:
363 void DIEHash::hashAttributes(
const DIEAttrs &Attrs,
dwarf::Tag Tag) {
364 #define ADD_ATTR(ATTR) \
367 hashAttribute(ATTR, Tag); \
371 ADD_ATTR(Attrs.DW_AT_accessibility);
372 ADD_ATTR(Attrs.DW_AT_address_class);
384 ADD_ATTR(Attrs.DW_AT_containing_type);
386 ADD_ATTR(Attrs.DW_AT_data_bit_offset);
387 ADD_ATTR(Attrs.DW_AT_data_location);
388 ADD_ATTR(Attrs.DW_AT_data_member_location);
389 ADD_ATTR(Attrs.DW_AT_decimal_scale);
391 ADD_ATTR(Attrs.DW_AT_default_value);
405 ADD_ATTR(Attrs.DW_AT_picture_string);
409 ADD_ATTR(Attrs.DW_AT_string_length);
410 ADD_ATTR(Attrs.DW_AT_threads_scaled);
414 ADD_ATTR(Attrs.DW_AT_variable_parameter);
417 ADD_ATTR(Attrs.DW_AT_vtable_elem_location);
424 void DIEHash::addAttributes(
const DIE &Die) {
426 collectAttributes(Die, Attrs);
427 hashAttributes(Attrs, Die.
getTag());
430 void DIEHash::hashNestedType(
const DIE &Die,
StringRef Name) {
445 void DIEHash::computeHash(
const DIE &Die) {
457 if (
isType(
C.getTag()) ||
C.getTag() == dwarf::DW_TAG_subprogram) {
461 hashNestedType(
C, Name);
484 addParentContext(*Parent);
534 addParentContext(*Parent);
ArrayRef< Entry > getEntries(const List &L) const
void push_back(const T &Elt)
uint64_t computeCUSignature(const DIE &Die)
Computes the CU signature.
void addULEB128(uint64_t Value)
Encodes and adds.
Collects and handles dwarf debug information.
const char * AttributeString(unsigned Attribute)
DIELocList - Represents a pointer to a location list in the debug_loc section.
size_t getValue() const
getValue - Grab the current index out.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
#define COLLECT_ATTR(NAME)
uint64_t read64le(const void *p)
const List & getList(size_t LI) const
uint64_t computeTypeSignature(const DIE &Die)
Computes the type signature.
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
dwarf::Tag getTag() const
DIE - A structured debug information entry.
DwarfDebug * getDwarfDebug()
uint64_t computeDIEODRSignature(const DIE &Die)
Computes the ODR signature.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const DebugLocStream & getDebugLocs() const
Returns the entries for the .debug_loc section.
dwarf::Attribute getAttribute() const
dwarf::Form getForm() const
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocStream::Entry &Entry)
Emit an entry for the debug loc section.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
A range adaptor for a pair of iterators.
void addSLEB128(int64_t Value)
Encodes and adds.
reverse_iterator rbegin()
LLVM Value Representation.
StringRef - Represent a constant reference to a string, i.e.
Byte stream of .debug_loc entries.
static StringRef getDIEStringAttr(const DIE &Die, uint16_t Attr)
Grabs the string in whichever attribute is passed in and returns a reference to it.
bool empty() const
empty - Check if the string is empty.