2017-08-18 05:26:39 +08:00
|
|
|
//===- llvm/CodeGen/DwarfStringPool.cpp - Dwarf Debug Framework -----------===//
|
2014-04-26 05:34:35 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2014-04-26 05:34:35 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "DwarfStringPool.h"
|
2017-08-18 05:26:39 +08:00
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
|
|
#include "llvm/ADT/Twine.h"
|
2015-05-25 00:54:59 +08:00
|
|
|
#include "llvm/CodeGen/AsmPrinter.h"
|
2015-05-25 00:58:59 +08:00
|
|
|
#include "llvm/MC/MCAsmInfo.h"
|
2014-04-26 05:34:35 +08:00
|
|
|
#include "llvm/MC/MCStreamer.h"
|
2017-08-18 05:26:39 +08:00
|
|
|
#include <cassert>
|
|
|
|
#include <utility>
|
2014-04-26 05:34:35 +08:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2015-05-25 00:58:59 +08:00
|
|
|
DwarfStringPool::DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm,
|
|
|
|
StringRef Prefix)
|
|
|
|
: Pool(A), Prefix(Prefix),
|
|
|
|
ShouldCreateSymbols(Asm.MAI->doesDwarfUseRelocationsAcrossSections()) {}
|
|
|
|
|
[DebugInfo] Reduce debug_str_offsets section size
Summary:
The accelerator tables use the debug_str section to store their strings.
However, they do not support the indirect method of access that is
available for the debug_info section (DW_FORM_strx et al.).
Currently our code is assuming that all strings can/will be referenced
indirectly, and puts all of them into the debug_str_offsets section.
This is generally true for regular (unsplit) dwarf, but in the DWO case,
most of the strings in the debug_str section will only be used from the
accelerator tables. Therefore the contents of the debug_str_offsets
section will be largely unused and bloating the main executable.
This patch rectifies this by teaching the DwarfStringPool to
differentiate between strings accessed directly and indirectly. When a
user inserts a string into the pool it has to declare whether that
string will be referenced directly or not. If at least one user requsts
indirect access, that string will be assigned an index ID and put into
debug_str_offsets table. Otherwise, the offset table is skipped.
This approach reduces the overall binary size (when compiled with
-gdwarf-5 -gsplit-dwarf) in my tests by about 2% (debug_str_offsets is
shrunk by 99%).
Reviewers: probinson, dblaikie, JDevlieghere
Subscribers: aprantl, mgrang, llvm-commits
Differential Revision: https://reviews.llvm.org/D49493
llvm-svn: 339122
2018-08-07 17:54:52 +08:00
|
|
|
StringMapEntry<DwarfStringPool::EntryTy> &
|
|
|
|
DwarfStringPool::getEntryImpl(AsmPrinter &Asm, StringRef Str) {
|
2015-05-25 00:33:33 +08:00
|
|
|
auto I = Pool.insert(std::make_pair(Str, EntryTy()));
|
[DebugInfo] Reduce debug_str_offsets section size
Summary:
The accelerator tables use the debug_str section to store their strings.
However, they do not support the indirect method of access that is
available for the debug_info section (DW_FORM_strx et al.).
Currently our code is assuming that all strings can/will be referenced
indirectly, and puts all of them into the debug_str_offsets section.
This is generally true for regular (unsplit) dwarf, but in the DWO case,
most of the strings in the debug_str section will only be used from the
accelerator tables. Therefore the contents of the debug_str_offsets
section will be largely unused and bloating the main executable.
This patch rectifies this by teaching the DwarfStringPool to
differentiate between strings accessed directly and indirectly. When a
user inserts a string into the pool it has to declare whether that
string will be referenced directly or not. If at least one user requsts
indirect access, that string will be assigned an index ID and put into
debug_str_offsets table. Otherwise, the offset table is skipped.
This approach reduces the overall binary size (when compiled with
-gdwarf-5 -gsplit-dwarf) in my tests by about 2% (debug_str_offsets is
shrunk by 99%).
Reviewers: probinson, dblaikie, JDevlieghere
Subscribers: aprantl, mgrang, llvm-commits
Differential Revision: https://reviews.llvm.org/D49493
llvm-svn: 339122
2018-08-07 17:54:52 +08:00
|
|
|
auto &Entry = I.first->second;
|
2015-05-25 00:33:33 +08:00
|
|
|
if (I.second) {
|
[DebugInfo] Reduce debug_str_offsets section size
Summary:
The accelerator tables use the debug_str section to store their strings.
However, they do not support the indirect method of access that is
available for the debug_info section (DW_FORM_strx et al.).
Currently our code is assuming that all strings can/will be referenced
indirectly, and puts all of them into the debug_str_offsets section.
This is generally true for regular (unsplit) dwarf, but in the DWO case,
most of the strings in the debug_str section will only be used from the
accelerator tables. Therefore the contents of the debug_str_offsets
section will be largely unused and bloating the main executable.
This patch rectifies this by teaching the DwarfStringPool to
differentiate between strings accessed directly and indirectly. When a
user inserts a string into the pool it has to declare whether that
string will be referenced directly or not. If at least one user requsts
indirect access, that string will be assigned an index ID and put into
debug_str_offsets table. Otherwise, the offset table is skipped.
This approach reduces the overall binary size (when compiled with
-gdwarf-5 -gsplit-dwarf) in my tests by about 2% (debug_str_offsets is
shrunk by 99%).
Reviewers: probinson, dblaikie, JDevlieghere
Subscribers: aprantl, mgrang, llvm-commits
Differential Revision: https://reviews.llvm.org/D49493
llvm-svn: 339122
2018-08-07 17:54:52 +08:00
|
|
|
Entry.Index = EntryTy::NotIndexed;
|
2015-05-25 00:14:59 +08:00
|
|
|
Entry.Offset = NumBytes;
|
2015-05-25 00:58:59 +08:00
|
|
|
Entry.Symbol = ShouldCreateSymbols ? Asm.createTempSymbol(Prefix) : nullptr;
|
2015-05-25 00:14:59 +08:00
|
|
|
|
|
|
|
NumBytes += Str.size() + 1;
|
2014-04-26 05:34:35 +08:00
|
|
|
}
|
[DebugInfo] Reduce debug_str_offsets section size
Summary:
The accelerator tables use the debug_str section to store their strings.
However, they do not support the indirect method of access that is
available for the debug_info section (DW_FORM_strx et al.).
Currently our code is assuming that all strings can/will be referenced
indirectly, and puts all of them into the debug_str_offsets section.
This is generally true for regular (unsplit) dwarf, but in the DWO case,
most of the strings in the debug_str section will only be used from the
accelerator tables. Therefore the contents of the debug_str_offsets
section will be largely unused and bloating the main executable.
This patch rectifies this by teaching the DwarfStringPool to
differentiate between strings accessed directly and indirectly. When a
user inserts a string into the pool it has to declare whether that
string will be referenced directly or not. If at least one user requsts
indirect access, that string will be assigned an index ID and put into
debug_str_offsets table. Otherwise, the offset table is skipped.
This approach reduces the overall binary size (when compiled with
-gdwarf-5 -gsplit-dwarf) in my tests by about 2% (debug_str_offsets is
shrunk by 99%).
Reviewers: probinson, dblaikie, JDevlieghere
Subscribers: aprantl, mgrang, llvm-commits
Differential Revision: https://reviews.llvm.org/D49493
llvm-svn: 339122
2018-08-07 17:54:52 +08:00
|
|
|
return *I.first;
|
|
|
|
}
|
|
|
|
|
|
|
|
DwarfStringPool::EntryRef DwarfStringPool::getEntry(AsmPrinter &Asm,
|
|
|
|
StringRef Str) {
|
|
|
|
auto &MapEntry = getEntryImpl(Asm, Str);
|
|
|
|
return EntryRef(MapEntry, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
DwarfStringPool::EntryRef DwarfStringPool::getIndexedEntry(AsmPrinter &Asm,
|
|
|
|
StringRef Str) {
|
|
|
|
auto &MapEntry = getEntryImpl(Asm, Str);
|
|
|
|
if (!MapEntry.getValue().isIndexed())
|
|
|
|
MapEntry.getValue().Index = NumIndexedStrings++;
|
|
|
|
return EntryRef(MapEntry, true);
|
2014-04-26 05:34:35 +08:00
|
|
|
}
|
|
|
|
|
2018-07-26 22:36:07 +08:00
|
|
|
void DwarfStringPool::emitStringOffsetsTableHeader(AsmPrinter &Asm,
|
|
|
|
MCSection *Section,
|
|
|
|
MCSymbol *StartSym) {
|
[DebugInfo] Reduce debug_str_offsets section size
Summary:
The accelerator tables use the debug_str section to store their strings.
However, they do not support the indirect method of access that is
available for the debug_info section (DW_FORM_strx et al.).
Currently our code is assuming that all strings can/will be referenced
indirectly, and puts all of them into the debug_str_offsets section.
This is generally true for regular (unsplit) dwarf, but in the DWO case,
most of the strings in the debug_str section will only be used from the
accelerator tables. Therefore the contents of the debug_str_offsets
section will be largely unused and bloating the main executable.
This patch rectifies this by teaching the DwarfStringPool to
differentiate between strings accessed directly and indirectly. When a
user inserts a string into the pool it has to declare whether that
string will be referenced directly or not. If at least one user requsts
indirect access, that string will be assigned an index ID and put into
debug_str_offsets table. Otherwise, the offset table is skipped.
This approach reduces the overall binary size (when compiled with
-gdwarf-5 -gsplit-dwarf) in my tests by about 2% (debug_str_offsets is
shrunk by 99%).
Reviewers: probinson, dblaikie, JDevlieghere
Subscribers: aprantl, mgrang, llvm-commits
Differential Revision: https://reviews.llvm.org/D49493
llvm-svn: 339122
2018-08-07 17:54:52 +08:00
|
|
|
if (getNumIndexedStrings() == 0)
|
2018-07-26 22:36:07 +08:00
|
|
|
return;
|
|
|
|
Asm.OutStreamer->SwitchSection(Section);
|
2020-09-15 12:30:53 +08:00
|
|
|
unsigned EntrySize = Asm.getDwarfOffsetByteSize();
|
2018-07-26 22:36:07 +08:00
|
|
|
// We are emitting the header for a contribution to the string offsets
|
|
|
|
// table. The header consists of an entry with the contribution's
|
|
|
|
// size (not including the size of the length field), the DWARF version and
|
|
|
|
// 2 bytes of padding.
|
2020-09-15 12:30:53 +08:00
|
|
|
Asm.emitDwarfUnitLength(getNumIndexedStrings() * EntrySize + 4,
|
|
|
|
"Length of String Offsets Set");
|
2018-07-26 22:36:07 +08:00
|
|
|
Asm.emitInt16(Asm.getDwarfVersion());
|
|
|
|
Asm.emitInt16(0);
|
|
|
|
// Define the symbol that marks the start of the contribution. It is
|
|
|
|
// referenced by most unit headers via DW_AT_str_offsets_base.
|
|
|
|
// Split units do not use the attribute.
|
|
|
|
if (StartSym)
|
2020-02-15 11:21:58 +08:00
|
|
|
Asm.OutStreamer->emitLabel(StartSym);
|
2018-07-26 22:36:07 +08:00
|
|
|
}
|
|
|
|
|
2015-05-22 03:20:38 +08:00
|
|
|
void DwarfStringPool::emit(AsmPrinter &Asm, MCSection *StrSection,
|
2018-01-27 02:52:58 +08:00
|
|
|
MCSection *OffsetSection, bool UseRelativeOffsets) {
|
2014-04-26 05:34:35 +08:00
|
|
|
if (Pool.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Start the dwarf str section.
|
2015-04-25 03:11:51 +08:00
|
|
|
Asm.OutStreamer->SwitchSection(StrSection);
|
2014-04-26 05:34:35 +08:00
|
|
|
|
[DebugInfo] Reduce debug_str_offsets section size
Summary:
The accelerator tables use the debug_str section to store their strings.
However, they do not support the indirect method of access that is
available for the debug_info section (DW_FORM_strx et al.).
Currently our code is assuming that all strings can/will be referenced
indirectly, and puts all of them into the debug_str_offsets section.
This is generally true for regular (unsplit) dwarf, but in the DWO case,
most of the strings in the debug_str section will only be used from the
accelerator tables. Therefore the contents of the debug_str_offsets
section will be largely unused and bloating the main executable.
This patch rectifies this by teaching the DwarfStringPool to
differentiate between strings accessed directly and indirectly. When a
user inserts a string into the pool it has to declare whether that
string will be referenced directly or not. If at least one user requsts
indirect access, that string will be assigned an index ID and put into
debug_str_offsets table. Otherwise, the offset table is skipped.
This approach reduces the overall binary size (when compiled with
-gdwarf-5 -gsplit-dwarf) in my tests by about 2% (debug_str_offsets is
shrunk by 99%).
Reviewers: probinson, dblaikie, JDevlieghere
Subscribers: aprantl, mgrang, llvm-commits
Differential Revision: https://reviews.llvm.org/D49493
llvm-svn: 339122
2018-08-07 17:54:52 +08:00
|
|
|
// Get all of the string pool entries and sort them by their offset.
|
|
|
|
SmallVector<const StringMapEntry<EntryTy> *, 64> Entries;
|
|
|
|
Entries.reserve(Pool.size());
|
2014-04-26 05:34:35 +08:00
|
|
|
|
|
|
|
for (const auto &E : Pool)
|
[DebugInfo] Reduce debug_str_offsets section size
Summary:
The accelerator tables use the debug_str section to store their strings.
However, they do not support the indirect method of access that is
available for the debug_info section (DW_FORM_strx et al.).
Currently our code is assuming that all strings can/will be referenced
indirectly, and puts all of them into the debug_str_offsets section.
This is generally true for regular (unsplit) dwarf, but in the DWO case,
most of the strings in the debug_str section will only be used from the
accelerator tables. Therefore the contents of the debug_str_offsets
section will be largely unused and bloating the main executable.
This patch rectifies this by teaching the DwarfStringPool to
differentiate between strings accessed directly and indirectly. When a
user inserts a string into the pool it has to declare whether that
string will be referenced directly or not. If at least one user requsts
indirect access, that string will be assigned an index ID and put into
debug_str_offsets table. Otherwise, the offset table is skipped.
This approach reduces the overall binary size (when compiled with
-gdwarf-5 -gsplit-dwarf) in my tests by about 2% (debug_str_offsets is
shrunk by 99%).
Reviewers: probinson, dblaikie, JDevlieghere
Subscribers: aprantl, mgrang, llvm-commits
Differential Revision: https://reviews.llvm.org/D49493
llvm-svn: 339122
2018-08-07 17:54:52 +08:00
|
|
|
Entries.push_back(&E);
|
|
|
|
|
2018-10-01 06:31:29 +08:00
|
|
|
llvm::sort(Entries, [](const StringMapEntry<EntryTy> *A,
|
|
|
|
const StringMapEntry<EntryTy> *B) {
|
|
|
|
return A->getValue().Offset < B->getValue().Offset;
|
|
|
|
});
|
2014-04-26 05:34:35 +08:00
|
|
|
|
|
|
|
for (const auto &Entry : Entries) {
|
2015-05-25 00:58:59 +08:00
|
|
|
assert(ShouldCreateSymbols == static_cast<bool>(Entry->getValue().Symbol) &&
|
|
|
|
"Mismatch between setting and entry");
|
|
|
|
|
2014-04-26 05:34:35 +08:00
|
|
|
// Emit a label for reference from debug information entries.
|
2015-05-25 00:58:59 +08:00
|
|
|
if (ShouldCreateSymbols)
|
2020-02-15 11:21:58 +08:00
|
|
|
Asm.OutStreamer->emitLabel(Entry->getValue().Symbol);
|
2014-04-26 05:34:35 +08:00
|
|
|
|
|
|
|
// Emit the string itself with a terminating null byte.
|
2015-05-25 00:14:59 +08:00
|
|
|
Asm.OutStreamer->AddComment("string offset=" +
|
|
|
|
Twine(Entry->getValue().Offset));
|
2020-02-15 10:16:24 +08:00
|
|
|
Asm.OutStreamer->emitBytes(
|
2014-04-26 05:34:35 +08:00
|
|
|
StringRef(Entry->getKeyData(), Entry->getKeyLength() + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we've got an offset section go ahead and emit that now as well.
|
|
|
|
if (OffsetSection) {
|
[DebugInfo] Reduce debug_str_offsets section size
Summary:
The accelerator tables use the debug_str section to store their strings.
However, they do not support the indirect method of access that is
available for the debug_info section (DW_FORM_strx et al.).
Currently our code is assuming that all strings can/will be referenced
indirectly, and puts all of them into the debug_str_offsets section.
This is generally true for regular (unsplit) dwarf, but in the DWO case,
most of the strings in the debug_str section will only be used from the
accelerator tables. Therefore the contents of the debug_str_offsets
section will be largely unused and bloating the main executable.
This patch rectifies this by teaching the DwarfStringPool to
differentiate between strings accessed directly and indirectly. When a
user inserts a string into the pool it has to declare whether that
string will be referenced directly or not. If at least one user requsts
indirect access, that string will be assigned an index ID and put into
debug_str_offsets table. Otherwise, the offset table is skipped.
This approach reduces the overall binary size (when compiled with
-gdwarf-5 -gsplit-dwarf) in my tests by about 2% (debug_str_offsets is
shrunk by 99%).
Reviewers: probinson, dblaikie, JDevlieghere
Subscribers: aprantl, mgrang, llvm-commits
Differential Revision: https://reviews.llvm.org/D49493
llvm-svn: 339122
2018-08-07 17:54:52 +08:00
|
|
|
// Now only take the indexed entries and put them in an array by their ID so
|
|
|
|
// we can emit them in order.
|
|
|
|
Entries.resize(NumIndexedStrings);
|
|
|
|
for (const auto &Entry : Pool) {
|
|
|
|
if (Entry.getValue().isIndexed())
|
|
|
|
Entries[Entry.getValue().Index] = &Entry;
|
|
|
|
}
|
|
|
|
|
2015-04-25 03:11:51 +08:00
|
|
|
Asm.OutStreamer->SwitchSection(OffsetSection);
|
2020-09-15 12:31:00 +08:00
|
|
|
unsigned size = Asm.getDwarfOffsetByteSize();
|
2015-05-25 00:14:59 +08:00
|
|
|
for (const auto &Entry : Entries)
|
2018-01-27 02:52:58 +08:00
|
|
|
if (UseRelativeOffsets)
|
|
|
|
Asm.emitDwarfStringOffset(Entry->getValue());
|
|
|
|
else
|
2020-02-15 14:40:47 +08:00
|
|
|
Asm.OutStreamer->emitIntValue(Entry->getValue().Offset, size);
|
2014-04-26 05:34:35 +08:00
|
|
|
}
|
|
|
|
}
|