mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-03-19 18:00:23 +08:00
Don't combine type and size into a single argument
Don't combine type and size into a single argument; *every* backend immediately breaks them apart, so it's really just a huge waste of effort. Additionally, it avoids using short immediates in the resulting code, which is a bad thing.
This commit is contained in:
parent
7eaf919a22
commit
34f6fb0a65
182
assemble.c
182
assemble.c
@ -164,44 +164,37 @@ static void warn_overflow(int size, int64_t data)
|
||||
* generator at the same time.
|
||||
*/
|
||||
static void out(int64_t offset, int32_t segto, const void *data,
|
||||
uint64_t type, int32_t segment, int32_t wrt)
|
||||
enum out_type type, uint64_t size,
|
||||
int32_t segment, int32_t wrt)
|
||||
{
|
||||
static int32_t lineno = 0; /* static!!! */
|
||||
static char *lnfname = NULL;
|
||||
uint8_t p[8];
|
||||
|
||||
if ((type & OUT_TYPMASK) == OUT_ADDRESS) {
|
||||
if (segment != NO_SEG || wrt != NO_SEG) {
|
||||
/*
|
||||
* This address is relocated. We must write it as
|
||||
* OUT_ADDRESS, so there's no work to be done here.
|
||||
*/
|
||||
list->output(offset, data, type);
|
||||
} else {
|
||||
uint8_t p[8], *q = p;
|
||||
/*
|
||||
* This is a non-relocated address, and we're going to
|
||||
* convert it into RAWDATA format.
|
||||
*/
|
||||
if ((type & OUT_SIZMASK) == 4) {
|
||||
WRITELONG(q, *(int32_t *)data);
|
||||
list->output(offset, p, OUT_RAWDATA + 4);
|
||||
} else if ((type & OUT_SIZMASK) == 8) {
|
||||
WRITEDLONG(q, *(int64_t *)data);
|
||||
list->output(offset, p, OUT_RAWDATA + 8);
|
||||
} else {
|
||||
WRITESHORT(q, *(int32_t *)data);
|
||||
list->output(offset, p, OUT_RAWDATA + 2);
|
||||
}
|
||||
}
|
||||
} else if ((type & OUT_TYPMASK) == OUT_RAWDATA) {
|
||||
list->output(offset, data, type);
|
||||
} else if ((type & OUT_TYPMASK) == OUT_RESERVE) {
|
||||
list->output(offset, NULL, type);
|
||||
} else if ((type & OUT_TYPMASK) == OUT_REL2ADR ||
|
||||
(type & OUT_TYPMASK) == OUT_REL4ADR) {
|
||||
list->output(offset, data, type);
|
||||
if (type == OUT_ADDRESS && segment == NO_SEG && wrt == NO_SEG) {
|
||||
/*
|
||||
* This is a non-relocated address, and we're going to
|
||||
* convert it into RAWDATA format.
|
||||
*/
|
||||
uint8_t *q = p;
|
||||
|
||||
switch (size) {
|
||||
case 2:
|
||||
WRITESHORT(q, *(int32_t *)data);
|
||||
break;
|
||||
case 4:
|
||||
WRITELONG(q, *(int32_t *)data);
|
||||
break;
|
||||
case 8:
|
||||
WRITEDLONG(q, *(int64_t *)data);
|
||||
break;
|
||||
}
|
||||
data = p;
|
||||
type = OUT_RAWDATA;
|
||||
}
|
||||
|
||||
list->output(offset, data, type, size);
|
||||
|
||||
/*
|
||||
* this call to src_get determines when we call the
|
||||
* debug-format-specific "linenum" function
|
||||
@ -215,7 +208,7 @@ static void out(int64_t offset, int32_t segto, const void *data,
|
||||
outfmt->current_dfmt->linenum(lnfname, lineno, segto);
|
||||
}
|
||||
|
||||
outfmt->output(segto, data, type, segment, wrt);
|
||||
outfmt->output(segto, data, type, size, segment, wrt);
|
||||
}
|
||||
|
||||
static int jmp_match(int32_t segment, int64_t offset, int bits,
|
||||
@ -302,26 +295,26 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
|
||||
else {
|
||||
uint8_t out_byte = e->offset;
|
||||
out(offset, segment, &out_byte,
|
||||
OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
}
|
||||
} else if (wsize > 8) {
|
||||
errfunc(ERR_NONFATAL, "integer supplied to a DT or DO"
|
||||
" instruction");
|
||||
} else
|
||||
out(offset, segment, &e->offset,
|
||||
OUT_ADDRESS + wsize, e->segment, e->wrt);
|
||||
OUT_ADDRESS, wsize, e->segment, e->wrt);
|
||||
offset += wsize;
|
||||
} else if (e->type == EOT_DB_STRING) {
|
||||
int align;
|
||||
|
||||
out(offset, segment, e->stringval,
|
||||
OUT_RAWDATA + e->stringlen, NO_SEG, NO_SEG);
|
||||
OUT_RAWDATA, e->stringlen, NO_SEG, NO_SEG);
|
||||
align = e->stringlen % wsize;
|
||||
|
||||
if (align) {
|
||||
align = wsize - align;
|
||||
out(offset, segment, "\0\0\0\0\0\0\0\0",
|
||||
OUT_RAWDATA + align, NO_SEG, NO_SEG);
|
||||
OUT_RAWDATA, align, NO_SEG, NO_SEG);
|
||||
}
|
||||
offset += e->stringlen + align;
|
||||
}
|
||||
@ -331,7 +324,7 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
|
||||
* Dummy call to list->output to give the offset to the
|
||||
* listing module.
|
||||
*/
|
||||
list->output(offset, NULL, OUT_RAWDATA);
|
||||
list->output(offset, NULL, OUT_RAWDATA, 0);
|
||||
list->uplevel(LIST_TIMES);
|
||||
}
|
||||
}
|
||||
@ -393,7 +386,7 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
|
||||
* Dummy call to list->output to give the offset to the
|
||||
* listing module.
|
||||
*/
|
||||
list->output(offset, NULL, OUT_RAWDATA);
|
||||
list->output(offset, NULL, OUT_RAWDATA, 0);
|
||||
list->uplevel(LIST_INCBIN);
|
||||
while (t--) {
|
||||
int32_t l;
|
||||
@ -416,7 +409,7 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
|
||||
t = 0; /* Try to exit cleanly */
|
||||
break;
|
||||
}
|
||||
out(offset, segment, buf, OUT_RAWDATA + m,
|
||||
out(offset, segment, buf, OUT_RAWDATA, m,
|
||||
NO_SEG, NO_SEG);
|
||||
l -= m;
|
||||
}
|
||||
@ -427,7 +420,7 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
|
||||
* Dummy call to list->output to give the offset to the
|
||||
* listing module.
|
||||
*/
|
||||
list->output(offset, NULL, OUT_RAWDATA);
|
||||
list->output(offset, NULL, OUT_RAWDATA, 0);
|
||||
list->uplevel(LIST_TIMES);
|
||||
list->downlevel(LIST_TIMES);
|
||||
}
|
||||
@ -553,7 +546,7 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
|
||||
error(ERR_PANIC, "invalid instruction prefix");
|
||||
}
|
||||
if (c != 0) {
|
||||
out(offset, segment, &c, OUT_RAWDATA + 1,
|
||||
out(offset, segment, &c, OUT_RAWDATA, 1,
|
||||
NO_SEG, NO_SEG);
|
||||
offset++;
|
||||
}
|
||||
@ -567,7 +560,7 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
|
||||
* Dummy call to list->output to give the offset to the
|
||||
* listing module.
|
||||
*/
|
||||
list->output(offset, NULL, OUT_RAWDATA);
|
||||
list->output(offset, NULL, OUT_RAWDATA, 0);
|
||||
list->uplevel(LIST_TIMES);
|
||||
}
|
||||
}
|
||||
@ -1092,7 +1085,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
|
||||
#define EMIT_REX() \
|
||||
if (!(ins->rex & REX_D) && (ins->rex & REX_REAL) && (bits == 64)) { \
|
||||
ins->rex = (ins->rex & REX_REAL)|REX_P; \
|
||||
out(offset, segment, &ins->rex, OUT_RAWDATA+1, NO_SEG, NO_SEG); \
|
||||
out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
|
||||
ins->rex = 0; \
|
||||
offset += 1; \
|
||||
}
|
||||
@ -1119,7 +1112,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
case 02:
|
||||
case 03:
|
||||
EMIT_REX();
|
||||
out(offset, segment, codes, OUT_RAWDATA + c, NO_SEG, NO_SEG);
|
||||
out(offset, segment, codes, OUT_RAWDATA, c, NO_SEG, NO_SEG);
|
||||
codes += c;
|
||||
offset += c;
|
||||
break;
|
||||
@ -1143,7 +1136,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
errfunc(ERR_PANIC,
|
||||
"bizarre 8086 segment register received");
|
||||
}
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset++;
|
||||
break;
|
||||
|
||||
@ -1160,7 +1153,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
errfunc(ERR_PANIC,
|
||||
"bizarre 386 segment register received");
|
||||
}
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset++;
|
||||
break;
|
||||
|
||||
@ -1170,7 +1163,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
case 013:
|
||||
EMIT_REX();
|
||||
bytes[0] = *codes++ + ((regval(opx)) & 7);
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
break;
|
||||
|
||||
@ -1184,11 +1177,11 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
|
||||
if (opx->segment != NO_SEG) {
|
||||
data = opx->offset;
|
||||
out(offset, segment, &data, OUT_ADDRESS + 1,
|
||||
out(offset, segment, &data, OUT_ADDRESS, 1,
|
||||
opx->segment, opx->wrt);
|
||||
} else {
|
||||
bytes[0] = opx->offset;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
|
||||
NO_SEG);
|
||||
}
|
||||
offset += 1;
|
||||
@ -1203,11 +1196,11 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
}
|
||||
if (opx->segment != NO_SEG) {
|
||||
data = opx->offset;
|
||||
out(offset, segment, &data, OUT_ADDRESS + 1,
|
||||
out(offset, segment, &data, OUT_ADDRESS, 1,
|
||||
opx->segment, opx->wrt);
|
||||
} else {
|
||||
bytes[0] = opx->offset;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
|
||||
NO_SEG);
|
||||
}
|
||||
offset += 1;
|
||||
@ -1221,11 +1214,11 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
errfunc(ERR_WARNING, "unsigned byte value exceeds bounds");
|
||||
if (opx->segment != NO_SEG) {
|
||||
data = opx->offset;
|
||||
out(offset, segment, &data, OUT_ADDRESS + 1,
|
||||
out(offset, segment, &data, OUT_ADDRESS, 1,
|
||||
opx->segment, opx->wrt);
|
||||
} else {
|
||||
bytes[0] = opx->offset;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
|
||||
NO_SEG);
|
||||
}
|
||||
offset += 1;
|
||||
@ -1238,7 +1231,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
data = opx->offset;
|
||||
if (opx->segment == NO_SEG && opx->wrt == NO_SEG)
|
||||
warn_overflow(2, data);
|
||||
out(offset, segment, &data, OUT_ADDRESS + 2,
|
||||
out(offset, segment, &data, OUT_ADDRESS, 2,
|
||||
opx->segment, opx->wrt);
|
||||
offset += 2;
|
||||
break;
|
||||
@ -1254,7 +1247,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
data = opx->offset;
|
||||
if (opx->segment == NO_SEG && opx->wrt == NO_SEG)
|
||||
warn_overflow(size, data);
|
||||
out(offset, segment, &data, OUT_ADDRESS + size,
|
||||
out(offset, segment, &data, OUT_ADDRESS, size,
|
||||
opx->segment, opx->wrt);
|
||||
offset += size;
|
||||
break;
|
||||
@ -1264,7 +1257,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
case 042:
|
||||
case 043:
|
||||
data = opx->offset;
|
||||
out(offset, segment, &data, OUT_ADDRESS + 4,
|
||||
out(offset, segment, &data, OUT_ADDRESS, 4,
|
||||
opx->segment, opx->wrt);
|
||||
offset += 4;
|
||||
break;
|
||||
@ -1278,7 +1271,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
if (opx->segment == NO_SEG &&
|
||||
opx->wrt == NO_SEG)
|
||||
warn_overflow(size, data);
|
||||
out(offset, segment, &data, OUT_ADDRESS + size,
|
||||
out(offset, segment, &data, OUT_ADDRESS, size,
|
||||
opx->segment, opx->wrt);
|
||||
offset += size;
|
||||
break;
|
||||
@ -1294,7 +1287,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
if (data > 127 || data < -128)
|
||||
errfunc(ERR_NONFATAL, "short jump is out of range");
|
||||
bytes[0] = data;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
break;
|
||||
|
||||
@ -1303,7 +1296,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
case 056:
|
||||
case 057:
|
||||
data = (int64_t)opx->offset;
|
||||
out(offset, segment, &data, OUT_ADDRESS + 8,
|
||||
out(offset, segment, &data, OUT_ADDRESS, 8,
|
||||
opx->segment, opx->wrt);
|
||||
offset += 8;
|
||||
break;
|
||||
@ -1315,12 +1308,12 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
if (opx->segment != segment) {
|
||||
data = opx->offset;
|
||||
out(offset, segment, &data,
|
||||
OUT_REL2ADR + insn_end - offset,
|
||||
OUT_REL2ADR, insn_end - offset,
|
||||
opx->segment, opx->wrt);
|
||||
} else {
|
||||
data = opx->offset - insn_end;
|
||||
out(offset, segment, &data,
|
||||
OUT_ADDRESS + 2, NO_SEG, NO_SEG);
|
||||
OUT_ADDRESS, 2, NO_SEG, NO_SEG);
|
||||
}
|
||||
offset += 2;
|
||||
break;
|
||||
@ -1334,14 +1327,14 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
else
|
||||
size = (bits == 16) ? 2 : 4;
|
||||
if (opx->segment != segment) {
|
||||
int64_t reltype = (size == 2 ? OUT_REL2ADR : OUT_REL4ADR);
|
||||
data = opx->offset;
|
||||
out(offset, segment, &data, reltype + insn_end - offset,
|
||||
opx->segment, opx->wrt);
|
||||
out(offset, segment, &data,
|
||||
size == 2 ? OUT_REL2ADR : OUT_REL4ADR,
|
||||
insn_end - offset, opx->segment, opx->wrt);
|
||||
} else {
|
||||
data = opx->offset - insn_end;
|
||||
out(offset, segment, &data,
|
||||
OUT_ADDRESS + size, NO_SEG, NO_SEG);
|
||||
OUT_ADDRESS, size, NO_SEG, NO_SEG);
|
||||
}
|
||||
offset += size;
|
||||
break;
|
||||
@ -1353,12 +1346,12 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
if (opx->segment != segment) {
|
||||
data = opx->offset;
|
||||
out(offset, segment, &data,
|
||||
OUT_REL4ADR + insn_end - offset,
|
||||
OUT_REL4ADR, insn_end - offset,
|
||||
opx->segment, opx->wrt);
|
||||
} else {
|
||||
data = opx->offset - insn_end;
|
||||
out(offset, segment, &data,
|
||||
OUT_ADDRESS + 4, NO_SEG, NO_SEG);
|
||||
OUT_ADDRESS, 4, NO_SEG, NO_SEG);
|
||||
}
|
||||
offset += 4;
|
||||
break;
|
||||
@ -1371,7 +1364,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
errfunc(ERR_NONFATAL, "value referenced by FAR is not"
|
||||
" relocatable");
|
||||
data = 0L;
|
||||
out(offset, segment, &data, OUT_ADDRESS + 2,
|
||||
out(offset, segment, &data, OUT_ADDRESS, 2,
|
||||
outfmt->segbase(1 + opx->segment),
|
||||
opx->wrt);
|
||||
offset += 2;
|
||||
@ -1384,14 +1377,14 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
data = opx->offset;
|
||||
if (is_sbyte(ins, c & 3, 16)) {
|
||||
bytes[0] = data;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
|
||||
NO_SEG);
|
||||
offset++;
|
||||
} else {
|
||||
if (opx->segment == NO_SEG &&
|
||||
opx->wrt == NO_SEG)
|
||||
warn_overflow(2, data);
|
||||
out(offset, segment, &data, OUT_ADDRESS + 2,
|
||||
out(offset, segment, &data, OUT_ADDRESS, 2,
|
||||
opx->segment, opx->wrt);
|
||||
offset += 2;
|
||||
}
|
||||
@ -1406,7 +1399,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
bytes[0] = *codes++;
|
||||
if (is_sbyte(ins, c & 3, 16))
|
||||
bytes[0] |= 2; /* s-bit */
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset++;
|
||||
break;
|
||||
|
||||
@ -1417,11 +1410,11 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
data = opx->offset;
|
||||
if (is_sbyte(ins, c & 3, 32)) {
|
||||
bytes[0] = data;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
|
||||
NO_SEG);
|
||||
offset++;
|
||||
} else {
|
||||
out(offset, segment, &data, OUT_ADDRESS + 4,
|
||||
out(offset, segment, &data, OUT_ADDRESS, 4,
|
||||
opx->segment, opx->wrt);
|
||||
offset += 4;
|
||||
}
|
||||
@ -1436,7 +1429,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
bytes[0] = *codes++;
|
||||
if (is_sbyte(ins, c & 3, 32))
|
||||
bytes[0] |= 2; /* s-bit */
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset++;
|
||||
break;
|
||||
|
||||
@ -1453,7 +1446,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
case 0170:
|
||||
EMIT_REX();
|
||||
bytes[0] = 0;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
break;
|
||||
|
||||
@ -1463,7 +1456,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
(ins->rex & REX_OC ? 0x08 : 0) |
|
||||
(ins->rex & (REX_R|REX_X|REX_B));
|
||||
ins->rex = 0;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset++;
|
||||
break;
|
||||
|
||||
@ -1476,8 +1469,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
case 0310:
|
||||
if (bits == 32 && !has_prefix(ins, PPS_ASIZE, P_A16)) {
|
||||
*bytes = 0x67;
|
||||
out(offset, segment, bytes,
|
||||
OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
} else
|
||||
offset += 0;
|
||||
@ -1486,8 +1478,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
case 0311:
|
||||
if (bits != 32 && !has_prefix(ins, PPS_ASIZE, P_A32)) {
|
||||
*bytes = 0x67;
|
||||
out(offset, segment, bytes,
|
||||
OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
} else
|
||||
offset += 0;
|
||||
@ -1503,8 +1494,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
case 0320:
|
||||
if (bits != 16) {
|
||||
*bytes = 0x66;
|
||||
out(offset, segment, bytes,
|
||||
OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
} else
|
||||
offset += 0;
|
||||
@ -1513,8 +1503,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
case 0321:
|
||||
if (bits == 16) {
|
||||
*bytes = 0x66;
|
||||
out(offset, segment, bytes,
|
||||
OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
} else
|
||||
offset += 0;
|
||||
@ -1530,7 +1519,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
|
||||
case 0330:
|
||||
*bytes = *codes++ ^ condval[ins->condition];
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
break;
|
||||
|
||||
@ -1540,14 +1529,14 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
case 0332:
|
||||
case 0333:
|
||||
*bytes = c - 0332 + 0xF2;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
break;
|
||||
|
||||
case 0334:
|
||||
if (ins->rex & REX_R) {
|
||||
*bytes = 0xF0;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
}
|
||||
ins->rex &= ~(REX_L|REX_R);
|
||||
@ -1565,7 +1554,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
int64_t size = ins->oprs[0].offset << (c & 3);
|
||||
if (size > 0)
|
||||
out(offset, segment, NULL,
|
||||
OUT_RESERVE + size, NO_SEG, NO_SEG);
|
||||
OUT_RESERVE, size, NO_SEG, NO_SEG);
|
||||
offset += size;
|
||||
}
|
||||
break;
|
||||
@ -1577,7 +1566,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
case 0366:
|
||||
case 0367:
|
||||
*bytes = c - 0366 + 0x66;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
break;
|
||||
|
||||
@ -1588,7 +1577,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
|
||||
case 0373:
|
||||
*bytes = bits == 16 ? 3 : 5;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
break;
|
||||
|
||||
@ -1632,8 +1621,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
}
|
||||
|
||||
s = p - bytes;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + s,
|
||||
NO_SEG, NO_SEG);
|
||||
out(offset, segment, bytes, OUT_RAWDATA, s, NO_SEG, NO_SEG);
|
||||
|
||||
switch (ea_data.bytes) {
|
||||
case 0:
|
||||
@ -1641,12 +1629,12 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
case 1:
|
||||
if (ins->oprs[(c >> 3) & 7].segment != NO_SEG) {
|
||||
data = ins->oprs[(c >> 3) & 7].offset;
|
||||
out(offset, segment, &data, OUT_ADDRESS + 1,
|
||||
out(offset, segment, &data, OUT_ADDRESS, 1,
|
||||
ins->oprs[(c >> 3) & 7].segment,
|
||||
ins->oprs[(c >> 3) & 7].wrt);
|
||||
} else {
|
||||
*bytes = ins->oprs[(c >> 3) & 7].offset;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1,
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1,
|
||||
NO_SEG, NO_SEG);
|
||||
}
|
||||
s++;
|
||||
@ -1657,8 +1645,8 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
data = ins->oprs[(c >> 3) & 7].offset;
|
||||
warn_overflow(ea_data.bytes, data);
|
||||
out(offset, segment, &data,
|
||||
(ea_data.rip ? OUT_REL4ADR : OUT_ADDRESS)
|
||||
+ ea_data.bytes,
|
||||
ea_data.rip ? OUT_REL4ADR : OUT_ADDRESS,
|
||||
ea_data.bytes,
|
||||
ins->oprs[(c >> 3) & 7].segment,
|
||||
ins->oprs[(c >> 3) & 7].wrt);
|
||||
s += ea_data.bytes;
|
||||
|
55
listing.c
55
listing.c
@ -125,18 +125,15 @@ static void list_out(int32_t offset, char *str)
|
||||
strcat(listdata, str);
|
||||
}
|
||||
|
||||
static void list_output(int32_t offset, const void *data, uint64_t type)
|
||||
static void list_output(int32_t offset, const void *data,
|
||||
enum out_type type, uint64_t size)
|
||||
{
|
||||
uint64_t typ, size;
|
||||
|
||||
if (!listp || suppress || user_nolist) /* fbk - 9/2/00 */
|
||||
return;
|
||||
|
||||
typ = type & OUT_TYPMASK;
|
||||
size = type & OUT_SIZMASK;
|
||||
|
||||
|
||||
if (typ == OUT_RAWDATA) {
|
||||
switch (type) {
|
||||
case OUT_RAWDATA:
|
||||
{
|
||||
uint8_t const *p = data;
|
||||
char q[3];
|
||||
while (size--) {
|
||||
@ -145,7 +142,10 @@ static void list_output(int32_t offset, const void *data, uint64_t type)
|
||||
list_out(offset++, q);
|
||||
p++;
|
||||
}
|
||||
} else if (typ == OUT_ADDRESS) {
|
||||
break;
|
||||
}
|
||||
case OUT_ADDRESS:
|
||||
{
|
||||
uint64_t d = *(int64_t *)data;
|
||||
char q[20];
|
||||
uint8_t p[8], *r = p;
|
||||
@ -182,7 +182,10 @@ static void list_output(int32_t offset, const void *data, uint64_t type)
|
||||
HEX(q + 3, p[1]);
|
||||
list_out(offset, q);
|
||||
}
|
||||
} else if (typ == OUT_REL2ADR) {
|
||||
break;
|
||||
}
|
||||
case OUT_REL2ADR:
|
||||
{
|
||||
uint32_t d = *(int32_t *)data;
|
||||
char q[11];
|
||||
uint8_t p[4], *r = p;
|
||||
@ -193,7 +196,10 @@ static void list_output(int32_t offset, const void *data, uint64_t type)
|
||||
HEX(q + 1, p[0]);
|
||||
HEX(q + 3, p[1]);
|
||||
list_out(offset, q);
|
||||
} else if (typ == OUT_REL4ADR) {
|
||||
break;
|
||||
}
|
||||
case OUT_REL4ADR:
|
||||
{
|
||||
uint32_t d = *(int32_t *)data;
|
||||
char q[11];
|
||||
uint8_t p[4], *r = p;
|
||||
@ -206,10 +212,35 @@ static void list_output(int32_t offset, const void *data, uint64_t type)
|
||||
HEX(q + 5, p[2]);
|
||||
HEX(q + 7, p[3]);
|
||||
list_out(offset, q);
|
||||
} else if (typ == OUT_RESERVE) {
|
||||
break;
|
||||
}
|
||||
case OUT_REL8ADR:
|
||||
{
|
||||
uint64_t d = *(int64_t *)data;
|
||||
char q[19];
|
||||
uint8_t p[4], *r = p;
|
||||
q[0] = '(';
|
||||
q[17] = ')';
|
||||
q[18] = '\0';
|
||||
WRITEDLONG(r, d);
|
||||
HEX(q + 1, p[0]);
|
||||
HEX(q + 3, p[1]);
|
||||
HEX(q + 5, p[2]);
|
||||
HEX(q + 7, p[3]);
|
||||
HEX(q + 9, p[4]);
|
||||
HEX(q + 11, p[5]);
|
||||
HEX(q + 13, p[6]);
|
||||
HEX(q + 15, p[7]);
|
||||
list_out(offset, q);
|
||||
break;
|
||||
}
|
||||
case OUT_RESERVE:
|
||||
{
|
||||
char q[20];
|
||||
snprintf(q, sizeof(q), "<res %08"PRIX64">", size);
|
||||
list_out(offset, q);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
60
nasm.h
60
nasm.h
@ -51,6 +51,32 @@
|
||||
*/
|
||||
struct ofmt;
|
||||
|
||||
/*
|
||||
* values for the `type' parameter to an output function.
|
||||
*
|
||||
* Exceptions are OUT_RELxADR, which denote an x-byte relocation
|
||||
* which will be a relative jump. For this we need to know the
|
||||
* distance in bytes from the start of the relocated record until
|
||||
* the end of the containing instruction. _This_ is what is stored
|
||||
* in the size part of the parameter, in this case.
|
||||
*
|
||||
* Also OUT_RESERVE denotes reservation of N bytes of BSS space,
|
||||
* and the contents of the "data" parameter is irrelevant.
|
||||
*
|
||||
* The "data" parameter for the output function points to a "int32_t",
|
||||
* containing the address in question, unless the type is
|
||||
* OUT_RAWDATA, in which case it points to an "uint8_t"
|
||||
* array.
|
||||
*/
|
||||
enum out_type {
|
||||
OUT_RAWDATA, /* Plain bytes */
|
||||
OUT_ADDRESS, /* An address (symbol value) */
|
||||
OUT_RESERVE, /* Reserved bytes (RESB et al) */
|
||||
OUT_REL2ADR, /* 2-byte relative address */
|
||||
OUT_REL4ADR, /* 4-byte relative address */
|
||||
OUT_REL8ADR, /* 8-byte relative address */
|
||||
};
|
||||
|
||||
/*
|
||||
* -----------------------
|
||||
* Other function typedefs
|
||||
@ -95,12 +121,12 @@ typedef struct {
|
||||
* output-format interface, only OUT_ADDRESS will _always_ be
|
||||
* displayed as if it's relocatable, so ensure that any non-
|
||||
* relocatable address has been converted to OUT_RAWDATA by
|
||||
* then. Note that OUT_RAWDATA+0 is a valid data type, and is a
|
||||
* then. Note that OUT_RAWDATA,0 is a valid data type, and is a
|
||||
* dummy call used to give the listing generator an offset to
|
||||
* work with when doing things like uplevel(LIST_TIMES) or
|
||||
* uplevel(LIST_INCBIN).
|
||||
*/
|
||||
void (*output) (int32_t, const void *, uint64_t);
|
||||
void (*output) (int32_t, const void *, enum out_type, uint64_t);
|
||||
|
||||
/*
|
||||
* Called to send a text line to the listing generator. The
|
||||
@ -709,7 +735,8 @@ struct ofmt {
|
||||
* The `type' argument specifies the type of output data, and
|
||||
* usually the size as well: its contents are described below.
|
||||
*/
|
||||
void (*output) (int32_t segto, const void *data, uint64_t type,
|
||||
void (*output) (int32_t segto, const void *data,
|
||||
enum out_type type, uint64_t size,
|
||||
int32_t segment, int32_t wrt);
|
||||
|
||||
/*
|
||||
@ -822,33 +849,6 @@ struct ofmt {
|
||||
void (*cleanup) (int debuginfo);
|
||||
};
|
||||
|
||||
/*
|
||||
* values for the `type' parameter to an output function. Each one
|
||||
* must have the actual number of _bytes_ added to it.
|
||||
*
|
||||
* Exceptions are OUT_RELxADR, which denote an x-byte relocation
|
||||
* which will be a relative jump. For this we need to know the
|
||||
* distance in bytes from the start of the relocated record until
|
||||
* the end of the containing instruction. _This_ is what is stored
|
||||
* in the size part of the parameter, in this case.
|
||||
*
|
||||
* Also OUT_RESERVE denotes reservation of N bytes of BSS space,
|
||||
* and the contents of the "data" parameter is irrelevant.
|
||||
*
|
||||
* The "data" parameter for the output function points to a "int32_t",
|
||||
* containing the address in question, unless the type is
|
||||
* OUT_RAWDATA, in which case it points to an "uint8_t"
|
||||
* array.
|
||||
*/
|
||||
#define OUT_RAWDATA UINT64_C(0x0000000000000000)
|
||||
#define OUT_ADDRESS UINT64_C(0x1000000000000000)
|
||||
#define OUT_REL2ADR UINT64_C(0x2000000000000000)
|
||||
#define OUT_REL4ADR UINT64_C(0x3000000000000000)
|
||||
#define OUT_RESERVE UINT64_C(0x4000000000000000)
|
||||
#define OUT_REL8ADR UINT64_C(0x5000000000000000)
|
||||
#define OUT_TYPMASK UINT64_C(0xF000000000000000)
|
||||
#define OUT_SIZMASK UINT64_C(0x0FFFFFFFFFFFFFFF)
|
||||
#define OUT_TYPE(x) ((int)((x) >> 60))
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------------
|
||||
|
@ -568,16 +568,14 @@ static int32_t aout_add_gotoff_reloc(struct Section *sect, int32_t segment,
|
||||
return offset - asym->value;
|
||||
}
|
||||
|
||||
static void aout_out(int32_t segto, const void *data, uint64_t type,
|
||||
static void aout_out(int32_t segto, const void *data,
|
||||
enum out_type type, uint64_t size,
|
||||
int32_t segment, int32_t wrt)
|
||||
{
|
||||
struct Section *s;
|
||||
int32_t realbytes = type & OUT_SIZMASK;
|
||||
int32_t addr;
|
||||
uint8_t mydata[4], *p;
|
||||
|
||||
type &= OUT_TYPMASK;
|
||||
|
||||
/*
|
||||
* handle absolute-assembly (structure definitions)
|
||||
*/
|
||||
@ -604,10 +602,10 @@ static void aout_out(int32_t segto, const void *data, uint64_t type,
|
||||
error(ERR_WARNING, "attempt to initialize memory in the"
|
||||
" BSS section: ignored");
|
||||
if (type == OUT_REL2ADR)
|
||||
realbytes = 2;
|
||||
size = 2;
|
||||
else if (type == OUT_REL4ADR)
|
||||
realbytes = 4;
|
||||
sbss.len += realbytes;
|
||||
size = 4;
|
||||
sbss.len += size;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -616,13 +614,13 @@ static void aout_out(int32_t segto, const void *data, uint64_t type,
|
||||
error(ERR_WARNING, "uninitialized space declared in"
|
||||
" %s section: zeroing",
|
||||
(segto == stext.index ? "code" : "data"));
|
||||
aout_sect_write(s, NULL, realbytes);
|
||||
aout_sect_write(s, NULL, size);
|
||||
} else
|
||||
sbss.len += realbytes;
|
||||
sbss.len += size;
|
||||
} else if (type == OUT_RAWDATA) {
|
||||
if (segment != NO_SEG)
|
||||
error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
|
||||
aout_sect_write(s, data, realbytes);
|
||||
aout_sect_write(s, data, size);
|
||||
} else if (type == OUT_ADDRESS) {
|
||||
addr = *(int32_t *)data;
|
||||
if (segment != NO_SEG) {
|
||||
@ -632,7 +630,7 @@ static void aout_out(int32_t segto, const void *data, uint64_t type,
|
||||
} else {
|
||||
if (wrt == NO_SEG) {
|
||||
aout_add_reloc(s, segment, RELTYPE_ABSOLUTE,
|
||||
realbytes);
|
||||
size);
|
||||
} else if (!bsd) {
|
||||
error(ERR_NONFATAL,
|
||||
"Linux a.out format does not support"
|
||||
@ -640,19 +638,19 @@ static void aout_out(int32_t segto, const void *data, uint64_t type,
|
||||
wrt = NO_SEG; /* we can at least _try_ to continue */
|
||||
} else if (wrt == aout_gotpc_sect + 1) {
|
||||
is_pic = 0x40;
|
||||
aout_add_reloc(s, segment, RELTYPE_GOTPC, realbytes);
|
||||
aout_add_reloc(s, segment, RELTYPE_GOTPC, size);
|
||||
} else if (wrt == aout_gotoff_sect + 1) {
|
||||
is_pic = 0x40;
|
||||
addr = aout_add_gotoff_reloc(s, segment,
|
||||
addr, realbytes);
|
||||
addr, size);
|
||||
} else if (wrt == aout_got_sect + 1) {
|
||||
is_pic = 0x40;
|
||||
addr =
|
||||
aout_add_gsym_reloc(s, segment, addr, RELTYPE_GOT,
|
||||
realbytes, true);
|
||||
size, true);
|
||||
} else if (wrt == aout_sym_sect + 1) {
|
||||
addr = aout_add_gsym_reloc(s, segment, addr,
|
||||
RELTYPE_ABSOLUTE, realbytes,
|
||||
RELTYPE_ABSOLUTE, size,
|
||||
false);
|
||||
} else if (wrt == aout_plt_sect + 1) {
|
||||
is_pic = 0x40;
|
||||
@ -668,11 +666,11 @@ static void aout_out(int32_t segto, const void *data, uint64_t type,
|
||||
}
|
||||
}
|
||||
p = mydata;
|
||||
if (realbytes == 2)
|
||||
if (size == 2)
|
||||
WRITESHORT(p, addr);
|
||||
else
|
||||
WRITELONG(p, addr);
|
||||
aout_sect_write(s, mydata, realbytes);
|
||||
aout_sect_write(s, mydata, size);
|
||||
} else if (type == OUT_REL2ADR) {
|
||||
if (segment == segto)
|
||||
error(ERR_PANIC, "intra-segment OUT_REL2ADR");
|
||||
@ -701,7 +699,7 @@ static void aout_out(int32_t segto, const void *data, uint64_t type,
|
||||
}
|
||||
}
|
||||
p = mydata;
|
||||
WRITESHORT(p, *(int32_t *)data - (realbytes + s->len));
|
||||
WRITESHORT(p, *(int32_t *)data - (size + s->len));
|
||||
aout_sect_write(s, mydata, 2L);
|
||||
} else if (type == OUT_REL4ADR) {
|
||||
if (segment == segto)
|
||||
@ -731,7 +729,7 @@ static void aout_out(int32_t segto, const void *data, uint64_t type,
|
||||
}
|
||||
}
|
||||
p = mydata;
|
||||
WRITELONG(p, *(int32_t *)data - (realbytes + s->len));
|
||||
WRITELONG(p, *(int32_t *)data - (size + s->len));
|
||||
aout_sect_write(s, mydata, 4L);
|
||||
}
|
||||
}
|
||||
|
@ -254,11 +254,11 @@ static void as86_add_piece(struct Section *sect, int type, int32_t offset,
|
||||
p->number = raa_read(bsym, segment), p->type = 2;
|
||||
}
|
||||
|
||||
static void as86_out(int32_t segto, const void *data, uint64_t type,
|
||||
static void as86_out(int32_t segto, const void *data,
|
||||
enum out_type type, uint64_t size,
|
||||
int32_t segment, int32_t wrt)
|
||||
{
|
||||
struct Section *s;
|
||||
int64_t realbytes = type & OUT_SIZMASK;
|
||||
int32_t offset;
|
||||
uint8_t mydata[4], *p;
|
||||
|
||||
@ -267,8 +267,6 @@ static void as86_out(int32_t segto, const void *data, uint64_t type,
|
||||
error(ERR_NONFATAL, "WRT not supported by as86 output format");
|
||||
}
|
||||
|
||||
type &= OUT_TYPMASK;
|
||||
|
||||
/*
|
||||
* handle absolute-assembly (structure definitions)
|
||||
*/
|
||||
@ -295,10 +293,10 @@ static void as86_out(int32_t segto, const void *data, uint64_t type,
|
||||
error(ERR_WARNING, "attempt to initialize memory in the"
|
||||
" BSS section: ignored");
|
||||
if (type == OUT_REL2ADR)
|
||||
realbytes = 2;
|
||||
size = 2;
|
||||
else if (type == OUT_REL4ADR)
|
||||
realbytes = 4;
|
||||
bsslen += realbytes;
|
||||
size = 4;
|
||||
bsslen += size;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -307,15 +305,15 @@ static void as86_out(int32_t segto, const void *data, uint64_t type,
|
||||
error(ERR_WARNING, "uninitialized space declared in"
|
||||
" %s section: zeroing",
|
||||
(segto == stext.index ? "code" : "data"));
|
||||
as86_sect_write(s, NULL, realbytes);
|
||||
as86_add_piece(s, 0, 0L, 0L, realbytes, 0);
|
||||
as86_sect_write(s, NULL, size);
|
||||
as86_add_piece(s, 0, 0L, 0L, size, 0);
|
||||
} else
|
||||
bsslen += realbytes;
|
||||
bsslen += size;
|
||||
} else if (type == OUT_RAWDATA) {
|
||||
if (segment != NO_SEG)
|
||||
error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
|
||||
as86_sect_write(s, data, realbytes);
|
||||
as86_add_piece(s, 0, 0L, 0L, realbytes, 0);
|
||||
as86_sect_write(s, data, size);
|
||||
as86_add_piece(s, 0, 0L, 0L, size, 0);
|
||||
} else if (type == OUT_ADDRESS) {
|
||||
if (segment != NO_SEG) {
|
||||
if (segment % 2) {
|
||||
@ -323,13 +321,13 @@ static void as86_out(int32_t segto, const void *data, uint64_t type,
|
||||
" segment base references");
|
||||
} else {
|
||||
offset = *(int32_t *)data;
|
||||
as86_add_piece(s, 1, offset, segment, realbytes, 0);
|
||||
as86_add_piece(s, 1, offset, segment, size, 0);
|
||||
}
|
||||
} else {
|
||||
p = mydata;
|
||||
WRITELONG(p, *(int32_t *)data);
|
||||
as86_sect_write(s, data, realbytes);
|
||||
as86_add_piece(s, 0, 0L, 0L, realbytes, 0);
|
||||
as86_sect_write(s, data, size);
|
||||
as86_add_piece(s, 0, 0L, 0L, size, 0);
|
||||
}
|
||||
} else if (type == OUT_REL2ADR) {
|
||||
if (segment == segto)
|
||||
@ -340,7 +338,7 @@ static void as86_out(int32_t segto, const void *data, uint64_t type,
|
||||
" segment base references");
|
||||
} else {
|
||||
offset = *(int32_t *)data;
|
||||
as86_add_piece(s, 1, offset - realbytes + 2, segment, 2L,
|
||||
as86_add_piece(s, 1, offset - size + 2, segment, 2L,
|
||||
1);
|
||||
}
|
||||
}
|
||||
@ -353,7 +351,7 @@ static void as86_out(int32_t segto, const void *data, uint64_t type,
|
||||
" segment base references");
|
||||
} else {
|
||||
offset = *(int32_t *)data;
|
||||
as86_add_piece(s, 1, offset - realbytes + 4, segment, 4L,
|
||||
as86_add_piece(s, 1, offset - size + 4, segment, 4L,
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
@ -737,13 +737,12 @@ static void bin_cleanup(int debuginfo)
|
||||
}
|
||||
}
|
||||
|
||||
static void bin_out(int32_t segto, const void *data, uint64_t type,
|
||||
static void bin_out(int32_t segto, const void *data,
|
||||
enum out_type type, uint64_t size,
|
||||
int32_t segment, int32_t wrt)
|
||||
{
|
||||
uint8_t *p, mydata[8];
|
||||
struct Section *s;
|
||||
int64_t realbytes;
|
||||
|
||||
|
||||
if (wrt != NO_SEG) {
|
||||
wrt = NO_SEG; /* continue to do _something_ */
|
||||
@ -752,7 +751,7 @@ static void bin_out(int32_t segto, const void *data, uint64_t type,
|
||||
|
||||
/* Handle absolute-assembly (structure definitions). */
|
||||
if (segto == NO_SEG) {
|
||||
if ((type & OUT_TYPMASK) != OUT_RESERVE)
|
||||
if (type != OUT_RESERVE)
|
||||
error(ERR_NONFATAL, "attempt to assemble code in"
|
||||
" [ABSOLUTE] space");
|
||||
return;
|
||||
@ -765,17 +764,17 @@ static void bin_out(int32_t segto, const void *data, uint64_t type,
|
||||
|
||||
/* "Smart" section-type adaptation code. */
|
||||
if (!(s->flags & TYPE_DEFINED)) {
|
||||
if ((type & OUT_TYPMASK) == OUT_RESERVE)
|
||||
if (type == OUT_RESERVE)
|
||||
s->flags |= TYPE_DEFINED | TYPE_NOBITS;
|
||||
else
|
||||
s->flags |= TYPE_DEFINED | TYPE_PROGBITS;
|
||||
}
|
||||
|
||||
if ((s->flags & TYPE_NOBITS) && ((type & OUT_TYPMASK) != OUT_RESERVE))
|
||||
if ((s->flags & TYPE_NOBITS) && (type != OUT_RESERVE))
|
||||
error(ERR_WARNING, "attempt to initialize memory in a"
|
||||
" nobits section: ignored");
|
||||
|
||||
if ((type & OUT_TYPMASK) == OUT_ADDRESS) {
|
||||
if (type == OUT_ADDRESS) {
|
||||
if (segment != NO_SEG && !find_section_by_index(segment)) {
|
||||
if (segment % 2)
|
||||
error(ERR_NONFATAL, "binary output format does not support"
|
||||
@ -787,37 +786,44 @@ static void bin_out(int32_t segto, const void *data, uint64_t type,
|
||||
}
|
||||
if (s->flags & TYPE_PROGBITS) {
|
||||
if (segment != NO_SEG)
|
||||
add_reloc(s, type & OUT_SIZMASK, segment, -1L);
|
||||
add_reloc(s, size, segment, -1L);
|
||||
p = mydata;
|
||||
if ((type & OUT_SIZMASK) == 4)
|
||||
if (size == 4)
|
||||
WRITELONG(p, *(int32_t *)data);
|
||||
else if ((type & OUT_SIZMASK) == 8)
|
||||
else if (size == 8)
|
||||
WRITEDLONG(p, *(int64_t *)data);
|
||||
else
|
||||
WRITESHORT(p, *(int32_t *)data);
|
||||
saa_wbytes(s->contents, mydata, type & OUT_SIZMASK);
|
||||
saa_wbytes(s->contents, mydata, size);
|
||||
}
|
||||
s->length += type & OUT_SIZMASK;
|
||||
} else if ((type & OUT_TYPMASK) == OUT_RAWDATA) {
|
||||
type &= OUT_SIZMASK;
|
||||
s->length += size;
|
||||
} else if (type == OUT_RAWDATA) {
|
||||
if (s->flags & TYPE_PROGBITS)
|
||||
saa_wbytes(s->contents, data, type);
|
||||
s->length += type;
|
||||
} else if ((type & OUT_TYPMASK) == OUT_RESERVE) {
|
||||
type &= OUT_SIZMASK;
|
||||
saa_wbytes(s->contents, data, size);
|
||||
s->length += size;
|
||||
} else if (type == OUT_RESERVE) {
|
||||
if (s->flags & TYPE_PROGBITS) {
|
||||
error(ERR_WARNING, "uninitialized space declared in"
|
||||
" %s section: zeroing", s->name);
|
||||
saa_wbytes(s->contents, NULL, type);
|
||||
saa_wbytes(s->contents, NULL, size);
|
||||
}
|
||||
s->length += type;
|
||||
} else if ((type & OUT_TYPMASK) == OUT_REL2ADR ||
|
||||
(type & OUT_TYPMASK) == OUT_REL4ADR) {
|
||||
realbytes = (type & OUT_TYPMASK);
|
||||
if (realbytes == OUT_REL2ADR)
|
||||
realbytes = 2;
|
||||
else
|
||||
realbytes = 4;
|
||||
} else if (type == OUT_REL2ADR || type == OUT_REL4ADR ||
|
||||
type == OUT_REL8ADR) {
|
||||
switch (type) {
|
||||
case OUT_REL2ADR:
|
||||
size = 2;
|
||||
break;
|
||||
case OUT_REL4ADR:
|
||||
size = 4;
|
||||
break;
|
||||
case OUT_REL8ADR:
|
||||
size = 8;
|
||||
break;
|
||||
default:
|
||||
size = 0; /* Shut up warning */
|
||||
break;
|
||||
}
|
||||
if (segment != NO_SEG && !find_section_by_index(segment)) {
|
||||
if (segment % 2)
|
||||
error(ERR_NONFATAL, "binary output format does not support"
|
||||
@ -828,15 +834,16 @@ static void bin_out(int32_t segto, const void *data, uint64_t type,
|
||||
segment = NO_SEG;
|
||||
}
|
||||
if (s->flags & TYPE_PROGBITS) {
|
||||
add_reloc(s, realbytes, segment, segto);
|
||||
add_reloc(s, size, segment, segto);
|
||||
p = mydata;
|
||||
if (realbytes == 4)
|
||||
WRITELONG(p, *(int32_t *)data - realbytes - s->length);
|
||||
/* XXX: WHAT ABOUT SIZE == 8? */
|
||||
if (size == 4)
|
||||
WRITELONG(p, *(int32_t *)data - size - s->length);
|
||||
else
|
||||
WRITESHORT(p, *(int32_t *)data - realbytes - s->length);
|
||||
saa_wbytes(s->contents, mydata, realbytes);
|
||||
WRITESHORT(p, *(int32_t *)data - size - s->length);
|
||||
saa_wbytes(s->contents, mydata, size);
|
||||
}
|
||||
s->length += realbytes;
|
||||
s->length += size;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -456,11 +456,11 @@ static int32_t coff_add_reloc(struct Section *sect, int32_t segment,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void coff_out(int32_t segto, const void *data, uint64_t type,
|
||||
static void coff_out(int32_t segto, const void *data,
|
||||
enum out_type type, uint64_t size,
|
||||
int32_t segment, int32_t wrt)
|
||||
{
|
||||
struct Section *s;
|
||||
int32_t realbytes = type & OUT_SIZMASK;
|
||||
uint8_t mydata[8], *p;
|
||||
int i;
|
||||
|
||||
@ -469,8 +469,6 @@ static void coff_out(int32_t segto, const void *data, uint64_t type,
|
||||
error(ERR_NONFATAL, "WRT not supported by COFF output formats");
|
||||
}
|
||||
|
||||
type &= OUT_TYPMASK;
|
||||
|
||||
/*
|
||||
* handle absolute-assembly (structure definitions)
|
||||
*/
|
||||
@ -499,10 +497,10 @@ static void coff_out(int32_t segto, const void *data, uint64_t type,
|
||||
error(ERR_WARNING, "attempt to initialize memory in"
|
||||
" BSS section `%s': ignored", s->name);
|
||||
if (type == OUT_REL2ADR)
|
||||
realbytes = 2;
|
||||
size = 2;
|
||||
else if (type == OUT_REL4ADR)
|
||||
realbytes = 4;
|
||||
s->len += realbytes;
|
||||
size = 4;
|
||||
s->len += size;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -510,16 +508,16 @@ static void coff_out(int32_t segto, const void *data, uint64_t type,
|
||||
if (s->data) {
|
||||
error(ERR_WARNING, "uninitialised space declared in"
|
||||
" non-BSS section `%s': zeroing", s->name);
|
||||
coff_sect_write(s, NULL, realbytes);
|
||||
coff_sect_write(s, NULL, size);
|
||||
} else
|
||||
s->len += realbytes;
|
||||
s->len += size;
|
||||
} else if (type == OUT_RAWDATA) {
|
||||
if (segment != NO_SEG)
|
||||
error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
|
||||
coff_sect_write(s, data, realbytes);
|
||||
coff_sect_write(s, data, size);
|
||||
} else if (type == OUT_ADDRESS) {
|
||||
if (!(win64)) {
|
||||
if (realbytes != 4 && (segment != NO_SEG || wrt != NO_SEG))
|
||||
if (size != 4 && (segment != NO_SEG || wrt != NO_SEG))
|
||||
error(ERR_NONFATAL, "COFF format does not support non-32-bit"
|
||||
" relocations");
|
||||
else {
|
||||
@ -536,12 +534,12 @@ static void coff_out(int32_t segto, const void *data, uint64_t type,
|
||||
}
|
||||
p = mydata;
|
||||
WRITELONG(p, *(int32_t *)data + fix);
|
||||
coff_sect_write(s, mydata, realbytes);
|
||||
coff_sect_write(s, mydata, size);
|
||||
}
|
||||
} else {
|
||||
int32_t fix = 0;
|
||||
p = mydata;
|
||||
if (realbytes == 8) {
|
||||
if (size == 8) {
|
||||
/* if (segment != NO_SEG || wrt != NO_SEG) {
|
||||
if (wrt != NO_SEG) {
|
||||
error(ERR_NONFATAL, "COFF format does not support"
|
||||
@ -554,11 +552,11 @@ static void coff_out(int32_t segto, const void *data, uint64_t type,
|
||||
} */
|
||||
fix = coff_add_reloc(s, segment, false, true);
|
||||
WRITEDLONG(p, *(int64_t *)data + fix);
|
||||
coff_sect_write(s, mydata, realbytes);
|
||||
coff_sect_write(s, mydata, size);
|
||||
} else {
|
||||
fix = coff_add_reloc(s, segment, false, false);
|
||||
WRITELONG(p, *(int32_t *)data + fix);
|
||||
coff_sect_write(s, mydata, realbytes);
|
||||
coff_sect_write(s, mydata, size);
|
||||
}
|
||||
}
|
||||
} else if (type == OUT_REL2ADR) {
|
||||
@ -579,9 +577,9 @@ static void coff_out(int32_t segto, const void *data, uint64_t type,
|
||||
fix = coff_add_reloc(s, segment, true, false);
|
||||
p = mydata;
|
||||
if (win32 | win64) {
|
||||
WRITELONG(p, *(int32_t *)data + 4 - realbytes + fix);
|
||||
WRITELONG(p, *(int32_t *)data + 4 - size + fix);
|
||||
} else {
|
||||
WRITELONG(p, *(int32_t *)data - (realbytes + s->len) + fix);
|
||||
WRITELONG(p, *(int32_t *)data - (size + s->len) + fix);
|
||||
}
|
||||
coff_sect_write(s, mydata, 4L);
|
||||
}
|
||||
|
@ -102,16 +102,14 @@ static void dbg_deflabel(char *name, int32_t segment, int32_t offset,
|
||||
is_global, special ? ": " : "", special);
|
||||
}
|
||||
|
||||
static void dbg_out(int32_t segto, const void *data, uint32_t type,
|
||||
static void dbg_out(int32_t segto, const void *data,
|
||||
enum out_type type, uint64_t size,
|
||||
int32_t segment, int32_t wrt)
|
||||
{
|
||||
int32_t realbytes = type & OUT_SIZMASK;
|
||||
int32_t ldata;
|
||||
int id;
|
||||
|
||||
type &= OUT_TYPMASK;
|
||||
|
||||
fprintf(dbgf, "out to %lx, len = %ld: ", segto, realbytes);
|
||||
fprintf(dbgf, "out to %lx, len = %ld: ", segto, size);
|
||||
|
||||
switch (type) {
|
||||
case OUT_RESERVE:
|
||||
@ -119,7 +117,7 @@ static void dbg_out(int32_t segto, const void *data, uint32_t type,
|
||||
break;
|
||||
case OUT_RAWDATA:
|
||||
fprintf(dbgf, "raw data = ");
|
||||
while (realbytes--) {
|
||||
while (size--) {
|
||||
id = *(uint8_t *)data;
|
||||
data = (char *)data + 1;
|
||||
fprintf(dbgf, "%02x ", id);
|
||||
@ -128,11 +126,11 @@ static void dbg_out(int32_t segto, const void *data, uint32_t type,
|
||||
break;
|
||||
case OUT_ADDRESS:
|
||||
ldata = 0; /* placate gcc */
|
||||
if (realbytes == 1)
|
||||
if (size == 1)
|
||||
ldata = *((char *)data);
|
||||
else if (realbytes == 2)
|
||||
else if (size == 2)
|
||||
ldata = *((int16_t *)data);
|
||||
else if (realbytes == 4)
|
||||
else if (size == 4)
|
||||
ldata = *((int32_t *)data);
|
||||
fprintf(dbgf, "addr %08lx (seg %08lx, wrt %08lx)\n", ldata,
|
||||
segment, wrt);
|
||||
|
@ -772,18 +772,16 @@ static int32_t elf_add_gsym_reloc(struct Section *sect,
|
||||
return offset - sym->value;
|
||||
}
|
||||
|
||||
static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
static void elf_out(int32_t segto, const void *data,
|
||||
enum out_type type, uint64_t size,
|
||||
int32_t segment, int32_t wrt)
|
||||
{
|
||||
struct Section *s;
|
||||
int32_t realbytes = type & OUT_SIZMASK;
|
||||
int32_t addr;
|
||||
uint8_t mydata[4], *p;
|
||||
int i;
|
||||
static struct symlininfo sinfo;
|
||||
|
||||
type &= OUT_TYPMASK;
|
||||
|
||||
/*
|
||||
* handle absolute-assembly (structure definitions)
|
||||
*/
|
||||
@ -823,10 +821,10 @@ static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
error(ERR_WARNING, "attempt to initialize memory in"
|
||||
" BSS section `%s': ignored", s->name);
|
||||
if (type == OUT_REL2ADR)
|
||||
realbytes = 2;
|
||||
size = 2;
|
||||
else if (type == OUT_REL4ADR)
|
||||
realbytes = 4;
|
||||
s->len += realbytes;
|
||||
size = 4;
|
||||
s->len += size;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -834,13 +832,13 @@ static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
if (s->type == SHT_PROGBITS) {
|
||||
error(ERR_WARNING, "uninitialized space declared in"
|
||||
" non-BSS section `%s': zeroing", s->name);
|
||||
elf_sect_write(s, NULL, realbytes);
|
||||
elf_sect_write(s, NULL, size);
|
||||
} else
|
||||
s->len += realbytes;
|
||||
s->len += size;
|
||||
} else if (type == OUT_RAWDATA) {
|
||||
if (segment != NO_SEG)
|
||||
error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
|
||||
elf_sect_write(s, data, realbytes);
|
||||
elf_sect_write(s, data, size);
|
||||
} else if (type == OUT_ADDRESS) {
|
||||
bool gnu16 = false;
|
||||
addr = *(int32_t *)data;
|
||||
@ -850,7 +848,7 @@ static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
" segment base references");
|
||||
} else {
|
||||
if (wrt == NO_SEG) {
|
||||
if (realbytes == 2) {
|
||||
if (size == 2) {
|
||||
gnu16 = true;
|
||||
elf_add_reloc(s, segment, R_386_16);
|
||||
} else {
|
||||
@ -870,7 +868,7 @@ static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
addr = elf_add_gsym_reloc(s, segment, addr,
|
||||
R_386_GOT32, true);
|
||||
} else if (wrt == elf_sym_sect + 1) {
|
||||
if (realbytes == 2) {
|
||||
if (size == 2) {
|
||||
gnu16 = true;
|
||||
addr = elf_add_gsym_reloc(s, segment, addr,
|
||||
R_386_16, false);
|
||||
@ -894,13 +892,13 @@ static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
"16-bit relocations in ELF is a GNU extension");
|
||||
WRITESHORT(p, addr);
|
||||
} else {
|
||||
if (realbytes != 4 && segment != NO_SEG) {
|
||||
if (size != 4 && segment != NO_SEG) {
|
||||
error(ERR_NONFATAL,
|
||||
"Unsupported non-32-bit ELF relocation");
|
||||
}
|
||||
WRITELONG(p, addr);
|
||||
}
|
||||
elf_sect_write(s, mydata, realbytes);
|
||||
elf_sect_write(s, mydata, size);
|
||||
} else if (type == OUT_REL2ADR) {
|
||||
if (segment == segto)
|
||||
error(ERR_PANIC, "intra-segment OUT_REL2ADR");
|
||||
@ -918,7 +916,7 @@ static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
}
|
||||
}
|
||||
p = mydata;
|
||||
WRITESHORT(p, *(int32_t *)data - realbytes);
|
||||
WRITESHORT(p, *(int32_t *)data - size);
|
||||
elf_sect_write(s, mydata, 2L);
|
||||
} else if (type == OUT_REL4ADR) {
|
||||
if (segment == segto)
|
||||
@ -943,7 +941,7 @@ static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
}
|
||||
}
|
||||
p = mydata;
|
||||
WRITELONG(p, *(int32_t *)data - realbytes);
|
||||
WRITELONG(p, *(int32_t *)data - size);
|
||||
elf_sect_write(s, mydata, 4L);
|
||||
}
|
||||
}
|
||||
|
@ -784,22 +784,20 @@ static int32_t elf_add_gsym_reloc(struct Section *sect,
|
||||
return offset - sym->value;
|
||||
}
|
||||
|
||||
static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
static void elf_out(int32_t segto, const void *data,
|
||||
enum out_type type, uint64_t size,
|
||||
int32_t segment, int32_t wrt)
|
||||
{
|
||||
struct Section *s;
|
||||
int32_t realbytes = type & OUT_SIZMASK;
|
||||
int64_t addr;
|
||||
uint8_t mydata[16], *p;
|
||||
int i;
|
||||
static struct symlininfo sinfo;
|
||||
|
||||
type &= OUT_TYPMASK;
|
||||
|
||||
#if defined(DEBUG) && DEBUG>2
|
||||
fprintf(stderr,
|
||||
" elf_out type: %x seg: %d bytes: %x data: %x\n",
|
||||
(type >> 24), segment, realbytes, *(int32_t *)data);
|
||||
(type >> 24), segment, size, *(int32_t *)data);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -841,10 +839,10 @@ static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
error(ERR_WARNING, "attempt to initialize memory in"
|
||||
" BSS section `%s': ignored", s->name);
|
||||
if (type == OUT_REL2ADR)
|
||||
realbytes = 2;
|
||||
size = 2;
|
||||
else if (type == OUT_REL4ADR)
|
||||
realbytes = 4;
|
||||
s->len += realbytes;
|
||||
size = 4;
|
||||
s->len += size;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -852,13 +850,13 @@ static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
if (s->type == SHT_PROGBITS) {
|
||||
error(ERR_WARNING, "uninitialized space declared in"
|
||||
" non-BSS section `%s': zeroing", s->name);
|
||||
elf_sect_write(s, NULL, realbytes);
|
||||
elf_sect_write(s, NULL, size);
|
||||
} else
|
||||
s->len += realbytes;
|
||||
s->len += size;
|
||||
} else if (type == OUT_RAWDATA) {
|
||||
if (segment != NO_SEG)
|
||||
error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
|
||||
elf_sect_write(s, data, realbytes);
|
||||
elf_sect_write(s, data, size);
|
||||
} else if (type == OUT_ADDRESS) {
|
||||
bool gnu16 = false;
|
||||
addr = *(int64_t *)data;
|
||||
@ -868,7 +866,7 @@ static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
" segment base references");
|
||||
} else {
|
||||
if (wrt == NO_SEG) {
|
||||
switch (realbytes) {
|
||||
switch (size) {
|
||||
case 2:
|
||||
elf_add_reloc(s, segment, R_X86_64_16);
|
||||
break;
|
||||
@ -896,7 +894,7 @@ static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
addr = elf_add_gsym_reloc(s, segment, addr,
|
||||
R_X86_64_GOT32, true);
|
||||
} else if (wrt == elf_sym_sect + 1) {
|
||||
switch (realbytes) {
|
||||
switch (size) {
|
||||
case 2:
|
||||
gnu16 = true;
|
||||
addr = elf_add_gsym_reloc(s, segment, addr,
|
||||
@ -928,14 +926,14 @@ static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
if (gnu16) {
|
||||
WRITESHORT(p, addr);
|
||||
} else {
|
||||
if (realbytes != 8 && realbytes != 4 && segment != NO_SEG) {
|
||||
if (size != 8 && size != 4 && segment != NO_SEG) {
|
||||
error(ERR_NONFATAL,
|
||||
"Unsupported non-64-bit ELF relocation");
|
||||
}
|
||||
if (realbytes == 4) WRITELONG(p, addr);
|
||||
if (size == 4) WRITELONG(p, addr);
|
||||
else WRITEDLONG(p, (int64_t)addr);
|
||||
}
|
||||
elf_sect_write(s, mydata, realbytes);
|
||||
elf_sect_write(s, mydata, size);
|
||||
} else if (type == OUT_REL2ADR) {
|
||||
if (segment == segto)
|
||||
error(ERR_PANIC, "intra-segment OUT_REL2ADR");
|
||||
@ -951,7 +949,7 @@ static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
}
|
||||
}
|
||||
p = mydata;
|
||||
WRITESHORT(p, *(int32_t *)data - realbytes);
|
||||
WRITESHORT(p, *(int32_t *)data - size);
|
||||
elf_sect_write(s, mydata, 2L);
|
||||
} else if (type == OUT_REL4ADR) {
|
||||
if (segment == segto)
|
||||
@ -976,7 +974,7 @@ static void elf_out(int32_t segto, const void *data, uint64_t type,
|
||||
}
|
||||
}
|
||||
p = mydata;
|
||||
WRITELONG(p, *(int32_t *)data - realbytes);
|
||||
WRITELONG(p, *(int32_t *)data - size);
|
||||
elf_sect_write(s, mydata, 4L);
|
||||
}
|
||||
}
|
||||
|
@ -372,10 +372,10 @@ static void ieee_deflabel(char *name, int32_t segment,
|
||||
/*
|
||||
* Put data out
|
||||
*/
|
||||
static void ieee_out(int32_t segto, const void *data, uint64_t type,
|
||||
static void ieee_out(int32_t segto, const void *data,
|
||||
enum out_type type, uint64_t size,
|
||||
int32_t segment, int32_t wrt)
|
||||
{
|
||||
uint64_t size, realtype;
|
||||
const uint8_t *ucdata;
|
||||
int32_t ldata;
|
||||
struct ieeeSection *seg;
|
||||
@ -384,7 +384,7 @@ static void ieee_out(int32_t segto, const void *data, uint64_t type,
|
||||
* handle absolute-assembly (structure definitions)
|
||||
*/
|
||||
if (segto == NO_SEG) {
|
||||
if ((type & OUT_TYPMASK) != OUT_RESERVE)
|
||||
if (type != OUT_RESERVE)
|
||||
error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
|
||||
" space");
|
||||
return;
|
||||
@ -409,28 +409,26 @@ static void ieee_out(int32_t segto, const void *data, uint64_t type,
|
||||
if (!seg)
|
||||
error(ERR_PANIC, "code directed to nonexistent segment?");
|
||||
|
||||
size = type & OUT_SIZMASK;
|
||||
realtype = type & OUT_TYPMASK;
|
||||
if (realtype == OUT_RAWDATA) {
|
||||
if (type == OUT_RAWDATA) {
|
||||
ucdata = data;
|
||||
while (size--)
|
||||
ieee_write_byte(seg, *ucdata++);
|
||||
} else if (realtype == OUT_ADDRESS || realtype == OUT_REL2ADR ||
|
||||
realtype == OUT_REL4ADR) {
|
||||
if (segment == NO_SEG && realtype != OUT_ADDRESS)
|
||||
} else if (type == OUT_ADDRESS || type == OUT_REL2ADR ||
|
||||
type == OUT_REL4ADR) {
|
||||
if (segment == NO_SEG && type != OUT_ADDRESS)
|
||||
error(ERR_NONFATAL, "relative call to absolute address not"
|
||||
" supported by IEEE format");
|
||||
ldata = *(int32_t *)data;
|
||||
if (realtype == OUT_REL2ADR)
|
||||
if (type == OUT_REL2ADR)
|
||||
ldata += (size - 2);
|
||||
if (realtype == OUT_REL4ADR)
|
||||
if (type == OUT_REL4ADR)
|
||||
ldata += (size - 4);
|
||||
ieee_write_fixup(segment, wrt, seg, size, realtype, ldata);
|
||||
ieee_write_fixup(segment, wrt, seg, size, type, ldata);
|
||||
if (size == 2)
|
||||
ieee_write_word(seg, ldata);
|
||||
else
|
||||
ieee_write_dword(seg, ldata);
|
||||
} else if (realtype == OUT_RESERVE) {
|
||||
} else if (type == OUT_RESERVE) {
|
||||
while (size--)
|
||||
ieee_write_byte(seg, 0);
|
||||
}
|
||||
|
@ -386,14 +386,13 @@ static void add_reloc(struct section *sect, int32_t section,
|
||||
++sect->nreloc;
|
||||
}
|
||||
|
||||
static void macho_output(int32_t secto, const void *data, uint64_t xtype,
|
||||
static void macho_output(int32_t secto, const void *data,
|
||||
enum out_type type, uint64_t size,
|
||||
int32_t section, int32_t wrt)
|
||||
{
|
||||
struct section *s, *sbss;
|
||||
int64_t realbytes = xtype & OUT_SIZMASK;
|
||||
int32_t addr;
|
||||
uint8_t mydata[4], *p;
|
||||
int type = OUT_TYPE(xtype);
|
||||
|
||||
if (wrt != NO_SEG) {
|
||||
wrt = NO_SEG;
|
||||
@ -402,7 +401,7 @@ static void macho_output(int32_t secto, const void *data, uint64_t xtype,
|
||||
}
|
||||
|
||||
if (secto == NO_SEG) {
|
||||
if (type != OUT_TYPE(OUT_RESERVE))
|
||||
if (type != OUT_RESERVE)
|
||||
error(ERR_NONFATAL, "attempt to assemble code in "
|
||||
"[ABSOLUTE] space");
|
||||
|
||||
@ -423,48 +422,48 @@ static void macho_output(int32_t secto, const void *data, uint64_t xtype,
|
||||
|
||||
sbss = get_section_by_name("__DATA", "__bss");
|
||||
|
||||
if (s == sbss && type != OUT_TYPE(OUT_RESERVE)) {
|
||||
if (s == sbss && type != OUT_RESERVE) {
|
||||
error(ERR_WARNING, "attempt to initialize memory in the"
|
||||
" BSS section: ignored");
|
||||
|
||||
switch (type) {
|
||||
case OUT_TYPE(OUT_REL2ADR):
|
||||
realbytes = 2;
|
||||
case OUT_REL2ADR:
|
||||
size = 2;
|
||||
break;
|
||||
|
||||
case OUT_TYPE(OUT_REL4ADR):
|
||||
realbytes = 4;
|
||||
case OUT_REL4ADR:
|
||||
size = 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
s->size += realbytes;
|
||||
s->size += size;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case OUT_TYPE(OUT_RESERVE):
|
||||
case OUT_RESERVE:
|
||||
if (s != sbss) {
|
||||
error(ERR_WARNING, "uninitialized space declared in"
|
||||
" %s section: zeroing",
|
||||
get_section_name_by_index(secto));
|
||||
|
||||
sect_write(s, NULL, realbytes);
|
||||
sect_write(s, NULL, size);
|
||||
} else
|
||||
s->size += realbytes;
|
||||
s->size += size;
|
||||
|
||||
break;
|
||||
|
||||
case OUT_TYPE(OUT_RAWDATA):
|
||||
case OUT_RAWDATA:
|
||||
if (section != NO_SEG)
|
||||
error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
|
||||
|
||||
sect_write(s, data, realbytes);
|
||||
sect_write(s, data, size);
|
||||
break;
|
||||
|
||||
case OUT_TYPE(OUT_ADDRESS):
|
||||
case OUT_ADDRESS:
|
||||
addr = *(int32_t *)data;
|
||||
|
||||
if (section != NO_SEG) {
|
||||
@ -472,20 +471,20 @@ static void macho_output(int32_t secto, const void *data, uint64_t xtype,
|
||||
error(ERR_NONFATAL, "Mach-O format does not support"
|
||||
" section base references");
|
||||
} else
|
||||
add_reloc(s, section, 0, realbytes);
|
||||
add_reloc(s, section, 0, size);
|
||||
}
|
||||
|
||||
p = mydata;
|
||||
|
||||
if (realbytes == 2)
|
||||
if (size == 2)
|
||||
WRITESHORT(p, addr);
|
||||
else
|
||||
WRITELONG(p, addr);
|
||||
|
||||
sect_write(s, mydata, realbytes);
|
||||
sect_write(s, mydata, size);
|
||||
break;
|
||||
|
||||
case OUT_TYPE(OUT_REL2ADR):
|
||||
case OUT_REL2ADR:
|
||||
if (section == secto)
|
||||
error(ERR_PANIC, "intra-section OUT_REL2ADR");
|
||||
|
||||
@ -496,11 +495,11 @@ static void macho_output(int32_t secto, const void *data, uint64_t xtype,
|
||||
add_reloc(s, section, 1, 2);
|
||||
|
||||
p = mydata;
|
||||
WRITESHORT(p, *(int32_t *)data - (realbytes + s->size));
|
||||
WRITESHORT(p, *(int32_t *)data - (size + s->size));
|
||||
sect_write(s, mydata, 2L);
|
||||
break;
|
||||
|
||||
case OUT_TYPE(OUT_REL4ADR):
|
||||
case OUT_REL4ADR:
|
||||
if (section == secto)
|
||||
error(ERR_PANIC, "intra-section OUT_REL4ADR");
|
||||
|
||||
@ -511,7 +510,7 @@ static void macho_output(int32_t secto, const void *data, uint64_t xtype,
|
||||
add_reloc(s, section, 1, 4);
|
||||
|
||||
p = mydata;
|
||||
WRITELONG(p, *(int32_t *)data - (realbytes + s->size));
|
||||
WRITELONG(p, *(int32_t *)data - (size + s->size));
|
||||
sect_write(s, mydata, 4L);
|
||||
break;
|
||||
|
||||
|
@ -996,10 +996,10 @@ static void obj_write_fixup(ObjRecord * orp, int bytes,
|
||||
int segrel, int32_t seg, int32_t wrt,
|
||||
struct Segment *segto);
|
||||
|
||||
static void obj_out(int32_t segto, const void *data, uint64_t type,
|
||||
static void obj_out(int32_t segto, const void *data,
|
||||
enum out_type type, uint64_t size,
|
||||
int32_t segment, int32_t wrt)
|
||||
{
|
||||
uint64_t size, realtype;
|
||||
const uint8_t *ucdata;
|
||||
int32_t ldata;
|
||||
struct Segment *seg;
|
||||
@ -1009,7 +1009,7 @@ static void obj_out(int32_t segto, const void *data, uint64_t type,
|
||||
* handle absolute-assembly (structure definitions)
|
||||
*/
|
||||
if (segto == NO_SEG) {
|
||||
if ((type & OUT_TYPMASK) != OUT_RESERVE)
|
||||
if (type != OUT_RESERVE)
|
||||
error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
|
||||
" space");
|
||||
return;
|
||||
@ -1037,9 +1037,7 @@ static void obj_out(int32_t segto, const void *data, uint64_t type,
|
||||
orp = seg->orp;
|
||||
orp->parm[0] = seg->currentpos;
|
||||
|
||||
size = type & OUT_SIZMASK;
|
||||
realtype = type & OUT_TYPMASK;
|
||||
if (realtype == OUT_RAWDATA) {
|
||||
if (type == OUT_RAWDATA) {
|
||||
ucdata = data;
|
||||
while (size > 0) {
|
||||
unsigned int len;
|
||||
@ -1053,22 +1051,22 @@ static void obj_out(int32_t segto, const void *data, uint64_t type,
|
||||
ucdata += len;
|
||||
size -= len;
|
||||
}
|
||||
} else if (realtype == OUT_ADDRESS || realtype == OUT_REL2ADR ||
|
||||
realtype == OUT_REL4ADR) {
|
||||
} else if (type == OUT_ADDRESS || type == OUT_REL2ADR ||
|
||||
type == OUT_REL4ADR) {
|
||||
int rsize;
|
||||
|
||||
if (segment == NO_SEG && realtype != OUT_ADDRESS)
|
||||
if (segment == NO_SEG && type != OUT_ADDRESS)
|
||||
error(ERR_NONFATAL, "relative call to absolute address not"
|
||||
" supported by OBJ format");
|
||||
if (segment >= SEG_ABS)
|
||||
error(ERR_NONFATAL, "far-absolute relocations not supported"
|
||||
" by OBJ format");
|
||||
ldata = *(int32_t *)data;
|
||||
if (realtype == OUT_REL2ADR) {
|
||||
if (type == OUT_REL2ADR) {
|
||||
ldata += (size - 2);
|
||||
size = 2;
|
||||
}
|
||||
if (realtype == OUT_REL4ADR) {
|
||||
if (type == OUT_REL4ADR) {
|
||||
ldata += (size - 4);
|
||||
size = 4;
|
||||
}
|
||||
@ -1093,10 +1091,10 @@ static void obj_out(int32_t segto, const void *data, uint64_t type,
|
||||
}
|
||||
if (segment != NO_SEG)
|
||||
obj_write_fixup(orp, rsize,
|
||||
(realtype == OUT_ADDRESS ? 0x4000 : 0),
|
||||
(type == OUT_ADDRESS ? 0x4000 : 0),
|
||||
segment, wrt, seg);
|
||||
seg->currentpos += size;
|
||||
} else if (realtype == OUT_RESERVE) {
|
||||
} else if (type == OUT_RESERVE) {
|
||||
if (orp->committed)
|
||||
orp = obj_bump(orp);
|
||||
seg->currentpos += size;
|
||||
@ -1997,7 +1995,7 @@ static void obj_write_file(int debuginfo)
|
||||
orp->parm[0] = 0;
|
||||
orp->parm[1] = 0;
|
||||
for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
|
||||
if (orp->parm[2] != pub->segment) {
|
||||
if ((uint64_t)orp->parm[2] != pub->segment) {
|
||||
obj_emit(orp);
|
||||
orp->parm[2] = pub->segment;
|
||||
}
|
||||
|
@ -507,16 +507,16 @@ static int getsegmentlength(int segment)
|
||||
return segments[i].seglength;
|
||||
}
|
||||
|
||||
static void rdf2_out(int32_t segto, const void *data, uint64_t type,
|
||||
static void rdf2_out(int32_t segto, const void *data,
|
||||
enum out_type type, uint64_t size,
|
||||
int32_t segment, int32_t wrt)
|
||||
{
|
||||
int64_t bytes = type & OUT_SIZMASK;
|
||||
struct RelocRec rr;
|
||||
uint8_t databuf[8], *pd;
|
||||
int seg;
|
||||
|
||||
if (segto == NO_SEG) {
|
||||
if ((type & OUT_TYPMASK) != OUT_RESERVE)
|
||||
if (type != OUT_RESERVE)
|
||||
error(ERR_NONFATAL,
|
||||
"attempt to assemble code in ABSOLUTE space");
|
||||
return;
|
||||
@ -539,31 +539,29 @@ static void rdf2_out(int32_t segto, const void *data, uint64_t type,
|
||||
error(ERR_NONFATAL, "WRT not supported by rdf output format");
|
||||
}
|
||||
|
||||
type &= OUT_TYPMASK;
|
||||
|
||||
if (segto == 2 && type != OUT_RESERVE) {
|
||||
error(ERR_NONFATAL, "BSS segments may not be initialized");
|
||||
|
||||
/* just reserve the space for now... */
|
||||
|
||||
if (type == OUT_REL2ADR)
|
||||
bytes = 2;
|
||||
size = 2;
|
||||
else
|
||||
bytes = 4;
|
||||
size = 4;
|
||||
type = OUT_RESERVE;
|
||||
}
|
||||
|
||||
if (type == OUT_RESERVE) {
|
||||
if (segto == 2) /* BSS segment space reserverd */
|
||||
bsslength += bytes;
|
||||
bsslength += size;
|
||||
else
|
||||
while (bytes--)
|
||||
while (size--)
|
||||
membufwrite(segto, databuf, 1);
|
||||
} else if (type == OUT_RAWDATA) {
|
||||
if (segment != NO_SEG)
|
||||
error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
|
||||
|
||||
membufwrite(segto, data, bytes);
|
||||
membufwrite(segto, data, size);
|
||||
} else if (type == OUT_ADDRESS) {
|
||||
|
||||
/* if segment == NO_SEG then we are writing an address of an
|
||||
@ -579,20 +577,20 @@ static void rdf2_out(int32_t segto, const void *data, uint64_t type,
|
||||
rr.reclen = 8;
|
||||
rr.segment = segto; /* segment we're currently in */
|
||||
rr.offset = getsegmentlength(segto); /* current offset */
|
||||
rr.length = bytes; /* length of reference */
|
||||
rr.length = size; /* length of reference */
|
||||
rr.refseg = segment; /* segment referred to */
|
||||
write_reloc_rec(&rr);
|
||||
}
|
||||
|
||||
pd = databuf; /* convert address to little-endian */
|
||||
if (bytes == 4)
|
||||
if (size == 4)
|
||||
WRITESHORT(pd, *(int32_t *)data);
|
||||
else if (bytes == 8)
|
||||
else if (size == 8)
|
||||
WRITEDLONG(pd, *(int64_t *)data);
|
||||
else
|
||||
WRITESHORT(pd, *(int32_t *)data);
|
||||
|
||||
membufwrite(segto, databuf, bytes);
|
||||
membufwrite(segto, databuf, size);
|
||||
|
||||
} else if (type == OUT_REL2ADR) {
|
||||
if (segment == segto)
|
||||
@ -622,7 +620,7 @@ static void rdf2_out(int32_t segto, const void *data, uint64_t type,
|
||||
* address of imported symbol onto it to get address relative to end of
|
||||
* instruction: import_address + data(offset) - end_of_instrn */
|
||||
|
||||
rr.offset = *(int32_t *)data - (rr.offset + bytes);
|
||||
rr.offset = *(int32_t *)data - (rr.offset + size);
|
||||
}
|
||||
|
||||
membufwrite(segto, &rr.offset, -2);
|
||||
@ -641,7 +639,7 @@ static void rdf2_out(int32_t segto, const void *data, uint64_t type,
|
||||
rr.reclen = 8;
|
||||
write_reloc_rec(&rr);
|
||||
|
||||
rr.offset = *(int32_t *)data - (rr.offset + bytes);
|
||||
rr.offset = *(int32_t *)data - (rr.offset + size);
|
||||
|
||||
membufwrite(segto, &rr.offset, -4);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user