1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include "header.h"
18
19#if TMS32060
20#include "tramp_table_c6000.c"
21#endif
22
23#define MAX_RELOS_PER_PASS 4
24
25
26
27
28
29
30static int priv_tramp_sect_tgt_alloc(struct dload_state *dlthis)
31{
32 int ret_val = 0;
33 struct ldr_section_info *sect_info;
34
35
36
37
38
39 sect_info = &dlthis->ldr_sections[dlthis->allocated_secn_count];
40
41 sect_info->name = dlthis->tramp.final_string_table;
42 sect_info->size = dlthis->tramp.tramp_sect_next_addr;
43 sect_info->context = 0;
44 sect_info->type =
45 (4 << 8) | DLOAD_TEXT | DS_ALLOCATE_MASK | DS_DOWNLOAD_MASK;
46 sect_info->page = 0;
47 sect_info->run_addr = 0;
48 sect_info->load_addr = 0;
49 ret_val = dlthis->myalloc->dload_allocate(dlthis->myalloc,
50 sect_info,
51 ds_alignment
52 (sect_info->type));
53
54 if (ret_val == 0)
55 dload_error(dlthis, "Failed to allocate target memory for"
56 " trampoline");
57
58 return ret_val;
59}
60
61
62
63
64
65
66static u8 priv_h2a(u8 value)
67{
68 if (value > 0xF)
69 return 0xFF;
70
71 if (value <= 9)
72 value += 0x30;
73 else
74 value += 0x37;
75
76 return value;
77}
78
79
80
81
82
83
84
85
86static void priv_tramp_sym_gen_name(u32 value, char *dst)
87{
88 u32 i;
89 char *prefix = TRAMP_SYM_PREFIX;
90 char *dst_local = dst;
91 u8 tmp;
92
93
94 for (i = 0; i < (TRAMP_SYM_PREFIX_LEN + TRAMP_SYM_HEX_ASCII_LEN); i++)
95 *(dst_local + i) = 0;
96
97
98 for (i = 0; i < strlen(TRAMP_SYM_PREFIX); i++) {
99 *dst_local = *(prefix + i);
100 dst_local++;
101 }
102
103
104 for (i = 0; i < sizeof(value); i++) {
105#ifndef _BIG_ENDIAN
106 tmp = *(((u8 *) &value) + (sizeof(value) - 1) - i);
107 *dst_local = priv_h2a((tmp & 0xF0) >> 4);
108 dst_local++;
109 *dst_local = priv_h2a(tmp & 0x0F);
110 dst_local++;
111#else
112 tmp = *(((u8 *) &value) + i);
113 *dst_local = priv_h2a((tmp & 0xF0) >> 4);
114 dst_local++;
115 *dst_local = priv_h2a(tmp & 0x0F);
116 dst_local++;
117#endif
118 }
119
120
121 *dst_local = 0;
122}
123
124
125
126
127
128
129
130static struct tramp_string *priv_tramp_string_create(struct dload_state *dlthis,
131 u32 str_len, char *str)
132{
133 struct tramp_string *new_string = NULL;
134 u32 i;
135
136
137 new_string =
138 (struct tramp_string *)dlthis->mysym->dload_allocate(dlthis->mysym,
139 (sizeof
140 (struct
141 tramp_string)
142 + str_len +
143 1));
144 if (new_string != NULL) {
145
146
147 for (i = 0; i < (sizeof(struct tramp_string) + str_len + 1);
148 i++)
149 *((u8 *) new_string + i) = 0;
150
151
152
153 new_string->index = dlthis->tramp.tramp_string_next_index;
154 dlthis->tramp.tramp_string_next_index++;
155 dlthis->tramp.tramp_string_size += str_len + 1;
156
157 new_string->next = NULL;
158 if (dlthis->tramp.string_head == NULL)
159 dlthis->tramp.string_head = new_string;
160 else
161 dlthis->tramp.string_tail->next = new_string;
162
163 dlthis->tramp.string_tail = new_string;
164
165
166 for (i = 0; i < str_len; i++)
167 new_string->str[i] = str[i];
168 }
169
170 return new_string;
171}
172
173
174
175
176
177
178static struct tramp_string *priv_tramp_string_find(struct dload_state *dlthis,
179 char *str)
180{
181 struct tramp_string *cur_str = NULL;
182 struct tramp_string *ret_val = NULL;
183 u32 i;
184 u32 str_len = strlen(str);
185
186 for (cur_str = dlthis->tramp.string_head;
187 (ret_val == NULL) && (cur_str != NULL); cur_str = cur_str->next) {
188
189
190 if (str_len != strlen(cur_str->str))
191 continue;
192
193
194 for (i = 0; i < str_len; i++) {
195
196
197
198 if (str[i] != cur_str->str[i])
199 break;
200 }
201
202 if (i == str_len)
203 ret_val = cur_str;
204 }
205
206 return ret_val;
207}
208
209
210
211
212
213
214
215static int priv_string_tbl_finalize(struct dload_state *dlthis)
216{
217 int ret_val = 0;
218 struct tramp_string *cur_string;
219 char *cur_loc;
220 char *tmp;
221
222
223
224
225 dlthis->tramp.final_string_table =
226 (char *)dlthis->mysym->dload_allocate(dlthis->mysym,
227 dlthis->tramp.
228 tramp_string_size);
229 if (dlthis->tramp.final_string_table != NULL) {
230
231
232 cur_loc = dlthis->tramp.final_string_table;
233 cur_string = dlthis->tramp.string_head;
234 while (cur_string != NULL) {
235
236 dlthis->tramp.string_head = cur_string->next;
237 if (dlthis->tramp.string_tail == cur_string)
238 dlthis->tramp.string_tail = NULL;
239
240
241 for (tmp = cur_string->str;
242 *tmp != '\0'; tmp++, cur_loc++)
243 *cur_loc = *tmp;
244
245
246
247 *cur_loc = '\0';
248 cur_loc++;
249
250
251 dlthis->mysym->dload_deallocate(dlthis->mysym,
252 cur_string);
253
254
255 cur_string = dlthis->tramp.string_head;
256 }
257
258
259 ret_val = 1;
260 } else
261 dload_error(dlthis, "Failed to allocate trampoline "
262 "string table");
263
264 return ret_val;
265}
266
267
268
269
270
271
272
273
274static u32 priv_tramp_sect_alloc(struct dload_state *dlthis, u32 tramp_size)
275{
276 u32 ret_val;
277
278
279
280 if (dlthis->tramp.tramp_sect_next_addr == 0) {
281 dload_syms_error(dlthis->mysym, "*** WARNING *** created "
282 "dynamic TRAMPOLINE section for module %s",
283 dlthis->str_head);
284 }
285
286
287 ret_val = dlthis->tramp.tramp_sect_next_addr;
288 dlthis->tramp.tramp_sect_next_addr += tramp_size;
289 return ret_val;
290}
291
292
293
294
295
296
297
298
299static struct tramp_sym *priv_tramp_sym_create(struct dload_state *dlthis,
300 u32 str_index,
301 struct local_symbol *tmp_sym)
302{
303 struct tramp_sym *new_sym = NULL;
304 u32 i;
305
306
307 new_sym =
308 (struct tramp_sym *)dlthis->mysym->dload_allocate(dlthis->mysym,
309 sizeof(struct tramp_sym));
310 if (new_sym != NULL) {
311 for (i = 0; i != sizeof(struct tramp_sym); i++)
312 *((char *)new_sym + i) = 0;
313
314
315
316 new_sym->index = dlthis->tramp.tramp_sym_next_index;
317 dlthis->tramp.tramp_sym_next_index++;
318
319
320
321
322
323 new_sym->sym_info = *tmp_sym;
324 new_sym->str_index = str_index;
325
326
327 new_sym->next = NULL;
328 if (dlthis->tramp.symbol_head == NULL)
329 dlthis->tramp.symbol_head = new_sym;
330 else
331 dlthis->tramp.symbol_tail->next = new_sym;
332
333 dlthis->tramp.symbol_tail = new_sym;
334 }
335
336 return new_sym;
337}
338
339
340
341
342
343
344
345static struct tramp_sym *priv_tramp_sym_get(struct dload_state *dlthis,
346 u32 string_index)
347{
348 struct tramp_sym *sym_found = NULL;
349
350
351 for (sym_found = dlthis->tramp.symbol_head;
352 sym_found != NULL; sym_found = sym_found->next) {
353 if (sym_found->str_index == string_index)
354 break;
355 }
356
357 return sym_found;
358}
359
360
361
362
363
364
365
366static struct tramp_sym *priv_tramp_sym_find(struct dload_state *dlthis,
367 char *string)
368{
369 struct tramp_sym *sym_found = NULL;
370 struct tramp_string *str_found = NULL;
371
372
373
374 str_found = priv_tramp_string_find(dlthis, string);
375 if (str_found != NULL)
376 sym_found = priv_tramp_sym_get(dlthis, str_found->index);
377
378 return sym_found;
379}
380
381
382
383
384
385
386
387
388static int priv_tramp_sym_finalize(struct dload_state *dlthis)
389{
390 int ret_val = 0;
391 struct tramp_sym *cur_sym;
392 struct ldr_section_info *tramp_sect =
393 &dlthis->ldr_sections[dlthis->allocated_secn_count];
394 struct local_symbol *new_sym;
395
396
397
398 dlthis->tramp.final_sym_table =
399 (struct local_symbol *)dlthis->mysym->dload_allocate(dlthis->mysym,
400 (sizeof(struct local_symbol) * dlthis->tramp.
401 tramp_sym_next_index));
402 if (dlthis->tramp.final_sym_table != NULL) {
403
404
405
406 new_sym = dlthis->tramp.final_sym_table;
407 cur_sym = dlthis->tramp.symbol_head;
408 while (cur_sym != NULL) {
409
410 dlthis->tramp.symbol_head = cur_sym->next;
411 if (cur_sym == dlthis->tramp.symbol_tail)
412 dlthis->tramp.symbol_tail = NULL;
413
414
415 *new_sym = cur_sym->sym_info;
416
417
418
419
420
421
422
423
424
425 if (new_sym->secnn < 0) {
426 new_sym->value += tramp_sect->load_addr;
427 new_sym->delta = new_sym->value;
428 }
429
430
431 dlthis->mysym->dload_deallocate(dlthis->mysym, cur_sym);
432
433
434 cur_sym = dlthis->tramp.symbol_head;
435 new_sym++;
436 }
437
438 ret_val = 1;
439 } else
440 dload_error(dlthis, "Failed to alloc trampoline sym table");
441
442 return ret_val;
443}
444
445
446
447
448
449
450
451
452static int priv_tgt_img_gen(struct dload_state *dlthis, u32 base,
453 u32 gen_index, struct tramp_sym *new_ext_sym)
454{
455 struct tramp_img_pkt *new_img_pkt = NULL;
456 u32 i;
457 u32 pkt_size = tramp_img_pkt_size_get();
458 u8 *gen_tbl_entry;
459 u8 *pkt_data;
460 struct reloc_record_t *cur_relo;
461 int ret_val = 0;
462
463
464 new_img_pkt =
465 (struct tramp_img_pkt *)dlthis->mysym->dload_allocate(dlthis->mysym,
466 pkt_size);
467 if (new_img_pkt != NULL) {
468
469 new_img_pkt->base = base;
470
471
472 pkt_data = (u8 *) &new_img_pkt->hdr;
473 gen_tbl_entry = (u8 *) &tramp_gen_info[gen_index];
474 for (i = 0; i < pkt_size; i++) {
475 *pkt_data = *gen_tbl_entry;
476 pkt_data++;
477 gen_tbl_entry++;
478 }
479
480
481 cur_relo =
482 (struct reloc_record_t *)((u8 *) &new_img_pkt->hdr +
483 new_img_pkt->hdr.relo_offset);
484 for (i = 0; i < new_img_pkt->hdr.num_relos; i++)
485 cur_relo[i].SYMNDX = new_ext_sym->index;
486
487
488 new_img_pkt->next = dlthis->tramp.tramp_pkts;
489 dlthis->tramp.tramp_pkts = new_img_pkt;
490
491 ret_val = 1;
492 }
493
494 return ret_val;
495}
496
497
498
499
500
501
502
503
504
505
506static int priv_pkt_relo(struct dload_state *dlthis, tgt_au_t * data,
507 struct reloc_record_t *rp[], u32 relo_count)
508{
509 int ret_val = 1;
510 u32 i;
511 bool tmp;
512
513
514
515
516 for (i = 0; i < relo_count; i++)
517 dload_relocate(dlthis, data, rp[i], &tmp, true);
518
519 return ret_val;
520}
521
522
523
524
525
526
527
528
529
530
531static int priv_tramp_pkt_finalize(struct dload_state *dlthis)
532{
533 int ret_val = 1;
534 struct tramp_img_pkt *cur_pkt = NULL;
535 struct reloc_record_t *relos[MAX_RELOS_PER_PASS];
536 u32 relos_done;
537 u32 i;
538 struct reloc_record_t *cur_relo;
539 struct ldr_section_info *sect_info =
540 &dlthis->ldr_sections[dlthis->allocated_secn_count];
541
542
543
544
545 cur_pkt = dlthis->tramp.tramp_pkts;
546 while ((ret_val != 0) && (cur_pkt != NULL)) {
547
548 dlthis->tramp.tramp_pkts = cur_pkt->next;
549
550
551 dlthis->image_secn = sect_info;
552 dlthis->image_offset = cur_pkt->base;
553 dlthis->delta_runaddr = sect_info->run_addr;
554
555
556 relos_done = 0;
557 cur_relo = (struct reloc_record_t *)((u8 *) &cur_pkt->hdr +
558 cur_pkt->hdr.relo_offset);
559 while (relos_done < cur_pkt->hdr.num_relos) {
560#ifdef ENABLE_TRAMP_DEBUG
561 dload_syms_error(dlthis->mysym,
562 "===> Trampoline %x branches to %x",
563 sect_info->run_addr +
564 dlthis->image_offset,
565 dlthis->
566 tramp.final_sym_table[cur_relo->
567 SYMNDX].value);
568#endif
569
570 for (i = 0;
571 ((i < MAX_RELOS_PER_PASS) &&
572 ((i + relos_done) < cur_pkt->hdr.num_relos)); i++)
573 relos[i] = cur_relo + i;
574
575
576 ret_val = priv_pkt_relo(dlthis,
577 (tgt_au_t *) &cur_pkt->payload,
578 relos, i);
579 if (ret_val == 0) {
580 dload_error(dlthis,
581 "Relocation of trampoline pkt at %x"
582 " failed", cur_pkt->base +
583 sect_info->run_addr);
584 break;
585 }
586
587 relos_done += i;
588 cur_relo += i;
589 }
590
591
592 if (ret_val != 0) {
593
594
595 ret_val = dlthis->myio->writemem(dlthis->myio,
596 &cur_pkt->payload,
597 sect_info->load_addr +
598 cur_pkt->base,
599 sect_info,
600 BYTE_TO_HOST
601 (cur_pkt->hdr.
602 tramp_code_size));
603 if (ret_val == 0) {
604 dload_error(dlthis,
605 "Write to " FMT_UI32 " failed",
606 sect_info->load_addr +
607 cur_pkt->base);
608 }
609
610
611 dlthis->mysym->dload_deallocate(dlthis->mysym, cur_pkt);
612
613
614 cur_pkt = dlthis->tramp.tramp_pkts;
615 }
616 }
617
618 return ret_val;
619}
620
621
622
623
624
625
626
627
628
629
630
631static int priv_dup_pkt_finalize(struct dload_state *dlthis)
632{
633 int ret_val = 1;
634 struct tramp_img_dup_pkt *cur_pkt;
635 struct tramp_img_dup_relo *cur_relo;
636 struct reloc_record_t *relos[MAX_RELOS_PER_PASS];
637 struct doff_scnhdr_t *sect_hdr = NULL;
638 s32 i;
639
640
641
642
643
644
645 cur_pkt = dlthis->tramp.dup_pkts;
646 while ((ret_val != 0) && (cur_pkt != NULL)) {
647
648
649 dlthis->tramp.dup_pkts = cur_pkt->next;
650
651
652 dlthis->image_secn = &dlthis->ldr_sections[cur_pkt->secnn];
653 dlthis->image_offset = cur_pkt->offset;
654
655
656
657
658 i = (s32) (dlthis->image_secn - dlthis->ldr_sections);
659 sect_hdr = dlthis->sect_hdrs + i;
660 dlthis->delta_runaddr = sect_hdr->ds_paddr;
661
662
663 cur_relo = cur_pkt->relo_chain;
664 while (cur_relo != NULL) {
665
666 for (i = 0; (i < MAX_RELOS_PER_PASS)
667 && (cur_relo != NULL);
668 i++, cur_relo = cur_relo->next) {
669 relos[i] = &cur_relo->relo;
670 cur_pkt->relo_chain = cur_relo->next;
671 }
672
673
674 ret_val = priv_pkt_relo(dlthis,
675 cur_pkt->img_pkt.img_data,
676 relos, i);
677 if (ret_val == 0) {
678 dload_error(dlthis,
679 "Relocation of dup pkt at %x"
680 " failed", cur_pkt->offset +
681 dlthis->image_secn->run_addr);
682 break;
683 }
684
685
686 while (i > 0) {
687 dlthis->mysym->dload_deallocate(dlthis->mysym,
688 GET_CONTAINER
689 (relos[i - 1],
690 struct tramp_img_dup_relo,
691 relo));
692 i--;
693 }
694
695
696
697 }
698
699
700
701 if (ret_val != 0) {
702 ret_val = dlthis->myio->writemem(dlthis->myio,
703 cur_pkt->img_pkt.
704 img_data,
705 dlthis->image_secn->
706 load_addr +
707 cur_pkt->offset,
708 dlthis->image_secn,
709 BYTE_TO_HOST
710 (cur_pkt->img_pkt.
711 packet_size));
712 if (ret_val == 0) {
713 dload_error(dlthis,
714 "Write to " FMT_UI32 " failed",
715 dlthis->image_secn->load_addr +
716 cur_pkt->offset);
717 }
718
719 dlthis->mysym->dload_deallocate(dlthis->mysym, cur_pkt);
720
721
722 cur_pkt = dlthis->tramp.dup_pkts;
723 }
724 }
725
726 return ret_val;
727}
728
729
730
731
732
733
734
735static struct tramp_img_dup_pkt *priv_dup_find(struct dload_state *dlthis,
736 s16 secnn, u32 image_offset)
737{
738 struct tramp_img_dup_pkt *cur_pkt = NULL;
739
740 for (cur_pkt = dlthis->tramp.dup_pkts;
741 cur_pkt != NULL; cur_pkt = cur_pkt->next) {
742 if ((cur_pkt->secnn == secnn) &&
743 (cur_pkt->offset == image_offset)) {
744
745 break;
746 }
747 }
748
749 return cur_pkt;
750}
751
752
753
754
755
756
757
758
759
760
761
762
763
764static int priv_img_pkt_dup(struct dload_state *dlthis,
765 s16 secnn, u32 image_offset,
766 struct image_packet_t *ipacket,
767 struct reloc_record_t *rp,
768 struct tramp_sym *new_tramp_sym)
769{
770 struct tramp_img_dup_pkt *dup_pkt = NULL;
771 u32 new_dup_size;
772 s32 i;
773 int ret_val = 0;
774 struct tramp_img_dup_relo *dup_relo = NULL;
775
776
777
778 dup_pkt = priv_dup_find(dlthis, secnn, image_offset);
779
780 if (dup_pkt == NULL) {
781
782
783 new_dup_size = sizeof(struct tramp_img_dup_pkt) +
784 ipacket->packet_size;
785
786 dup_pkt = (struct tramp_img_dup_pkt *)
787 dlthis->mysym->dload_allocate(dlthis->mysym, new_dup_size);
788 if (dup_pkt != NULL) {
789
790 dup_pkt->secnn = secnn;
791 dup_pkt->offset = image_offset;
792 dup_pkt->relo_chain = NULL;
793
794
795 dup_pkt->img_pkt = *ipacket;
796 dup_pkt->img_pkt.img_data = (u8 *) (dup_pkt + 1);
797 for (i = 0; i < ipacket->packet_size; i++)
798 *(dup_pkt->img_pkt.img_data + i) =
799 *(ipacket->img_data + i);
800
801
802 dup_pkt->next = dlthis->tramp.dup_pkts;
803 dlthis->tramp.dup_pkts = dup_pkt;
804 } else
805 dload_error(dlthis, "Failed to create dup packet!");
806 } else {
807
808
809
810
811 for (i = 0; i < dup_pkt->img_pkt.packet_size; i++)
812 *(dup_pkt->img_pkt.img_data + i) =
813 *(ipacket->img_data + i);
814 }
815
816
817
818 if (dup_pkt != NULL) {
819
820
821
822
823 dup_relo = dlthis->mysym->dload_allocate(dlthis->mysym,
824 sizeof(struct tramp_img_dup_relo));
825 if (dup_relo != NULL) {
826
827
828 dup_relo->relo = *rp;
829 dup_relo->relo.SYMNDX = new_tramp_sym->index;
830
831 dup_relo->next = dup_pkt->relo_chain;
832 dup_pkt->relo_chain = dup_relo;
833
834
835
836
837 ret_val = 1;
838 } else
839 dload_error(dlthis, "Unable to alloc dup relo");
840 }
841
842 return ret_val;
843}
844
845
846
847
848
849
850bool dload_tramp_avail(struct dload_state *dlthis, struct reloc_record_t *rp)
851{
852 bool ret_val = false;
853 u16 map_index;
854 u16 gen_index;
855
856
857 map_index = HASH_FUNC(rp->TYPE);
858 gen_index = tramp_map[map_index];
859 if (gen_index != TRAMP_NO_GEN_AVAIL)
860 ret_val = true;
861
862 return ret_val;
863}
864
865
866
867
868
869
870
871
872
873int dload_tramp_generate(struct dload_state *dlthis, s16 secnn,
874 u32 image_offset, struct image_packet_t *ipacket,
875 struct reloc_record_t *rp)
876{
877 u16 map_index;
878 u16 gen_index;
879 int ret_val = 1;
880 char tramp_sym_str[TRAMP_SYM_PREFIX_LEN + TRAMP_SYM_HEX_ASCII_LEN];
881 struct local_symbol *ref_sym;
882 struct tramp_sym *new_tramp_sym;
883 struct tramp_sym *new_ext_sym;
884 struct tramp_string *new_tramp_str;
885 u32 new_tramp_base;
886 struct local_symbol tmp_sym;
887 struct local_symbol ext_tmp_sym;
888
889
890 map_index = HASH_FUNC(rp->TYPE);
891 gen_index = tramp_map[map_index];
892 if (gen_index != TRAMP_NO_GEN_AVAIL) {
893
894
895 if (dlthis->tramp.string_head == NULL) {
896 priv_tramp_string_create(dlthis,
897 strlen(TRAMP_SECT_NAME),
898 TRAMP_SECT_NAME);
899 }
900#ifdef ENABLE_TRAMP_DEBUG
901 dload_syms_error(dlthis->mysym,
902 "Trampoline at img loc %x, references %x",
903 dlthis->ldr_sections[secnn].run_addr +
904 image_offset + rp->vaddr,
905 dlthis->local_symtab[rp->SYMNDX].value);
906#endif
907
908
909
910
911
912 if (rp->SYMNDX == -1) {
913 ext_tmp_sym.value =
914 dlthis->ldr_sections[secnn].run_addr;
915 ext_tmp_sym.delta = dlthis->sect_hdrs[secnn].ds_paddr;
916 ref_sym = &ext_tmp_sym;
917 } else
918 ref_sym = &(dlthis->local_symtab[rp->SYMNDX]);
919
920 priv_tramp_sym_gen_name(ref_sym->value, tramp_sym_str);
921 new_tramp_sym = priv_tramp_sym_find(dlthis, tramp_sym_str);
922 if (new_tramp_sym == NULL) {
923
924
925
926 new_tramp_str = priv_tramp_string_create(dlthis,
927 strlen
928 (tramp_sym_str),
929 tramp_sym_str);
930 if (new_tramp_str == NULL) {
931 dload_error(dlthis, "Failed to create new "
932 "trampoline string\n");
933 ret_val = 0;
934 } else {
935
936
937 new_tramp_base = priv_tramp_sect_alloc(dlthis,
938 tramp_size_get());
939
940
941
942 tmp_sym.value = new_tramp_base;
943 tmp_sym.delta = 0;
944 tmp_sym.secnn = -1;
945 tmp_sym.sclass = 0;
946 new_tramp_sym = priv_tramp_sym_create(dlthis,
947 new_tramp_str->
948 index,
949 &tmp_sym);
950
951 new_ext_sym = priv_tramp_sym_create(dlthis, -1,
952 ref_sym);
953
954 if ((new_tramp_sym != NULL) &&
955 (new_ext_sym != NULL)) {
956
957
958
959
960 ret_val = priv_tgt_img_gen(dlthis,
961 new_tramp_base,
962 gen_index,
963 new_ext_sym);
964
965
966
967 if (ret_val != 1) {
968 dload_error(dlthis, "Failed to "
969 "create img pkt for"
970 " trampoline\n");
971 }
972 } else {
973 dload_error(dlthis, "Failed to create "
974 "new tramp syms "
975 "(%8.8X, %8.8X)\n",
976 new_tramp_sym, new_ext_sym);
977 ret_val = 0;
978 }
979 }
980 }
981
982
983
984
985 if (ret_val == 1) {
986 ret_val = priv_img_pkt_dup(dlthis, secnn, image_offset,
987 ipacket, rp, new_tramp_sym);
988 if (ret_val != 1) {
989 dload_error(dlthis, "Failed to create dup of "
990 "original img pkt\n");
991 }
992 }
993 }
994
995 return ret_val;
996}
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008int dload_tramp_pkt_udpate(struct dload_state *dlthis, s16 secnn,
1009 u32 image_offset, struct image_packet_t *ipacket)
1010{
1011 struct tramp_img_dup_pkt *dup_pkt = NULL;
1012 s32 i;
1013 int ret_val = 0;
1014
1015
1016
1017 dup_pkt = priv_dup_find(dlthis, secnn, image_offset);
1018 if (dup_pkt != NULL) {
1019 for (i = 0; i < dup_pkt->img_pkt.packet_size; i++)
1020 *(dup_pkt->img_pkt.img_data + i) =
1021 *(ipacket->img_data + i);
1022
1023 ret_val = 1;
1024 } else {
1025 dload_error(dlthis,
1026 "Unable to find existing DUP pkt for %x, offset %x",
1027 secnn, image_offset);
1028
1029 }
1030
1031 return ret_val;
1032}
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042int dload_tramp_finalize(struct dload_state *dlthis)
1043{
1044 int ret_val = 1;
1045
1046 if (dlthis->tramp.tramp_sect_next_addr != 0) {
1047
1048
1049 ret_val = priv_string_tbl_finalize(dlthis);
1050
1051
1052
1053 if (ret_val != 0)
1054 ret_val = priv_tramp_sect_tgt_alloc(dlthis);
1055
1056
1057
1058 if (ret_val != 0)
1059 ret_val = priv_tramp_sym_finalize(dlthis);
1060
1061
1062
1063
1064 if (ret_val != 0)
1065 ret_val = priv_tramp_pkt_finalize(dlthis);
1066
1067
1068 if (ret_val != 0)
1069 ret_val = priv_dup_pkt_finalize(dlthis);
1070 }
1071
1072 return ret_val;
1073}
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083void dload_tramp_cleanup(struct dload_state *dlthis)
1084{
1085 struct tramp_info *tramp = &dlthis->tramp;
1086 struct tramp_sym *cur_sym;
1087 struct tramp_string *cur_string;
1088 struct tramp_img_pkt *cur_tramp_pkt;
1089 struct tramp_img_dup_pkt *cur_dup_pkt;
1090 struct tramp_img_dup_relo *cur_dup_relo;
1091
1092
1093 if (tramp->tramp_sect_next_addr == 0)
1094 return;
1095
1096
1097 for (cur_sym = tramp->symbol_head;
1098 cur_sym != NULL; cur_sym = tramp->symbol_head) {
1099 tramp->symbol_head = cur_sym->next;
1100 if (tramp->symbol_tail == cur_sym)
1101 tramp->symbol_tail = NULL;
1102
1103 dlthis->mysym->dload_deallocate(dlthis->mysym, cur_sym);
1104 }
1105
1106 if (tramp->final_sym_table != NULL)
1107 dlthis->mysym->dload_deallocate(dlthis->mysym,
1108 tramp->final_sym_table);
1109
1110 for (cur_string = tramp->string_head;
1111 cur_string != NULL; cur_string = tramp->string_head) {
1112 tramp->string_head = cur_string->next;
1113 if (tramp->string_tail == cur_string)
1114 tramp->string_tail = NULL;
1115
1116 dlthis->mysym->dload_deallocate(dlthis->mysym, cur_string);
1117 }
1118
1119 if (tramp->final_string_table != NULL)
1120 dlthis->mysym->dload_deallocate(dlthis->mysym,
1121 tramp->final_string_table);
1122
1123 for (cur_tramp_pkt = tramp->tramp_pkts;
1124 cur_tramp_pkt != NULL; cur_tramp_pkt = tramp->tramp_pkts) {
1125 tramp->tramp_pkts = cur_tramp_pkt->next;
1126 dlthis->mysym->dload_deallocate(dlthis->mysym, cur_tramp_pkt);
1127 }
1128
1129 for (cur_dup_pkt = tramp->dup_pkts;
1130 cur_dup_pkt != NULL; cur_dup_pkt = tramp->dup_pkts) {
1131 tramp->dup_pkts = cur_dup_pkt->next;
1132
1133 for (cur_dup_relo = cur_dup_pkt->relo_chain;
1134 cur_dup_relo != NULL;
1135 cur_dup_relo = cur_dup_pkt->relo_chain) {
1136 cur_dup_pkt->relo_chain = cur_dup_relo->next;
1137 dlthis->mysym->dload_deallocate(dlthis->mysym,
1138 cur_dup_relo);
1139 }
1140
1141 dlthis->mysym->dload_deallocate(dlthis->mysym, cur_dup_pkt);
1142 }
1143}
1144