1 /* Create new section in output file.
2 Copyright (C) 2002-2011 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2002.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
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
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
19 or both in parallel, as here.
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.
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/>. */
45 /* Memory for the default pattern. The type uses a flexible array
46 which does work well with a static initializer. So we play some
50 struct FillPattern pattern;
60 const struct FillPattern *__libasm_default_pattern = &xdefault_pattern.pattern;
64 text_newscn (AsmScn_t *result, GElf_Word type, GElf_Xword flags)
66 /* Buffer where we construct the flag string. */
67 char flagstr[sizeof (GElf_Xword) * 8 + 5];
69 const char *typestr = "";
71 /* Only write out the flag string if this is the first time the
72 section is selected. Some assemblers cannot cope with the
73 .section pseudo-op otherwise. */
74 wp = stpcpy (wp, ", \"");
76 if (flags & SHF_WRITE)
78 if (flags & SHF_ALLOC)
80 if (flags & SHF_EXECINSTR)
82 if (flags & SHF_MERGE)
84 if (flags & SHF_STRINGS)
86 if (flags & SHF_LINK_ORDER)
91 if (type == SHT_PROGBITS)
92 typestr = ",@progbits";
93 else if (type == SHT_NOBITS)
96 /* Terminate the string. */
99 fprintf (result->ctx->out.file, "\t.section \"%s\"%s%s\n",
100 result->name, flagstr, typestr);
107 binary_newscn (AsmScn_t *result, GElf_Word type, GElf_Xword flags,
114 /* The initial subsection has the number zero. */
115 result->subsection_id = 0;
117 /* We start at offset zero. */
119 /* And generic alignment. */
120 result->max_align = 1;
123 result->content = NULL;
125 /* Put the default fill pattern in place. */
126 result->pattern = (struct FillPattern *) __libasm_default_pattern;
128 /* There are no subsections so far. */
129 result->subnext = NULL;
131 /* Add the name to the section header string table. */
132 result->data.main.strent = ebl_strtabadd (result->ctx->section_strtab,
133 result->name, scnname_len);
134 assert (result->data.main.strent != NULL);
136 /* Create the new ELF section. */
137 result->data.main.scn = scn = elf_newscn (result->ctx->out.elf);
141 __libasm_seterrno (ASM_E_LIBELF);
145 /* Not part of a section group (yet). */
146 result->data.main.next_in_group = NULL;
148 /* Remember the flags. */
149 shdr = gelf_getshdr (scn, &shdr_mem);
151 shdr->sh_flags = flags;
152 result->type = shdr->sh_type = type;
154 (void) gelf_update_shdr (scn, shdr);
161 asm_newscn (AsmCtx_t *ctx, const char *scnname, GElf_Word type,
164 size_t scnname_len = strlen (scnname) + 1;
167 /* If no context is given there might be an earlier error. */
171 /* Check whether only flags are set which areselectable by the user. */
172 if (unlikely ((flags & ~(SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE
173 | SHF_STRINGS | SHF_LINK_ORDER)) != 0)
174 /* We allow only two section types: data and data without file
176 || (type != SHT_PROGBITS && unlikely (type != SHT_NOBITS)))
178 __libasm_seterrno (ASM_E_INVALID);
182 rwlock_wrlock (ctx->lock);
184 /* This is a new section. */
185 result = (AsmScn_t *) malloc (sizeof (AsmScn_t) + scnname_len);
189 memcpy (result->name, scnname, scnname_len);
191 /* Add the reference to the context. */
194 /* Perform operations according to output mode. */
195 result = (unlikely (ctx->textp)
196 ? text_newscn (result, type, flags)
197 : binary_newscn (result, type, flags, scnname_len));
199 /* If everything went well finally add the new section to the hash
203 result->allnext = ctx->section_list;
204 ctx->section_list = result;
208 rwlock_unlock (ctx->lock);