iPXE
segment.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26/**
27 * @file
28 *
29 * Executable image segments
30 *
31 */
32
33#include <string.h>
34#include <errno.h>
35#include <ipxe/uaccess.h>
36#include <ipxe/memmap.h>
37#include <ipxe/errortab.h>
38#include <ipxe/segment.h>
39
40/**
41 * Segment-specific error messages
42 *
43 * This error happens sufficiently often to merit a user-friendly
44 * description.
45 */
46#define ERANGE_SEGMENT __einfo_error ( EINFO_ERANGE_SEGMENT )
47#define EINFO_ERANGE_SEGMENT \
48 __einfo_uniqify ( EINFO_ERANGE, 0x01, "Requested memory not available" )
49struct errortab segment_errors[] __errortab = {
51};
52
53/**
54 * Prepare segment for loading
55 *
56 * @v segment Segment start
57 * @v filesz Size of the "allocated bytes" portion of the segment
58 * @v memsz Size of the segment
59 * @ret rc Return status code
60 */
61int prep_segment ( void *segment, size_t filesz, size_t memsz ) {
62 struct memmap_region region;
63 physaddr_t start = virt_to_phys ( segment );
64 physaddr_t mid = ( start + filesz );
65 physaddr_t end = ( start + memsz );
67
68 DBGC ( segment, "SEGMENT [%#08lx,%#08lx,%#08lx)\n", start, mid, end );
69
70 /* Check for malformed lengths */
71 if ( filesz > memsz ) {
72 DBGC ( segment, "SEGMENT [%#08lx,%#08lx,%#08lx) is "
73 "malformed\n", start, mid, end );
74 return -EINVAL;
75 }
76
77 /* Zero-length segments do not need a memory region */
78 if ( memsz == 0 )
79 return 0;
80 max = ( end - 1 );
81
82 /* Check for address space overflow */
83 if ( max < start ) {
84 DBGC ( segment, "SEGMENT [%#08lx,%#08lx,%#08lx) wraps "
85 "around\n", start, mid, end );
86 return -EINVAL;
87 }
88
89 /* Describe region containing this segment */
90 memmap_describe ( start, 1, &region );
91 DBGC_MEMMAP ( segment, &region );
92
93 /* Fail unless region is usable and sufficiently large */
94 if ( ( ! memmap_is_usable ( &region ) ) || ( region.max < max ) ) {
95 DBGC ( segment, "SEGMENT [%#08lx,%#08lx,%#08lx) does not fit "
96 "into available memory\n", start, mid, end );
97 return -ERANGE_SEGMENT;
98 }
99
100 /* Found valid region: zero bss and return */
101 memset ( ( segment + filesz ), 0, ( memsz - filesz ) );
102 return 0;
103}
unsigned long physaddr_t
Definition stdint.h:20
#define max(x, y)
Definition ath.h:41
Error codes.
Error message tables.
#define __errortab
Definition errortab.h:22
#define __einfo_errortab(einfo)
Definition errortab.h:24
static size_t memsz
Definition fdtmem.c:51
#define DBGC(...)
Definition compiler.h:505
uint32_t start
Starting offset.
Definition netvsc.h:1
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define EINVAL
Invalid argument.
Definition errno.h:429
System memory map.
static int memmap_is_usable(const struct memmap_region *region)
Check if memory region is usable.
Definition memmap.h:87
void memmap_describe(uint64_t min, int hide, struct memmap_region *region)
Describe memory region from system memory map.
Definition null_memmap.h:29
#define DBGC_MEMMAP(...)
Definition memmap.h:207
String functions.
void * memset(void *dest, int character, size_t len) __nonnull
Access to external ("user") memory.
uint16_t segment
Code segment.
Definition librm.h:3
uint16_t mid
Middle 16 bits of address.
Definition librm.h:9
uint32_t end
Ending offset.
Definition netvsc.h:7
#define EINFO_ERANGE_SEGMENT
Definition segment.c:47
int prep_segment(void *segment, size_t filesz, size_t memsz)
Prepare segment for loading.
Definition segment.c:61
#define ERANGE_SEGMENT
Segment-specific error messages.
Definition segment.c:46
Executable image segments.
A memory region descriptor.
Definition memmap.h:49
uint64_t max
Maximum address in region.
Definition memmap.h:53