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
22 static const char fname[] = "asm-tst7-out.o";
23
24
25 int
main(void)26 main (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_newcomsym (ctx, "commsym", 4, 16) == NULL)
44 {
45 printf ("cannot create common symbol: %s\n", asm_errmsg (-1));
46 asm_abort (ctx);
47 return 1;
48 }
49
50 /* Create the output file. */
51 if (asm_end (ctx) != 0)
52 {
53 printf ("cannot create output file: %s\n", asm_errmsg (-1));
54 asm_abort (ctx);
55 return 1;
56 }
57
58 /* Check the file. */
59 fd = open (fname, O_RDONLY);
60 if (fd == -1)
61 {
62 printf ("cannot open generated file: %m\n");
63 result = 1;
64 goto out;
65 }
66
67 elf = elf_begin (fd, ELF_C_READ, NULL);
68 if (elf == NULL)
69 {
70 printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
71 result = 1;
72 goto out_close;
73 }
74 if (elf_kind (elf) != ELF_K_ELF)
75 {
76 puts ("not a valid ELF file");
77 result = 1;
78 goto out_close2;
79 }
80
81 for (cnt = 1; 1; ++cnt)
82 {
83 Elf_Scn *scn;
84 GElf_Shdr shdr_mem;
85 GElf_Shdr *shdr;
86
87 scn = elf_getscn (elf, cnt);
88 if (scn == NULL)
89 {
90 printf ("cannot get section %Zd: %s\n", cnt, elf_errmsg (-1));
91 result = 1;
92 continue;
93 }
94
95 shdr = gelf_getshdr (scn, &shdr_mem);
96 if (shdr == NULL)
97 {
98 printf ("cannot get section header for section %Zd: %s\n",
99 cnt, elf_errmsg (-1));
100 result = 1;
101 continue;
102 }
103 /* We are looking for the symbol table. */
104 if (shdr->sh_type != SHT_SYMTAB)
105 continue;
106
107 for (cnt = 1; cnt< (shdr->sh_size
108 / gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT));
109 ++cnt)
110 {
111 GElf_Sym sym_mem;
112 GElf_Sym *sym;
113
114 if (cnt > 1)
115 {
116 puts ("too many symbol");
117 result = 1;
118 break;
119 }
120
121 sym = gelf_getsym (elf_getdata (scn, NULL), cnt, &sym_mem);
122 if (sym == NULL)
123 {
124 printf ("cannot get symbol %zu: %s\n", cnt, elf_errmsg (-1));
125 result = 1;
126 }
127 else
128 {
129 if (sym->st_shndx != SHN_COMMON)
130 {
131 printf ("expected common symbol, got section %u\n",
132 (unsigned int) sym->st_shndx);
133 result = 1;
134 }
135
136 if (sym->st_value != 16)
137 {
138 printf ("requested alignment 16, is %" PRIuMAX "\n",
139 (uintmax_t) sym->st_value);
140 result = 1;
141 }
142
143 if (sym->st_size != 4)
144 {
145 printf ("requested size 4, is %" PRIuMAX "\n",
146 (uintmax_t) sym->st_value);
147 result = 1;
148 }
149 }
150 }
151
152 break;
153 }
154
155 out_close2:
156 elf_end (elf);
157 out_close:
158 close (fd);
159 out:
160 /* We don't need the file anymore. */
161 unlink (fname);
162
163 return result;
164 }
165