* 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;
-
- 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);
+ uint8_t p[8];
+
+ 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
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,
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;
}
* 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);
}
}
* 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;
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;
}
* 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);
}
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++;
}
* 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);
}
}
#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; \
}
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;
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;
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;
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;
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;
}
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
}
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;
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;
}
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;
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;
(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;
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;
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;
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;
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;
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;
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);
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;
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;
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;
}
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:
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++;
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;
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--) {
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;
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;
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;
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;
+ }
}
}
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
* -----------------------
* 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
* 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);
/*
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))
/*
* ------------------------------------------------------------
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)
*/
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;
}
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) {
} 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"
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;
}
}
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");
}
}
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)
}
}
p = mydata;
- WRITELONG(p, *(int32_t *)data - (realbytes + s->len));
+ WRITELONG(p, *(int32_t *)data - (size + s->len));
aout_sect_write(s, mydata, 4L);
}
}
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;
error(ERR_NONFATAL, "WRT not supported by as86 output format");
}
- type &= OUT_TYPMASK;
-
/*
* handle absolute-assembly (structure definitions)
*/
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;
}
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) {
" 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)
" 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);
}
}
" 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);
}
}
}
}
-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_ */
/* 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;
/* "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"
}
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"
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;
}
}
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;
error(ERR_NONFATAL, "WRT not supported by COFF output formats");
}
- type &= OUT_TYPMASK;
-
/*
* handle absolute-assembly (structure definitions)
*/
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;
}
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 {
}
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"
} */
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) {
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);
}
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:
break;
case OUT_RAWDATA:
fprintf(dbgf, "raw data = ");
- while (realbytes--) {
+ while (size--) {
id = *(uint8_t *)data;
data = (char *)data + 1;
fprintf(dbgf, "%02x ", id);
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);
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)
*/
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;
}
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;
" 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 {
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);
"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");
}
}
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)
}
}
p = mydata;
- WRITELONG(p, *(int32_t *)data - realbytes);
+ WRITELONG(p, *(int32_t *)data - size);
elf_sect_write(s, mydata, 4L);
}
}
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
/*
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;
}
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;
" segment base references");
} else {
if (wrt == NO_SEG) {
- switch (realbytes) {
+ switch (size) {
case 2:
elf_add_reloc(s, segment, R_X86_64_16);
break;
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,
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");
}
}
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)
}
}
p = mydata;
- WRITELONG(p, *(int32_t *)data - realbytes);
+ WRITELONG(p, *(int32_t *)data - size);
elf_sect_write(s, mydata, 4L);
}
}
/*
* 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;
* 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;
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);
}
++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;
}
if (secto == NO_SEG) {
- if (type != OUT_TYPE(OUT_RESERVE))
+ if (type != OUT_RESERVE)
error(ERR_NONFATAL, "attempt to assemble code in "
"[ABSOLUTE] space");
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) {
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");
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");
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;
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;
* 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;
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;
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;
}
}
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;
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;
}
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;
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
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)
* 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);
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);
}