+ debug_info = (uint8_t*)_file->fileContent() + _file->_dwarfDebugInfoSect->offset();
+ debug_abbrev = (uint8_t*)_file->fileContent() + _file->_dwarfDebugAbbrevSect->offset();
+ next_cu = debug_info;
+
+ while ((uint64_t)(next_cu - debug_info) < _file->_dwarfDebugInfoSect->size()) {
+ di = next_cu;
+ sz = A::P::E::get32(*(uint32_t*)di);
+ di += 4;
+ dwarf64 = sz == 0xffffffff;
+ if (dwarf64)
+ sz = A::P::E::get64(*(uint64_t*)di), di += 8;
+ else if (sz > 0xffffff00)
+ /* Unknown dwarf format. */
+ return false;
+
+ /* Verify claimed size. */
+ if (sz + (di - debug_info) > _file->_dwarfDebugInfoSect->size() || sz <= (dwarf64 ? 23 : 11))
+ return false;
+
+ next_cu = di + sz;
+
+ vers = A::P::E::get16(*(uint16_t*)di);
+ if (vers < 2 || vers > 4)
+ /* DWARF version wrong for this code.
+ Chances are we could continue anyway, but we don't know for sure. */
+ return false;
+ di += 2;
+
+ /* Find the debug_abbrev section. */
+ abbrev_base = dwarf64 ? A::P::E::get64(*(uint64_t*)di) : A::P::E::get32(*(uint32_t*)di);
+ di += dwarf64 ? 8 : 4;
+
+ if (abbrev_base > _file->_dwarfDebugAbbrevSect->size())
+ return false;
+ da = debug_abbrev + abbrev_base;
+ enda = debug_abbrev + _file->_dwarfDebugAbbrevSect->size();
+
+ address_size = *di++;
+
+ /* Find the abbrev number we're looking for. */
+ end = di + sz;
+ abbrev = read_uleb128 (&di, end);
+ if (abbrev == (uint64_t) -1)
+ return false;
+
+ /* Skip through the debug_abbrev section looking for that abbrev. */
+ for (;;)
+ {
+ uint64_t this_abbrev = read_uleb128 (&da, enda);
+ uint64_t attr;
+
+ if (this_abbrev == abbrev)
+ /* This is almost always taken. */
+ break;
+ skip_leb128 (&da, enda); /* Skip the tag. */
+ if (da == enda)
+ return false;
+ da++; /* Skip the DW_CHILDREN_* value. */
+
+ do {
+ attr = read_uleb128 (&da, enda);
+ skip_leb128 (&da, enda);
+ } while (attr != 0 && attr != (uint64_t) -1);
+ if (attr != 0)
+ return false;
+ }
+
+ /* Check that the abbrev is one for a DW_TAG_compile_unit. */
+ if (read_uleb128 (&da, enda) != DW_TAG_compile_unit)
+ return false;
+ if (da == enda)
+ return false;
+ da++; /* Skip the DW_CHILDREN_* value. */
+
+ /* Now, go through the DIE looking for DW_AT_name,
+ DW_AT_comp_dir, and DW_AT_stmt_list. */
+ bool skip_to_next_cu = false;
+ while (!skip_to_next_cu) {
+
+ uint64_t attr = read_uleb128 (&da, enda);
+ uint64_t form = read_uleb128 (&da, enda);
+
+ if (attr == (uint64_t) -1)
+ return false;
+ else if (attr == 0)
+ return true;
+ if (form == DW_FORM_indirect)
+ form = read_uleb128 (&di, end);
+
+ switch (attr) {
+ case DW_AT_name:
+ *name = getDwarfString(form, di);
+ /* Swift object files may contain two CUs: One
+ describes the Swift code, one is created by the
+ clang importer. Skip over the CU created by the
+ clang importer as it may be empty. */
+ if (std::string(*name) == "<swift-imported-modules>")
+ skip_to_next_cu = true;
+ break;
+ case DW_AT_comp_dir:
+ *comp_dir = getDwarfString(form, di);
+ break;
+ case DW_AT_stmt_list:
+ *stmt_list = getDwarfOffset(form, di, dwarf64);
+ break;
+ default:
+ if (! skip_form (&di, end, form, address_size, dwarf64))
+ return false;
+ }
+ }
+ }
+ return false;