summaryrefslogtreecommitdiff
path: root/output/outcoff.c
diff options
context:
space:
mode:
authorMarat Dukhan <maratek@gmail.com>2013-09-19 19:19:52 -0400
committerCyrill Gorcunov <gorcunov@gmail.com>2013-10-03 16:55:50 +0400
commit29227125f05302cc3e084f2e799411c78b0258e0 (patch)
tree5a0f5f36c3bdb0d911b4dd3fee3fac734c25f078 /output/outcoff.c
parente81b2ee85ca0f06705181dca615f13b50fcb3c35 (diff)
downloadnasm-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/outcoff.c')
-rw-r--r--output/outcoff.c39
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;