@@ -419,7 +419,6 @@ void DWARFLinker::cleanupAuxiliarryData(LinkContext &Context) {
419
419
DIEAlloc.Reset ();
420
420
}
421
421
422
-
423
422
// / Check if a variable describing DIE should be kept.
424
423
// / \returns updated TraversalFlags.
425
424
unsigned DWARFLinker::shouldKeepVariableDIE (AddressesMap &RelocMgr,
@@ -845,9 +844,12 @@ void DWARFLinker::assignAbbrev(DIEAbbrev &Abbrev) {
845
844
unsigned DWARFLinker::DIECloner::cloneStringAttribute (
846
845
DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val,
847
846
const DWARFUnit &U, OffsetsStringPool &StringPool, AttributesInfo &Info) {
847
+ Optional<const char *> String = Val.getAsCString ();
848
+ if (!String)
849
+ return 0 ;
850
+
848
851
// Switch everything to out of line strings.
849
- const char *String = *Val.getAsCString ();
850
- auto StringEntry = StringPool.getEntry (String);
852
+ auto StringEntry = StringPool.getEntry (*String);
851
853
852
854
// Update attributes info.
853
855
if (AttrSpec.Attr == dwarf::DW_AT_name)
@@ -1056,6 +1058,7 @@ unsigned DWARFLinker::DIECloner::cloneBlockAttribute(
1056
1058
unsigned DWARFLinker::DIECloner::cloneAddressAttribute (
1057
1059
DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val,
1058
1060
const CompileUnit &Unit, AttributesInfo &Info) {
1061
+ dwarf::Form Form = AttrSpec.Form ;
1059
1062
uint64_t Addr = *Val.getAsAddress ();
1060
1063
1061
1064
if (LLVM_UNLIKELY (Linker.Options .Update )) {
@@ -1105,8 +1108,19 @@ unsigned DWARFLinker::DIECloner::cloneAddressAttribute(
1105
1108
Addr = (Info.OrigCallPc ? Info.OrigCallPc : Addr) + Info.PCOffset ;
1106
1109
}
1107
1110
1111
+ // If this is an indexed address emit the relocated address.
1112
+ if (Form == dwarf::DW_FORM_addrx) {
1113
+ if (llvm::Expected<uint64_t > RelocAddr =
1114
+ ObjFile.Addresses ->relocateIndexedAddr (Addr)) {
1115
+ Addr = *RelocAddr;
1116
+ Form = dwarf::DW_FORM_addr;
1117
+ } else {
1118
+ Linker.reportWarning (toString (RelocAddr.takeError ()), ObjFile);
1119
+ }
1120
+ }
1121
+
1108
1122
Die.addValue (DIEAlloc, static_cast <dwarf::Attribute>(AttrSpec.Attr ),
1109
- static_cast <dwarf::Form>(AttrSpec. Form ), DIEInteger (Addr));
1123
+ static_cast <dwarf::Form>(Form), DIEInteger (Addr));
1110
1124
return Unit.getOrigUnit ().getAddressByteSize ();
1111
1125
}
1112
1126
@@ -1188,6 +1202,11 @@ unsigned DWARFLinker::DIECloner::cloneAttribute(
1188
1202
switch (AttrSpec.Form ) {
1189
1203
case dwarf::DW_FORM_strp:
1190
1204
case dwarf::DW_FORM_string:
1205
+ case dwarf::DW_FORM_strx:
1206
+ case dwarf::DW_FORM_strx1:
1207
+ case dwarf::DW_FORM_strx2:
1208
+ case dwarf::DW_FORM_strx3:
1209
+ case dwarf::DW_FORM_strx4:
1191
1210
return cloneStringAttribute (Die, AttrSpec, Val, U, StringPool, Info);
1192
1211
case dwarf::DW_FORM_ref_addr:
1193
1212
case dwarf::DW_FORM_ref1:
@@ -1204,6 +1223,7 @@ unsigned DWARFLinker::DIECloner::cloneAttribute(
1204
1223
return cloneBlockAttribute (Die, File, Unit, AttrSpec, Val, AttrSize,
1205
1224
IsLittleEndian);
1206
1225
case dwarf::DW_FORM_addr:
1226
+ case dwarf::DW_FORM_addrx:
1207
1227
return cloneAddressAttribute (Die, AttrSpec, Val, Unit, Info);
1208
1228
case dwarf::DW_FORM_data1:
1209
1229
case dwarf::DW_FORM_data2:
@@ -1284,6 +1304,9 @@ shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec,
1284
1304
case dwarf::DW_AT_high_pc:
1285
1305
case dwarf::DW_AT_ranges:
1286
1306
return SkipPC;
1307
+ case dwarf::DW_AT_str_offsets_base:
1308
+ // FIXME: Use the string offset table with Dwarf 5.
1309
+ return true ;
1287
1310
case dwarf::DW_AT_location:
1288
1311
case dwarf::DW_AT_frame_base:
1289
1312
// FIXME: for some reason dsymutil-classic keeps the location attributes
@@ -2127,22 +2150,24 @@ uint64_t DWARFLinker::DIECloner::cloneAllCompileUnits(
2127
2150
const uint64_t StartOutputDebugInfoSize = OutputDebugInfoSize;
2128
2151
2129
2152
for (auto &CurrentUnit : CompileUnits) {
2153
+ const uint16_t DwarfVersion = CurrentUnit->getOrigUnit ().getVersion ();
2154
+ const uint32_t UnitHeaderSize = DwarfVersion >= 5 ? 12 : 11 ;
2130
2155
auto InputDIE = CurrentUnit->getOrigUnit ().getUnitDIE ();
2131
2156
CurrentUnit->setStartOffset (OutputDebugInfoSize);
2132
2157
if (!InputDIE) {
2133
- OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset ();
2158
+ OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset (DwarfVersion );
2134
2159
continue ;
2135
2160
}
2136
2161
if (CurrentUnit->getInfo (0 ).Keep ) {
2137
2162
// Clone the InputDIE into your Unit DIE in our compile unit since it
2138
2163
// already has a DIE inside of it.
2139
2164
CurrentUnit->createOutputDIE ();
2140
2165
cloneDIE (InputDIE, File, *CurrentUnit, StringPool, 0 /* PC offset */ ,
2141
- 11 /* Unit Header size */ , 0 , IsLittleEndian,
2166
+ UnitHeaderSize , 0 , IsLittleEndian,
2142
2167
CurrentUnit->getOutputUnitDIE ());
2143
2168
}
2144
2169
2145
- OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset ();
2170
+ OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset (DwarfVersion );
2146
2171
2147
2172
if (!Linker.Options .NoOutput ) {
2148
2173
assert (Emitter);
@@ -2183,12 +2208,14 @@ uint64_t DWARFLinker::DIECloner::cloneAllCompileUnits(
2183
2208
if (!CurrentUnit->getOutputUnitDIE ())
2184
2209
continue ;
2185
2210
2211
+ unsigned DwarfVersion = CurrentUnit->getOrigUnit ().getVersion ();
2212
+
2186
2213
assert (Emitter->getDebugInfoSectionSize () ==
2187
2214
CurrentUnit->getStartOffset ());
2188
- Emitter->emitCompileUnitHeader (*CurrentUnit);
2215
+ Emitter->emitCompileUnitHeader (*CurrentUnit, DwarfVersion );
2189
2216
Emitter->emitDIE (*CurrentUnit->getOutputUnitDIE ());
2190
2217
assert (Emitter->getDebugInfoSectionSize () ==
2191
- CurrentUnit->computeNextUnitOffset ());
2218
+ CurrentUnit->computeNextUnitOffset (DwarfVersion ));
2192
2219
}
2193
2220
}
2194
2221
0 commit comments