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 <inttypes.h>
16#include <libasm.h>
17#include <libelf.h>
18#include <stdio.h>
19#include <unistd.h>
20
21
22static const char fname[] = "asm-tst8-out.o";
23
24
25int
26main (void)
27{
28  int result = 0;
29  size_t cnt;
30  AsmCtx_t *ctx;
31  Elf *elf;
32  int fd;
33
34  elf_version (EV_CURRENT);
35
36  ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB);
37  if (ctx == NULL)
38    {
39      printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
40      return 1;
41    }
42
43  if (asm_newabssym (ctx, "tst8-out.s", 4, 0xfeedbeef, STT_FILE, STB_LOCAL)
44      == NULL)
45    {
46      printf ("cannot create absolute symbol: %s\n", asm_errmsg (-1));
47      asm_abort (ctx);
48      return 1;
49    }
50
51  /* Create the output file.  */
52  if (asm_end (ctx) != 0)
53    {
54      printf ("cannot create output file: %s\n", asm_errmsg (-1));
55      asm_abort (ctx);
56      return 1;
57    }
58
59  /* Check the file.  */
60  fd = open (fname, O_RDONLY);
61  if (fd == -1)
62    {
63      printf ("cannot open generated file: %m\n");
64      result = 1;
65      goto out;
66    }
67
68  elf = elf_begin (fd, ELF_C_READ, NULL);
69  if (elf == NULL)
70    {
71      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
72      result = 1;
73      goto out_close;
74    }
75  if (elf_kind (elf) != ELF_K_ELF)
76    {
77      puts ("not a valid ELF file");
78      result = 1;
79      goto out_close2;
80    }
81
82  for (cnt = 1; 1; ++cnt)
83    {
84      Elf_Scn *scn;
85      GElf_Shdr shdr_mem;
86      GElf_Shdr *shdr;
87
88      scn = elf_getscn (elf, cnt);
89      if (scn == NULL)
90	{
91	  printf ("cannot get section %Zd: %s\n", cnt, elf_errmsg (-1));
92	  result = 1;
93	  continue;
94	}
95
96      shdr = gelf_getshdr (scn, &shdr_mem);
97      if (shdr == NULL)
98	{
99	  printf ("cannot get section header for section %Zd: %s\n",
100		  cnt, elf_errmsg (-1));
101	  result = 1;
102	  continue;
103	}
104      /* We are looking for the symbol table.  */
105      if (shdr->sh_type != SHT_SYMTAB)
106	continue;
107
108      for (cnt = 1; cnt< (shdr->sh_size
109			  / gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT));
110	   ++cnt)
111	{
112	  GElf_Sym sym_mem;
113	  GElf_Sym *sym;
114
115	  if (cnt > 1)
116	    {
117	      puts ("too many symbol");
118	      result = 1;
119	      break;
120	    }
121
122	  sym = gelf_getsym (elf_getdata (scn, NULL), cnt, &sym_mem);
123	  if (sym == NULL)
124	    {
125	      printf ("cannot get symbol %zu: %s\n", cnt, elf_errmsg (-1));
126	      result = 1;
127	    }
128	  else
129	    {
130	      if (sym->st_shndx != SHN_ABS)
131		{
132		  printf ("expected common symbol, got section %u\n",
133			  (unsigned int) sym->st_shndx);
134		  result = 1;
135		}
136
137	      if (sym->st_value != 0xfeedbeef)
138		{
139		  printf ("requested value 0xfeedbeef, is %#" PRIxMAX "\n",
140			  (uintmax_t) sym->st_value);
141		  result = 1;
142		}
143
144	      if (sym->st_size != 4)
145		{
146		  printf ("requested size 4, is %" PRIuMAX "\n",
147			  (uintmax_t) sym->st_value);
148		  result = 1;
149		}
150
151	      if (GELF_ST_TYPE (sym->st_info) != STT_FILE)
152		{
153		  printf ("requested type FILE, is %u\n",
154			  (unsigned int) GELF_ST_TYPE (sym->st_info));
155		  result = 1;
156		}
157	    }
158	}
159
160      break;
161    }
162
163 out_close2:
164  elf_end (elf);
165 out_close:
166  close (fd);
167 out:
168  /* We don't need the file anymore.  */
169  unlink (fname);
170
171  return result;
172}
173