summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@gmail.com>2013-10-03 17:21:39 +0400
committerCyrill Gorcunov <gorcunov@gmail.com>2013-10-03 17:21:39 +0400
commita1d481041ab3ac6b44f1d3c1975c3d8df307852a (patch)
treedc821f3be58ed986ca8ba10a898702ff73ba345a
parent9d5461069d80d0201efb1e98d31a29fdc0fcfbce (diff)
parent29227125f05302cc3e084f2e799411c78b0258e0 (diff)
downloadnasm-a1d481041ab3ac6b44f1d3c1975c3d8df307852a.tar.gz
Merge branch 'nasm-2.10.xx'
* nasm-2.10.xx: coff: Better handling of section redefinition
-rw-r--r--output/outcoff.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/output/outcoff.c b/output/outcoff.c
index b404347b..d0fcb775 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;