Line data Source code
1 : /* Create new ABS symbol.
2 : Copyright (C) 2002, 2016 Red Hat, Inc.
3 : This file is part of elfutils.
4 : Written by Ulrich Drepper <drepper@redhat.com>, 2002.
5 :
6 : This file is free software; you can redistribute it and/or modify
7 : it under the terms of either
8 :
9 : * the GNU Lesser General Public License as published by the Free
10 : Software Foundation; either version 3 of the License, or (at
11 : your option) any later version
12 :
13 : or
14 :
15 : * the GNU General Public License as published by the Free
16 : Software Foundation; either version 2 of the License, or (at
17 : your option) any later version
18 :
19 : or both in parallel, as here.
20 :
21 : elfutils is distributed in the hope that it will be useful, but
22 : WITHOUT ANY WARRANTY; without even the implied warranty of
23 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : General Public License for more details.
25 :
26 : You should have received copies of the GNU General Public License and
27 : the GNU Lesser General Public License along with this program. If
28 : not, see <http://www.gnu.org/licenses/>. */
29 :
30 : #ifdef HAVE_CONFIG_H
31 : # include <config.h>
32 : #endif
33 :
34 : #include <inttypes.h>
35 : #include <stdio.h>
36 : #include <stdlib.h>
37 : #include <string.h>
38 :
39 : #include <libasmP.h>
40 : #include <system.h>
41 :
42 :
43 : /* Object for special COMMON section. */
44 : static const AsmScn_t __libasm_abs_scn =
45 : {
46 : .data = {
47 : .main = {
48 : .scn = ASM_ABS_SCN
49 : }
50 : }
51 : };
52 :
53 :
54 : AsmSym_t *
55 1 : asm_newabssym (AsmCtx_t *ctx, const char *name, GElf_Xword size,
56 : GElf_Addr value, int type, int binding)
57 : {
58 1 : AsmSym_t *result;
59 :
60 1 : if (ctx == NULL)
61 : /* Something went wrong before. */
62 : return NULL;
63 :
64 : /* Common symbols are public. Therefore the user must provide a
65 : name. */
66 1 : if (name == NULL)
67 : {
68 0 : __libasm_seterrno (ASM_E_INVALID);
69 0 : return NULL;
70 : }
71 :
72 1 : rwlock_wrlock (ctx->lock);
73 :
74 1 : result = (AsmSym_t *) malloc (sizeof (AsmSym_t));
75 1 : if (result == NULL)
76 : return NULL;
77 :
78 1 : result->scn = (AsmScn_t *) &__libasm_abs_scn;
79 1 : result->size = size;
80 1 : result->type = type;
81 1 : result->binding = binding;
82 1 : result->symidx = 0;
83 1 : result->strent = dwelf_strtab_add (ctx->symbol_strtab, name);
84 :
85 : /* The value of an ABS symbol must not be modified. Since there are
86 : no subsection and the initial offset of the section is 0 we can
87 : get the alignment recorded by storing it into the offset
88 : field. */
89 1 : result->offset = value;
90 :
91 1 : if (unlikely (ctx->textp))
92 : {
93 : /* An absolute symbol can be defined by giving a symbol a
94 : specific value. */
95 0 : if (binding == STB_GLOBAL)
96 0 : fprintf (ctx->out.file, "\t.globl %s\n", name);
97 0 : else if (binding == STB_WEAK)
98 0 : fprintf (ctx->out.file, "\t.weak %s\n", name);
99 :
100 0 : if (type == STT_OBJECT)
101 0 : fprintf (ctx->out.file, "\t.type %s,@object\n", name);
102 0 : else if (type == STT_FUNC)
103 0 : fprintf (ctx->out.file, "\t.type %s,@function\n", name);
104 :
105 0 : fprintf (ctx->out.file, "%s = %llu\n",
106 : name, (unsigned long long int) value);
107 :
108 0 : if (size != 0)
109 0 : fprintf (ctx->out.file, "\t.size %s, %llu\n",
110 : name, (unsigned long long int) size);
111 : }
112 : else
113 : {
114 : /* Put the symbol in the hash table so that we can later find it. */
115 1 : if (asm_symbol_tab_insert (&ctx->symbol_tab, elf_hash (name), result)
116 : != 0)
117 : {
118 : /* The symbol already exists. */
119 0 : __libasm_seterrno (ASM_E_DUPLSYM);
120 0 : free (result);
121 0 : result = NULL;
122 : }
123 1 : else if (name != NULL && asm_emit_symbol_p (name))
124 : /* Only count non-private symbols. */
125 1 : ++ctx->nsymbol_tab;
126 : }
127 :
128 : rwlock_unlock (ctx->lock);
129 :
130 : return result;
131 : }
|