1 /* Copyright (C) 2002, 2005 Red Hat, Inc.
2 This file is part of Red Hat elfutils.
3 Written by Ulrich Drepper <drepper@redhat.com>, 2002.
4
5 Red Hat elfutils is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by the
7 Free Software Foundation; version 2 of the License.
8
9 Red Hat elfutils is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with Red Hat elfutils; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
17
18 Red Hat elfutils is an included package of the Open Invention Network.
19 An included package of the Open Invention Network is a package for which
20 Open Invention Network licensees cross-license their patents. No patent
21 license is granted, either expressly or impliedly, by designation as an
22 included package. Should you wish to participate in the Open Invention
23 Network licensing program, please visit www.openinventionnetwork.com
24 <http://www.openinventionnetwork.com>. */
25
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29
30 #include <fcntl.h>
31 #include <inttypes.h>
32 #include ELFUTILS_HEADER(asm)
33 #include <libelf.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <unistd.h>
37
38
39 static const char fname[] = "asm-tst9-out.o";
40
41
42 static int32_t input[] =
43 {
44 0, 1, 129, 510, 2000, 33000, 0x7ffffff, 0x7fffffff
45 };
46 #define ninput (sizeof (input) / sizeof (input[0]))
47
48
49 static const GElf_Ehdr expected_ehdr =
50 {
51 .e_ident = { [EI_MAG0] = ELFMAG0,
52 [EI_MAG1] = ELFMAG1,
53 [EI_MAG2] = ELFMAG2,
54 [EI_MAG3] = ELFMAG3,
55 [EI_CLASS] = ELFCLASS32,
56 [EI_DATA] = ELFDATA2LSB,
57 [EI_VERSION] = EV_CURRENT },
58 .e_type = ET_REL,
59 .e_machine = EM_386,
60 .e_version = EV_CURRENT,
61 .e_shoff = 180,
62 .e_ehsize = sizeof (Elf32_Ehdr),
63 .e_shentsize = sizeof (Elf32_Shdr),
64 .e_shnum = 3,
65 .e_shstrndx = 2
66 };
67
68
69 static const char *scnnames[3] =
70 {
71 [0] = "",
72 [1] = ".data",
73 [2] = ".shstrtab"
74 };
75
76
77 static const char expecteddata[] =
78 {
79 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x7f,
80 0x81, 0x01, 0x81, 0x01, 0xff, 0xfe, 0xff, 0xff, 0x0f, 0xff, 0x7e, 0xfe,
81 0x03, 0xfe, 0x03, 0x82, 0xfc, 0xff, 0xff, 0x0f, 0x82, 0x7c, 0xd0, 0x0f,
82 0xd0, 0x0f, 0xb0, 0xf0, 0xff, 0xff, 0x0f, 0xb0, 0x70, 0xe8, 0x81, 0x02,
83 0xe8, 0x81, 0x02, 0x98, 0xfe, 0xfd, 0xff, 0x0f, 0x98, 0xfe, 0x7d, 0xff,
84 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x3f, 0x81, 0x80, 0x80, 0xc0, 0x0f,
85 0x81, 0x80, 0x80, 0x40, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff,
86 0xff, 0x07, 0x81, 0x80, 0x80, 0x80, 0x08, 0x81, 0x80, 0x80, 0x80, 0x78
87 };
88
89
90 int
main(void)91 main (void)
92 {
93 AsmCtx_t *ctx;
94 AsmScn_t *scn;
95 int result = 0;
96 int fd;
97 Elf *elf;
98 GElf_Ehdr ehdr_mem;
99 GElf_Ehdr *ehdr;
100 size_t cnt;
101
102 elf_version (EV_CURRENT);
103
104 Ebl *ebl = ebl_openbackend_machine (EM_386);
105 if (ebl == NULL)
106 {
107 puts ("cannot open backend library");
108 return 1;
109 }
110
111 ctx = asm_begin (fname, ebl, false);
112 if (ctx == NULL)
113 {
114 printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
115 return 1;
116 }
117
118 /* Create two sections. */
119 scn = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
120 if (scn == NULL)
121 {
122 printf ("cannot create section in output file: %s\n", asm_errmsg (-1));
123 asm_abort (ctx);
124 return 1;
125 }
126
127 /* Special alignment for the .text section. */
128 if (asm_align (scn, 16) != 0)
129 {
130 printf ("cannot align .text section: %s\n", asm_errmsg (-1));
131 result = 1;
132 }
133
134 /* Add a few ULEB128 and SLEB128 numbers. */
135 for (cnt = 0; cnt < ninput; ++cnt)
136 {
137 if (asm_adduleb128 (scn, input[cnt]) != 0)
138 {
139 printf ("cannot insert uleb %" PRIu32 ": %s\n",
140 (uint32_t) input[cnt], asm_errmsg (-1));
141 result = 1;
142 }
143
144 if (asm_addsleb128 (scn, input[cnt]) != 0)
145 {
146 printf ("cannot insert sleb %" PRId32 ": %s\n",
147 input[cnt], asm_errmsg (-1));
148 result = 1;
149 }
150
151 if (asm_adduleb128 (scn, -input[cnt]) != 0)
152 {
153 printf ("cannot insert uleb %" PRIu32 ": %s\n",
154 (uint32_t) -input[cnt], asm_errmsg (-1));
155 result = 1;
156 }
157
158 if (asm_addsleb128 (scn, -input[cnt]) != 0)
159 {
160 printf ("cannot insert sleb %" PRId32 ": %s\n",
161 -input[cnt], asm_errmsg (-1));
162 result = 1;
163 }
164 }
165
166 /* Create the output file. */
167 if (asm_end (ctx) != 0)
168 {
169 printf ("cannot create output file: %s\n", asm_errmsg (-1));
170 asm_abort (ctx);
171 return 1;
172 }
173
174 /* Check the file. */
175 fd = open (fname, O_RDONLY);
176 if (fd == -1)
177 {
178 printf ("cannot open generated file: %m\n");
179 result = 1;
180 goto out;
181 }
182
183 elf = elf_begin (fd, ELF_C_READ, NULL);
184 if (elf == NULL)
185 {
186 printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
187 result = 1;
188 goto out_close;
189 }
190 if (elf_kind (elf) != ELF_K_ELF)
191 {
192 puts ("not a valid ELF file");
193 result = 1;
194 goto out_close2;
195 }
196
197 ehdr = gelf_getehdr (elf, &ehdr_mem);
198 if (ehdr == NULL)
199 {
200 printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
201 result = 1;
202 goto out_close2;
203 }
204
205 if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0)
206 {
207 puts ("ELF header does not match");
208 result = 1;
209 goto out_close2;
210 }
211
212 for (cnt = 1; cnt < 3; ++cnt)
213 {
214 Elf_Scn *scn;
215 GElf_Shdr shdr_mem;
216 GElf_Shdr *shdr;
217
218 scn = elf_getscn (elf, cnt);
219 if (scn == NULL)
220 {
221 printf ("cannot get section %Zd: %s\n", cnt, elf_errmsg (-1));
222 result = 1;
223 continue;
224 }
225
226 shdr = gelf_getshdr (scn, &shdr_mem);
227 if (shdr == NULL)
228 {
229 printf ("cannot get section header for section %Zd: %s\n",
230 cnt, elf_errmsg (-1));
231 result = 1;
232 continue;
233 }
234
235 if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
236 scnnames[cnt]) != 0)
237 {
238 printf ("section %Zd's name differs: %s vs %s\n", cnt,
239 elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
240 scnnames[cnt]);
241 result = 1;
242 }
243
244 if (shdr->sh_type != (cnt == 2 ? SHT_STRTAB : SHT_PROGBITS))
245 {
246 printf ("section %Zd's type differs\n", cnt);
247 result = 1;
248 }
249
250 if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE))
251 || (cnt == 2 && shdr->sh_flags != 0))
252 {
253 printf ("section %Zd's flags differs\n", cnt);
254 result = 1;
255 }
256
257 if (shdr->sh_addr != 0)
258 {
259 printf ("section %Zd's address differs\n", cnt);
260 result = 1;
261 }
262
263 if ((cnt == 1 && shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 15) & ~15))
264 || (cnt == 2
265 && shdr->sh_offset != (((sizeof (Elf32_Ehdr) + 15) & ~15)
266 + sizeof (expecteddata))))
267 {
268 printf ("section %Zd's offset differs\n", cnt);
269 result = 1;
270 }
271
272 if ((cnt == 1 && shdr->sh_size != sizeof (expecteddata))
273 || (cnt == 2 && shdr->sh_size != 17))
274 {
275 printf ("section %Zd's size differs\n", cnt);
276 result = 1;
277 }
278
279 if (shdr->sh_link != 0)
280 {
281 printf ("section %Zd's link differs\n", cnt);
282 result = 1;
283 }
284
285 if (shdr->sh_info != 0)
286 {
287 printf ("section %Zd's info differs\n", cnt);
288 result = 1;
289 }
290
291 if ((cnt == 1 && shdr->sh_addralign != 16)
292 || (cnt != 1 && shdr->sh_addralign != 1))
293 {
294 printf ("section %Zd's addralign differs\n", cnt);
295 result = 1;
296 }
297
298 if (shdr->sh_entsize != 0)
299 {
300 printf ("section %Zd's entsize differs\n", cnt);
301 result = 1;
302 }
303
304 if (cnt == 1)
305 {
306 Elf_Data *data = elf_getdata (scn, NULL);
307
308 if (data == NULL)
309 {
310 printf ("cannot get data of section %Zd\n", cnt);
311 result = 1;
312 }
313 else
314 {
315 if (data->d_size != sizeof (expecteddata))
316 {
317 printf ("data block size of section %Zd wrong: got %Zd, "
318 "expected 96\n", cnt, data->d_size);
319 result = 1;
320 }
321
322 if (memcmp (data->d_buf, expecteddata, sizeof (expecteddata))
323 != 0)
324 {
325 printf ("data block content of section %Zd wrong\n", cnt);
326 result = 1;
327 }
328 }
329 }
330 }
331
332 out_close2:
333 elf_end (elf);
334 out_close:
335 close (fd);
336 out:
337 /* We don't need the file anymore. */
338 unlink (fname);
339
340 ebl_closebackend (ebl);
341
342 return result;
343 }
344