/*@null@*/ /*@only@*/ unsigned char *
yasm_bc_tobytes(yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
- /*@out@*/ unsigned long *multiple, /*@out@*/ int *gap,
- void *d, yasm_output_value_func output_value,
+ /*@out@*/ int *gap, void *d,
+ yasm_output_value_func output_value,
/*@null@*/ yasm_output_reloc_func output_reloc)
/*@sets *buf@*/
{
/*@only@*/ /*@null@*/ unsigned char *mybuf = NULL;
unsigned char *origbuf, *destbuf;
- /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
- unsigned long datasize;
+ unsigned long datasize, multiple, i;
int error = 0;
- if (bc->multiple) {
- num = yasm_expr_get_intnum(&bc->multiple, NULL);
- if (!num)
- yasm_internal_error(
- N_("could not determine multiple in bc_tobytes"));
- if (yasm_intnum_sign(num) < 0) {
- yasm_error_set(YASM_ERROR_VALUE, N_("multiple is negative"));
- *bufsize = 0;
- return NULL;
- }
- *multiple = yasm_intnum_get_uint(num);
- if (*multiple == 0) {
- *bufsize = 0;
- return NULL;
- }
- } else
- *multiple = 1;
-
- datasize = bc->len / (*multiple);
+ if (yasm_bc_get_multiple(bc, &multiple, NULL) || multiple == 0) {
+ *bufsize = 0;
+ return NULL;
+ }
/* special case for reserve bytecodes */
if (bc->callback->reserve) {
- *bufsize = datasize;
+ *bufsize = bc->len;
*gap = 1;
return NULL; /* we didn't allocate a buffer */
}
-
*gap = 0;
- if (*bufsize < datasize) {
+ if (*bufsize < bc->len) {
mybuf = yasm_xmalloc(bc->len);
- origbuf = mybuf;
destbuf = mybuf;
- } else {
- origbuf = buf;
+ } else
destbuf = buf;
- }
- *bufsize = datasize;
+
+ *bufsize = bc->len;
+ datasize = bc->len / multiple;
if (!bc->callback)
yasm_internal_error(N_("got empty bytecode in bc_tobytes"));
- else
+ else for (i=0; i<multiple; i++) {
+ origbuf = destbuf;
error = bc->callback->tobytes(bc, &destbuf, d, output_value,
output_reloc);
- if (!error && ((unsigned long)(destbuf - origbuf) != datasize))
- yasm_internal_error(
- N_("written length does not match optimized length"));
+ if (!error && ((unsigned long)(destbuf - origbuf) != datasize))
+ yasm_internal_error(
+ N_("written length does not match optimized length"));
+ }
+
return mybuf;
}
+
+int
+yasm_bc_get_multiple(yasm_bytecode *bc, unsigned long *multiple,
+ yasm_calc_bc_dist_func calc_bc_dist)
+{
+ /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
+
+ *multiple = 1;
+ if (bc->multiple) {
+ num = yasm_expr_get_intnum(&bc->multiple, calc_bc_dist);
+ if (!num) {
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("could not determine multiple"));
+ return 1;
+ }
+ if (yasm_intnum_sign(num) < 0) {
+ yasm_error_set(YASM_ERROR_VALUE, N_("multiple is negative"));
+ return 1;
+ }
+ *multiple = yasm_intnum_get_uint(num);
+ }
+ return 0;
+}
* \param buf byte representation destination buffer
* \param bufsize size of buf (in bytes) prior to call; size of the
* generated data after call
- * \param multiple number of times the data should be duplicated when
- * written to the object file [output]
* \param gap if nonzero, indicates the data does not really need to
* exist in the object file; if nonzero, contents of buf
* are undefined [output]
*/
/*@null@*/ /*@only@*/ unsigned char *yasm_bc_tobytes
(yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
- /*@out@*/ unsigned long *multiple, /*@out@*/ int *gap, void *d,
- yasm_output_value_func output_value,
+ /*@out@*/ int *gap, void *d, yasm_output_value_func output_value,
/*@null@*/ yasm_output_reloc_func output_reloc)
/*@sets *buf@*/;
+/** Get the bytecode multiple value as an unsigned long integer.
+ * \param bc bytecode
+ * \param multiple multiple value (output)
+ * \param calc_bc_dist bytecode distance calculation function (optional)
+ * \return 1 on error (set with yasm_error_set), 0 on success.
+ */
+int yasm_bc_get_multiple(yasm_bytecode *bc, /*@out@*/ unsigned long *multiple,
+ /*@null@*/ yasm_calc_bc_dist_func calc_bc_dist);
+
/** Create a new data value from an expression.
* \param expn expression
* \return Newly allocated data value.
/* convert bytecode into bytes, recording relocs along the
* way
*/
- bigbuf = yasm_bc_tobytes(bc, buf, &size, &multiple, &gap,
- &info, nasm_listfmt_output_value,
- NULL);
+ bigbuf = yasm_bc_tobytes(bc, buf, &size, &gap, &info,
+ nasm_listfmt_output_value, NULL);
+ yasm_bc_get_multiple(bc, &multiple, NULL);
+ size /= multiple;
/* output bytes with reloc information */
origp = bigbuf ? bigbuf : buf;
/*@null@*/ bin_objfmt_output_info *info = (bin_objfmt_output_info *)d;
/*@null@*/ /*@only@*/ unsigned char *bigbuf;
unsigned long size = REGULAR_OUTBUF_SIZE;
- unsigned long multiple;
- unsigned long i;
int gap;
assert(info != NULL);
- bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &multiple, &gap, info,
+ bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &gap, info,
bin_objfmt_output_value, NULL);
/* Don't bother doing anything else if size ended up being 0. */
N_("uninitialized space declared in code/data section: zeroing"));
/* Write out in chunks */
memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
- left = multiple*size;
+ left = size;
while (left > REGULAR_OUTBUF_SIZE) {
fwrite(info->buf, REGULAR_OUTBUF_SIZE, 1, info->f);
left -= REGULAR_OUTBUF_SIZE;
}
fwrite(info->buf, left, 1, info->f);
} else {
- /* Output multiple copies of buf (or bigbuf if non-NULL) to file */
- for (i=0; i<multiple; i++)
- fwrite(bigbuf ? bigbuf : info->buf, (size_t)size, 1, info->f);
+ /* Output buf (or bigbuf if non-NULL) to file */
+ fwrite(bigbuf ? bigbuf : info->buf, (size_t)size, 1, info->f);
}
/* If bigbuf was allocated, free it */
/*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
/*@null@*/ /*@only@*/ unsigned char *bigbuf;
unsigned long size = REGULAR_OUTBUF_SIZE;
- unsigned long multiple;
- unsigned long i;
int gap;
assert(info != NULL);
- bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &multiple, &gap, info,
+ bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &gap, info,
coff_objfmt_output_value, NULL);
/* Don't bother doing anything else if size ended up being 0. */
return 0;
}
- info->csd->size += multiple*size;
+ info->csd->size += size;
/* Warn that gaps are converted to 0 and write out the 0's. */
if (gap) {
N_("uninitialized space declared in code/data section: zeroing"));
/* Write out in chunks */
memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
- left = multiple*size;
+ left = size;
while (left > REGULAR_OUTBUF_SIZE) {
fwrite(info->buf, REGULAR_OUTBUF_SIZE, 1, info->f);
left -= REGULAR_OUTBUF_SIZE;
}
fwrite(info->buf, left, 1, info->f);
} else {
- /* Output multiple copies of buf (or bigbuf if non-NULL) to file */
- for (i=0; i<multiple; i++)
- fwrite(bigbuf ? bigbuf : info->buf, (size_t)size, 1, info->f);
+ /* Output buf (or bigbuf if non-NULL) to file */
+ fwrite(bigbuf ? bigbuf : info->buf, (size_t)size, 1, info->f);
}
/* If bigbuf was allocated, free it */
unsigned char buf[256];
/*@null@*/ /*@only@*/ unsigned char *bigbuf;
unsigned long size = 256;
- unsigned long multiple;
- unsigned long i;
int gap;
if (info == NULL)
yasm_internal_error("null info struct");
- bigbuf = yasm_bc_tobytes(bc, buf, &size, &multiple, &gap, info,
+ bigbuf = yasm_bc_tobytes(bc, buf, &size, &gap, info,
elf_objfmt_output_value, elf_objfmt_output_reloc);
/* Don't bother doing anything else if size ended up being 0. */
}
else {
yasm_intnum *bcsize = yasm_intnum_create_uint(size);
- yasm_intnum *mult = yasm_intnum_create_uint(multiple);
-
- yasm_intnum_calc(bcsize, YASM_EXPR_MUL, mult);
elf_secthead_add_size(info->shead, bcsize);
-
yasm_intnum_destroy(bcsize);
- yasm_intnum_destroy(mult);
}
/* Warn that gaps are converted to 0 and write out the 0's. */
N_("uninitialized space declared in code/data section: zeroing"));
/* Write out in chunks */
memset(buf, 0, 256);
- left = multiple*size;
+ left = size;
while (left > 256) {
fwrite(buf, 256, 1, info->f);
left -= 256;
}
fwrite(buf, left, 1, info->f);
} else {
- /* Output multiple copies of buf (or bigbuf if non-NULL) to file */
- for (i=0; i<multiple; i++)
- fwrite(bigbuf ? bigbuf : buf, (size_t)size, 1, info->f);
+ /* Output buf (or bigbuf if non-NULL) to file */
+ fwrite(bigbuf ? bigbuf : buf, (size_t)size, 1, info->f);
}
/* If bigbuf was allocated, free it */
/*@null@*/ xdf_objfmt_output_info *info = (xdf_objfmt_output_info *)d;
/*@null@*/ /*@only@*/ unsigned char *bigbuf;
unsigned long size = REGULAR_OUTBUF_SIZE;
- unsigned long multiple;
- unsigned long i;
int gap;
assert(info != NULL);
- bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &multiple, &gap, info,
+ bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &gap, info,
xdf_objfmt_output_value, NULL);
/* Don't bother doing anything else if size ended up being 0. */
return 0;
}
- info->xsd->size += multiple*size;
+ info->xsd->size += size;
/* Warn that gaps are converted to 0 and write out the 0's. */
if (gap) {
N_("uninitialized space: zeroing"));
/* Write out in chunks */
memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
- left = multiple*size;
+ left = size;
while (left > REGULAR_OUTBUF_SIZE) {
fwrite(info->buf, REGULAR_OUTBUF_SIZE, 1, info->f);
left -= REGULAR_OUTBUF_SIZE;
}
fwrite(info->buf, left, 1, info->f);
} else {
- /* Output multiple copies of buf (or bigbuf if non-NULL) to file */
- for (i=0; i<multiple; i++)
- fwrite(bigbuf ? bigbuf : info->buf, (size_t)size, 1, info->f);
+ /* Output buf (or bigbuf if non-NULL) to file */
+ fwrite(bigbuf ? bigbuf : info->buf, (size_t)size, 1, info->f);
}
/* If bigbuf was allocated, free it */
--- /dev/null
+extern foo
+section .text
+times 64*1024 dd foo
cdef yasm_bc_resolve_flags yasm_bc_resolve(yasm_bytecode *bc, int save,
yasm_calc_bc_dist_func calc_bc_dist)
cdef unsigned char* yasm_bc_tobytes(yasm_bytecode *bc,
- unsigned char *buf, unsigned long *bufsize,
- unsigned long *multiple, int *gap, void *d,
+ unsigned char *buf, unsigned long *bufsize, int *gap, void *d,
yasm_output_value_func output_value,
yasm_output_reloc_func output_reloc)
+ cdef int yasm_bc_get_multiple(yasm_bytecode *bc, unsigned long *multiple,
+ yasm_calc_bc_dist_func calc_bc_dist)
cdef yasm_dataval* yasm_dv_create_expr(yasm_expr *expn)
cdef yasm_dataval* yasm_dv_create_string(char *contents, size_t len)