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 $
29 * $DragonFly: src/usr.bin/genassym/Attic/genassym.c,v 1.2 2003/06/17 04:29:27 dillon Exp $
32 #include <sys/types.h>
33 #if defined(arch_i386)
34 #include <sys/elf32.h>
35 #define __ELF_WORD_SIZE 32
36 #elif defined(arch_alpha)
37 #include <sys/elf64.h>
38 #define __ELF_WORD_SIZE 64
40 #error unknown or missing architecture
42 #include <sys/elf_generic.h>
51 const char s_data[] = ".data";
52 const char s_strtab[] = ".strtab";
53 const char s_symtab[] = ".symtab";
54 const char assym[] = "assym_";
65 static unsigned short s = 0xbbaa;
68 byte0 = *(unsigned char *)&s;
71 else if (byte0 == 0xbb)
77 read_section(int index)
83 size = shdr[index].sh_size;
87 if (lseek(fd, shdr[index].sh_offset, SEEK_SET) == -1)
89 bytes = read(fd, buf, size);
93 warnx("%s: section %d partially read", objfile, index);
97 int section_index(const char *section)
101 for (i = 1; i < ehdr.e_shnum; i++)
102 if (!strcmp(section, shstr + shdr[i].sh_name))
112 name += sizeof(assym) - 1;
113 dot = strchr(name, '.');
121 fprintf(stderr, "usage: genassym [-o outfile] objfile\n");
127 main(int argc, char *argv[])
130 char *data, *name, *symbols;
135 int ch, i, numsym, warn_ld_bug;
136 int si_data, si_strtab, si_symtab;
142 while ((ch = getopt(argc, argv, "o:")) != -1) {
160 warnx("ignoring trailing arguments");
163 fd = open(objfile, O_RDONLY);
165 err(1, "%s", objfile);
167 bytes = read(fd, &ehdr, sizeof(ehdr));
169 err(1, "%s", objfile);
170 if (bytes != sizeof(ehdr) ||
171 ehdr.e_ident[EI_MAG0] != ELFMAG0 ||
172 ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
173 ehdr.e_ident[EI_MAG2] != ELFMAG2 ||
174 ehdr.e_ident[EI_MAG3] != ELFMAG3)
175 errx(1, "%s: not an ELF file", objfile);
176 if (ehdr.e_ident[EI_VERSION] != EV_CURRENT)
177 errx(1, "%s: unsupported ELF version", objfile);
178 if (ehdr.e_ident[EI_DATA] != my_byte_order())
179 errx(1, "%s: unsupported byte order", objfile);
180 if (ehdr.e_shoff == 0)
181 errx(1, "%s: no section table", objfile);
182 if (ehdr.e_shstrndx == SHN_UNDEF)
183 errx(1, "%s: no section name string table", objfile);
185 size = sizeof(*shdr) * ehdr.e_shnum;
189 if (lseek(fd, ehdr.e_shoff, SEEK_SET) == -1)
190 err(1, "%s", objfile);
191 bytes = read(fd, shdr, size);
193 err(1, "%s", objfile);
195 errx(1, "%s: truncated section table", objfile);
197 shstr = read_section(ehdr.e_shstrndx);
199 err(1, "%s[%d]", objfile, ehdr.e_shstrndx);
201 si_data = section_index(s_data);
203 errx(1, "%s: section %s not present", objfile, s_data);
204 data = read_section(si_data);
206 err(1, "%s[%d]", objfile, si_data);
208 si_strtab = section_index(s_strtab);
210 errx(1, "%s: section %s not present", objfile, s_strtab);
211 symbols = read_section(si_strtab);
213 err(1, "%s[%d]", objfile, si_strtab);
215 si_symtab = section_index(s_symtab);
217 errx(1, "%s: section %s not present", objfile, s_symtab);
218 sym = read_section(si_symtab);
220 err(1, "%s[%d]", objfile, si_symtab);
222 numsym = shdr[si_symtab].sh_size / sizeof(*sym);
225 freopen(outfile, "w", stdout);
227 for (i = 0; i < numsym; i++) {
228 name = symbols + sym[i].st_name;
229 if (sym[i].st_shndx == si_data &&
230 !strncmp(name, assym, sizeof(assym) - 1)) {
231 valp = (void*)(data + sym[i].st_value);
233 * XXX - ld(1) on Alpha doesn't store the size of
234 * the symbol in the object file. The following
235 * fix handles this case quite genericly. It
236 * assumes that the symbols have the same size as
237 * a word on that architecture, determined by the
238 * word size in the ELF object file.
240 if (sym[i].st_size == 0) {
241 sym[i].st_size = __ELF_WORD_SIZE >> 3;
243 warnx("%s: symbol sizes not properly"
248 switch (sym[i].st_size) {
250 value = *(u_int8_t*)valp;
253 value = *(u_int16_t*)valp;
256 value = *(u_int32_t*)valp;
259 value = *(u_int64_t*)valp;
262 warnx("unsupported size (%lld) for symbol %s",
263 (long long)sym[i].st_size, filter(name));
266 fprintf(stdout, "#define\t%s 0x%llx\n", filter(name),