mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00
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:
commit
ff14dc9385
57 changed files with 114 additions and 2297 deletions
|
@ -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
|
||||
################################################################################
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
LIBRARY dserver
|
||||
EXETYPE NT
|
||||
SUBSYSTEM WINDOWS
|
||||
EXPORTS
|
||||
DllGetClassObject = _DllGetClassObject@12
|
||||
DllCanUnloadNow = _DllCanUnloadNow@0
|
||||
DllRegisterServer = _DllRegisterServer@0
|
||||
DllUnregisterServer = _DllUnregisterServer@0
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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="))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 = ¶ms;
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// REQUIRED_ARGS: -g
|
||||
|
||||
// If this is failing, you need optlink 8.00.14 or higher
|
||||
|
||||
string gen()
|
||||
{
|
||||
string m;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// DISABLED: win32mscoff win64 freebsd
|
||||
// DISABLED: win freebsd
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23886
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
2
dub.sdl
2
dub.sdl
|
@ -134,14 +134,12 @@ subPackage {
|
|||
libelf,\
|
||||
libmach,\
|
||||
libmscoff,\
|
||||
libomf,\
|
||||
link,\
|
||||
objc_glue,\
|
||||
s2ir,\
|
||||
scanelf,\
|
||||
scanmach,\
|
||||
scanmscoff,\
|
||||
scanomf,\
|
||||
tocsym,\
|
||||
toctype,\
|
||||
tocvdebug,\
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue