[nasm:nasm-2.15.xx] outcoff: don't drop align= option alone on a section line

nasm-bot for H. Peter Anvin (Intel) hpa at zytor.com
Fri Jul 10 18:18:03 PDT 2020


Commit-ID:  baaa5ca4413e7ac73fe98e682be13f2da529e2cf
Gitweb:     http://repo.or.cz/w/nasm.git?a=commitdiff;h=baaa5ca4413e7ac73fe98e682be13f2da529e2cf
Author:     H. Peter Anvin (Intel) <hpa at zytor.com>
AuthorDate: Fri, 10 Jul 2020 18:14:09 -0700
Committer:  H. Peter Anvin (Intel) <hpa at zytor.com>
CommitDate: Fri, 10 Jul 2020 18:14:09 -0700

outcoff: don't drop align= option alone on a section line

If the section/segment directive *only* contained an align= directive,
it would get lost. Fix that.

Signed-off-by: H. Peter Anvin (Intel) <hpa at zytor.com>


---
 output/outcoff.c | 68 ++++++++++++++++++++++++++++++++------------------------
 1 file changed, 39 insertions(+), 29 deletions(-)

diff --git a/output/outcoff.c b/output/outcoff.c
index de22fb88..bcd9ff3f 100644
--- a/output/outcoff.c
+++ b/output/outcoff.c
@@ -72,11 +72,11 @@
  * (2) Win32 doesn't bother putting any flags in the header flags
  * field (at offset 0x12 into the file).
  *
- * (3) Win32 uses some extra flags into the section header table:
+ * (3) Win32/64 uses some extra flags into the section header table:
  * it defines flags 0x80000000 (writable), 0x40000000 (readable)
  * and 0x20000000 (executable), and uses them in the expected
- * combinations. It also defines 0x00100000 through 0x00700000 for
- * section alignments of 1 through 64 bytes.
+ * combinations. It also defines 0x00100000 through 0x00f00000 for
+ * section alignments of 1 through 8192 bytes.
  *
  * (4) Both standard COFF and Win32 COFF seem to use the DWORD
  * field directly after the section name in the section header
@@ -285,14 +285,22 @@ int coff_make_section(char *name, uint32_t flags)
     return coff_nsects - 1;
 }
 
+/*
+ * Convert an alignment value to the corresponding flags.
+ * An alignment value of 0 means no flags should be set.
+ */
 static inline uint32_t coff_sectalign_flags(unsigned int align)
 {
-    return (ilog2_32(align) + 1) << 20;
+    return (alignlog2_32(align) + 1) << 20;
 }
 
+/*
+ * Get the alignment value from a flags field.
+ * Returns 0 if no alignment defined.
+ */
 static inline unsigned int coff_alignment(uint32_t flags)
 {
-    return 1U << (((flags & IMAGE_SCN_ALIGN_MASK) >> 20) - 1);
+    return (1U << ((flags & IMAGE_SCN_ALIGN_MASK) >> 20)) >> 1;
 }
 
 static int32_t coff_section_names(char *name, int *bits)
@@ -364,10 +372,13 @@ static int32_t coff_section_names(char *name, int *bits)
                 nasm_nonfatal("argument to `align' is not numeric");
             else {
                 unsigned int align = atoi(q + 6);
-                if (!align || ((align - 1) & align)) {
+                /* Allow align=0 meaning use default */
+                if (!align) {
+                    align_flags = 0;
+                } else if (!is_power2(align)) {
                     nasm_nonfatal("argument to `align' is not a"
                                   " power of two");
-                } else if (align > 8192) {
+                } else if (align > COFF_MAX_ALIGNMENT) {
                     nasm_nonfatal("maximum alignment in COFF is %d bytes",
                                   COFF_MAX_ALIGNMENT);
                 } else {
@@ -382,30 +393,31 @@ static int32_t coff_section_names(char *name, int *bits)
             break;
     if (i == coff_nsects) {
         if (!flags) {
-            if (!strcmp(name, ".data"))
+            flags = TEXT_FLAGS;
+
+            if (!strcmp(name, ".data")) {
                 flags = DATA_FLAGS;
-            else if (!strcmp(name, ".rdata"))
+            } else if (!strcmp(name, ".rdata")) {
                 flags = RDATA_FLAGS;
-            else if (!strcmp(name, ".bss"))
+            } else if (!strcmp(name, ".bss")) {
                 flags = BSS_FLAGS;
-            else if (win64 && !strcmp(name, ".pdata"))
-                flags = PDATA_FLAGS;
-            else if (win64 && !strcmp(name, ".xdata"))
-                flags = XDATA_FLAGS;
-            else
-                flags = TEXT_FLAGS;
+            } else if (win64) {
+                if (!strcmp(name, ".pdata"))
+                    flags = PDATA_FLAGS;
+                else if (!strcmp(name, ".xdata"))
+                    flags = XDATA_FLAGS;
+            }
         }
         i = coff_make_section(name, flags);
-        if (flags)
-            coff_sects[i]->flags = flags;
-    } else if (flags) {
-        /* Check if any flags are respecified */
-
-        /* Warn if non-alignment flags differ */
-        if ((flags ^ coff_sects[i]->flags) & ~IMAGE_SCN_ALIGN_MASK &&
-            coff_sects[i]->pass_last_seen == pass_count()) {
-            nasm_warn(WARN_OTHER, "section attributes changed on"
-                      " redeclaration of section `%s'", name);
+        coff_sects[i]->align_flags = align_flags;
+    } else {
+        if (flags) {
+            /* Warn if non-alignment flags differ */
+            if (((flags ^ coff_sects[i]->flags) & ~IMAGE_SCN_ALIGN_MASK) &&
+                coff_sects[i]->pass_last_seen == pass_count()) {
+                nasm_warn(WARN_OTHER, "section attributes changed on"
+                          " redeclaration of section `%s'", name);
+            }
         }
 
         /* Check if alignment might be needed */
@@ -419,6 +431,7 @@ static int32_t coff_section_names(char *name, int *bits)
             if (align_flags > sect_align_flags) {
                 coff_sects[i]->align_flags = align_flags;
             }
+
             /* Check if not already aligned */
             /* XXX: other formats don't do this... */
             if (coff_sects[i]->len % align) {
@@ -428,9 +441,6 @@ static int32_t coff_section_names(char *name, int *bits)
 
                 nasm_assert(padding <= sizeof buffer);
 
-                if (pass_final())
-                    nasm_nonfatal("section alignment changed during code generation");
-
                 if (coff_sects[i]->flags & IMAGE_SCN_CNT_CODE) {
                     /* Fill with INT 3 instructions */
                     memset(buffer, 0xCC, padding);


More information about the Nasm-commits mailing list