Line data Source code
1 : /* Create new COMMON 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_com_scn =
45 : {
46 : .data = {
47 : .main = {
48 : .scn = ASM_COM_SCN
49 : }
50 : }
51 : };
52 :
53 :
54 : AsmSym_t *
55 1 : asm_newcomsym (AsmCtx_t *ctx, const char *name, GElf_Xword size,
56 : GElf_Addr align)
57 : {
58 : 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 : 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_com_scn;
79 1 : result->size = size;
80 : /* XXX Do we have to allow a different type? */
81 1 : result->type = STT_OBJECT;
82 : /* XXX Do we have to allow a different binding? */
83 1 : result->binding = STB_GLOBAL;
84 1 : result->symidx = 0;
85 1 : result->strent = dwelf_strtab_add (ctx->symbol_strtab, name);
86 :
87 : /* The value of a COM symbol is the alignment. Since there are no
88 : subsection and the initial offset of the section is 0 we can get
89 : the alignment recorded by storing it into the offset field. */
90 1 : result->offset = align;
91 :
92 1 : if (unlikely (ctx->textp))
93 0 : fprintf (ctx->out.file, "\t.comm %s, %" PRIuMAX ", %" PRIuMAX "\n",
94 : name, (uintmax_t) size, (uintmax_t) align);
95 : else
96 : {
97 : /* Put the symbol in the hash table so that we can later find it. */
98 1 : if (asm_symbol_tab_insert (&ctx->symbol_tab, elf_hash (name), result)
99 : != 0)
100 : {
101 : /* The symbol already exists. */
102 0 : __libasm_seterrno (ASM_E_DUPLSYM);
103 0 : free (result);
104 0 : result = NULL;
105 : }
106 1 : else if (name != NULL && asm_emit_symbol_p (name))
107 : /* Only count non-private symbols. */
108 1 : ++ctx->nsymbol_tab;
109 : }
110 :
111 : rwlock_unlock (ctx->lock);
112 :
113 : return result;
114 : }
|