xref: /freebsd/stand/common/modinfo.c (revision 5d1531d9d4e7d1b1b706ab23ac3f864416e87522)
1*5d1531d9SWarner Losh /*-
2*5d1531d9SWarner Losh  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3*5d1531d9SWarner Losh  * All rights reserved.
4*5d1531d9SWarner Losh  *
5*5d1531d9SWarner Losh  * Redistribution and use in source and binary forms, with or without
6*5d1531d9SWarner Losh  * modification, are permitted provided that the following conditions
7*5d1531d9SWarner Losh  * are met:
8*5d1531d9SWarner Losh  * 1. Redistributions of source code must retain the above copyright
9*5d1531d9SWarner Losh  *    notice, this list of conditions and the following disclaimer.
10*5d1531d9SWarner Losh  * 2. Redistributions in binary form must reproduce the above copyright
11*5d1531d9SWarner Losh  *    notice, this list of conditions and the following disclaimer in the
12*5d1531d9SWarner Losh  *    documentation and/or other materials provided with the distribution.
13*5d1531d9SWarner Losh  *
14*5d1531d9SWarner Losh  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*5d1531d9SWarner Losh  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*5d1531d9SWarner Losh  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*5d1531d9SWarner Losh  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*5d1531d9SWarner Losh  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*5d1531d9SWarner Losh  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*5d1531d9SWarner Losh  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*5d1531d9SWarner Losh  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*5d1531d9SWarner Losh  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*5d1531d9SWarner Losh  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*5d1531d9SWarner Losh  * SUCH DAMAGE.
25*5d1531d9SWarner Losh  *
26*5d1531d9SWarner Losh  *	from: FreeBSD: src/sys/boot/sparc64/loader/metadata.c,v 1.6
27*5d1531d9SWarner Losh  */
28*5d1531d9SWarner Losh #include <stand.h>
29*5d1531d9SWarner Losh #include <sys/param.h>
30*5d1531d9SWarner Losh #include <sys/linker.h>
31*5d1531d9SWarner Losh #include <sys/boot.h>
32*5d1531d9SWarner Losh #include <sys/reboot.h>
33*5d1531d9SWarner Losh #if defined(LOADER_FDT_SUPPORT)
34*5d1531d9SWarner Losh #include <fdt_platform.h>
35*5d1531d9SWarner Losh #endif
36*5d1531d9SWarner Losh 
37*5d1531d9SWarner Losh #ifdef __arm__
38*5d1531d9SWarner Losh #include <machine/elf.h>
39*5d1531d9SWarner Losh #endif
40*5d1531d9SWarner Losh #include <machine/metadata.h>
41*5d1531d9SWarner Losh 
42*5d1531d9SWarner Losh #include "bootstrap.h"
43*5d1531d9SWarner Losh #include "modinfo.h"
44*5d1531d9SWarner Losh 
45*5d1531d9SWarner Losh static int align;
46*5d1531d9SWarner Losh #define MOD_ALIGN(l)	roundup(l, align)
47*5d1531d9SWarner Losh 
48*5d1531d9SWarner Losh vm_offset_t
49*5d1531d9SWarner Losh md_copymodules(vm_offset_t addr, bool kern64)
50*5d1531d9SWarner Losh {
51*5d1531d9SWarner Losh 	struct preloaded_file	*fp;
52*5d1531d9SWarner Losh 	struct file_metadata	*md;
53*5d1531d9SWarner Losh 	uint64_t		scratch64;
54*5d1531d9SWarner Losh 	uint32_t		scratch32;
55*5d1531d9SWarner Losh 	int			c;
56*5d1531d9SWarner Losh 
57*5d1531d9SWarner Losh 	c = addr != 0;
58*5d1531d9SWarner Losh 	/* start with the first module on the list, should be the kernel */
59*5d1531d9SWarner Losh 	for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
60*5d1531d9SWarner Losh 
61*5d1531d9SWarner Losh 		MOD_NAME(addr, fp->f_name, c);	/* this field must come first */
62*5d1531d9SWarner Losh 		MOD_TYPE(addr, fp->f_type, c);
63*5d1531d9SWarner Losh 		if (fp->f_args)
64*5d1531d9SWarner Losh 			MOD_ARGS(addr, fp->f_args, c);
65*5d1531d9SWarner Losh 		if (kern64) {
66*5d1531d9SWarner Losh 			scratch64 = fp->f_addr;
67*5d1531d9SWarner Losh 			MOD_ADDR(addr, scratch64, c);
68*5d1531d9SWarner Losh 			scratch64 = fp->f_size;
69*5d1531d9SWarner Losh 			MOD_SIZE(addr, scratch64, c);
70*5d1531d9SWarner Losh 		} else {
71*5d1531d9SWarner Losh 			scratch32 = fp->f_addr;
72*5d1531d9SWarner Losh #ifdef __arm__
73*5d1531d9SWarner Losh 			scratch32 -= __elfN(relocation_offset);
74*5d1531d9SWarner Losh #endif
75*5d1531d9SWarner Losh 			MOD_ADDR(addr, scratch32, c);
76*5d1531d9SWarner Losh 			MOD_SIZE(addr, fp->f_size, c);
77*5d1531d9SWarner Losh 		}
78*5d1531d9SWarner Losh 		for (md = fp->f_metadata; md != NULL; md = md->md_next) {
79*5d1531d9SWarner Losh 			if (!(md->md_type & MODINFOMD_NOCOPY)) {
80*5d1531d9SWarner Losh 				MOD_METADATA(addr, md, c);
81*5d1531d9SWarner Losh 			}
82*5d1531d9SWarner Losh 		}
83*5d1531d9SWarner Losh 	}
84*5d1531d9SWarner Losh 	MOD_END(addr, c);
85*5d1531d9SWarner Losh 	return(addr);
86*5d1531d9SWarner Losh }
87