Home | History | Annotate | Download | only in libasm
      1 /* Add string 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 <ctype.h>
     20 #include <stdio.h>
     21 #include <string.h>
     22 
     23 #include <libasmP.h>
     24 
     25 
     26 /* Add zero terminated string STR of size LEN to (sub)section ASMSCN.  */
     27 int
     28 asm_addstrz (asmscn, str, len)
     29      AsmScn_t *asmscn;
     30      const char *str;
     31      size_t len;
     32 {
     33   if (asmscn == NULL)
     34     return -1;
     35 
     36   if (unlikely (asmscn->type == SHT_NOBITS))
     37     {
     38       if (len == 0)
     39 	{
     40 	  if (str[0] != '\0')
     41 	    {
     42 	      __libasm_seterrno (ASM_E_TYPE);
     43 	      return -1;
     44 	    }
     45 	}
     46       else
     47 	{
     48 	  size_t cnt;
     49 
     50 	  for (cnt = 0; cnt < len; ++cnt)
     51 	    if (str[cnt] != '\0')
     52 	      {
     53 		__libasm_seterrno (ASM_E_TYPE);
     54 		return -1;
     55 	      }
     56 	}
     57     }
     58 
     59   if (len == 0)
     60     len = strlen (str) + 1;
     61 
     62   if (unlikely (asmscn->ctx->textp))
     63     {
     64       bool nextline = true;
     65 
     66       do
     67 	{
     68 	  if (nextline)
     69 	    {
     70 	      fputs ("\t.string\t\"", asmscn->ctx->out.file);
     71 	      nextline = false;
     72 	    }
     73 
     74 	  if (*str == '\0')
     75 	    fputs ("\\000", asmscn->ctx->out.file);
     76 	  else if (! isascii (*str))
     77 	    fprintf (asmscn->ctx->out.file, "\\%03o",
     78 		     (unsigned int) *((unsigned char *)str));
     79 	  else if (*str == '\\')
     80 	    fputs ("\\\\", asmscn->ctx->out.file);
     81 	  else if (*str == '\n')
     82 	    {
     83 	      fputs ("\\n\"", asmscn->ctx->out.file);
     84 	      nextline = true;
     85 	    }
     86 	  else
     87 	    fputc (*str, asmscn->ctx->out.file);
     88 
     89 	  ++str;
     90 	}
     91       while (--len > 0 && (len > 1 || *str != '\0'));
     92 
     93       if (! nextline)
     94 	fputs ("\"\n", asmscn->ctx->out.file);
     95     }
     96   else
     97     {
     98       /* Make sure there is enough room.  */
     99       if (__libasm_ensure_section_space (asmscn, len) != 0)
    100 	return -1;
    101 
    102       /* Copy the string.  */
    103       memcpy (&asmscn->content->data[asmscn->content->len], str, len);
    104 
    105       /* Adjust the pointer in the data buffer.  */
    106       asmscn->content->len += len;
    107 
    108       /* Increment the offset in the (sub)section.  */
    109       asmscn->offset += len;
    110     }
    111 
    112   return 0;
    113 }
    114