mirror of
https://github.com/ipxe/ipxe
synced 2026-02-12 21:29:39 +03:00
[nbi] Remove userptr_t from NBI image parsing
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -106,7 +106,7 @@ struct ebinfo {
|
|||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int nbi_prepare_segment ( struct image *image, size_t offset __unused,
|
static int nbi_prepare_segment ( struct image *image, size_t offset __unused,
|
||||||
userptr_t dest, size_t filesz, size_t memsz ){
|
void *dest, size_t filesz, size_t memsz ) {
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if ( ( rc = prep_segment ( dest, filesz, memsz ) ) != 0 ) {
|
if ( ( rc = prep_segment ( dest, filesz, memsz ) ) != 0 ) {
|
||||||
@@ -129,7 +129,7 @@ static int nbi_prepare_segment ( struct image *image, size_t offset __unused,
|
|||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int nbi_load_segment ( struct image *image, size_t offset,
|
static int nbi_load_segment ( struct image *image, size_t offset,
|
||||||
userptr_t dest, size_t filesz,
|
void *dest, size_t filesz,
|
||||||
size_t memsz __unused ) {
|
size_t memsz __unused ) {
|
||||||
memcpy ( dest, ( image->data + offset ), filesz );
|
memcpy ( dest, ( image->data + offset ), filesz );
|
||||||
return 0;
|
return 0;
|
||||||
@@ -144,16 +144,16 @@ static int nbi_load_segment ( struct image *image, size_t offset,
|
|||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int nbi_process_segments ( struct image *image,
|
static int nbi_process_segments ( struct image *image,
|
||||||
struct imgheader *imgheader,
|
const struct imgheader *imgheader,
|
||||||
int ( * process ) ( struct image *image,
|
int ( * process ) ( struct image *image,
|
||||||
size_t offset,
|
size_t offset,
|
||||||
userptr_t dest,
|
void *dest,
|
||||||
size_t filesz,
|
size_t filesz,
|
||||||
size_t memsz ) ) {
|
size_t memsz ) ) {
|
||||||
struct segheader sh;
|
const struct segheader *sh;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
size_t sh_off;
|
size_t sh_off;
|
||||||
userptr_t dest;
|
void *dest;
|
||||||
size_t filesz;
|
size_t filesz;
|
||||||
size_t memsz;
|
size_t memsz;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -170,8 +170,8 @@ static int nbi_process_segments ( struct image *image,
|
|||||||
sh_off = NBI_LENGTH ( imgheader->length );
|
sh_off = NBI_LENGTH ( imgheader->length );
|
||||||
do {
|
do {
|
||||||
/* Read segment header */
|
/* Read segment header */
|
||||||
copy_from_user ( &sh, image->data, sh_off, sizeof ( sh ) );
|
sh = ( image->data + sh_off );
|
||||||
if ( sh.length == 0 ) {
|
if ( sh->length == 0 ) {
|
||||||
/* Avoid infinite loop? */
|
/* Avoid infinite loop? */
|
||||||
DBGC ( image, "NBI %p invalid segheader length 0\n",
|
DBGC ( image, "NBI %p invalid segheader length 0\n",
|
||||||
image );
|
image );
|
||||||
@@ -179,15 +179,15 @@ static int nbi_process_segments ( struct image *image,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate segment load address */
|
/* Calculate segment load address */
|
||||||
switch ( NBI_LOADADDR_FLAGS ( sh.flags ) ) {
|
switch ( NBI_LOADADDR_FLAGS ( sh->flags ) ) {
|
||||||
case NBI_LOADADDR_ABS:
|
case NBI_LOADADDR_ABS:
|
||||||
dest = phys_to_virt ( sh.loadaddr );
|
dest = phys_to_virt ( sh->loadaddr );
|
||||||
break;
|
break;
|
||||||
case NBI_LOADADDR_AFTER:
|
case NBI_LOADADDR_AFTER:
|
||||||
dest = ( dest + memsz + sh.loadaddr );
|
dest = ( dest + memsz + sh->loadaddr );
|
||||||
break;
|
break;
|
||||||
case NBI_LOADADDR_BEFORE:
|
case NBI_LOADADDR_BEFORE:
|
||||||
dest = ( dest - sh.loadaddr );
|
dest = ( dest - sh->loadaddr );
|
||||||
break;
|
break;
|
||||||
case NBI_LOADADDR_END:
|
case NBI_LOADADDR_END:
|
||||||
/* Not correct according to the spec, but
|
/* Not correct according to the spec, but
|
||||||
@@ -195,7 +195,7 @@ static int nbi_process_segments ( struct image *image,
|
|||||||
* previous versions of Etherboot.
|
* previous versions of Etherboot.
|
||||||
*/
|
*/
|
||||||
dest = phys_to_virt ( ( extmemsize() + 1024 ) * 1024
|
dest = phys_to_virt ( ( extmemsize() + 1024 ) * 1024
|
||||||
- sh.loadaddr );
|
- sh->loadaddr );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Cannot be reached */
|
/* Cannot be reached */
|
||||||
@@ -203,8 +203,8 @@ static int nbi_process_segments ( struct image *image,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Process this segment */
|
/* Process this segment */
|
||||||
filesz = sh.imglength;
|
filesz = sh->imglength;
|
||||||
memsz = sh.memlength;
|
memsz = sh->memlength;
|
||||||
if ( ( offset + filesz ) > image->len ) {
|
if ( ( offset + filesz ) > image->len ) {
|
||||||
DBGC ( image, "NBI %p segment outside file\n", image );
|
DBGC ( image, "NBI %p segment outside file\n", image );
|
||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
@@ -216,13 +216,13 @@ static int nbi_process_segments ( struct image *image,
|
|||||||
offset += filesz;
|
offset += filesz;
|
||||||
|
|
||||||
/* Next segheader */
|
/* Next segheader */
|
||||||
sh_off += NBI_LENGTH ( sh.length );
|
sh_off += NBI_LENGTH ( sh->length );
|
||||||
if ( sh_off >= NBI_HEADER_LENGTH ) {
|
if ( sh_off >= NBI_HEADER_LENGTH ) {
|
||||||
DBGC ( image, "NBI %p header overflow\n", image );
|
DBGC ( image, "NBI %p header overflow\n", image );
|
||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
} while ( ! NBI_LAST_SEGHEADER ( sh.flags ) );
|
} while ( ! NBI_LAST_SEGHEADER ( sh->flags ) );
|
||||||
|
|
||||||
if ( offset != image->len ) {
|
if ( offset != image->len ) {
|
||||||
DBGC ( image, "NBI %p length wrong (file %zd, metadata %zd)\n",
|
DBGC ( image, "NBI %p length wrong (file %zd, metadata %zd)\n",
|
||||||
@@ -239,7 +239,8 @@ static int nbi_process_segments ( struct image *image,
|
|||||||
* @v imgheader Image header information
|
* @v imgheader Image header information
|
||||||
* @ret rc Return status code, if image returns
|
* @ret rc Return status code, if image returns
|
||||||
*/
|
*/
|
||||||
static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) {
|
static int nbi_boot16 ( struct image *image,
|
||||||
|
const struct imgheader *imgheader ) {
|
||||||
int discard_D, discard_S, discard_b;
|
int discard_D, discard_S, discard_b;
|
||||||
int32_t rc;
|
int32_t rc;
|
||||||
|
|
||||||
@@ -277,7 +278,8 @@ static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) {
|
|||||||
* @v imgheader Image header information
|
* @v imgheader Image header information
|
||||||
* @ret rc Return status code, if image returns
|
* @ret rc Return status code, if image returns
|
||||||
*/
|
*/
|
||||||
static int nbi_boot32 ( struct image *image, struct imgheader *imgheader ) {
|
static int nbi_boot32 ( struct image *image,
|
||||||
|
const struct imgheader *imgheader ) {
|
||||||
struct ebinfo loaderinfo = {
|
struct ebinfo loaderinfo = {
|
||||||
product_major_version, product_minor_version,
|
product_major_version, product_minor_version,
|
||||||
0
|
0
|
||||||
@@ -342,15 +344,15 @@ static int nbi_prepare_dhcp ( struct image *image ) {
|
|||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int nbi_exec ( struct image *image ) {
|
static int nbi_exec ( struct image *image ) {
|
||||||
struct imgheader imgheader;
|
const struct imgheader *imgheader;
|
||||||
int may_return;
|
int may_return;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Retrieve image header */
|
/* Retrieve image header */
|
||||||
copy_from_user ( &imgheader, image->data, 0, sizeof ( imgheader ) );
|
imgheader = image->data;
|
||||||
|
|
||||||
DBGC ( image, "NBI %p placing header at %hx:%hx\n", image,
|
DBGC ( image, "NBI %p placing header at %hx:%hx\n", image,
|
||||||
imgheader.location.segment, imgheader.location.offset );
|
imgheader->location.segment, imgheader->location.offset );
|
||||||
|
|
||||||
/* NBI files can have overlaps between segments; the bss of
|
/* NBI files can have overlaps between segments; the bss of
|
||||||
* one segment may overlap the initialised data of another. I
|
* one segment may overlap the initialised data of another. I
|
||||||
@@ -359,10 +361,10 @@ static int nbi_exec ( struct image *image ) {
|
|||||||
* passes: first to initialise the segments, then to copy the
|
* passes: first to initialise the segments, then to copy the
|
||||||
* data. This avoids zeroing out already-copied data.
|
* data. This avoids zeroing out already-copied data.
|
||||||
*/
|
*/
|
||||||
if ( ( rc = nbi_process_segments ( image, &imgheader,
|
if ( ( rc = nbi_process_segments ( image, imgheader,
|
||||||
nbi_prepare_segment ) ) != 0 )
|
nbi_prepare_segment ) ) != 0 )
|
||||||
return rc;
|
return rc;
|
||||||
if ( ( rc = nbi_process_segments ( image, &imgheader,
|
if ( ( rc = nbi_process_segments ( image, imgheader,
|
||||||
nbi_load_segment ) ) != 0 )
|
nbi_load_segment ) ) != 0 )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@@ -371,15 +373,15 @@ static int nbi_exec ( struct image *image ) {
|
|||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* Shut down now if NBI image will not return */
|
/* Shut down now if NBI image will not return */
|
||||||
may_return = NBI_PROGRAM_RETURNS ( imgheader.flags );
|
may_return = NBI_PROGRAM_RETURNS ( imgheader->flags );
|
||||||
if ( ! may_return )
|
if ( ! may_return )
|
||||||
shutdown_boot();
|
shutdown_boot();
|
||||||
|
|
||||||
/* Execute NBI image */
|
/* Execute NBI image */
|
||||||
if ( NBI_LINEAR_EXEC_ADDR ( imgheader.flags ) ) {
|
if ( NBI_LINEAR_EXEC_ADDR ( imgheader->flags ) ) {
|
||||||
rc = nbi_boot32 ( image, &imgheader );
|
rc = nbi_boot32 ( image, imgheader );
|
||||||
} else {
|
} else {
|
||||||
rc = nbi_boot16 ( image, &imgheader );
|
rc = nbi_boot16 ( image, imgheader );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! may_return ) {
|
if ( ! may_return ) {
|
||||||
@@ -401,17 +403,17 @@ static int nbi_exec ( struct image *image ) {
|
|||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int nbi_probe ( struct image *image ) {
|
static int nbi_probe ( struct image *image ) {
|
||||||
struct imgheader imgheader;
|
const struct imgheader *imgheader;
|
||||||
|
|
||||||
/* If we don't have enough data give up */
|
/* If we don't have enough data give up */
|
||||||
if ( image->len < NBI_HEADER_LENGTH ) {
|
if ( image->len < NBI_HEADER_LENGTH ) {
|
||||||
DBGC ( image, "NBI %p too short for an NBI image\n", image );
|
DBGC ( image, "NBI %p too short for an NBI image\n", image );
|
||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
}
|
}
|
||||||
|
imgheader = image->data;
|
||||||
|
|
||||||
/* Check image header */
|
/* Check image header */
|
||||||
copy_from_user ( &imgheader, image->data, 0, sizeof ( imgheader ) );
|
if ( imgheader->magic != NBI_MAGIC ) {
|
||||||
if ( imgheader.magic != NBI_MAGIC ) {
|
|
||||||
DBGC ( image, "NBI %p has no NBI signature\n", image );
|
DBGC ( image, "NBI %p has no NBI signature\n", image );
|
||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user