blob: 61e5a90931e1fb2cdd18a0ae0bee47ba4087c65e [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Create new COMMON 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. */
29static const AsmScn_t __libasm_com_scn =
30 {
31 .data = {
32 .main = {
33 .scn = ASM_COM_SCN
34 }
35 }
36 };
37
38
39AsmSym_t *
40asm_newcomsym (ctx, name, size, align)
41 AsmCtx_t *ctx;
42 const char *name;
43 GElf_Xword size;
44 GElf_Addr align;
45{
46 AsmSym_t *result;
47
48 if (ctx == NULL)
49 /* Something went wrong before. */
50 return NULL;
51
52 /* Common symbols are public. Therefore the user must provide a
53 name. */
54 if (name == NULL)
55 {
56 __libasm_seterrno (ASM_E_INVALID);
57 return NULL;
58 }
59
60 rwlock_wrlock (ctx->lock);
61
62 result = (AsmSym_t *) malloc (sizeof (AsmSym_t));
63 if (result == NULL)
64 return NULL;
65
66 result->scn = (AsmScn_t *) &__libasm_com_scn;
67 result->size = size;
68 /* XXX Do we have to allow a different type? */
69 result->type = STT_OBJECT;
70 /* XXX Do we have to allow a different binding? */
71 result->binding = STB_GLOBAL;
72 result->symidx = 0;
73 result->strent = ebl_strtabadd (ctx->symbol_strtab, name, 0);
74
75 /* The value of a COM symbol is the alignment. Since there are no
76 subsection and the initial offset of the section is 0 we can get
77 the alignment recorded by storing it into the offset field. */
78 result->offset = align;
79
80 if (unlikely (ctx->textp))
81 fprintf (ctx->out.file, "\t.comm %s, %" PRIuMAX ", %" PRIuMAX "\n",
82 name, (uintmax_t) size, (uintmax_t) align);
83 else
84 {
85 /* Put the symbol in the hash table so that we can later find it. */
86 if (asm_symbol_tab_insert (&ctx->symbol_tab, elf_hash (name), result)
87 != 0)
88 {
89 /* The symbol already exists. */
90 __libasm_seterrno (ASM_E_DUPLSYM);
91 free (result);
92 result = NULL;
93 }
94 else if (name != NULL && asm_emit_symbol_p (name))
95 /* Only count non-private symbols. */
96 ++ctx->nsymbol_tab;
97 }
98
99 rwlock_unlock (ctx->lock);
100
101 return result;
102}