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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions std/digest/sha.d
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,14 @@ unittest
hash1 = sha1.finish();
}

version(D_PIC)
{
// Do not use (Bug9378).
}
else version(Win64)
version(Win64)
{
// wrong calling convention
}
else version(D_InlineAsm_X86)
{
private version = USE_SSSE3;
version (D_PIC) {} // Bugzilla 9378
else private version = USE_SSSE3;
}
else version(D_InlineAsm_X86_64)
{
Expand Down Expand Up @@ -216,11 +213,20 @@ struct SHA(uint hashBlockSize, uint digestSize)
version(USE_SSSE3)
{
import core.cpuid : ssse3;
import std.internal.digest.sha_SSSE3 : transformSSSE3;
import std.internal.digest.sha_SSSE3 : sse3_constants=constants, transformSSSE3;

static void transform(uint[5]* state, const(ubyte[64])* block) pure nothrow @nogc
{
return ssse3 ? transformSSSE3(state, block) : transformX86(state, block);
if (ssse3)
{
version (D_InlineAsm_X86_64)
// constants as extra argument for PIC, see Bugzilla 9378
transformSSSE3(state, block, &sse3_constants);
else
transformSSSE3(state, block);
}
else
transformX86(state, block);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shoud we worry that this is not covered?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's run as part of the 32-bit shared library test suite (b/c that is still PIC incompatible).

}
}
else
Expand Down
64 changes: 41 additions & 23 deletions std/internal/digest/sha_SSSE3.d
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
*/
module std.internal.digest.sha_SSSE3;

version(D_PIC)
version(D_InlineAsm_X86)
{
// Do not use (Bug9378).
}
else version(D_InlineAsm_X86)
{
private version = USE_SSSE3;
private version = _32Bit;
version (D_PIC) {} // Bugzilla 9378
else
{
private version = USE_SSSE3;
private version = _32Bit;
}
}
else version(D_InlineAsm_X86_64)
{
Expand Down Expand Up @@ -108,6 +108,7 @@ version(USE_SSSE3)
private immutable string SP = "RSP";
private immutable string BUFFER_PTR = "R9";
private immutable string STATE_PTR = "R8";
private immutable string CONSTANTS_PTR = "R10";

// Registers for temporary results (XMM10 and XMM11 are also used temporary)
private immutable string W_TMP = "XMM8";
Expand All @@ -120,15 +121,11 @@ version(USE_SSSE3)
private immutable string X_CONSTANT = "XMM13";
}

/* The control words for the byte shuffle instruction. */
align(16) private immutable uint[4] bswap_shufb_ctl =
[
0x0001_0203, 0x0405_0607, 0x0809_0a0b, 0x0c0d_0e0f
];

/* The round constants. */
align(16) private immutable uint[16] constants =
/* The control words for the byte shuffle instruction and the round constants. */
align(16) public immutable uint[20] constants =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why public?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's passed to the asm function from std.digest.sha, because it's not possible to access globals in PIC code from asm. That's the fix!

[
// The control words for the byte shuffle instruction.
0x0001_0203, 0x0405_0607, 0x0809_0a0b, 0x0c0d_0e0f,
// Constants for round 0-19
0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
// Constants for round 20-39
Expand All @@ -152,10 +149,22 @@ version(USE_SSSE3)
return s.idup;
}

/** Returns the reference to the byte shuffle control word. */
private nothrow pure string bswap_shufb_ctl()
{
version (_64Bit)
return "["~CONSTANTS_PTR~"]";
else
return "[constants]";
}

/** Returns the reference to constant used in round i. */
private nothrow pure string constant(uint i)
{
return "[constants + 16*"~to_string(i/20)~"]";
version (_64Bit)
return "16 + 16*"~to_string(i/20)~"["~CONSTANTS_PTR~"]";
else
return "[constants + 16 + 16*"~to_string(i/20)~"]";
}

/** Returns the XMM register number used in round i */
Expand Down Expand Up @@ -304,9 +313,9 @@ version(USE_SSSE3)
{
if (i == 0)
{
return swt3264(["movdqa "~X_SHUFFLECTL~",[bswap_shufb_ctl]",
return swt3264(["movdqa "~X_SHUFFLECTL~","~bswap_shufb_ctl(),
"movdqa "~X_CONSTANT~","~constant(i)],
["movdqa "~X_SHUFFLECTL~",[bswap_shufb_ctl]",
["movdqa "~X_SHUFFLECTL~","~bswap_shufb_ctl(),
"movdqa "~X_CONSTANT~","~constant(i)]);
}
version(_64Bit)
Expand Down Expand Up @@ -589,8 +598,9 @@ version(USE_SSSE3)
{
/*
* Parameters:
* RSI contains pointer to state
* RDI contains pointer to input buffer
* RDX contains pointer to state
* RSI contains pointer to input buffer
* RDI contains pointer to constants
*
* Stack layout as follows:
* +----------------+
Expand All @@ -610,8 +620,9 @@ version(USE_SSSE3)
"push RBP",
"push RBX",
// Save parameters
"mov "~STATE_PTR~", RSI", //pointer to state
"mov "~BUFFER_PTR~", RDI", //pointer to buffer
"mov "~STATE_PTR~", RDX", //pointer to state
"mov "~BUFFER_PTR~", RSI", //pointer to buffer
"mov "~CONSTANTS_PTR~", RDI", //pointer to constants to avoid absolute addressing
// Align stack
"sub RSP, 4*16+8",
];
Expand Down Expand Up @@ -643,10 +654,17 @@ version(USE_SSSE3)
}
}

// constants as extra argument for PIC, see Bugzilla 9378
import std.meta : AliasSeq;
version (_64Bit)
alias ExtraArgs = AliasSeq!(typeof(&constants));
else
alias ExtraArgs = AliasSeq!();

/**
*
*/
public void transformSSSE3(uint[5]* state, const(ubyte[64])* buffer) pure nothrow @nogc
public void transformSSSE3(uint[5]* state, const(ubyte[64])* buffer, ExtraArgs) pure nothrow @nogc
{
mixin(wrap(["naked;"] ~ prologue()));
// Precalc first 4*16=64 bytes
Expand Down