bin_nlist.c revision 1.1 1 1.1 christos /* $NetBSD: bin_nlist.c,v 1.1 2016/09/21 16:25:41 christos Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * Copyright (c) 1996, 2002 Christopher G. Demetriou
5 1.1 christos * All rights reserved.
6 1.1 christos *
7 1.1 christos * Redistribution and use in source and binary forms, with or without
8 1.1 christos * modification, are permitted provided that the following conditions
9 1.1 christos * are met:
10 1.1 christos * 1. Redistributions of source code must retain the above copyright
11 1.1 christos * notice, this list of conditions and the following disclaimer.
12 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 christos * notice, this list of conditions and the following disclaimer in the
14 1.1 christos * documentation and/or other materials provided with the distribution.
15 1.1 christos * 3. The name of the author may not be used to endorse or promote products
16 1.1 christos * derived from this software without specific prior written permission.
17 1.1 christos *
18 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 1.1 christos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 1.1 christos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 1.1 christos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 1.1 christos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 1.1 christos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 1.1 christos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 1.1 christos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 1.1 christos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 1.1 christos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 1.1 christos *
29 1.1 christos * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
30 1.1 christos */
31 1.1 christos #include <sys/cdefs.h>
32 1.1 christos __RCSID("$NetBSD: bin_nlist.c,v 1.1 2016/09/21 16:25:41 christos Exp $");
33 1.1 christos
34 1.1 christos #include <stdio.h>
35 1.1 christos #include <stdlib.h>
36 1.1 christos #include <string.h>
37 1.1 christos #include <nlist.h>
38 1.1 christos #include <err.h>
39 1.1 christos
40 1.1 christos #include "bin.h"
41 1.1 christos #include "extern.h"
42 1.1 christos
43 1.1 christos struct bininfo {
44 1.1 christos const char *fname;
45 1.1 christos int kfd;
46 1.1 christos };
47 1.1 christos
48 1.1 christos #define X_MD_ROOT_IMAGE 0
49 1.1 christos #define X_MD_ROOT_SIZE 1
50 1.1 christos
51 1.1 christos struct {
52 1.1 christos const char *name;
53 1.1 christos int (*check)(const char *, size_t);
54 1.1 christos int (*findoff)(const char *, size_t, u_long, size_t *, u_long);
55 1.1 christos } exec_formats[] = {
56 1.1 christos #ifdef NLIST_AOUT
57 1.1 christos { "a.out", check_aout, findoff_aout, },
58 1.1 christos #endif
59 1.1 christos #ifdef NLIST_ECOFF
60 1.1 christos { "ECOFF", check_ecoff, findoff_ecoff, },
61 1.1 christos #endif
62 1.1 christos #ifdef NLIST_ELF32
63 1.1 christos { "ELF32", check_elf32, findoff_elf32, },
64 1.1 christos #endif
65 1.1 christos #ifdef NLIST_ELF64
66 1.1 christos { "ELF64", check_elf64, findoff_elf64, },
67 1.1 christos #endif
68 1.1 christos #ifdef NLIST_COFF
69 1.1 christos { "COFF", check_coff, findoff_coff, },
70 1.1 christos #endif
71 1.1 christos };
72 1.1 christos
73 1.1 christos void *
74 1.1 christos bin_open(int kfd, const char *kfile, const char *bfdname)
75 1.1 christos {
76 1.1 christos struct bininfo *bin;
77 1.1 christos
78 1.1 christos if ((bin = malloc(sizeof(*bin))) == NULL) {
79 1.1 christos warn("%s", kfile);
80 1.1 christos return NULL;
81 1.1 christos }
82 1.1 christos bin->kfd = kfd;
83 1.1 christos bin->fname = kfile;
84 1.1 christos
85 1.1 christos return bin;
86 1.1 christos }
87 1.1 christos
88 1.1 christos
89 1.1 christos int
90 1.1 christos bin_find_md_root(void *binp, const char *mappedfile, off_t mappedsize,
91 1.1 christos unsigned long text_start, const char *root_name, const char *size_name,
92 1.1 christos size_t *md_root_image_offset, size_t *md_root_size_offset,
93 1.1 christos uint32_t *md_root_size, int verbose)
94 1.1 christos {
95 1.1 christos struct bininfo *bin = binp;
96 1.1 christos struct nlist nl[3];
97 1.1 christos size_t i, n = sizeof exec_formats / sizeof exec_formats[0];
98 1.1 christos
99 1.1 christos for (i = 0; i < n; i++) {
100 1.1 christos if ((*exec_formats[i].check)(mappedfile, mappedsize) == 0)
101 1.1 christos break;
102 1.1 christos }
103 1.1 christos if (i == n) {
104 1.1 christos warnx("%s: unknown executable format", bin->fname);
105 1.1 christos return 1;
106 1.1 christos }
107 1.1 christos
108 1.1 christos if (verbose) {
109 1.1 christos fprintf(stderr, "%s is an %s binary\n", bin->fname,
110 1.1 christos exec_formats[i].name);
111 1.1 christos #ifdef NLIST_AOUT
112 1.1 christos if (text_start != (unsigned long)~0)
113 1.1 christos fprintf(stderr, "kernel text loads at 0x%lx\n",
114 1.1 christos text_start);
115 1.1 christos #endif
116 1.1 christos }
117 1.1 christos
118 1.1 christos (void)memset(nl, 0, sizeof(nl));
119 1.1 christos N_NAME(&nl[X_MD_ROOT_IMAGE]) = root_name;
120 1.1 christos N_NAME(&nl[X_MD_ROOT_SIZE]) = size_name;
121 1.1 christos
122 1.1 christos if (__fdnlist(bin->kfd, nl) != 0)
123 1.1 christos return 1;
124 1.1 christos
125 1.1 christos if ((*exec_formats[i].findoff)(mappedfile, mappedsize,
126 1.1 christos nl[1].n_value, md_root_size_offset, text_start) != 0) {
127 1.1 christos warnx("couldn't find offset for %s in %s",
128 1.1 christos nl[X_MD_ROOT_SIZE].n_name, bin->fname);
129 1.1 christos return 1;
130 1.1 christos }
131 1.1 christos if (verbose)
132 1.1 christos fprintf(stderr, "%s is at offset %#zx in %s\n",
133 1.1 christos nl[X_MD_ROOT_SIZE].n_name, *md_root_size_offset,
134 1.1 christos bin->fname);
135 1.1 christos memcpy(md_root_size, &mappedfile[*md_root_size_offset],
136 1.1 christos sizeof(*md_root_size));
137 1.1 christos if (verbose)
138 1.1 christos fprintf(stderr, "%s has value %#x\n",
139 1.1 christos nl[X_MD_ROOT_SIZE].n_name, *md_root_size);
140 1.1 christos
141 1.1 christos if ((*exec_formats[i].findoff)(mappedfile, mappedsize,
142 1.1 christos nl[0].n_value, md_root_image_offset, text_start) != 0) {
143 1.1 christos warnx("couldn't find offset for %s in %s",
144 1.1 christos nl[X_MD_ROOT_IMAGE].n_name, bin->fname);
145 1.1 christos return 1;
146 1.1 christos }
147 1.1 christos if (verbose)
148 1.1 christos fprintf(stderr, "%s is at offset %#zx in %s\n",
149 1.1 christos nl[X_MD_ROOT_IMAGE].n_name,
150 1.1 christos *md_root_image_offset, bin->fname);
151 1.1 christos
152 1.1 christos return 0;
153 1.1 christos }
154 1.1 christos
155 1.1 christos void
156 1.1 christos bin_put_32(void *bin, off_t size, char *buf)
157 1.1 christos {
158 1.1 christos uint32_t s = (uint32_t)size;
159 1.1 christos memcpy(buf, &s, sizeof(s));
160 1.1 christos }
161 1.1 christos
162 1.1 christos void
163 1.1 christos bin_close(void *bin)
164 1.1 christos {
165 1.1 christos }
166 1.1 christos
167 1.1 christos const char **
168 1.1 christos bin_supported_targets(void)
169 1.1 christos {
170 1.1 christos static const char *fmts[] = {
171 1.1 christos #ifdef NLIST_AOUT
172 1.1 christos "aout",
173 1.1 christos #endif
174 1.1 christos #ifdef NLIST_ECOFF
175 1.1 christos "ecoff",
176 1.1 christos #endif
177 1.1 christos #ifdef NLIST_ELF32
178 1.1 christos "elf32",
179 1.1 christos #endif
180 1.1 christos #ifdef NLIST_ELF64
181 1.1 christos "elf64",
182 1.1 christos #endif
183 1.1 christos #ifdef NLIST_COFF
184 1.1 christos "coff",
185 1.1 christos #endif
186 1.1 christos NULL,
187 1.1 christos };
188 1.1 christos
189 1.1 christos return fmts;
190 1.1 christos }
191