https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5489efcb1abaea61f2033909d4a8636045690d57

commit 5489efcb1abaea61f2033909d4a8636045690d57
Author:     Jérôme Gardou <[email protected]>
AuthorDate: Wed Feb 24 10:14:40 2021 +0100
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Tue Mar 23 11:18:43 2021 +0100

    [SDK:TOOLS] Add --driver option to pefixup
    
    For now, this adds IMAGE_SCN_MEM_DISCARDABLE to the INIT section, and 
IMAGE_SCN_MEM_NOT_PAGED to sections which are not named PAGE or .reloc
---
 sdk/cmake/gcc.cmake |  2 +-
 sdk/tools/pefixup.c | 85 +++++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 74 insertions(+), 13 deletions(-)

diff --git a/sdk/cmake/gcc.cmake b/sdk/cmake/gcc.cmake
index 9c0bce9c685..9f38f811e4d 100644
--- a/sdk/cmake/gcc.cmake
+++ b/sdk/cmake/gcc.cmake
@@ -308,7 +308,7 @@ endif()
 
 function(fixup_load_config _target)
     add_custom_command(TARGET ${_target} POST_BUILD
-        COMMAND native-pefixup "$<TARGET_FILE:${_target}>"
+        COMMAND native-pefixup --loadconfig "$<TARGET_FILE:${_target}>"
         COMMENT "Patching in LOAD_CONFIG"
         DEPENDS native-pefixup)
 endfunction()
diff --git a/sdk/tools/pefixup.c b/sdk/tools/pefixup.c
index 07a1d71121d..81dfcc96c5a 100644
--- a/sdk/tools/pefixup.c
+++ b/sdk/tools/pefixup.c
@@ -24,6 +24,12 @@
 static const char* g_ApplicationName;
 static const char* g_Target;
 
+enum fixup_mode
+{
+    MODE_LOADCONFIG,
+    MODE_DRIVER
+};
+
 void *rva_to_ptr(unsigned char *buffer, PIMAGE_NT_HEADERS nt_header, DWORD rva)
 {
     unsigned int i;
@@ -121,6 +127,47 @@ static int add_loadconfig(unsigned char *buffer, 
PIMAGE_NT_HEADERS nt_header)
     return 1;
 }
 
+static int driver_fixup(unsigned char *buffer, PIMAGE_NT_HEADERS nt_header)
+{
+    /* GNU LD just doesn't know what a driver is, and has notably no idea of 
paged vs non-paged sections */
+    for (unsigned i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
+    {
+        PIMAGE_SECTION_HEADER Section = IMAGE_FIRST_SECTION(nt_header) + i;
+
+        /* Known sections which can be discarded */
+        if (strncasecmp((char*)Section->Name, "INIT", 4) == 0)
+        {
+            Section->Characteristics |= IMAGE_SCN_MEM_DISCARDABLE;
+            continue;
+        }
+
+        /* Known sections which can be paged */
+        if ((strncasecmp((char*)Section->Name, "PAGE", 4) == 0)
+            || (strncasecmp((char*)Section->Name, ".reloc", 6) == 0))
+        {
+            continue;
+        }
+
+        /* If it's discardable, don't set the flag */
+        if (Section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
+            continue;
+
+        Section->Characteristics |= IMAGE_SCN_MEM_NOT_PAGED;
+    }
+
+    return 0;
+}
+
+static
+void
+print_usage(void)
+{
+    printf("Usage: %s <mode> <filename>\n", g_ApplicationName);
+    printf("Where <mode> is on of the following:\n");
+    printf("  --loadconfig  Fix the LOAD_CONFIG directory entry\n");
+    printf("  --driver      Fix code and data sections for driver images\n");
+}
+
 int main(int argc, char **argv)
 {
     FILE* file;
@@ -128,19 +175,34 @@ int main(int argc, char **argv)
     unsigned char *buffer;
     PIMAGE_DOS_HEADER dos_header;
     int result = 1;
+    enum fixup_mode mode;
 
     g_ApplicationName = argv[0];
 
-    if (argc < 2)
+    if (argc != 3)
     {
-        printf("Usage: %s <filename>\n", g_ApplicationName);
+        print_usage();
         return 1;
     }
 
-    g_Target = argv[1];
+    if (strcmp(argv[1], "--loadconfig") == 0)
+    {
+        mode = MODE_LOADCONFIG;
+    }
+    else if (strcmp(argv[1], "--driver") == 0)
+    {
+        mode = MODE_DRIVER;
+    }
+    else
+    {
+        print_usage();
+        return 1;
+    }
+
+    g_Target = argv[2];
 
     /* Read the whole file to memory. */
-    file = fopen(argv[1], "r+b");
+    file = fopen(g_Target, "r+b");
     if (!file)
     {
         fprintf(stderr, "%s ERROR: Can't open '%s'.\n", g_ApplicationName, 
g_Target);
@@ -180,20 +242,19 @@ int main(int argc, char **argv)
 
         if (nt_header->Signature == IMAGE_NT_SIGNATURE)
         {
-            if (!add_loadconfig(buffer, nt_header))
+            if (mode == MODE_LOADCONFIG)
+                result = add_loadconfig(buffer, nt_header);
+            else
+                result = driver_fixup(buffer, nt_header);
+
+            if (!result)
             {
+                /* Success. Fix checksum and write to file */
                 fix_checksum(buffer, len, nt_header);
 
                 /* We could 'optimize by only writing the changed parts, but 
keep it simple for now */
                 fseek(file, 0, SEEK_SET);
                 fwrite(buffer, 1, len, file);
-
-                /* Success */
-                result = 0;
-            }
-            else
-            {
-                /* Error already printed inside add_loadconfig */
             }
         }
         else

Reply via email to