From 5df6ca712df59a7f83b27ebd382bfb6ee851fff8 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin (Intel)" Date: Tue, 18 Dec 2018 12:25:11 -0800 Subject: With buffered warnings, change the handling of error passes With buffered warnings, most warnings *must* be issued on every pass, so ERR_PASS1 is simply wrong in most cases. ERR_PASS1 now means "force this warning to be output even in pass_first(). This is to be used for the case where the warning is only executed in pass_first() code; this is highly discouraged as it means the warnings will not appear in the list file and subsequent passes may make the warning suddenly vanish. ERR_PASS2 just as before suppresses an error or warning unless we are in pass_final(). Signed-off-by: H. Peter Anvin (Intel) --- output/outbin.c | 4 ++-- output/outcoff.c | 68 ++++++++++++++++++++++++++++++-------------------------- output/outelf.c | 9 ++++---- output/outelf.h | 1 + output/outieee.c | 5 ++++- output/outobj.c | 4 +++- output/pecoff.h | 1 + 7 files changed, 53 insertions(+), 39 deletions(-) (limited to 'output') diff --git a/output/outbin.c b/output/outbin.c index 4bf13fa4..73a4d8a7 100644 --- a/output/outbin.c +++ b/output/outbin.c @@ -1328,13 +1328,13 @@ bin_directive(enum directive directive, char *args) else { /* Must be a filename. */ rf = nasm_open_write(p, NF_TEXT); if (!rf) { - nasm_warn(WARN_OTHER, "unable to open map file `%s'", p); + nasm_warn(WARN_OTHER|ERR_PASS1, "unable to open map file `%s'", p); map_control = 0; return DIRR_OK; } } } else - nasm_warn(WARN_OTHER, "map file already specified"); + nasm_warn(WARN_OTHER|ERR_PASS1, "map file already specified"); } if (map_control == 0) map_control |= MAP_ORIGIN | MAP_SUMMARY; diff --git a/output/outcoff.c b/output/outcoff.c index a90e355e..2c8520f1 100644 --- a/output/outcoff.c +++ b/output/outcoff.c @@ -402,45 +402,51 @@ static int32_t coff_section_names(char *name, int *bits) coff_sects[i]->flags = flags; coff_sects[i]->flags &= align_and; coff_sects[i]->flags |= align_or; - } else if (pass_first()) { - /* 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 ^ coff_sects[i]->flags) & ~IMAGE_SCN_ALIGN_MASK) { - nasm_warn(WARN_OTHER, "section attributes ignored on" - " redeclaration of section `%s'", name); + } else if (flags) { + /* Check if any flags are respecified */ + unsigned int align_flags = flags & IMAGE_SCN_ALIGN_MASK; + + /* 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 */ + if (align_flags > IMAGE_SCN_ALIGN_1BYTES) { + unsigned int sect_align_flags = coff_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) { + coff_sects[i]->flags = (coff_sects[i]->flags & ~IMAGE_SCN_ALIGN_MASK) | align_flags; } - /* Check if alignment might be needed */ - if (align_flags > IMAGE_SCN_ALIGN_1BYTES) { - unsigned int sect_align_flags = coff_sects[i]->flags & IMAGE_SCN_ALIGN_MASK; + /* Check if not already aligned */ + if (coff_sects[i]->len % align) { + unsigned int padding = (align - coff_sects[i]->len) % align; + /* We need to write at most 8095 bytes */ + char buffer[8095]; - /* Compute the actual alignment */ - unsigned int align = 1u << ((align_flags - IMAGE_SCN_ALIGN_1BYTES) >> 20); + nasm_assert(padding <= sizeof buffer); - /* Update section header as needed */ - if (align_flags > sect_align_flags) { - coff_sects[i]->flags = (coff_sects[i]->flags & ~IMAGE_SCN_ALIGN_MASK) | align_flags; - } - /* Check if not already aligned */ - if (coff_sects[i]->len % align) { - unsigned int padding = (align - coff_sects[i]->len) % align; - /* We need to write at most 8095 bytes */ - char buffer[8095]; - if (coff_sects[i]->flags & IMAGE_SCN_CNT_CODE) { - /* Fill with INT 3 instructions */ - memset(buffer, 0xCC, padding); - } else { - memset(buffer, 0x00, padding); - } - saa_wbytes(coff_sects[i]->data, buffer, padding); - coff_sects[i]->len += padding; + 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); + } else { + memset(buffer, 0x00, padding); } + saa_wbytes(coff_sects[i]->data, buffer, padding); + coff_sects[i]->len += padding; } } } + coff_sects[i]->pass_last_seen = pass_count(); return coff_sects[i]->index; } diff --git a/output/outelf.c b/output/outelf.c index cd77901f..366e52de 100644 --- a/output/outelf.c +++ b/output/outelf.c @@ -258,8 +258,8 @@ static void elf_section_attrib(char *name, char *attr, *type = SHT_PROGBITS; } else if (!nasm_stricmp(opt, "nobits")) { *type = SHT_NOBITS; - } else if (pass_first()) { - nasm_warn(WARN_OTHER, "Unknown section attribute '%s' ignored on" + } else { + nasm_warn(WARN_OTHER, "unknown section attribute '%s' ignored on" " declaration of section `%s'", opt, name); } opt = next; @@ -458,14 +458,15 @@ static int32_t elf_section_names(char *name, int *bits) flags = (ks->flags & ~flags_and) | flags_or; i = elf_make_section(name, type, flags, align); - } else if (pass_first()) { + } else if (sects[i]->pass_last_seen == pass_count()) { if ((type && sects[i]->type != type) || (align && sects[i]->align != align) || (flags_and && ((sects[i]->flags & flags_and) != flags_or))) - nasm_warn(WARN_OTHER, "incompatible section attributes ignored on" + nasm_warn(WARN_OTHER|ERR_PASS1, "incompatible section attributes ignored on" " redeclaration of section `%s'", name); } + sects[i]->pass_last_seen = pass_count(); return sects[i]->index; } diff --git a/output/outelf.h b/output/outelf.h index 8eef73ae..0801eaf8 100644 --- a/output/outelf.h +++ b/output/outelf.h @@ -141,6 +141,7 @@ struct elf_section { int type; /* SHT_PROGBITS or SHT_NOBITS */ uint64_t align; /* alignment: power of two */ uint64_t flags; /* section flags */ + int64_t pass_last_seen; char *name; struct SAA *rel; uint64_t rellen; diff --git a/output/outieee.c b/output/outieee.c index 1247077e..f2f598ee 100644 --- a/output/outieee.c +++ b/output/outieee.c @@ -151,6 +151,7 @@ static struct ieeeSection { int32_t align; /* can be SEG_ABS + absolute addr */ int32_t startpos; int32_t use32; /* is this segment 32-bit? */ + int64_t pass_last_seen; struct ieeePublic *pubhead, **pubtail, *lochead, **loctail; enum { CMB_PRIVATE = 0, @@ -705,13 +706,15 @@ static int32_t ieee_segment(char *name, int *bits) for (seg = seghead; seg; seg = seg->next) { ieee_idx++; if (!strcmp(seg->name, name)) { - if (attrs > 0 && pass_first()) + if (attrs > 0 && seg->pass_last_seen == pass_count()) nasm_warn(WARN_OTHER, "segment attributes specified on" " redeclaration of segment: ignoring"); if (seg->use32) *bits = 32; else *bits = 16; + + seg->pass_last_seen = pass_count(); return seg->index; } } diff --git a/output/outobj.c b/output/outobj.c index e861754e..c7407cf9 100644 --- a/output/outobj.c +++ b/output/outobj.c @@ -580,6 +580,7 @@ static struct Segment { struct Group *grp; /* the group it beint32_ts to */ uint32_t currentpos; int32_t align; /* can be SEG_ABS + absolute addr */ + int64_t pass_last_seen; struct Public *pubhead, **pubtail, *lochead, **loctail; char *segclass, *overlay; /* `class' is a C++ keyword :-) */ ObjRecord *orp; @@ -1379,7 +1380,7 @@ static int32_t obj_segment(char *name, int *bits) break; if (!strcmp(seg->name, name)) { - if (attrs > 0 && pass_first()) + if (attrs > 0 && seg->pass_last_seen == pass_count()) nasm_warn(WARN_OTHER, "segment attributes specified on" " redeclaration of segment: ignoring"); if (seg->use32) @@ -1387,6 +1388,7 @@ static int32_t obj_segment(char *name, int *bits) else *bits = 16; current_seg = seg; + seg->pass_last_seen = pass_count(); return seg->index; } } diff --git a/output/pecoff.h b/output/pecoff.h index 8b57d6b2..7b6f46c2 100644 --- a/output/pecoff.h +++ b/output/pecoff.h @@ -484,6 +484,7 @@ struct coff_Section { char *name; int32_t namepos; /* Offset of name into the strings table */ int32_t pos, relpos; + int64_t pass_last_seen; }; struct coff_Reloc { -- cgit v1.2.1