|
@@ -14,6 +14,8 @@
|
|
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
*/
|
|
|
|
|
|
+#include <linux/slab.h>
|
|
|
+
|
|
|
#include "header.h"
|
|
|
|
|
|
#include "module_list.h"
|
|
@@ -1116,6 +1118,11 @@ static int relocate_packet(struct dload_state *dlthis,
|
|
|
/* VERY dangerous */
|
|
|
static const char imagepak[] = { "image packet" };
|
|
|
|
|
|
+struct img_buffer {
|
|
|
+ struct image_packet_t ipacket;
|
|
|
+ u8 bufr[BYTE_TO_HOST(IMAGE_PACKET_SIZE)];
|
|
|
+};
|
|
|
+
|
|
|
/*************************************************************************
|
|
|
* Procedure dload_data
|
|
|
*
|
|
@@ -1131,16 +1138,16 @@ static void dload_data(struct dload_state *dlthis)
|
|
|
u16 curr_sect;
|
|
|
struct doff_scnhdr_t *sptr = dlthis->sect_hdrs;
|
|
|
struct ldr_section_info *lptr = dlthis->ldr_sections;
|
|
|
+ struct img_buffer *ibuf;
|
|
|
u8 *dest;
|
|
|
|
|
|
- struct {
|
|
|
- struct image_packet_t ipacket;
|
|
|
- u8 bufr[BYTE_TO_HOST(IMAGE_PACKET_SIZE)];
|
|
|
- } ibuf;
|
|
|
-
|
|
|
/* Indicates whether CINIT processing has occurred */
|
|
|
bool cinit_processed = false;
|
|
|
|
|
|
+ ibuf = kzalloc(sizeof(*ibuf), GFP_KERNEL);
|
|
|
+ if (!ibuf)
|
|
|
+ return;
|
|
|
+
|
|
|
/* Loop through the sections and load them one at a time.
|
|
|
*/
|
|
|
for (curr_sect = 0; curr_sect < dlthis->dfile_hdr.df_no_scns;
|
|
@@ -1168,37 +1175,37 @@ static void dload_data(struct dload_state *dlthis)
|
|
|
|
|
|
/* get the fixed header bits */
|
|
|
if (dlthis->strm->read_buffer(dlthis->strm,
|
|
|
- &ibuf.ipacket,
|
|
|
+ &ibuf->ipacket,
|
|
|
IPH_SIZE) !=
|
|
|
IPH_SIZE) {
|
|
|
DL_ERROR(readstrm, imagepak);
|
|
|
- return;
|
|
|
+ goto free_ibuf;
|
|
|
}
|
|
|
/* reorder the header if need be */
|
|
|
if (dlthis->reorder_map) {
|
|
|
- dload_reorder(&ibuf.ipacket, IPH_SIZE,
|
|
|
+ dload_reorder(&ibuf->ipacket, IPH_SIZE,
|
|
|
dlthis->reorder_map);
|
|
|
}
|
|
|
/* now read the rest of the packet */
|
|
|
ipsize =
|
|
|
BYTE_TO_HOST(DOFF_ALIGN
|
|
|
- (ibuf.ipacket.packet_size));
|
|
|
+ (ibuf->ipacket.packet_size));
|
|
|
if (ipsize > BYTE_TO_HOST(IMAGE_PACKET_SIZE)) {
|
|
|
DL_ERROR("Bad image packet size %d",
|
|
|
ipsize);
|
|
|
- return;
|
|
|
+ goto free_ibuf;
|
|
|
}
|
|
|
- dest = ibuf.bufr;
|
|
|
+ dest = ibuf->bufr;
|
|
|
/* End of determination */
|
|
|
|
|
|
if (dlthis->strm->read_buffer(dlthis->strm,
|
|
|
- ibuf.bufr,
|
|
|
+ ibuf->bufr,
|
|
|
ipsize) !=
|
|
|
ipsize) {
|
|
|
DL_ERROR(readstrm, imagepak);
|
|
|
- return;
|
|
|
+ goto free_ibuf;
|
|
|
}
|
|
|
- ibuf.ipacket.img_data = dest;
|
|
|
+ ibuf->ipacket.img_data = dest;
|
|
|
|
|
|
/* reorder the bytes if need be */
|
|
|
#if !defined(_BIG_ENDIAN) || (TARGET_AU_BITS > 16)
|
|
@@ -1225,16 +1232,16 @@ static void dload_data(struct dload_state *dlthis)
|
|
|
#endif
|
|
|
#endif
|
|
|
|
|
|
- checks += dload_checksum(&ibuf.ipacket,
|
|
|
+ checks += dload_checksum(&ibuf->ipacket,
|
|
|
IPH_SIZE);
|
|
|
/* relocate the image bits as needed */
|
|
|
- if (ibuf.ipacket.num_relocs) {
|
|
|
+ if (ibuf->ipacket.num_relocs) {
|
|
|
dlthis->image_offset = image_offset;
|
|
|
if (!relocate_packet(dlthis,
|
|
|
- &ibuf.ipacket,
|
|
|
+ &ibuf->ipacket,
|
|
|
&checks,
|
|
|
&tramp_generated))
|
|
|
- return; /* serious error */
|
|
|
+ goto free_ibuf; /* error */
|
|
|
}
|
|
|
if (~checks)
|
|
|
DL_ERROR(err_checksum, imagepak);
|
|
@@ -1249,20 +1256,20 @@ static void dload_data(struct dload_state *dlthis)
|
|
|
if (dload_check_type(sptr,
|
|
|
DLOAD_CINIT)) {
|
|
|
cload_cinit(dlthis,
|
|
|
- &ibuf.ipacket);
|
|
|
+ &ibuf->ipacket);
|
|
|
cinit_processed = true;
|
|
|
} else {
|
|
|
/* FIXME */
|
|
|
if (!dlthis->myio->
|
|
|
writemem(dlthis->
|
|
|
myio,
|
|
|
- ibuf.bufr,
|
|
|
+ ibuf->bufr,
|
|
|
lptr->
|
|
|
load_addr +
|
|
|
image_offset,
|
|
|
lptr,
|
|
|
BYTE_TO_HOST
|
|
|
- (ibuf.
|
|
|
+ (ibuf->
|
|
|
ipacket.
|
|
|
packet_size))) {
|
|
|
DL_ERROR
|
|
@@ -1276,7 +1283,7 @@ static void dload_data(struct dload_state *dlthis)
|
|
|
}
|
|
|
}
|
|
|
image_offset +=
|
|
|
- BYTE_TO_TADDR(ibuf.ipacket.packet_size);
|
|
|
+ BYTE_TO_TADDR(ibuf->ipacket.packet_size);
|
|
|
} /* process packets */
|
|
|
/* if this is a BSS section, we may want to fill it */
|
|
|
if (!dload_check_type(sptr, DLOAD_BSS))
|
|
@@ -1334,6 +1341,9 @@ loop_cont:
|
|
|
DL_ERROR("Finalization of auto-trampolines (size = " FMT_UI32
|
|
|
") failed", dlthis->tramp.tramp_sect_next_addr);
|
|
|
}
|
|
|
+free_ibuf:
|
|
|
+ kfree(ibuf);
|
|
|
+ return;
|
|
|
} /* dload_data */
|
|
|
|
|
|
/*************************************************************************
|