Skip to content

Commit

Permalink
Update address ranges of inlined functions and try/catch blocks.
Browse files Browse the repository at this point in the history
Summary:
Update address ranges of inlined functions and try/catch blocks.
This was missing and lead gdb to show weird information in a core dump we inspected
because of the several nestings of inline in the call stack.

This is very similar to Lexical Blocks, so the change is to basically generalize that
code to do the same for DW_AT_try_block, DW_AT_catch_block and DW_AT_inlined_subroutine.

(cherry picked from FBD3169417)
  • Loading branch information
Gabriel Poesia authored and maksfb committed Apr 12, 2016
1 parent e16b5d8 commit 0e77c53
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 36 deletions.
16 changes: 8 additions & 8 deletions bolt/LexicalBlock.h → bolt/AddressRangesDWARFObject.h
@@ -1,4 +1,4 @@
//===--- LexicalBlock.h - DWARF lexical blocks ----------------------------===//
//===--- AddressRangesDWARFObject.h - DWARF Entities with address ranges --===//
//
// The LLVM Compiler Infrastructure
//
Expand All @@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TOOLS_LLVM_BOLT_LEXICAL_BLOCK_H
#define LLVM_TOOLS_LLVM_BOLT_LEXICAL_BLOCK_H
#ifndef LLVM_TOOLS_LLVM_BOLT_ADDRESS_RANGES_DWARF_OBJECT_H
#define LLVM_TOOLS_LLVM_BOLT_ADDRESS_RANGES_DWARF_OBJECT_H

#include "DebugRangesSectionsWriter.h"
#include "BasicBlockOffsetRanges.h"
Expand All @@ -29,13 +29,13 @@ class BasicBlockTable;
class BinaryBasicBlock;
class BinaryFunction;

class LexicalBlock : public AddressRangesOwner {
class AddressRangesDWARFObject : public AddressRangesOwner {
public:
LexicalBlock(const DWARFCompileUnit *CU,
const DWARFDebugInfoEntryMinimal *DIE)
AddressRangesDWARFObject(const DWARFCompileUnit *CU,
const DWARFDebugInfoEntryMinimal *DIE)
: CU(CU), DIE(DIE) { }

/// Add range [BeginAddress, EndAddress) to lexical block.
/// Add range [BeginAddress, EndAddress) to this object.
void addAddressRange(BinaryFunction &Function,
uint64_t BeginAddress,
uint64_t EndAddress) {
Expand Down Expand Up @@ -66,7 +66,7 @@ class LexicalBlock : public AddressRangesOwner {

BasicBlockOffsetRanges BBOffsetRanges;

// Offset of the address ranges of this block in the output .debug_ranges.
// Offset of the address ranges of this object in the output .debug_ranges.
uint32_t AddressRangesOffset;
};

Expand Down
32 changes: 19 additions & 13 deletions bolt/BinaryContext.cpp
Expand Up @@ -71,27 +71,33 @@ BinaryFunction *getBinaryFunctionContainingAddress(
}

// Traverses the DIE tree in a recursive depth-first search and finds lexical
// blocks, saving them in LexicalBlocks.
void findLexicalBlocks(const DWARFCompileUnit *Unit,
const DWARFDebugInfoEntryMinimal *DIE,
std::map<uint64_t, BinaryFunction> &Functions,
std::vector<llvm::bolt::LexicalBlock> &LexicalBlocks) {
if (DIE->getTag() == dwarf::DW_TAG_lexical_block) {
LexicalBlocks.emplace_back(Unit, DIE);
auto &LB = LexicalBlocks.back();
// blocks and instances of inlined subroutines, saving them in
// AddressRangesObjects.
void findAddressRangesObjects(
const DWARFCompileUnit *Unit,
const DWARFDebugInfoEntryMinimal *DIE,
std::map<uint64_t, BinaryFunction> &Functions,
std::vector<llvm::bolt::AddressRangesDWARFObject> &AddressRangesObjects) {
auto Tag = DIE->getTag();
if (Tag == dwarf::DW_TAG_lexical_block ||
Tag == dwarf::DW_TAG_inlined_subroutine ||
Tag == dwarf::DW_TAG_try_block ||
Tag == dwarf::DW_TAG_catch_block) {
AddressRangesObjects.emplace_back(Unit, DIE);
auto &Object = AddressRangesObjects.back();
for (const auto &Range : DIE->getAddressRanges(Unit)) {
if (auto *Function = getBinaryFunctionContainingAddress(Range.first,
Functions)) {
if (Function->isSimple()) {
LB.addAddressRange(*Function, Range.first, Range.second);
Object.addAddressRange(*Function, Range.first, Range.second);
}
}
}
}

// Recursively visit each child.
for (auto Child = DIE->getFirstChild(); Child; Child = Child->getSibling()) {
findLexicalBlocks(Unit, Child, Functions, LexicalBlocks);
findAddressRangesObjects(Unit, Child, Functions, AddressRangesObjects);
}
}

Expand Down Expand Up @@ -163,10 +169,10 @@ void BinaryContext::preprocessFunctionDebugInfo(
UnknownFunctions);
}

// Iterate over DIE trees finding lexical blocks.
// Iterate over DIE trees finding objects that contain address ranges.
for (const auto &CU : DwCtx->compile_units()) {
findLexicalBlocks(CU.get(), CU->getUnitDIE(false), BinaryFunctions,
LexicalBlocks);
findAddressRangesObjects(CU.get(), CU->getUnitDIE(false), BinaryFunctions,
AddressRangesObjects);
}

// Iterate over location lists and save them in LocationLists.
Expand Down
8 changes: 5 additions & 3 deletions bolt/BinaryContext.h
Expand Up @@ -14,7 +14,7 @@
#ifndef LLVM_TOOLS_LLVM_BOLT_BINARY_CONTEXT_H
#define LLVM_TOOLS_LLVM_BOLT_BINARY_CONTEXT_H

#include "LexicalBlock.h"
#include "AddressRangesDWARFObject.h"
#include "LocationList.h"
#include "llvm/ADT/Triple.h"
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
Expand Down Expand Up @@ -75,8 +75,10 @@ class BinaryContext {
/// Maps DWARF CUID to offset of stmt_list attribute in .debug_info.
std::map<unsigned, uint32_t> LineTableOffsetCUMap;

/// List of DWARF lexical blocks in .debug_info.
std::vector<LexicalBlock> LexicalBlocks;
/// List of DWARF entries in .debug_info that have address ranges to be
/// updated. These include lexical blocks (DW_TAG_lexical_block) and concrete
/// instances of inlined subroutines (DW_TAG_inlined_subroutine).
std::vector<AddressRangesDWARFObject> AddressRangesObjects;

/// List of DWARF location lists in .debug_loc.
std::vector<LocationList> LocationLists;
Expand Down
21 changes: 11 additions & 10 deletions bolt/RewriteInstance.cpp
Expand Up @@ -2075,10 +2075,10 @@ void RewriteInstance::rewriteFile() {
Out->keep();
}

void RewriteInstance::updateLexicalBlocksAddresses() {
for (auto &LB : BC->LexicalBlocks) {
for (const auto &Range : LB.getAbsoluteAddressRanges()) {
RangesSectionsWriter.AddRange(&LB, Range.first,
void RewriteInstance::updateAddressRangesObjects() {
for (auto &Obj : BC->AddressRangesObjects) {
for (const auto &Range : Obj.getAbsoluteAddressRanges()) {
RangesSectionsWriter.AddRange(&Obj, Range.first,
Range.second - Range.first);
}
}
Expand Down Expand Up @@ -2150,7 +2150,7 @@ void RewriteInstance::updateDebugInfo() {

updateFunctionRanges();

updateLexicalBlocksAddresses();
updateAddressRangesObjects();

generateDebugRanges();

Expand Down Expand Up @@ -2202,12 +2202,13 @@ void RewriteInstance::updateDWARFAddressRanges() {
DIECompileUnitPair.first);
}

// Update address ranges of lexical blocks.
for (const auto &LB : BC->LexicalBlocks) {
// Update address ranges of DWARF block objects (lexical/try/catch blocks,
// inlined subroutine instances, etc).
for (const auto &Obj : BC->AddressRangesObjects) {
updateDWARFObjectAddressRanges(
LB.getAddressRangesOffset() + DebugRangesSize,
LB.getCompileUnit(),
LB.getDIE());
Obj.getAddressRangesOffset() + DebugRangesSize,
Obj.getCompileUnit(),
Obj.getDIE());
}
}

Expand Down
4 changes: 2 additions & 2 deletions bolt/RewriteInstance.h
Expand Up @@ -212,8 +212,8 @@ class RewriteInstance {
/// Update internal function ranges after functions have been written.
void updateFunctionRanges();

/// Update lexical blocks ranges after optimizations.
void updateLexicalBlocksAddresses();
/// Update objects with address ranges after optimization.
void updateAddressRangesObjects();

/// Generate new contents for .debug_loc.
void updateLocationLists();
Expand Down

0 comments on commit 0e77c53

Please sign in to comment.