+ if (!elf_) { // No file.
+ return false;
+ }
+
+ if (!aranges_.empty()) {
+ // Fast path: find the right .debug_info entry by looking up the
+ // address in .debug_aranges.
+ uint64_t offset = 0;
+ if (findDebugInfoOffset(address, aranges_, offset)) {
+ // Read compilation unit header from .debug_info
+ folly::StringPiece infoEntry(info_);
+ infoEntry.advance(offset);
+ findLocation(address, infoEntry, locationInfo);
+ return locationInfo.hasFileAndLine;
+ } else if (mode == LocationInfoMode::FAST) {
+ // NOTE: Clang (when using -gdwarf-aranges) doesn't generate entries
+ // in .debug_aranges for some functions, but always generates
+ // .debug_info entries. Scanning .debug_info is slow, so fall back to
+ // it only if such behavior is requested via LocationInfoMode.
+ return false;
+ } else {
+ DCHECK(mode == LocationInfoMode::FULL);
+ // Fall back to the linear scan.
+ }
+ }
+
+
+ // Slow path (linear scan): Iterate over all .debug_info entries
+ // and look for the address in each compilation unit.
+ folly::StringPiece infoEntry(info_);
+ while (!infoEntry.empty() && !locationInfo.hasFileAndLine) {
+ findLocation(address, infoEntry, locationInfo);
+ }
+ return locationInfo.hasFileAndLine;