[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/arm/elf_machdep.c

Version: -  FREEBSD  -  FREEBSD7  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  OPENSOLARIS  -  minix-3-1-1  -  TRUSTEDBSD-SEBSD  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

  1 /*-
  2  * Copyright 1996-1998 John D. Polstra.
  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
  9  *    notice, this list of conditions and the following disclaimer.
 10  * 2. Redistributions in binary form must reproduce the above copyright
 11  *    notice, this list of conditions and the following disclaimer in the
 12  *    documentation and/or other materials provided with the distribution.
 13  *
 14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24  */
 25 
 26 #include <sys/cdefs.h>
 27 __FBSDID("$FreeBSD: src/sys/arm/arm/elf_machdep.c,v 1.10 2008/11/22 12:36:15 kib Exp $");
 28 
 29 #include <sys/param.h>
 30 #include <sys/kernel.h>
 31 #include <sys/systm.h>
 32 #include <sys/exec.h>
 33 #include <sys/imgact.h>
 34 #include <sys/linker.h>
 35 #include <sys/sysent.h>
 36 #include <sys/imgact_elf.h>
 37 #include <sys/syscall.h>
 38 #include <sys/signalvar.h>
 39 #include <sys/vnode.h>
 40 
 41 #include <vm/vm.h>
 42 #include <vm/pmap.h>
 43 #include <vm/vm_param.h>
 44 
 45 #include <machine/elf.h>
 46 #include <machine/md_var.h>
 47 
 48 struct sysentvec elf32_freebsd_sysvec = {
 49         .sv_size        = SYS_MAXSYSCALL,
 50         .sv_table       = sysent,
 51         .sv_mask        = 0,
 52         .sv_sigsize     = 0,
 53         .sv_sigtbl      = NULL,
 54         .sv_errsize     = 0,
 55         .sv_errtbl      = NULL,
 56         .sv_transtrap   = NULL,
 57         .sv_fixup       = __elfN(freebsd_fixup),
 58         .sv_sendsig     = sendsig,
 59         .sv_sigcode     = sigcode,
 60         .sv_szsigcode   = &szsigcode,
 61         .sv_prepsyscall = NULL,
 62         .sv_name        = "FreeBSD ELF32",
 63         .sv_coredump    = __elfN(coredump),
 64         .sv_imgact_try  = NULL,
 65         .sv_minsigstksz = MINSIGSTKSZ,
 66         .sv_pagesize    = PAGE_SIZE,
 67         .sv_minuser     = VM_MIN_ADDRESS,
 68         .sv_maxuser     = VM_MAXUSER_ADDRESS,
 69         .sv_usrstack    = USRSTACK,
 70         .sv_psstrings   = PS_STRINGS,
 71         .sv_stackprot   = VM_PROT_ALL,
 72         .sv_copyout_strings = exec_copyout_strings,
 73         .sv_setregs     = exec_setregs,
 74         .sv_fixlimit    = NULL,
 75         .sv_maxssiz     = NULL,
 76         .sv_flags       = SV_ABI_FREEBSD | SV_ILP32
 77 };
 78 
 79 static Elf32_Brandinfo freebsd_brand_info = {
 80         .brand          = ELFOSABI_FREEBSD,
 81         .machine        = EM_ARM,
 82         .compat_3_brand = "FreeBSD",
 83         .emul_path      = NULL,
 84         .interp_path    = "/libexec/ld-elf.so.1",
 85         .sysvec         = &elf32_freebsd_sysvec,
 86         .interp_newpath = NULL,
 87         .flags          = BI_CAN_EXEC_DYN,
 88 };
 89 
 90 SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY,
 91         (sysinit_cfunc_t) elf32_insert_brand_entry,
 92         &freebsd_brand_info);
 93 
 94 static Elf32_Brandinfo freebsd_brand_oinfo = {
 95         .brand          = ELFOSABI_FREEBSD,
 96         .machine        = EM_ARM,
 97         .compat_3_brand = "FreeBSD",
 98         .emul_path      = NULL,
 99         .interp_path    = "/usr/libexec/ld-elf.so.1",
100         .sysvec         = &elf32_freebsd_sysvec,
101         .interp_newpath = NULL,
102         .flags          = BI_CAN_EXEC_DYN,
103 };
104 
105 SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
106         (sysinit_cfunc_t) elf32_insert_brand_entry,
107         &freebsd_brand_oinfo);
108 
109 
110 void
111 elf32_dump_thread(struct thread *td __unused, void *dst __unused,
112     size_t *off __unused)
113 {
114 }
115 
116 
117 /* Process one elf relocation with addend. */
118 static int
119 elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
120     int type, int local, elf_lookup_fn lookup)
121 {
122         Elf_Addr *where;
123         Elf_Addr addr;
124         Elf_Addr addend;
125         Elf_Word rtype, symidx;
126         const Elf_Rel *rel;
127         const Elf_Rela *rela;
128 
129         switch (type) {
130         case ELF_RELOC_REL:
131                 rel = (const Elf_Rel *)data;
132                 where = (Elf_Addr *) (relocbase + rel->r_offset);
133                 addend = *where;
134                 rtype = ELF_R_TYPE(rel->r_info);
135                 symidx = ELF_R_SYM(rel->r_info);
136                 break;
137         case ELF_RELOC_RELA:
138                 rela = (const Elf_Rela *)data;
139                 where = (Elf_Addr *) (relocbase + rela->r_offset);
140                 addend = rela->r_addend;
141                 rtype = ELF_R_TYPE(rela->r_info);
142                 symidx = ELF_R_SYM(rela->r_info);
143                 break;
144         default:
145                 panic("unknown reloc type %d\n", type);
146         }
147 
148         if (local) {
149                 if (rtype == R_ARM_RELATIVE) {  /* A + B */
150                         addr = relocbase + addend;
151                         if (*where != addr)
152                                 *where = addr;
153                 }
154                 return (0);
155         }
156 
157         switch (rtype) {
158 
159                 case R_ARM_NONE:        /* none */
160                         break;
161 
162                 case R_ARM_ABS32:
163                         addr = lookup(lf, symidx, 1);
164                         if (addr == 0)
165                                 return -1;
166                         if (*where != addr)
167                                 *where = addr;
168 
169                         break;
170 
171                 case R_ARM_COPY:        /* none */
172                         /*
173                          * There shouldn't be copy relocations in kernel
174                          * objects.
175                          */
176                         printf("kldload: unexpected R_COPY relocation\n");
177                         return -1;
178                         break;
179 
180                 case R_ARM_JUMP_SLOT:
181                         addr = lookup(lf, symidx, 1);
182                         if (addr) {
183                                 *where = addr;
184                                 return (0);
185                         }
186                         return (-1);
187                 case R_ARM_RELATIVE:
188                         break;
189 
190                 default:
191                         printf("kldload: unexpected relocation type %d\n",
192                                rtype);
193                         return -1;
194         }
195         return(0);
196 }
197 
198 int
199 elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
200     elf_lookup_fn lookup)
201 {
202 
203         return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup));
204 }
205 
206 int
207 elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
208     int type, elf_lookup_fn lookup)
209 {
210 
211         return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup));
212 }
213 
214 int
215 elf_cpu_load_file(linker_file_t lf __unused)
216 {
217 
218         cpu_idcache_wbinv_all();
219         cpu_l2cache_wbinv_all();
220         cpu_tlb_flushID();
221         return (0);
222 }
223 
224 int
225 elf_cpu_unload_file(linker_file_t lf __unused)
226 {
227 
228         return (0);
229 }
230 

Cache object: 2359c9be1b2cfcd3fe39b59e381f4f01


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.