2020-12-15 09:27:44 -04:00
|
|
|
// Copyright 2011-2020 Molecular Matters GmbH, all rights reserved.
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
|
2020-12-15 09:27:44 -04:00
|
|
|
// BEGIN EPIC MOD
|
|
|
|
|
//#include PCH_INCLUDE
|
|
|
|
|
// END EPIC MOD
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
#include "LC_Executable.h"
|
2020-12-15 09:27:44 -04:00
|
|
|
#include "LC_MemoryMappedFile.h"
|
|
|
|
|
// BEGIN EPIC MOD
|
|
|
|
|
#include "LC_Assert.h"
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
#include "LC_Logging.h"
|
|
|
|
|
#include <algorithm>
|
2020-12-15 09:27:44 -04:00
|
|
|
// END EPIC MOD
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
|
|
|
|
|
// this is the default DLL entry point, taken from the CRT. we don't need it, but can extract its signature.
|
|
|
|
|
extern "C" BOOL WINAPI _DllMainCRTStartup(
|
|
|
|
|
HINSTANCE const instance,
|
|
|
|
|
DWORD const reason,
|
|
|
|
|
LPVOID const reserved
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace detail
|
|
|
|
|
{
|
|
|
|
|
static inline bool SortSectionByAscendingRVA(const executable::ImageSection& lhs, const executable::ImageSection& rhs)
|
|
|
|
|
{
|
|
|
|
|
return lhs.rva < rhs.rva;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const IMAGE_NT_HEADERS* GetNtHeader(const executable::Image* image)
|
|
|
|
|
{
|
2020-12-15 09:27:44 -04:00
|
|
|
const void* base = Filesystem::GetMemoryMappedFileData(image);
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
|
|
|
|
|
// PE image start with a DOS header
|
2020-12-15 09:27:44 -04:00
|
|
|
const IMAGE_DOS_HEADER* dosHeader = static_cast<const IMAGE_DOS_HEADER*>(base);
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
|
|
|
|
{
|
2022-10-21 19:50:32 -04:00
|
|
|
LC_ERROR_USER("%s", "Image has unknown file format");
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-18 17:51:25 -04:00
|
|
|
const IMAGE_NT_HEADERS* ntHeader = pointer::Offset<const IMAGE_NT_HEADERS*>(dosHeader, dosHeader->e_lfanew);
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
if (ntHeader->Signature != IMAGE_NT_SIGNATURE)
|
|
|
|
|
{
|
2022-10-21 19:50:32 -04:00
|
|
|
LC_ERROR_USER("%s", "Invalid .exe file");
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ntHeader;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static IMAGE_NT_HEADERS* GetNtHeader(executable::Image* image)
|
|
|
|
|
{
|
|
|
|
|
return const_cast<IMAGE_NT_HEADERS*>(GetNtHeader(const_cast<const executable::Image*>(image)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const IMAGE_SECTION_HEADER* GetSectionHeader(const IMAGE_NT_HEADERS* ntHeader)
|
|
|
|
|
{
|
|
|
|
|
return IMAGE_FIRST_SECTION(ntHeader);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t executable::GetEntryPointRva(const Image* image)
|
|
|
|
|
{
|
|
|
|
|
const IMAGE_NT_HEADERS* ntHeader = detail::GetNtHeader(image);
|
|
|
|
|
if (!ntHeader)
|
|
|
|
|
{
|
|
|
|
|
return 0u;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ntHeader->OptionalHeader.AddressOfEntryPoint;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
executable::PreferredBase executable::GetPreferredBase(const Image* image)
|
|
|
|
|
{
|
|
|
|
|
const IMAGE_NT_HEADERS* ntHeader = detail::GetNtHeader(image);
|
|
|
|
|
if (!ntHeader)
|
|
|
|
|
{
|
|
|
|
|
return 0ull;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ntHeader->OptionalHeader.ImageBase;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
executable::Header executable::GetHeader(const Image* image)
|
|
|
|
|
{
|
|
|
|
|
const IMAGE_NT_HEADERS* ntHeader = detail::GetNtHeader(image);
|
|
|
|
|
if (!ntHeader)
|
|
|
|
|
{
|
|
|
|
|
return executable::Header {};
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-15 09:27:44 -04:00
|
|
|
const uint64_t sizeOnDisk = Filesystem::GetMemoryMappedFileSizeOnDisk(image);
|
2019-05-24 11:51:54 -04:00
|
|
|
return executable::Header { sizeOnDisk, ntHeader->FileHeader, ntHeader->OptionalHeader };
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool executable::IsValidHeader(const Header& header)
|
|
|
|
|
{
|
|
|
|
|
return header.imageHeader.NumberOfSections != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t executable::GetSize(const Image* image)
|
|
|
|
|
{
|
|
|
|
|
const IMAGE_NT_HEADERS* ntHeader = detail::GetNtHeader(image);
|
|
|
|
|
if (!ntHeader)
|
|
|
|
|
{
|
|
|
|
|
return 0ull;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ntHeader->OptionalHeader.SizeOfImage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t executable::RvaToFileOffset(const ImageSectionDB* database, uint32_t rva)
|
|
|
|
|
{
|
|
|
|
|
LC_ASSERT(rva != 0u, "RVA cannot be mapped to image.");
|
|
|
|
|
|
|
|
|
|
const size_t count = database->sections.size();
|
|
|
|
|
for (size_t i = 0u; i < count; ++i)
|
|
|
|
|
{
|
|
|
|
|
const ImageSection& section = database->sections[i];
|
|
|
|
|
if ((rva >= section.rva) && (rva < section.rva + section.size))
|
|
|
|
|
{
|
|
|
|
|
const uint32_t sectionOffset = rva - section.rva;
|
|
|
|
|
if (sectionOffset >= section.rawDataSize)
|
|
|
|
|
{
|
|
|
|
|
// the offset relative to the section lies outside the section data stored in the image.
|
|
|
|
|
// this can happen for sections like .bss/.data which don't store uninitialized data for
|
|
|
|
|
// the symbols.
|
|
|
|
|
return 0u;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return section.rawDataRva + sectionOffset;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LC_ERROR_DEV("Cannot map RVA 0x%X to executable image file offset", rva);
|
|
|
|
|
return 0u;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void executable::ReadFromFileOffset(const Image* image, uint32_t offset, void* destination, size_t byteCount)
|
|
|
|
|
{
|
2020-12-15 09:27:44 -04:00
|
|
|
const void* address = pointer::Offset<const void*>(Filesystem::GetMemoryMappedFileData(image), offset);
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
memcpy(destination, address, byteCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void executable::WriteToFileOffset(Image* image, uint32_t offset, const void* source, size_t byteCount)
|
|
|
|
|
{
|
2020-12-15 09:27:44 -04:00
|
|
|
void* address = pointer::Offset<void*>(Filesystem::GetMemoryMappedFileData(image), offset);
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
memcpy(address, source, byteCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-12-15 09:27:44 -04:00
|
|
|
executable::Image* executable::OpenImage(const wchar_t* filename, Filesystem::OpenMode::Enum openMode)
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
{
|
2020-12-15 09:27:44 -04:00
|
|
|
return Filesystem::OpenMemoryMappedFile(filename, openMode);
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void executable::CloseImage(Image*& image)
|
|
|
|
|
{
|
2020-12-15 09:27:44 -04:00
|
|
|
Filesystem::CloseMemoryMappedFile(image);
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void executable::RebaseImage(Image* image, PreferredBase preferredBase)
|
|
|
|
|
{
|
2020-12-15 09:27:44 -04:00
|
|
|
void* base = Filesystem::GetMemoryMappedFileData(image);
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
|
|
|
|
|
IMAGE_NT_HEADERS* ntHeader = detail::GetNtHeader(image);
|
|
|
|
|
if (!ntHeader)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const IMAGE_SECTION_HEADER* sectionHeader = detail::GetSectionHeader(ntHeader);
|
|
|
|
|
if (!sectionHeader)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-24 11:51:54 -04:00
|
|
|
ImageSectionDB* database = GatherImageSectionDB(image);
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
|
|
|
|
|
// the image has been linked against a certain base address, namely ntHeader->OptionalHeader.ImageBase.
|
|
|
|
|
// work out by how much all relocations need to be shifted if basing the image against the new
|
|
|
|
|
// preferred base.
|
|
|
|
|
const int64_t baseDelta = static_cast<int64_t>(preferredBase - ntHeader->OptionalHeader.ImageBase);
|
|
|
|
|
|
|
|
|
|
// this is the easy part: simply set the new preferred base address in the image
|
|
|
|
|
ntHeader->OptionalHeader.ImageBase = preferredBase;
|
|
|
|
|
|
|
|
|
|
// now comes the hard part: patch all relocation entries in the image
|
|
|
|
|
const DWORD relocSectionSize = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
|
|
|
|
if (relocSectionSize != 0u)
|
|
|
|
|
{
|
|
|
|
|
// .reloc section exists, patch it
|
|
|
|
|
const DWORD baseRelocationOffset = RvaToFileOffset(database, ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
|
|
|
|
|
const IMAGE_BASE_RELOCATION* baseRelocations = pointer::Offset<const IMAGE_BASE_RELOCATION*>(base, baseRelocationOffset);
|
|
|
|
|
|
|
|
|
|
DWORD blockSizeLeft = relocSectionSize;
|
|
|
|
|
while (blockSizeLeft > 0u)
|
|
|
|
|
{
|
|
|
|
|
const DWORD pageRVA = baseRelocations->VirtualAddress;
|
|
|
|
|
const DWORD blockSize = baseRelocations->SizeOfBlock;
|
|
|
|
|
const DWORD blockOffset = RvaToFileOffset(database, pageRVA);
|
|
|
|
|
|
|
|
|
|
// PE spec: Block size: The total number of bytes in the base relocation block, *including* the Page RVA and
|
|
|
|
|
// Block Size fields and the Type/Offset fields that follow.
|
2019-04-18 17:51:25 -04:00
|
|
|
const DWORD numberOfEntriesInThisBlock = (blockSize - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
const WORD* entries = pointer::Offset<const WORD*>(baseRelocations, sizeof(IMAGE_BASE_RELOCATION));
|
|
|
|
|
for (DWORD i = 0u; i < numberOfEntriesInThisBlock; ++i)
|
|
|
|
|
{
|
|
|
|
|
// PE spec: Type: Stored in the high 4 bits of the WORD
|
|
|
|
|
// Offset: Stored in the remaining 12 bits of the WORD
|
|
|
|
|
const WORD low12BitMask = 0x0FFF;
|
|
|
|
|
const WORD type = static_cast<WORD>(entries[i] >> 12u);
|
|
|
|
|
const WORD offset = static_cast<WORD>(entries[i] & low12BitMask);
|
|
|
|
|
|
|
|
|
|
// PE spec:
|
|
|
|
|
// IMAGE_REL_BASED_ABSOLUTE: The base relocation is skipped. This type can be used to pad a block.
|
|
|
|
|
// IMAGE_REL_BASED_HIGH: The base relocation adds the high 16 bits of the difference to the 16-bit field
|
|
|
|
|
// at offset. The 16-bit field represents the high value of a 32-bit word.
|
|
|
|
|
// IMAGE_REL_BASED_LOW: The base relocation adds the low 16 bits of the difference to the 16-bit field
|
|
|
|
|
// at offset. The 16-bit field represents the low half of a 32-bit word.
|
|
|
|
|
// IMAGE_REL_BASED_HIGHLOW: The base relocation applies all 32 bits of the difference to the 32-bit field at
|
|
|
|
|
// offset.
|
|
|
|
|
// IMAGE_REL_BASED_HIGHADJ: The base relocation adds the high 16 bits of the difference to the 16-bit field
|
|
|
|
|
// at offset. The 16-bit field represents the high value of a 32-bit word. The low 16 bits of the 32-bit value
|
|
|
|
|
// are stored in the 16-bit word that follows this base relocation. This means that this base relocation
|
|
|
|
|
// occupies two slots.
|
|
|
|
|
// IMAGE_REL_BASED_DIR64: The base relocation applies the difference to the 64-bit field at offset.
|
|
|
|
|
if (type == IMAGE_REL_BASED_ABSOLUTE)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else if (type == IMAGE_REL_BASED_HIGHLOW)
|
|
|
|
|
{
|
|
|
|
|
uint32_t* relocation = pointer::Offset<uint32_t*>(base, blockOffset + offset);
|
|
|
|
|
*relocation += static_cast<uint32_t>(baseDelta);
|
|
|
|
|
}
|
|
|
|
|
else if (type == IMAGE_REL_BASED_DIR64)
|
|
|
|
|
{
|
|
|
|
|
uint64_t* relocation = pointer::Offset<uint64_t*>(base, blockOffset + offset);
|
|
|
|
|
*relocation += static_cast<uint64_t>(baseDelta);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
baseRelocations = pointer::Offset<const IMAGE_BASE_RELOCATION*>(baseRelocations, baseRelocations->SizeOfBlock);
|
|
|
|
|
LC_ASSERT(blockSizeLeft >= blockSize, "Underflow while reading image relocations");
|
|
|
|
|
blockSizeLeft -= blockSize;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DestroyImageSectionDB(database);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-05-24 11:51:54 -04:00
|
|
|
executable::ImageSectionDB* executable::GatherImageSectionDB(const Image* image)
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
{
|
|
|
|
|
const IMAGE_NT_HEADERS* ntHeader = detail::GetNtHeader(image);
|
|
|
|
|
if (!ntHeader)
|
|
|
|
|
{
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const IMAGE_SECTION_HEADER* sectionHeader = detail::GetSectionHeader(ntHeader);
|
|
|
|
|
if (!sectionHeader)
|
|
|
|
|
{
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImageSectionDB* database = new ImageSectionDB;
|
|
|
|
|
const size_t sectionCount = ntHeader->FileHeader.NumberOfSections;
|
|
|
|
|
database->sections.reserve(sectionCount);
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0u; i < sectionCount; ++i)
|
|
|
|
|
{
|
|
|
|
|
database->sections.emplace_back(ImageSection { sectionHeader->VirtualAddress, sectionHeader->Misc.VirtualSize, sectionHeader->PointerToRawData, sectionHeader->SizeOfRawData });
|
|
|
|
|
++sectionHeader;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::sort(database->sections.begin(), database->sections.end(), &detail::SortSectionByAscendingRVA);
|
|
|
|
|
|
|
|
|
|
return database;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void executable::DestroyImageSectionDB(ImageSectionDB* database)
|
|
|
|
|
{
|
|
|
|
|
delete database;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-05-24 11:51:54 -04:00
|
|
|
executable::ImportModuleDB* executable::GatherImportModuleDB(const Image* image, const ImageSectionDB* imageSections)
|
|
|
|
|
{
|
|
|
|
|
const IMAGE_NT_HEADERS* ntHeader = detail::GetNtHeader(image);
|
|
|
|
|
if (!ntHeader)
|
|
|
|
|
{
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const IMAGE_SECTION_HEADER* sectionHeader = detail::GetSectionHeader(ntHeader);
|
|
|
|
|
if (!sectionHeader)
|
|
|
|
|
{
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImportModuleDB* database = new ImportModuleDB;
|
|
|
|
|
|
|
|
|
|
// the import directory stores an array of IMAGE_IMPORT_DESCRIPTOR entries
|
|
|
|
|
const size_t count = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);
|
|
|
|
|
if (count == 0u)
|
|
|
|
|
{
|
|
|
|
|
// no import modules
|
|
|
|
|
return database;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const DWORD baseImportModule = RvaToFileOffset(imageSections, ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
|
|
|
|
if (baseImportModule == 0u)
|
|
|
|
|
{
|
|
|
|
|
// no import modules
|
|
|
|
|
return database;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
database->modules.reserve(count);
|
|
|
|
|
|
2020-12-15 09:27:44 -04:00
|
|
|
const IMAGE_IMPORT_DESCRIPTOR* importModules = pointer::Offset<const IMAGE_IMPORT_DESCRIPTOR*>(Filesystem::GetMemoryMappedFileData(image), baseImportModule);
|
2019-05-24 11:51:54 -04:00
|
|
|
while (importModules->Name != 0)
|
|
|
|
|
{
|
|
|
|
|
const DWORD fileOffset = RvaToFileOffset(imageSections, importModules->Name);
|
2020-12-15 09:27:44 -04:00
|
|
|
const char* importModuleName = pointer::Offset<const char*>(Filesystem::GetMemoryMappedFileData(image), fileOffset);
|
2019-05-24 11:51:54 -04:00
|
|
|
|
|
|
|
|
ImportModule module;
|
|
|
|
|
strcpy_s(module.path, importModuleName);
|
|
|
|
|
database->modules.emplace_back(module);
|
|
|
|
|
|
|
|
|
|
++importModules;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return database;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void executable::DestroyImportModuleDB(ImportModuleDB* database)
|
|
|
|
|
{
|
|
|
|
|
delete database;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-01-29 14:48:18 -05:00
|
|
|
executable::PdbInfo* executable::GatherPdbInfo(const Image* image, const ImageSectionDB* imageSections)
|
|
|
|
|
{
|
|
|
|
|
const IMAGE_NT_HEADERS* ntHeader = detail::GetNtHeader(image);
|
|
|
|
|
if (!ntHeader)
|
|
|
|
|
{
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const IMAGE_SECTION_HEADER* sectionHeader = detail::GetSectionHeader(ntHeader);
|
|
|
|
|
if (!sectionHeader)
|
|
|
|
|
{
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// the debug directory stores an array of IMAGE_DEBUG_DIRECTORY entries
|
|
|
|
|
const size_t count = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size / sizeof(IMAGE_DEBUG_DIRECTORY);
|
|
|
|
|
if (count == 0u)
|
|
|
|
|
{
|
|
|
|
|
// no debug directories
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const DWORD baseDebugDirectory = RvaToFileOffset(imageSections, ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress);
|
|
|
|
|
if (baseDebugDirectory == 0u)
|
|
|
|
|
{
|
|
|
|
|
// no debug directories
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-15 09:27:44 -04:00
|
|
|
const IMAGE_DEBUG_DIRECTORY* debugDirectory = pointer::Offset<const IMAGE_DEBUG_DIRECTORY*>(Filesystem::GetMemoryMappedFileData(image), baseDebugDirectory);
|
2020-01-29 14:48:18 -05:00
|
|
|
for (size_t i=0u; i < count; ++i)
|
|
|
|
|
{
|
|
|
|
|
// we are only interested in PDB files
|
|
|
|
|
if (debugDirectory->Type == IMAGE_DEBUG_TYPE_CODEVIEW)
|
|
|
|
|
{
|
|
|
|
|
// try interpreting the raw data as PDB 7.0 info. if it belongs to PDB 7.0 data, the signature matches "RSDS"
|
|
|
|
|
// http://www.debuginfo.com/articles/debuginfomatch.html
|
|
|
|
|
struct PDB70Header
|
|
|
|
|
{
|
|
|
|
|
DWORD signature; // 'RSDS'
|
|
|
|
|
GUID guid;
|
|
|
|
|
DWORD age;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const DWORD RSDS = 0x53445352u;
|
2020-12-15 09:27:44 -04:00
|
|
|
const PDB70Header* pdbHeader = pointer::Offset<const PDB70Header*>(Filesystem::GetMemoryMappedFileData(image), debugDirectory->PointerToRawData);
|
2020-01-29 14:48:18 -05:00
|
|
|
if (pdbHeader->signature == RSDS)
|
|
|
|
|
{
|
|
|
|
|
// PDB filename follows right after the header data
|
|
|
|
|
const char* pdbPath = pointer::Offset<const char*>(pdbHeader, sizeof(PDB70Header));
|
|
|
|
|
|
|
|
|
|
PdbInfo* pdbInfo = new PdbInfo;
|
|
|
|
|
pdbInfo->guid = pdbHeader->guid;
|
|
|
|
|
pdbInfo->age = pdbHeader->age;
|
|
|
|
|
strcpy_s(pdbInfo->path, pdbPath);
|
|
|
|
|
|
|
|
|
|
return pdbInfo;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void executable::DestroyPdbInfo(PdbInfo* pdbInfo)
|
|
|
|
|
{
|
|
|
|
|
delete pdbInfo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
[FYI] Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
#ROBOMERGE-SOURCE: CL 5304722 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)
[CL 5309051 by ben marsh in Main branch]
2019-03-05 18:49:25 -05:00
|
|
|
void executable::CallDllEntryPoint(void* moduleBase, uint32_t entryPointRva)
|
|
|
|
|
{
|
|
|
|
|
typedef decltype(_DllMainCRTStartup) DllEntryPoint;
|
|
|
|
|
|
|
|
|
|
DllEntryPoint* entryPoint = pointer::Offset<DllEntryPoint*>(moduleBase, entryPointRva);
|
|
|
|
|
entryPoint(static_cast<HINSTANCE>(moduleBase), DLL_PROCESS_ATTACH, NULL);
|
|
|
|
|
}
|