Home | History | Annotate | Download | only in libasm
      1 /* Add integer to a section.
      2    Copyright (C) 2002 Red Hat, Inc.
      3    Written by Ulrich Drepper <drepper (at) 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
     26 asm_adduleb128 (asmscn, num)
     27      AsmScn_t *asmscn;
     28      uint32_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.uleb128\t%" PRIu32 "\n", num);
     41   else
     42     {
     43       char tmpbuf[(sizeof (num) * 8 + 6) / 7];
     44       char *dest = tmpbuf;
     45       uint32_t byte;
     46 
     47       while (1)
     48 	{
     49 	  byte = num & 0x7f;
     50 
     51 	  num >>= 7;
     52 	  if (num == 0)
     53 	    /* This is the last byte.  */
     54 	    break;
     55 
     56 	  *dest++ = byte | 0x80;
     57 	}
     58 
     59       *dest++ = byte;
     60 
     61       /* Number of bytes produced.  */
     62       size_t nbytes = dest - tmpbuf;
     63 
     64       /* Make sure we have enough room.  */
     65       if (__libasm_ensure_section_space (asmscn, nbytes) != 0)
     66 	return -1;
     67 
     68       /* Copy the bytes.  */
     69       if (likely (asmscn->type != SHT_NOBITS))
     70 	memcpy (&asmscn->content->data[asmscn->content->len], tmpbuf, nbytes);
     71 
     72       /* Adjust the pointer in the data buffer.  */
     73       asmscn->content->len += nbytes;
     74 
     75       /* Increment the offset in the (sub)section.  */
     76       asmscn->offset += nbytes;
     77     }
     78 
     79   return 0;
     80 }
     81