/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // DWARF record parser #pragma once #include #include #include #include #include #include #include #include #include namespace folly { namespace symbolizer { #if FOLLY_HAVE_DWARF && FOLLY_HAVE_ELF struct CallLocation; class DwarfImpl { public: explicit DwarfImpl( ElfCacheBase* elfCache, CompilationUnits& cu, LocationInfoMode mode); /** * Find the @locationInfo for @address in the compilation unit @cu. * * Best effort: * - fills @inlineFrames if mode == FULL_WITH_INLINE, * - calls @eachParameterName on the function parameters. * * if @checkAddress is true, we verify that the address is mapped to * a range in this CU before running the line number VM */ bool findLocation( uintptr_t address, LocationInfo& info, folly::Range inlineFrames, folly::FunctionRef eachParameterName, bool checkAddress = true) const; private: using AttributeValue = boost::variant; /** * Finds a subprogram debugging info entry that contains a given address among * children of given die. Depth first search. */ bool findSubProgramDieForAddress( const CompilationUnit& cu, const Die& die, uint64_t address, folly::Optional baseAddrCU, Die& subprogram) const; /** * Finds inlined subroutine DIEs and their caller lines that contains a given * address among children of given die. Depth first search. */ void findInlinedSubroutineDieForAddress( const CompilationUnit& cu, const Die& die, const DwarfLineNumberVM& lineVM, uint64_t address, folly::Optional baseAddrCU, folly::Range locations, size_t& numFound) const; CompilationUnit findCompilationUnit( const CompilationUnit& cu, uint64_t targetOffset) const; /** * Find the actual definition DIE instead of declaration for the given die. */ Die findDefinitionDie(const CompilationUnit& cu, const Die& die) const; /** * Iterates over all children of a debugging info entry, calling the given * callable for each. Iteration is stopped early if any of the calls return * false. Returns the offset of next DIE after iterations. */ size_t forEachChild( const CompilationUnit& cu, const Die& die, folly::FunctionRef f) const; template folly::Optional getAttribute( const CompilationUnit& cu, const Die& die, uint64_t attrName) const; /** * Check if the given address is in the range list at the given offset in * .debug_ranges. */ bool isAddrInRangeList( const CompilationUnit& cu, uint64_t address, folly::Optional baseAddr, size_t offset, uint8_t addrSize) const; void fillInlineFrames( uintptr_t address, LocationInfo& locationInfo, folly::Range inlineLocations, folly::Range inlineFrames) const; ElfCacheBase* elfCache_; CompilationUnits& cu_; const LocationInfoMode mode_; }; #endif } // namespace symbolizer } // namespace folly