From ea0c7395de439e698b24d5373560662728c7b4b8 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 3 Feb 2007 02:51:13 +0000 Subject: [PATCH] - Added a new fixrtext tool that sets the IMAGE_SCN_MEM_WRITE flag for .rtext files in the assembly object files. Now I can avoid doing this at runtime, which means that ZDoom is now UPX-compatible if anyone wants to pack it. You will need to do a rebuild or manually delete the old assembly .obj files for the first build from this revision to succeed, since there are no changes to the assembly files themselves, and the build process will not be able to automatically detect that they need to be rebuilt. SVN r473 (trunk) --- Makefile.mgw | 2 + Makefile.mingw | 1 + docs/rh-log.txt | 9 ++ src/win32/i_main.cpp | 40 -------- tools/fixrtext/Makefile | 33 ++++++ tools/fixrtext/fixrtext.c | 88 ++++++++++++++++ tools/fixrtext/fixrtext.vcproj | 179 +++++++++++++++++++++++++++++++++ zdoom.sln | 23 +++-- zdoom.vcproj | 28 +++--- 9 files changed, 342 insertions(+), 61 deletions(-) create mode 100644 tools/fixrtext/Makefile create mode 100644 tools/fixrtext/fixrtext.c create mode 100644 tools/fixrtext/fixrtext.vcproj diff --git a/Makefile.mgw b/Makefile.mgw index 1dde9ce9c..4edb0dab5 100644 --- a/Makefile.mgw +++ b/Makefile.mgw @@ -25,6 +25,7 @@ basetools: ccdv.exe $(MAKE) -C tools/makewad $(MAKE) -C tools/dehsupp $(MAKE) -C tools/xlatcc + $(MAKE) -C tools/fixrtext $(MAKE) -C wadsrc -f Makefile.mgw $(MAKE) -C flac -f Makefile.mgw $(MAKE) -C jpeg-6b -f Makefile.mgw @@ -38,6 +39,7 @@ clean: @$(MAKE) -C tools/dehsupp clean @$(MAKE) -C tools/makewad clean @$(MAKE) -C tools/xlatcc clean + @$(MAKE) -C tools/fixrtext clean @$(MAKE) -C wadsrc -f Makefile.mgw clean @$(MAKE) -C . -f Makefile.mingw clean @$(MAKE) -C zlib -f Makefile.mgw clean diff --git a/Makefile.mingw b/Makefile.mingw index d1cad3f61..81be2ff65 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -91,6 +91,7 @@ $(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.o : %.nas $(CCDV) nasmw -o $@ -f win32 $< + @tools/fixrtext/fixrtext $@ $(OBJDIR)/%.o : %.rc $(CCDV) windres --include-dir=src/win32 -o $@ -i $< diff --git a/docs/rh-log.txt b/docs/rh-log.txt index e586dc0b4..038aee92f 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,13 @@ February 2, 2007 +- Added a new fixrtext tool that sets the IMAGE_SCN_MEM_WRITE flag for + .rtext files in the assembly object files. Now I can avoid doing this at + runtime, which means that ZDoom is now UPX-compatible if anyone wants to + pack it. + + You will need to do a rebuild or manually delete the old assembly .obj files + for the first build from this revision to succeed, since there are no + changes to the assembly files themselves, and the build process will not be + able to automatically detect that they need to be rebuilt. - Fixed: The SafeDivScales used a signed shift for their if test. This fails when a == 0x80000000, because the result of abs will still be negative as long as we use signed math. diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index dcddd4829..011126083 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -779,46 +779,6 @@ void DoMain (HINSTANCE hInstance) // need to extract the ProcessIdToSessionId function from kernel32.dll manually. HMODULE kernel = GetModuleHandle ("kernel32.dll"); - // NASM does not support creating writeable code sections (even though this - // is a perfectly valid configuration for Microsoft's COFF format), so I - // need to make the self-modifying code writeable after it's already loaded. -#ifdef USEASM - { - BYTE *module = (BYTE *)GetModuleHandle (NULL); - IMAGE_DOS_HEADER *dosHeader = (IMAGE_DOS_HEADER *)module; - IMAGE_NT_HEADERS *ntHeaders = (IMAGE_NT_HEADERS *)(module + dosHeader->e_lfanew); - IMAGE_SECTION_HEADER *sections = IMAGE_FIRST_SECTION (ntHeaders); - int i; - LPVOID *start = NULL; - SIZE_T size = 0; - DWORD oldprotect; - - for (i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i) - { - if (memcmp (sections[i].Name, ".rtext\0", 8) == 0) - { - start = (LPVOID *)(sections[i].VirtualAddress + module); - size = sections[i].Misc.VirtualSize; - break; - } - } - - // I think these pages need to be mapped PAGE_EXECUTE_WRITECOPY (based on the - // description of PAGE_WRITECOPY), but PAGE_EXECUTE_READWRITE seems to work - // just as well; two instances of the program can be running with different - // resolutions at the same time either way. Perhaps the file mappings for - // executables are created with PAGE_WRITECOPY, so any attempts to give them - // write access are automatically transformed to copy-on-write? - // - // This used to be PAGE_EXECUTE_WRITECOPY until Timmie found out Win9x doesn't - // support it, although the MSDN does not indicate it. - if (!VirtualProtect (start, size, PAGE_EXECUTE_READWRITE, &oldprotect)) - { - I_FatalError ("The self-modifying code section code not be made writeable."); - } - } -#endif - // Set the timer to be as accurate as possible if (timeGetDevCaps (&tc, sizeof(tc)) != TIMERR_NOERROR) TimerPeriod = 1; // Assume minimum resolution of 1 ms diff --git a/tools/fixrtext/Makefile b/tools/fixrtext/Makefile new file mode 100644 index 000000000..83e166d92 --- /dev/null +++ b/tools/fixrtext/Makefile @@ -0,0 +1,33 @@ +ifeq (Windows_NT,$(OS)) + WIN=1 + WINCMD=1 +endif +ifeq (msys,$(OSTYPE)) + WIN=1 + WINCMD=0 +endif + +ifeq (1,$(WIN)) + EXE = fixrtext.exe + CFLAGS = $(LOC) -D_WIN32 -Os -Wall -fomit-frame-pointer +else +# This is only useful for Win32 builds. +endif + +CCDV = @../../ccdv +CC = gcc +LDFLAGS = -s + +all: $(EXE) + +$(EXE): fixrtext.c + $(CCDV) $(CC) $(LDFLAGS) -o $(EXE) fixrtext.c + +.PHONY: clean + +clean: +ifeq (1,$(WINCMD)) + -del /q /f $(EXE) 2>nul +else + rm -f $(EXE) +endif diff --git a/tools/fixrtext/fixrtext.c b/tools/fixrtext/fixrtext.c new file mode 100644 index 000000000..01a91e6f4 --- /dev/null +++ b/tools/fixrtext/fixrtext.c @@ -0,0 +1,88 @@ +/* fixrtext.c +** +** Given a coff-win32 object file, search for an .rtext section header and +** set its IMAGE_SCN_MEM_WRITE flag if it isn't already set. This gets +** around an NASM deficiency that prevents creating such files with +** "execute read write" sections. +** +** The author of this program disclaims copyright. +*/ + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#ifndef _MSC_VER +#include + +int fopen_s (FILE **pFile, const char *filename, const char *mode) +{ + if ((*pFile = fopen (filename, mode)) == NULL) + { + return errno; + } + return 0; +} +#endif + +int main (int argc, char **argv) +{ + FILE *f; + IMAGE_FILE_HEADER filehead; + IMAGE_SECTION_HEADER secthead; + int i; + + if (argc != 2) + return 1; + + if (fopen_s (&f, argv[1], "r+b")) + { + fprintf (stderr, "Could not open %s\n", argv[1]); + return 1; + } + + if (fread (&filehead, sizeof filehead, 1, f) != 1 || + filehead.Machine != IMAGE_FILE_MACHINE_I386) + { + fprintf (stderr, "%s is not an x86 object file\n", argv[1]); + fclose (f); + return 1; + } + + for (i = 0; i < filehead.NumberOfSections; ++i) + { + if (fread (§head, sizeof secthead, 1, f) != 1) + { + fprintf (stderr, "Could not read section header %d\n", i + 1); + fclose (f); + return 1; + } + if (memcmp (secthead.Name, ".rtext\0", IMAGE_SIZEOF_SHORT_NAME) == 0) + { + if (secthead.Characteristics & IMAGE_SCN_MEM_WRITE) + { + fprintf (stderr, "The .rtext section in %s is already writeable\n", argv[1]); + fclose (f); + return 0; + } + secthead.Characteristics |= IMAGE_SCN_MEM_WRITE; + if (fseek (f, -(long)sizeof secthead, SEEK_CUR)) + { + fprintf (stderr, "Failed to seek back to start of .rtext section header\n"); + fclose (f); + return 1; + } + if (fwrite (§head, sizeof secthead, 1, f) != 1) + { + fprintf (stderr, "Failed to rewrite .rtext section header\n"); + fclose (f); + return 1; + } +/* fprintf (stderr, "The .rtext section in %s was successfully made writeable\n", argv[1]); */ + fclose (f); + return 0; + } + } + fclose (f); + return 0; +} diff --git a/tools/fixrtext/fixrtext.vcproj b/tools/fixrtext/fixrtext.vcproj new file mode 100644 index 000000000..bc78575e6 --- /dev/null +++ b/tools/fixrtext/fixrtext.vcproj @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zdoom.sln b/zdoom.sln index e8a222603..7705de308 100644 --- a/zdoom.sln +++ b/zdoom.sln @@ -3,11 +3,12 @@ Microsoft Visual Studio Solution File, Format Version 9.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zdoom", "zdoom.vcproj", "{8049475B-5C87-46F9-9358-635218A4EF18}" ProjectSection(ProjectDependencies) = postProject {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466} = {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466} - {1D179D4B-F008-431B-8C72-111F8372584F} = {1D179D4B-F008-431B-8C72-111F8372584F} - {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} = {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} - {6077B7D6-349F-4077-B552-3BC302EF5859} = {6077B7D6-349F-4077-B552-3BC302EF5859} - {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} = {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} + {DA47396F-60C1-4BDE-A977-7F7DE461CF77} = {DA47396F-60C1-4BDE-A977-7F7DE461CF77} {873F2EEA-24DF-454C-B245-CB9738BA993E} = {873F2EEA-24DF-454C-B245-CB9738BA993E} + {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} = {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} + {6077B7D6-349F-4077-B552-3BC302EF5859} = {6077B7D6-349F-4077-B552-3BC302EF5859} + {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} = {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} + {1D179D4B-F008-431B-8C72-111F8372584F} = {1D179D4B-F008-431B-8C72-111F8372584F} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "zlib\zlib.vcproj", "{F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}" @@ -20,9 +21,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "re2c", "tools\re2c\re2c.vcp EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wadsrc", "wadsrc\wadsrc.vcproj", "{1D179D4B-F008-431B-8C72-111F8372584F}" ProjectSection(ProjectDependencies) = postProject - {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3} = {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3} - {AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8} = {AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8} {3FFA68B3-9449-4B03-ADEE-194C3638623B} = {3FFA68B3-9449-4B03-ADEE-194C3638623B} + {AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8} = {AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8} + {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3} = {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makewad", "tools\makewad\makewad.vcproj", "{24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}" @@ -34,14 +35,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xlatcc", "tools\xlatcc\xlat EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dehsupp", "tools\dehsupp\dehsupp.vcproj", "{AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8}" ProjectSection(ProjectDependencies) = postProject - {0F80ACBF-460E-44F0-B28E-B3272D1774A7} = {0F80ACBF-460E-44F0-B28E-B3272D1774A7} {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} = {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} + {0F80ACBF-460E-44F0-B28E-B3272D1774A7} = {0F80ACBF-460E-44F0-B28E-B3272D1774A7} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "updaterevision", "tools\updaterevision\updaterevision.vcproj", "{6077B7D6-349F-4077-B552-3BC302EF5859}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jpeg-6b", "jpeg-6b\jpeg-6b.vcproj", "{AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fixrtext", "tools\fixrtext\fixrtext.vcproj", "{DA47396F-60C1-4BDE-A977-7F7DE461CF77}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -136,6 +139,12 @@ Global {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Release|Win32.ActiveCfg = Release|Win32 {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Release|Win32.Build.0 = Release|Win32 {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Release|x64.ActiveCfg = Debug|x64 + {DA47396F-60C1-4BDE-A977-7F7DE461CF77}.Debug|Win32.ActiveCfg = Debug|Win32 + {DA47396F-60C1-4BDE-A977-7F7DE461CF77}.Debug|Win32.Build.0 = Debug|Win32 + {DA47396F-60C1-4BDE-A977-7F7DE461CF77}.Debug|x64.ActiveCfg = Debug|Win32 + {DA47396F-60C1-4BDE-A977-7F7DE461CF77}.Release|Win32.ActiveCfg = Release|Win32 + {DA47396F-60C1-4BDE-A977-7F7DE461CF77}.Release|Win32.Build.0 = Release|Win32 + {DA47396F-60C1-4BDE-A977-7F7DE461CF77}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/zdoom.vcproj b/zdoom.vcproj index 6ee4c8b90..d9e4df07b 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -4754,8 +4754,8 @@ @@ -4862,7 +4862,7 @@ @@ -4886,7 +4886,7 @@ @@ -4906,7 +4906,7 @@ @@ -4930,7 +4930,7 @@ @@ -4950,7 +4950,7 @@