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