link_elf.c (1f49b573e112e6e78a145c9a3cb7ea60b6c3ea85) link_elf.c (a2024a3edff86b418e3e599ee5db65a7e653605d)
1/*-
2 * Copyright (c) 1998-2000 Doug Rabson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD$");
29
1/*-
2 * Copyright (c) 1998-2000 Doug Rabson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD$");
29
30#include "opt_ddb.h"
30#include "opt_gdb.h"
31#include "opt_mac.h"
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#ifdef GPROF
36#include <sys/gmon.h>
37#endif

--- 19 unchanged lines hidden (view full) ---

57#include <vm/vm_kern.h>
58#include <vm/vm_extern.h>
59#endif
60#include <vm/pmap.h>
61#include <vm/vm_map.h>
62
63#include <sys/link_elf.h>
64
31#include "opt_gdb.h"
32#include "opt_mac.h"
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#ifdef GPROF
37#include <sys/gmon.h>
38#endif

--- 19 unchanged lines hidden (view full) ---

58#include <vm/vm_kern.h>
59#include <vm/vm_extern.h>
60#endif
61#include <vm/pmap.h>
62#include <vm/vm_map.h>
63
64#include <sys/link_elf.h>
65
66#ifdef DDB_CTF
67#include <net/zlib.h>
68#endif
69
65#include "linker_if.h"
66
67#define MAXSEGS 4
68
69typedef struct elf_file {
70 struct linker_file lf; /* Common fields */
71 int preloaded; /* Was file pre-loaded */
72 caddr_t address; /* Relocation address */

--- 20 unchanged lines hidden (view full) ---

93 int relasize; /* DT_RELASZ */
94 caddr_t modptr;
95 const Elf_Sym* ddbsymtab; /* The symbol table we are using */
96 long ddbsymcnt; /* Number of symbols */
97 caddr_t ddbstrtab; /* String table */
98 long ddbstrcnt; /* number of bytes in string table */
99 caddr_t symbase; /* malloc'ed symbold base */
100 caddr_t strbase; /* malloc'ed string base */
70#include "linker_if.h"
71
72#define MAXSEGS 4
73
74typedef struct elf_file {
75 struct linker_file lf; /* Common fields */
76 int preloaded; /* Was file pre-loaded */
77 caddr_t address; /* Relocation address */

--- 20 unchanged lines hidden (view full) ---

98 int relasize; /* DT_RELASZ */
99 caddr_t modptr;
100 const Elf_Sym* ddbsymtab; /* The symbol table we are using */
101 long ddbsymcnt; /* Number of symbols */
102 caddr_t ddbstrtab; /* String table */
103 long ddbstrcnt; /* number of bytes in string table */
104 caddr_t symbase; /* malloc'ed symbold base */
105 caddr_t strbase; /* malloc'ed string base */
106 caddr_t ctftab; /* CTF table */
107 long ctfcnt; /* number of bytes in CTF table */
108 caddr_t ctfoff; /* CTF offset table */
109 caddr_t typoff; /* Type offset table */
110 long typlen; /* Number of type entries. */
101#ifdef GDB
102 struct link_map gdb; /* hooks for gdb */
103#endif
104} *elf_file_t;
105
111#ifdef GDB
112 struct link_map gdb; /* hooks for gdb */
113#endif
114} *elf_file_t;
115
116#include <kern/kern_ctf.c>
117
106static int link_elf_link_common_finish(linker_file_t);
107static int link_elf_link_preload(linker_class_t cls,
108 const char*, linker_file_t*);
109static int link_elf_link_preload_finish(linker_file_t);
110static int link_elf_load_file(linker_class_t, const char*, linker_file_t*);
111static int link_elf_lookup_symbol(linker_file_t, const char*,
112 c_linker_sym_t*);
113static int link_elf_symbol_values(linker_file_t, c_linker_sym_t, linker_symval_t*);
114static int link_elf_search_symbol(linker_file_t, caddr_t value,
115 c_linker_sym_t* sym, long* diffp);
116
117static void link_elf_unload_file(linker_file_t);
118static void link_elf_unload_preload(linker_file_t);
119static int link_elf_lookup_set(linker_file_t, const char *,
120 void ***, void ***, int *);
121static int link_elf_each_function_name(linker_file_t,
122 int (*)(const char *, void *),
123 void *);
118static int link_elf_link_common_finish(linker_file_t);
119static int link_elf_link_preload(linker_class_t cls,
120 const char*, linker_file_t*);
121static int link_elf_link_preload_finish(linker_file_t);
122static int link_elf_load_file(linker_class_t, const char*, linker_file_t*);
123static int link_elf_lookup_symbol(linker_file_t, const char*,
124 c_linker_sym_t*);
125static int link_elf_symbol_values(linker_file_t, c_linker_sym_t, linker_symval_t*);
126static int link_elf_search_symbol(linker_file_t, caddr_t value,
127 c_linker_sym_t* sym, long* diffp);
128
129static void link_elf_unload_file(linker_file_t);
130static void link_elf_unload_preload(linker_file_t);
131static int link_elf_lookup_set(linker_file_t, const char *,
132 void ***, void ***, int *);
133static int link_elf_each_function_name(linker_file_t,
134 int (*)(const char *, void *),
135 void *);
136static int link_elf_each_function_nameval(linker_file_t,
137 linker_function_nameval_callback_t,
138 void *);
124static void link_elf_reloc_local(linker_file_t);
125static Elf_Addr elf_lookup(linker_file_t lf, Elf_Size symidx, int deps);
126
127static kobj_method_t link_elf_methods[] = {
128 KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol),
129 KOBJMETHOD(linker_symbol_values, link_elf_symbol_values),
130 KOBJMETHOD(linker_search_symbol, link_elf_search_symbol),
131 KOBJMETHOD(linker_unload, link_elf_unload_file),
132 KOBJMETHOD(linker_load_file, link_elf_load_file),
133 KOBJMETHOD(linker_link_preload, link_elf_link_preload),
134 KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish),
135 KOBJMETHOD(linker_lookup_set, link_elf_lookup_set),
136 KOBJMETHOD(linker_each_function_name, link_elf_each_function_name),
139static void link_elf_reloc_local(linker_file_t);
140static Elf_Addr elf_lookup(linker_file_t lf, Elf_Size symidx, int deps);
141
142static kobj_method_t link_elf_methods[] = {
143 KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol),
144 KOBJMETHOD(linker_symbol_values, link_elf_symbol_values),
145 KOBJMETHOD(linker_search_symbol, link_elf_search_symbol),
146 KOBJMETHOD(linker_unload, link_elf_unload_file),
147 KOBJMETHOD(linker_load_file, link_elf_load_file),
148 KOBJMETHOD(linker_link_preload, link_elf_link_preload),
149 KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish),
150 KOBJMETHOD(linker_lookup_set, link_elf_lookup_set),
151 KOBJMETHOD(linker_each_function_name, link_elf_each_function_name),
152 KOBJMETHOD(linker_each_function_nameval, link_elf_each_function_nameval),
153 KOBJMETHOD(linker_ctf_get, link_elf_ctf_get),
137 { 0, 0 }
138};
139
140static struct linker_class link_elf_class = {
141#if ELF_TARG_CLASS == ELFCLASS32
142 "elf32",
143#else
144 "elf64",

--- 760 unchanged lines hidden (view full) ---

905#else
906 if (ef->address)
907 free(ef->address, M_LINKER);
908#endif
909 if (ef->symbase)
910 free(ef->symbase, M_LINKER);
911 if (ef->strbase)
912 free(ef->strbase, M_LINKER);
154 { 0, 0 }
155};
156
157static struct linker_class link_elf_class = {
158#if ELF_TARG_CLASS == ELFCLASS32
159 "elf32",
160#else
161 "elf64",

--- 760 unchanged lines hidden (view full) ---

922#else
923 if (ef->address)
924 free(ef->address, M_LINKER);
925#endif
926 if (ef->symbase)
927 free(ef->symbase, M_LINKER);
928 if (ef->strbase)
929 free(ef->strbase, M_LINKER);
930 if (ef->ctftab)
931 free(ef->ctftab, M_LINKER);
932 if (ef->ctfoff)
933 free(ef->ctfoff, M_LINKER);
934 if (ef->typoff)
935 free(ef->typoff, M_LINKER);
913}
914
915static void
916link_elf_unload_preload(linker_file_t file)
917{
918 if (file->filename)
919 preload_delete_name(file->filename);
920}

--- 301 unchanged lines hidden (view full) ---

1222 error = callback(ef->ddbstrtab + symp->st_name, opaque);
1223 if (error)
1224 return (error);
1225 }
1226 }
1227 return (0);
1228}
1229
936}
937
938static void
939link_elf_unload_preload(linker_file_t file)
940{
941 if (file->filename)
942 preload_delete_name(file->filename);
943}

--- 301 unchanged lines hidden (view full) ---

1245 error = callback(ef->ddbstrtab + symp->st_name, opaque);
1246 if (error)
1247 return (error);
1248 }
1249 }
1250 return (0);
1251}
1252
1253static int
1254link_elf_each_function_nameval(linker_file_t file,
1255 linker_function_nameval_callback_t callback, void *opaque)
1256{
1257 linker_symval_t symval;
1258 elf_file_t ef = (elf_file_t)file;
1259 const Elf_Sym* symp;
1260 int i, error;
1261
1262 /* Exhaustive search */
1263 for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
1264 if (symp->st_value != 0 &&
1265 ELF_ST_TYPE(symp->st_info) == STT_FUNC) {
1266 error = link_elf_symbol_values(file, (c_linker_sym_t) symp, &symval);
1267 if (error)
1268 return (error);
1269 error = callback(file, i, &symval, opaque);
1270 if (error)
1271 return (error);
1272 }
1273 }
1274 return (0);
1275}
1276
1230#ifdef __ia64__
1231/*
1232 * Each KLD has its own GP. The GP value for each load module is given by
1233 * DT_PLTGOT on ia64. We need GP to construct function descriptors, but
1234 * don't have direct access to the ELF file structure. The link_elf_get_gp()
1235 * function returns the GP given a pointer to a generic linker file struct.
1236 */
1237Elf_Addr

--- 105 unchanged lines hidden ---
1277#ifdef __ia64__
1278/*
1279 * Each KLD has its own GP. The GP value for each load module is given by
1280 * DT_PLTGOT on ia64. We need GP to construct function descriptors, but
1281 * don't have direct access to the ELF file structure. The link_elf_get_gp()
1282 * function returns the GP given a pointer to a generic linker file struct.
1283 */
1284Elf_Addr

--- 105 unchanged lines hidden ---