aboutsummaryrefslogtreecommitdiff
path: root/src/common/dwarf_cu_to_module_unittest.cc
diff options
context:
space:
mode:
authorjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-01-08 02:14:44 +0000
committerjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-01-08 02:14:44 +0000
commita8426a5c6607c5f3384e948c74e7cab29c3809ff (patch)
treea07c7a8865235f8b47c444e41bd5a85e76287512 /src/common/dwarf_cu_to_module_unittest.cc
parent Fix typo. (diff)
downloadbreakpad-a8426a5c6607c5f3384e948c74e7cab29c3809ff.tar.xz
DWARF can store DW_AT_high_pc as either an address or a constant. In the latter
case it's the length of the function. breakpad always treats it as an address. a=mattdr, r=jimb git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1094 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/dwarf_cu_to_module_unittest.cc')
-rw-r--r--src/common/dwarf_cu_to_module_unittest.cc65
1 files changed, 48 insertions, 17 deletions
diff --git a/src/common/dwarf_cu_to_module_unittest.cc b/src/common/dwarf_cu_to_module_unittest.cc
index e71d344b..37061d2a 100644
--- a/src/common/dwarf_cu_to_module_unittest.cc
+++ b/src/common/dwarf_cu_to_module_unittest.cc
@@ -193,12 +193,15 @@ class CUFixtureBase {
DIEHandler *StartSpecifiedDIE(DIEHandler *parent, DwarfTag tag,
uint64 specification, const char *name = NULL);
- // Define a function as a child of PARENT with the given name,
- // address, and size. Call EndAttributes and Finish; one cannot
- // define children of the defined function's DIE.
+ // Define a function as a child of PARENT with the given name, address, and
+ // size. If high_pc_form is DW_FORM_addr then the DW_AT_high_pc attribute
+ // will be written as an address; otherwise it will be written as the
+ // function's size. Call EndAttributes and Finish; one cannot define
+ // children of the defined function's DIE.
void DefineFunction(DIEHandler *parent, const string &name,
Module::Address address, Module::Address size,
- const char* mangled_name);
+ const char* mangled_name,
+ DwarfForm high_pc_form = dwarf2reader::DW_FORM_addr);
// Create a declaration DIE as a child of PARENT with the given
// offset, tag and name. If NAME is the empty string, don't provide
@@ -414,7 +417,8 @@ DIEHandler *CUFixtureBase::StartSpecifiedDIE(DIEHandler *parent,
void CUFixtureBase::DefineFunction(dwarf2reader::DIEHandler *parent,
const string &name, Module::Address address,
Module::Address size,
- const char* mangled_name) {
+ const char* mangled_name,
+ DwarfForm high_pc_form) {
dwarf2reader::DIEHandler *func
= parent->FindChildHandler(0xe34797c7e68590a8LL,
dwarf2reader::DW_TAG_subprogram);
@@ -425,9 +429,15 @@ void CUFixtureBase::DefineFunction(dwarf2reader::DIEHandler *parent,
func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_low_pc,
dwarf2reader::DW_FORM_addr,
address);
+
+ Module::Address high_pc = size;
+ if (high_pc_form == dwarf2reader::DW_FORM_addr) {
+ high_pc += address;
+ }
func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_high_pc,
- dwarf2reader::DW_FORM_addr,
- address + size);
+ high_pc_form,
+ high_pc);
+
if (mangled_name)
func->ProcessAttributeString(dwarf2reader::DW_AT_MIPS_linkage_name,
dwarf2reader::DW_FORM_strp,
@@ -598,16 +608,20 @@ void CUFixtureBase::TestLine(int i, int j,
// Include caller locations for our test subroutines.
#define TRACE(call) do { SCOPED_TRACE("called from here"); call; } while (0)
-#define PushLine(a,b,c,d) TRACE(PushLine((a),(b),(c),(d)))
-#define SetLanguage(a) TRACE(SetLanguage(a))
-#define StartCU() TRACE(StartCU())
-#define DefineFunction(a,b,c,d,e) TRACE(DefineFunction((a),(b),(c),(d),(e)))
-#define DeclarationDIE(a,b,c,d,e) TRACE(DeclarationDIE((a),(b),(c),(d),(e)))
-#define DefinitionDIE(a,b,c,d,e,f) TRACE(DefinitionDIE((a),(b),(c),(d),(e),(f)))
-#define TestFunctionCount(a) TRACE(TestFunctionCount(a))
-#define TestFunction(a,b,c,d) TRACE(TestFunction((a),(b),(c),(d)))
-#define TestLineCount(a,b) TRACE(TestLineCount((a),(b)))
-#define TestLine(a,b,c,d,e,f) TRACE(TestLine((a),(b),(c),(d),(e),(f)))
+#define PushLine(a,b,c,d) TRACE(PushLine((a),(b),(c),(d)))
+#define SetLanguage(a) TRACE(SetLanguage(a))
+#define StartCU() TRACE(StartCU())
+#define DefineFunction(a,b,c,d,e) TRACE(DefineFunction((a),(b),(c),(d),(e)))
+// (DefineFunction) instead of DefineFunction to avoid macro expansion.
+#define DefineFunction6(a,b,c,d,e,f) \
+ TRACE((DefineFunction)((a),(b),(c),(d),(e),(f)))
+#define DeclarationDIE(a,b,c,d,e) TRACE(DeclarationDIE((a),(b),(c),(d),(e)))
+#define DefinitionDIE(a,b,c,d,e,f) \
+ TRACE(DefinitionDIE((a),(b),(c),(d),(e),(f)))
+#define TestFunctionCount(a) TRACE(TestFunctionCount(a))
+#define TestFunction(a,b,c,d) TRACE(TestFunction((a),(b),(c),(d)))
+#define TestLineCount(a,b) TRACE(TestLineCount((a),(b)))
+#define TestLine(a,b,c,d,e,f) TRACE(TestLine((a),(b),(c),(d),(e),(f)))
class SimpleCU: public CUFixtureBase, public Test {
};
@@ -627,6 +641,23 @@ TEST_F(SimpleCU, OneFunc) {
246571772);
}
+// As above, only DW_AT_high_pc is a length rather than an address.
+TEST_F(SimpleCU, OneFuncHighPcIsLength) {
+ PushLine(0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", 246571772);
+
+ StartCU();
+ DefineFunction6(&root_handler_, "function1",
+ 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, NULL,
+ dwarf2reader::DW_FORM_udata);
+ root_handler_.Finish();
+
+ TestFunctionCount(1);
+ TestFunction(0, "function1", 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL);
+ TestLineCount(0, 1);
+ TestLine(0, 0, 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file",
+ 246571772);
+}
+
TEST_F(SimpleCU, MangledName) {
PushLine(0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", 246571772);