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:
H. Peter Anvin 2007-11-09 14:44:02 -08:00
parent 7eaf919a22
commit 34f6fb0a65
14 changed files with 340 additions and 333 deletions

View File

@ -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;

View File

@ -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
View File

@ -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))
/*
* ------------------------------------------------------------

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}