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 ELFUTILS_HEADER(asm)
32 #include <libelf.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <unistd.h>
36
37
38 static const char fname[] = "asm-tst1-out.o";
39
40
41 static const GElf_Ehdr expected_ehdr =
42 {
43 .e_ident = { [EI_MAG0] = ELFMAG0,
44 [EI_MAG1] = ELFMAG1,
45 [EI_MAG2] = ELFMAG2,
46 [EI_MAG3] = ELFMAG3,
47 [EI_CLASS] = ELFCLASS32,
48 [EI_DATA] = ELFDATA2LSB,
49 [EI_VERSION] = EV_CURRENT },
50 .e_type = ET_REL,
51 .e_machine = EM_386,
52 .e_version = EV_CURRENT,
53 .e_shoff = 88,
54 .e_ehsize = sizeof (Elf32_Ehdr),
55 .e_shentsize = sizeof (Elf32_Shdr),
56 .e_shnum = 4,
57 .e_shstrndx = 3
58 };
59
60
61 static const char *scnnames[4] =
62 {
63 [0] = "",
64 [1] = ".text",
65 [2] = ".data",
66 [3] = ".shstrtab"
67 };
68
69
70 int
main(void)71 main (void)
72 {
73 AsmCtx_t *ctx;
74 AsmScn_t *scn1;
75 AsmScn_t *scn2;
76 int fd;
77 Elf *elf;
78 GElf_Ehdr ehdr_mem;
79 GElf_Ehdr *ehdr;
80 int result = 0;
81 size_t cnt;
82
83 elf_version (EV_CURRENT);
84
85 Ebl *ebl = ebl_openbackend_machine (EM_386);
86 if (ebl == NULL)
87 {
88 puts ("cannot open backend library");
89 return 1;
90 }
91
92 ctx = asm_begin (fname, ebl, false);
93 if (ctx == NULL)
94 {
95 printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
96 return 1;
97 }
98
99 /* Create two sections. */
100 scn1 = asm_newscn (ctx, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
101 scn2 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
102 if (scn1 == NULL || scn2 == NULL)
103 {
104 printf ("cannot create section in output file: %s\n", asm_errmsg (-1));
105 asm_abort (ctx);
106 return 1;
107 }
108
109 /* Special alignment for the .text section. */
110 if (asm_align (scn1, 32) != 0)
111 {
112 printf ("cannot align .text section: %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 if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0)
156 {
157 puts ("ELF header does not match");
158 result = 1;
159 goto out_close2;
160 }
161
162 for (cnt = 1; cnt < 4; ++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 != (cnt == 3 ? SHT_STRTAB : SHT_PROGBITS))
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_EXECINSTR))
201 || (cnt == 2 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE))
202 || (cnt == 3 && shdr->sh_flags != 0))
203 {
204 printf ("section %Zd's flags differs\n", cnt);
205 result = 1;
206 }
207
208 if (shdr->sh_addr != 0)
209 {
210 printf ("section %Zd's address differs\n", cnt);
211 result = 1;
212 }
213
214 if (shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 31) & ~31))
215 {
216 printf ("section %Zd's offset differs\n", cnt);
217 result = 1;
218 }
219
220 if ((cnt != 3 && shdr->sh_size != 0)
221 || (cnt == 3 && shdr->sh_size != 23))
222 {
223 printf ("section %Zd's size differs\n", cnt);
224 result = 1;
225 }
226
227 if (shdr->sh_link != 0)
228 {
229 printf ("section %Zd's link differs\n", cnt);
230 result = 1;
231 }
232
233 if (shdr->sh_info != 0)
234 {
235 printf ("section %Zd's info differs\n", cnt);
236 result = 1;
237 }
238
239 if ((cnt == 1 && shdr->sh_addralign != 32)
240 || (cnt != 1 && shdr->sh_addralign != 1))
241 {
242 printf ("section %Zd's addralign differs\n", cnt);
243 result = 1;
244 }
245
246 if (shdr->sh_entsize != 0)
247 {
248 printf ("section %Zd's entsize differs\n", cnt);
249 result = 1;
250 }
251 }
252
253 out_close2:
254 elf_end (elf);
255 out_close:
256 close (fd);
257 out:
258 /* We don't need the file anymore. */
259 unlink (fname);
260
261 ebl_closebackend (ebl);
262
263 return result;
264 }
265