diff options
author | Marat Dukhan <maratek@gmail.com> | 2013-09-19 19:19:52 -0400 |
---|---|---|
committer | Cyrill Gorcunov <gorcunov@gmail.com> | 2013-10-03 16:55:50 +0400 |
commit | 29227125f05302cc3e084f2e799411c78b0258e0 (patch) | |
tree | 5a0f5f36c3bdb0d911b4dd3fee3fac734c25f078 /output | |
parent | e81b2ee85ca0f06705181dca615f13b50fcb3c35 (diff) | |
download | nasm-29227125f05302cc3e084f2e799411c78b0258e0.tar.gz nasm-29227125f05302cc3e084f2e799411c78b0258e0.tar.bz2 nasm-29227125f05302cc3e084f2e799411c78b0258e0.zip |
coff: Better handling of section redefinition
Currently, if we try to define an already defined section and specify
section flags, NASM will output "warning: section attributes ignored
on redeclaration of section %SECTIONNAME%".
The patch modifies this behaviour:
1. If the previous section definition differs only in alignment flags,
no warning is generated
2. If the new definition implies larger alignment, it overrides the
previous section alignment
3. If the new definition specifies any section alignment, the content of
the section will be aligned on the new boundary (i.e. the effect is the
same as if there was ALIGN macro)
Signed-off-by: Marat Dukhan <maratek@gmail.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Diffstat (limited to 'output')
-rw-r--r-- | output/outcoff.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/output/outcoff.c b/output/outcoff.c index b404347..d0fcb77 100644 --- a/output/outcoff.c +++ b/output/outcoff.c @@ -442,9 +442,42 @@ static int32_t coff_section_names(char *name, int pass, int *bits) sects[i]->flags &= align_and; sects[i]->flags |= align_or; } else if (pass == 1) { - if (flags) - nasm_error(ERR_WARNING, "section attributes ignored on" - " redeclaration of section `%s'", name); + /* Check if any flags are specified */ + if (flags) { + unsigned int align_flags = flags & IMAGE_SCN_ALIGN_MASK; + + /* Warn if non-alignment flags differ */ + if ((flags ^ sects[i]->flags) & ~IMAGE_SCN_ALIGN_MASK) { + nasm_error(ERR_WARNING, "section attributes ignored on" + " redeclaration of section `%s'", name); + } + /* Check if alignment might be needed */ + if (align_flags > IMAGE_SCN_ALIGN_1BYTES) { + unsigned int sect_align_flags = sects[i]->flags & IMAGE_SCN_ALIGN_MASK; + + /* Compute the actual alignment */ + unsigned int align = 1u << ((align_flags - IMAGE_SCN_ALIGN_1BYTES) >> 20); + + /* Update section header as needed */ + if (align_flags > sect_align_flags) { + sects[i]->flags = (sects[i]->flags & ~IMAGE_SCN_ALIGN_MASK) | align_flags; + } + /* Check if not already aligned */ + if (sects[i]->len % align) { + unsigned int padding = (align - sects[i]->len) % align; + /* We need to write at most 8095 bytes */ + char buffer[8095]; + if (sects[i]->flags & IMAGE_SCN_CNT_CODE) { + /* Fill with INT 3 instructions */ + memset(buffer, 0xCC, padding); + } else { + memset(buffer, 0x00, padding); + } + saa_wbytes(sects[i]->data, buffer, padding); + sects[i]->len += padding; + } + } + } } return sects[i]->index; |