2 * Copyright (c) 1999 Marcel Moolenaar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer
10 * in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software withough specific prior written permission
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * $FreeBSD: src/usr.bin/genassym/genassym.c,v 1.1 1999/12/23 11:07:45 marcel Exp $
31 #include <sys/types.h>
32 #if defined(arch_i386)
33 #include <sys/elf32.h>
34 #define __ELF_WORD_SIZE 32
35 #elif defined(arch_alpha)
36 #include <sys/elf64.h>
37 #define __ELF_WORD_SIZE 64
39 #error unknown or missing architecture
41 #include <sys/elf_generic.h>
50 const char s_data[] = ".data";
51 const char s_strtab[] = ".strtab";
52 const char s_symtab[] = ".symtab";
53 const char assym[] = "assym_";
64 static unsigned short s = 0xbbaa;
67 byte0 = *(unsigned char *)&s;
70 else if (byte0 == 0xbb)
76 read_section(int index)
82 size = shdr[index].sh_size;
86 if (lseek(fd, shdr[index].sh_offset, SEEK_SET) == -1)
88 bytes = read(fd, buf, size);
92 warnx("%s: section %d partially read", objfile, index);
96 int section_index(const char *section)
100 for (i = 1; i < ehdr.e_shnum; i++)
101 if (!strcmp(section, shstr + shdr[i].sh_name))
111 name += sizeof(assym) - 1;
112 dot = strchr(name, '.');
120 fprintf(stderr, "usage: genassym [-o outfile] objfile\n");
126 main(int argc, char *argv[])
129 char *data, *name, *symbols;
134 int ch, i, numsym, warn_ld_bug;
135 int si_data, si_strtab, si_symtab;
141 while ((ch = getopt(argc, argv, "o:")) != -1) {
159 warnx("ignoring trailing arguments");
162 fd = open(objfile, O_RDONLY);
164 err(1, "%s", objfile);
166 bytes = read(fd, &ehdr, sizeof(ehdr));
168 err(1, "%s", objfile);
169 if (bytes != sizeof(ehdr) ||
170 ehdr.e_ident[EI_MAG0] != ELFMAG0 ||
171 ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
172 ehdr.e_ident[EI_MAG2] != ELFMAG2 ||
173 ehdr.e_ident[EI_MAG3] != ELFMAG3)
174 errx(1, "%s: not an ELF file", objfile);
175 if (ehdr.e_ident[EI_VERSION] != EV_CURRENT)
176 errx(1, "%s: unsupported ELF version", objfile);
177 if (ehdr.e_ident[EI_DATA] != my_byte_order())
178 errx(1, "%s: unsupported byte order", objfile);
179 if (ehdr.e_shoff == 0)
180 errx(1, "%s: no section table", objfile);
181 if (ehdr.e_shstrndx == SHN_UNDEF)
182 errx(1, "%s: no section name string table", objfile);
184 size = sizeof(*shdr) * ehdr.e_shnum;
188 if (lseek(fd, ehdr.e_shoff, SEEK_SET) == -1)
189 err(1, "%s", objfile);
190 bytes = read(fd, shdr, size);
192 err(1, "%s", objfile);
194 errx(1, "%s: truncated section table", objfile);
196 shstr = read_section(ehdr.e_shstrndx);
198 err(1, "%s[%d]", objfile, ehdr.e_shstrndx);
200 si_data = section_index(s_data);
202 errx(1, "%s: section %s not present", objfile, s_data);
203 data = read_section(si_data);
205 err(1, "%s[%d]", objfile, si_data);
207 si_strtab = section_index(s_strtab);
209 errx(1, "%s: section %s not present", objfile, s_strtab);
210 symbols = read_section(si_strtab);
212 err(1, "%s[%d]", objfile, si_strtab);
214 si_symtab = section_index(s_symtab);
216 errx(1, "%s: section %s not present", objfile, s_symtab);
217 sym = read_section(si_symtab);
219 err(1, "%s[%d]", objfile, si_symtab);
221 numsym = shdr[si_symtab].sh_size / sizeof(*sym);
224 freopen(outfile, "w", stdout);
226 for (i = 0; i < numsym; i++) {
227 name = symbols + sym[i].st_name;
228 if (sym[i].st_shndx == si_data &&
229 !strncmp(name, assym, sizeof(assym) - 1)) {
230 valp = (void*)(data + sym[i].st_value);
232 * XXX - ld(1) on Alpha doesn't store the size of
233 * the symbol in the object file. The following
234 * fix handles this case quite genericly. It
235 * assumes that the symbols have the same size as
236 * a word on that architecture, determined by the
237 * word size in the ELF object file.
239 if (sym[i].st_size == 0) {
240 sym[i].st_size = __ELF_WORD_SIZE >> 3;
242 warnx("%s: symbol sizes not properly"
247 switch (sym[i].st_size) {
249 value = *(u_int8_t*)valp;
252 value = *(u_int16_t*)valp;
255 value = *(u_int32_t*)valp;
258 value = *(u_int64_t*)valp;
261 warnx("unsupported size (%lld) for symbol %s",
262 (long long)sym[i].st_size, filter(name));
265 fprintf(stdout, "#define\t%s 0x%llx\n", filter(name),