Branch data Line data Source code
1 : : /* Define new symbol for current position in given section.
2 : : Copyright (C) 2002, 2005 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 : : AsmSym_t *
44 : 88003 : asm_newsym (asmscn, name, size, type, binding)
45 : : AsmScn_t *asmscn;
46 : : const char *name;
47 : : GElf_Xword size;
48 : : int type;
49 : : int binding;
50 : : {
51 : : #define TEMPSYMLEN 10
52 : : char tempsym[TEMPSYMLEN];
53 : : AsmSym_t *result;
54 : :
55 [ + - ]: 88003 : if (asmscn == NULL)
56 : : /* Something went wrong before. */
57 : : return NULL;
58 : :
59 : : /* Generate a temporary symbol if necessary. */
60 [ - + ]: 88003 : if (name == NULL)
61 : : {
62 : : /* If a local symbol name is created the symbol better have
63 : : local binding. */
64 [ # # ]: 0 : if (binding != STB_LOCAL)
65 : : {
66 : 0 : __libasm_seterrno (ASM_E_INVALID);
67 : : return NULL;
68 : : }
69 : :
70 : : // XXX This requires getting the format from the machine backend. */
71 : 0 : snprintf (tempsym, TEMPSYMLEN, ".L%07u", asmscn->ctx->tempsym_count++);
72 : :
73 : 0 : name = tempsym;
74 : : }
75 : :
76 : 88003 : size_t name_len = strlen (name) + 1;
77 : :
78 : 88003 : result = (AsmSym_t *) malloc (sizeof (AsmSym_t) + name_len);
79 [ + - ]: 88003 : if (result == NULL)
80 : : return NULL;
81 : :
82 : : rwlock_wrlock (asmscn->ctx->lock);
83 : :
84 : 88003 : result->scn = asmscn;
85 : 88003 : result->offset = asmscn->offset;
86 : 88003 : result->size = size;
87 : 88003 : result->type = type;
88 : 88003 : result->binding = binding;
89 : 88003 : result->symidx = 0;
90 : 88003 : result->strent = ebl_strtabadd (asmscn->ctx->symbol_strtab,
91 : 88003 : memcpy (result + 1, name, name_len), 0);
92 : :
93 [ - + ]: 88003 : if (unlikely (asmscn->ctx->textp))
94 : : {
95 : : /* We are only interested in the name and don't need to know whether
96 : : it is a local name or not. */
97 : : /* First print the binding pseudo-op. */
98 [ # # ]: 0 : if (binding == STB_GLOBAL)
99 : 0 : fprintf (asmscn->ctx->out.file, "\t.globl\t%s\n", name);
100 [ # # ]: 0 : else if (binding == STB_WEAK)
101 : 0 : fprintf (asmscn->ctx->out.file, "\t.weak\t%s\n", name);
102 : :
103 : : /* Next the symbol type. */
104 [ # # ]: 0 : if (type == STT_OBJECT)
105 : 0 : fprintf (asmscn->ctx->out.file, "\t.type\t%s,@object\n", name);
106 [ # # ]: 0 : else if (type == STT_FUNC)
107 : 0 : fprintf (asmscn->ctx->out.file, "\t.type\t%s,@function\n", name);
108 : :
109 : : /* Finally the size and the label. */
110 : 0 : fprintf (asmscn->ctx->out.file, "\t.size\t%s,%" PRIuMAX "\n%s:\n",
111 : : name, (uintmax_t) size, name);
112 : : }
113 : : else
114 : : {
115 : : /* Put the symbol in the hash table so that we can later find it. */
116 [ - + ]: 88003 : if (asm_symbol_tab_insert (&asmscn->ctx->symbol_tab, elf_hash (name),
117 : : result) != 0)
118 : : {
119 : : /* The symbol already exists. */
120 : 0 : __libasm_seterrno (ASM_E_DUPLSYM);
121 : : /* Note that we can free the entry since there must be no
122 : : reference in the string table to the string. We can only
123 : : fail to insert the symbol into the symbol table if there
124 : : is already a symbol with this name. In this case the
125 : : ebl_strtabadd function would use the previously provided
126 : : name. */
127 : 0 : free (result);
128 : 0 : result = NULL;
129 : : }
130 [ + - ][ + - ]: 88003 : else if (name != tempsym && asm_emit_symbol_p (name))
131 : : /* Only count non-private symbols. */
132 : 88003 : ++asmscn->ctx->nsymbol_tab;
133 : : }
134 : :
135 : : rwlock_unlock (asmscn->ctx->lock);
136 : :
137 : : return result;
138 : : }
|