diff options
author | somov <somov@yandex-team.ru> | 2022-02-10 16:45:47 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:47 +0300 |
commit | a5950576e397b1909261050b8c7da16db58f10b1 (patch) | |
tree | 7ba7677f6a4c3e19e2cefab34d16df2c8963b4d4 /contrib/tools/yasm/libyasm/bc-align.c | |
parent | 81eddc8c0b55990194e112b02d127b87d54164a9 (diff) | |
download | ydb-a5950576e397b1909261050b8c7da16db58f10b1.tar.gz |
Restoring authorship annotation for <somov@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/tools/yasm/libyasm/bc-align.c')
-rw-r--r-- | contrib/tools/yasm/libyasm/bc-align.c | 490 |
1 files changed, 245 insertions, 245 deletions
diff --git a/contrib/tools/yasm/libyasm/bc-align.c b/contrib/tools/yasm/libyasm/bc-align.c index 2a47882ef0..42a9cc4671 100644 --- a/contrib/tools/yasm/libyasm/bc-align.c +++ b/contrib/tools/yasm/libyasm/bc-align.c @@ -1,245 +1,245 @@ -/* - * Align bytecode - * - * Copyright (C) 2005-2007 Peter Johnson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#include "util.h" - -#include "libyasm-stdint.h" -#include "coretype.h" - -#include "errwarn.h" -#include "intnum.h" -#include "expr.h" - -#include "bytecode.h" - - -typedef struct bytecode_align { - /*@only@*/ yasm_expr *boundary; /* alignment boundary */ - - /* What to fill intervening locations with, NULL if using code_fill */ - /*@only@*/ /*@null@*/ yasm_expr *fill; - - /* Maximum number of bytes to skip, NULL if no maximum. */ - /*@only@*/ /*@null@*/ yasm_expr *maxskip; - - /* Code fill, NULL if using 0 fill */ - /*@null@*/ const unsigned char **code_fill; -} bytecode_align; - -static void bc_align_destroy(void *contents); -static void bc_align_print(const void *contents, FILE *f, int indent_level); -static void bc_align_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc); -static int bc_align_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, - void *add_span_data); -static int bc_align_expand(yasm_bytecode *bc, int span, long old_val, - long new_val, /*@out@*/ long *neg_thres, - /*@out@*/ long *pos_thres); -static int bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, - unsigned char *bufstart, void *d, - yasm_output_value_func output_value, - /*@null@*/ yasm_output_reloc_func output_reloc); - -static const yasm_bytecode_callback bc_align_callback = { - bc_align_destroy, - bc_align_print, - bc_align_finalize, - NULL, - bc_align_calc_len, - bc_align_expand, - bc_align_tobytes, - YASM_BC_SPECIAL_OFFSET -}; - - -static void -bc_align_destroy(void *contents) -{ - bytecode_align *align = (bytecode_align *)contents; - if (align->boundary) - yasm_expr_destroy(align->boundary); - if (align->fill) - yasm_expr_destroy(align->fill); - if (align->maxskip) - yasm_expr_destroy(align->maxskip); - yasm_xfree(contents); -} - -static void -bc_align_print(const void *contents, FILE *f, int indent_level) -{ - const bytecode_align *align = (const bytecode_align *)contents; - fprintf(f, "%*s_Align_\n", indent_level, ""); - fprintf(f, "%*sBoundary=", indent_level, ""); - yasm_expr_print(align->boundary, f); - fprintf(f, "\n%*sFill=", indent_level, ""); - yasm_expr_print(align->fill, f); - fprintf(f, "\n%*sMax Skip=", indent_level, ""); - yasm_expr_print(align->maxskip, f); - fprintf(f, "\n"); -} - -static void -bc_align_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc) -{ - bytecode_align *align = (bytecode_align *)bc->contents; - if (!yasm_expr_get_intnum(&align->boundary, 0)) - yasm_error_set(YASM_ERROR_NOT_CONSTANT, - N_("align boundary must be a constant")); - if (align->fill && !yasm_expr_get_intnum(&align->fill, 0)) - yasm_error_set(YASM_ERROR_NOT_CONSTANT, - N_("align fill must be a constant")); - if (align->maxskip && !yasm_expr_get_intnum(&align->maxskip, 0)) - yasm_error_set(YASM_ERROR_NOT_CONSTANT, - N_("align maximum skip must be a constant")); -} - -static int -bc_align_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, - void *add_span_data) -{ - long neg_thres = 0; - long pos_thres = 0; - - if (bc_align_expand(bc, 0, 0, (long)bc->offset, &neg_thres, - &pos_thres) < 0) - return -1; - - return 0; -} - -static int -bc_align_expand(yasm_bytecode *bc, int span, long old_val, long new_val, - /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres) -{ - bytecode_align *align = (bytecode_align *)bc->contents; - unsigned long end; - unsigned long boundary = - yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, 0)); - - if (boundary == 0) { - bc->len = 0; - *pos_thres = new_val; - return 0; - } - - end = (unsigned long)new_val; - if ((unsigned long)new_val & (boundary-1)) - end = ((unsigned long)new_val & ~(boundary-1)) + boundary; - - *pos_thres = (long)end; - bc->len = end - (unsigned long)new_val; - - if (align->maxskip) { - unsigned long maxskip = - yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip, 0)); - if (bc->len > maxskip) { - *pos_thres = (long)end-maxskip-1; - bc->len = 0; - } - } - return 1; -} - -static int -bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, - unsigned char *bufstart, void *d, - yasm_output_value_func output_value, - /*@unused@*/ yasm_output_reloc_func output_reloc) -{ - bytecode_align *align = (bytecode_align *)bc->contents; - unsigned long len; - unsigned long boundary = - yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, 0)); - - if (boundary == 0) - return 0; - else { - unsigned long end = bc->offset; - if (bc->offset & (boundary-1)) - end = (bc->offset & ~(boundary-1)) + boundary; - len = end - bc->offset; - if (len == 0) - return 0; - if (align->maxskip) { - unsigned long maxskip = - yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip, 0)); - if (len > maxskip) - return 0; - } - } - - if (align->fill) { - unsigned long v; - v = yasm_intnum_get_uint(yasm_expr_get_intnum(&align->fill, 0)); - memset(*bufp, (int)v, len); - *bufp += len; - } else if (align->code_fill) { - unsigned long maxlen = 15; - while (!align->code_fill[maxlen] && maxlen>0) - maxlen--; - if (maxlen == 0) { - yasm_error_set(YASM_ERROR_GENERAL, - N_("could not find any code alignment size")); - return 1; - } - - /* Fill with maximum code fill as much as possible */ - while (len > maxlen) { - memcpy(*bufp, align->code_fill[maxlen], maxlen); - *bufp += maxlen; - len -= maxlen; - } - - if (!align->code_fill[len]) { - yasm_error_set(YASM_ERROR_VALUE, - N_("invalid alignment size %d"), len); - return 1; - } - /* Handle rest of code fill */ - memcpy(*bufp, align->code_fill[len], len); - *bufp += len; - } else { - /* Just fill with 0 */ - memset(*bufp, 0, len); - *bufp += len; - } - return 0; -} - -yasm_bytecode * -yasm_bc_create_align(yasm_expr *boundary, yasm_expr *fill, - yasm_expr *maxskip, const unsigned char **code_fill, - unsigned long line) -{ - bytecode_align *align = yasm_xmalloc(sizeof(bytecode_align)); - - align->boundary = boundary; - align->fill = fill; - align->maxskip = maxskip; - align->code_fill = code_fill; - - return yasm_bc_create_common(&bc_align_callback, align, line); -} +/* + * Align bytecode + * + * Copyright (C) 2005-2007 Peter Johnson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include "util.h" + +#include "libyasm-stdint.h" +#include "coretype.h" + +#include "errwarn.h" +#include "intnum.h" +#include "expr.h" + +#include "bytecode.h" + + +typedef struct bytecode_align { + /*@only@*/ yasm_expr *boundary; /* alignment boundary */ + + /* What to fill intervening locations with, NULL if using code_fill */ + /*@only@*/ /*@null@*/ yasm_expr *fill; + + /* Maximum number of bytes to skip, NULL if no maximum. */ + /*@only@*/ /*@null@*/ yasm_expr *maxskip; + + /* Code fill, NULL if using 0 fill */ + /*@null@*/ const unsigned char **code_fill; +} bytecode_align; + +static void bc_align_destroy(void *contents); +static void bc_align_print(const void *contents, FILE *f, int indent_level); +static void bc_align_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc); +static int bc_align_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, + void *add_span_data); +static int bc_align_expand(yasm_bytecode *bc, int span, long old_val, + long new_val, /*@out@*/ long *neg_thres, + /*@out@*/ long *pos_thres); +static int bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, + unsigned char *bufstart, void *d, + yasm_output_value_func output_value, + /*@null@*/ yasm_output_reloc_func output_reloc); + +static const yasm_bytecode_callback bc_align_callback = { + bc_align_destroy, + bc_align_print, + bc_align_finalize, + NULL, + bc_align_calc_len, + bc_align_expand, + bc_align_tobytes, + YASM_BC_SPECIAL_OFFSET +}; + + +static void +bc_align_destroy(void *contents) +{ + bytecode_align *align = (bytecode_align *)contents; + if (align->boundary) + yasm_expr_destroy(align->boundary); + if (align->fill) + yasm_expr_destroy(align->fill); + if (align->maxskip) + yasm_expr_destroy(align->maxskip); + yasm_xfree(contents); +} + +static void +bc_align_print(const void *contents, FILE *f, int indent_level) +{ + const bytecode_align *align = (const bytecode_align *)contents; + fprintf(f, "%*s_Align_\n", indent_level, ""); + fprintf(f, "%*sBoundary=", indent_level, ""); + yasm_expr_print(align->boundary, f); + fprintf(f, "\n%*sFill=", indent_level, ""); + yasm_expr_print(align->fill, f); + fprintf(f, "\n%*sMax Skip=", indent_level, ""); + yasm_expr_print(align->maxskip, f); + fprintf(f, "\n"); +} + +static void +bc_align_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc) +{ + bytecode_align *align = (bytecode_align *)bc->contents; + if (!yasm_expr_get_intnum(&align->boundary, 0)) + yasm_error_set(YASM_ERROR_NOT_CONSTANT, + N_("align boundary must be a constant")); + if (align->fill && !yasm_expr_get_intnum(&align->fill, 0)) + yasm_error_set(YASM_ERROR_NOT_CONSTANT, + N_("align fill must be a constant")); + if (align->maxskip && !yasm_expr_get_intnum(&align->maxskip, 0)) + yasm_error_set(YASM_ERROR_NOT_CONSTANT, + N_("align maximum skip must be a constant")); +} + +static int +bc_align_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, + void *add_span_data) +{ + long neg_thres = 0; + long pos_thres = 0; + + if (bc_align_expand(bc, 0, 0, (long)bc->offset, &neg_thres, + &pos_thres) < 0) + return -1; + + return 0; +} + +static int +bc_align_expand(yasm_bytecode *bc, int span, long old_val, long new_val, + /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres) +{ + bytecode_align *align = (bytecode_align *)bc->contents; + unsigned long end; + unsigned long boundary = + yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, 0)); + + if (boundary == 0) { + bc->len = 0; + *pos_thres = new_val; + return 0; + } + + end = (unsigned long)new_val; + if ((unsigned long)new_val & (boundary-1)) + end = ((unsigned long)new_val & ~(boundary-1)) + boundary; + + *pos_thres = (long)end; + bc->len = end - (unsigned long)new_val; + + if (align->maxskip) { + unsigned long maxskip = + yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip, 0)); + if (bc->len > maxskip) { + *pos_thres = (long)end-maxskip-1; + bc->len = 0; + } + } + return 1; +} + +static int +bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, + unsigned char *bufstart, void *d, + yasm_output_value_func output_value, + /*@unused@*/ yasm_output_reloc_func output_reloc) +{ + bytecode_align *align = (bytecode_align *)bc->contents; + unsigned long len; + unsigned long boundary = + yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, 0)); + + if (boundary == 0) + return 0; + else { + unsigned long end = bc->offset; + if (bc->offset & (boundary-1)) + end = (bc->offset & ~(boundary-1)) + boundary; + len = end - bc->offset; + if (len == 0) + return 0; + if (align->maxskip) { + unsigned long maxskip = + yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip, 0)); + if (len > maxskip) + return 0; + } + } + + if (align->fill) { + unsigned long v; + v = yasm_intnum_get_uint(yasm_expr_get_intnum(&align->fill, 0)); + memset(*bufp, (int)v, len); + *bufp += len; + } else if (align->code_fill) { + unsigned long maxlen = 15; + while (!align->code_fill[maxlen] && maxlen>0) + maxlen--; + if (maxlen == 0) { + yasm_error_set(YASM_ERROR_GENERAL, + N_("could not find any code alignment size")); + return 1; + } + + /* Fill with maximum code fill as much as possible */ + while (len > maxlen) { + memcpy(*bufp, align->code_fill[maxlen], maxlen); + *bufp += maxlen; + len -= maxlen; + } + + if (!align->code_fill[len]) { + yasm_error_set(YASM_ERROR_VALUE, + N_("invalid alignment size %d"), len); + return 1; + } + /* Handle rest of code fill */ + memcpy(*bufp, align->code_fill[len], len); + *bufp += len; + } else { + /* Just fill with 0 */ + memset(*bufp, 0, len); + *bufp += len; + } + return 0; +} + +yasm_bytecode * +yasm_bc_create_align(yasm_expr *boundary, yasm_expr *fill, + yasm_expr *maxskip, const unsigned char **code_fill, + unsigned long line) +{ + bytecode_align *align = yasm_xmalloc(sizeof(bytecode_align)); + + align->boundary = boundary; + align->fill = fill; + align->maxskip = maxskip; + align->code_fill = code_fill; + + return yasm_bc_create_common(&bc_align_callback, align, line); +} |