Merge pull request #16522 from kinke/rm_omf

Get rid of obsolete OMF support

Signed-off-by: Nicholas Wilson <thewilsonator@users.noreply.github.com>
Merged-on-behalf-of: Nicholas Wilson <thewilsonator@users.noreply.github.com>
This commit is contained in:
The Dlang Bot 2024-05-25 21:45:16 +02:00 committed by GitHub
commit ff14dc9385
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
57 changed files with 114 additions and 2297 deletions

View file

@ -44,20 +44,6 @@ install_host_dmd() {
dmd --version
}
################################################################################
# Download dmc
################################################################################
install_host_dmc() {
if [ ! -f dm/README.TXT ]; then
download "https://downloads.dlang.org/other/dm857c.zip" dmc.zip
7z x dmc.zip > /dev/null
download "http://ftp.digitalmars.com/sppn.zip" sppn.zip
7z x -odm/bin sppn.zip > /dev/null
fi
dm/bin/dmc | head -n 1 || true
}
################################################################################
# Download Grep
################################################################################

View file

@ -71,15 +71,12 @@ if [[ "$HOST_DMD_VERSION" == "2.079.0" ]]; then
disable_debug_for_unittests=(ENABLE_DEBUG=0)
fi
# avoid the DMC runtime and its limitations for the compiler and {build,run}.d tools themselves
TOOL_MODEL="$MODEL"
cd "$DMD_DIR"
"$HOST_DC" -m$TOOL_MODEL compiler/src/build.d -ofgenerated/build.exe
generated/build.exe -j$N MODEL=$TOOL_MODEL HOST_DMD=$HOST_DC BUILD=debug "${disable_debug_for_unittests[@]}" unittest
generated/build.exe -j$N MODEL=$TOOL_MODEL HOST_DMD=$HOST_DC DFLAGS="-L-LARGEADDRESSAWARE" ENABLE_RELEASE=1 ENABLE_ASSERTS=1 dmd
"$HOST_DC" -m$MODEL compiler/src/build.d -ofgenerated/build.exe
generated/build.exe -j$N MODEL=$MODEL HOST_DMD=$HOST_DC BUILD=debug "${disable_debug_for_unittests[@]}" unittest
generated/build.exe -j$N MODEL=$MODEL HOST_DMD=$HOST_DC DFLAGS="-L-LARGEADDRESSAWARE" ENABLE_RELEASE=1 ENABLE_ASSERTS=1 dmd
DMD_BIN_PATH="$DMD_DIR/generated/windows/release/$TOOL_MODEL/dmd.exe"
DMD_BIN_PATH="$DMD_DIR/generated/windows/release/$MODEL/dmd.exe"
################################################################################
# Build Druntime and Phobos
@ -100,11 +97,11 @@ if [ "${DMD_TEST_COVERAGE:-0}" = "1" ] ; then
# Recompile debug dmd + unittests
rm -rf "$DMD_DIR/generated/windows"
../../generated/build.exe -j$N MODEL=$TOOL_MODEL DFLAGS="-L-LARGEADDRESSAWARE" ENABLE_DEBUG=1 ENABLE_COVERAGE=1 dmd
../../generated/build.exe -j$N MODEL=$TOOL_MODEL DFLAGS="-L-LARGEADDRESSAWARE" ENABLE_DEBUG=1 ENABLE_COVERAGE=1 unittest
../../generated/build.exe -j$N MODEL=$MODEL DFLAGS="-L-LARGEADDRESSAWARE" ENABLE_DEBUG=1 ENABLE_COVERAGE=1 dmd
../../generated/build.exe -j$N MODEL=$MODEL DFLAGS="-L-LARGEADDRESSAWARE" ENABLE_DEBUG=1 ENABLE_COVERAGE=1 unittest
fi
"$HOST_DC" -m$TOOL_MODEL -g -i run.d
"$HOST_DC" -m$MODEL -g -i run.d
targets=("all")
args=('ARGS=-O -inline -g') # no -release for faster builds

View file

@ -6,20 +6,8 @@ version=7.51 Build 020
[Environment]
DFLAGS="-I%@P%\..\..\src\phobos" "-I%@P%\..\..\src\druntime\import"
; optlink only reads from the Environment section so we need this redundancy
; from the Environment32omf section (bugzilla 11302)
LIB="%@P%\..\lib"
[Environment32]
LIB=%@P%\..\lib32mscoff
[Environment32omf]
LIB="%@P%\..\lib"
LINKCMD=%@P%\optlink.exe
[Environment64]
LIB=%@P%\..\lib64
; -----------------------------------------------------------------------------
[Environment32mscoff]
LIB=%@P%\..\lib32mscoff

View file

@ -1,8 +0,0 @@
LIBRARY dserver
EXETYPE NT
SUBSYSTEM WINDOWS
EXPORTS
DllGetClassObject = _DllGetClassObject@12
DllCanUnloadNow = _DllCanUnloadNow@0
DllRegisterServer = _DllRegisterServer@0
DllUnregisterServer = _DllUnregisterServer@0

View file

@ -3,7 +3,7 @@ DMD=..\..\windows\bin\dmd
DFLAGS=-m$(MODEL)
EXAMPLES = hello d2html dhry pi sieve wc wc2 \
winsamp dserver$(MODEL) mydll$(MODEL) htmlget listener
winsamp dserver mydll htmlget listener
all: $(EXAMPLES)
echo done
@ -50,22 +50,12 @@ winsamp:
# COM client/server example
# dclient will fail unless run with administrator rights
dserver32:
$(DMD) dserver.d chello.d $(DFLAGS) dserver.def advapi32.lib ole32.lib user32.lib
$(DMD) dclient $(DFLAGS) ole32.lib uuid.lib
.\dclient.exe
dserver64 dserver32mscoff:
dserver:
$(DMD) dserver.d chello.d $(DFLAGS) -L/DLL dserver64.def advapi32.lib ole32.lib user32.lib
$(DMD) dclient $(DFLAGS) ole32.lib uuid.lib
.\dclient.exe
mydll32:
$(DMD) $(DFLAGS) -ofmydll.dll -L/IMPLIB mydll\mydll.d mydll\dll.d mydll\mydll.def
$(DMD) $(DFLAGS) -ofdlltest.exe mydll\test.d mydll\mydll.di mydll.lib
.\dlltest.exe
mydll64 mydll32mscoff:
mydll:
$(DMD) $(DFLAGS) -ofmydll.dll mydll\mydll.d mydll\dll.d -L/DLL
$(DMD) $(DFLAGS) -ofdlltest.exe mydll\test.d mydll\mydll.di mydll.lib
.\dlltest.exe

View file

@ -299,9 +299,6 @@ DFLAGS=%DFLAGS% -L/OPT:NOICF
[Environment64]
DFLAGS=%DFLAGS% -L/OPT:NOICF
[Environment32mscoff]
DFLAGS=%DFLAGS% -L/OPT:NOICF
`;
}
else
@ -1562,8 +1559,8 @@ auto sourceFiles()
dmsc.d e2ir.d iasmdmd.d glue.d objc_glue.d
s2ir.d tocsym.d toctype.d tocvdebug.d todt.d toir.d toobj.d
"),
driver: fileArray(env["D"], "dinifile.d dmdparams.d gluelayer.d lib.d libelf.d libmach.d libmscoff.d libomf.d
link.d mars.d main.d scanelf.d scanmach.d scanmscoff.d scanomf.d vsoptions.d
driver: fileArray(env["D"], "dinifile.d dmdparams.d gluelayer.d lib.d libelf.d libmach.d libmscoff.d
link.d mars.d main.d scanelf.d scanmach.d scanmscoff.d vsoptions.d
"),
frontend: fileArray(env["D"], "
access.d aggregate.d aliasthis.d argtypes_x86.d argtypes_sysv_x64.d argtypes_aarch64.d arrayop.d

View file

@ -201,11 +201,9 @@ Note that these groups have no strict meaning, the category assignments are a bi
| [libelf.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/libelf.d) | Library in ELF format (Unix) |
| [libmach.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/libmach.d) | Library in Mach-O format (macOS) |
| [libmscoff.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/libmscoff.d) | Library in COFF format (32/64-bit Windows) |
| [libomf.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/libomf.d) | Library in OMF format (legacy 32-bit Windows) |
| [scanelf.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/scanelf.d) | Extract symbol names from a library in ELF format |
| [scanmach.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/scanmach.d) | Extract symbol names from a library in Mach-O format |
| [scanmscoff.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/scanmscoff.d) | Extract symbol names from a library in COFF format |
| [scanomf.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/scanomf.d) | Extract symbol names from a library in OMF format |
### Code generation / back-end interfacing

View file

@ -41,7 +41,7 @@ import dmd.visitor;
const(char)* toCppMangleMSVC(Dsymbol s)
{
scope VisualCPPMangler v = new VisualCPPMangler(false, s.loc, global.errorSink);
scope VisualCPPMangler v = new VisualCPPMangler(s.loc, global.errorSink);
auto p = v.mangleOf(s);
if (v.errors)
fatal(); // because this error should be handled in frontend
@ -54,21 +54,6 @@ const(char)* cppTypeInfoMangleMSVC(Dsymbol s) @safe
assert(0);
}
const(char)* toCppMangleDMC(Dsymbol s)
{
scope VisualCPPMangler v = new VisualCPPMangler(true, s.loc, global.errorSink);
auto p = v.mangleOf(s);
if (v.errors)
fatal(); // because this error should be handled in frontend
return p;
}
const(char)* cppTypeInfoMangleDMC(Dsymbol s) @safe
{
//printf("cppTypeInfoMangle(%s)\n", s.toChars());
assert(0);
}
private extern (C++) final class VisualCPPMangler : Visitor
{
alias visit = Visitor.visit;
@ -85,7 +70,6 @@ private extern (C++) final class VisualCPPMangler : Visitor
bool ignoreConst; /// in some cases we should ignore CV-modifiers.
bool escape; /// toplevel const non-pointer types need a '$$C' escape in addition to a cv qualifier.
bool mangleReturnType; /// return type shouldn't be saved and substituted in arguments
bool isDmc; /// Digital Mars C++ name mangling
bool errors; /// errors occurred
OutBuffer buf;
@ -94,16 +78,14 @@ private extern (C++) final class VisualCPPMangler : Visitor
{
saved_idents[] = rvl.saved_idents[];
saved_types[] = rvl.saved_types[];
isDmc = rvl.isDmc;
loc = rvl.loc;
}
public:
extern (D) this(bool isDmc, Loc loc, ErrorSink eSink) scope @safe
extern (D) this(Loc loc, ErrorSink eSink) scope @safe
{
saved_idents[] = null;
saved_types[] = null;
this.isDmc = isDmc;
this.loc = loc;
this.eSink = eSink;
}
@ -147,7 +129,7 @@ public:
if (checkImmutableShared(type, loc))
return;
if (type.isConst() && (isNotTopType || isDmc))
if (type.isConst() && isNotTopType)
{
if (checkTypeSaved(type))
return;
@ -156,23 +138,20 @@ public:
{
return;
}
if (!isDmc)
switch (type.ty)
{
switch (type.ty)
{
case Tint64:
case Tuns64:
case Tint128:
case Tuns128:
case Tfloat80:
case Twchar:
if (checkTypeSaved(type))
return;
break;
case Tint64:
case Tuns64:
case Tint128:
case Tuns128:
case Tfloat80:
case Twchar:
if (checkTypeSaved(type))
return;
break;
default:
break;
}
default:
break;
}
mangleModifier(type);
switch (type.ty)
@ -217,10 +196,7 @@ public:
buf.writeByte('N');
break;
case Tfloat80:
if (isDmc)
buf.writestring("_Z"); // DigitalMars long double
else
buf.writestring("_T"); // Intel long double
buf.writestring("_T"); // Intel long double
break;
case Tbool:
buf.writestring("_N");
@ -260,10 +236,7 @@ public:
if (checkTypeSaved(type))
return;
// first dimension always mangled as const pointer
if (isDmc)
buf.writeByte('Q');
else
buf.writeByte('P');
buf.writeByte('P');
isNotTopType = true;
assert(type.next);
if (type.next.ty == Tsarray)
@ -309,10 +282,7 @@ public:
if (checkTypeSaved(type))
return;
mangleModifier(type);
if (type.isConst() || !isDmc)
buf.writeByte('Q'); // const
else
buf.writeByte('P'); // mutable
buf.writeByte('Q'); // const
if (target.isLP64)
buf.writeByte('E');
isNotTopType = true;
@ -366,15 +336,7 @@ public:
override void visit(TypeFunction type)
{
const(char)* arg = mangleFunctionType(type);
if (isDmc)
{
if (checkTypeSaved(type))
return;
}
else
{
buf.writestring("$$A6");
}
buf.writestring("$$A6");
buf.writestring(arg);
isNotTopType = false;
ignoreConst = false;
@ -414,16 +376,14 @@ public:
else if (id == Id.__c_char)
c = "D"; // VC++ char
else if (id == Id.__c_wchar_t)
{
c = isDmc ? "_Y" : "_W";
}
c = "_W";
if (c.length)
{
if (checkImmutableShared(type, loc))
return;
if (type.isConst() && (isNotTopType || isDmc))
if (type.isConst() && isNotTopType)
{
if (checkTypeSaved(type))
return;
@ -582,9 +542,8 @@ extern(D):
* Params:
* o = expression that represents the value
* tv = template value
* is_dmc_template = use DMC mangling
*/
void mangleTemplateValue(RootObject o, TemplateValueParameter tv, Dsymbol sym, bool is_dmc_template)
void mangleTemplateValue(RootObject o, TemplateValueParameter tv, Dsymbol sym)
{
if (!tv.valType.isintegral())
{
@ -600,12 +559,6 @@ extern(D):
{
mangleNumber(buf, e.toUInteger());
}
else if (is_dmc_template)
{
// NOTE: DMC mangles everything based on
// unsigned int
mangleNumber(buf, e.toInteger());
}
else
{
sinteger_t val = e.toInteger();
@ -638,40 +591,30 @@ extern(D):
else if (e && e.op == EXP.variable && (cast(VarExp)e).var.isVarDeclaration())
{
buf.writeByte('$');
if (isDmc)
buf.writeByte('1');
else
buf.writeByte('E');
buf.writeByte('E');
mangleVariable((cast(VarExp)e).var.isVarDeclaration());
}
else if (d && d.isTemplateDeclaration() && d.isTemplateDeclaration().onemember)
{
Dsymbol ds = d.isTemplateDeclaration().onemember;
if (isDmc)
if (ds.isUnionDeclaration())
{
buf.writeByte('T');
}
else if (ds.isStructDeclaration())
{
buf.writeByte('U');
}
else if (ds.isClassDeclaration())
{
buf.writeByte('V');
}
else
{
if (ds.isUnionDeclaration())
{
buf.writeByte('T');
}
else if (ds.isStructDeclaration())
{
buf.writeByte('U');
}
else if (ds.isClassDeclaration())
{
buf.writeByte('V');
}
else
{
eSink.error(sym.loc, "%s `%s` internal compiler error: C++ templates support only integral value, type parameters, alias templates and alias function parameters",
sym.kind, sym.toPrettyChars);
errors = true;
return;
}
eSink.error(sym.loc, "%s `%s` internal compiler error: C++ templates support only integral value, type parameters, alias templates and alias function parameters",
sym.kind, sym.toPrettyChars);
errors = true;
return;
}
mangleIdent(d);
}
@ -707,7 +650,6 @@ extern(D):
void mangleName(Dsymbol sym, bool dont_use_back_reference)
{
//printf("mangleName('%s')\n", sym.toChars());
bool is_dmc_template = false;
if (string s = mangleSpecialName(sym))
{
@ -718,7 +660,7 @@ extern(D):
void writeName(Identifier name)
{
assert(name);
if (!is_dmc_template && dont_use_back_reference)
if (dont_use_back_reference)
saveIdent(name);
else if (checkAndSaveIdent(name))
return;
@ -780,18 +722,13 @@ extern(D):
}
}
scope VisualCPPMangler tmp = new VisualCPPMangler(isDmc ? true : false, loc, eSink);
scope VisualCPPMangler tmp = new VisualCPPMangler(loc, eSink);
tmp.buf.writeByte('?');
tmp.buf.writeByte('$');
tmp.buf.writestring(symName);
tmp.saved_idents[0] = id;
if (symName == id.toString())
tmp.buf.writeByte('@');
if (isDmc)
{
tmp.mangleIdent(sym.parent, true);
is_dmc_template = true;
}
bool is_var_arg = false;
for (size_t i = firstTemplateArg; i < actualti.tiargs.length; i++)
{
@ -814,7 +751,7 @@ extern(D):
}
if (tv)
{
tmp.mangleTemplateValue(o, tv, actualti, is_dmc_template);
tmp.mangleTemplateValue(o, tv, actualti);
}
else if (!tp || tp.isTemplateTypeParameter())
{
@ -979,8 +916,6 @@ extern(D):
buf.writestring("$$CB");
else if (isNotTopType)
buf.writeByte('B'); // const
else if (isDmc && type.ty != Tpointer)
buf.writestring("_O");
}
else if (isNotTopType)
buf.writeByte('A'); // mutable

View file

@ -122,10 +122,6 @@ private const(char)[] cppCommand()
auto path = vsopt.compilerPath(target.isX86_64);
return toDString(path);
}
if (target.objectFormat() == Target.ObjectFormat.omf)
{
return "sppn.exe";
}
// Perhaps we are cross-compiling.
return "cpp";
}

View file

@ -323,7 +323,6 @@ void setTargetBuildDefaults(ref Target target)
target.os = defaultTargetOS();
target.osMajor = defaultTargetOSMajor();
target.cpu = CPU.baseline;
target.omfobj = false;
target.isX86_64 = (size_t.sizeof == 8);
}

View file

@ -766,7 +766,7 @@ extern (C++) final class Module : Package
{
filetype = FileType.c;
global.compileEnv.masm = target.os == Target.OS.Windows && !target.omfobj; // Microsoft inline assembler format
global.compileEnv.masm = target.os == Target.OS.Windows; // Microsoft inline assembler format
scope p = new CParser!AST(this, buf, cast(bool) docfile, global.errorSink, target.c, &defines, &global.compileEnv);
global.compileEnv.masm = false;
p.nextToken();

View file

@ -320,11 +320,6 @@ extern (C++) class StructDeclaration : AggregateDeclaration
*/
structsize = 4;
}
else if (target.c.bitFieldStyle == TargetC.BitFieldStyle.DM)
{
structsize = 0;
alignsize = 0;
}
else
structsize = 0;
break;

View file

@ -7259,25 +7259,6 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
return;
}
}
else if (style == TargetC.BitFieldStyle.DM)
{
if (anon && bfd.fieldWidth && (!fieldState.inFlight || fieldState.bitOffset == 0))
return; // this probably should be a bug in DMC
if (ad.alignsize == 0)
ad.alignsize = 1;
if (bfd.fieldWidth == 0)
{
if (fieldState.inFlight && !isunion)
{
const alsz = memsize;
fieldState.offset = (fieldState.offset + alsz - 1) & ~(alsz - 1);
ad.structsize = fieldState.offset;
}
fieldState.inFlight = false;
return;
}
}
if (!fieldState.inFlight)
{
@ -7307,8 +7288,7 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
}
}
}
else if (style == TargetC.BitFieldStyle.DM ||
style == TargetC.BitFieldStyle.MS)
else if (style == TargetC.BitFieldStyle.MS)
{
if (memsize != fieldState.fieldSize ||
fieldState.bitOffset + bfd.fieldWidth > fieldState.fieldSize * 8)

View file

@ -5968,9 +5968,8 @@ struct TargetC final
enum class BitFieldStyle : uint8_t
{
Unspecified = 0u,
DM = 1u,
MS = 2u,
Gcc_Clang = 3u,
MS = 1u,
Gcc_Clang = 2u,
};
bool crtDestructorsSupported;
@ -7551,7 +7550,6 @@ struct Target final
_d_dynamicArray< const char > lib_ext;
_d_dynamicArray< const char > dll_ext;
bool run_noext;
bool omfobj;
template <typename T>
struct FPTypeProperties final
{
@ -7623,7 +7621,6 @@ public:
lib_ext(),
dll_ext(),
run_noext(),
omfobj(),
FloatProperties(),
DoubleProperties(),
RealProperties(),
@ -7631,7 +7628,7 @@ public:
params()
{
}
Target(OS os, uint8_t osMajor = 0u, uint8_t ptrsize = 0u, uint8_t realsize = 0u, uint8_t realpad = 0u, uint8_t realalignsize = 0u, uint8_t classinfosize = 0u, uint64_t maxStaticDataSize = 0LLU, TargetC c = TargetC(), TargetCPP cpp = TargetCPP(), TargetObjC objc = TargetObjC(), _d_dynamicArray< const char > architectureName = {}, CPU cpu = (CPU)0u, bool isX86_64 = false, bool isLP64 = false, _d_dynamicArray< const char > obj_ext = {}, _d_dynamicArray< const char > lib_ext = {}, _d_dynamicArray< const char > dll_ext = {}, bool run_noext = false, bool omfobj = false, FPTypeProperties<float > FloatProperties = FPTypeProperties<float >(), FPTypeProperties<double > DoubleProperties = FPTypeProperties<double >(), FPTypeProperties<_d_real > RealProperties = FPTypeProperties<_d_real >(), Type* tvalist = nullptr, const Param* params = nullptr) :
Target(OS os, uint8_t osMajor = 0u, uint8_t ptrsize = 0u, uint8_t realsize = 0u, uint8_t realpad = 0u, uint8_t realalignsize = 0u, uint8_t classinfosize = 0u, uint64_t maxStaticDataSize = 0LLU, TargetC c = TargetC(), TargetCPP cpp = TargetCPP(), TargetObjC objc = TargetObjC(), _d_dynamicArray< const char > architectureName = {}, CPU cpu = (CPU)0u, bool isX86_64 = false, bool isLP64 = false, _d_dynamicArray< const char > obj_ext = {}, _d_dynamicArray< const char > lib_ext = {}, _d_dynamicArray< const char > dll_ext = {}, bool run_noext = false, FPTypeProperties<float > FloatProperties = FPTypeProperties<float >(), FPTypeProperties<double > DoubleProperties = FPTypeProperties<double >(), FPTypeProperties<_d_real > RealProperties = FPTypeProperties<_d_real >(), Type* tvalist = nullptr, const Param* params = nullptr) :
os(os),
osMajor(osMajor),
ptrsize(ptrsize),
@ -7651,7 +7648,6 @@ public:
lib_ext(lib_ext),
dll_ext(dll_ext),
run_noext(run_noext),
omfobj(omfobj),
FloatProperties(FloatProperties),
DoubleProperties(DoubleProperties),
RealProperties(RealProperties),

View file

@ -389,16 +389,7 @@ private void obj_start(ref OutBuffer objbuf, const(char)* srcfile)
version (Windows)
{
import dmd.backend.mscoffobj;
import dmd.backend.cgobj;
// Produce Ms COFF files by default, OMF for -m32omf
assert(objbuf.length() == 0);
switch (target.objectFormat())
{
case Target.ObjectFormat.coff: objmod = MsCoffObj_init(&objbuf, srcfile, null); break;
case Target.ObjectFormat.omf: objmod = OmfObj_init(&objbuf, srcfile, null); break;
default: assert(0);
}
objmod = MsCoffObj_init(&objbuf, srcfile, null);
}
else
{
@ -1388,9 +1379,6 @@ private bool entryPointFunctions(Obj objmod, FuncDeclaration fd)
case Target.ObjectFormat.coff:
objmod.external_def("main");
break;
case Target.ObjectFormat.omf:
objmod.external_def("_main");
break;
}
if (const libname = finalDefaultlibname())
obj_includelib(libname);
@ -1400,16 +1388,7 @@ private bool entryPointFunctions(Obj objmod, FuncDeclaration fd)
// D runtime library
if (fd.isRtInit())
{
final switch (target.objectFormat())
{
case Target.ObjectFormat.elf:
case Target.ObjectFormat.macho:
case Target.ObjectFormat.coff:
objmod.ehsections(); // initialize exception handling sections
break;
case Target.ObjectFormat.omf:
break;
}
objmod.ehsections(); // initialize exception handling sections
return true;
}
@ -1424,11 +1403,6 @@ private bool entryPointFunctions(Obj objmod, FuncDeclaration fd)
objmod.includelib("OLDNAMES");
break;
case Target.ObjectFormat.omf:
objmod.external_def("__acrtused_con"); // bring in C console startup code
objmod.includelib("snn.lib"); // bring in C runtime library
break;
default:
break;
}
@ -1440,23 +1414,10 @@ private bool entryPointFunctions(Obj objmod, FuncDeclaration fd)
(fd.isWinMain() || fd.isDllMain()) &&
onlyOneMain(fd))
{
switch (target.objectFormat())
{
case Target.ObjectFormat.coff:
objmod.includelib("uuid");
if (driverParams.mscrtlib.length && driverParams.mscrtlib[0])
obj_includelib(driverParams.mscrtlib);
objmod.includelib("OLDNAMES");
break;
case Target.ObjectFormat.omf:
objmod.external_def(fd.isWinMain() ? "__acrtused" : "__acrtused_dll");
break;
default:
assert(0);
}
objmod.includelib("uuid");
if (driverParams.mscrtlib.length && driverParams.mscrtlib[0])
obj_includelib(driverParams.mscrtlib);
objmod.includelib("OLDNAMES");
if (const libname = finalDefaultlibname())
obj_includelib(libname);
return true;

View file

@ -22,7 +22,6 @@ import dmd.target : Target;
import dmd.libelf;
import dmd.libmach;
import dmd.libmscoff;
import dmd.libomf;
private enum LOG = false;
@ -39,7 +38,6 @@ class Library
case Target.ObjectFormat.elf: lib = LibElf_factory(); break;
case Target.ObjectFormat.macho: lib = LibMach_factory(); break;
case Target.ObjectFormat.coff: lib = LibMSCoff_factory(); break;
case Target.ObjectFormat.omf: lib = LibOMF_factory(); break;
}
lib.lib_ext = lib_ext;
lib.eSink = eSink;

View file

@ -1,596 +0,0 @@
/**
* A library in the OMF format, a legacy format for 32-bit Windows.
*
* Copyright: Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved
* Authors: $(LINK2 https://www.digitalmars.com, Walter Bright)
* License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/libomf.d, _libomf.d)
* Documentation: https://dlang.org/phobos/dmd_libomf.html
* Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/libomf.d
*/
module dmd.libomf;
import core.stdc.stdio;
import core.stdc.string;
import core.stdc.stdlib;
import core.bitop;
import dmd.errors : fatal;
import dmd.utils;
import dmd.lib;
import dmd.location;
import dmd.root.array;
import dmd.root.file;
import dmd.root.filename;
import dmd.root.rmem;
import dmd.common.outbuffer;
import dmd.root.string;
import dmd.root.stringtable;
import dmd.scanomf;
// Entry point (only public symbol in this module).
Library LibOMF_factory()
{
return new LibOMF();
}
private: // for the remainder of this module
nothrow:
enum LOG = false;
struct OmfObjSymbol
{
char* name;
OmfObjModule* om;
/// Predicate for `Array.sort`for name comparison
static int name_pred (scope const OmfObjSymbol** ppe1, scope const OmfObjSymbol** ppe2) nothrow @nogc pure
{
return strcmp((**ppe1).name, (**ppe2).name);
}
}
alias OmfObjModules = Array!(OmfObjModule*);
alias OmfObjSymbols = Array!(OmfObjSymbol*);
final class LibOMF : Library
{
OmfObjModules objmodules; // OmfObjModule[]
OmfObjSymbols objsymbols; // OmfObjSymbol[]
StringTable!(OmfObjSymbol*) tab;
extern (D) this()
{
tab._init(14_000);
}
/***************************************
* Add object module or library to the library.
* Examine the buffer to see which it is.
* If the buffer is NULL, use module_name as the file name
* and load the file.
*/
override void addObject(const(char)[] module_name, const(ubyte)[] buffer)
{
static if (LOG)
{
printf("LibOMF::addObject(%.*s)\n", cast(int)module_name.length,
module_name.ptr);
}
void corrupt(int reason)
{
eSink.error(loc, "corrupt OMF object module %.*s %d",
cast(int)module_name.length, module_name.ptr, reason);
}
if (!buffer.length)
{
assert(module_name.length, "No module nor buffer provided to `addObject`");
// read file and take buffer ownership
OutBuffer b;
if (readFile(Loc.initial, module_name, b))
fatal();
buffer = cast(ubyte[])b.extractSlice();
}
uint g_page_size;
ubyte* pstart = cast(ubyte*)buffer.ptr;
bool islibrary = false;
/* See if it's an OMF library.
* Don't go by file extension.
*/
struct LibHeader
{
align(1):
ubyte recTyp; // 0xF0
ushort pagesize;
uint lSymSeek;
ushort ndicpages;
}
/* Determine if it is an OMF library, an OMF object module,
* or something else.
*/
if (buffer.length < (LibHeader).sizeof)
return corrupt(__LINE__);
const lh = cast(const(LibHeader)*)buffer.ptr;
if (lh.recTyp == 0xF0)
{
/* OMF library
* The modules are all at buffer.ptr[g_page_size .. lh.lSymSeek]
*/
islibrary = 1;
g_page_size = lh.pagesize + 3;
if (lh.lSymSeek > buffer.length || g_page_size > buffer.length)
return corrupt(__LINE__);
buffer = (cast(ubyte*)pstart)[g_page_size .. lh.lSymSeek];
}
else if (lh.recTyp == '!' && memcmp(lh, "!<arch>\n".ptr, 8) == 0)
{
eSink.error(loc, "COFF libraries not supported");
return;
}
else
{
// Not a library, assume OMF object module
g_page_size = 16;
}
bool firstmodule = true;
void addOmfObjModule(char* name, void* base, size_t length)
{
auto om = new OmfObjModule();
om.base = cast(ubyte*)base;
om.page = cast(ushort)((om.base - pstart) / g_page_size);
om.length = cast(uint)length;
/* Determine the name of the module
*/
const(char)[] n;
if (firstmodule && module_name && !islibrary)
{
// Remove path and extension
n = FileName.sansExt(FileName.name(module_name));
}
else
{
/* Use THEADR name as module name,
* removing path and extension.
*/
n = FileName.sansExt(FileName.name(name.toDString()));
}
om.name = toCString(n)[0 .. n.length];
firstmodule = false;
this.objmodules.push(om);
}
if (scanOmfLib(&addOmfObjModule, cast(void*)buffer.ptr, buffer.length, g_page_size))
return corrupt(__LINE__);
}
/*****************************************************************************/
void addSymbol(OmfObjModule* om, const(char)[] name, int pickAny = 0) nothrow
{
assert(name.length == strlen(name.ptr));
static if (LOG)
{
printf("LibOMF::addSymbol(%.*s, %.*s, %d)\n",
cast(int)om.name.length, om.name.ptr,
cast(int)name.length, name.ptr, pickAny);
}
if (auto s = tab.insert(name, null))
{
auto os = new OmfObjSymbol();
os.name = cast(char*)Mem.check(strdup(name.ptr));
os.om = om;
s.value = os;
objsymbols.push(os);
}
else
{
// already in table
if (!pickAny)
{
const s2 = tab.lookup(name);
assert(s2);
const os = s2.value;
eSink.error(loc, "multiple definition of %.*s: %.*s and %.*s: %s",
cast(int)om.name.length, om.name.ptr,
cast(int)name.length, name.ptr,
cast(int)os.om.name.length, os.om.name.ptr, os.name);
}
}
}
private:
/************************************
* Scan single object module for dictionary symbols.
* Send those symbols to LibOMF::addSymbol().
*/
void scanObjModule(OmfObjModule* om)
{
static if (LOG)
{
printf("LibMSCoff::scanObjModule(%s)\n", om.name.ptr);
}
extern (D) void addSymbol(const(char)[] name, int pickAny) nothrow
{
this.addSymbol(om, name, pickAny);
}
scanOmfObjModule(&addSymbol, om.base[0 .. om.length], om.name.ptr, loc, eSink);
}
/***********************************
* Calculates number of pages needed for dictionary
* Returns:
* number of pages
*/
ushort numDictPages(uint padding)
{
ushort ndicpages;
ushort bucksForHash;
ushort bucksForSize;
uint symSize = 0;
foreach (s; objsymbols)
{
symSize += (strlen(s.name) + 4) & ~1;
}
foreach (om; objmodules)
{
size_t len = om.name.length;
if (len > 0xFF)
len += 2; // Digital Mars long name extension
symSize += (len + 4 + 1) & ~1;
}
bucksForHash = cast(ushort)((objsymbols.length + objmodules.length + HASHMOD - 3) / (HASHMOD - 2));
bucksForSize = cast(ushort)((symSize + BUCKETSIZE - padding - padding - 1) / (BUCKETSIZE - padding));
ndicpages = (bucksForHash > bucksForSize) ? bucksForHash : bucksForSize;
//printf("ndicpages = %u\n",ndicpages);
// Find prime number greater than ndicpages
__gshared uint* primes =
[
1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103,
107, 109, 113, 127, 131, 137, 139, 149, 151, 157,
163, 167, 173, 179, 181, 191, 193, 197, 199, 211,
223, 227, 229, 233, 239, 241, 251, 257, 263, 269,
271, 277, 281, 283, 293, 307, 311, 313, 317, 331,
337, 347, 349, 353, 359, 367, 373, 379, 383, 389,
397, 401, 409, 419, 421, 431, 433, 439, 443, 449,
457, 461, 463, 467, 479, 487, 491, 499, 503, 509,
//521,523,541,547,
0
];
for (size_t i = 0; 1; i++)
{
if (primes[i] == 0)
{
// Quick and easy way is out.
// Now try and find first prime number > ndicpages
uint prime;
for (prime = (ndicpages + 1) | 1; 1; prime += 2)
{
// Determine if prime is prime
for (uint u = 3; u < prime / 2; u += 2)
{
if ((prime / u) * u == prime)
goto L1;
}
break;
L1:
}
ndicpages = cast(ushort)prime;
break;
}
if (primes[i] > ndicpages)
{
ndicpages = cast(ushort)primes[i];
break;
}
}
return ndicpages;
}
/*******************************************
* Write the module and symbol names to the dictionary.
* Returns:
* false failure
*/
bool FillDict(ubyte* bucketsP, ushort ndicpages)
{
// max size that will fit in dictionary
enum LIBIDMAX = (512 - 0x25 - 3 - 4);
ubyte[4 + LIBIDMAX + 2 + 1] entry;
//printf("FillDict()\n");
// Add each of the module names
foreach (om; objmodules)
{
ushort n = cast(ushort)om.name.length;
if (n > 255)
{
entry[0] = 0xFF;
entry[1] = 0;
*cast(ushort*)(entry.ptr + 2) = cast(ushort)(n + 1);
memcpy(entry.ptr + 4, om.name.ptr, n);
n += 3;
}
else
{
entry[0] = cast(ubyte)(1 + n);
memcpy(entry.ptr + 1, om.name.ptr, n);
}
entry[n + 1] = '!';
*(cast(ushort*)(n + 2 + entry.ptr)) = om.page;
if (n & 1)
entry[n + 2 + 2] = 0;
if (!EnterDict(bucketsP, ndicpages, entry.ptr, n + 1))
return false;
}
// Sort the symbols
objsymbols.sort!(OmfObjSymbol.name_pred);
// Add each of the symbols
foreach (os; objsymbols)
{
ushort n = cast(ushort)strlen(os.name);
if (n > 255)
{
entry[0] = 0xFF;
entry[1] = 0;
*cast(ushort*)(entry.ptr + 2) = n;
memcpy(entry.ptr + 4, os.name, n);
n += 3;
}
else
{
entry[0] = cast(ubyte)n;
memcpy(entry.ptr + 1, os.name, n);
}
*(cast(ushort*)(n + 1 + entry.ptr)) = os.om.page;
if ((n & 1) == 0)
entry[n + 3] = 0;
if (!EnterDict(bucketsP, ndicpages, entry.ptr, n))
{
return false;
}
}
return true;
}
/**********************************************
* Create and write library to libbuf.
* The library consists of:
* library header
* object modules...
* dictionary header
* dictionary pages...
*/
protected override void writeLibToBuffer(ref OutBuffer libbuf)
{
/* Scan each of the object modules for symbols
* to go into the dictionary
*/
foreach (om; objmodules)
{
scanObjModule(om);
}
uint g_page_size = 16;
/* Calculate page size so that the number of pages
* fits in 16 bits. This is because object modules
* are indexed by page number, stored as an unsigned short.
*/
while (1)
{
Lagain:
static if (LOG)
{
printf("g_page_size = %d\n", g_page_size);
}
uint offset = g_page_size;
foreach (om; objmodules)
{
uint page = offset / g_page_size;
if (page > 0xFFFF)
{
// Page size is too small, double it and try again
g_page_size *= 2;
goto Lagain;
}
offset += OMFObjSize(om.base, om.length, om.name.ptr);
// Round the size of the file up to the next page size
// by filling with 0s
uint n = (g_page_size - 1) & offset;
if (n)
offset += g_page_size - n;
}
break;
}
/* Leave one page of 0s at start as a dummy library header.
* Fill it in later with the real data.
*/
libbuf.fill0(g_page_size);
/* Write each object module into the library
*/
foreach (om; objmodules)
{
uint page = cast(uint)(libbuf.length / g_page_size);
assert(page <= 0xFFFF);
om.page = cast(ushort)page;
// Write out the object module om
writeOMFObj(libbuf, om.base, om.length, om.name.ptr);
// Round the size of the file up to the next page size
// by filling with 0s
uint n = (g_page_size - 1) & libbuf.length;
if (n)
libbuf.fill0(g_page_size - n);
}
// File offset of start of dictionary
uint offset = cast(uint)libbuf.length;
// Write dictionary header, then round it to a BUCKETPAGE boundary
ushort size = (BUCKETPAGE - (cast(short)offset + 3)) & (BUCKETPAGE - 1);
libbuf.writeByte(0xF1);
libbuf.writeword(size);
libbuf.fill0(size);
// Create dictionary
ubyte* bucketsP = null;
ushort ndicpages;
ushort padding = 32;
for (;;)
{
ndicpages = numDictPages(padding);
static if (LOG)
{
printf("ndicpages = %d\n", ndicpages);
}
// Allocate dictionary
if (bucketsP)
bucketsP = cast(ubyte*)Mem.check(realloc(bucketsP, ndicpages * BUCKETPAGE));
else
bucketsP = cast(ubyte*)Mem.check(malloc(ndicpages * BUCKETPAGE));
memset(bucketsP, 0, ndicpages * BUCKETPAGE);
for (uint u = 0; u < ndicpages; u++)
{
// 'next available' slot
bucketsP[u * BUCKETPAGE + HASHMOD] = (HASHMOD + 1) >> 1;
}
if (FillDict(bucketsP, ndicpages))
break;
padding += 16; // try again with more margins
}
// Write dictionary
libbuf.write(bucketsP[0 .. ndicpages * BUCKETPAGE]);
if (bucketsP)
free(bucketsP);
// Create library header
struct Libheader
{
align(1):
ubyte recTyp;
ushort recLen;
uint trailerPosn;
ushort ndicpages;
ubyte flags;
uint filler;
}
Libheader libHeader;
memset(&libHeader, 0, (Libheader).sizeof);
libHeader.recTyp = 0xF0;
libHeader.recLen = 0x0D;
libHeader.trailerPosn = offset + (3 + size);
libHeader.recLen = cast(ushort)(g_page_size - 3);
libHeader.ndicpages = ndicpages;
libHeader.flags = 1; // always case sensitive
// Write library header at start of buffer
memcpy(cast(void*)libbuf[].ptr, &libHeader, (libHeader).sizeof);
}
}
/*****************************************************************************/
/*****************************************************************************/
struct OmfObjModule
{
ubyte* base; // where are we holding it in memory
uint length; // in bytes
ushort page; // page module starts in output file
const(char)[] name; // module name, with terminating 0
}
enum HASHMOD = 0x25;
enum BUCKETPAGE = 512;
enum BUCKETSIZE = (BUCKETPAGE - HASHMOD - 1);
/*******************************************
* Write a single entry into dictionary.
* Returns:
* false failure
*/
bool EnterDict(ubyte* bucketsP, ushort ndicpages, ubyte* entry, uint entrylen)
{
ushort uStartIndex;
ushort uStep;
ushort uStartPage;
ushort uPageStep;
ushort uIndex;
ushort uPage;
ushort n;
uint u;
uint nbytes;
ubyte* aP;
ubyte* zP;
aP = entry;
zP = aP + entrylen; // point at last char in identifier
uStartPage = 0;
uPageStep = 0;
uStartIndex = 0;
uStep = 0;
u = entrylen;
while (u--)
{
uStartPage = rol!(ushort)(uStartPage, 2) ^ (*aP | 0x20);
uStep = ror!(ushort)(uStep, 2) ^ (*aP++ | 0x20);
uStartIndex = ror!(ushort)(uStartIndex, 2) ^ (*zP | 0x20);
uPageStep = rol!(ushort)(uPageStep, 2) ^ (*zP-- | 0x20);
}
uStartPage %= ndicpages;
uPageStep %= ndicpages;
if (uPageStep == 0)
uPageStep++;
uStartIndex %= HASHMOD;
uStep %= HASHMOD;
if (uStep == 0)
uStep++;
uPage = uStartPage;
uIndex = uStartIndex;
// number of bytes in entry
nbytes = 1 + entrylen + 2;
if (entrylen > 255)
nbytes += 2;
while (1)
{
aP = &bucketsP[uPage * BUCKETPAGE];
uStartIndex = uIndex;
while (1)
{
if (0 == aP[uIndex])
{
// n = next available position in this page
n = aP[HASHMOD] << 1;
assert(n > HASHMOD);
// if off end of this page
if (n + nbytes > BUCKETPAGE)
{
aP[HASHMOD] = 0xFF;
break;
// next page
}
else
{
aP[uIndex] = cast(ubyte)(n >> 1);
memcpy((aP + n), entry, nbytes);
aP[HASHMOD] += (nbytes + 1) >> 1;
if (aP[HASHMOD] == 0)
aP[HASHMOD] = 0xFF;
return true;
}
}
uIndex += uStep;
uIndex %= 0x25;
/*if (uIndex > 0x25)
uIndex -= 0x25;*/
if (uIndex == uStartIndex)
break;
}
uPage += uPageStep;
if (uPage >= ndicpages)
uPage -= ndicpages;
if (uPage == uStartPage)
break;
}
return false;
}

View file

@ -336,123 +336,6 @@ public int runLINK(bool verbose, ErrorSink eSink)
parseLinkerOutput(cast(const(char)[]) buf.peekSlice(), new ErrorSinkCompiler());
return status;
}
else if (target.objectFormat() == Target.ObjectFormat.omf)
{
OutBuffer cmdbuf;
global.params.libfiles.push("user32");
global.params.libfiles.push("kernel32");
for (size_t i = 0; i < global.params.objfiles.length; i++)
{
if (i)
cmdbuf.writeByte('+');
const(char)[] p = global.params.objfiles[i].toDString();
const(char)[] basename = FileName.sansExt(FileName.name(p));
const(char)[] ext = FileName.ext(p);
if (ext.length && !memchr(basename.ptr, '.', basename.length))
{
// Write name sans extension (but not if a double extension)
writeFilename(&cmdbuf, FileName.sansExt(p));
}
else
writeFilename(&cmdbuf, p);
}
cmdbuf.writeByte(',');
if (global.params.exefile)
writeFilename(&cmdbuf, global.params.exefile);
else
{
setExeFile();
}
// Make sure path to exe file exists
if (!ensurePathToNameExists(Loc.initial, global.params.exefile))
return STATUS_FAILED;
cmdbuf.writeByte(',');
if (global.params.mapfile)
writeFilename(&cmdbuf, global.params.mapfile);
else if (driverParams.map)
{
writeFilename(&cmdbuf, getMapFilename());
}
else
cmdbuf.writestring("nul");
cmdbuf.writeByte(',');
for (size_t i = 0; i < global.params.libfiles.length; i++)
{
if (i)
cmdbuf.writeByte('+');
writeFilename(&cmdbuf, global.params.libfiles[i]);
}
if (global.params.deffile)
{
cmdbuf.writeByte(',');
writeFilename(&cmdbuf, global.params.deffile);
}
/* Eliminate unnecessary trailing commas */
while (1)
{
const size_t i = cmdbuf.length;
if (!i || cmdbuf[i - 1] != ',')
break;
cmdbuf.setsize(cmdbuf.length - 1);
}
if (global.params.resfile)
{
cmdbuf.writestring("/RC:");
writeFilename(&cmdbuf, global.params.resfile);
}
if (driverParams.map || global.params.mapfile)
cmdbuf.writestring("/m");
version (none)
{
if (debuginfo)
cmdbuf.writestring("/li");
if (codeview)
{
cmdbuf.writestring("/co");
if (codeview3)
cmdbuf.writestring(":3");
}
}
else
{
if (driverParams.symdebug)
cmdbuf.writestring("/co");
}
cmdbuf.writestring("/noi");
for (size_t i = 0; i < global.params.linkswitches.length; i++)
{
cmdbuf.writestring(global.params.linkswitches[i]);
}
cmdbuf.writeByte(';');
cmdbuf.writeByte(0); //null terminate the buffer
char[] p = cmdbuf.extractSlice()[0 .. $-1];
const(char)[] lnkfilename;
if (p.length > 7000)
{
lnkfilename = FileName.forceExt(global.params.exefile, "lnk");
if (!writeFile(Loc.initial, lnkfilename, p))
return STATUS_FAILED;
if (lnkfilename.length < p.length)
{
p[0] = '@';
p[1 .. lnkfilename.length +1] = lnkfilename;
p[lnkfilename.length +1] = 0;
}
}
const(char)* linkcmd = getenv("LINKCMD");
if (!linkcmd)
linkcmd = "optlink";
OutBuffer buf;
const int status = executecmd(linkcmd, p.ptr, verbose, eSink, buf);
if (lnkfilename)
{
lnkfilename.toCStringThen!(lf => remove(lf.ptr));
FileName.free(lnkfilename.ptr);
}
parseLinkerOutput(cast(const(char)[]) buf.peekSlice(), new ErrorSinkCompiler());
return status;
}
else
{
assert(0);
@ -842,20 +725,8 @@ version (Windows)
private int executecmd(const(char)* cmd, const(char)* args, bool verbose, ErrorSink eSink, ref OutBuffer buf)
{
int status;
size_t len;
if (verbose)
eSink.message(Loc.initial, "%s %s", cmd, args);
if (target.objectFormat() == Target.ObjectFormat.omf)
{
if ((len = strlen(args)) > 255)
{
status = putenvRestorable("_CMDLINE", args[0 .. len]);
if (status == 0)
args = "@_CMDLINE";
else
error(Loc.initial, "command line length of %llu is too long", cast(ulong) len);
}
}
// Normalize executable path separators
// https://issues.dlang.org/show_bug.cgi?id=9330
cmd = toWinPath(cmd);
@ -1082,12 +953,6 @@ public int runPreprocessor(ref const Loc loc, const(char)[] cpp, const(char)[] f
{
//printf("runPreprocessor() cpp: %.*s filename: %.*s\n", cast(int)cpp.length, cpp.ptr, cast(int)filename.length, filename.ptr);
/*
To get sppn.exe: http://ftp.digitalmars.com/sppn.zip
To get the dmc C headers, dmc will need to be installed:
http://ftp.digitalmars.com/Digital_Mars_C++/Patch/dm857c.zip
*/
version (Windows)
{
// generate unique temporary file name for preprocessed output
@ -1268,117 +1133,6 @@ public int runPreprocessor(ref const Loc loc, const(char)[] cpp, const(char)[] f
return returnResult(exitCode);
}
}
else if (target.objectFormat() == Target.ObjectFormat.omf)
{
/* Digital Mars Win32 target
* sppn filename -oooutput
* https://www.digitalmars.com/ctg/sc.html
*/
static if (1)
{
/* Run command
*/
OutBuffer buf;
buf.writestring(cpp);
buf.printf(" %.*s -HI%s -ED -o%.*s",
cast(int)filename.length, filename.ptr, importc_h, cast(int)output.length, output.ptr);
/* Append preprocessor switches to command line
*/
foreach (a; cppswitches)
{
if (a && a[0])
{
buf.writeByte(' ');
buf.writestring(a);
}
}
if (verbose)
eSink.message(Loc.initial, buf.peekChars());
ubyte[2048] buffer = void;
/* Write lines captured from stdout to either defines[] or stdout
*/
enum S
{
start, // start of line
hash, // write to defines[]
other, // write to stdout
}
S state = S.start;
void sinkomf(ubyte[] data)
{
foreach (c; data)
{
final switch (state)
{
case S.start:
if (c == '#')
{
defines.writeByte(c);
state = S.hash;
}
else
{
fputc(c, stdout);
state = S.other;
}
break;
case S.hash:
if (c == '\r')
{
}
else if (c == '\n')
{
defines.writeByte(0); // 0-terminate lines in defines[]
state = S.start;
}
else
defines.writeByte(c);
break;
case S.other:
fputc(c, stdout);
if (c == '\n')
state = S.start;
break;
}
}
}
// Convert command to wchar
wchar[1024] scratch = void;
auto smbuf = SmallBuffer!wchar(scratch.length, scratch[]);
auto szCommand = toWStringz(buf.peekChars()[0 .. buf.length], smbuf);
//printf("szCommand: %ls\n", szCommand.ptr);
int exitCode = runProcessCollectStdout(szCommand.ptr, buffer[], &sinkomf);
printf("\n");
return returnResult(exitCode);
}
else
{
auto cmd = cpp.xarraydup.ptr;
argv.push(cmd); // Digita; Mars C preprocessor
argv.push(filename.xarraydup.ptr); // and the input file
OutBuffer buf;
buf.writestring("-o"); // https://www.digitalmars.com/ctg/sc.html#dashofilename
buf.writeString(output);
argv.push(buf.extractData()); // output file
argv.push(null); // argv[] always ends with a null
// spawnlp returns intptr_t in some systems, not int
auto exitCode = spawnvp(_P_WAIT, cmd, argv.tdata());
return returnResult(exitCode);
}
}
else
{
assert(0);

View file

@ -812,7 +812,6 @@ bool parseCommandlineAndConfig(size_t argc, const(char)** argv, ref Param params
bool isX86_64 = arch[0] == '6';
version(Windows) // delete LIB entry in [Environment] (necessary for optlink) to allow inheriting environment for MS-COFF
if (arch != "32omf")
environment.update("LIB", 3).value = null;
// read from DFLAGS in [Environment{arch}] section
@ -971,8 +970,6 @@ void reconcileCommands(ref Param params, ref Target target)
}
else
{
if (target.omfobj)
error(Loc.initial, "`-m32omf` can only be used when targetting windows");
if (driverParams.mscrtlib)
error(Loc.initial, "`-mscrtlib` can only be used when targetting windows");
}

View file

@ -350,12 +350,7 @@ void setDefaultLibrary(ref Param params, const ref Target target)
{
if (target.os == Target.OS.Windows)
{
if (target.isX86_64)
driverParams.defaultlibname = "phobos64";
else if (!target.omfobj)
driverParams.defaultlibname = "phobos32mscoff";
else
driverParams.defaultlibname = "phobos";
driverParams.defaultlibname = target.isX86_64 ? "phobos64" : "phobos32mscoff";
}
else if (target.os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD))
{
@ -889,17 +884,14 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, ref Param
else if (arg == "-m32") // https://dlang.org/dmd.html#switch-m32
{
target.isX86_64 = false;
target.omfobj = false;
}
else if (arg == "-m64") // https://dlang.org/dmd.html#switch-m64
{
target.isX86_64 = true;
target.omfobj = false;
}
else if (arg == "-m32mscoff") // https://dlang.org/dmd.html#switch-m32mscoff
{
target.isX86_64 = false;
target.omfobj = false;
}
else if (startsWith(p + 1, "mscrtlib="))
{

View file

@ -1,394 +0,0 @@
/**
* Extract symbols from an OMF object file.
*
* Copyright: Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved
* Authors: $(LINK2 https://www.digitalmars.com, Walter Bright)
* License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/scanomf.d, _scanomf.d)
* Documentation: https://dlang.org/phobos/dmd_scanomf.html
* Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/scanomf.d
*/
module dmd.scanomf;
import core.stdc.string;
import core.stdc.stdlib;
import dmd.arraytypes;
import dmd.common.outbuffer;
import dmd.errorsink;
import dmd.location;
import dmd.root.rmem;
import dmd.root.string;
nothrow:
private enum LOG = false;
/*****************************************
* Reads an object module from base[] and passes the names
* of any exported symbols to (*pAddSymbol)().
* Params:
* pAddSymbol = function to pass the names to
* base = array of contents of object module
* module_name = name of the object module (used for error messages)
* loc = location to use for error printing
* eSink = where the error messages go
*/
void scanOmfObjModule(void delegate(const(char)[] name, int pickAny) nothrow pAddSymbol,
scope const ubyte[] base, scope const char* module_name, Loc loc, ErrorSink eSink)
{
static if (LOG)
{
printf("scanOmfObjModule(%s)\n", module_name);
}
char[LIBIDMAX + 1] name = void;
Strings names;
scope(exit)
for (size_t u = 1; u < names.length; u++)
free(cast(void*)names[u]);
names.push(null); // don't use index 0
bool easyomf = false; // assume not EASY-OMF
const pend = base.ptr + base.length;
const(ubyte)* pnext;
for (auto p = base.ptr; 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);
char* copy = cast(char*)Mem.check(strdup(name.ptr));
names.push(copy);
}
break;
case PUBDEF:
if (easyomf)
recTyp = PUB386; // convert to MS format
goto case;
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(name[0 .. strlen(name.ptr)], 0);
}
break;
case COMDAT:
if (easyomf)
recTyp = COMDAT + 1; // convert to MS format
goto case;
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.length)
{
//debug(printf("[s] name idx=%d, uCntNames=%d\n", idx, uCntNames));
eSink.error(loc, "corrupt COMDAT");
return;
}
//printf("[s] name='%s'\n",name);
const(char)* n = names[idx];
pAddSymbol(n.toDString(), pickAny);
break;
}
case COMDEF:
{
while (p + 1 < pnext)
{
parseName(p, name.ptr);
parseIdx(p); // type index
skipDataType(p); // data type
pAddSymbol(name[0 .. strlen(name.ptr)], 1);
}
break;
}
case ALIAS:
while (p + 1 < pnext)
{
parseName(p, name.ptr);
pAddSymbol(name[0 .. strlen(name.ptr)], 0);
parseName(p, name.ptr);
}
break;
case MODEND:
case M386END:
return;
case COMENT:
// Recognize Phar Lap EASY-OMF format
{
__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 = true;
break;
L1:
}
}
// Recognize .IMPDEF Import Definition Records
{
__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(name[0 .. strlen(name.ptr)], 0);
break;
L2:
}
}
break;
default:
// ignore
}
}
}
/*************************************************
* 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
*/
bool scanOmfLib(void delegate(char* name, void* base, size_t length) nothrow pAddObjModule, scope void* buf, size_t buflen, uint pagesize)
{
/* Split up the buffer buf[0..buflen] into multiple object modules,
* each aligned on a pagesize boundary.
*/
const(ubyte)* base = null;
char[LIBIDMAX + 1] name = void;
auto p = cast(const(ubyte)*)buf;
auto pend = p + buflen;
const(ubyte)* pnext;
for (; p < pend; p = pnext) // for each OMF record
{
if (p + 3 >= pend)
return true; // corrupt
ubyte recTyp = *p;
ushort recLen = *cast(const(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(name.ptr, cast(ubyte*)base, pnext - base);
base = null;
}
// Round up to next page
uint t = cast(uint)(pnext - cast(const(ubyte)*)buf);
t = (t + pagesize - 1) & ~cast(uint)(pagesize - 1);
pnext = cast(const(ubyte)*)buf + t;
break;
}
default:
// ignore
}
}
return (base !is null); // missing MODEND record
}
uint OMFObjSize(scope const void* base, size_t length, scope 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 cast(uint)length;
}
void writeOMFObj(ref OutBuffer buf, scope const void* base, size_t length, scope const char* name)
{
ubyte c = *cast(const(ubyte)*)base;
if (c != THEADR && c != LHEADR)
{
const len = strlen(name);
assert(len <= LIBIDMAX);
ubyte[4 + LIBIDMAX + 1] header = void;
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[0 .. len + 5]);
}
buf.write(base[0 .. length]);
}
private: // for the remainder of this module
/**************************
* 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
void parseName(ref scope const(ubyte)* pp, char* name)
{
auto 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;
}
ushort parseIdx(ref scope const(ubyte)* pp)
{
auto p = pp;
const 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
void skipNumericField(ref scope const(ubyte)* pp)
{
const(ubyte)* p = pp;
const 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
void skipDataType(ref scope const(ubyte)* pp)
{
auto p = pp;
const 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;
}

View file

@ -324,7 +324,6 @@ extern (C++) struct Target
elf,
macho,
coff,
omf
}
OS os;
@ -358,7 +357,6 @@ extern (C++) struct Target
const(char)[] lib_ext; /// extension for static library files
const(char)[] dll_ext; /// extension for dynamic library files
bool run_noext; /// allow -run sources without extensions
bool omfobj; // for Win32: write OMF object files instead of MsCoff
/**
* Values representing all properties for floating point types
*/
@ -406,7 +404,7 @@ extern (C++) struct Target
*/
extern (C++) void _init(ref const Param params)
{
// isX86_64, omfobj and cpu are initialized in parseCommandLine
// isX86_64 and cpu are initialized in parseCommandLine
this.params = &params;
@ -451,13 +449,6 @@ extern (C++) struct Target
realsize = 10;
realpad = 0;
realalignsize = 2;
if (omfobj)
{
/* Optlink cannot deal with individual data chunks
* larger than 16Mb
*/
maxStaticDataSize = 0x100_0000; // 16Mb
}
}
else
assert(0);
@ -511,7 +502,7 @@ extern (C++) struct Target
else if (os & Target.OS.Posix)
return Target.ObjectFormat.elf;
else if (os == Target.OS.Windows)
return omfobj ? Target.ObjectFormat.omf : Target.ObjectFormat.coff;
return Target.ObjectFormat.coff;
else
assert(0, "unkown object format");
}
@ -1238,7 +1229,7 @@ extern (C++) struct Target
{
case objectFormat.stringof:
if (os == Target.OS.Windows)
return stringExp(omfobj ? "omf" : "coff" );
return stringExp("coff");
else if (os == Target.OS.OSX)
return stringExp("macho");
else
@ -1247,11 +1238,7 @@ extern (C++) struct Target
return stringExp("hard");
case cppRuntimeLibrary.stringof:
if (os == Target.OS.Windows)
{
if (omfobj)
return stringExp("snn");
return stringExp(driverParams.mscrtlib);
}
return stringExp("");
case cppStd.stringof:
return new IntegerExp(params.cplusplus);
@ -1310,7 +1297,7 @@ extern (C++) struct Target
*/
extern (C++) bool supportsLinkerDirective() const @safe
{
return os == Target.OS.Windows && !omfobj;
return os == Target.OS.Windows;
}
////////////////////////////////////////////////////////////////////////////
@ -1370,7 +1357,6 @@ struct TargetC
enum BitFieldStyle : ubyte
{
Unspecified,
DM, /// Digital Mars 32 bit C compiler
MS, /// Microsoft 32 and 64 bit C compilers
/// https://docs.microsoft.com/en-us/cpp/c-language/c-bit-fields?view=msvc-160
/// https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=msvc-160
@ -1419,7 +1405,7 @@ struct TargetC
wchar_tsize = 4;
if (os == Target.OS.Windows)
runtime = target.omfobj ? Runtime.DigitalMars : Runtime.Microsoft;
runtime = Runtime.Microsoft;
else if (os == Target.OS.linux)
{
// Note: This is overridden later by `-target=<triple>` if supplied.
@ -1431,7 +1417,7 @@ struct TargetC
}
if (os == Target.OS.Windows)
bitFieldStyle = target.omfobj ? BitFieldStyle.DM : BitFieldStyle.MS;
bitFieldStyle = BitFieldStyle.MS;
else if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OSX |
Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris))
bitFieldStyle = BitFieldStyle.Gcc_Clang;
@ -1484,13 +1470,13 @@ struct TargetCPP
else if (os == Target.OS.Windows)
{
reverseOverloads = true;
splitVBasetable = !target.omfobj;
splitVBasetable = true;
}
else
assert(0);
exceptions = (os & Target.OS.Posix) != 0;
if (os == Target.OS.Windows)
runtime = target.omfobj ? Runtime.DigitalMars : Runtime.Microsoft;
runtime = Runtime.Microsoft;
else if (os & (Target.OS.linux | Target.OS.DragonFlyBSD))
runtime = Runtime.Gcc;
else if (os & (Target.OS.OSX | Target.OS.FreeBSD | Target.OS.OpenBSD))
@ -1513,17 +1499,12 @@ struct TargetCPP
extern (C++) const(char)* toMangle(Dsymbol s)
{
import dmd.cppmangle : toCppMangleItanium;
import dmd.cppmanglewin : toCppMangleDMC, toCppMangleMSVC;
import dmd.cppmanglewin : toCppMangleMSVC;
if (target.os & (Target.OS.linux | Target.OS.OSX | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD))
return toCppMangleItanium(s);
if (target.os == Target.OS.Windows)
{
if (target.omfobj)
return toCppMangleDMC(s);
else
return toCppMangleMSVC(s);
}
return toCppMangleMSVC(s);
else
assert(0, "fix this");
}
@ -1538,17 +1519,12 @@ struct TargetCPP
extern (C++) const(char)* typeInfoMangle(ClassDeclaration cd)
{
import dmd.cppmangle : cppTypeInfoMangleItanium;
import dmd.cppmanglewin : cppTypeInfoMangleDMC, cppTypeInfoMangleMSVC;
import dmd.cppmanglewin : cppTypeInfoMangleMSVC;
if (target.os & (Target.OS.linux | Target.OS.OSX | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD))
return cppTypeInfoMangleItanium(cd);
if (target.os == Target.OS.Windows)
{
if (target.omfobj)
return cppTypeInfoMangleDMC(cd);
else
return cppTypeInfoMangleMSVC(cd);
}
return cppTypeInfoMangleMSVC(cd);
else
assert(0, "fix this");
}

View file

@ -62,7 +62,6 @@ struct TargetC
enum class BitFieldStyle : unsigned char
{
Unspecified,
DM, // Digital Mars 32 bit C compiler
MS, // Microsoft 32 and 64 bit C compilers
// https://docs.microsoft.com/en-us/cpp/c-language/c-bit-fields?view=msvc-160
// https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=msvc-160
@ -164,7 +163,6 @@ struct Target
DString lib_ext; /// extension for static library files
DString dll_ext; /// extension for dynamic library files
d_bool run_noext; /// allow -run sources without extensions
d_bool omfobj; /// for Win32: write OMF object files instead of COFF
template <typename T>
struct FPTypeProperties

View file

@ -960,7 +960,6 @@ private void membersToDt(AggregateDeclaration ad, ref DtBuilder dtb,
bitFieldSize = (bf.bitOffset + bf.fieldWidth + 7) / 8;
break;
case TargetC.BitFieldStyle.DM:
case TargetC.BitFieldStyle.MS:
// This relies on all bit fields in the same storage location have the same type
bitFieldSize = cast(uint)vd.type.size();

View file

@ -191,7 +191,7 @@ void main(string[] args)
Test parameters can be restricted to certain targets by adding a brace-enclosed
condition after the name, i.e. `REQUIRED_ARGS(<condition>): ...`. The `<condition>`
consists of the target operating system followed by an optional model suffix,
e.g. `linux`, `win32mscoff`, `freebsd64`.
e.g. `linux`, `win32`, `freebsd64`.
Valid platforms:
- win
@ -203,8 +203,6 @@ Valid platforms:
Valid models:
- 32
- 32mscoff (windows only)
- 32omf (windows only)
- 64
Note that test parameters *MUST* be followed by a colon (intermediate whitespace is allowed).
@ -358,7 +356,7 @@ Environment variables
ARGS: set to execute all combinations of
AUTO_UPDATE: set to 1 to auto-update mismatching test output
CC: C++ compiler to use, ex: dmc, g++
CC: C++ compiler to use, ex: cl, g++
DMD: compiler to use, ex: ../src/dmd (required)
MODEL: 32 or 64 (required)
OS: windows, linux, freebsd, osx, netbsd, dragonflybsd
@ -430,7 +428,7 @@ depend on the current platform and target:
Supported conditions:
- OS: posix, windows, ...
- Model: 64, 32mscoff, 32omf and 32 (also matches 32mscoff + 32omf)
- Model: 64, 32
$r:<regex>$ any text matching <regex> (using $ inside of <regex> is not
supported, use multiple regexes instead)

View file

@ -1,8 +1,5 @@
// REQUIRED_ARGS: -identifiers-importc=UAX31
// sppn doesn't support anything newer than c99
// DISABLED: win32omf
// verify that the UAX31 identifier set is applied.
int \u00F8ide\u00F9nt;

View file

@ -1,8 +1,5 @@
// REQUIRED_ARGS: -identifiers-importc=all
// sppn doesn't support anything newer than c99
// DISABLED: win32omf
// verify that the All identifier set is applied.
int \u00F8ide\u00F9nt;

View file

@ -1,8 +1,5 @@
// REQUIRED_ARGS: -identifiers-importc=c11
// sppn doesn't support anything newer than c99
// DISABLED: win32omf
// verify that the C11 identifier set is applied.
int \u00A8ide\u00AFnt;

View file

@ -13,7 +13,7 @@ src="$bin_base.d"
echo 'void main() {}' > "${src}"
# Only compile, not link, since optlink can't handle long file names
# Only compile, don't link, since the Microsoft linker doesn't implicitly support long paths
$DMD -m"${MODEL}" "${DFLAGS}" -c -of"${bin}" "${src}"
rm_retry -r "${OUTPUT_BASE}"

View file

@ -4,9 +4,7 @@
#include <assert.h>
#ifndef __DMC__ // D:\a\1\s\tools\dm\include\complex.h(105): Deprecation: use of complex type `cdouble` is deprecated, use `std.complex.Complex!(double)` instead
#include <complex.h>
#endif
#include <ctype.h>
#include <errno.h>
@ -34,13 +32,10 @@ float x = NAN;
#include <signal.h>
#endif
#ifndef __DMC__ // no stdalign.h
#include <stdalign.h>
#endif
#include <stdarg.h>
#ifndef __DMC__ // no stdatomic.h
#ifndef __linux__
#ifndef _MSC_VER
#ifndef __APPLE__ // /Applications/Xcode-14.2.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/stdatomic.h(80): Error: type-specifier is missing
@ -48,7 +43,6 @@ float x = NAN;
#endif
#endif
#endif
#endif
#include <stdbool.h>
#include <stddef.h>
@ -59,13 +53,10 @@ float x = NAN;
#include <stdlib.h>
#endif
#ifndef __DMC__ // no stdnoreturn.h
#include <stdnoreturn.h>
#endif
#include <string.h>
#ifndef __DMC__ // no tgmath.h
#ifndef _MSC_VER // C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt\tgmath.h(33): Error: no type for declarator before `)`
#ifndef __APPLE__ // /Applications/Xcode-14.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/tgmath.h(39): Error: named parameter required before `...`
#if !(defined(__linux__) && defined(__aarch64__)) // /tmp/clang/lib/clang/15.0.3/include/tgmath.h(34): Error: named parameter required before `...`
@ -73,9 +64,7 @@ float x = NAN;
#endif
#endif
#endif
#endif
#ifndef __DMC__
#ifndef __linux__
#ifndef __APPLE__
#ifndef _MSC_VER
@ -83,18 +72,13 @@ float x = NAN;
#endif
#endif
#endif
#endif
#include <time.h>
#ifndef __DMC__ // no uchar.h
#ifndef __APPLE__ // no uchar.h
#include <uchar.h>
#endif
#endif
#include <wchar.h>
#ifndef __DMC__ // wctype.h(102): Error: unterminated string constant starting at #defines(780)
#include <wctype.h>
#endif

View file

@ -1,7 +1,5 @@
// REQUIRED_ARGS: -g
// If this is failing, you need optlink 8.00.14 or higher
string gen()
{
string m;

View file

@ -9,16 +9,6 @@ int main()
writeln("CPP header generation test was skipped because $CXX is empty!");
return DISABLED;
}
// DMC cannot compile the generated headers ...
version (Windows)
{
import std.algorithm : canFind;
if (CXX.canFind("dmc"))
{
writeln("CPP header generation test was skipped because DMC is not supported!");
return DISABLED;
}
}
Vars.set("SOURCE_DIR", "$EXTRA_FILES/cpp_header_gen");
Vars.set("LIB", "$OUTPUT_BASE/library$LIBEXT");

View file

@ -49,13 +49,6 @@ void testConfigurations()
"-conf=" ~ configPath
];
version (Windows) if (MODEL == "32omf")
{
// 32-OMF tries to use `optlink.exe` located next to `sc.ini`
// and also doesn't like the LIB setup, so skip it for now
extraFlags = [""];
}
foreach (const target; targets)
{
foreach (const flags; extraFlags)

View file

@ -2,9 +2,6 @@ import dshell;
int main()
{
version (Windows) if (Vars.MODEL == "32omf") // Avoid optlink
return DISABLED;
version (DigitalMars)
{
// Disable DM Dlls for now, need to redesign it

View file

@ -25,18 +25,9 @@ int main()
version (Windows)
{
Vars.set(`DLL_LIB`, `$OUTPUT_BASE${SEP}mydll.lib`);
if (Vars.MODEL == "32omf")
{
// CXX should be dmc for win32omf.
dllCmd ~= [`-mn`, `-L/implib:` ~ Vars.DLL_LIB, `-WD`, `-o` ~ Vars.DLL, `kernel32.lib`, `user32.lib`];
mainExtra = `$DLL_LIB`;
}
else
{
// CXX should be cl for win32mscoff.
dllCmd ~= [`/LD`, `/nologo`, `/Fe` ~ Vars.DLL];
mainExtra = `$DLL_LIB`;
}
// CXX should be cl
dllCmd ~= [`/LD`, `/nologo`, `/Fe` ~ Vars.DLL];
mainExtra = `$DLL_LIB`;
}
else version(OSX)
{

View file

@ -2,15 +2,6 @@ import dshell;
int main()
{
version (DigitalMars)
{
if (OS == "windows" && MODEL == "32omf")
{
writeln("Skipping test when using Optlink.");
return DISABLED;
}
}
Vars.set("lib", "$OUTPUT_BASE/dir with spaces/b$LIBEXT");
run("$DMD -m$MODEL -of$lib -lib $EXTRA_FILES/linker_flag_with_spaces_b.d");

View file

@ -307,12 +307,9 @@ void ensureToolsExists(const string[string] env, const TestTool[] tools ...)
}
else
{
string model = env["MODEL"];
if (model == "32omf") model = "32";
buildCommand = [
hostDMD,
"-m"~model,
"-m"~env["MODEL"],
"-of"~targetBin,
sourceFile
] ~ getPicFlags(env) ~ tool.extraArgs;

View file

@ -1,206 +0,0 @@
/* test bitfields for Digital Mars C
* Note that this test is for win32 only
*
* REQUIRED_ARGS:
* DISABLED: win32mscoff win64 linux freebsd osx
* RUN_OUTPUT:
---
DM | MS | P32 | P64
T0 = 1 1 || 1 1 | 1 1 | 1 1 | 1 1
T1 = 2 2 || 2 2 | 2 2 | 2 2 | 2 2
T2 = 4 4 || 4 4 | 4 4 | 4 4 | 4 4
T3 = 16 8 || 16 8 | 16 8 | 8 4 | 8 8
T4 = 16 8 || 16 8 | 16 8 | 12 4 | 16 8
T5 = 16 8 || 16 8 | 16 8 | 8 4 | 8 8
S1 = 8 8 || 8 8 | 8 8 | 4 4 | 8 8
S2 = 4 4 || 4 4 | 4 4 | 4 4 | 4 4
S3 = 8 4 || 8 4 | 8 4 | 4 4 | 4 4
S4 = 8 4 || 8 4 | 8 4 | 4 4 | 4 4
S5 = 8 4 || 8 4 | 8 4 | 4 4 | 4 4
S6 = 2 2 || 2 2 | 2 2 | 2 2 | 2 2
S7 = 16 8 || 16 8 | 16 8 | 4 4 | 8 8
S8 = 4 2 || 4 2 | 4 2 | 2 2 | 2 2
S8A = 4 2 || 4 2 | 4 2 | 2 2 | 2 2
S8B = 6 2 || 6 2 | 6 2 | 2 2 | 2 2
S8C = 8 4 || 8 4 | 8 4 | 4 4 | 4 4
S9 = 4 2 || 4 2 | 4 2 | 4 2 | 4 2
S10 = 0 0 || 0 0 | * * | 0 1 | 0 1
S11 = 0 0 || 0 0 | 4 1 | 0 1 | 0 1
S12 = 4 4 || 4 4 | 4 4 | 4 4 | 4 4
S13 = 8 4 || 8 4 | 8 4 | 8 4 | 8 4
S14 = 8 4 || 8 4 | 8 4 | 8 4 | 8 4
S15 = 8 4 || 8 4 | 8 4 | 4 4 | 4 4
S16 = 0 0 || 0 0 | 4 4 | 4 1 | 4 1
S17 = 4 4 || 4 4 | 4 4 | 4 4 | 4 4
S18 = 2 1 || 2 1 | 2 1 | 5 1 | 9 1
A0 = 16 8 || 16 8 | 16 8 | 12 4 | 16 8
A1 = 12 4 || 12 4 | 12 4 | 12 4 | 12 4
A2 = 12 4 || 12 4 | 12 4 | 12 4 | 12 4
A3 = 16 4 || 16 4 | 16 4 | 16 4 | 16 4
A4 = 12 4 || 12 4 | 12 4 | 8 4 | 8 4
A5 = 2 1 || 2 1 | 2 1 | 2 1 | 2 1
A6 = 4 2 || 4 2 | 4 2 | 2 2 | 2 2
A7 = 16 4 || 16 4 | 16 4 | 12 4 | 16 8
A8 = 12 4 || 12 4 | 12 4 | 8 4 | 8 8
A9 = 32 8 || 32 8 | 32 8 | 16 4 | 16 8
A10 = 4 2 || 4 2 | 4 2 | 2 2 | 2 2
A11 = 16 4 || 16 4 | 16 4 | 12 4 | 12 4
S9 = x30200
S14 = x300000201
S15 = x201
S18 = 1 should be 4
A0 = x1
---
*/
int printf(const char *fmt, ...);
void exit(int);
void assert(int n, int b)
{
if (!b)
{
printf("assert fail %d\n", n);
exit(1);
}
}
int is64bit() { return sizeof(long) == 8; } // otherwise assume 32 bit
/*************************************************************/
struct T0 { char x:1; }; //
struct T1 { short x:1; }; //
struct T2 { int x:1; }; //
struct T3 { char a,b,c,d; long long x:1; }; //
struct T4 { char a,b,c,d,e,f,g,h; long long x:1; }; //
struct T5 { char a,b,c,d,e,f,g; long long x:1; }; //
struct S1 { long long int f:1; }; //
struct S2 { int x:1; int y:1; }; //
struct S3 { short c; int x:1; unsigned y:1; }; //
struct S4 { int x:1; short y:1; }; //
struct S5 { short x:1; int y:1; }; //
struct S6 { short x:1; short y:1; }; //
struct S7 { short x:1; int y:1; long long z:1; }; //
struct S8 { char a; char b:1; short c:2; }; //
struct S8A { char b:1; short c:2; }; //
struct S8B { char a; short b:1; char c:2; }; //
struct S8C { char a; int b:1; }; //
struct S9 { char a; char b:2; short c:9; }; //
struct S10 { }; //
struct S11 { int :0; }; //
struct S12 { int :0; int x; }; //
struct S13 { unsigned x:12; unsigned x1:1; unsigned x2:1; unsigned x3:1; unsigned x4:1; int w; }; //
struct S14 { char a; char b:4; int c:30; }; //
struct S15 { char a; char b:2; int c:9; }; //
struct S16 { int :32; }; //
struct S17 { int a:32; }; //
struct S18 { char a; long long :0; char b; }; //
struct A0 { int a; long long b:34, c:4; }; //
struct A1 { int a; unsigned b:11; int c; }; //
struct A2 { int a; unsigned b:11, c:5, d:16; //
int e; };
struct A3 { int a; unsigned b:11, c:5, :0, d:16; //
int e; };
struct A4 { int a:8; short b:7; //
unsigned int c:29; };
struct A5 { char a:7, b:2; }; //
struct A6 { char a:7; short b:2; }; //
struct A7 { short a:8; long b:16; int c; //
char d:7; };
struct A8 { short a:8; long b:16; int :0; //
char c:7; };
struct A9 { unsigned short a:8; long b:16; //
unsigned long c:29; long long d:9;
unsigned long e:2, f:31; };
struct A10 { unsigned short a:8; char b; }; //
struct A11 { char a; int b:5, c:11, :0, d:8; //
struct { int ee:8; } e; };
int main()
{
/* MS produces identical results for 32 and 64 bit compiles,
* DM is 32 bit only
*/
printf(" DM | MS | P32 | P64\n");
printf("T0 = %2d %d || 1 1 | 1 1 | 1 1 | 1 1\n", (int)sizeof(struct T0), (int)_Alignof(struct T0));
printf("T1 = %2d %d || 2 2 | 2 2 | 2 2 | 2 2\n", (int)sizeof(struct T1), (int)_Alignof(struct T1));
printf("T2 = %2d %d || 4 4 | 4 4 | 4 4 | 4 4\n", (int)sizeof(struct T2), (int)_Alignof(struct T2));
printf("T3 = %2d %d || 16 8 | 16 8 | 8 4 | 8 8\n", (int)sizeof(struct T3), (int)_Alignof(struct T3));
printf("T4 = %2d %d || 16 8 | 16 8 | 12 4 | 16 8\n", (int)sizeof(struct T4), (int)_Alignof(struct T4));
printf("T5 = %2d %d || 16 8 | 16 8 | 8 4 | 8 8\n", (int)sizeof(struct T5), (int)_Alignof(struct T5));
printf("S1 = %2d %d || 8 8 | 8 8 | 4 4 | 8 8\n", (int)sizeof(struct S1), (int)_Alignof(struct S1));
printf("S2 = %2d %d || 4 4 | 4 4 | 4 4 | 4 4\n", (int)sizeof(struct S2), (int)_Alignof(struct S2));
printf("S3 = %2d %d || 8 4 | 8 4 | 4 4 | 4 4\n", (int)sizeof(struct S3), (int)_Alignof(struct S3));
printf("S4 = %2d %d || 8 4 | 8 4 | 4 4 | 4 4\n", (int)sizeof(struct S4), (int)_Alignof(struct S4));
printf("S5 = %2d %d || 8 4 | 8 4 | 4 4 | 4 4\n", (int)sizeof(struct S5), (int)_Alignof(struct S5));
printf("S6 = %2d %d || 2 2 | 2 2 | 2 2 | 2 2\n", (int)sizeof(struct S6), (int)_Alignof(struct S6));
printf("S7 = %2d %d || 16 8 | 16 8 | 4 4 | 8 8\n", (int)sizeof(struct S7), (int)_Alignof(struct S7));
printf("S8 = %2d %d || 4 2 | 4 2 | 2 2 | 2 2\n", (int)sizeof(struct S8), (int)_Alignof(struct S8));
printf("S8A = %2d %d || 4 2 | 4 2 | 2 2 | 2 2\n", (int)sizeof(struct S8A), (int)_Alignof(struct S8A));
printf("S8B = %2d %d || 6 2 | 6 2 | 2 2 | 2 2\n", (int)sizeof(struct S8B), (int)_Alignof(struct S8B));
printf("S8C = %2d %d || 8 4 | 8 4 | 4 4 | 4 4\n", (int)sizeof(struct S8C), (int)_Alignof(struct S8C));
printf("S9 = %2d %d || 4 2 | 4 2 | 4 2 | 4 2\n", (int)sizeof(struct S9), (int)_Alignof(struct S9));
printf("S10 = %2d %d || 0 0 | * * | 0 1 | 0 1\n", (int)sizeof(struct S10), (int)_Alignof(struct S10)); // MS doesn't compile
printf("S11 = %2d %d || 0 0 | 4 1 | 0 1 | 0 1\n", (int)sizeof(struct S11), (int)_Alignof(struct S11));
printf("S12 = %2d %d || 4 4 | 4 4 | 4 4 | 4 4\n", (int)sizeof(struct S12), (int)_Alignof(struct S12));
printf("S13 = %2d %d || 8 4 | 8 4 | 8 4 | 8 4\n", (int)sizeof(struct S13), (int)_Alignof(struct S13));
printf("S14 = %2d %d || 8 4 | 8 4 | 8 4 | 8 4\n", (int)sizeof(struct S14), (int)_Alignof(struct S14));
printf("S15 = %2d %d || 8 4 | 8 4 | 4 4 | 4 4\n", (int)sizeof(struct S15), (int)_Alignof(struct S15));
printf("S16 = %2d %d || 0 0 | 4 4 | 4 1 | 4 1\n", (int)sizeof(struct S16), (int)_Alignof(struct S16));
printf("S17 = %2d %d || 4 4 | 4 4 | 4 4 | 4 4\n", (int)sizeof(struct S17), (int)_Alignof(struct S17));
printf("S18 = %2d %d || 2 1 | 2 1 | 5 1 | 9 1\n", (int)sizeof(struct S18), (int)_Alignof(struct S18));
printf("A0 = %2d %d || 16 8 | 16 8 | 12 4 | 16 8\n", (int)sizeof(struct A0), (int)_Alignof(struct A0));
printf("A1 = %2d %d || 12 4 | 12 4 | 12 4 | 12 4\n", (int)sizeof(struct A1), (int)_Alignof(struct A1));
printf("A2 = %2d %d || 12 4 | 12 4 | 12 4 | 12 4\n", (int)sizeof(struct A2), (int)_Alignof(struct A2));
printf("A3 = %2d %d || 16 4 | 16 4 | 16 4 | 16 4\n", (int)sizeof(struct A3), (int)_Alignof(struct A3));
printf("A4 = %2d %d || 12 4 | 12 4 | 8 4 | 8 4\n", (int)sizeof(struct A4), (int)_Alignof(struct A4));
printf("A5 = %2d %d || 2 1 | 2 1 | 2 1 | 2 1\n", (int)sizeof(struct A5), (int)_Alignof(struct A5));
printf("A6 = %2d %d || 4 2 | 4 2 | 2 2 | 2 2\n", (int)sizeof(struct A6), (int)_Alignof(struct A6));
printf("A7 = %2d %d || 16 4 | 16 4 | 12 4 | 16 8\n", (int)sizeof(struct A7), (int)_Alignof(struct A7));
printf("A8 = %2d %d || 12 4 | 12 4 | 8 4 | 8 8\n", (int)sizeof(struct A8), (int)_Alignof(struct A8));
printf("A9 = %2d %d || 32 8 | 32 8 | 16 4 | 16 8\n", (int)sizeof(struct A9), (int)_Alignof(struct A9));
printf("A10 = %2d %d || 4 2 | 4 2 | 2 2 | 2 2\n", (int)sizeof(struct A10), (int)_Alignof(struct A10));
printf("A11 = %2d %d || 16 4 | 16 4 | 12 4 | 12 4\n", (int)sizeof(struct A11), (int)_Alignof(struct A11));
{
struct S9 s;
unsigned x;
*(unsigned *)&s = 0;
s.b = 2; s.c = 3;
x = *(unsigned *)&s;
printf("S9 = x%x\n", x);
}
{
struct S14 s = { 1, 2, 3 };
unsigned long long v;
*(long long *)&s = 0;
s.a = 1;
s.b = 2;
s.c = 3;
v = *(unsigned long long *)&s;
printf("S14 = x%llx\n", v);
}
{
struct S15 s = { 1,2,3 };
unsigned x;
*(unsigned *)&s = 0;
s.a = 1; s.b = 2; s.c = 3;
x = *(unsigned *)&s;
printf("S15 = x%x\n", x);
}
{
struct S18 s;
printf("S18 = %d should be %d\n", (int)(&s.b - &s.a), is64bit() ? 8 : 4);
}
{
struct A0 s;
long long x;
*(long long *)&s = 0;
s.a = 1; s.b = 15;
x = *(long long *)&s;
printf("A0 = x%llx\n", x);
}
return 0;
}

View file

@ -1,196 +0,0 @@
/* test bitfields for Digital Mars
* Note that this test is for win32 only
*
* REQUIRED_ARGS: -preview=bitfields
* DISABLED: win32mscoff win64 linux freebsd osx
* RUN_OUTPUT:
---
DM | MS | P32 | P64
T0 = 1 1 || 1 1 | 1 1 | 1 1 | 1 1
T1 = 2 2 || 2 2 | 2 2 | 2 2 | 2 2
T2 = 4 4 || 4 4 | 4 4 | 4 4 | 4 4
T3 = 16 8 || 16 8 | 16 8 | 8 4 | 8 8
T4 = 16 8 || 16 8 | 16 8 | 12 4 | 16 8
T5 = 16 8 || 16 8 | 16 8 | 8 4 | 8 8
S1 = 8 8 || 8 8 | 8 8 | 4 4 | 8 8
S2 = 4 4 || 4 4 | 4 4 | 4 4 | 4 4
S3 = 8 4 || 8 4 | 8 4 | 4 4 | 4 4
S4 = 8 4 || 8 4 | 8 4 | 4 4 | 4 4
S5 = 8 4 || 8 4 | 8 4 | 4 4 | 4 4
S6 = 2 2 || 2 2 | 2 2 | 2 2 | 2 2
S7 = 16 8 || 16 8 | 16 8 | 4 4 | 8 8
S8 = 4 2 || 4 2 | 4 2 | 2 2 | 2 2
S8A = 4 2 || 4 2 | 4 2 | 2 2 | 2 2
S8B = 6 2 || 6 2 | 6 2 | 2 2 | 2 2
S8C = 8 4 || 8 4 | 8 4 | 4 4 | 4 4
S9 = 4 2 || 4 2 | 4 2 | 4 2 | 4 2
S10 = 1 1 || 0 0 | * * | 0 1 | 0 1
S11 = 1 1 || 0 0 | 4 1 | 0 1 | 0 1
S12 = 4 4 || 4 4 | 4 4 | 4 4 | 4 4
S13 = 8 4 || 8 4 | 8 4 | 8 4 | 8 4
S14 = 8 4 || 8 4 | 8 4 | 8 4 | 8 4
S15 = 8 4 || 8 4 | 8 4 | 4 4 | 4 4
S16 = 1 1 || 0 0 | 4 4 | 4 1 | 4 1
S17 = 4 4 || 4 4 | 4 4 | 4 4 | 4 4
S18 = 2 1 || 2 1 | 2 1 | 5 1 | 9 1
A0 = 16 8 || 16 8 | 16 8 | 12 4 | 16 8
A1 = 12 4 || 12 4 | 12 4 | 12 4 | 12 4
A2 = 12 4 || 12 4 | 12 4 | 12 4 | 12 4
A3 = 16 4 || 16 4 | 16 4 | 16 4 | 16 4
A4 = 12 4 || 12 4 | 12 4 | 8 4 | 8 4
A5 = 2 1 || 2 1 | 2 1 | 2 1 | 2 1
A6 = 4 2 || 4 2 | 4 2 | 2 2 | 2 2
A7 = 16 4 || 16 4 | 16 4 | 12 4 | 16 8
A8 = 12 4 || 12 4 | 12 4 | 8 4 | 8 8
A9 = 32 8 || 32 8 | 32 8 | 16 4 | 16 8
A10 = 4 2 || 4 2 | 4 2 | 2 2 | 2 2
A11 = 16 4 || 16 4 | 16 4 | 12 4 | 12 4
S9 = x30200
S14 = x300000201
S15 = x201
S18 = 1 should be 4
A0 = x1
---
*/
import core.stdc.stdio;
int is64bit() { return size_t.sizeof == 8; } // otherwise assume 32 bit
/*************************************************************/
struct T0 { ubyte x:1; }; //
struct T1 { short x:1; }; //
struct T2 { int x:1; }; //
struct T3 { ubyte a,b,c,d; long x:1; }; //
struct T4 { ubyte a,b,c,d,e,f,g,h; long x:1; }; //
struct T5 { ubyte a,b,c,d,e,f,g; long x:1; }; //
struct S1 { long f:1; }; //
struct S2 { int x:1; int y:1; }; //
struct S3 { short c; int x:1; uint y:1; }; //
struct S4 { int x:1; short y:1; }; //
struct S5 { short x:1; int y:1; }; //
struct S6 { short x:1; short y:1; }; //
struct S7 { short x:1; int y:1; long z:1; }; //
struct S8 { ubyte a; ubyte b:1; short c:2; }; //
struct S8A { ubyte b:1; short c:2; }; //
struct S8B { ubyte a; short b:1; ubyte c:2; }; //
struct S8C { ubyte a; int b:1; }; //
struct S9 { ubyte a; ubyte b:2; short c:9; }; //
struct S10 { }; // sizeof differs from C treatment
struct S11 { int :0; }; // sizeof differs from C treatment
struct S12 { int :0; int x; }; //
struct S13 { uint x:12; uint x1:1; uint x2:1; uint x3:1; uint x4:1; int w; }; //
struct S14 { ubyte a; ubyte b:4; int c:30; }; //
struct S15 { ubyte a; ubyte b:2; int c:9; }; //
struct S16 { int :32; }; // sizeof differs from C treatment
struct S17 { int a:32; }; //
struct S18 { ubyte a; long :0; ubyte b; }; //
struct A0 { int a; long b:34, c:4; }; //
struct A1 { int a; uint b:11; int c; }; //
struct A2 { int a; uint b:11, c:5, d:16; //
int e; };
struct A3 { int a; uint b:11, c:5, :0, d:16; //
int e; };
struct A4 { int a:8; short b:7; //
uint c:29; };
struct A5 { ubyte a:7, b:2; }; //
struct A6 { ubyte a:7; short b:2; }; //
struct A7 { short a:8; int b:16; int c; //
ubyte d:7; };
struct A8 { short a:8; int b:16; int :0; //
ubyte c:7; };
struct A9 { ushort a:8; int b:16; //
uint c:29; long d:9;
uint e:2, f:31; };
struct A10 { ushort a:8; ubyte b; }; //
struct A11 { ubyte a; int b:5, c:11, :0, d:8; //
struct { int ee:8; } };
int main()
{
/* MS produces identical results for 32 and 64 bit compiles,
* DM is 32 bit only
*/
printf(" DM | MS | P32 | P64\n");
printf("T0 = %2d %d || 1 1 | 1 1 | 1 1 | 1 1\n", cast(int)T0.sizeof, cast(int)T0.alignof);
printf("T1 = %2d %d || 2 2 | 2 2 | 2 2 | 2 2\n", cast(int)T1.sizeof, cast(int)T1.alignof);
printf("T2 = %2d %d || 4 4 | 4 4 | 4 4 | 4 4\n", cast(int)T2.sizeof, cast(int)T2.alignof);
printf("T3 = %2d %d || 16 8 | 16 8 | 8 4 | 8 8\n", cast(int)T3.sizeof, cast(int)T3.alignof);
printf("T4 = %2d %d || 16 8 | 16 8 | 12 4 | 16 8\n", cast(int)T4.sizeof, cast(int)T4.alignof);
printf("T5 = %2d %d || 16 8 | 16 8 | 8 4 | 8 8\n", cast(int)T5.sizeof, cast(int)T5.alignof);
printf("S1 = %2d %d || 8 8 | 8 8 | 4 4 | 8 8\n", cast(int)S1.sizeof, cast(int)S1.alignof);
printf("S2 = %2d %d || 4 4 | 4 4 | 4 4 | 4 4\n", cast(int)S2.sizeof, cast(int)S2.alignof);
printf("S3 = %2d %d || 8 4 | 8 4 | 4 4 | 4 4\n", cast(int)S3.sizeof, cast(int)S3.alignof);
printf("S4 = %2d %d || 8 4 | 8 4 | 4 4 | 4 4\n", cast(int)S4.sizeof, cast(int)S4.alignof);
printf("S5 = %2d %d || 8 4 | 8 4 | 4 4 | 4 4\n", cast(int)S5.sizeof, cast(int)S5.alignof);
printf("S6 = %2d %d || 2 2 | 2 2 | 2 2 | 2 2\n", cast(int)S6.sizeof, cast(int)S6.alignof);
printf("S7 = %2d %d || 16 8 | 16 8 | 4 4 | 8 8\n", cast(int)S7.sizeof, cast(int)S7.alignof);
printf("S8 = %2d %d || 4 2 | 4 2 | 2 2 | 2 2\n", cast(int)S8.sizeof, cast(int)S8.alignof);
printf("S8A = %2d %d || 4 2 | 4 2 | 2 2 | 2 2\n", cast(int)S8A.sizeof, cast(int)S8A.alignof);
printf("S8B = %2d %d || 6 2 | 6 2 | 2 2 | 2 2\n", cast(int)S8B.sizeof, cast(int)S8B.alignof);
printf("S8C = %2d %d || 8 4 | 8 4 | 4 4 | 4 4\n", cast(int)S8C.sizeof, cast(int)S8C.alignof);
printf("S9 = %2d %d || 4 2 | 4 2 | 4 2 | 4 2\n", cast(int)S9.sizeof, cast(int)S9.alignof);
printf("S10 = %2d %d || 0 0 | * * | 0 1 | 0 1\n", cast(int)S10.sizeof, cast(int)S10.alignof); // MS doesn't compile
printf("S11 = %2d %d || 0 0 | 4 1 | 0 1 | 0 1\n", cast(int)S11.sizeof, cast(int)S11.alignof);
printf("S12 = %2d %d || 4 4 | 4 4 | 4 4 | 4 4\n", cast(int)S12.sizeof, cast(int)S12.alignof);
printf("S13 = %2d %d || 8 4 | 8 4 | 8 4 | 8 4\n", cast(int)S13.sizeof, cast(int)S13.alignof);
printf("S14 = %2d %d || 8 4 | 8 4 | 8 4 | 8 4\n", cast(int)S14.sizeof, cast(int)S14.alignof);
printf("S15 = %2d %d || 8 4 | 8 4 | 4 4 | 4 4\n", cast(int)S15.sizeof, cast(int)S15.alignof);
printf("S16 = %2d %d || 0 0 | 4 4 | 4 1 | 4 1\n", cast(int)S16.sizeof, cast(int)S16.alignof);
printf("S17 = %2d %d || 4 4 | 4 4 | 4 4 | 4 4\n", cast(int)S17.sizeof, cast(int)S17.alignof);
printf("S18 = %2d %d || 2 1 | 2 1 | 5 1 | 9 1\n", cast(int)S18.sizeof, cast(int)S18.alignof);
printf("A0 = %2d %d || 16 8 | 16 8 | 12 4 | 16 8\n", cast(int)A0.sizeof, cast(int)A0.alignof);
printf("A1 = %2d %d || 12 4 | 12 4 | 12 4 | 12 4\n", cast(int)A1.sizeof, cast(int)A1.alignof);
printf("A2 = %2d %d || 12 4 | 12 4 | 12 4 | 12 4\n", cast(int)A2.sizeof, cast(int)A2.alignof);
printf("A3 = %2d %d || 16 4 | 16 4 | 16 4 | 16 4\n", cast(int)A3.sizeof, cast(int)A3.alignof);
printf("A4 = %2d %d || 12 4 | 12 4 | 8 4 | 8 4\n", cast(int)A4.sizeof, cast(int)A4.alignof);
printf("A5 = %2d %d || 2 1 | 2 1 | 2 1 | 2 1\n", cast(int)A5.sizeof, cast(int)A5.alignof);
printf("A6 = %2d %d || 4 2 | 4 2 | 2 2 | 2 2\n", cast(int)A6.sizeof, cast(int)A6.alignof);
printf("A7 = %2d %d || 16 4 | 16 4 | 12 4 | 16 8\n", cast(int)A7.sizeof, cast(int)A7.alignof);
printf("A8 = %2d %d || 12 4 | 12 4 | 8 4 | 8 8\n", cast(int)A8.sizeof, cast(int)A8.alignof);
printf("A9 = %2d %d || 32 8 | 32 8 | 16 4 | 16 8\n", cast(int)A9.sizeof, cast(int)A9.alignof);
printf("A10 = %2d %d || 4 2 | 4 2 | 2 2 | 2 2\n", cast(int)A10.sizeof, cast(int)A10.alignof);
printf("A11 = %2d %d || 16 4 | 16 4 | 12 4 | 12 4\n", cast(int)A11.sizeof, cast(int)A11.alignof);
{
S9 s;
uint x;
*cast(uint *)&s = 0;
s.b = 2; s.c = 3;
x = *cast(uint *)&s;
printf("S9 = x%x\n", x);
}
{
S14 s = { 1, 2, 3 };
ulong v;
*cast(long *)&s = 0;
s.a = 1;
s.b = 2;
s.c = 3;
v = *cast(ulong *)&s;
printf("S14 = x%llx\n", v);
}
{
S15 s = { 1,2,3 };
uint x;
*cast(uint *)&s = 0;
s.a = 1; s.b = 2; s.c = 3;
x = *cast(uint *)&s;
printf("S15 = x%x\n", x);
}
{
S18 s;
printf("S18 = %d should be %d\n", cast(int)(&s.b - &s.a), is64bit() ? 8 : 4);
}
{
A0 s;
long x;
*cast(long *)&s = 0;
s.a = 1; s.b = 15;
x = *cast(long *)&s;
printf("A0 = x%llx\n", x);
}
return 0;
}

View file

@ -5,10 +5,10 @@ PERMUTE_ARGS:
ARG_SETS: -version=Single
ARG_SETS: -version=Double
ARG_SETS(win32mscoff windows64): -version=Extended ../src/dmd/root/longdouble.d
ARG_SETS(win32mscoff windows64): -version=ExtendedSoft ../src/dmd/root/longdouble.d
ARG_SETS(windows): -version=Extended ../src/dmd/root/longdouble.d
ARG_SETS(windows): -version=ExtendedSoft ../src/dmd/root/longdouble.d
ARG_SETS(linux osx win32): -version=Extended
ARG_SETS(linux osx): -version=Extended
*/
module test.runnable.paranoia;

View file

@ -3,9 +3,6 @@
// COMDAT folding increases runtime by > 80x
// REQUIRED_ARGS(windows): -L/OPT:NOICF
// Apparently omf or optlink does not support more than 32767 symbols.
// DISABLED: win32
// Generate \sum_{i=0}^{14} 2^i = 32767 template instantiations
// (each with 3 sections) to use more than 64Ki sections in total.

View file

@ -1,4 +1,4 @@
// DISABLED: win32mscoff win64 freebsd
// DISABLED: win freebsd
// https://issues.dlang.org/show_bug.cgi?id=23886

View file

@ -8,9 +8,6 @@
// N.B MSVC doesn't have a C++11 switch, but it defaults to the latest fully-supported standard
// Broken for unknown reasons since the OMF => MsCOFF switch
// DISABLED: win32omf
import core.stdc.stdio;
import core.stdc.stdarg;
import core.stdc.config;

View file

@ -90,14 +90,10 @@ void runCPPTests()
int (C2::*fp1)(int) = &C2::f1;
int (C2::*fp2)(int, int) = &C2::f2;
int (C2::*fp3)(int, int) = &C2::f3;
#ifndef __DMC__
int (C2::*fp4)(int, ...) = &C2::f4;
#endif
assert((c2->*(fp0))() == 100);
assert((c2->*(fp1))(1) == 101);
assert((c2->*(fp2))(20, 3) == 123);
assert((c2->*(fp3))(20, 3) == 123);
#ifndef __DMC__
assert((c2->*(fp4))(20, 3, 0) == 123);
#endif
}

View file

@ -10,9 +10,7 @@ namespace std
struct test19248 {int a;};
};
#ifdef __DMC__
// DMC doesn't support c++11
#elif defined (_MSC_VER) && _MSC_VER <= 1800
#if defined (_MSC_VER) && _MSC_VER <= 1800
// MSVC2013 doesn't support char16_t/char32_t
#else
#define TEST_UNICODE
@ -26,11 +24,7 @@ struct S18784
S18784::S18784(int n) : i(n) {}
#ifdef __DMC__ // DMC doesn't support c++11
template <class>
#else
template <class...>
#endif
struct SPack
{
int i;

View file

@ -374,9 +374,7 @@ wchar_t f13289_cpp_wchar_t(wchar_t ch)
return ch;
}
}
#ifdef __DMC__
// DMC doesn't support c++11
#elif defined (_MSC_VER) //&& _MSC_VER <= 1800
#if defined (_MSC_VER) //&& _MSC_VER <= 1800
// MSVC2013 doesn't support char16_t/char32_t
#else
#define TEST_UNICODE

View file

@ -426,7 +426,6 @@ namespace foo
}
}
#ifndef __DMC__ // DMC doesn't support c++11
template<typename ...T> void foovargs(T... args);
void test40()
@ -446,4 +445,3 @@ void test41()
make_shared_poc<int, int, int>(a, b);
}
#endif

View file

@ -1,6 +1,3 @@
#if defined(__DMC__) // DMC doesn't support immintrin.h
#else
#include <assert.h>
// Inline the typedef of __m128 instead of including immintrin.h.
@ -30,5 +27,3 @@ void test20652(const __m128& a)
assert(b.array[2] == 1);
assert(b.array[3] == 1);
}
#endif

View file

@ -60,8 +60,8 @@ void usage()
~ " ARGS: set to execute all combinations of\n"
~ " REQUIRED_ARGS: arguments always passed to the compiler\n"
~ " DMD: compiler to use, ex: ../src/dmd (required)\n"
~ " CC: C compiler to use, ex: dmc, cc\n"
~ " CXX: C++ compiler to use, ex: dmc, g++\n"
~ " CC: C compiler to use, ex: cl, cc\n"
~ " CXX: C++ compiler to use, ex: cl, g++\n"
~ " OS: windows, linux, freebsd, osx, netbsd, dragonflybsd\n"
~ " RESULTS_DIR: base directory for test results\n"
~ " MODEL: 32 or 64 (required)\n"
@ -175,15 +175,6 @@ immutable(EnvData) processEnvironment()
envData.ccompiler = environment.get("CC");
envData.cxxcompiler = environment.get("CXX");
envData.model = envGetRequired("MODEL");
if (envData.os == "windows" && envData.model == "32")
{
// FIXME: we need to translate the default 32-bit model (COFF) on Windows to legacy `32mscoff`.
// Reason: OMF-specific tests are currently specified like this:
// DISABLED: win32mscoff win64 …
// and `DISABLED: win32` would disable it for `win32omf` too.
// So we'd need something like an `ENABLED: win32omf` parameter to restrict tests to specific platforms.
envData.model = "32mscoff";
}
envData.required_args = environment.get("REQUIRED_ARGS");
envData.dobjc = environment.get("D_OBJC") == "1";
envData.coverage_build = environment.get("DMD_TEST_COVERAGE") == "1";
@ -196,35 +187,17 @@ immutable(EnvData) processEnvironment()
if (envData.ccompiler.empty)
{
if (envData.os != "windows")
envData.ccompiler = "cc";
else if (envData.model == "32omf")
envData.ccompiler = "dmc";
else if (envData.model == "64")
envData.ccompiler = "cl";
else if (envData.model == "32mscoff")
if (envData.os == "windows")
envData.ccompiler = "cl";
else
{
writeln("Can't determine C compiler (CC). Unknown $OS$MODEL combination: ", envData.os, envData.model);
throw new SilentQuit();
}
envData.ccompiler = "cc";
}
if (envData.cxxcompiler.empty)
{
if (envData.os != "windows")
envData.cxxcompiler = "c++";
else if (envData.model == "32omf")
envData.cxxcompiler = "dmc";
else if (envData.model == "64")
envData.cxxcompiler = "cl";
else if (envData.model == "32mscoff")
if (envData.os == "windows")
envData.cxxcompiler = "cl";
else
{
writeln("Can't determine C++ compiler (CXX). Unknown $OS$MODEL combination: ", envData.os, envData.model);
throw new SilentQuit();
}
envData.cxxcompiler = "c++";
}
version (Windows) {} else
@ -547,9 +520,7 @@ private bool consumeNextToken(ref string file, const string token, ref const Env
file = file.stripLeft!(ch => ch == ' '); // Don't read line breaks
// Check if the current environment matches an entry in oss, which can either
// be an OS (e.g. "linux") or a combination of OS + MODEL (e.g. "windows32omf").
// The latter is important on windows because m32omf might require other
// parameters than m32mscoff/m64.
// be an OS (e.g. "linux") or a combination of OS + MODEL (e.g. "windows32").
if (!oss.canFind!(o => o.skipOver(envData.os) && (o.empty || o == envData.model)))
continue; // Parameter was skipped
}
@ -646,9 +617,8 @@ string getDisabledReason(string[] disabledPlatforms, const ref EnvData envData)
unittest
{
immutable EnvData win32omf = { os: "windows", model: "32omf" };
immutable EnvData win32mscoff = { os: "windows", model: "32mscoff" };
immutable EnvData win64 = { os: "windows", model: "64" };
immutable EnvData win32 = { os: "windows", model: "32" };
immutable EnvData win64 = { os: "windows", model: "64" };
assert(getDisabledReason(null, win64) is null);
@ -658,11 +628,8 @@ unittest
assert(getDisabledReason([ "linux", "win64" ], win64) == "on win64");
assert(getDisabledReason([ "linux", "win32" ], win64) is null);
assert(getDisabledReason([ "win32mscoff" ], win32mscoff) == "on win32mscoff");
assert(getDisabledReason([ "win32mscoff" ], win32omf) is null);
assert(getDisabledReason([ "win32" ], win32mscoff) == "on win32");
assert(getDisabledReason([ "win32" ], win32omf) == "on win32");
assert(getDisabledReason([ "win32" ], win32) == "on win32");
assert(getDisabledReason([ "win32" ], win64) is null);
}
/**
* Reads the test configuration from the source code (using `findTestParameter` and
@ -1126,11 +1093,7 @@ bool collectExtraSources (in string input_dir, in string output_dir, in string[]
auto curObj = output_dir ~ envData.sep ~ cur ~ envData.obj;
bool is_cpp_file = cur.extension() == ".cpp";
string command = quoteSpaces(is_cpp_file ? cxxcompiler : ccompiler);
if (envData.model == "32omf") // dmc.exe
{
command ~= " -c "~curSrc~" -o"~curObj;
}
else if (envData.os == "windows") // cl.exe
if (envData.os == "windows") // cl.exe
{
command ~= ` /c /nologo `~curSrc~` /Fo`~curObj;
}
@ -1413,8 +1376,8 @@ bool compareOutput(string output, string refoutput, const ref EnvData envData)
toSkip = chunk;
break;
}
// Match against OS or model (accepts "32mscoff" as "32")
else if (searchResult[0].splitter('+').all!(c => c.among(envData.os, envData.model, envData.model[0 .. min(2, $)])))
// Match against OS or model
else if (searchResult[0].splitter('+').all!(c => c.among(envData.os, envData.model)))
{
toSkip = searchResult[2];
break;
@ -1487,7 +1450,7 @@ unittest
const emptyFmt = "On <$?:windows=abc|$> use <$?:posix=$>!";
assert(compareOutput("On <> use <>!", emptyFmt, ed));
ed.model = "32mscoff";
ed.model = "32";
assert(compareOutput("size_t is uint!", "size_t is $?:32=uint|64=ulong$!", ed));
assert(compareOutput("no", "$?:posix+64=yes|no$", ed));
@ -1872,11 +1835,10 @@ int tryMain(string[] args)
{
toCleanup ~= test_app_dmd;
version(Windows)
if (envData.model != "32omf")
{
toCleanup ~= test_app_dmd_base ~ to!string(permuteIndex) ~ ".ilk";
toCleanup ~= test_app_dmd_base ~ to!string(permuteIndex) ~ ".pdb";
}
{
toCleanup ~= test_app_dmd_base ~ to!string(permuteIndex) ~ ".ilk";
toCleanup ~= test_app_dmd_base ~ to!string(permuteIndex) ~ ".pdb";
}
if (testArgs.gdbScript is null)
{

View file

@ -36,8 +36,8 @@ else
export SOEXT=.so
fi
# Default to DigitalMars C++ on Win32
if [ "$OS" == "win32" ] && [ -z "${CC+set}" ] ; then
CC="dmc"
# Default to Microsoft cl on Windows
if [[ "$OS" == "win"* && -z "${CC+set}" ]] ; then
CC="cl"
fi
export CC="${CC:-c++}" # C++ compiler to use

View file

@ -259,6 +259,7 @@ string[] buildCmdArgs(string runnerPath, string outputPath, const string[] testF
"-version=NoMain",
"-version=MARS",
"-version=DMDLIB",
"-g",
"-unittest",
"-J" ~ buildOutputPath,
"-Jsrc/dmd/res",
@ -277,10 +278,6 @@ string[] buildCmdArgs(string runnerPath, string outputPath, const string[] testF
if (environment.get("DMD_TEST_COVERAGE", "0") == "1")
flags ~= "-cov";
// older versions of Optlink causes: "Error 45: Too Much DEBUG Data for Old CodeView format"
if (!usesOptlink)
flags ~= "-g";
return flags;
}
@ -306,15 +303,6 @@ bool missingTestFiles(Range)(Range givenFiles)
return false;
}
bool usesOptlink()
{
version (DigitalMars)
return os == "windows" && model == "32";
else
return false;
}
int main(string[] args)
{
string unitTestFilter;

View file

@ -375,10 +375,7 @@ $(abspath ../generated/$(OS)/$(BUILD)/$(MODEL)/dmd$(DOTEXE)): ../generated/$(OS)
################### C/ASM Targets ############################
OBJS:=$(ROOT)/errno_c$(DOTOBJ)
ifeq (32omf,$(MODEL))
# minit.asm is only used for -m32omf on Windows; there's a pre-built minit.obj
OBJS+=src/rt/minit$(DOTOBJ)
else ifneq (windows,$(OS))
ifneq (windows,$(OS))
OBJS+=$(ROOT)/threadasm$(DOTOBJ) $(ROOT)/valgrind$(DOTOBJ)
endif
@ -434,12 +431,7 @@ endif
.PHONY : unittest
ifeq (1,$(BUILD_WAS_SPECIFIED))
ifeq (32omf,$(MODEL))
unittest :
@echo "Skipping druntime unittests because they cannot be linked on Win32 + OMF due to OPTLINK issues."
else
unittest : $(UT_MODULES) $(addsuffix /.run,$(ADDITIONAL_TESTS))
endif
else
unittest : unittest-debug unittest-release
unittest-%: target
@ -519,7 +511,7 @@ benchmark-compile-only: $(ROOT)/benchmark$(DOTEXE) $(DMD)
MANIFEST = $(shell git ls-tree --name-only -r HEAD)
CWS_MAKEFILES = $(filter mak/% %.mak %/Makefile,$(MANIFEST))
NOT_MAKEFILES = $(filter-out $(CWS_MAKEFILES) src/rt/minit.obj test/%.exp,$(MANIFEST))
NOT_MAKEFILES = $(filter-out $(CWS_MAKEFILES) test/%.exp,$(MANIFEST))
GREP = grep
checkwhitespace:

View file

@ -339,34 +339,6 @@ private:
}
// Workaround OPTLINK bug (Bugzilla 8263)
extern(Windows) BOOL FixupDebugHeader(HANDLE hProcess, ULONG ActionCode,
ulong CallbackContext, ulong UserContext)
{
if (ActionCode == CBA_READ_MEMORY)
{
auto p = cast(IMAGEHLP_CBA_READ_MEMORY*)CallbackContext;
if (!(p.addr & 0xFF) && p.bytes == 0x1C &&
// IMAGE_DEBUG_DIRECTORY.PointerToRawData
(*cast(DWORD*)(p.addr + 24) & 0xFF) == 0x20)
{
immutable base = DbgHelp.get().SymGetModuleBase64(hProcess, p.addr);
// IMAGE_DEBUG_DIRECTORY.AddressOfRawData
if (base + *cast(DWORD*)(p.addr + 20) == p.addr + 0x1C &&
*cast(DWORD*)(p.addr + 0x1C) == 0 &&
*cast(DWORD*)(p.addr + 0x20) == ('N'|'B'<<8|'0'<<16|'9'<<24))
{
debug(PRINTF) printf("fixup IMAGE_DEBUG_DIRECTORY.AddressOfRawData\n");
memcpy(p.buf, cast(void*)p.addr, 0x1C);
*cast(DWORD*)(p.buf + 20) = cast(DWORD)(p.addr - base) + 0x20;
*p.bytesread = 0x1C;
return TRUE;
}
}
}
return FALSE;
}
private string generateSearchPath()
{
__gshared string[3] defaultPathList = ["_NT_SYMBOL_PATH",
@ -427,8 +399,6 @@ shared static this()
if (!dbghelp.SymInitialize(hProcess, generateSearchPath().ptr, TRUE))
return;
dbghelp.SymRegisterCallback64(hProcess, &FixupDebugHeader, 0);
InitializeCriticalSection(&mutex);
initialized = true;
}

View file

@ -11,20 +11,6 @@
module rt.alloca;
version (Posix)
{
version = alloca;
}
else version (CRuntime_Microsoft)
{
version = alloca;
}
// Use DMC++'s alloca() for Win32
version (alloca)
{
/*******************************************
* Allocate data from the caller's stack frame.
* This is a 'magic' function that needs help from the compiler to
@ -215,5 +201,3 @@ extern (C) void* __alloca(int nbytes)
else
static assert(0);
}
}

View file

@ -1,114 +0,0 @@
;_ minit.asm
; Module initialization support.
;
; Copyright: Copyright Digital Mars 2000 - 2010.
; License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
; Authors: Walter Bright
;
; Copyright Digital Mars 2000 - 2010.
; Distributed under the Boost Software License, Version 1.0.
; (See accompanying file LICENSE or copy at
; http://www.boost.org/LICENSE_1_0.txt)
;
; With VC installed, build with:
; ml /omf minit.asm
.model FLAT
ifdef _WIN32
DATAGRP EQU FLAT
else
DATAGRP EQU DGROUP
endif
; Provide a default resolution for weak extern records, no way in C
; to define an omf symbol with a specific value
public __nullext
__nullext equ 0
extrn __moduleinfo_array:near
; This bit of assembler is needed because, from C or D, one cannot
; specify the names of data segments. Why does this matter?
; All the ModuleInfo pointers are placed into a segment named 'FM'.
; The order in which they are placed in 'FM' is arbitrarily up to the linker.
; In order to walk all the pointers, we need to be able to find the
; beginning and the end of the 'FM' segment.
; This is done by bracketing the 'FM' segment with two other, empty,
; segments named 'FMB' and 'FME'. Since this module is the only one that
; ever refers to 'FMB' and 'FME', we get to control the order in which
; these segments appear relative to 'FM' by using a GROUP statement.
; So, we have in memory:
; FMB empty segment
; FM contains all the pointers
; FME empty segment
; and finding the limits of FM is as easy as taking the address of FMB
; and the address of FME.
; These segments bracket FM, which contains the list of ModuleInfo pointers
FMB segment dword use32 public 'DATA'
FMB ends
FM segment dword use32 public 'DATA'
FM ends
FME segment dword use32 public 'DATA'
FME ends
; This leaves room in the _fatexit() list for _moduleDtor()
XOB segment dword use32 public 'BSS'
XOB ends
XO segment dword use32 public 'BSS'
dd ?
XO ends
XOE segment dword use32 public 'BSS'
XOE ends
DGROUP group FMB,FM,FME
; These segments bracket DP, which contains the _DATA pointer references
public __DPbegin, __DPend
DPB segment dword use32 public 'CODE'
__DPbegin:
DPB ends
DP segment dword use32 public 'CODE'
DP ends
DPE segment dword use32 public 'CODE'
__DPend:
DPE ends
CGROUP group DPB,DP,DPE
; These segments bracket TP, which contains the TLS pointer references
public __TPbegin, __TPend
TPB segment dword use32 public 'CODE'
__TPbegin:
TPB ends
TP segment dword use32 public 'CODE'
TP ends
TPE segment dword use32 public 'CODE'
__TPend:
TPE ends
CGROUP group TPB,TP,TPE
_TEXT segment para use32 public 'CODE'
assume CS:_TEXT
; extern (C) void _minit();
; Converts array of ModuleInfo pointers to a D dynamic array of them,
; so they can be accessed via D.
; Result is written to:
; extern (C) ModuleInfo[] _moduleinfo_array;
public __minit
__minit:
mov EDX,offset DATAGRP:FMB
mov EAX,offset DATAGRP:FME
mov dword ptr __moduleinfo_array+4,EDX
sub EAX,EDX ; size in bytes of FM segment
shr EAX,2 ; convert to array length
mov dword ptr __moduleinfo_array,EAX
ret
_TEXT ends
end

Binary file not shown.

View file

@ -134,14 +134,12 @@ subPackage {
libelf,\
libmach,\
libmscoff,\
libomf,\
link,\
objc_glue,\
s2ir,\
scanelf,\
scanmach,\
scanmscoff,\
scanomf,\
tocsym,\
toctype,\
tocvdebug,\