X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=drivers%2Fstaging%2Ftidspbridge%2Fdynload%2Fcload.c;h=9d54744805b88a6ea9a3dba376685800996c34dd;hb=152fcb2784c9305e19e7caee2932b9e32b0a1d41;hp=fe1ef0addb09e4da2cf73f7fe36fac818b2bb436;hpb=3190dad97b5105ec9b9720f6d7bea54ee830fc2d;p=~andy%2Flinux diff --git a/drivers/staging/tidspbridge/dynload/cload.c b/drivers/staging/tidspbridge/dynload/cload.c index fe1ef0addb0..9d54744805b 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 + #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 */ /*************************************************************************