asm-tst1.c revision 441f72d43a9b550baa779fc82f70816da5f74f0e
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
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}
240