• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* 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 
22 static const char fname[] = "asm-tst2-out.o";
23 
24 
25 static 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 = 96,
38     .e_ehsize = sizeof (Elf32_Ehdr),
39     .e_shentsize = sizeof (Elf32_Shdr),
40     .e_shnum = 3,
41     .e_shstrndx = 2
42   };
43 
44 
45 static const char *scnnames[3] =
46   {
47     [0] = "",
48     [1] = ".data",
49     [2] = ".shstrtab"
50   };
51 
52 
53 int
main(void)54 main (void)
55 {
56   AsmCtx_t *ctx;
57   AsmScn_t *scn1;
58   AsmScn_t *scn2;
59   int result = 0;
60   int fd;
61   Elf *elf;
62   GElf_Ehdr ehdr_mem;
63   GElf_Ehdr *ehdr;
64   size_t cnt;
65 
66   elf_version (EV_CURRENT);
67 
68   ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB);
69   if (ctx == NULL)
70     {
71       printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
72       return 1;
73     }
74 
75   /* Create two sections.  */
76   scn1 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
77   scn2 = asm_newsubscn (scn1, 1);
78   if (scn1 == NULL || scn2 == NULL)
79     {
80       printf ("cannot create section in output file: %s\n", asm_errmsg (-1));
81       asm_abort (ctx);
82       return 1;
83     }
84 
85   /* Special alignment for the .text section.  */
86   if (asm_align (scn1, 16) != 0)
87     {
88       printf ("cannot align .text section: %s\n", asm_errmsg (-1));
89       result = 1;
90     }
91 
92   /* Add a few strings.  */
93   if (asm_addstrz (scn1, "one", 4) != 0)
94     {
95       printf ("cannot insert first string: %s\n", asm_errmsg (-1));
96       result = 1;
97     }
98   if (asm_addstrz (scn2, "three", 0) != 0)
99     {
100       printf ("cannot insert second string: %s\n", asm_errmsg (-1));
101       result = 1;
102     }
103   if (asm_addstrz (scn1, "two", 4) != 0)
104     {
105       printf ("cannot insert third string: %s\n", asm_errmsg (-1));
106       result = 1;
107     }
108 
109   /* Create the output file.  */
110   if (asm_end (ctx) != 0)
111     {
112       printf ("cannot create output file: %s\n", asm_errmsg (-1));
113       asm_abort (ctx);
114       return 1;
115     }
116 
117   /* Check the file.  */
118   fd = open (fname, O_RDONLY);
119   if (fd == -1)
120     {
121       printf ("cannot open generated file: %m\n");
122       result = 1;
123       goto out;
124     }
125 
126   elf = elf_begin (fd, ELF_C_READ, NULL);
127   if (elf == NULL)
128     {
129       printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
130       result = 1;
131       goto out_close;
132     }
133   if (elf_kind (elf) != ELF_K_ELF)
134     {
135       puts ("not a valid ELF file");
136       result = 1;
137       goto out_close2;
138     }
139 
140   ehdr = gelf_getehdr (elf, &ehdr_mem);
141   if (ehdr == NULL)
142     {
143       printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
144       result = 1;
145       goto out_close2;
146     }
147 
148   if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0)
149     {
150       puts ("ELF header does not match");
151       result = 1;
152       goto out_close2;
153     }
154 
155   for (cnt = 1; cnt < 3; ++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 != (cnt == 2 ? SHT_STRTAB : SHT_PROGBITS))
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 == 2 && 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 == 1 && shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 15) & ~15))
207 	  || (cnt == 2
208 	      && shdr->sh_offset != (((sizeof (Elf32_Ehdr) + 15) & ~15)
209 				     + strlen ("one") + 1
210 				     + strlen ("two") + 1
211 				     + strlen ("three") + 1)))
212 	{
213 	  printf ("section %Zd's offset differs\n", cnt);
214 	  result = 1;
215 	}
216 
217       if ((cnt == 1 && shdr->sh_size != (strlen ("one") + 1
218 					 + strlen ("two") + 1
219 					 + strlen ("three") + 1))
220 	  || (cnt == 2 && shdr->sh_size != 17))
221 	{
222 	  printf ("section %Zd's size differs\n", cnt);
223 	  result = 1;
224 	}
225 
226       if (shdr->sh_link != 0)
227 	{
228 	  printf ("section %Zd's link differs\n", cnt);
229 	  result = 1;
230 	}
231 
232       if (shdr->sh_info != 0)
233 	{
234 	  printf ("section %Zd's info differs\n", cnt);
235 	  result = 1;
236 	}
237 
238       if ((cnt == 1 && shdr->sh_addralign != 16)
239 	  || (cnt != 1 && shdr->sh_addralign != 1))
240 	{
241 	  printf ("section %Zd's addralign differs\n", cnt);
242 	  result = 1;
243 	}
244 
245       if (shdr->sh_entsize != 0)
246 	{
247 	  printf ("section %Zd's entsize differs\n", cnt);
248 	  result = 1;
249 	}
250     }
251 
252  out_close2:
253   elf_end (elf);
254  out_close:
255   close (fd);
256  out:
257   /* We don't need the file anymore.  */
258   unlink (fname);
259 
260   return result;
261 }
262