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