• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Create new ABS symbol.
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 <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include <libasmP.h>
25 #include <system.h>
26 
27 
28 /* Object for special COMMON section.  */
29 static const AsmScn_t __libasm_abs_scn =
30   {
31     .data = {
32       .main = {
33 	.scn = ASM_ABS_SCN
34       }
35     }
36   };
37 
38 
39 AsmSym_t *
asm_newabssym(ctx,name,size,value,type,binding)40 asm_newabssym (ctx, name, size, value, type, binding)
41      AsmCtx_t *ctx;
42      const char *name;
43      GElf_Xword size;
44      GElf_Addr value;
45      int type;
46      int binding;
47 {
48   AsmSym_t *result;
49 
50   if (ctx == NULL)
51     /* Something went wrong before.  */
52     return NULL;
53 
54   /* Common symbols are public.  Therefore the user must provide a
55      name.  */
56   if (name == NULL)
57     {
58       __libasm_seterrno (ASM_E_INVALID);
59       return NULL;
60     }
61 
62   rwlock_wrlock (ctx->lock);
63 
64   result = (AsmSym_t *) malloc (sizeof (AsmSym_t));
65   if (result == NULL)
66     return NULL;
67 
68   result->scn = (AsmScn_t *) &__libasm_abs_scn;
69   result->size = size;
70   result->type = type;
71   result->binding = binding;
72   result->symidx = 0;
73   result->strent = ebl_strtabadd (ctx->symbol_strtab, name, 0);
74 
75   /* The value of an ABS symbol must not be modified.  Since there are
76      no subsection and the initial offset of the section is 0 we can
77      get the alignment recorded by storing it into the offset
78      field.  */
79   result->offset = value;
80 
81   if (unlikely (ctx->textp))
82     {
83       /* An absolute symbol can be defined by giving a symbol a
84 	 specific value.  */
85       if (binding == STB_GLOBAL)
86 	fprintf (ctx->out.file, "\t.globl %s\n", name);
87       else if (binding == STB_WEAK)
88 	fprintf (ctx->out.file, "\t.weak %s\n", name);
89 
90       if (type == STT_OBJECT)
91 	fprintf (ctx->out.file, "\t.type %s,@object\n", name);
92       else if (type == STT_FUNC)
93 	fprintf (ctx->out.file, "\t.type %s,@function\n", name);
94 
95       fprintf (ctx->out.file, "%s = %llu\n",
96 	       name, (unsigned long long int) value);
97 
98       if (size != 0)
99 	fprintf (ctx->out.file, "\t.size %s, %llu\n",
100 		 name, (unsigned long long int) size);
101     }
102   else
103     {
104       /* Put the symbol in the hash table so that we can later find it.  */
105       if (asm_symbol_tab_insert (&ctx->symbol_tab, elf_hash (name), result)
106 	  != 0)
107 	{
108 	  /* The symbol already exists.  */
109 	  __libasm_seterrno (ASM_E_DUPLSYM);
110 	  free (result);
111 	  result = NULL;
112 	}
113       else if (name != NULL && asm_emit_symbol_p (name))
114 	/* Only count non-private symbols.  */
115 	++ctx->nsymbol_tab;
116     }
117 
118   rwlock_unlock (ctx->lock);
119 
120   return result;
121 }
122