blob: b76930d02277a18c636cc4f27ecdfcd9f3b02b5c [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-tst1-out.o";
23
24
25static const GElf_Ehdr expected_ehdr =
26 {
27 .e_ident = { [EI_MAG0] = ELFMAG0,
28 [EI_MAG1] = ELFMAG1,
29 [EI_MAG2] = ELFMAG2,
30 [EI_MAG3] = ELFMAG3,
31 [EI_CLASS] = ELFCLASS32,
32 [EI_DATA] = ELFDATA2LSB,
33 [EI_VERSION] = EV_CURRENT },
34 .e_type = ET_REL,
35 .e_machine = EM_386,
36 .e_version = EV_CURRENT,
37 .e_shoff = 88,
38 .e_ehsize = sizeof (Elf32_Ehdr),
39 .e_shentsize = sizeof (Elf32_Shdr),
40 .e_shnum = 4,
41 .e_shstrndx = 3
42 };
43
44
45static const char *scnnames[4] =
46 {
47 [0] = "",
48 [1] = ".text",
49 [2] = ".data",
50 [3] = ".shstrtab"
51 };
52
53
54int
55main (void)
56{
57 AsmCtx_t *ctx;
58 AsmScn_t *scn1;
59 AsmScn_t *scn2;
60 int fd;
61 Elf *elf;
62 GElf_Ehdr ehdr_mem;
63 GElf_Ehdr *ehdr;
64 int result = 0;
65 size_t cnt;
66
67 elf_version (EV_CURRENT);
68
69 ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB);
70 if (ctx == NULL)
71 {
72 printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
73 return 1;
74 }
75
76 /* Create two sections. */
77 scn1 = asm_newscn (ctx, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
78 scn2 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
79 if (scn1 == NULL || scn2 == NULL)
80 {
81 printf ("cannot create section in output file: %s\n", asm_errmsg (-1));
82 asm_abort (ctx);
83 return 1;
84 }
85
86 /* Special alignment for the .text section. */
87 if (asm_align (scn1, 32) != 0)
88 {
89 printf ("cannot align .text section: %s\n", asm_errmsg (-1));
90 result = 1;
91 }
92
93 /* Create the output file. */
94 if (asm_end (ctx) != 0)
95 {
96 printf ("cannot create output file: %s\n", asm_errmsg (-1));
97 asm_abort (ctx);
98 return 1;
99 }
100
101 /* Check the file. */
102 fd = open (fname, O_RDONLY);
103 if (fd == -1)
104 {
105 printf ("cannot open generated file: %m\n");
106 result = 1;
107 goto out;
108 }
109
110 elf = elf_begin (fd, ELF_C_READ, NULL);
111 if (elf == NULL)
112 {
113 printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
114 result = 1;
115 goto out_close;
116 }
117 if (elf_kind (elf) != ELF_K_ELF)
118 {
119 puts ("not a valid ELF file");
120 result = 1;
121 goto out_close2;
122 }
123
124 ehdr = gelf_getehdr (elf, &ehdr_mem);
125 if (ehdr == NULL)
126 {
127 printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
128 result = 1;
129 goto out_close2;
130 }
131
132 if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0)
133 {
134 puts ("ELF header does not match");
135 result = 1;
136 goto out_close2;
137 }
138
139 for (cnt = 1; cnt < 4; ++cnt)
140 {
141 Elf_Scn *scn;
142 GElf_Shdr shdr_mem;
143 GElf_Shdr *shdr;
144
145 scn = elf_getscn (elf, cnt);
146 if (scn == NULL)
147 {
148 printf ("cannot get section %Zd: %s\n", cnt, elf_errmsg (-1));
149 result = 1;
150 continue;
151 }
152
153 shdr = gelf_getshdr (scn, &shdr_mem);
154 if (shdr == NULL)
155 {
156 printf ("cannot get section header for section %Zd: %s\n",
157 cnt, elf_errmsg (-1));
158 result = 1;
159 continue;
160 }
161
162 if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
163 scnnames[cnt]) != 0)
164 {
165 printf ("section %Zd's name differs: %s vs %s\n", cnt,
166 elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
167 scnnames[cnt]);
168 result = 1;
169 }
170
171 if (shdr->sh_type != (cnt == 3 ? SHT_STRTAB : SHT_PROGBITS))
172 {
173 printf ("section %Zd's type differs\n", cnt);
174 result = 1;
175 }
176
177 if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_EXECINSTR))
178 || (cnt == 2 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE))
179 || (cnt == 3 && shdr->sh_flags != 0))
180 {
181 printf ("section %Zd's flags differs\n", cnt);
182 result = 1;
183 }
184
185 if (shdr->sh_addr != 0)
186 {
187 printf ("section %Zd's address differs\n", cnt);
188 result = 1;
189 }
190
191 if (shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 31) & ~31))
192 {
193 printf ("section %Zd's offset differs\n", cnt);
194 result = 1;
195 }
196
197 if ((cnt != 3 && shdr->sh_size != 0)
198 || (cnt == 3 && shdr->sh_size != 23))
199 {
200 printf ("section %Zd's size differs\n", cnt);
201 result = 1;
202 }
203
204 if (shdr->sh_link != 0)
205 {
206 printf ("section %Zd's link differs\n", cnt);
207 result = 1;
208 }
209
210 if (shdr->sh_info != 0)
211 {
212 printf ("section %Zd's info differs\n", cnt);
213 result = 1;
214 }
215
216 if ((cnt == 1 && shdr->sh_addralign != 32)
217 || (cnt != 1 && shdr->sh_addralign != 1))
218 {
219 printf ("section %Zd's addralign differs\n", cnt);
220 result = 1;
221 }
222
223 if (shdr->sh_entsize != 0)
224 {
225 printf ("section %Zd's entsize differs\n", cnt);
226 result = 1;
227 }
228 }
229
230 out_close2:
231 elf_end (elf);
232 out_close:
233 close (fd);
234 out:
235 /* We don't need the file anymore. */
236 unlink (fname);
237
238 return result;
239}