mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-10-10 00:25:06 -04:00
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@zytor.com>
This commit is contained in:
@@ -72,11 +72,11 @@
|
|||||||
* (2) Win32 doesn't bother putting any flags in the header flags
|
* (2) Win32 doesn't bother putting any flags in the header flags
|
||||||
* field (at offset 0x12 into the file).
|
* 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)
|
* it defines flags 0x80000000 (writable), 0x40000000 (readable)
|
||||||
* and 0x20000000 (executable), and uses them in the expected
|
* and 0x20000000 (executable), and uses them in the expected
|
||||||
* combinations. It also defines 0x00100000 through 0x00700000 for
|
* combinations. It also defines 0x00100000 through 0x00f00000 for
|
||||||
* section alignments of 1 through 64 bytes.
|
* section alignments of 1 through 8192 bytes.
|
||||||
*
|
*
|
||||||
* (4) Both standard COFF and Win32 COFF seem to use the DWORD
|
* (4) Both standard COFF and Win32 COFF seem to use the DWORD
|
||||||
* field directly after the section name in the section header
|
* 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;
|
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)
|
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)
|
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)
|
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");
|
nasm_nonfatal("argument to `align' is not numeric");
|
||||||
else {
|
else {
|
||||||
unsigned int align = atoi(q + 6);
|
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"
|
nasm_nonfatal("argument to `align' is not a"
|
||||||
" power of two");
|
" power of two");
|
||||||
} else if (align > 8192) {
|
} else if (align > COFF_MAX_ALIGNMENT) {
|
||||||
nasm_nonfatal("maximum alignment in COFF is %d bytes",
|
nasm_nonfatal("maximum alignment in COFF is %d bytes",
|
||||||
COFF_MAX_ALIGNMENT);
|
COFF_MAX_ALIGNMENT);
|
||||||
} else {
|
} else {
|
||||||
@@ -382,30 +393,31 @@ static int32_t coff_section_names(char *name, int *bits)
|
|||||||
break;
|
break;
|
||||||
if (i == coff_nsects) {
|
if (i == coff_nsects) {
|
||||||
if (!flags) {
|
if (!flags) {
|
||||||
if (!strcmp(name, ".data"))
|
flags = TEXT_FLAGS;
|
||||||
|
|
||||||
|
if (!strcmp(name, ".data")) {
|
||||||
flags = DATA_FLAGS;
|
flags = DATA_FLAGS;
|
||||||
else if (!strcmp(name, ".rdata"))
|
} else if (!strcmp(name, ".rdata")) {
|
||||||
flags = RDATA_FLAGS;
|
flags = RDATA_FLAGS;
|
||||||
else if (!strcmp(name, ".bss"))
|
} else if (!strcmp(name, ".bss")) {
|
||||||
flags = BSS_FLAGS;
|
flags = BSS_FLAGS;
|
||||||
else if (win64 && !strcmp(name, ".pdata"))
|
} else if (win64) {
|
||||||
flags = PDATA_FLAGS;
|
if (!strcmp(name, ".pdata"))
|
||||||
else if (win64 && !strcmp(name, ".xdata"))
|
flags = PDATA_FLAGS;
|
||||||
flags = XDATA_FLAGS;
|
else if (!strcmp(name, ".xdata"))
|
||||||
else
|
flags = XDATA_FLAGS;
|
||||||
flags = TEXT_FLAGS;
|
}
|
||||||
}
|
}
|
||||||
i = coff_make_section(name, flags);
|
i = coff_make_section(name, flags);
|
||||||
if (flags)
|
coff_sects[i]->align_flags = align_flags;
|
||||||
coff_sects[i]->flags = flags;
|
} else {
|
||||||
} else if (flags) {
|
if (flags) {
|
||||||
/* Check if any flags are respecified */
|
/* Warn if non-alignment flags differ */
|
||||||
|
if (((flags ^ coff_sects[i]->flags) & ~IMAGE_SCN_ALIGN_MASK) &&
|
||||||
/* Warn if non-alignment flags differ */
|
coff_sects[i]->pass_last_seen == pass_count()) {
|
||||||
if ((flags ^ coff_sects[i]->flags) & ~IMAGE_SCN_ALIGN_MASK &&
|
nasm_warn(WARN_OTHER, "section attributes changed on"
|
||||||
coff_sects[i]->pass_last_seen == pass_count()) {
|
" redeclaration of section `%s'", name);
|
||||||
nasm_warn(WARN_OTHER, "section attributes changed on"
|
}
|
||||||
" redeclaration of section `%s'", name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if alignment might be needed */
|
/* 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) {
|
if (align_flags > sect_align_flags) {
|
||||||
coff_sects[i]->align_flags = align_flags;
|
coff_sects[i]->align_flags = align_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if not already aligned */
|
/* Check if not already aligned */
|
||||||
/* XXX: other formats don't do this... */
|
/* XXX: other formats don't do this... */
|
||||||
if (coff_sects[i]->len % align) {
|
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);
|
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) {
|
if (coff_sects[i]->flags & IMAGE_SCN_CNT_CODE) {
|
||||||
/* Fill with INT 3 instructions */
|
/* Fill with INT 3 instructions */
|
||||||
memset(buffer, 0xCC, padding);
|
memset(buffer, 0xCC, padding);
|
||||||
|
|||||||
Reference in New Issue
Block a user