diff options
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 33 | ||||
-rw-r--r-- | lldb/test/inlines/Makefile | 125 | ||||
-rw-r--r-- | lldb/test/inlines/inlines.c | 38 |
3 files changed, 190 insertions, 6 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 463599f9bd3..f4e4d9e5cdf 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1144,8 +1144,8 @@ SymbolFileDWARF::ParseFunctionBlocks switch (tag) { - case DW_TAG_subprogram: case DW_TAG_inlined_subroutine: + case DW_TAG_subprogram: case DW_TAG_lexical_block: { DWARFDebugRanges::RangeList ranges; @@ -1160,25 +1160,44 @@ SymbolFileDWARF::ParseFunctionBlocks int call_file = 0; int call_line = 0; int call_column = 0; - if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled_name, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column)) + if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled_name, ranges, + decl_file, decl_line, decl_column, + call_file, call_line, call_column)) { if (tag == DW_TAG_subprogram) { assert (subprogram_low_pc == LLDB_INVALID_ADDRESS); subprogram_low_pc = ranges.LowestAddress(0); } - + else if (tag == DW_TAG_inlined_subroutine) + { + // We get called here for inlined subroutines in two ways. + // The first time is when we are making the Function object + // for this inlined concrete instance. Since we're creating a top level block at + // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to + // adjust the containing address. + // The second time is when we are parsing the blocks inside the function that contains + // the inlined concrete instance. Since these will be blocks inside the containing "real" + // function the offset will be for that function. + if (subprogram_low_pc == LLDB_INVALID_ADDRESS) + { + subprogram_low_pc = ranges.LowestAddress(0); + } + } + AddRangesToBlock (blocks, blockID, ranges, subprogram_low_pc); if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL)) { std::auto_ptr<Declaration> decl_ap; if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column)); + decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), + decl_line, decl_column)); std::auto_ptr<Declaration> call_ap; if (call_file != 0 || call_line != 0 || call_column != 0) - call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), call_line, call_column)); + call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), + call_line, call_column)); blocks.SetInlinedFunctionInfo(blockID, name, mangled_name, decl_ap.get(), call_ap.get()); } @@ -1187,7 +1206,8 @@ SymbolFileDWARF::ParseFunctionBlocks if (parse_children && die->HasChildren()) { - blocks_added += ParseFunctionBlocks(sc, blockID, dwarf_cu, die->GetFirstChild(), subprogram_low_pc, true, true); + blocks_added += ParseFunctionBlocks(sc, blockID, dwarf_cu, die->GetFirstChild(), + subprogram_low_pc, true, true); } } } @@ -2854,6 +2874,7 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar } break; + case DW_TAG_inlined_subroutine: case DW_TAG_subprogram: case DW_TAG_subroutine_type: { diff --git a/lldb/test/inlines/Makefile b/lldb/test/inlines/Makefile new file mode 100644 index 00000000000..fcebb691d08 --- /dev/null +++ b/lldb/test/inlines/Makefile @@ -0,0 +1,125 @@ +#---------------------------------------------------------------------- +# Fill in the source files to build +#---------------------------------------------------------------------- +C_SOURCES := inlines.c +CXX_SOURCES := +OBJC_SOURCES := +OBJCXX_SOURCES := + +# Uncomment line below for debugging shell commands +# SHELL = /bin/sh -x + +#---------------------------------------------------------------------- +# Change any build/tool options needed +#---------------------------------------------------------------------- +DS := /usr/bin/dsymutil +DSFLAGS = +CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 +CPLUSPLUSFLAGS +=$(CFLAGS) +CPPFLAGS +=$(CFLAGS) +LD = gcc +LDFLAGS = $(CFLAGS) +OBJECTS = +EXE=a.out +DSYM=$(EXE).dSYM + +#---------------------------------------------------------------------- +# Check if we have any C source files +#---------------------------------------------------------------------- +ifneq "$(strip $(C_SOURCES))" "" + OBJECTS +=$(strip $(C_SOURCES:.c=.o)) +endif + +#---------------------------------------------------------------------- +# Check if we have any C++ source files +#---------------------------------------------------------------------- +ifneq "$(strip $(CXX_SOURCES))" "" + OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) + LD = g++ +endif + +#---------------------------------------------------------------------- +# Check if we have any ObjC source files +#---------------------------------------------------------------------- +ifneq "$(strip $(OBJC_SOURCES))" "" + OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) + LDFLAGS +=-lobjc +endif + +#---------------------------------------------------------------------- +# Check if we have any ObjC++ source files +#---------------------------------------------------------------------- +ifneq "$(strip $(OBJCXX_SOURCES))" "" + OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) + LD = g++ + ifeq $(findstring lobjc,$(LDFLAGS)) "" + LDFLAGS +=-lobjc + endif +endif + + +#---------------------------------------------------------------------- +# Make the dSYM file from the executable +#---------------------------------------------------------------------- +$(DSYM) : $(EXE) + $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" + +#---------------------------------------------------------------------- +# Compile the executable from all the objects (default rule) with no +# dsym file. +#---------------------------------------------------------------------- +$(EXE) : $(OBJECTS) + $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" + + +#---------------------------------------------------------------------- +# Automatic variables based on items already entered. Below we create +# an objects lists from the list of sources by replacing all entries +# that end with .c with .o, and we also create a list of prerequisite +# files by replacing all .c files with .d. +#---------------------------------------------------------------------- +PREREQS := $(OBJECTS:.o=.d) + +#---------------------------------------------------------------------- +# Rule for Generating Prerequisites Automatically using .d files and +# the compiler -MM option. The -M option will list all system headers, +# and the -MM option will list all non-system dependencies. +#---------------------------------------------------------------------- +%.d: %.c + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +%.d: %.cpp + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +%.d: %.m + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +%.d: %.mm + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +#---------------------------------------------------------------------- +# Include all of the makefiles for each source file so we don't have +# to manually track all of the prerequisites for each source file. +#---------------------------------------------------------------------- +sinclude $(PREREQS) + +.PHONY: clean +dsym: $(DSYM) +all: $(EXE) $(DSYM) +clean: + rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) *~ + + + diff --git a/lldb/test/inlines/inlines.c b/lldb/test/inlines/inlines.c new file mode 100644 index 00000000000..d81d44f743f --- /dev/null +++ b/lldb/test/inlines/inlines.c @@ -0,0 +1,38 @@ +#include <stdio.h> + +#define INLINE_ME __inline__ __attribute__((always_inline)) + +INLINE_ME int +inner_inline (int inner_input, int mod_value) +{ + int inner_result; + inner_result = inner_input % mod_value; + printf ("Returning: %d.\n", inner_result); + return inner_result; +} + +INLINE_ME int +outer_inline (int outer_input) +{ + int outer_result; + + outer_result = inner_inline (outer_input, outer_input % 3); + return outer_result; +} + +int +main (int argc, char **argv) +{ + printf ("Starting...\n"); + + int (*func_ptr) (int); + func_ptr = outer_inline; + + outer_inline (argc); + + func_ptr (argc); + + return 0; +} + + |