summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-02-21 17:19:05 -0800
committerH. Peter Anvin <hpa@zytor.com>2009-02-21 17:19:05 -0800
commit04616f4e85d7c5c8501432f7124cf15f440aeae1 (patch)
tree0e938ef7824594b31e71c1768372478aff85ca9d
parent719f55938e3a0403eecd1952b3ef5c03b96231e2 (diff)
downloadnasm-04616f4e85d7c5c8501432f7124cf15f440aeae1.tar.gz
BR 2611906: proper error message for start < origin
When a section other than .text has a start < origin, we would segfault; fix that. Furthermore, at bin_cleanup() we don't have usable file/line information, so pass ERR_NOFILE to the error() function. Perhaps less than ideal, but better than printing a null pointer.
-rw-r--r--output/outbin.c61
1 files changed, 31 insertions, 30 deletions
diff --git a/output/outbin.c b/output/outbin.c
index f6be9643..f6de9302 100644
--- a/output/outbin.c
+++ b/output/outbin.c
@@ -247,10 +247,9 @@ static void bin_cleanup(int debuginfo)
}
/* Do some special pre-processing on nobits sections' attributes. */
if (s->flags & (START_DEFINED | ALIGN_DEFINED | FOLLOWS_DEFINED)) { /* Check for a mixture of real and virtual section attributes. */
- if (s->
- flags & (VSTART_DEFINED | VALIGN_DEFINED |
- VFOLLOWS_DEFINED))
- error(ERR_FATAL,
+ if (s->flags & (VSTART_DEFINED | VALIGN_DEFINED |
+ VFOLLOWS_DEFINED))
+ error(ERR_FATAL|ERR_NOFILE,
"cannot mix real and virtual attributes"
" in nobits section (%s)", s->name);
/* Real and virtual attributes mean the same thing for nobits sections. */
@@ -321,11 +320,11 @@ static void bin_cleanup(int debuginfo)
s && strcmp(s->name, g->follows);
sp = &s->next, s = s->next) ;
if (!s)
- error(ERR_FATAL, "section %s follows an invalid or"
+ error(ERR_FATAL|ERR_NOFILE, "section %s follows an invalid or"
" unknown section (%s)", g->name, g->follows);
if (s->next && (s->next->flags & FOLLOWS_DEFINED) &&
!strcmp(s->name, s->next->follows))
- error(ERR_FATAL, "sections %s and %s can't both follow"
+ error(ERR_FATAL|ERR_NOFILE, "sections %s and %s can't both follow"
" section %s", g->name, s->next->name, s->name);
/* Find the end of the current follows group (gs). */
for (gsp = &g->next, gs = g->next;
@@ -365,21 +364,18 @@ static void bin_cleanup(int debuginfo)
/* Step 3: Compute start addresses for all progbits sections. */
/* Make sure we have an origin and a start address for the first section. */
- if (origin_defined)
- switch (sections->flags & (START_DEFINED | ALIGN_DEFINED)) {
- case START_DEFINED | ALIGN_DEFINED:
- case START_DEFINED:
+ if (origin_defined) {
+ if (section->flags & START_DEFINED) {
/* Make sure this section doesn't begin before the origin. */
if (sections->start < origin)
- error(ERR_FATAL, "section %s begins"
+ error(ERR_FATAL|ERR_NOFILE, "section %s begins"
" before program origin", sections->name);
- break;
- case ALIGN_DEFINED:
+ } else if (section->flags & ALIGN_DEFINED) {
sections->start = ((origin + sections->align - 1) &
~(sections->align - 1));
- break;
- case 0:
+ } else {
sections->start = origin;
+ }
} else {
if (!(sections->flags & START_DEFINED))
sections->start = 0;
@@ -428,11 +424,14 @@ static void bin_cleanup(int debuginfo)
pend = g->start + g->length;
/* Check for section overlap. */
if (s) {
- if (g->start > s->start)
- error(ERR_FATAL, "sections %s ~ %s and %s overlap!",
+ if (s->start < origin)
+ error(ERR_FATAL|ERR_NOFILE, "section %s beings before program origin",
+ s->name);
+ if (g->start > s->start)
+ error(ERR_FATAL|ERR_NOFILE, "sections %s ~ %s and %s overlap!",
gs->name, g->name, s->name);
if (pend > s->start)
- error(ERR_FATAL, "sections %s and %s overlap!",
+ error(ERR_FATAL|ERR_NOFILE, "sections %s and %s overlap!",
g->name, s->name);
}
/* Remember this section as the latest >0 length section. */
@@ -445,11 +444,13 @@ static void bin_cleanup(int debuginfo)
for (s = sections; s->next; s = s->next) ;
s->next = nobits;
last_progbits = s;
- /* Scan for sections that don't have a vstart address. If we find one we'll
- * attempt to compute its vstart. If we can't compute the vstart, we leave
- * it alone and come back to it in a subsequent scan. We continue scanning
- * and re-scanning until we've gone one full cycle without computing any
- * vstarts. */
+ /*
+ * Scan for sections that don't have a vstart address. If we find
+ * one we'll attempt to compute its vstart. If we can't compute
+ * the vstart, we leave it alone and come back to it in a
+ * subsequent scan. We continue scanning and re-scanning until
+ * we've gone one full cycle without computing any vstarts.
+ */
do { /* Do one full scan of the sections list. */
for (h = 0, g = sections; g; g = g->next) {
if (g->flags & VSTART_DEFINED)
@@ -459,13 +460,14 @@ static void bin_cleanup(int debuginfo)
for (s = sections; s && strcmp(g->vfollows, s->name);
s = s->next) ;
if (!s)
- error(ERR_FATAL,
+ error(ERR_FATAL|ERR_NOFILE,
"section %s vfollows unknown section (%s)",
g->name, g->vfollows);
} else if (g->ifollows != NULL)
for (s = sections; s && (s != g->ifollows); s = s->next) ;
- /* The .bss section is the only one with ifollows = NULL. In this case we
- * implicitly follow the last progbits section. */
+ /* The .bss section is the only one with ifollows = NULL.
+ In this case we implicitly follow the last progbits
+ section. */
else
s = last_progbits;
@@ -476,9 +478,8 @@ static void bin_cleanup(int debuginfo)
g->flags |= VALIGN_DEFINED;
}
/* Compute the vstart address. */
- g->vstart =
- (s->vstart + s->length + g->valign - 1) & ~(g->valign -
- 1);
+ g->vstart = (s->vstart + s->length + g->valign - 1)
+ & ~(g->valign - 1);
g->flags |= VSTART_DEFINED;
h++;
/* Start and vstart mean the same thing for nobits sections. */
@@ -499,7 +500,7 @@ static void bin_cleanup(int debuginfo)
}
}
if (h)
- error(ERR_FATAL, "circular vfollows path detected");
+ error(ERR_FATAL|ERR_NOFILE, "circular vfollows path detected");
#ifdef DEBUG
fprintf(stdout,