mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-19 15:13:49 -04:00
[CodeView] Use assembler directives for line tables
Adds a new family of .cv_* directives to LLVM's variant of GAS syntax: - .cv_file: Similar to DWARF .file directives - .cv_loc: Similar to the DWARF .loc directive, but starts with a function id. CodeView line tables are emitted by function instead of by compilation unit, so we needed an extra field to communicate this. Rather than overloading the .loc direction further, we decided it was better to have our own directive. - .cv_stringtable: Emits the codeview string table at the current position. Currently this just contains the filenames as null-terminated strings. - .cv_filechecksums: Emits the file checksum table for all files used with .cv_file so far. There is currently no support for emitting actual checksums, just filenames. This moves the line table emission code down into the assembler. This is in preparation for implementing the inlined call site line table format. The inline line table format encoding algorithm requires knowing the absolute code offsets, so it must run after the assembler has laid out the code. David Majnemer collaborated on this patch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@259117 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -16,7 +16,22 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
StringTableBuilder::StringTableBuilder(Kind K) : K(K) {}
|
||||
StringTableBuilder::StringTableBuilder(Kind K) : K(K) {
|
||||
// Account for leading bytes in table so that offsets returned from add are
|
||||
// correct.
|
||||
switch (K) {
|
||||
case RAW:
|
||||
Size = 0;
|
||||
break;
|
||||
case MachO:
|
||||
case ELF:
|
||||
Size = 1;
|
||||
break;
|
||||
case WinCOFF:
|
||||
Size = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::pair<StringRef, size_t> StringPair;
|
||||
|
||||
@@ -62,13 +77,32 @@ tailcall:
|
||||
}
|
||||
|
||||
void StringTableBuilder::finalize() {
|
||||
std::vector<std::pair<StringRef, size_t> *> Strings;
|
||||
finalizeStringTable(/*Optimize=*/true);
|
||||
}
|
||||
|
||||
void StringTableBuilder::finalizeInOrder() {
|
||||
finalizeStringTable(/*Optimize=*/false);
|
||||
}
|
||||
|
||||
void StringTableBuilder::finalizeStringTable(bool Optimize) {
|
||||
typedef std::pair<StringRef, size_t> StringOffsetPair;
|
||||
std::vector<StringOffsetPair *> Strings;
|
||||
Strings.reserve(StringIndexMap.size());
|
||||
for (std::pair<StringRef, size_t> &P : StringIndexMap)
|
||||
for (StringOffsetPair &P : StringIndexMap)
|
||||
Strings.push_back(&P);
|
||||
|
||||
if (!Strings.empty())
|
||||
multikey_qsort(&Strings[0], &Strings[0] + Strings.size(), 0);
|
||||
if (!Strings.empty()) {
|
||||
// If we're optimizing, sort by name. If not, sort by previously assigned
|
||||
// offset.
|
||||
if (Optimize) {
|
||||
multikey_qsort(&Strings[0], &Strings[0] + Strings.size(), 0);
|
||||
} else {
|
||||
std::sort(Strings.begin(), Strings.end(),
|
||||
[](const StringOffsetPair *LHS, const StringOffsetPair *RHS) {
|
||||
return LHS->second < RHS->second;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
switch (K) {
|
||||
case RAW:
|
||||
@@ -85,17 +119,22 @@ void StringTableBuilder::finalize() {
|
||||
}
|
||||
|
||||
StringRef Previous;
|
||||
for (std::pair<StringRef, size_t> *P : Strings) {
|
||||
for (StringOffsetPair *P : Strings) {
|
||||
StringRef S = P->first;
|
||||
if (K == WinCOFF)
|
||||
assert(S.size() > COFF::NameSize && "Short string in COFF string table!");
|
||||
|
||||
if (Previous.endswith(S)) {
|
||||
if (Optimize && Previous.endswith(S)) {
|
||||
P->second = StringTable.size() - S.size() - (K != RAW);
|
||||
continue;
|
||||
}
|
||||
|
||||
P->second = StringTable.size();
|
||||
if (Optimize)
|
||||
P->second = StringTable.size();
|
||||
else
|
||||
assert(P->second == StringTable.size() &&
|
||||
"different strtab offset after finalization");
|
||||
|
||||
StringTable += S;
|
||||
if (K != RAW)
|
||||
StringTable += '\x00';
|
||||
|
||||
Reference in New Issue
Block a user