summaryrefslogtreecommitdiff
path: root/output
diff options
context:
space:
mode:
authorH. Peter Anvin (Intel) <hpa@zytor.com>2018-12-18 12:25:11 -0800
committerH. Peter Anvin (Intel) <hpa@zytor.com>2018-12-18 12:25:11 -0800
commit5df6ca712df59a7f83b27ebd382bfb6ee851fff8 (patch)
treed926fa961f5a91c71317ac34c2867246f8d229eb /output
parent21da8ae8e5163aa6dd2042d70a7530d7d6accab7 (diff)
downloadnasm-5df6ca712df59a7f83b27ebd382bfb6ee851fff8.tar.gz
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) <hpa@zytor.com>
Diffstat (limited to 'output')
-rw-r--r--output/outbin.c4
-rw-r--r--output/outcoff.c68
-rw-r--r--output/outelf.c9
-rw-r--r--output/outelf.h1
-rw-r--r--output/outieee.c5
-rw-r--r--output/outobj.c4
-rw-r--r--output/pecoff.h1
7 files changed, 53 insertions, 39 deletions
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 {