Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 15 additions & 32 deletions compiler/src/dmd/backend/cgcv.d
Original file line number Diff line number Diff line change
Expand Up @@ -193,18 +193,16 @@ int cv_namestring(ubyte* p, const(char)* name, int length = -1)
@trusted
debtyp_t* debtyp_alloc(uint length)
{
debtyp_t* d;
uint pad = 0;

//printf("len = %u, x%x\n", length, length);
// length+2 must lie on 4 byte boundary
pad = ((length + 2 + 3) & ~3) - (length + 2);
uint pad = ((length + 2 + 3) & ~3) - (length + 2);
length += pad;

if (length > ushort.max)
err_nomem();

const len = debtyp_t.sizeof - (d.data).sizeof + length;
const len = debtyp_t.sizeof - debtyp_t.data.sizeof + length;
debtyp_t* d;
debug
{
d = cast(debtyp_t*) mem_malloc(len /*+ 1*/);
Expand Down Expand Up @@ -324,8 +322,7 @@ idx_t cv_numdebtypes()

@trusted
void cv_init()
{ debtyp_t* d;

{
//printf("cv_init()\n");

// Initialize statics
Expand Down Expand Up @@ -404,12 +401,7 @@ void cv_init()
cgcv.FD_code = 0x10;
}

int flags;
__gshared ushort[5] memmodel = [0,0x100,0x20,0x120,0x120];
char[1 + (VERSION).sizeof] version_;
ubyte[8 + (version_).sizeof] debsym;

// Put out signature indicating CV4 format
// Put out signature indicating CV8 format
cgcv.signature = 4;
cgcv.deb_offset = 0x1000;
cgcv.sz_idx = 4;
Expand Down Expand Up @@ -604,29 +596,23 @@ private uint cv4_symtypidx(Symbol* s)
uint cv4_typidx(type* t)
{ uint typidx;
uint u;
uint next;
uint key;
debtyp_t* d;
targ_size_t size;
tym_t tym;
tym_t tycv;
tym_t tymnext;
type* tv;
uint dt;
uint attribute;
ubyte call;

//printf("cv4_typidx(%p)\n",t);
if (!t)
return dttab4[TYint]; // assume int
type_debug(t);
next = cv4_typidx(t.Tnext);
tycv = t.Tty;
tym = tybasic(tycv);
uint next = cv4_typidx(t.Tnext);
tym_t tycv = t.Tty;
tym_t tym = tybasic(tycv);
tycv &= mTYconst | mTYvolatile | mTYimmutable;
attribute = 0;
uint attribute = 0;
L1:
dt = dttab4[tym];
uint dt = dttab4[tym];
switch (tym)
{
case TYllong:
Expand Down Expand Up @@ -700,7 +686,7 @@ L1:
attribute |= 0x200;
tycv = 0;
d = debtyp_alloc(10);
TOWORD(d.data.ptr,0x1002);
TOWORD(d.data.ptr,LF_POINTER_V2);
TOLONG(d.data.ptr + 2,next);
// see https://github.com/Microsoft/microsoft-pdb/blob/master/include/cvinfo.h#L1514
// add size and pointer type (PTR_64 or PTR_NEAR32)
Expand Down Expand Up @@ -754,7 +740,7 @@ L1:
next = dttab4[TYuchar]; // use ubyte instead

d = debtyp_alloc(10 + u + 1);
TOWORD(d.data.ptr,0x1503);
TOWORD(d.data.ptr,LF_ARRAY_V3);
TOLONG(d.data.ptr + 2,next);
TOLONG(d.data.ptr + 6,idxtype);
d.data.ptr[10 + u] = 0; // no name
Expand All @@ -776,12 +762,9 @@ L1:
case TYjfunc:
case TYifunc:
{
param_t* p;
uint nparam;
idx_t paramidx;

call = cv4_callconv(t);
paramidx = cv4_arglist(t,&nparam);
ubyte call = cv4_callconv(t);
idx_t paramidx = cv4_arglist(t,&nparam);

// Construct an LF_PROCEDURE
d = debtyp_alloc(2 + 4 + 1 + 1 + 2 + 4);
Expand Down Expand Up @@ -866,7 +849,7 @@ L1:
modifier = (tycv & (mTYconst | mTYimmutable)) ? 1 : 0;
modifier |= (tycv & mTYvolatile) ? 2 : 0;
d = debtyp_alloc(8);
TOWORD(d.data.ptr,0x1001);
TOWORD(d.data.ptr,LF_MODIFIER_V2);
TOLONG(d.data.ptr + 2,typidx);
TOWORD(d.data.ptr + 6,modifier);
typidx = cv_debtyp(d);
Expand Down
67 changes: 61 additions & 6 deletions compiler/src/dmd/backend/cv4.d
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
/**
* CodeView 4 symbolic debug info declarations
* CodeView symbolic debug info declarations
*
* See "Microsoft Symbol and Type OMF" document
*
* See https://github.com/microsoft/microsoft-pdb/tree/master/include
* for a more complete set of publicly available definitions
*
* Compiler implementation of the
* $(LINK2 https://www.dlang.org, D programming language).
*
Expand All @@ -15,8 +18,6 @@ module dmd.backend.cv4;

// Online documentation: https://dlang.org/phobos/dmd_backend_cv4.html

enum OEM = 0x42; // Digital Mars OEM number (picked at random)

// Symbol Indices
enum
{
Expand Down Expand Up @@ -82,7 +83,7 @@ enum
S_FUNCINFO_V2 = 0x1012,
S_COMPILAND_V2 = 0x1013,

S_COMPILAND_V3 = 0x1101,
S_OBJNAME_V3 = 0x1101,
S_THUNK_V3 = 0x1102,
S_BLOCK_V3 = 0x1103,
S_LABEL_V3 = 0x1105,
Expand All @@ -103,8 +104,16 @@ enum
S_SUBSECTINFO_V3 = 0x1137,
S_ENTRYPOINT_V3 = 0x1138,
S_SECUCOOKIE_V3 = 0x113A,
S_MSTOOLINFO_V3 = 0x113C,
S_MSTOOLENV_V3 = 0x113D,

S_COMPILE3 = 0x113C, // compile flags, language and compiler version
S_ENVBLOCK = 0x113D, // build environment block
S_BUILDINFO = 0x114C, // reference to an LF_BUILDINFO record
S_FRAMEPROC = 0x1012, // extra frame and procedure information
S_REGREL32 = 0x1111, // register-relative address
S_LTHREAD32 = 0x1112, // thread-local static data (local)
S_GTHREAD32 = 0x1113, // thread-local static data (global)
S_LPROC32_ID = 0x1146, // local procedure (type field is an LF_FUNC_ID)
S_GPROC32_ID = 0x1147, // global procedure (type field is an LF_FUNC_ID)
}

// Leaf Indices
Expand Down Expand Up @@ -242,4 +251,50 @@ enum
LF_METHOD_V3 = 0x150F,
LF_NESTTYPE_V3 = 0x1510,
LF_ONEMETHOD_V3 = 0x1511,

// Type leaf records used by the ID stream
LF_FUNC_ID = 0x1601, // function id: function type + name
LF_STRING_ID = 0x1605, // interned string -> type index
LF_BUILDINFO = 0x1603, // cwd, tool, source, pdb, args
LF_UDT_SRC_LINE = 0x1606, // source file/line where a UDT is defined
}

// .debug$S subsection kinds
enum
{
DEBUG_S_SYMBOLS = 0xF1,
DEBUG_S_LINES = 0xF2,
DEBUG_S_STRINGTABLE = 0xF3,
DEBUG_S_FILECHKSMS = 0xF4,
}

// Source file checksum kinds
enum
{
CHKSUM_NONE = 0,
CHKSUM_MD5 = 1,
CHKSUM_SHA1 = 2,
CHKSUM_SHA256 = 3,
}

// S_FRAMEPROC flags
enum
{
CV_FRAME_HASALLOCA = 1 << 0, // function uses alloca()
CV_FRAME_HASINLASM = 1 << 3, // function has inline asm
CV_FRAME_HASEH = 1 << 4, // function has exception handling
CV_FRAME_SECURITY = 1 << 8, // function has a stack security cookie
CV_FRAME_OPTSPEED = 1 << 20, // function was optimized for speed
CV_FRAME_LOCALBP_RBP = 2 << 14, // locals addressed relative to RBP/EBP
CV_FRAME_PARAMBP_RBP = 2 << 16, // parameters addressed relative to RBP/EBP
}

// Mark a line-number entry as a statement (not an expression)
enum CV_LINE_STATEMENT = 0x80000000;

// CodeView register encodings for base-pointer-relative records
enum
{
CV_REG_EBP = 22, // x86 EBP
CV_AMD64_RBP = 334, // x64 RBP
}
103 changes: 1 addition & 102 deletions compiler/src/dmd/backend/cv8.d
Original file line number Diff line number Diff line change
Expand Up @@ -64,70 +64,6 @@ private bool symbol_iscomdat4(Symbol* s)
// 'fatal error LNK1318: Unexpected PDB error; RPC (23) '(0x000006BA)'
enum CV8_MAX_SYMBOL_LENGTH = 0xffd8;

// Modern CodeView symbol records not declared in cv4.d
enum
{
S_OBJNAME_V3 = 0x1101, // object file name (same value as S_COMPILAND_V3)
S_COMPILE3 = 0x113C, // compile flags, language and compiler version
S_ENVBLOCK = 0x113D, // build environment block
S_BUILDINFO = 0x114C, // reference to an LF_BUILDINFO record
S_FRAMEPROC = 0x1012, // extra frame and procedure information
S_REGREL32 = 0x1111, // register-relative address
S_LTHREAD32 = 0x1112, // thread-local static data (local)
S_GTHREAD32 = 0x1113, // thread-local static data (global)
S_LPROC32_ID = 0x1146, // local procedure (type field is an LF_FUNC_ID)
S_GPROC32_ID = 0x1147, // global procedure (type field is an LF_FUNC_ID)
}

// Type leaf records used by the ID stream
enum
{
LF_FUNC_ID = 0x1601, // function id: function type + name
LF_STRING_ID = 0x1605, // interned string -> type index
LF_BUILDINFO = 0x1603, // cwd, tool, source, pdb, args
LF_UDT_SRC_LINE = 0x1606, // source file/line where a UDT is defined
}

// .debug$S subsection kinds
enum
{
DEBUG_S_SYMBOLS = 0xF1,
DEBUG_S_LINES = 0xF2,
DEBUG_S_STRINGTABLE = 0xF3,
DEBUG_S_FILECHKSMS = 0xF4,
}

// Source file checksum kinds
enum
{
CHKSUM_NONE = 0,
CHKSUM_MD5 = 1,
CHKSUM_SHA1 = 2,
CHKSUM_SHA256 = 3,
}

// S_FRAMEPROC flags
enum
{
CV_FRAME_HASALLOCA = 1 << 0, // function uses alloca()
CV_FRAME_HASINLASM = 1 << 3, // function has inline asm
CV_FRAME_HASEH = 1 << 4, // function has exception handling
CV_FRAME_SECURITY = 1 << 8, // function has a stack security cookie
CV_FRAME_OPTSPEED = 1 << 20, // function was optimized for speed
CV_FRAME_LOCALBP_RBP = 2 << 14, // locals addressed relative to RBP/EBP
CV_FRAME_PARAMBP_RBP = 2 << 16, // parameters addressed relative to RBP/EBP
}

// Mark a line-number entry as a statement (not an expression)
enum CV_LINE_STATEMENT = 0x80000000;

// CodeView register encodings for base-pointer-relative records
enum
{
CV_REG_EBP = 22, // x86 EBP
CV_AMD64_RBP = 334, // x64 RBP
}

// The "F1" section, which is the symbols
private __gshared OutBuffer* F1_buf;

Expand Down Expand Up @@ -1059,18 +995,6 @@ idx_t cv8_darray(type* t, idx_t etypidx)
* }
*/

static if (0)
{
d = debtyp_alloc(18);
TOWORD(d.data.ptr, 0x100F);
TOWORD(d.data.ptr + 2, OEM);
TOWORD(d.data.ptr + 4, 1); // 1 = dynamic array
TOLONG(d.data.ptr + 6, 2); // count of type indices to follow
TOLONG(d.data.ptr + 10, 0x23); // index type, T_UQUAD
TOLONG(d.data.ptr + 14, next); // element type
return cv_debtyp(d);
}

type* tp = type_pointer(t.Tnext);
idx_t ptridx = cv4_typidx(tp);
type_free(tp);
Expand Down Expand Up @@ -1169,18 +1093,6 @@ idx_t cv8_ddelegate(type* t, idx_t functypidx)
idx_t ptridx = cv4_typidx(tp);
type_free(tp);

static if (0)
{
debtyp_t* d = debtyp_alloc(18);
TOWORD(d.data.ptr, 0x100F);
TOWORD(d.data.ptr + 2, OEM);
TOWORD(d.data.ptr + 4, 3); // 3 = delegate
TOLONG(d.data.ptr + 6, 2); // count of type indices to follow
TOLONG(d.data.ptr + 10, key); // void* type
TOLONG(d.data.ptr + 14, functypidx); // function type
}
else
{
__gshared const ubyte[38] fl =
[
0x03, 0x12, // LF_FIELDLIST_V2
Expand Down Expand Up @@ -1220,7 +1132,7 @@ else
TOWORD(d.data.ptr + 18, 2 * _tysize[TYnptr]); // size
memcpy(d.data.ptr + 20, id, idlen);
d.data.ptr[20 + idlen] = 0;
}

return cv_debtyp(d);
}

Expand All @@ -1243,18 +1155,6 @@ idx_t cv8_daarray(type* t, idx_t keyidx, idx_t validx)
* }
*/

static if (0)
{
debtyp_t* d = debtyp_alloc(18);
TOWORD(d.data.ptr, 0x100F);
TOWORD(d.data.ptr + 2, OEM);
TOWORD(d.data.ptr + 4, 2); // 2 = associative array
TOLONG(d.data.ptr + 6, 2); // count of type indices to follow
TOLONG(d.data.ptr + 10, keyidx); // key type
TOLONG(d.data.ptr + 14, validx); // element type
}
else
{
type* tv = type_fake(TYnptr);
tv.Tcount++;
idx_t pvidx = cv4_typidx(tv);
Expand Down Expand Up @@ -1304,7 +1204,6 @@ else
memcpy(d.data.ptr + 20, id, idlen);
d.data.ptr[20 + idlen] = 0;

}
return cv_debtyp(d);
}

Expand Down
8 changes: 2 additions & 6 deletions compiler/src/dmd/glue/tocvdebug.d
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ uint cv4_memfunctypidx(FuncDeclaration fd)

debtyp_t* d = debtyp_alloc(26);
ubyte* p = &d.data[0];
TOWORD(p,0x1009);
TOWORD(p,LF_MFUNCTION_V2);
TOLONG(p + 2,cv4_typidx(t.Tnext));
TOLONG(p + 6,cv4_typidx(Type_toCtype(ad.type)));
TOLONG(p + 10,thisidx);
Expand Down Expand Up @@ -302,11 +302,8 @@ struct CvFieldList
const uint fieldLenMax;
const uint fieldIndexLen;

const bool canSplitList;

this(uint fields, uint len) scope
{
canSplitList = true; // optlink bails out with LF_INDEX
fieldIndexLen = 2 + 2 + 4;
fieldLenMax = CV8_NAMELENMAX - fieldIndexLen;

Expand Down Expand Up @@ -363,8 +360,7 @@ struct CvFieldList
idx_t debtyp()
{
idx_t typidx;
auto numCreate = canSplitList ? fieldLists.length : 1;
for(auto i = numCreate; i > 0; --i)
for(auto i = fieldLists.length; i > 0; --i)
{
auto fld = &fieldLists[i - 1];
if (typidx)
Expand Down
Loading