@@ -4005,3 +4005,155 @@ TEST(GSYMTest, TestEmptyRangeWarnings) {
4005
4005
// Make sure we don't see spurious errors in the output:
4006
4006
EXPECT_TRUE (errors.find (" error:" ) == std::string::npos);
4007
4007
}
4008
+
4009
+
4010
+ TEST (GSYMTest, TestEmptyLinkageName) {
4011
+ // This example has a single compile unit that has a DW_TAG_subprogram that
4012
+ // has a function that has an empty linkage name and a valid normal name.
4013
+ // Previously this would cause an encoding error:
4014
+ //
4015
+ // DWARF conversion failed: attempted to encode invalid FunctionInfo object
4016
+ //
4017
+ // This was because we would get a valid but empty linkage name and we would
4018
+ // try to use this in the GSYM FunctionInfo and that would cause the error
4019
+ // as the name was empty.
4020
+ //
4021
+ // 0x0000000b: DW_TAG_compile_unit
4022
+ // DW_AT_name ("/tmp/main.cpp")
4023
+ // DW_AT_language (DW_LANG_C)
4024
+ // DW_AT_stmt_list (0x00000000)
4025
+ //
4026
+ // 0x00000015: DW_TAG_subprogram
4027
+ // DW_AT_name ("foo")
4028
+ // DW_AT_linkage_name ("")
4029
+ // DW_AT_low_pc (0x0000000000001000)
4030
+ // DW_AT_high_pc (0x0000000000001050)
4031
+ //
4032
+ // 0x0000002e: NULL
4033
+
4034
+
4035
+ StringRef yamldata = R"(
4036
+ debug_str:
4037
+ - ''
4038
+ - '/tmp/main.cpp'
4039
+ - foo
4040
+ - ''
4041
+ debug_abbrev:
4042
+ - ID: 0
4043
+ Table:
4044
+ - Code: 0x1
4045
+ Tag: DW_TAG_compile_unit
4046
+ Children: DW_CHILDREN_yes
4047
+ Attributes:
4048
+ - Attribute: DW_AT_name
4049
+ Form: DW_FORM_strp
4050
+ - Attribute: DW_AT_language
4051
+ Form: DW_FORM_udata
4052
+ - Attribute: DW_AT_stmt_list
4053
+ Form: DW_FORM_sec_offset
4054
+ - Code: 0x2
4055
+ Tag: DW_TAG_subprogram
4056
+ Children: DW_CHILDREN_no
4057
+ Attributes:
4058
+ - Attribute: DW_AT_name
4059
+ Form: DW_FORM_strp
4060
+ - Attribute: DW_AT_linkage_name
4061
+ Form: DW_FORM_strp
4062
+ - Attribute: DW_AT_low_pc
4063
+ Form: DW_FORM_addr
4064
+ - Attribute: DW_AT_high_pc
4065
+ Form: DW_FORM_addr
4066
+ debug_info:
4067
+ - Length: 0x2B
4068
+ Version: 4
4069
+ AbbrevTableID: 0
4070
+ AbbrOffset: 0x0
4071
+ AddrSize: 8
4072
+ Entries:
4073
+ - AbbrCode: 0x1
4074
+ Values:
4075
+ - Value: 0x1
4076
+ - Value: 0x2
4077
+ - Value: 0x0
4078
+ - AbbrCode: 0x2
4079
+ Values:
4080
+ - Value: 0xF
4081
+ - Value: 0x13
4082
+ - Value: 0x1000
4083
+ - Value: 0x1050
4084
+ - AbbrCode: 0x0
4085
+ debug_line:
4086
+ - Length: 68
4087
+ Version: 2
4088
+ PrologueLength: 36
4089
+ MinInstLength: 1
4090
+ DefaultIsStmt: 1
4091
+ LineBase: 251
4092
+ LineRange: 14
4093
+ OpcodeBase: 13
4094
+ StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]
4095
+ IncludeDirs:
4096
+ - '/tmp'
4097
+ Files:
4098
+ - Name: main.cpp
4099
+ DirIdx: 1
4100
+ ModTime: 0
4101
+ Length: 0
4102
+ Opcodes:
4103
+ - Opcode: DW_LNS_extended_op
4104
+ ExtLen: 9
4105
+ SubOpcode: DW_LNE_set_address
4106
+ Data: 4096
4107
+ - Opcode: DW_LNS_advance_line
4108
+ SData: 9
4109
+ Data: 0
4110
+ - Opcode: DW_LNS_copy
4111
+ Data: 0
4112
+ - Opcode: DW_LNS_advance_pc
4113
+ Data: 256
4114
+ - Opcode: DW_LNS_advance_line
4115
+ SData: 1
4116
+ Data: 0
4117
+ - Opcode: DW_LNS_copy
4118
+ Data: 0
4119
+ - Opcode: DW_LNS_advance_pc
4120
+ Data: 256
4121
+ - Opcode: DW_LNS_extended_op
4122
+ ExtLen: 1
4123
+ SubOpcode: DW_LNE_end_sequence
4124
+ Data: 0
4125
+ )" ;
4126
+ auto ErrOrSections = DWARFYAML::emitDebugSections (yamldata);
4127
+ ASSERT_THAT_EXPECTED (ErrOrSections, Succeeded ());
4128
+ std::unique_ptr<DWARFContext> DwarfContext =
4129
+ DWARFContext::create (*ErrOrSections, 8 );
4130
+ ASSERT_TRUE (DwarfContext.get () != nullptr );
4131
+ std::string errors;
4132
+ raw_string_ostream OS (errors);
4133
+ GsymCreator GC;
4134
+ DwarfTransformer DT (*DwarfContext, GC);
4135
+ const uint32_t ThreadCount = 1 ;
4136
+ ASSERT_THAT_ERROR (DT.convert (ThreadCount, &OS), Succeeded ());
4137
+ ASSERT_THAT_ERROR (GC.finalize (OS), Succeeded ());
4138
+ OS.flush ();
4139
+ SmallString<512 > Str;
4140
+ raw_svector_ostream OutStrm (Str);
4141
+ const auto ByteOrder = llvm::endianness::native;
4142
+ FileWriter FW (OutStrm, ByteOrder);
4143
+ ASSERT_THAT_ERROR (GC.encode (FW), Succeeded ());
4144
+ Expected<GsymReader> GR = GsymReader::copyBuffer (OutStrm.str ());
4145
+ ASSERT_THAT_EXPECTED (GR, Succeeded ());
4146
+ // There should be one function in our GSYM.
4147
+ EXPECT_EQ (GR->getNumAddresses (), 1u );
4148
+ // Verify "foo" is present and has a line table and no inline info.
4149
+ auto ExpFI = GR->getFunctionInfo (0x1000 );
4150
+ ASSERT_THAT_EXPECTED (ExpFI, Succeeded ());
4151
+ ASSERT_EQ (ExpFI->Range , AddressRange (0x1000 , 0x1050 ));
4152
+ EXPECT_TRUE (ExpFI->OptLineTable .has_value ());
4153
+ EXPECT_FALSE (ExpFI->Inline .has_value ());
4154
+ StringRef FuncName = GR->getString (ExpFI->Name );
4155
+ EXPECT_EQ (FuncName, " foo" );
4156
+
4157
+ // Make sure we don't see spurious errors in the output:
4158
+ EXPECT_TRUE (errors.find (" error:" ) == std::string::npos);
4159
+ }
0 commit comments