Skip to content

Commit

Permalink
Use CMAKE 3.9 property to enable LTCG instead of manual options.
Browse files Browse the repository at this point in the history
Link with full warnings, and warnings as errors, on both clang and cl.
Enable fast optimizations on clang builds too.
Compile with permissive- on VS for standards confirmance
Remove #pragmas
Remove linker garbage that VS adds
Build the DLL as a driver so that it has the correct non-paged pool flags and can be used in KM
Remove global variable pointers and leverage global structures directly. This has the side effect of removing the need for any initialized .data section, as well as removing .reloc completely.
Remove full PDB name of my computer :)
Remove manifest in DLL for kernel compatibility
Remove usage of unused unions and structure names.
Define __security_check_cookie to make CL happy -- there are no stack buffers at all, and linking with BufferOverflowU.lib simply adds 4KB of UM code that is not called by anything. This also removes the need for an import directory and makes the DLL usable in kernel-mode.
  • Loading branch information
Alex Ionescu committed Apr 18, 2020
1 parent 3341bf2 commit 2df7adf
Show file tree
Hide file tree
Showing 12 changed files with 166 additions and 168 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required (VERSION 3.8)
cmake_minimum_required (VERSION 3.9)
project (minlzma)

add_subdirectory(minlzlib)
Expand Down
8 changes: 6 additions & 2 deletions minlzdec/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ target_link_libraries(minlzdec LINK_PUBLIC minlzlib)

if(MSVC)
set(CMAKE_C_STANDARD_LIBRARIES "")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/Ox /Ob2 /Oi /Ot /Oy /GF /GL /Gy /MT /Zi /DNDEBUG")
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/LTCG /INCREMENTAL:NO /OPT:ICF /OPT:REF /DEBUG")
set_property(TARGET minlzdec PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/WX /Ox /Ob2 /Oi /Ot /Oy /GF /Gy /MT /Zi /permissive-")
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/OPT:ICF /OPT:REF /DEBUG /EMITPOGOPHASEINFO /NOVCFEATURE /NOCOFFGRPINFO /PDBALTPATH:minlzdec.pdb")
else()
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Ofast -Wall -Werror")
endif()
15 changes: 9 additions & 6 deletions minlzlib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
cmake_minimum_required (VERSION 3.8)

set(MINLZLIB_SOURCES "inputbuf.c" "dictbuf.c" "lzma2dec.c" "lzmadec.c" "rangedec.c" "xzstream.c" "lzmadec.h" "xzstream.h" "minlzlib.h")
set(MINLZLIB_SOURCES "inputbuf.c" "dictbuf.c" "lzma2dec.c" "lzmadec.c" "rangedec.c" "xzstream.c" "lzmadec.h" "xzstream.h" "minlzlib.h")
add_library(minlz_obj OBJECT ${MINLZLIB_SOURCES})
set_target_properties(minlz_obj PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED YES C_EXTENSIONS NO)

Expand All @@ -13,7 +11,12 @@ target_include_directories (minlz_obj PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

if(MSVC)
set(CMAKE_C_STANDARD_LIBRARIES "")
target_link_libraries(minlz BufferOverflowU kernel32)
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/Ox /Ob2 /Oi /Ot /Oy /GF /GL /Gy /MT /Zi")
set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "/LTCG /INCREMENTAL:NO /OPT:ICF /OPT:REF /NODEFAULTLIB /NOENTRY /DEBUG /EXPORT:XzDecode")
target_link_libraries(minlz)
set_property(TARGET minlz_obj PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
set_property(TARGET minlz PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/WX /Ox /Ob2 /Oi /Ot /Oy /GF /Gy /MT /Zi /wd4214 /permissive-")
set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "/OPT:ICF /OPT:REF /NODEFAULTLIB /NOENTRY /DEBUG /EXPORT:XzDecode /EMITPOGOPHASEINFO /NOVCFEATURE /NOCOFFGRPINFO /DRIVER /MANIFEST:NO /PDBALTPATH:minlz.pdb /MERGE:.edata=.rdata")
else()
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Ofast -Wall -Werror")
endif()
31 changes: 15 additions & 16 deletions minlzlib/dictbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ typedef struct _DICTIONARY_STATE
uint32_t Limit;
uint32_t Size;
} DICTIONARY_STATE, *PDICTIONARY_STATE;
DICTIONARY_STATE g_Dictionary;
PDICTIONARY_STATE Dictionary = &g_Dictionary;
DICTIONARY_STATE Dictionary;

void
DtInitialize (
Expand All @@ -54,9 +53,9 @@ DtInitialize (
//
// Initialize the buffer and reset the position
//
Dictionary->Buffer = HistoryBuffer;
Dictionary->Offset = 0;
Dictionary->Size = Size;
Dictionary.Buffer = HistoryBuffer;
Dictionary.Offset = 0;
Dictionary.Size = Size;
}

bool
Expand All @@ -68,12 +67,12 @@ DtSetLimit (
// Make sure that the passed in dictionary limit fits within the size, and
// then set this as the new limit. Save the starting point (current offset)
//
if ((Dictionary->Offset + Limit) > Dictionary->Size)
if ((Dictionary.Offset + Limit) > Dictionary.Size)
{
return false;
}
Dictionary->Limit = Dictionary->Offset + Limit;
Dictionary->Start = Dictionary->Offset;
Dictionary.Limit = Dictionary.Offset + Limit;
Dictionary.Start = Dictionary.Offset;
return true;
}

Expand All @@ -85,8 +84,8 @@ DtIsComplete (
//
// Return bytes processed and if the dictionary has been fully written to
//
*BytesProcessed = Dictionary->Offset - Dictionary->Start;
return (Dictionary->Offset == Dictionary->Limit);
*BytesProcessed = Dictionary.Offset - Dictionary.Start;
return (Dictionary.Offset == Dictionary.Limit);
}

bool
Expand All @@ -97,8 +96,8 @@ DtCanWrite (
//
// Return our position and make sure it's not beyond the uncompressed size
//
*Position = Dictionary->Offset;
return (Dictionary->Offset < Dictionary->Limit);
*Position = Dictionary.Offset;
return (Dictionary.Offset < Dictionary.Limit);
}

uint8_t
Expand All @@ -110,11 +109,11 @@ DtGetSymbol (
// If the dictionary is still empty, just return 0, otherwise, return the
// symbol that is Distance bytes backward
//
if (Distance > Dictionary->Offset)
if (Distance > Dictionary.Offset)
{
return 0;
}
return Dictionary->Buffer[Dictionary->Offset - Distance];
return Dictionary.Buffer[Dictionary.Offset - Distance];
}

void
Expand All @@ -125,7 +124,7 @@ DtPutSymbol (
//
// Write the symbol and advance our position
//
Dictionary->Buffer[Dictionary->Offset++] = Symbol;
Dictionary.Buffer[Dictionary.Offset++] = Symbol;
}

bool
Expand All @@ -138,7 +137,7 @@ DtRepeatSymbol (
// Make sure we never get asked to write past the end of the dictionary,
// then rewrite the stream of symbols forward into the dictionary
//
if ((Length + Dictionary->Offset) > Dictionary->Limit)
if ((Length + Dictionary.Offset) > Dictionary.Limit)
{
return false;
}
Expand Down
17 changes: 8 additions & 9 deletions minlzlib/inputbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ typedef struct _BUFFER_STATE
uint32_t Offset;
uint32_t Size;
} BUFFER_STATE, * PBUFFER_STATE;
BUFFER_STATE g_In;
PBUFFER_STATE In = &g_In;
BUFFER_STATE In;

bool
BfAlign (
Expand All @@ -51,7 +50,7 @@ BfAlign (
//
// Keep reading until we reach 32-bit alignment. All bytes must be zero.
//
while (In->Offset & 3)
while (In.Offset & 3)
{
if (!BfRead(&padByte) || (padByte != 0))
{
Expand All @@ -71,13 +70,13 @@ BfSeek (
// Make sure the input buffer has enough space to seek the desired size, if
// it does, return the current position and then seek past the desired size
//
if ((In->Offset + Length) > In->Size)
if ((In.Offset + Length) > In.Size)
{
*Bytes = 0;
return false;
}
*Bytes = &In->Buffer[In->Offset];
In->Offset += Length;
*Bytes = &In.Buffer[In.Offset];
In.Offset += Length;
return true;
}

Expand Down Expand Up @@ -108,7 +107,7 @@ BfInitialize (
//
// Save all the data in the context buffer state
//
In->Buffer = InputBuffer;
In->Size = InputSize;
In->Offset = 0;
In.Buffer = InputBuffer;
In.Size = InputSize;
In.Offset = 0;
}
29 changes: 14 additions & 15 deletions minlzlib/lzma2dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ typedef struct _CHUNK_STATE
uint32_t UncompressedSize;
uint16_t CompressedSize;
} CHUNK_STATE, * PCHUNK_STATE;
CHUNK_STATE g_ChunkState;
PCHUNK_STATE ChunkState = &g_ChunkState;
CHUNK_STATE ChunkState;

bool
Lz2DecodeChunk (
Expand All @@ -51,7 +50,7 @@ Lz2DecodeChunk (
//
// Make sure we always have space for the biggest possible LZMA sequence
//
if (ChunkState->CompressedSize < LZMA_MAX_SEQUENCE_SIZE)
if (ChunkState.CompressedSize < LZMA_MAX_SEQUENCE_SIZE)
{
return false;
}
Expand All @@ -70,7 +69,7 @@ Lz2DecodeChunk (
// exactly where we expected it to.
//
if (!RcIsComplete(&bytesProcessed) ||
(bytesProcessed != ChunkState->CompressedSize))
(bytesProcessed != ChunkState.CompressedSize))
{
return false;
}
Expand All @@ -80,7 +79,7 @@ Lz2DecodeChunk (
// must be full now.
//
if (!DtIsComplete(&bytesProcessed) ||
(bytesProcessed != ChunkState->UncompressedSize))
(bytesProcessed != ChunkState.UncompressedSize))
{
return false;
}
Expand Down Expand Up @@ -115,7 +114,7 @@ Lz2DecodeStream (
//
// We only support compressed streams, not uncompressed ones
//
if (controlByte.Common.IsLzma == 0)
if (controlByte.u.Common.IsLzma == 0)
{
break;
}
Expand All @@ -132,10 +131,10 @@ Lz2DecodeStream (
// Decode the 1-based big-endian uncompressed size. It must fit into
// the output buffer that was supplied.
//
ChunkState->UncompressedSize = controlByte.Lzma.UncompressedSize << 16;
ChunkState->UncompressedSize += (*pInfoBytes)[0] << 8;
ChunkState->UncompressedSize += (*pInfoBytes)[1] + 1;
if (!DtSetLimit(ChunkState->UncompressedSize))
ChunkState.UncompressedSize = controlByte.u.Lzma.UncompressedSize << 16;
ChunkState.UncompressedSize += (*pInfoBytes)[0] << 8;
ChunkState.UncompressedSize += (*pInfoBytes)[1] + 1;
if (!DtSetLimit(ChunkState.UncompressedSize))
{
break;
}
Expand All @@ -144,14 +143,14 @@ Lz2DecodeStream (
// Decode the 1-based big-endian compressed size. It must fit into the
// input buffer that was given, which RcInitialize will verify below.
//
ChunkState->CompressedSize = (*pInfoBytes)[2] << 8;
ChunkState->CompressedSize += (*pInfoBytes)[3] + 1;
ChunkState.CompressedSize = (*pInfoBytes)[2] << 8;
ChunkState.CompressedSize += (*pInfoBytes)[3] + 1;

//
// Check if the full LZMA state needs to be reset, which must happen at
// the start of stream. Other reset states are not supported.
//
if (controlByte.Lzma.ResetState == Lzma2FullReset)
if (controlByte.u.Lzma.ResetState == Lzma2FullReset)
{
//
// Read the LZMA properties and then initialize the decoder.
Expand All @@ -161,7 +160,7 @@ Lz2DecodeStream (
break;
}
}
else if (controlByte.Lzma.ResetState != Lzma2NoReset)
else if (controlByte.u.Lzma.ResetState != Lzma2NoReset)
{
break;
}
Expand All @@ -171,7 +170,7 @@ Lz2DecodeStream (
// coding decoder, and let it know how much input data exists. We've
// already validated that this much space exists in the input buffer.
//
if (!RcInitialize(&ChunkState->CompressedSize))
if (!RcInitialize(&ChunkState.CompressedSize))
{
break;
}
Expand Down
6 changes: 1 addition & 5 deletions minlzlib/lzma2dec.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,6 @@ typedef enum _LZMA2_COMPRESSED_RESET_STATE
//
// This describes how an LZMA2 control byte can be parsed
//
#pragma warning(push)
#pragma warning(disable:4201)
#pragma warning(disable:4214)
typedef union _LZMA2_CONTROL_BYTE
{
union
Expand All @@ -90,8 +87,7 @@ typedef union _LZMA2_CONTROL_BYTE
uint8_t ResetState : 2;
uint8_t IsLzma : 1;
} Common;
};
} u;
uint8_t Value;
} LZMA2_CONTROL_BYTE;
static_assert(sizeof(LZMA2_CONTROL_BYTE) == 1, "Invalid control byte size");
#pragma warning(pop)
Loading

0 comments on commit 2df7adf

Please sign in to comment.