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