summaryrefslogtreecommitdiff
path: root/output
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2010-05-06 17:52:57 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2010-05-06 17:52:57 -0700
commit931ce775cfcaec93f7c2df90d32023f2544373ed (patch)
tree77a608498b0ed9be077795a590eb6af3fdb078fd /output
parentbce369022a23010e97d37a514a4c59f4ad5e840a (diff)
downloadnasm-931ce775cfcaec93f7c2df90d32023f2544373ed.tar.gz
outobj: properly error on unsupported relocations
Error out on any relocations not supported by the backend. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'output')
-rw-r--r--output/outobj.c50
1 files changed, 38 insertions, 12 deletions
diff --git a/output/outobj.c b/output/outobj.c
index 2453c9fb..cae02148 100644
--- a/output/outobj.c
+++ b/output/outobj.c
@@ -1060,7 +1060,8 @@ static void obj_out(int32_t segto, const void *data,
orp = seg->orp;
orp->parm[0] = seg->currentpos;
- if (type == OUT_RAWDATA) {
+ switch (type) {
+ case OUT_RAWDATA:
ucdata = data;
while (size > 0) {
unsigned int len;
@@ -1074,8 +1075,14 @@ static void obj_out(int32_t segto, const void *data,
ucdata += len;
size -= len;
}
- } else if (type == OUT_ADDRESS || type == OUT_REL2ADR ||
- type == OUT_REL4ADR) {
+ break;
+
+ case OUT_ADDRESS:
+ case OUT_REL1ADR:
+ case OUT_REL2ADR:
+ case OUT_REL4ADR:
+ case OUT_REL8ADR:
+ {
int rsize;
if (segment == NO_SEG && type != OUT_ADDRESS)
@@ -1084,18 +1091,28 @@ static void obj_out(int32_t segto, const void *data,
if (segment >= SEG_ABS)
nasm_error(ERR_NONFATAL, "far-absolute relocations not supported"
" by OBJ format");
+
ldata = *(int64_t *)data;
- if (type == OUT_REL2ADR) {
- ldata += (size - 2);
- size = 2;
- } else if (type == OUT_REL4ADR) {
- ldata += (size - 4);
- size = 4;
+ if (type != OUT_ADDRESS) {
+ ldata += size;
+ size = realsize(type, size);
+ ldata -= size;
}
- if (size == 2)
+
+ switch (size) {
+ default:
+ nasm_error(ERR_NONFATAL, "OBJ format can only handle 16- or "
+ "32-byte relocations");
+ segment = NO_SEG; /* Don't actually generate a relocation */
+ break;
+ case 2:
orp = obj_word(orp, ldata);
- else
+ break;
+ case 4:
orp = obj_dword(orp, ldata);
+ break;
+ }
+
rsize = size;
if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
size == 4) {
@@ -1116,10 +1133,19 @@ static void obj_out(int32_t segto, const void *data,
(type == OUT_ADDRESS ? 0x4000 : 0),
segment, wrt, seg);
seg->currentpos += size;
- } else if (type == OUT_RESERVE) {
+ break;
+ }
+
+ default:
+ nasm_error(ERR_NONFATAL,
+ "Relocation type not supported by output format");
+ /* fall through */
+
+ case OUT_RESERVE:
if (orp->committed)
orp = obj_bump(orp);
seg->currentpos += size;
+ break;
}
obj_commit(orp);
}