blob: acec1a481652f12e7999f8cd783e0b5793208ef2 [file] [log] [blame]
Ulrich Dreppera38998e2005-08-03 02:05:39 +00001/* Copyright (C) 2002, 2005 Red Hat, Inc.
Mark Wielaardde2ed972012-06-05 17:15:16 +02002 This file is part of elfutils.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00003 Written by Ulrich Drepper <drepper@redhat.com>, 2002.
4
Mark Wielaardde2ed972012-06-05 17:15:16 +02005 This file is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00009
Mark Wielaardde2ed972012-06-05 17:15:16 +020010 elfutils is distributed in the hope that it will be useful, but
Ulrich Drepper361df7d2006-04-04 21:38:57 +000011 WITHOUT ANY WARRANTY; without even the implied warranty of
Mark Wielaardde2ed972012-06-05 17:15:16 +020012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
Ulrich Drepper361df7d2006-04-04 21:38:57 +000014
Mark Wielaardde2ed972012-06-05 17:15:16 +020015 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000017
Roland McGrathd7f8d0c2005-11-17 02:32:03 +000018#ifdef HAVE_CONFIG_H
19# include <config.h>
20#endif
21
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000022#include <fcntl.h>
Roland McGrathd7f8d0c2005-11-17 02:32:03 +000023#include ELFUTILS_HEADER(asm)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000024#include <libelf.h>
25#include <stdio.h>
26#include <string.h>
27#include <unistd.h>
28
29
30static const char fname[] = "asm-tst3-out.o";
31
32
33static const char *scnnames[5] =
34 {
35 [0] = "",
36 [1] = ".data",
37 [2] = ".strtab",
38 [3] = ".symtab",
39 [4] = ".shstrtab"
40 };
41
42
43static unsigned int scntypes[5] =
44 {
45 [0] = SHT_NULL,
46 [1] = SHT_PROGBITS,
47 [2] = SHT_STRTAB,
48 [3] = SHT_SYMTAB,
49 [4] = SHT_STRTAB
50 };
51
52
53int
54main (void)
55{
56 AsmCtx_t *ctx;
57 AsmScn_t *scn1;
58 AsmScn_t *scn2;
59 int result = 0;
60 int fd;
61 Elf *elf;
62 GElf_Ehdr ehdr_mem;
63 GElf_Ehdr *ehdr;
64 size_t cnt;
65
66 elf_version (EV_CURRENT);
67
Ulrich Dreppera38998e2005-08-03 02:05:39 +000068 Ebl *ebl = ebl_openbackend_machine (EM_386);
69 if (ebl == NULL)
70 {
71 puts ("cannot open backend library");
72 return 1;
73 }
74
75 ctx = asm_begin (fname, ebl, false);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000076 if (ctx == NULL)
77 {
78 printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
79 return 1;
80 }
81
82 /* Create two sections. */
83 scn1 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
84 scn2 = asm_newsubscn (scn1, 1);
85 if (scn1 == NULL || scn2 == NULL)
86 {
87 printf ("cannot create section in output file: %s\n", asm_errmsg (-1));
88 asm_abort (ctx);
89 return 1;
90 }
91
92 /* Special alignment for the .text section. */
93 if (asm_align (scn1, 16) != 0)
94 {
95 printf ("cannot align .text section: %s\n", asm_errmsg (-1));
96 result = 1;
97 }
98
99 /* Add a few strings with names. */
100 if (asm_newsym (scn1, "one", 4, STT_OBJECT, STB_GLOBAL) == NULL)
101 {
102 printf ("cannot create first name: %s\n", asm_errmsg (-1));
103 result = 1;
104 }
105 if (asm_addstrz (scn1, "one", 4) != 0)
106 {
107 printf ("cannot insert first string: %s\n", asm_errmsg (-1));
108 result = 1;
109 }
110 if (asm_newsym (scn2, "three", 6, STT_OBJECT, STB_WEAK) == NULL)
111 {
112 printf ("cannot create second name: %s\n", asm_errmsg (-1));
113 result = 1;
114 }
115 if (asm_addstrz (scn2, "three", 0) != 0)
116 {
117 printf ("cannot insert second string: %s\n", asm_errmsg (-1));
118 result = 1;
119 }
120 if (asm_newsym (scn1, "two", 4, STT_OBJECT, STB_LOCAL) == NULL)
121 {
122 printf ("cannot create third name: %s\n", asm_errmsg (-1));
123 result = 1;
124 }
125 if (asm_addstrz (scn1, "two", 4) != 0)
126 {
127 printf ("cannot insert third string: %s\n", asm_errmsg (-1));
128 result = 1;
129 }
130
131 /* Create the output file. */
132 if (asm_end (ctx) != 0)
133 {
134 printf ("cannot create output file: %s\n", asm_errmsg (-1));
135 asm_abort (ctx);
136 return 1;
137 }
138
139 /* Check the file. */
140 fd = open (fname, O_RDONLY);
141 if (fd == -1)
142 {
143 printf ("cannot open generated file: %m\n");
144 result = 1;
145 goto out;
146 }
147
148 elf = elf_begin (fd, ELF_C_READ, NULL);
149 if (elf == NULL)
150 {
151 printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
152 result = 1;
153 goto out_close;
154 }
155 if (elf_kind (elf) != ELF_K_ELF)
156 {
157 puts ("not a valid ELF file");
158 result = 1;
159 goto out_close2;
160 }
161
162 ehdr = gelf_getehdr (elf, &ehdr_mem);
163 if (ehdr == NULL)
164 {
165 printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
166 result = 1;
167 goto out_close2;
168 }
169
170 for (cnt = 1; cnt < 5; ++cnt)
171 {
172 Elf_Scn *scn;
173 GElf_Shdr shdr_mem;
174 GElf_Shdr *shdr;
175
176 scn = elf_getscn (elf, cnt);
177 if (scn == NULL)
178 {
179 printf ("cannot get section %Zd: %s\n", cnt, elf_errmsg (-1));
180 result = 1;
181 continue;
182 }
183
184 shdr = gelf_getshdr (scn, &shdr_mem);
185 if (shdr == NULL)
186 {
187 printf ("cannot get section header for section %Zd: %s\n",
188 cnt, elf_errmsg (-1));
189 result = 1;
190 continue;
191 }
192
193 if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
194 scnnames[cnt]) != 0)
195 {
196 printf ("section %Zd's name differs: %s vs %s\n", cnt,
197 elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
198 scnnames[cnt]);
199 result = 1;
200 }
201
202 if (shdr->sh_type != scntypes[cnt])
203 {
204 printf ("section %Zd's type differs\n", cnt);
205 result = 1;
206 }
207
208 if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE))
209 || (cnt != 1 && shdr->sh_flags != 0))
210 {
211 printf ("section %Zd's flags differs\n", cnt);
212 result = 1;
213 }
214
215 if (shdr->sh_addr != 0)
216 {
217 printf ("section %Zd's address differs\n", cnt);
218 result = 1;
219 }
220
221 if (cnt == 3)
222 {
223 Elf_Data *data;
224
225 if (shdr->sh_link != 2)
226 {
227 puts ("symbol table has incorrect link");
228 result = 1;
229 }
230
231 data = elf_getdata (scn, NULL);
232 if (data == NULL)
233 {
234 puts ("cannot get data of symbol table");
235 result = 1;
236 }
237 else
238 {
239 size_t inner;
240
241 for (inner = 1;
242 inner < (shdr->sh_size
243 / gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT));
244 ++inner)
245 {
246 GElf_Sym sym_mem;
247 GElf_Sym *sym;
248
249 sym = gelf_getsym (data, inner, &sym_mem);
250 if (sym == NULL)
251 {
252 printf ("cannot get symbol %zu: %s\n",
253 inner, elf_errmsg (-1));
254 result = 1;
255 }
256 else
257 {
258 /* The order of the third and fourth entry depends
259 on how the hash table is organized. */
260 static const char *names[4] =
261 {
262 [0] = "",
263 [1] = "two",
264 [2] = "one",
265 [3] = "three"
266 };
267 static const int info[4] =
268 {
269 [0] = GELF_ST_INFO (STB_LOCAL, STT_NOTYPE),
270 [1] = GELF_ST_INFO (STB_LOCAL, STT_OBJECT),
271 [2] = GELF_ST_INFO (STB_GLOBAL, STT_OBJECT),
272 [3] = GELF_ST_INFO (STB_WEAK, STT_OBJECT)
273 };
274 static const unsigned value[4] =
275 {
276 [0] = 0,
277 [1] = 4,
278 [2] = 0,
279 [3] = 8
280 };
281
282 if (strcmp (names[inner],
283 elf_strptr (elf, shdr->sh_link,
284 sym->st_name)) != 0)
285 {
286 printf ("symbol %zu has different name\n", inner);
287 result = 1;
288 }
289
290 if (sym->st_value != value[inner])
291 {
292 printf ("symbol %zu has wrong value\n", inner);
293 result = 1;
294 }
295
296 if (sym->st_other != 0)
297 {
298 printf ("symbol %zu has wrong other info\n", inner);
299 result = 1;
300 }
301
302 if (sym->st_shndx != 1)
303 {
304 printf ("symbol %zu has wrong section reference\n",
305 inner);
306 result = 1;
307 }
308
309 if (sym->st_info != info[inner])
310 {
311 printf ("symbol %zu has wrong type or binding\n",
312 inner);
313 result = 1;
314 }
315
316 if ((inner != 3 && sym->st_size != 4)
317 || (inner == 3 && sym->st_size != 6))
318 {
319 printf ("symbol %zu has wrong size\n", inner);
320 result = 1;
321 }
322 }
323 }
324 }
325 }
326 }
327
328 out_close2:
329 elf_end (elf);
330 out_close:
331 close (fd);
332 out:
333 /* We don't need the file anymore. */
334 unlink (fname);
335
Ulrich Dreppera38998e2005-08-03 02:05:39 +0000336 ebl_closebackend (ebl);
337
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000338 return result;
339}