• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Add signed little endian base 128 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 <inttypes.h>
20 #include <string.h>
21 
22 #include <libasmP.h>
23 
24 
25 int
asm_addsleb128(asmscn,num)26 asm_addsleb128 (asmscn, num)
27      AsmScn_t *asmscn;
28      int32_t num;
29 {
30   if (asmscn == NULL)
31     return -1;
32 
33   if (asmscn->type == SHT_NOBITS && unlikely (num != 0))
34     {
35       __libasm_seterrno (ASM_E_TYPE);
36       return -1;
37     }
38 
39   if (unlikely (asmscn->ctx->textp))
40     printf ("\t.sleb128\t%" PRId32 "\n", num);
41   else
42     {
43       char tmpbuf[(sizeof (num) * 8 + 6) / 7];
44       char *dest = tmpbuf;
45       uint32_t byte;
46       int32_t endval = num >> 31;
47 
48       if (num == 0)
49 	byte = 0;
50       else
51 	while (1)
52 	  {
53 	    byte = num & 0x7f;
54 
55 	    num >>= 7;
56 	    if (num == endval)
57 	      /* This is the last byte.  */
58 	      break;
59 
60 	    *dest++ = byte | 0x80;
61 	  }
62 
63       *dest++ = byte;
64 
65       /* Number of bytes produced.  */
66       size_t nbytes = dest - tmpbuf;
67 
68       /* Make sure we have enough room.  */
69       if (__libasm_ensure_section_space (asmscn, nbytes) != 0)
70 	return -1;
71 
72       /* Copy the bytes.  */
73       if (likely (asmscn->type != SHT_NOBITS))
74 	memcpy (&asmscn->content->data[asmscn->content->len], tmpbuf, nbytes);
75 
76       /* Adjust the pointer in the data buffer.  */
77       asmscn->content->len += nbytes;
78 
79       /* Increment the offset in the (sub)section.  */
80       asmscn->offset += nbytes;
81     }
82 
83   return 0;
84 }
85