blob: 35d9bf574cf4106589aa83814c8ff668e43c4a0e [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Add integer to a section.
2 Copyright (C) 2002 Red Hat, Inc.
3 Written by Ulrich Drepper <drepper@redhat.com>, 2002.
4
5 This program is Open Source software; you can redistribute it and/or
6 modify it under the terms of the Open Software License version 1.0 as
7 published by the Open Source Initiative.
8
9 You should have received a copy of the Open Software License along
10 with this program; if not, you may obtain a copy of the Open Software
11 License version 1.0 from http://www.opensource.org/licenses/osl.php or
12 by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
13 3001 King Ranch Road, Ukiah, CA 95482. */
14
15#ifdef HAVE_CONFIG_H
16# include <config.h>
17#endif
18
19#include <byteswap.h>
20#include <endian.h>
21#include <inttypes.h>
22#include <string.h>
23
24#include <libasmP.h>
25
26#ifndef SIZE
27# define SIZE 8
28#endif
29
30#define FCT(size) _FCT(size)
31#define _FCT(size) asm_addint##size
32#define TYPE(size) _TYPE(size)
33#define _TYPE(size) int##size##_t
34#define BSWAP(size) _BSWAP(size)
35#define _BSWAP(size) bswap_##size
36
37
38int
39FCT(SIZE) (asmscn, num)
40 AsmScn_t *asmscn;
41 TYPE(SIZE) num;
42{
43 if (asmscn == NULL)
44 return -1;
45
46 if (asmscn->type == SHT_NOBITS && unlikely (num != 0))
47 {
48 __libasm_seterrno (ASM_E_TYPE);
49 return -1;
50 }
51
52 if (unlikely (asmscn->ctx->textp))
53 {
54 // XXX Needs to use backend specified pseudo-ops
55 if (SIZE == 8)
56 printf ("\t.byte\t%" PRId8 "\n", (int8_t) num);
57 else if (SIZE == 16)
58 printf ("\t.value\t%" PRId16 "\n", (int16_t) num);
59 else if (SIZE == 32)
60 printf ("\t.long\t%" PRId32 "\n", (int32_t) num);
61 else
62 {
63 // XXX This is not necessary for 64-bit machines
64 bool is_leb = (elf_getident (asmscn->ctx->out.elf, NULL)[EI_DATA]
65 == ELFDATA2LSB);
66
67 printf ("\t.long\t%" PRId32 "\n\t.long\t%" PRId32 "\n",
68 (int32_t) (is_leb
69 ? num % 0x100000000ll : num / 0x100000000ll),
70 (int32_t) (is_leb
71 ? num / 0x100000000ll : num % 0x100000000ll));
72 }
73 }
74 else
75 {
76#if SIZE > 8
77 bool is_leb = (elf_getident (asmscn->ctx->out.elf, NULL)[EI_DATA]
78 == ELFDATA2LSB);
79#endif
80 TYPE(SIZE) var = num;
81
82 /* Make sure we have enough room. */
83 if (__libasm_ensure_section_space (asmscn, SIZE / 8) != 0)
84 return -1;
85
86#if SIZE > 8
87 if ((BYTE_ORDER == LITTLE_ENDIAN && !is_leb)
88 || (BYTE_ORDER == BIG_ENDIAN && is_leb))
89 var = BSWAP(SIZE) (var);
90#endif
91
92 /* Copy the variable value. */
93 if (likely (asmscn->type == SHT_NOBITS))
94 memcpy (&asmscn->content->data[asmscn->content->len], &var, SIZE / 8);
95
96 /* Adjust the pointer in the data buffer. */
97 asmscn->content->len += SIZE / 8;
98
99 /* Increment the offset in the (sub)section. */
100 asmscn->offset += SIZE / 8;
101 }
102
103 return 0;
104}
105INTDEF(FCT(SIZE))