summaryrefslogtreecommitdiffstats
path: root/drivers/staging/tidspbridge/dynload/cload.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/tidspbridge/dynload/cload.c')
-rw-r--r--drivers/staging/tidspbridge/dynload/cload.c69
1 files changed, 44 insertions, 25 deletions
diff --git a/drivers/staging/tidspbridge/dynload/cload.c b/drivers/staging/tidspbridge/dynload/cload.c
index fe1ef0addb09..9d54744805b8 100644
--- a/drivers/staging/tidspbridge/dynload/cload.c
+++ b/drivers/staging/tidspbridge/dynload/cload.c
@@ -14,6 +14,8 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+#include <linux/slab.h>
+
#include "header.h"
#include "module_list.h"
@@ -706,6 +708,7 @@ static void dload_symbols(struct dload_state *dlthis)
struct local_symbol *sp;
struct dynload_symbol *symp;
struct dynload_symbol *newsym;
+ struct doff_syment_t *my_sym_buf;
sym_count = dlthis->dfile_hdr.df_no_syms;
if (sym_count == 0)
@@ -739,13 +742,18 @@ static void dload_symbols(struct dload_state *dlthis)
become defined from the global symbol table */
checks = dlthis->verify.dv_sym_tab_checksum;
symbols_left = sym_count;
+
+ my_sym_buf = kzalloc(sizeof(*my_sym_buf) * MY_SYM_BUF_SIZ, GFP_KERNEL);
+ if (!my_sym_buf)
+ return;
+
do { /* read all symbols */
char *sname;
u32 val;
s32 delta;
struct doff_syment_t *input_sym;
unsigned syms_in_buf;
- struct doff_syment_t my_sym_buf[MY_SYM_BUF_SIZ];
+
input_sym = my_sym_buf;
syms_in_buf = symbols_left > MY_SYM_BUF_SIZ ?
MY_SYM_BUF_SIZ : symbols_left;
@@ -753,7 +761,7 @@ static void dload_symbols(struct dload_state *dlthis)
if (dlthis->strm->read_buffer(dlthis->strm, input_sym, siz) !=
siz) {
DL_ERROR(readstrm, sym_errid);
- return;
+ goto free_sym_buf;
}
if (dlthis->reorder_map)
dload_reorder(input_sym, siz, dlthis->reorder_map);
@@ -856,7 +864,7 @@ static void dload_symbols(struct dload_state *dlthis)
DL_ERROR("Absolute symbol %s is "
"defined multiple times with "
"different values", sname);
- return;
+ goto free_sym_buf;
}
}
loop_itr:
@@ -887,6 +895,9 @@ loop_cont:
if (~checks)
dload_error(dlthis, "Checksum of symbols failed");
+free_sym_buf:
+ kfree(my_sym_buf);
+ return;
} /* dload_symbols */
/*****************************************************************************
@@ -1116,6 +1127,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 +1147,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 +1184,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 +1241,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 +1265,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 +1292,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 +1350,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 */
/*************************************************************************