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 <inttypes.h> 35 : : #include <string.h> 36 : : 37 : : #include <libasmP.h> 38 : : 39 : : #ifndef SIZE 40 : : # define SIZE 8 41 : : #endif 42 : : 43 : : #define FCT(size) _FCT(size) 44 : : #define _FCT(size) asm_addint##size 45 : : #define TYPE(size) _TYPE(size) 46 : : #define _TYPE(size) int##size##_t 47 : : #define BSWAP(size) _BSWAP(size) 48 : : #define _BSWAP(size) bswap_##size 49 : : 50 : : 51 : : int 52 : 176000 : FCT(SIZE) (AsmScn_t *asmscn, TYPE(SIZE) num) 53 : : { 54 [ + - ]: 176000 : if (asmscn == NULL) 55 : : return -1; 56 : : 57 [ - + - - ]: 176000 : if (asmscn->type == SHT_NOBITS && unlikely (num != 0)) 58 : : { 59 : 0 : __libasm_seterrno (ASM_E_TYPE); 60 : 0 : return -1; 61 : : } 62 : : 63 [ - + ]: 176000 : if (unlikely (asmscn->ctx->textp)) 64 : : { 65 : : // XXX Needs to use backend specified pseudo-ops 66 : 0 : if (SIZE == 8) 67 : : fprintf (asmscn->ctx->out.file, "\t.byte\t%" PRId8 "\n", (int8_t) num); 68 : 0 : else if (SIZE == 16) 69 : : fprintf (asmscn->ctx->out.file, "\t.value\t%" PRId16 "\n", 70 : : (int16_t) num); 71 : 0 : else if (SIZE == 32) 72 : 0 : fprintf (asmscn->ctx->out.file, "\t.long\t%" PRId32 "\n", 73 : : (int32_t) num); 74 : : else 75 : : { 76 : : // XXX This is not necessary for 64-bit machines 77 : : bool is_leb = (elf_getident (asmscn->ctx->out.elf, NULL)[EI_DATA] 78 : : == ELFDATA2LSB); 79 : : 80 : : fprintf (asmscn->ctx->out.file, 81 : : "\t.long\t%" PRId32 "\n\t.long\t%" PRId32 "\n", 82 : : (int32_t) (is_leb 83 : : ? num % 0x100000000ll : num / 0x100000000ll), 84 : : (int32_t) (is_leb 85 : : ? num / 0x100000000ll : num % 0x100000000ll)); 86 : : } 87 : : } 88 : : else 89 : : { 90 : : #if SIZE > 8 91 : 176000 : bool is_leb = (elf_getident (asmscn->ctx->out.elf, NULL)[EI_DATA] 92 : : == ELFDATA2LSB); 93 : : #endif 94 : 176000 : TYPE(SIZE) var = num; 95 : : 96 : : /* Make sure we have enough room. */ 97 [ - + ]: 176000 : if (__libasm_ensure_section_space (asmscn, SIZE / 8) != 0) 98 : 0 : return -1; 99 : : 100 : : #if SIZE > 8 101 [ - + ]: 176000 : if ((BYTE_ORDER == LITTLE_ENDIAN && !is_leb) 102 : : || (BYTE_ORDER == BIG_ENDIAN && is_leb)) 103 : 0 : var = BSWAP(SIZE) (var); 104 : : #endif 105 : : 106 : : /* Copy the variable value. */ 107 [ - + ]: 176000 : if (likely (asmscn->type == SHT_NOBITS)) 108 : 0 : memcpy (&asmscn->content->data[asmscn->content->len], &var, SIZE / 8); 109 : : 110 : : /* Adjust the pointer in the data buffer. */ 111 : 176000 : asmscn->content->len += SIZE / 8; 112 : : 113 : : /* Increment the offset in the (sub)section. */ 114 : 176000 : asmscn->offset += SIZE / 8; 115 : : } 116 : : 117 : : return 0; 118 : : } 119 : : INTDEF(FCT(SIZE))