Skip to content

Commit f8cf79c

Browse files
author
git apple-llvm automerger
committed
Merge commit '0549aa11c2c1' from llvm.org/main into next
2 parents d71a2ab + 0549aa1 commit f8cf79c

File tree

14 files changed

+155
-30
lines changed

14 files changed

+155
-30
lines changed

llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,11 @@ class LLVM_ABI DWARFLinker : public DWARFLinkerBase {
709709
/// already there.
710710
/// \returns is a name was found.
711711
bool getDIENames(const DWARFDie &Die, AttributesInfo &Info,
712-
OffsetsStringPool &StringPool, bool StripTemplate = false);
712+
OffsetsStringPool &StringPool, const DWARFFile &File,
713+
CompileUnit &Unit, bool StripTemplate = false);
714+
715+
llvm::StringRef getCanonicalDIEName(DWARFDie Die, const DWARFFile &File,
716+
CompileUnit *Unit);
713717

714718
uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
715719
const DWARFFile &File,

llvm/include/llvm/DWARFLinker/Classic/DWARFLinkerDeclContext.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,13 @@ class DeclContext {
8484
DeclContext() : DefinedInClangModule(0), Parent(*this) {}
8585

8686
DeclContext(unsigned Hash, uint32_t Line, uint32_t ByteSize, uint16_t Tag,
87-
StringRef Name, StringRef File, const DeclContext &Parent,
88-
DWARFDie LastSeenDIE = DWARFDie(), unsigned CUId = 0)
87+
StringRef Name, StringRef NameForUniquing, StringRef File,
88+
const DeclContext &Parent, DWARFDie LastSeenDIE = DWARFDie(),
89+
unsigned CUId = 0)
8990
: QualifiedNameHash(Hash), Line(Line), ByteSize(ByteSize), Tag(Tag),
90-
DefinedInClangModule(0), Name(Name), File(File), Parent(Parent),
91-
LastSeenDIE(LastSeenDIE), LastSeenCompileUnitID(CUId) {}
91+
DefinedInClangModule(0), Name(Name), NameForUniquing(NameForUniquing),
92+
File(File), Parent(Parent), LastSeenDIE(LastSeenDIE),
93+
LastSeenCompileUnitID(CUId) {}
9294

9395
uint32_t getQualifiedNameHash() const { return QualifiedNameHash; }
9496

@@ -100,6 +102,7 @@ class DeclContext {
100102

101103
uint32_t getCanonicalDIEOffset() const { return CanonicalDIEOffset; }
102104
void setCanonicalDIEOffset(uint32_t Offset) { CanonicalDIEOffset = Offset; }
105+
llvm::StringRef getCanonicalName() const { return Name; }
103106

104107
bool isDefinedInClangModule() const { return DefinedInClangModule; }
105108
void setDefinedInClangModule(bool Val) { DefinedInClangModule = Val; }
@@ -115,6 +118,7 @@ class DeclContext {
115118
uint16_t Tag = dwarf::DW_TAG_compile_unit;
116119
unsigned DefinedInClangModule : 1;
117120
StringRef Name;
121+
StringRef NameForUniquing;
118122
StringRef File;
119123
const DeclContext &Parent;
120124
DWARFDie LastSeenDIE;
@@ -180,7 +184,7 @@ struct DeclMapInfo : private DenseMapInfo<DeclContext *> {
180184
return RHS == LHS;
181185
return LHS->QualifiedNameHash == RHS->QualifiedNameHash &&
182186
LHS->Line == RHS->Line && LHS->ByteSize == RHS->ByteSize &&
183-
LHS->Name.data() == RHS->Name.data() &&
187+
LHS->NameForUniquing.data() == RHS->NameForUniquing.data() &&
184188
LHS->File.data() == RHS->File.data() &&
185189
LHS->Parent.QualifiedNameHash == RHS->Parent.QualifiedNameHash;
186190
}

llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,22 +151,84 @@ static bool isTypeTag(uint16_t Tag) {
151151
return false;
152152
}
153153

154-
bool DWARFLinker::DIECloner::getDIENames(const DWARFDie &Die,
155-
AttributesInfo &Info,
156-
OffsetsStringPool &StringPool,
157-
bool StripTemplate) {
154+
/// Recurse through the input DIE's canonical references until we find a
155+
/// DW_AT_name.
156+
llvm::StringRef
157+
DWARFLinker::DIECloner::getCanonicalDIEName(DWARFDie Die, const DWARFFile &File,
158+
CompileUnit *Unit) {
159+
if (!Die)
160+
return {};
161+
162+
std::optional<DWARFFormValue> Ref;
163+
164+
auto GetDieName = [](const DWARFDie &D) -> llvm::StringRef {
165+
auto NameForm = D.find(llvm::dwarf::DW_AT_name);
166+
if (!NameForm)
167+
return {};
168+
169+
auto NameOrErr = NameForm->getAsCString();
170+
if (!NameOrErr) {
171+
llvm::consumeError(NameOrErr.takeError());
172+
return {};
173+
}
174+
175+
return *NameOrErr;
176+
};
177+
178+
llvm::StringRef Name = GetDieName(Die);
179+
if (!Name.empty())
180+
return Name;
181+
182+
while (true) {
183+
if (!(Ref = Die.find(llvm::dwarf::DW_AT_specification)) &&
184+
!(Ref = Die.find(llvm::dwarf::DW_AT_abstract_origin)))
185+
break;
186+
187+
Die = Linker.resolveDIEReference(File, CompileUnits, *Ref, Die, Unit);
188+
if (!Die)
189+
break;
190+
191+
assert(Unit);
192+
193+
unsigned SpecIdx = Unit->getOrigUnit().getDIEIndex(Die);
194+
CompileUnit::DIEInfo &SpecInfo = Unit->getInfo(SpecIdx);
195+
if (SpecInfo.Ctxt && SpecInfo.Ctxt->hasCanonicalDIE()) {
196+
if (!SpecInfo.Ctxt->getCanonicalName().empty()) {
197+
Name = SpecInfo.Ctxt->getCanonicalName();
198+
break;
199+
}
200+
}
201+
202+
Name = GetDieName(Die);
203+
if (!Name.empty())
204+
break;
205+
}
206+
207+
return Name;
208+
}
209+
210+
bool DWARFLinker::DIECloner::getDIENames(
211+
const DWARFDie &Die, AttributesInfo &Info, OffsetsStringPool &StringPool,
212+
const DWARFFile &File, CompileUnit &Unit, bool StripTemplate) {
158213
// This function will be called on DIEs having low_pcs and
159214
// ranges. As getting the name might be more expansive, filter out
160215
// blocks directly.
161216
if (Die.getTag() == dwarf::DW_TAG_lexical_block)
162217
return false;
163218

219+
// The mangled name of an specification DIE will by virtue of the
220+
// uniquing algorithm be the same as the one it got uniqued into.
221+
// So just use the input DIE's linkage name.
164222
if (!Info.MangledName)
165223
if (const char *MangledName = Die.getLinkageName())
166224
Info.MangledName = StringPool.getEntry(MangledName);
167225

226+
// For subprograms with linkage names, we unique on the linkage name,
227+
// so DW_AT_name's may differ between the input and canonical DIEs.
228+
// Use the name of the canonical DIE.
168229
if (!Info.Name)
169-
if (const char *Name = Die.getShortName())
230+
if (llvm::StringRef Name = getCanonicalDIEName(Die, File, &Unit);
231+
!Name.empty())
170232
Info.Name = StringPool.getEntry(Name);
171233

172234
if (!Info.MangledName)
@@ -1939,7 +2001,7 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
19392001
// accelerator tables too. For now stick with dsymutil's behavior.
19402002
if ((Info.InDebugMap || AttrInfo.HasLowPc || AttrInfo.HasRanges) &&
19412003
Tag != dwarf::DW_TAG_compile_unit &&
1942-
getDIENames(InputDIE, AttrInfo, DebugStrPool,
2004+
getDIENames(InputDIE, AttrInfo, DebugStrPool, File, Unit,
19432005
Tag != dwarf::DW_TAG_inlined_subroutine)) {
19442006
if (AttrInfo.MangledName && AttrInfo.MangledName != AttrInfo.Name)
19452007
Unit.addNameAccelerator(Die, AttrInfo.MangledName,
@@ -1962,7 +2024,7 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
19622024
} else if (Tag == dwarf::DW_TAG_imported_declaration && AttrInfo.Name) {
19632025
Unit.addNamespaceAccelerator(Die, AttrInfo.Name);
19642026
} else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration) {
1965-
bool Success = getDIENames(InputDIE, AttrInfo, DebugStrPool);
2027+
bool Success = getDIENames(InputDIE, AttrInfo, DebugStrPool, File, Unit);
19662028
uint64_t RuntimeLang =
19672029
dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_runtime_class))
19682030
.value_or(0);

llvm/lib/DWARFLinker/Classic/DWARFLinkerDeclContext.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,24 +84,26 @@ DeclContextTree::getChildDeclContext(DeclContext &Context, const DWARFDie &DIE,
8484
break;
8585
}
8686

87-
StringRef NameRef;
87+
StringRef Name = DIE.getShortName();
88+
StringRef NameForUniquing;
8889
StringRef FileRef;
8990

9091
if (const char *LinkageName = DIE.getLinkageName())
91-
NameRef = StringPool.internString(LinkageName);
92-
else if (const char *ShortName = DIE.getShortName())
93-
NameRef = StringPool.internString(ShortName);
92+
NameForUniquing = StringPool.internString(LinkageName);
93+
else if (!Name.empty())
94+
NameForUniquing = StringPool.internString(Name);
9495

95-
bool IsAnonymousNamespace = NameRef.empty() && Tag == dwarf::DW_TAG_namespace;
96+
bool IsAnonymousNamespace =
97+
NameForUniquing.empty() && Tag == dwarf::DW_TAG_namespace;
9698
if (IsAnonymousNamespace) {
9799
// FIXME: For dsymutil-classic compatibility. I think uniquing within
98100
// anonymous namespaces is wrong. There is no ODR guarantee there.
99-
NameRef = "(anonymous namespace)";
101+
NameForUniquing = "(anonymous namespace)";
100102
}
101103

102104
if (Tag != dwarf::DW_TAG_class_type && Tag != dwarf::DW_TAG_structure_type &&
103105
Tag != dwarf::DW_TAG_union_type &&
104-
Tag != dwarf::DW_TAG_enumeration_type && NameRef.empty())
106+
Tag != dwarf::DW_TAG_enumeration_type && NameForUniquing.empty())
105107
return PointerIntPair<DeclContext *, 1>(nullptr);
106108

107109
unsigned Line = 0;
@@ -140,10 +142,10 @@ DeclContextTree::getChildDeclContext(DeclContext &Context, const DWARFDie &DIE,
140142
}
141143
}
142144

143-
if (!Line && NameRef.empty())
145+
if (!Line && NameForUniquing.empty())
144146
return PointerIntPair<DeclContext *, 1>(nullptr);
145147

146-
// We hash NameRef, which is the mangled name, in order to get most
148+
// We hash NameForUniquing, which is the mangled name, in order to get most
147149
// overloaded functions resolve correctly.
148150
//
149151
// Strictly speaking, hashing the Tag is only necessary for a
@@ -153,23 +155,25 @@ DeclContextTree::getChildDeclContext(DeclContext &Context, const DWARFDie &DIE,
153155
// FIXME: dsymutil-classic won't unique the same type presented
154156
// once as a struct and once as a class. Using the Tag in the fully
155157
// qualified name hash to get the same effect.
156-
unsigned Hash = hash_combine(Context.getQualifiedNameHash(), Tag, NameRef);
158+
unsigned Hash =
159+
hash_combine(Context.getQualifiedNameHash(), Tag, NameForUniquing);
157160

158161
// FIXME: dsymutil-classic compatibility: when we don't have a name,
159162
// use the filename.
160163
if (IsAnonymousNamespace)
161164
Hash = hash_combine(Hash, FileRef);
162165

163166
// Now look if this context already exists.
164-
DeclContext Key(Hash, Line, ByteSize, Tag, NameRef, FileRef, Context);
167+
DeclContext Key(Hash, Line, ByteSize, Tag, Name, NameForUniquing, FileRef,
168+
Context);
165169
auto ContextIter = Contexts.find(&Key);
166170

167171
if (ContextIter == Contexts.end()) {
168172
// The context wasn't found.
169173
bool Inserted;
170-
DeclContext *NewContext =
171-
new (Allocator) DeclContext(Hash, Line, ByteSize, Tag, NameRef, FileRef,
172-
Context, DIE, U.getUniqueID());
174+
DeclContext *NewContext = new (Allocator)
175+
DeclContext(Hash, Line, ByteSize, Tag, Name, NameForUniquing, FileRef,
176+
Context, DIE, U.getUniqueID());
173177
std::tie(ContextIter, Inserted) = Contexts.insert(NewContext);
174178
assert(Inserted && "Failed to insert DeclContext");
175179
(void)Inserted;

llvm/test/tools/dsymutil/AArch64/dummy-debug-map-arm64.map

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@ objects:
1111
- filename: 1.o
1212
symbols:
1313
- { sym: _bar, objAddr: 0x0, binAddr: 0x10000, size: 0x10 }
14+
- { sym: __Z13lib1_internalv, objAddr: 0x0, binAddr: 0x10020, size: 0x20 }
15+
- { sym: __ZN3Foo4funcIZ13lib1_internalvE3$_0EEvv, objAddr: 0x0, binAddr: 0x10040, size: 0x20 }
1416
- filename: 2.o
1517
symbols:
1618
- { sym: __Z3foov, objAddr: 0x0, binAddr: 0x20000, size: 0x10 }
19+
- { sym: __Z13lib1_internalv, objAddr: 0x0, binAddr: 0x20020, size: 0x20 }
20+
- { sym: __ZN3Foo4funcIZ13lib1_internalvE3$_0EEvv, objAddr: 0x0, binAddr: 0x20040, size: 0x20 }
1721
- filename: 3.o
1822
symbols:
1923
- { sym: __Z3foov, objAddr: 0x0, binAddr: 0x30000, size: 0x10 }

llvm/test/tools/dsymutil/AArch64/dwarf5-str-offsets-base-strx.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ CHECK: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x000000
9898
CHECK: DW_AT_comp_dir [DW_FORM_strx] (indexed (00000004) string = "/Users/shubham/Development/test109275485")
9999

100100
CHECK: DW_TAG_subprogram
101-
CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x0000000000010000)
101+
CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x0000000000010040)
102102
CHECK: DW_AT_linkage_name [DW_FORM_strx] (indexed (00000005) string = "_Z4foo2i")
103103
CHECK: DW_AT_name [DW_FORM_strx] (indexed (00000006) string = "foo2")
104104

llvm/test/tools/dsymutil/AArch64/inlined-low_pc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ int bar(int a) { return foo(a); }
1010
// RUN: llvm-dwarfdump - | FileCheck %s
1111

1212
// CHECK: DW_TAG_subprogram
13-
// CHECK: DW_AT_low_pc{{.*}}0x0000000000010000
13+
// CHECK: DW_AT_low_pc{{.*}}0x0000000000010040
1414
// CHECK: DW_AT_name{{.*}}"bar"
1515
// CHECK-NOT: NULL
1616
// CHECK: DW_TAG_inlined_subroutine
1717
// CHECK-NEXT: DW_AT_abstract_origin{{.*}}"foo"
18-
// CHECK-NEXT: DW_AT_low_pc{{.*}}0x0000000000010000
18+
// CHECK-NEXT: DW_AT_low_pc{{.*}}0x0000000000010040
1919

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Tests the case where a DW_TAG_subprogram for a method declaration
2+
# got uniqued into a DW_TAG_subprogram with the same linkage name (but
3+
# different DW_AT_name). Make sure the DW_TAG_subprogram DIE for the
4+
# definition, which previously pointed to the now de-deduplicated declaration,
5+
# gets inserted into the .debug_names table using the DW_AT_name of the canonical
6+
# declaration DW_TAG_subprogram.
7+
#
8+
# Object files compiled as follows:
9+
# clang -g -c -o 1.o Inputs/odr-uniquing-DW_AT_name-conflict/lib1.cpp
10+
# clang -g -c -o 2.o Inputs/odr-uniquing-DW_AT_name-conflict/lib2.cpp
11+
12+
# RUN: dsymutil -f -oso-prepend-path=%p/../Inputs/odr-uniquing-DW_AT_name-conflict -y %p/dummy-debug-map-arm64.map -o - \
13+
# RUN: | llvm-dwarfdump --verify - | FileCheck %s
14+
15+
# RUN: dsymutil --linker parallel -f -oso-prepend-path=%p/../Inputs/odr-uniquing-DW_AT_name-conflict -y %p/dummy-debug-map-arm64.map -o - \
16+
# RUN: | not llvm-dwarfdump --verify - | FileCheck %s --check-prefix=PARALLEL-ODR
17+
18+
# RUN: dsymutil -f -oso-prepend-path=%p/../Inputs/odr-uniquing-DW_AT_name-conflict -y %p/dummy-debug-map-arm64.map -no-odr -o - \
19+
# RUN: | llvm-dwarfdump --verify - | FileCheck %s
20+
21+
# RUN: dsymutil --linker parallel -f -oso-prepend-path=%p/../Inputs/odr-uniquing-DW_AT_name-conflict -y %p/dummy-debug-map-arm64.map -no-odr -o - \
22+
# RUN: | llvm-dwarfdump --verify - | FileCheck %s
23+
24+
# CHECK: No errors.
25+
26+
# FIXME: parallel DWARFLinker uses wrong DW_AT_name when inserting uniqued subprogram into .debug_names
27+
# PARALLEL-ODR: Verifying .debug_names...
28+
# PARALLEL-ODR-NEXT: error: Name Index {{.*}} mismatched Name of DIE
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)