[codeview] Add .cv_string directive for testing purposes

The main use case for this directive is to allow assembly writers to
write their own FPO data strings without going through the .cv_fpo*
directive family.

I'm experimenting with different RPN programs to fix PR38857, and I
figured I should go ahead and make this directive permanent.

llvm-svn: 341712
This commit is contained in:
Reid Kleckner 2018-09-07 21:30:52 +00:00
parent fa535c027e
commit 06d02d0306
2 changed files with 89 additions and 1 deletions

View File

@ -467,6 +467,7 @@ private:
DK_CV_INLINE_LINETABLE,
DK_CV_DEF_RANGE,
DK_CV_STRINGTABLE,
DK_CV_STRING,
DK_CV_FILECHECKSUMS,
DK_CV_FILECHECKSUM_OFFSET,
DK_CV_FPO_DATA,
@ -538,7 +539,7 @@ private:
bool parseDirectiveStabs();
// ".cv_file", ".cv_func_id", ".cv_inline_site_id", ".cv_loc", ".cv_linetable",
// ".cv_inline_linetable", ".cv_def_range"
// ".cv_inline_linetable", ".cv_def_range", ".cv_string"
bool parseDirectiveCVFile();
bool parseDirectiveCVFuncId();
bool parseDirectiveCVInlineSiteId();
@ -546,6 +547,7 @@ private:
bool parseDirectiveCVLinetable();
bool parseDirectiveCVInlineLinetable();
bool parseDirectiveCVDefRange();
bool parseDirectiveCVString();
bool parseDirectiveCVStringTable();
bool parseDirectiveCVFileChecksums();
bool parseDirectiveCVFileChecksumOffset();
@ -2029,6 +2031,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveCVInlineLinetable();
case DK_CV_DEF_RANGE:
return parseDirectiveCVDefRange();
case DK_CV_STRING:
return parseDirectiveCVString();
case DK_CV_STRINGTABLE:
return parseDirectiveCVStringTable();
case DK_CV_FILECHECKSUMS:
@ -3813,6 +3817,20 @@ bool AsmParser::parseDirectiveCVDefRange() {
return false;
}
/// parseDirectiveCVString
/// ::= .cv_stringtable "string"
bool AsmParser::parseDirectiveCVString() {
std::string Data;
if (checkForValidSection() || parseEscapedString(Data))
return addErrorSuffix(" in '.cv_string' directive");
// Put the string in the table and emit the offset.
std::pair<StringRef, unsigned> Insertion =
getCVContext().addToStringTable(Data);
getStreamer().EmitIntValue(Insertion.second, 4);
return false;
}
/// parseDirectiveCVStringTable
/// ::= .cv_stringtable
bool AsmParser::parseDirectiveCVStringTable() {
@ -5238,6 +5256,7 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
DirectiveKindMap[".cv_string"] = DK_CV_STRING;
DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;

View File

@ -0,0 +1,69 @@
# RUN: llvm-mc -triple=i686-windows-msvc %s -filetype=obj -o %t.obj
# RUN: llvm-readobj -codeview %t.obj | FileCheck %s
# The .cv_string directive mainly exists as a convenience for manually writing
# FPO data in assembler. Test that we can write FPO data using this directive,
# and that the string comes out in the dumper.
# void g(int);
# void f(int x) {
# g(x+1);
# }
# CHECK: FrameFunc [
# CHECK-NEXT: abc =
# CHECK-NEXT: def =
# CHECK-NEXT: ghi =
# CHECK-NEXT: ]
.text
.def @feat.00;
.scl 3;
.type 0;
.endef
.globl @feat.00
.set @feat.00, 1
.def _f;
.scl 2;
.type 32;
.endef
.globl _f # -- Begin function f
.p2align 4, 0x90
_f: # @f
Lfunc_begin0:
# %bb.0: # %entry
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl 8(%ebp), %eax
movl 8(%ebp), %ecx
addl $1, %ecx
movl %ecx, (%esp)
movl %eax, -4(%ebp) # 4-byte Spill
calll _g
addl $8, %esp
popl %ebp
retl
Lfunc_end0:
# -- End function
.section .debug$S,"dr"
.p2align 2
.long 4 # Debug section magic
# Open coded frame data
.long 245
.long Lfoo_fpo_end-Lfoo_fpo_begin # Subsection size
Lfoo_fpo_begin:
.long _f
.long 0
.long Lfunc_end0-Lfunc_begin0
.long 24 # LocalSize
.long 0 # ParamSize
.long 0 # MaxStackSize
.cv_string "abc = def = ghi = "
.short 0 # PrologSize
.short 0 # SavedRegSize
.long 0x4 # Flags
Lfoo_fpo_end:
.p2align 2
.cv_stringtable # String table