Branch data Line data Source code
1 : : /* Add integer to a section. 2 : : Copyright (C) 2002, 2005 Red Hat, Inc. 3 : : This file is part of elfutils. 4 : : Written by Ulrich Drepper <drepper@redhat.com>, 2002. 5 : : 6 : : This file is free software; you can redistribute it and/or modify 7 : : it under the terms of either 8 : : 9 : : * the GNU Lesser General Public License as published by the Free 10 : : Software Foundation; either version 3 of the License, or (at 11 : : your option) any later version 12 : : 13 : : or 14 : : 15 : : * the GNU General Public License as published by the Free 16 : : Software Foundation; either version 2 of the License, or (at 17 : : your option) any later version 18 : : 19 : : or both in parallel, as here. 20 : : 21 : : elfutils is distributed in the hope that it will be useful, but 22 : : WITHOUT ANY WARRANTY; without even the implied warranty of 23 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 : : General Public License for more details. 25 : : 26 : : You should have received copies of the GNU General Public License and 27 : : the GNU Lesser General Public License along with this program. If 28 : : not, see <http://www.gnu.org/licenses/>. */ 29 : : 30 : : #ifdef HAVE_CONFIG_H 31 : : # include <config.h> 32 : : #endif 33 : : 34 : : #include <byteswap.h> 35 : : #include <endian.h> 36 : : #include <inttypes.h> 37 : : #include <string.h> 38 : : 39 : : #include <libasmP.h> 40 : : 41 : : #ifndef SIZE 42 : : # define SIZE 8 43 : : #endif 44 : : 45 : : #define FCT(size) _FCT(size) 46 : : #define _FCT(size) asm_addint##size 47 : : #define TYPE(size) _TYPE(size) 48 : : #define _TYPE(size) int##size##_t 49 : : #define BSWAP(size) _BSWAP(size) 50 : : #define _BSWAP(size) bswap_##size 51 : : 52 : : 53 : : int 54 : 176000 : FCT(SIZE) (AsmScn_t *asmscn, TYPE(SIZE) num) 55 : : { 56 [ + - ]: 176000 : if (asmscn == NULL) 57 : : return -1; 58 : : 59 [ - + - - ]: 176000 : if (asmscn->type == SHT_NOBITS && unlikely (num != 0)) 60 : : { 61 : 0 : __libasm_seterrno (ASM_E_TYPE); 62 : 0 : return -1; 63 : : } 64 : : 65 [ - + ]: 176000 : if (unlikely (asmscn->ctx->textp)) 66 : : { 67 : : // XXX Needs to use backend specified pseudo-ops 68 : 0 : if (SIZE == 8) 69 : : fprintf (asmscn->ctx->out.file, "\t.byte\t%" PRId8 "\n", (int8_t) num); 70 : 0 : else if (SIZE == 16) 71 : : fprintf (asmscn->ctx->out.file, "\t.value\t%" PRId16 "\n", 72 : : (int16_t) num); 73 : 0 : else if (SIZE == 32) 74 : 0 : fprintf (asmscn->ctx->out.file, "\t.long\t%" PRId32 "\n", 75 : : (int32_t) num); 76 : : else 77 : : { 78 : : // XXX This is not necessary for 64-bit machines 79 : : bool is_leb = (elf_getident (asmscn->ctx->out.elf, NULL)[EI_DATA] 80 : : == ELFDATA2LSB); 81 : : 82 : : fprintf (asmscn->ctx->out.file, 83 : : "\t.long\t%" PRId32 "\n\t.long\t%" PRId32 "\n", 84 : : (int32_t) (is_leb 85 : : ? num % 0x100000000ll : num / 0x100000000ll), 86 : : (int32_t) (is_leb 87 : : ? num / 0x100000000ll : num % 0x100000000ll)); 88 : : } 89 : : } 90 : : else 91 : : { 92 : : #if SIZE > 8 93 : 176000 : bool is_leb = (elf_getident (asmscn->ctx->out.elf, NULL)[EI_DATA] 94 : : == ELFDATA2LSB); 95 : : #endif 96 : 176000 : TYPE(SIZE) var = num; 97 : : 98 : : /* Make sure we have enough room. */ 99 [ - + ]: 176000 : if (__libasm_ensure_section_space (asmscn, SIZE / 8) != 0) 100 : 0 : return -1; 101 : : 102 : : #if SIZE > 8 103 [ - + ]: 176000 : if ((BYTE_ORDER == LITTLE_ENDIAN && !is_leb) 104 : : || (BYTE_ORDER == BIG_ENDIAN && is_leb)) 105 : 0 : var = BSWAP(SIZE) (var); 106 : : #endif 107 : : 108 : : /* Copy the variable value. */ 109 [ - + ]: 176000 : if (likely (asmscn->type == SHT_NOBITS)) 110 : 0 : memcpy (&asmscn->content->data[asmscn->content->len], &var, SIZE / 8); 111 : : 112 : : /* Adjust the pointer in the data buffer. */ 113 : 176000 : asmscn->content->len += SIZE / 8; 114 : : 115 : : /* Increment the offset in the (sub)section. */ 116 : 176000 : asmscn->offset += SIZE / 8; 117 : : } 118 : : 119 : : return 0; 120 : : } 121 : : INTDEF(FCT(SIZE))