763 changes: 0 additions & 763 deletions src/libomf.c

This file was deleted.

683 changes: 683 additions & 0 deletions src/libomf.d

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/posix.mak
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ SRC = win32.mak posix.mak osmodel.mak aggregate.h aliasthis.h arraytypes.h \
impcnvgen.c import.h init.h intrange.h json.h lexer.h lib.h macro.h \
mars.h module.h mtype.h nspace.h objc.h parse.h scanmscoff.c scanomf.c \
scope.h statement.h staticassert.h target.h template.h tokens.h utf.h \
version.h visitor.h $(DMD_SRCS)
version.h visitor.h libomf.d scanomf.d $(DMD_SRCS)

ROOT_SRC = $(addprefix $(ROOT)/,aav.h array.h file.h filename.h \
longdouble.h newdelete.c object.h outbuffer.h port.h rmem.h \
Expand All @@ -245,7 +245,7 @@ ROOT_SRC = $(addprefix $(ROOT)/,aav.h array.h file.h filename.h \
GLUE_SRC = glue.c msc.c s2ir.c todt.c e2ir.c tocsym.c \
toobj.c toctype.c tocvdebug.c toir.h toir.c \
libmscoff.c scanmscoff.c irstate.h irstate.c typinf.c iasm.c \
toelfdebug.c libomf.c scanomf.c libelf.c scanelf.c libmach.c scanmach.c \
toelfdebug.c libelf.c scanelf.c libmach.c scanmach.c \
tk.c eh.c gluestub.c objc_glue.c objc_glue_stubs.c

BACK_SRC = \
Expand Down
425 changes: 0 additions & 425 deletions src/scanomf.c

This file was deleted.

380 changes: 380 additions & 0 deletions src/scanomf.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,380 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt

module ddmd.scanomf;

import core.stdc.string, core.stdc.stdlib;
import ddmd.globals, ddmd.root.outbuffer, ddmd.arraytypes, ddmd.errors;

enum LOG = false;

/**************************
* Record types:
*/
enum RHEADR = 0x6E;
enum REGINT = 0x70;
enum REDATA = 0x72;
enum RIDATA = 0x74;
enum OVLDEF = 0x76;
enum ENDREC = 0x78;
enum BLKDEF = 0x7A;
enum BLKEND = 0x7C;
enum DEBSYM = 0x7E;
enum THEADR = 0x80;
enum LHEADR = 0x82;
enum PEDATA = 0x84;
enum PIDATA = 0x86;
enum COMENT = 0x88;
enum MODEND = 0x8A;
enum M386END = 0x8B;
/* 32 bit module end record */
enum EXTDEF = 0x8C;
enum TYPDEF = 0x8E;
enum PUBDEF = 0x90;
enum PUB386 = 0x91;
enum LOCSYM = 0x92;
enum LINNUM = 0x94;
enum LNAMES = 0x96;
enum SEGDEF = 0x98;
enum GRPDEF = 0x9A;
enum FIXUPP = 0x9C;
/*#define (none) 0x9E */
enum LEDATA = 0xA0;
enum LIDATA = 0xA2;
enum LIBHED = 0xA4;
enum LIBNAM = 0xA6;
enum LIBLOC = 0xA8;
enum LIBDIC = 0xAA;
enum COMDEF = 0xB0;
enum LEXTDEF = 0xB4;
enum LPUBDEF = 0xB6;
enum LCOMDEF = 0xB8;
enum CEXTDEF = 0xBC;
enum COMDAT = 0xC2;
enum LINSYM = 0xC4;
enum ALIAS = 0xC6;
enum LLNAMES = 0xCA;
enum LIBIDMAX = (512 - 0x25 - 3 - 4);

// max size that will fit in dictionary
extern (C++) void parseName(ubyte** pp, char* name)
{
ubyte* p = *pp;
uint len = *p++;
if (len == 0xFF && *p == 0) // if long name
{
len = p[1] & 0xFF;
len |= cast(uint)p[2] << 8;
p += 3;
assert(len <= LIBIDMAX);
}
memcpy(name, p, len);
name[len] = 0;
*pp = p + len;
}

extern (C++) static ushort parseIdx(ubyte** pp)
{
ubyte* p = *pp;
ubyte c = *p++;
ushort idx = (0x80 & c) ? ((0x7F & c) << 8) + *p++ : c;
*pp = p;
return idx;
}

// skip numeric field of a data type of a COMDEF record
extern (C++) static void skipNumericField(ubyte** pp)
{
ubyte* p = *pp;
ubyte c = *p++;
if (c == 0x81)
p += 2;
else if (c == 0x84)
p += 3;
else if (c == 0x88)
p += 4;
else
assert(c <= 0x80);
*pp = p;
}

// skip data type of a COMDEF record
extern (C++) static void skipDataType(ubyte** pp)
{
ubyte* p = *pp;
ubyte c = *p++;
if (c == 0x61)
{
// FAR data
skipNumericField(&p);
skipNumericField(&p);
}
else if (c == 0x62)
{
// NEAR data
skipNumericField(&p);
}
else
{
assert(1 <= c && c <= 0x5f); // Borland segment indices
}
*pp = p;
}

/*****************************************
* Reads an object module from base[0..buflen] and passes the names
* of any exported symbols to (*pAddSymbol)().
* Input:
* pctx context pointer, pass to *pAddSymbol
* pAddSymbol function to pass the names to
* base[0..buflen] contains contents of object module
* module_name name of the object module (used for error messages)
* loc location to use for error printing
*/
extern (C++) void scanOmfObjModule(void* pctx, void function(void* pctx, const(char)* name, int pickAny) pAddSymbol, void* base, size_t buflen, const(char)* module_name, Loc loc)
{
static if (LOG)
{
printf("scanMSCoffObjModule(%s)\n", module_name);
}
int easyomf;
ubyte result = 0;
char[LIBIDMAX + 1] name;
Strings names;
names.push(null); // don't use index 0
easyomf = 0; // assume not EASY-OMF
ubyte* pend = cast(ubyte*)base + buflen;
ubyte* pnext;
for (ubyte* p = cast(ubyte*)base; 1; p = pnext)
{
assert(p < pend);
ubyte recTyp = *p++;
ushort recLen = *cast(ushort*)p;
p += 2;
pnext = p + recLen;
recLen--; // forget the checksum
switch (recTyp)
{
case LNAMES:
case LLNAMES:
while (p + 1 < pnext)
{
parseName(&p, name.ptr);
names.push(strdup(name.ptr));
}
break;
case PUBDEF:
if (easyomf)
recTyp = PUB386; // convert to MS format
case PUB386:
if (!(parseIdx(&p) | parseIdx(&p)))
p += 2; // skip seg, grp, frame
while (p + 1 < pnext)
{
parseName(&p, name.ptr);
p += (recTyp == PUBDEF) ? 2 : 4; // skip offset
parseIdx(&p); // skip type index
(*pAddSymbol)(pctx, name.ptr, 0);
}
break;
case COMDAT:
if (easyomf)
recTyp = COMDAT + 1; // convert to MS format
case COMDAT + 1:
{
int pickAny = 0;
if (*p++ & 5) // if continuation or local comdat
break;
ubyte attr = *p++;
if (attr & 0xF0) // attr: if multiple instances allowed
pickAny = 1;
p++; // align
p += 2; // enum data offset
if (recTyp == COMDAT + 1)
p += 2; // enum data offset
parseIdx(&p); // type index
if ((attr & 0x0F) == 0) // if explicit allocation
{
parseIdx(&p); // base group
parseIdx(&p); // base segment
}
uint idx = parseIdx(&p); // public name index
if (idx == 0 || idx >= names.dim)
{
//debug(printf("[s] name idx=%d, uCntNames=%d\n", idx, uCntNames));
error(loc, "corrupt COMDAT");
return;
}
//printf("[s] name='%s'\n",name);
(*pAddSymbol)(pctx, names[idx], pickAny);
break;
}
case COMDEF:
{
while (p + 1 < pnext)
{
parseName(&p, name.ptr);
parseIdx(&p); // type index
skipDataType(&p); // data type
(*pAddSymbol)(pctx, name.ptr, 1);
}
break;
}
case ALIAS:
while (p + 1 < pnext)
{
parseName(&p, name.ptr);
(*pAddSymbol)(pctx, name.ptr, 0);
parseName(&p, name.ptr);
}
break;
case MODEND:
case M386END:
result = 1;
goto Ret;
case COMENT:
// Recognize Phar Lap EASY-OMF format
{
static __gshared ubyte* omfstr1 = [0x80, 0xAA, '8', '0', '3', '8', '6'];
if (recLen == (omfstr1).sizeof)
{
for (uint i = 0; i < (omfstr1).sizeof; i++)
if (*p++ != omfstr1[i])
goto L1;
easyomf = 1;
break;
L1:
}
}
// Recognize .IMPDEF Import Definition Records
{
static __gshared ubyte* omfstr2 = [0, 0xA0, 1];
if (recLen >= 7)
{
p++;
for (uint i = 1; i < (omfstr2).sizeof; i++)
if (*p++ != omfstr2[i])
goto L2;
p++; // skip OrdFlag field
parseName(&p, name.ptr);
(*pAddSymbol)(pctx, name.ptr, 0);
break;
L2:
}
}
break;
default:
// ignore
}
}
Ret:
for (size_t u = 1; u < names.dim; u++)
free(cast(void*)names[u]);
}

/*************************************************
* Scan a block of memory buf[0..buflen], pulling out each
* OMF object module in it and sending the info in it to (*pAddObjModule).
* Returns:
* true for corrupt OMF data
*/
extern (C++) bool scanOmfLib(void* pctx, void function(void* pctx, char* name, void* base, size_t length) pAddObjModule, void* buf, size_t buflen, uint pagesize)
{
/* Split up the buffer buf[0..buflen] into multiple object modules,
* each aligned on a pagesize boundary.
*/
bool first_module = true;
ubyte* base = null;
char[LIBIDMAX + 1] name;
ubyte* p = cast(ubyte*)buf;
ubyte* pend = p + buflen;
ubyte* pnext;
for (; p < pend; p = pnext) // for each OMF record
{
if (p + 3 >= pend)
return true; // corrupt
ubyte recTyp = *p;
ushort recLen = *cast(ushort*)(p + 1);
pnext = p + 3 + recLen;
if (pnext > pend)
return true; // corrupt
recLen--; // forget the checksum
switch (recTyp)
{
case LHEADR:
case THEADR:
if (!base)
{
base = p;
p += 3;
parseName(&p, name.ptr);
if (name[0] == 'C' && name[1] == 0) // old C compilers did this
base = pnext; // skip past THEADR
}
break;
case MODEND:
case M386END:
{
if (base)
{
(*pAddObjModule)(pctx, name.ptr, base, pnext - base);
base = null;
}
// Round up to next page
uint t = cast(uint)(pnext - cast(ubyte*)buf);
t = (t + pagesize - 1) & ~cast(uint)(pagesize - 1);
pnext = cast(ubyte*)buf + t;
break;
}
default:
// ignore
}
}
return (base !is null); // missing MODEND record
}

extern (C++) uint OMFObjSize(const(void)* base, uint length, const(char)* name)
{
ubyte c = *cast(const(ubyte)*)base;
if (c != THEADR && c != LHEADR)
{
size_t len = strlen(name);
assert(len <= LIBIDMAX);
length += len + 5;
}
return length;
}

extern (C++) void writeOMFObj(OutBuffer* buf, const(void)* base, uint length, const(char)* name)
{
ubyte c = *cast(const(ubyte)*)base;
if (c != THEADR && c != LHEADR)
{
size_t len = strlen(name);
assert(len <= LIBIDMAX);
ubyte[4 + LIBIDMAX + 1] header;
header[0] = THEADR;
header[1] = cast(ubyte)(2 + len);
header[2] = 0;
header[3] = cast(ubyte)len;
assert(len <= 0xFF - 2);
memcpy(4 + header.ptr, name, len);
// Compute and store record checksum
uint n = cast(uint)(len + 4);
ubyte checksum = 0;
ubyte* p = header.ptr;
while (n--)
{
checksum -= *p;
p++;
}
*p = checksum;
buf.write(header.ptr, len + 5);
}
buf.write(base, length);
}
8 changes: 3 additions & 5 deletions src/win32.mak
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,13 @@ DMD_SRCS=access.d aggregate.d aliasthis.d apply.d argtypes.d arrayop.d \
impcnvtab.d init.d inline.d intrange.d json.d lexer.d lib.d link.d \
mars.d mtype.d nogc.d nspace.d objc_stubs.d opover.d optimize.d parse.d \
sapply.d sideeffect.d statement.d staticassert.d target.d tokens.d \
traits.d utf.d visitor.d
traits.d utf.d visitor.d libomf.d scanomf.d

# Glue layer
GLUEOBJ=glue.obj msc.obj s2ir.obj todt.obj e2ir.obj tocsym.obj \
toobj.obj toctype.obj tocvdebug.obj toir.obj \
libmscoff.obj scanmscoff.obj irstate.obj typinf.obj \
libomf.obj scanomf.obj iasm.obj objc_glue_stubs.obj
iasm.obj objc_glue_stubs.obj

#GLUEOBJ=gluestub.obj

Expand Down Expand Up @@ -189,7 +189,7 @@ SRCS = win32.mak posix.mak osmodel.mak aggregate.h aliasthis.h arraytypes.h \
GLUESRC= glue.c msc.c s2ir.c todt.c e2ir.c tocsym.c \
toobj.c toctype.c tocvdebug.c toir.h toir.c \
libmscoff.c scanmscoff.c irstate.h irstate.c typinf.c iasm.c \
toelfdebug.c libomf.c scanomf.c libelf.c scanelf.c libmach.c scanmach.c \
toelfdebug.c libelf.c scanelf.c libmach.c scanmach.c \
tk.c eh.c gluestub.c objc_glue_stubs.c objc_glue.c

# D back end
Expand Down Expand Up @@ -657,7 +657,6 @@ intrange.obj : $(TOTALH) intrange.h intrange.c
json.obj : $(TOTALH) json.h json.c
lexer.obj : $(TOTALH) lexer.c
libmscoff.obj : $(TOTALH) lib.h libmscoff.c
libomf.obj : $(TOTALH) lib.h libomf.c
link.obj : $(TOTALH) link.c
macro.obj : $(TOTALH) macro.h macro.c
mangle.obj : $(TOTALH) dsymbol.h declaration.h mangle.c
Expand All @@ -668,7 +667,6 @@ opover.obj : $(TOTALH) expression.h opover.c
optimize.obj : $(TOTALH) expression.h optimize.c
parse.obj : $(TOTALH) attrib.h lexer.h parse.h parse.c
sapply.obj : $(TOTALH) sapply.c
scanomf.obj : $(TOTALH) lib.h scanomf.c
scope.obj : $(TOTALH) scope.h scope.c
sideeffect.obj : $(TOTALH) sideeffect.c
statement.obj : $(TOTALH) statement.h statement.c expression.h
Expand Down