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