Skip to content

Commit 254ceed

Browse files
committed
[lld][ELF] Address last review comments.
- Pulled body of loop that reads/parses IndexEntries into a separate function (readEntry) - Removed unnecessary 'const' qualifiers on local vars - Updated comment about handling type units - Created getChunks accessor function; used it to eliminate use of 'seq' in for-loop. - Enhanced some error messages - Update debug-names-bad.s test to handle udpated error messages
1 parent 41580dd commit 254ceed

File tree

3 files changed

+111
-87
lines changed

3 files changed

+111
-87
lines changed

lld/ELF/SyntheticSections.cpp

Lines changed: 105 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -2734,14 +2734,99 @@ static uint32_t getDebugNamesHeaderSize(uint32_t augmentationStringSize) {
27342734
/* Augmentation string */ augmentationStringSize;
27352735
}
27362736

2737+
static Expected<DebugNamesBaseSection::IndexEntry *>
2738+
readEntry(uint64_t &offset, const DWARFDebugNames::NameIndex &ni,
2739+
uint64_t entriesBase, DWARFDataExtractor &namesExtractor,
2740+
const LLDDWARFSection &namesSec) {
2741+
std::string errMsg;
2742+
auto ie = makeThreadLocal<DebugNamesBaseSection::IndexEntry>();
2743+
ie->poolOffset = offset;
2744+
Error err = Error::success();
2745+
uint64_t ulebVal = namesExtractor.getULEB128(&offset, &err);
2746+
if (err) {
2747+
errMsg = ": invalid abbrev code in entry: ";
2748+
errMsg.append(toString(std::move(err)));
2749+
return createStringError(inconvertibleErrorCode(), errMsg.c_str());
2750+
}
2751+
if (ulebVal < UINT32_MAX)
2752+
ie->abbrevCode = static_cast<uint32_t>(ulebVal);
2753+
else {
2754+
errMsg = ": abbrev code in entry too large for DWARF32: ";
2755+
errMsg.append(std::to_string(ulebVal));
2756+
return createStringError(inconvertibleErrorCode(), errMsg.c_str());
2757+
}
2758+
auto it = ni.getAbbrevs().find_as(ie->abbrevCode);
2759+
if (it == ni.getAbbrevs().end()) {
2760+
errMsg = ": entry abbrev code not found in abbrev table: ";
2761+
errMsg.append(std::to_string(ie->abbrevCode));
2762+
return createStringError(inconvertibleErrorCode(), errMsg.c_str());
2763+
}
2764+
2765+
DebugNamesBaseSection::AttrValue attr, cuAttr = {0, 0};
2766+
for (DWARFDebugNames::AttributeEncoding a : it->Attributes) {
2767+
if (a.Index == dwarf::DW_IDX_parent) {
2768+
if (a.Form == dwarf::DW_FORM_ref4) {
2769+
attr.attrValue = namesExtractor.getU32(&offset, &err);
2770+
attr.attrSize = 4;
2771+
ie->parentOffset = entriesBase + attr.attrValue;
2772+
} else if (a.Form != DW_FORM_flag_present) {
2773+
errMsg = ": invalid form for DW_IDX_parent";
2774+
}
2775+
} else {
2776+
switch (a.Form) {
2777+
case DW_FORM_data1:
2778+
case DW_FORM_ref1: {
2779+
attr.attrValue = namesExtractor.getU8(&offset, &err);
2780+
attr.attrSize = 1;
2781+
break;
2782+
}
2783+
case DW_FORM_data2:
2784+
case DW_FORM_ref2: {
2785+
attr.attrValue = namesExtractor.getU16(&offset, &err);
2786+
attr.attrSize = 2;
2787+
break;
2788+
}
2789+
case DW_FORM_data4:
2790+
case DW_FORM_ref4: {
2791+
attr.attrValue = namesExtractor.getU32(&offset, &err);
2792+
attr.attrSize = 4;
2793+
break;
2794+
}
2795+
default:
2796+
errMsg = ": unrecognized form encoding ";
2797+
errMsg.append(std::to_string(a.Form));
2798+
errMsg.append(" in abbrev table");
2799+
return createStringError(inconvertibleErrorCode(), errMsg.c_str());
2800+
}
2801+
}
2802+
if (err) {
2803+
errMsg = ": error while reading attributes: ";
2804+
errMsg.append(toString(std::move(err)));
2805+
return createStringError(inconvertibleErrorCode(), errMsg.c_str());
2806+
}
2807+
if (a.Index == DW_IDX_compile_unit)
2808+
cuAttr = attr;
2809+
else if (a.Form != DW_FORM_flag_present)
2810+
ie->attrValues.push_back(attr);
2811+
}
2812+
2813+
// Canonicalize abbrev by placing the CU/TU index at the end.
2814+
ie->attrValues.push_back(cuAttr);
2815+
2816+
if (!errMsg.empty())
2817+
return createStringError(inconvertibleErrorCode(), errMsg.c_str());
2818+
else
2819+
return ie;
2820+
}
2821+
27372822
void DebugNamesBaseSection::parseDebugNames(
27382823
InputChunk &inputChunk, OutputChunk &chunk,
27392824
DWARFDataExtractor &namesExtractor, DataExtractor &strExtractor,
27402825
function_ref<SmallVector<uint32_t, 0>(
27412826
uint32_t numCus, const DWARFDebugNames::Header &,
27422827
const DWARFDebugNames::DWARFDebugNamesOffsets &)>
27432828
readOffsets) {
2744-
const LLDDWARFSection namesSec = inputChunk.section;
2829+
const LLDDWARFSection &namesSec = inputChunk.section;
27452830
DenseMap<uint32_t, IndexEntry *> offsetMap;
27462831
// Number of CUs seen in previous NameIndex sections within current chunk.
27472832
uint32_t numCus = 0;
@@ -2758,8 +2843,7 @@ void DebugNamesBaseSection::parseDebugNames(
27582843
Twine(nd.hdr.Version));
27592844
return;
27602845
}
2761-
const uint32_t dwarfSize =
2762-
dwarf::getDwarfOffsetByteSize(DwarfFormat::DWARF32);
2846+
uint32_t dwarfSize = dwarf::getDwarfOffsetByteSize(DwarfFormat::DWARF32);
27632847
DWARFDebugNames::DWARFDebugNamesOffsets locs = ni.getOffsets();
27642848
if (locs.EntriesBase > namesExtractor.getData().size()) {
27652849
errorOrWarn(toString(namesSec.sec) +
@@ -2782,83 +2866,23 @@ void DebugNamesBaseSection::parseDebugNames(
27822866
ne.hashValue = caseFoldingDjbHash(name);
27832867

27842868
// Read a series of index entries that end with abbreviation code 0.
2785-
const char *errMsg = nullptr;
2869+
std::string errMsg;
27862870
uint64_t offset = locs.EntriesBase + entryOffsets[i];
27872871
while (offset < namesSec.Data.size() && namesSec.Data[offset] != 0) {
27882872
// Read & store all entries (for the same string).
2789-
auto ie = makeThreadLocal<IndexEntry>();
2790-
ie->poolOffset = offset;
2791-
Error err = Error::success();
2792-
ie->abbrevCode =
2793-
static_cast<uint32_t>(namesExtractor.getULEB128(&offset, &err));
2794-
if (err) {
2795-
consumeError(std::move(err));
2796-
errMsg = ": invalid abbrev code in entry";
2797-
break;
2873+
Expected<IndexEntry *> ieOrErr =
2874+
readEntry(offset, ni, locs.EntriesBase, namesExtractor, namesSec);
2875+
if (!ieOrErr) {
2876+
errorOrWarn(toString(namesSec.sec) +
2877+
Twine(toString(ieOrErr.takeError())));
2878+
return;
27982879
}
2799-
auto it = ni.getAbbrevs().find_as(ie->abbrevCode);
2800-
if (it == ni.getAbbrevs().end()) {
2801-
errMsg = ": invalid abbrev code in entry";
2802-
break;
2803-
}
2804-
2805-
AttrValue attr, cuAttr = {0, 0};
2806-
for (DWARFDebugNames::AttributeEncoding a : it->Attributes) {
2807-
if (a.Index == dwarf::DW_IDX_parent) {
2808-
if (a.Form == dwarf::DW_FORM_ref4) {
2809-
attr.attrValue = namesExtractor.getU32(&offset, &err);
2810-
attr.attrSize = 4;
2811-
ie->parentOffset = locs.EntriesBase + attr.attrValue;
2812-
} else if (a.Form != DW_FORM_flag_present) {
2813-
errMsg = ": invalid form for DW_IDX_parent";
2814-
}
2815-
} else {
2816-
switch (a.Form) {
2817-
case DW_FORM_data1:
2818-
case DW_FORM_ref1: {
2819-
attr.attrValue = namesExtractor.getU8(&offset, &err);
2820-
attr.attrSize = 1;
2821-
break;
2822-
}
2823-
case DW_FORM_data2:
2824-
case DW_FORM_ref2: {
2825-
attr.attrValue = namesExtractor.getU16(&offset, &err);
2826-
attr.attrSize = 2;
2827-
break;
2828-
}
2829-
case DW_FORM_data4:
2830-
case DW_FORM_ref4: {
2831-
attr.attrValue = namesExtractor.getU32(&offset, &err);
2832-
attr.attrSize = 4;
2833-
break;
2834-
}
2835-
default:
2836-
errorOrWarn(toString(namesSec.sec) +
2837-
Twine(": unrecognized form encoding ") +
2838-
Twine(a.Form) + Twine(" in abbrev table"));
2839-
return;
2840-
}
2841-
}
2842-
if (err) {
2843-
errorOrWarn(toString(namesSec.sec) +
2844-
Twine(": error while reading attributes: ") +
2845-
toString(std::move(err)));
2846-
return;
2847-
}
2848-
if (a.Index == DW_IDX_compile_unit)
2849-
cuAttr = attr;
2850-
else if (a.Form != DW_FORM_flag_present)
2851-
ie->attrValues.push_back(attr);
2852-
}
2853-
2854-
// Canonicalize abbrev by placing the CU/TU index at the end.
2855-
ie->attrValues.push_back(cuAttr);
2856-
ne.indexEntries.push_back(std::move(ie));
2880+
ne.indexEntries.push_back(std::move(*ieOrErr));
28572881
}
28582882
if (offset >= namesSec.Data.size())
28592883
errMsg = ": index entry is out of bounds";
2860-
if (errMsg)
2861-
errorOrWarn(toString(namesSec.sec) + Twine(errMsg));
2884+
if (!errMsg.empty())
2885+
errorOrWarn(toString(namesSec.sec) + Twine(errMsg.c_str()));
28622886

28632887
for (IndexEntry &ie : ne.entries())
28642888
offsetMap[ie.poolOffset] = &ie;
@@ -2904,12 +2928,8 @@ void DebugNamesBaseSection::computeHdrAndAbbrevTable(
29042928
numCu += chunks[i].compUnits.size();
29052929
for (const NameData &nd : inputChunk.nameData) {
29062930
hdr.CompUnitCount += nd.hdr.CompUnitCount;
2907-
// We are not actually handling or emitting type units yet, so
2908-
// so non-zero type unit counts will crash LLD.
2909-
// TODO: Uncomment the two lines below when we implement this for
2910-
// type units & remove the following check/warning.
2911-
//hdr.LocalTypeUnitCount += nd.hdr.LocalTypeUnitCount;
2912-
//hdr.ForeignTypeUnitCount += nd.hdr.ForeignTypeUnitCount;
2931+
// TODO: We don't handle type units yet, so LocalTypeUnitCount &
2932+
// ForeignTypeUnitCount are left as 0.
29132933
if (nd.hdr.LocalTypeUnitCount || nd. hdr.ForeignTypeUnitCount)
29142934
warn(toString(inputChunk.section.sec) +
29152935
Twine(": type units are not implemented"));
@@ -2932,7 +2952,7 @@ void DebugNamesBaseSection::computeHdrAndAbbrevTable(
29322952
FoldingSet<Abbrev> abbrevSet;
29332953
// Determine the form for the DW_IDX_compile_unit attributes in the merged
29342954
// index. The input form may not be big enough for all CU indices.
2935-
const dwarf::Form cuAttrForm = getMergedCuCountForm(hdr.CompUnitCount).second;
2955+
dwarf::Form cuAttrForm = getMergedCuCountForm(hdr.CompUnitCount).second;
29362956
for (InputChunk &inputChunk : inputChunks) {
29372957
for (auto [i, ni] : enumerate(*inputChunk.llvmDebugNames)) {
29382958
for (const DWARFDebugNames::Abbrev &oldAbbrev : ni.getAbbrevs()) {
@@ -3003,10 +3023,10 @@ std::pair<uint32_t, uint32_t> DebugNamesBaseSection::computeEntryPool(
30033023
// Collect and de-duplicate all the names (preserving all the entries).
30043024
// Speed it up using multithreading, as the number of symbols can be in the
30053025
// order of millions.
3006-
const size_t concurrency =
3026+
size_t concurrency =
30073027
bit_floor(std::min<size_t>(config->threadCount, numShards));
3008-
const size_t shift = 32 - countr_zero(numShards);
3009-
const uint8_t cuAttrSize = getMergedCuCountForm(hdr.CompUnitCount).first;
3028+
size_t shift = 32 - countr_zero(numShards);
3029+
uint8_t cuAttrSize = getMergedCuCountForm(hdr.CompUnitCount).first;
30103030
DenseMap<CachedHashStringRef, size_t> maps[numShards];
30113031

30123032
parallelFor(0, concurrency, [&](size_t threadId) {
@@ -3237,8 +3257,8 @@ template <class ELFT> void DebugNamesSection<ELFT>::writeTo(uint8_t *buf) {
32373257
buf += hdr.AugmentationStringSize;
32383258

32393259
// Write the CU list.
3240-
for (auto i : seq(numChunks))
3241-
for (uint32_t cuOffset : chunks[i].compUnits)
3260+
for (auto &chunk : getChunks())
3261+
for (uint32_t cuOffset : chunk.compUnits)
32423262
endian::writeNext<uint32_t, ELFT::Endianness>(buf, cuOffset);
32433263

32443264
// TODO: Write the local TU list, then the foreign TU list..

lld/ELF/SyntheticSections.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,10 @@ class DebugNamesBaseSection : public SyntheticSection {
892892
SmallVector<Abbrev *, 0> abbrevTable;
893893
SmallVector<char, 0> abbrevTableBuf;
894894

895+
ArrayRef<OutputChunk> getChunks() {
896+
return ArrayRef(chunks.get(), numChunks);
897+
}
898+
895899
// Sharded name entries that will be used to compute bucket_count and the
896900
// count name table.
897901
static constexpr size_t numShards = 32;

lld/test/ELF/debug-names-bad.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
# RUN: llvm-mc -filetype=obj -triple=x86_64 bad-parent-form.s -o bad-parent-form.o
2727
# RUN: not ld.lld --debug-names bad-parent-form.o 2>&1 | FileCheck %s --check-prefix=BAD-PARENT-FORM --implicit-check-not=error:
2828

29-
# BAD-PARENT-FORM-COUNT-2: error: bad-parent-form.o:(.debug_names): invalid form for DW_IDX_parent
29+
# BAD-PARENT-FORM: error: bad-parent-form.o:(.debug_names): invalid form for DW_IDX_parent
3030

3131
# RUN: sed -E '/DW_IDX_die_offset/{n;s/[0-9]+.*DW_FORM_ref4/16/}' %S/Inputs/debug-names-a.s > bad-die-form.s
3232
# RUN: llvm-mc -filetype=obj -triple=x86_64 bad-die-form.s -o bad-die-form.o
@@ -41,7 +41,7 @@
4141
# RUN: ld.lld --debug-names bad-abbrev-code.o -o bad-abbrev-code --noinhibit-exec
4242
# RUN: llvm-dwarfdump --debug-names bad-abbrev-code | FileCheck %s --check-prefix=BAD-ABBREV-CODE-DWARF
4343

44-
# BAD-ABBREV-CODE-COUNT-2: error: bad-abbrev-code.o:(.debug_names): invalid abbrev code in entry
44+
# BAD-ABBREV-CODE: error: bad-abbrev-code.o:(.debug_names): entry abbrev code not found in abbrev table: 3
4545

4646
# BAD-ABBREV-CODE-DWARF: Abbreviations [
4747
# BAD-ABBREV-CODE-DWARF-NEXT: Abbreviation 0x1 {

0 commit comments

Comments
 (0)