mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-28 14:10:55 +00:00
[DWARF] Make -g with empty assembler source work better.
This was sometimes causing clang or llvm-mc to crash, and in other cases could emit a bogus DWARF line-table header. I did an interim patch in r352541; this patch should be a cleaner and more complete fix, and retains the test. Addresses PR40538. Differential Revision: https://reviews.llvm.org/D58750 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355226 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a3fccdcc5d
commit
f3284d8600
@ -594,6 +594,10 @@ namespace llvm {
|
||||
GenDwarfFileNumber = FileNumber;
|
||||
}
|
||||
|
||||
/// Specifies information about the "root file" for assembler clients
|
||||
/// (e.g., llvm-mc). Assumes compilation dir etc. have been set up.
|
||||
void setGenDwarfRootFile(StringRef FileName, StringRef Buffer);
|
||||
|
||||
const SetVector<MCSection *> &getGenDwarfSectionSyms() {
|
||||
return SectionsForRanges;
|
||||
}
|
||||
|
@ -320,6 +320,8 @@ public:
|
||||
|
||||
bool hasRootFile() const { return !Header.RootFile.Name.empty(); }
|
||||
|
||||
const MCDwarfFile &getRootFile() const { return Header.RootFile; }
|
||||
|
||||
// Report whether MD5 usage has been consistent (all-or-none).
|
||||
bool isMD5UsageConsistent() const { return Header.isMD5UsageConsistent(); }
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/Signals.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@ -565,6 +566,29 @@ void MCContext::RemapDebugPaths() {
|
||||
// Dwarf Management
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) {
|
||||
// MCDwarf needs the root file as well as the compilation directory.
|
||||
// If we find a '.file 0' directive that will supersede these values.
|
||||
MD5::MD5Result *Cksum = nullptr;
|
||||
if (getDwarfVersion() >= 5) {
|
||||
MD5 Hash;
|
||||
Cksum = (MD5::MD5Result *)allocate(sizeof(MD5::MD5Result), 1);
|
||||
Hash.update(Buffer);
|
||||
Hash.final(*Cksum);
|
||||
}
|
||||
// Canonicalize the root filename. It cannot be empty, and should not
|
||||
// repeat the compilation dir.
|
||||
StringRef FileName =
|
||||
!getMainFileName().empty() ? StringRef(getMainFileName()) : InputFileName;
|
||||
if (FileName.empty() || FileName == "-")
|
||||
FileName = "<stdin>";
|
||||
if (FileName.consume_front(getCompilationDir()))
|
||||
FileName.consume_front(llvm::sys::path::get_separator());
|
||||
assert(!FileName.empty());
|
||||
setMCLineTableRootFile(
|
||||
/*CUID=*/0, getCompilationDir(), FileName, Cksum, None);
|
||||
}
|
||||
|
||||
/// getDwarfFile - takes a file name and number to place in the dwarf file and
|
||||
/// directory tables. If the file number has already been allocated it is an
|
||||
/// error and zero is returned and the client reports the error, else the
|
||||
|
@ -430,10 +430,14 @@ void MCDwarfLineTableHeader::emitV5FileDirTables(
|
||||
: dwarf::DW_FORM_string);
|
||||
}
|
||||
// Then the counted list of files. The root file is file #0, then emit the
|
||||
// files as provide by .file directives. To accommodate assembler source
|
||||
// written for DWARF v4 but trying to emit v5, if we didn't see a root file
|
||||
// explicitly, replicate file #1.
|
||||
MCOS->EmitULEB128IntValue(MCDwarfFiles.size());
|
||||
// files as provide by .file directives.
|
||||
// MCDwarfFiles has an unused element [0] so use size() not size()+1.
|
||||
// But sometimes MCDwarfFiles is empty, in which case we still emit one file.
|
||||
MCOS->EmitULEB128IntValue(MCDwarfFiles.empty() ? 1 : MCDwarfFiles.size());
|
||||
// To accommodate assembler source written for DWARF v4 but trying to emit
|
||||
// v5: If we didn't see a root file explicitly, replicate file #1.
|
||||
assert((!RootFile.Name.empty() || MCDwarfFiles.size() >= 1) &&
|
||||
"No root file and no .file directives");
|
||||
emitOneV5FileEntry(MCOS, RootFile.Name.empty() ? MCDwarfFiles[1] : RootFile,
|
||||
HasAllMD5, HasSource, LineStr);
|
||||
for (unsigned i = 1; i < MCDwarfFiles.size(); ++i)
|
||||
@ -1006,9 +1010,15 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
|
||||
MCOS->EmitBytes(MCDwarfDirs[0]);
|
||||
MCOS->EmitBytes(sys::path::get_separator());
|
||||
}
|
||||
const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles =
|
||||
MCOS->getContext().getMCDwarfFiles();
|
||||
MCOS->EmitBytes(MCDwarfFiles[1].Name);
|
||||
const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = context.getMCDwarfFiles();
|
||||
// MCDwarfFiles might be empty if we have an empty source file.
|
||||
// If it's not empty, [0] is unused and [1] is the first actual file.
|
||||
assert(MCDwarfFiles.empty() || MCDwarfFiles.size() >= 2);
|
||||
const MCDwarfFile &RootFile =
|
||||
MCDwarfFiles.empty()
|
||||
? context.getMCDwarfLineTable(/*CUID=*/0).getRootFile()
|
||||
: MCDwarfFiles[1];
|
||||
MCOS->EmitBytes(RootFile.Name);
|
||||
MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
|
||||
|
||||
// AT_comp_dir, the working directory the assembly was done in.
|
||||
|
@ -845,9 +845,13 @@ bool AsmParser::enabledGenDwarfForAssembly() {
|
||||
// If we haven't encountered any .file directives (which would imply that
|
||||
// the assembler source was produced with debug info already) then emit one
|
||||
// describing the assembler source file itself.
|
||||
if (getContext().getGenDwarfFileNumber() == 0)
|
||||
if (getContext().getGenDwarfFileNumber() == 0) {
|
||||
const MCDwarfFile &RootFile =
|
||||
getContext().getMCDwarfLineTable(/*CUID=*/0).getRootFile();
|
||||
getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective(
|
||||
0, StringRef(), getContext().getMainFileName()));
|
||||
/*CUID=*/0, getContext().getCompilationDir(), RootFile.Name,
|
||||
RootFile.Checksum, RootFile.Source));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -900,9 +904,6 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
|
||||
eatToEndOfStatement();
|
||||
}
|
||||
|
||||
// Make sure we get proper DWARF even for empty files.
|
||||
(void)enabledGenDwarfForAssembly();
|
||||
|
||||
getTargetParser().onEndOfFile();
|
||||
printPendingErrors();
|
||||
|
||||
|
@ -20,6 +20,6 @@ f:
|
||||
// MAP: DW_AT_comp_dir [DW_FORM_string] ("src_root")
|
||||
// MAP: DW_AT_decl_file [DW_FORM_data4] ("src_root{{(/|\\)+}}src.s")
|
||||
|
||||
// MAP_ABS: DW_AT_name [DW_FORM_string] ("{{(/|\\)+}}src_root{{(/|\\)+}}src.s")
|
||||
// MAP_ABS: DW_AT_name [DW_FORM_string] ("src.s")
|
||||
// MAP_ABS: DW_AT_comp_dir [DW_FORM_string] ("{{(/|\\)+}}src_root")
|
||||
// MAP_ABS: DW_AT_decl_file [DW_FORM_data4] ("{{(/|\\)+}}src_root{{(/|\\)+}}src.s")
|
||||
|
@ -401,18 +401,8 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
if (!MainFileName.empty())
|
||||
Ctx.setMainFileName(MainFileName);
|
||||
if (GenDwarfForAssembly && DwarfVersion >= 5) {
|
||||
// DWARF v5 needs the root file as well as the compilation directory.
|
||||
// If we find a '.file 0' directive that will supersede these values.
|
||||
MD5 Hash;
|
||||
MD5::MD5Result *Cksum =
|
||||
(MD5::MD5Result *)Ctx.allocate(sizeof(MD5::MD5Result), 1);
|
||||
Hash.update(Buffer->getBuffer());
|
||||
Hash.final(*Cksum);
|
||||
Ctx.setMCLineTableRootFile(
|
||||
/*CUID=*/0, Ctx.getCompilationDir(),
|
||||
!MainFileName.empty() ? MainFileName : InputFilename, Cksum, None);
|
||||
}
|
||||
if (GenDwarfForAssembly)
|
||||
Ctx.setGenDwarfRootFile(InputFilename, Buffer->getBuffer());
|
||||
|
||||
// Package up features to be passed to target/subtarget
|
||||
std::string FeaturesStr;
|
||||
|
Loading…
Reference in New Issue
Block a user