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 @@