1*7304104dSAndroid Build Coastguard Worker /* Add signed little endian base 128 integer to a section.
2*7304104dSAndroid Build Coastguard Worker Copyright (C) 2002, 2005 Red Hat, Inc.
3*7304104dSAndroid Build Coastguard Worker This file is part of elfutils.
4*7304104dSAndroid Build Coastguard Worker Written by Ulrich Drepper <[email protected]>, 2002.
5*7304104dSAndroid Build Coastguard Worker
6*7304104dSAndroid Build Coastguard Worker This file is free software; you can redistribute it and/or modify
7*7304104dSAndroid Build Coastguard Worker it under the terms of either
8*7304104dSAndroid Build Coastguard Worker
9*7304104dSAndroid Build Coastguard Worker * the GNU Lesser General Public License as published by the Free
10*7304104dSAndroid Build Coastguard Worker Software Foundation; either version 3 of the License, or (at
11*7304104dSAndroid Build Coastguard Worker your option) any later version
12*7304104dSAndroid Build Coastguard Worker
13*7304104dSAndroid Build Coastguard Worker or
14*7304104dSAndroid Build Coastguard Worker
15*7304104dSAndroid Build Coastguard Worker * the GNU General Public License as published by the Free
16*7304104dSAndroid Build Coastguard Worker Software Foundation; either version 2 of the License, or (at
17*7304104dSAndroid Build Coastguard Worker your option) any later version
18*7304104dSAndroid Build Coastguard Worker
19*7304104dSAndroid Build Coastguard Worker or both in parallel, as here.
20*7304104dSAndroid Build Coastguard Worker
21*7304104dSAndroid Build Coastguard Worker elfutils is distributed in the hope that it will be useful, but
22*7304104dSAndroid Build Coastguard Worker WITHOUT ANY WARRANTY; without even the implied warranty of
23*7304104dSAndroid Build Coastguard Worker MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24*7304104dSAndroid Build Coastguard Worker General Public License for more details.
25*7304104dSAndroid Build Coastguard Worker
26*7304104dSAndroid Build Coastguard Worker You should have received copies of the GNU General Public License and
27*7304104dSAndroid Build Coastguard Worker the GNU Lesser General Public License along with this program. If
28*7304104dSAndroid Build Coastguard Worker not, see <http://www.gnu.org/licenses/>. */
29*7304104dSAndroid Build Coastguard Worker
30*7304104dSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
31*7304104dSAndroid Build Coastguard Worker # include <config.h>
32*7304104dSAndroid Build Coastguard Worker #endif
33*7304104dSAndroid Build Coastguard Worker
34*7304104dSAndroid Build Coastguard Worker #include <inttypes.h>
35*7304104dSAndroid Build Coastguard Worker #include <string.h>
36*7304104dSAndroid Build Coastguard Worker
37*7304104dSAndroid Build Coastguard Worker #include <libasmP.h>
38*7304104dSAndroid Build Coastguard Worker
39*7304104dSAndroid Build Coastguard Worker
40*7304104dSAndroid Build Coastguard Worker int
asm_addsleb128(AsmScn_t * asmscn,int32_t num)41*7304104dSAndroid Build Coastguard Worker asm_addsleb128 (AsmScn_t *asmscn, int32_t num)
42*7304104dSAndroid Build Coastguard Worker {
43*7304104dSAndroid Build Coastguard Worker if (asmscn == NULL)
44*7304104dSAndroid Build Coastguard Worker return -1;
45*7304104dSAndroid Build Coastguard Worker
46*7304104dSAndroid Build Coastguard Worker if (asmscn->type == SHT_NOBITS && unlikely (num != 0))
47*7304104dSAndroid Build Coastguard Worker {
48*7304104dSAndroid Build Coastguard Worker __libasm_seterrno (ASM_E_TYPE);
49*7304104dSAndroid Build Coastguard Worker return -1;
50*7304104dSAndroid Build Coastguard Worker }
51*7304104dSAndroid Build Coastguard Worker
52*7304104dSAndroid Build Coastguard Worker if (unlikely (asmscn->ctx->textp))
53*7304104dSAndroid Build Coastguard Worker fprintf (asmscn->ctx->out.file, "\t.sleb128\t%" PRId32 "\n", num);
54*7304104dSAndroid Build Coastguard Worker else
55*7304104dSAndroid Build Coastguard Worker {
56*7304104dSAndroid Build Coastguard Worker char tmpbuf[(sizeof (num) * 8 + 6) / 7];
57*7304104dSAndroid Build Coastguard Worker char *dest = tmpbuf;
58*7304104dSAndroid Build Coastguard Worker uint32_t byte;
59*7304104dSAndroid Build Coastguard Worker int32_t endval = num >> 31;
60*7304104dSAndroid Build Coastguard Worker
61*7304104dSAndroid Build Coastguard Worker if (num == 0)
62*7304104dSAndroid Build Coastguard Worker byte = 0;
63*7304104dSAndroid Build Coastguard Worker else
64*7304104dSAndroid Build Coastguard Worker while (1)
65*7304104dSAndroid Build Coastguard Worker {
66*7304104dSAndroid Build Coastguard Worker byte = num & 0x7f;
67*7304104dSAndroid Build Coastguard Worker
68*7304104dSAndroid Build Coastguard Worker num >>= 7;
69*7304104dSAndroid Build Coastguard Worker if (num == endval)
70*7304104dSAndroid Build Coastguard Worker /* This is the last byte. */
71*7304104dSAndroid Build Coastguard Worker break;
72*7304104dSAndroid Build Coastguard Worker
73*7304104dSAndroid Build Coastguard Worker *dest++ = byte | 0x80;
74*7304104dSAndroid Build Coastguard Worker }
75*7304104dSAndroid Build Coastguard Worker
76*7304104dSAndroid Build Coastguard Worker *dest++ = byte;
77*7304104dSAndroid Build Coastguard Worker
78*7304104dSAndroid Build Coastguard Worker /* Number of bytes produced. */
79*7304104dSAndroid Build Coastguard Worker size_t nbytes = dest - tmpbuf;
80*7304104dSAndroid Build Coastguard Worker
81*7304104dSAndroid Build Coastguard Worker /* Make sure we have enough room. */
82*7304104dSAndroid Build Coastguard Worker if (__libasm_ensure_section_space (asmscn, nbytes) != 0)
83*7304104dSAndroid Build Coastguard Worker return -1;
84*7304104dSAndroid Build Coastguard Worker
85*7304104dSAndroid Build Coastguard Worker /* Copy the bytes. */
86*7304104dSAndroid Build Coastguard Worker if (likely (asmscn->type != SHT_NOBITS))
87*7304104dSAndroid Build Coastguard Worker memcpy (&asmscn->content->data[asmscn->content->len], tmpbuf, nbytes);
88*7304104dSAndroid Build Coastguard Worker
89*7304104dSAndroid Build Coastguard Worker /* Adjust the pointer in the data buffer. */
90*7304104dSAndroid Build Coastguard Worker asmscn->content->len += nbytes;
91*7304104dSAndroid Build Coastguard Worker
92*7304104dSAndroid Build Coastguard Worker /* Increment the offset in the (sub)section. */
93*7304104dSAndroid Build Coastguard Worker asmscn->offset += nbytes;
94*7304104dSAndroid Build Coastguard Worker }
95*7304104dSAndroid Build Coastguard Worker
96*7304104dSAndroid Build Coastguard Worker return 0;
97*7304104dSAndroid Build Coastguard Worker }
98