/*
 * tramp.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Copyright (C) 2009 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "header.h"

#if TMS32060
#include "tramp_table_c6000.c"
#endif

#define MAX_RELOS_PER_PASS	4

/*
 * Function:	priv_tramp_sect_tgt_alloc
 * Description: Allocate target memory for the trampoline section.  The
 *	  target mem size is easily obtained as the next available address.
 */
static int priv_tramp_sect_tgt_alloc(struct dload_state *dlthis)
{
	int ret_val = 0;
	struct ldr_section_info *sect_info;

	/*  Populate the trampoline loader section and allocate it on the
	 * target.  The section name is ALWAYS the first string in the final
	 * string table for trampolines.  The trampoline section is always
	 * 1 beyond the total number of allocated sections. */
	sect_info = &dlthis->ldr_sections[dlthis->allocated_secn_count];

	sect_info->name = dlthis->tramp.final_string_table;
	sect_info->size = dlthis->tramp.tramp_sect_next_addr;
	sect_info->context = 0;
	sect_info->type =
	    (4 << 8) | DLOAD_TEXT | DS_ALLOCATE_MASK | DS_DOWNLOAD_MASK;
	sect_info->page = 0;
	sect_info->run_addr = 0;
	sect_info->load_addr = 0;
	ret_val = dlthis->myalloc->dload_allocate(dlthis->myalloc,
						  sect_info,
						  ds_alignment
						  (sect_info->type));

	if (ret_val == 0)
		dload_error(dlthis, "Failed to allocate target memory for"
			    " trampoline");

	return ret_val;
}

/*
 * Function:	priv_h2a
 * Description: Helper function to convert a hex value to its ASCII
 *	  representation.  Used for trampoline symbol name generation.
 */
static u8 priv_h2a(u8 value)
{
	if (value > 0xF)
		return 0xFF;

	if (value <= 9)
		value += 0x30;
	else
		value += 0x37;

	return value;
}

/*
 * Function:	priv_tramp_sym_gen_name
 * Description: Generate a trampoline symbol name (ASCII) using the value
 *	  of the symbol.  This places the new name into the user buffer.
 *	  The name is fixed in length and of the form: __$dbTR__xxxxxxxx
 *	  (where "xxxxxxxx" is the hex value.
 */
static void priv_tramp_sym_gen_name(u32 value, char *dst)
{
	u32 i;
	char *prefix = TRAMP_SYM_PREFIX;
	char *dst_local = dst;
	u8 tmp;

	/*  Clear out the destination, including the ending NULL */
	for (i = 0; i < (TRAMP_SYM_PREFIX_LEN + TRAMP_SYM_HEX_ASCII_LEN); i++)
		*(dst_local + i) = 0;

	/*  Copy the prefix to start */
	for (i = 0; i < strlen(TRAMP_SYM_PREFIX); i++) {
		*dst_local = *(prefix + i);
		dst_local++;
	}

	/*  Now convert the value passed in to a string equiv of the hex */
	for (i = 0; i < sizeof(value); i++) {
#ifndef _BIG_ENDIAN
		tmp = *(((u8 *) &value) + (sizeof(value) - 1) - i);
		*dst_local = priv_h2a((tmp & 0xF0) >> 4);
		dst_local++;
		*dst_local = priv_h2a(tmp & 0x0F);
		dst_local++;
#else
		tmp = *(((u8 *) &value) + i);
		*dst_local = priv_h2a((tmp & 0xF0) >> 4);
		dst_local++;
		*dst_local = priv_h2a(tmp & 0x0F);
		dst_local++;
#endif
	}

	/*  NULL terminate */
	*dst_local = 0;
}

/*
 * Function:	priv_tramp_string_create
 * Description: Create a new string specific to the trampoline loading and add
 *	  it to the trampoline string list.  This list contains the
 *	  trampoline section name and trampoline point symbols.
 */
static struct tramp_string *priv_tramp_string_create(struct dload_state *dlthis,
						     u32 str_len, char *str)
{
	struct tramp_string *new_string = NULL;
	u32 i;

	/*  Create a new string object with the specified size. */
	new_string =
	    (struct tramp_string *)dlthis->mysym->dload_allocate(dlthis->mysym,
								 (sizeof
								  (struct
								   tramp_string)
								  + str_len +
								  1));
	if (new_string != NULL) {
		/*  Clear the string first.  This ensures the ending NULL is
		 * present and the optimizer won't touch it. */
		for (i = 0; i < (sizeof(struct tramp_string) + str_len + 1);
		     i++)
			*((u8 *) new_string + i) = 0;

		/*  Add this string to our virtual table by assigning it the
		 * next index and pushing it to the tail of the list. */
		new_string->index = dlthis->tramp.tramp_string_next_index;
		dlthis->tramp.tramp_string_next_index++;
		dlthis->tramp.tramp_string_size += str_len + 1;

		new_string->next = NULL;
		if (dlthis->tramp.string_head == NULL)
			dlthis->tramp.string_head = new_string;
		else
			dlthis->tramp.string_tail->next = new_string;

		dlthis->tramp.string_tail = new_string;

		/*  Copy the string over to the new object */
		for (i = 0; i < str_len; i++)
			new_string->str[i] = str[i];
	}

	return new_string;
}

/*
 * Function:	priv_tramp_string_find
 * Description: Walk the trampoline string list and find a match for the
 *	  provided string.  If not match is found, NULL is returned.
 */
static struct tramp_string *priv_tramp_string_find(struct dload_state *dlthis,
						   char *str)
{
	struct tramp_string *cur_str = NULL;
	struct tramp_string *ret_val = NULL;
	u32 i;
	u32 str_len = strlen(str);

	for (cur_str = dlthis->tramp.string_head;
	     (ret_val == NULL) && (cur_str != NULL); cur_str = cur_str->next) {
		/*  If the string lengths aren't equal, don't bother
		 * comparing */
		if (str_len != strlen(cur_str->str))
			continue;

		/*  Walk the strings until one of them ends */
		for (i = 0; i < str_len; i++) {
			/*  If they don't match in the current position then
			 * break out now, no sense in continuing to look at
			 * this string. */
			if (str[i] != cur_str->str[i])
				break;
		}

		if (i == str_len)
			ret_val = cur_str;
	}

	return ret_val;
}

/*
 * Function:	priv_string_tbl_finalize
 * Description: Flatten the trampoline string list into a table of NULL
 *	  terminated strings.  This is the same format of string table
 *	  as used by the COFF/DOFF file.
 */
static int priv_string_tbl_finalize(struct dload_state *dlthis)
{
	int ret_val = 0;
	struct tramp_string *cur_string;
	char *cur_loc;
	char *tmp;

	/*  Allocate enough space for all strings that have been created.  The
	 * table is simply all strings concatenated together will NULL
	 * endings. */
	dlthis->tramp.final_string_table =
	    (char *)dlthis->mysym->dload_allocate(dlthis->mysym,
						  dlthis->tramp.
						  tramp_string_size);
	if (dlthis->tramp.final_string_table != NULL) {
		/*  We got our buffer, walk the list and release the nodes as*
		 * we go */
		cur_loc = dlthis->tramp.final_string_table;
		cur_string = dlthis->tramp.string_head;
		while (cur_string != NULL) {
			/*  Move the head/tail pointers */
			dlthis->tramp.string_head = cur_string->next;
			if (dlthis->tramp.string_tail == cur_string)
				dlthis->tramp.string_tail = NULL;

			/*  Copy the string contents */
			for (tmp = cur_string->str;
			     *tmp != '\0'; tmp++, cur_loc++)
				*cur_loc = *tmp;

			/*  Pick up the NULL termination since it was missed by
			 * breaking using it to end the above loop. */
			*cur_loc = '\0';
			cur_loc++;

			/*  Free the string node, we don't need it any more. */
			dlthis->mysym->dload_deallocate(dlthis->mysym,
							cur_string);

			/*  Move our pointer to the next one */
			cur_string = dlthis->tramp.string_head;
		}

		/*  Update our return value to success */
		ret_val = 1;
	} else
		dload_error(dlthis, "Failed to allocate trampoline "
			    "string table");

	return ret_val;
}

/*
 * Function:	priv_tramp_sect_alloc
 * Description: Virtually allocate space from the trampoline section.  This
 *	  function returns the next offset within the trampoline section
 *	  that is available and moved the next available offset by the
 *	  requested size.  NO TARGET ALLOCATION IS DONE AT THIS TIME.
 */
static u32 priv_tramp_sect_alloc(struct dload_state *dlthis, u32 tramp_size)
{
	u32 ret_val;

	/*  If the next available address is 0, this is our first allocation.
	 * Create a section name string to go into the string table . */
	if (dlthis->tramp.tramp_sect_next_addr == 0) {
		dload_syms_error(dlthis->mysym, "*** WARNING ***  created "
				 "dynamic TRAMPOLINE section for module %s",
				 dlthis->str_head);
	}

	/*  Reserve space for the new trampoline */
	ret_val = dlthis->tramp.tramp_sect_next_addr;
	dlthis->tramp.tramp_sect_next_addr += tramp_size;
	return ret_val;
}

/*
 * Function:	priv_tramp_sym_create
 * Description: Allocate and create a new trampoline specific symbol and add
 *	  it to the trampoline symbol list.  These symbols will include
 *	  trampoline points as well as the external symbols they
 *	  reference.
 */
static struct tramp_sym *priv_tramp_sym_create(struct dload_state *dlthis,
					       u32 str_index,
					       struct local_symbol *tmp_sym)
{
	struct tramp_sym *new_sym = NULL;
	u32 i;

	/*  Allocate new space for the symbol in the symbol table. */
	new_sym =
	    (struct tramp_sym *)dlthis->mysym->dload_allocate(dlthis->mysym,
					      sizeof(struct tramp_sym));
	if (new_sym != NULL) {
		for (i = 0; i != sizeof(struct tramp_sym); i++)
			*((char *)new_sym + i) = 0;

		/*  Assign this symbol the next symbol index for easier
		 * reference later during relocation. */
		new_sym->index = dlthis->tramp.tramp_sym_next_index;
		dlthis->tramp.tramp_sym_next_index++;

		/*  Populate the symbol information.  At this point any
		 * trampoline symbols will be the offset location, not the
		 * final.  Copy over the symbol info to start, then be sure to
		 * get the string index from the trampoline string table. */
		new_sym->sym_info = *tmp_sym;
		new_sym->str_index = str_index;

		/*  Push the new symbol to the tail of the symbol table list */
		new_sym->next = NULL;
		if (dlthis->tramp.symbol_head == NULL)
			dlthis->tramp.symbol_head = new_sym;
		else
			dlthis->tramp.symbol_tail->next = new_sym;

		dlthis->tramp.symbol_tail = new_sym;
	}

	return new_sym;
}

/*
 * Function:	priv_tramp_sym_get
 * Description: Search for the symbol with the matching string index (from
 *	  the trampoline string table) and return the trampoline
 *	  symbol object, if found.  Otherwise return NULL.
 */
static struct tramp_sym *priv_tramp_sym_get(struct dload_state *dlthis,
					    u32 string_index)
{
	struct tramp_sym *sym_found = NULL;

	/*  Walk the symbol table list and search vs. the string index */
	for (sym_found = dlthis->tramp.symbol_head;
	     sym_found != NULL; sym_found = sym_found->next) {
		if (sym_found->str_index == string_index)
			break;
	}

	return sym_found;
}

/*
 * Function:	priv_tramp_sym_find
 * Description: Search for a trampoline symbol based on the string name of
 *	  the symbol.  Return the symbol object, if found, otherwise
 *	  return NULL.
 */
static struct tramp_sym *priv_tramp_sym_find(struct dload_state *dlthis,
					     char *string)
{
	struct tramp_sym *sym_found = NULL;
	struct tramp_string *str_found = NULL;

	/*  First, search for the string, then search for the sym based on the
	   string index. */
	str_found = priv_tramp_string_find(dlthis, string);
	if (str_found != NULL)
		sym_found = priv_tramp_sym_get(dlthis, str_found->index);

	return sym_found;
}

/*
 * Function:	priv_tramp_sym_finalize
 * Description: Allocate a flat symbol table for the trampoline section,
 *	  put each trampoline symbol into the table, adjust the
 *	  symbol value based on the section address on the target and
 *	  free the trampoline symbol list nodes.
 */
static int priv_tramp_sym_finalize(struct dload_state *dlthis)
{
	int ret_val = 0;
	struct tramp_sym *cur_sym;
	struct ldr_section_info *tramp_sect =
	    &dlthis->ldr_sections[dlthis->allocated_secn_count];
	struct local_symbol *new_sym;

	/*  Allocate a table to hold a flattened version of all symbols
	 * created. */
	dlthis->tramp.final_sym_table =
	    (struct local_symbol *)dlthis->mysym->dload_allocate(dlthis->mysym,
				 (sizeof(struct local_symbol) * dlthis->tramp.
						  tramp_sym_next_index));
	if (dlthis->tramp.final_sym_table != NULL) {
		/*  Walk the list of all symbols, copy it over to the flattened
		 * table. After it has been copied, the node can be freed as
		 * it is no longer needed. */
		new_sym = dlthis->tramp.final_sym_table;
		cur_sym = dlthis->tramp.symbol_head;
		while (cur_sym != NULL) {
			/*  Pop it off the list */
			dlthis->tramp.symbol_head = cur_sym->next;
			if (cur_sym == dlthis->tramp.symbol_tail)
				dlthis->tramp.symbol_tail = NULL;

			/*  Copy the symbol contents into the flat table */
			*new_sym = cur_sym->sym_info;

			/*  Now finaize the symbol.  If it is in the tramp
			 * section, we need to adjust for the section start.
			 * If it is external then we don't need to adjust at
			 * all.
			 * NOTE: THIS CODE ASSUMES THAT THE TRAMPOLINE IS
			 * REFERENCED LIKE A CALL TO AN EXTERNAL SO VALUE AND
			 * DELTA ARE THE SAME.  SEE THE FUNCTION dload_symbols
			 * WHERE DN_UNDEF IS HANDLED FOR MORE REFERENCE. */
			if (new_sym->secnn < 0) {
				new_sym->value += tramp_sect->load_addr;
				new_sym->delta = new_sym->value;
			}

			/*  Let go of the symbol node */
			dlthis->mysym->dload_deallocate(dlthis->mysym, cur_sym);

			/*  Move to the next node */
			cur_sym = dlthis->tramp.symbol_head;
			new_sym++;
		}

		ret_val = 1;
	} else
		dload_error(dlthis, "Failed to alloc trampoline sym table");

	return ret_val;
}

/*
 * Function:	priv_tgt_img_gen
 * Description: Allocate storage for and copy the target specific image data
 *	and fix up its relocations for the new external symbol.  If
 *	a trampoline image packet was successfully created it is added
 *	to the trampoline list.
 */
static int priv_tgt_img_gen(struct dload_state *dlthis, u32 base,
			    u32 gen_index, struct tramp_sym *new_ext_sym)
{
	struct tramp_img_pkt *new_img_pkt = NULL;
	u32 i;
	u32 pkt_size = tramp_img_pkt_size_get();
	u8 *gen_tbl_entry;
	u8 *pkt_data;
	struct reloc_record_t *cur_relo;
	int ret_val = 0;

	/*  Allocate a new image packet and set it up. */
	new_img_pkt =
	    (struct tramp_img_pkt *)dlthis->mysym->dload_allocate(dlthis->mysym,
								  pkt_size);
	if (new_img_pkt != NULL) {
		/*  Save the base, this is where it goes in the section */
		new_img_pkt->base = base;

		/*  Copy over the image data and relos from the target table */
		pkt_data = (u8 *) &new_img_pkt->hdr;
		gen_tbl_entry = (u8 *) &tramp_gen_info[gen_index];
		for (i = 0; i < pkt_size; i++) {
			*pkt_data = *gen_tbl_entry;
			pkt_data++;
			gen_tbl_entry++;
		}

		/*  Update the relocations to point to the external symbol */
		cur_relo =
		    (struct reloc_record_t *)((u8 *) &new_img_pkt->hdr +
					      new_img_pkt->hdr.relo_offset);
		for (i = 0; i < new_img_pkt->hdr.num_relos; i++)
			cur_relo[i].SYMNDX = new_ext_sym->index;

		/*  Add it to the trampoline list. */
		new_img_pkt->next = dlthis->tramp.tramp_pkts;
		dlthis->tramp.tramp_pkts = new_img_pkt;

		ret_val = 1;
	}

	return ret_val;
}

/*
 * Function:	priv_pkt_relo
 * Description: Take the provided image data and the collection of relocations
 *	  for it and perform the relocations.  Note that all relocations
 *	  at this stage are considered SECOND PASS since the original
 *	  image has already been processed in the first pass.  This means
 *	  TRAMPOLINES ARE TREATED AS 2ND PASS even though this is really
 *	  the first (and only) relocation that will be performed on them.
 */
static int priv_pkt_relo(struct dload_state *dlthis, tgt_au_t * data,
			 struct reloc_record_t *rp[], u32 relo_count)
{
	int ret_val = 1;
	u32 i;
	bool tmp;

	/*  Walk through all of the relos and process them.  This function is
	 * the equivalent of relocate_packet() from cload.c, but specialized
	 * for trampolines and 2nd phase relocations. */
	for (i = 0; i < relo_count; i++)
		dload_relocate(dlthis, data, rp[i], &tmp, true);

	return ret_val;
}

/*
 * Function:	priv_tramp_pkt_finalize
 * Description: Walk the list of all trampoline packets and finalize them.
 *	  Each trampoline image packet will be relocated now that the
 *	  trampoline section has been allocated on the target.  Once
 *	  all of the relocations are done the trampoline image data
 *	  is written into target memory and the trampoline packet
 *	  is freed: it is no longer needed after this point.
 */
static int priv_tramp_pkt_finalize(struct dload_state *dlthis)
{
	int ret_val = 1;
	struct tramp_img_pkt *cur_pkt = NULL;
	struct reloc_record_t *relos[MAX_RELOS_PER_PASS];
	u32 relos_done;
	u32 i;
	struct reloc_record_t *cur_relo;
	struct ldr_section_info *sect_info =
	    &dlthis->ldr_sections[dlthis->allocated_secn_count];

	/*  Walk the list of trampoline packets and relocate each packet.  This
	 * function is the trampoline equivalent of dload_data() from
	 * cload.c. */
	cur_pkt = dlthis->tramp.tramp_pkts;
	while ((ret_val != 0) && (cur_pkt != NULL)) {
		/*  Remove the pkt from the list */
		dlthis->tramp.tramp_pkts = cur_pkt->next;

		/*  Setup section and image offset information for the relo */
		dlthis->image_secn = sect_info;
		dlthis->image_offset = cur_pkt->base;
		dlthis->delta_runaddr = sect_info->run_addr;

		/*  Walk through all relos for the packet */
		relos_done = 0;
		cur_relo = (struct reloc_record_t *)((u8 *) &cur_pkt->hdr +
						     cur_pkt->hdr.relo_offset);
		while (relos_done < cur_pkt->hdr.num_relos) {
#ifdef ENABLE_TRAMP_DEBUG
			dload_syms_error(dlthis->mysym,
					 "===> Trampoline %x branches to %x",
					 sect_info->run_addr +
					 dlthis->image_offset,
					 dlthis->
					 tramp.final_sym_table[cur_relo->
							       SYMNDX].value);
#endif

			for (i = 0;
			     ((i < MAX_RELOS_PER_PASS) &&
			      ((i + relos_done) < cur_pkt->hdr.num_relos)); i++)
				relos[i] = cur_relo + i;

			/*  Do the actual relo */
			ret_val = priv_pkt_relo(dlthis,
						(tgt_au_t *) &cur_pkt->payload,
						relos, i);
			if (ret_val == 0) {
				dload_error(dlthis,
					    "Relocation of trampoline pkt at %x"
					    " failed", cur_pkt->base +
					    sect_info->run_addr);
				break;
			}

			relos_done += i;
			cur_relo += i;
		}

		/*  Make sure we didn't hit a problem */
		if (ret_val != 0) {
			/*  Relos are done for the packet, write it to the
			 * target */
			ret_val = dlthis->myio->writemem(dlthis->myio,
							 &cur_pkt->payload,
							 sect_info->load_addr +
							 cur_pkt->base,
							 sect_info,
							 BYTE_TO_HOST
							 (cur_pkt->hdr.
							  tramp_code_size));
			if (ret_val == 0) {
				dload_error(dlthis,
					    "Write to " FMT_UI32 " failed",
					    sect_info->load_addr +
					    cur_pkt->base);
			}

			/*  Done with the pkt, let it go */
			dlthis->mysym->dload_deallocate(dlthis->mysym, cur_pkt);

			/*  Get the next packet to process */
			cur_pkt = dlthis->tramp.tramp_pkts;
		}
	}

	return ret_val;
}

/*
 * Function:	priv_dup_pkt_finalize
 * Description: Walk the list of duplicate image packets and finalize them.
 *	  Each duplicate packet will be relocated again for the
 *	  relocations that previously failed and have been adjusted
 *	  to point at a trampoline.  Once all relocations for a packet
 *	  have been done, write the packet into target memory.  The
 *	  duplicate packet and its relocation chain are all freed
 *	  after use here as they are no longer needed after this.
 */
static int priv_dup_pkt_finalize(struct dload_state *dlthis)
{
	int ret_val = 1;
	struct tramp_img_dup_pkt *cur_pkt;
	struct tramp_img_dup_relo *cur_relo;
	struct reloc_record_t *relos[MAX_RELOS_PER_PASS];
	struct doff_scnhdr_t *sect_hdr = NULL;
	s32 i;

	/* Similar to the trampoline pkt finalize, this function walks each dup
	 * pkt that was generated and performs all relocations that were
	 * deferred to a 2nd pass.  This is the equivalent of dload_data() from
	 * cload.c, but does not need the additional reorder and checksum
	 * processing as it has already been done. */
	cur_pkt = dlthis->tramp.dup_pkts;
	while ((ret_val != 0) && (cur_pkt != NULL)) {
		/*  Remove the node from the list, we'll be freeing it
		 * shortly */
		dlthis->tramp.dup_pkts = cur_pkt->next;

		/*  Setup the section and image offset for relocation */
		dlthis->image_secn = &dlthis->ldr_sections[cur_pkt->secnn];
		dlthis->image_offset = cur_pkt->offset;

		/*  In order to get the delta run address, we need to reference
		 * the original section header.  It's a bit ugly, but needed
		 * for relo. */
		i = (s32) (dlthis->image_secn - dlthis->ldr_sections);
		sect_hdr = dlthis->sect_hdrs + i;
		dlthis->delta_runaddr = sect_hdr->ds_paddr;

		/*  Walk all relos in the chain and process each. */
		cur_relo = cur_pkt->relo_chain;
		while (cur_relo != NULL) {
			/*  Process them a chunk at a time to be efficient */
			for (i = 0; (i < MAX_RELOS_PER_PASS)
			     && (cur_relo != NULL);
			     i++, cur_relo = cur_relo->next) {
				relos[i] = &cur_relo->relo;
				cur_pkt->relo_chain = cur_relo->next;
			}

			/*  Do the actual relo */
			ret_val = priv_pkt_relo(dlthis,
						cur_pkt->img_pkt.img_data,
						relos, i);
			if (ret_val == 0) {
				dload_error(dlthis,
					    "Relocation of dup pkt at %x"
					    " failed", cur_pkt->offset +
					    dlthis->image_secn->run_addr);
				break;
			}

			/*  Release all of these relos, we're done with them */
			while (i > 0) {
				dlthis->mysym->dload_deallocate(dlthis->mysym,
						GET_CONTAINER
						(relos[i - 1],
						 struct tramp_img_dup_relo,
						 relo));
				i--;
			}

			/*  DO NOT ADVANCE cur_relo, IT IS ALREADY READY TO
			 * GO! */
		}

		/* Done with all relos.  Make sure we didn't have a problem and
		 * write it out to the target */
		if (ret_val != 0) {
			ret_val = dlthis->myio->writemem(dlthis->myio,
							 cur_pkt->img_pkt.
							 img_data,
							 dlthis->image_secn->
							 load_addr +
							 cur_pkt->offset,
							 dlthis->image_secn,
							 BYTE_TO_HOST
							 (cur_pkt->img_pkt.
							  packet_size));
			if (ret_val == 0) {
				dload_error(dlthis,
					    "Write to " FMT_UI32 " failed",
					    dlthis->image_secn->load_addr +
					    cur_pkt->offset);
			}

			dlthis->mysym->dload_deallocate(dlthis->mysym, cur_pkt);

			/*  Advance to the next packet */
			cur_pkt = dlthis->tramp.dup_pkts;
		}
	}

	return ret_val;
}

/*
 * Function:	priv_dup_find
 * Description: Walk the list of existing duplicate packets and find a
 *	  match based on the section number and image offset.  Return
 *	  the duplicate packet if found, otherwise NULL.
 */
static struct tramp_img_dup_pkt *priv_dup_find(struct dload_state *dlthis,
					       s16 secnn, u32 image_offset)
{
	struct tramp_img_dup_pkt *cur_pkt = NULL;

	for (cur_pkt = dlthis->tramp.dup_pkts;
	     cur_pkt != NULL; cur_pkt = cur_pkt->next) {
		if ((cur_pkt->secnn == secnn) &&
		    (cur_pkt->offset == image_offset)) {
			/*  Found a match, break out */
			break;
		}
	}

	return cur_pkt;
}

/*
 * Function:	priv_img_pkt_dup
 * Description: Duplicate the original image packet.  If this is the first
 *	  time this image packet has been seen (based on section number
 *	  and image offset), create a new duplicate packet and add it
 *	  to the dup packet list.  If not, just get the existing one and
 *	  update it with the current packet contents (since relocation
 *	  on the packet is still ongoing in first pass.)  Create a
 *	  duplicate of the provided relocation, but update it to point
 *	  to the new trampoline symbol.  Add the new relocation dup to
 *	  the dup packet's relo chain for 2nd pass relocation later.
 */
static int priv_img_pkt_dup(struct dload_state *dlthis,
			    s16 secnn, u32 image_offset,
			    struct image_packet_t *ipacket,
			    struct reloc_record_t *rp,
			    struct tramp_sym *new_tramp_sym)
{
	struct tramp_img_dup_pkt *dup_pkt = NULL;
	u32 new_dup_size;
	s32 i;
	int ret_val = 0;
	struct tramp_img_dup_relo *dup_relo = NULL;

	/*  Determinne if this image packet is already being tracked in the
	   dup list for other trampolines. */
	dup_pkt = priv_dup_find(dlthis, secnn, image_offset);

	if (dup_pkt == NULL) {
		/*  This image packet does not exist in our tracking, so create
		 * a new one and add it to the head of the list. */
		new_dup_size = sizeof(struct tramp_img_dup_pkt) +
		    ipacket->packet_size;

		dup_pkt = (struct tramp_img_dup_pkt *)
		    dlthis->mysym->dload_allocate(dlthis->mysym, new_dup_size);
		if (dup_pkt != NULL) {
			/*  Save off the section and offset information */
			dup_pkt->secnn = secnn;
			dup_pkt->offset = image_offset;
			dup_pkt->relo_chain = NULL;

			/*  Copy the original packet content */
			dup_pkt->img_pkt = *ipacket;
			dup_pkt->img_pkt.img_data = (u8 *) (dup_pkt + 1);
			for (i = 0; i < ipacket->packet_size; i++)
				*(dup_pkt->img_pkt.img_data + i) =
				    *(ipacket->img_data + i);

			/*  Add the packet to the dup list */
			dup_pkt->next = dlthis->tramp.dup_pkts;
			dlthis->tramp.dup_pkts = dup_pkt;
		} else
			dload_error(dlthis, "Failed to create dup packet!");
	} else {
		/*  The image packet contents could have changed since
		 * trampoline detection happens during relocation of the image
		 * packets.  So, we need to update the image packet contents
		 * before adding relo information. */
		for (i = 0; i < dup_pkt->img_pkt.packet_size; i++)
			*(dup_pkt->img_pkt.img_data + i) =
			    *(ipacket->img_data + i);
	}

	/*  Since the previous code may have allocated a new dup packet for us,
	   double check that we actually have one. */
	if (dup_pkt != NULL) {
		/*  Allocate a new node for the relo chain.  Each image packet
		 * can potentially have multiple relocations that cause a
		 * trampoline to be generated.  So, we keep them in a chain,
		 * order is not important. */
		dup_relo = dlthis->mysym->dload_allocate(dlthis->mysym,
					 sizeof(struct tramp_img_dup_relo));
		if (dup_relo != NULL) {
			/*  Copy the relo contents, adjust for the new
			 * trampoline and add it to the list. */
			dup_relo->relo = *rp;
			dup_relo->relo.SYMNDX = new_tramp_sym->index;

			dup_relo->next = dup_pkt->relo_chain;
			dup_pkt->relo_chain = dup_relo;

			/*  That's it, we're done.  Make sure we update our
			 * return value to be success since everything finished
			 * ok */
			ret_val = 1;
		} else
			dload_error(dlthis, "Unable to alloc dup relo");
	}

	return ret_val;
}

/*
 * Function:	dload_tramp_avail
 * Description: Check to see if the target supports a trampoline for this type
 *	  of relocation.  Return true if it does, otherwise false.
 */
bool dload_tramp_avail(struct dload_state *dlthis, struct reloc_record_t *rp)
{
	bool ret_val = false;
	u16 map_index;
	u16 gen_index;

	/*  Check type hash vs. target tramp table */
	map_index = HASH_FUNC(rp->TYPE);
	gen_index = tramp_map[map_index];
	if (gen_index != TRAMP_NO_GEN_AVAIL)
		ret_val = true;

	return ret_val;
}

/*
 * Function:	dload_tramp_generate
 * Description: Create a new trampoline for the provided image packet and
 *	  relocation causing problems.  This will create the trampoline
 *	  as well as duplicate/update the image packet and relocation
 *	  causing the problem, which will be relo'd again during
 *	  finalization.
 */
int dload_tramp_generate(struct dload_state *dlthis, s16 secnn,
			 u32 image_offset, struct image_packet_t *ipacket,
			 struct reloc_record_t *rp)
{
	u16 map_index;
	u16 gen_index;
	int ret_val = 1;
	char tramp_sym_str[TRAMP_SYM_PREFIX_LEN + TRAMP_SYM_HEX_ASCII_LEN];
	struct local_symbol *ref_sym;
	struct tramp_sym *new_tramp_sym;
	struct tramp_sym *new_ext_sym;
	struct tramp_string *new_tramp_str;
	u32 new_tramp_base;
	struct local_symbol tmp_sym;
	struct local_symbol ext_tmp_sym;

	/*  Hash the relo type to get our generator information */
	map_index = HASH_FUNC(rp->TYPE);
	gen_index = tramp_map[map_index];
	if (gen_index != TRAMP_NO_GEN_AVAIL) {
		/*  If this is the first trampoline, create the section name in
		 * our string table for debug help later. */
		if (dlthis->tramp.string_head == NULL) {
			priv_tramp_string_create(dlthis,
						 strlen(TRAMP_SECT_NAME),
						 TRAMP_SECT_NAME);
		}
#ifdef ENABLE_TRAMP_DEBUG
		dload_syms_error(dlthis->mysym,
				 "Trampoline at img loc %x, references %x",
				 dlthis->ldr_sections[secnn].run_addr +
				 image_offset + rp->vaddr,
				 dlthis->local_symtab[rp->SYMNDX].value);
#endif

		/*  Generate the trampoline string, check if already defined.
		 * If the relo symbol index is -1, it means we need the section
		 * info for relo later.  To do this we'll dummy up a symbol
		 * with the section delta and run addresses. */
		if (rp->SYMNDX == -1) {
			ext_tmp_sym.value =
			    dlthis->ldr_sections[secnn].run_addr;
			ext_tmp_sym.delta = dlthis->sect_hdrs[secnn].ds_paddr;
			ref_sym = &ext_tmp_sym;
		} else
			ref_sym = &(dlthis->local_symtab[rp->SYMNDX]);

		priv_tramp_sym_gen_name(ref_sym->value, tramp_sym_str);
		new_tramp_sym = priv_tramp_sym_find(dlthis, tramp_sym_str);
		if (new_tramp_sym == NULL) {
			/*  If tramp string not defined, create it and a new
			 * string, and symbol for it as well as the original
			 * symbol which caused the trampoline. */
			new_tramp_str = priv_tramp_string_create(dlthis,
								strlen
								(tramp_sym_str),
								 tramp_sym_str);
			if (new_tramp_str == NULL) {
				dload_error(dlthis, "Failed to create new "
					    "trampoline string\n");
				ret_val = 0;
			} else {
				/*  Allocate tramp section space for the new
				 * tramp from the target */
				new_tramp_base = priv_tramp_sect_alloc(dlthis,
						       tramp_size_get());

				/*  We have a string, create the new symbol and
				 * duplicate the external. */
				tmp_sym.value = new_tramp_base;
				tmp_sym.delta = 0;
				tmp_sym.secnn = -1;
				tmp_sym.sclass = 0;
				new_tramp_sym = priv_tramp_sym_create(dlthis,
							      new_tramp_str->
							      index,
							      &tmp_sym);

				new_ext_sym = priv_tramp_sym_create(dlthis, -1,
								    ref_sym);

				if ((new_tramp_sym != NULL) &&
				    (new_ext_sym != NULL)) {
					/*  Call the image generator to get the
					 * new image data and fix up its
					 * relocations for the external
					 * symbol. */
					ret_val = priv_tgt_img_gen(dlthis,
								 new_tramp_base,
								 gen_index,
								 new_ext_sym);

					/*  Add generated image data to tramp
					 * image list */
					if (ret_val != 1) {
						dload_error(dlthis, "Failed to "
							    "create img pkt for"
							    " trampoline\n");
					}
				} else {
					dload_error(dlthis, "Failed to create "
						    "new tramp syms "
						    "(%8.8X, %8.8X)\n",
						    new_tramp_sym, new_ext_sym);
					ret_val = 0;
				}
			}
		}

		/*  Duplicate the image data and relo record that caused the
		 * tramp, including update the relo data to point to the tramp
		 * symbol. */
		if (ret_val == 1) {
			ret_val = priv_img_pkt_dup(dlthis, secnn, image_offset,
						   ipacket, rp, new_tramp_sym);
			if (ret_val != 1) {
				dload_error(dlthis, "Failed to create dup of "
					    "original img pkt\n");
			}
		}
	}

	return ret_val;
}

/*
 * Function:	dload_tramp_pkt_update
 * Description: Update the duplicate copy of this image packet, which the
 *	  trampoline layer is already tracking.  This is call is critical
 *	  to make if trampolines were generated anywhere within the
 *	  packet and first pass relo continued on the remainder.  The
 *	  trampoline layer needs the updates image data so when 2nd
 *	  pass relo is done during finalize the image packet can be
 *	  written to the target since all relo is done.
 */
int dload_tramp_pkt_udpate(struct dload_state *dlthis, s16 secnn,
			   u32 image_offset, struct image_packet_t *ipacket)
{
	struct tramp_img_dup_pkt *dup_pkt = NULL;
	s32 i;
	int ret_val = 0;

	/*  Find the image packet in question, the caller needs us to update it
	   since a trampoline was previously generated. */
	dup_pkt = priv_dup_find(dlthis, secnn, image_offset);
	if (dup_pkt != NULL) {
		for (i = 0; i < dup_pkt->img_pkt.packet_size; i++)
			*(dup_pkt->img_pkt.img_data + i) =
			    *(ipacket->img_data + i);

		ret_val = 1;
	} else {
		dload_error(dlthis,
			    "Unable to find existing DUP pkt for %x, offset %x",
			    secnn, image_offset);

	}

	return ret_val;
}

/*
 * Function:	dload_tramp_finalize
 * Description: If any trampolines were created, finalize everything on the
 *	  target by allocating the trampoline section on the target,
 *	  finalizing the trampoline symbols, finalizing the trampoline
 *	  packets (write the new section to target memory) and finalize
 *	  the duplicate packets by doing 2nd pass relo over them.
 */
int dload_tramp_finalize(struct dload_state *dlthis)
{
	int ret_val = 1;

	if (dlthis->tramp.tramp_sect_next_addr != 0) {
		/*  Finalize strings into a flat table.  This is needed so it
		 * can be added to the debug string table later. */
		ret_val = priv_string_tbl_finalize(dlthis);

		/*  Do target allocation for section BEFORE finalizing
		 * symbols. */
		if (ret_val != 0)
			ret_val = priv_tramp_sect_tgt_alloc(dlthis);

		/*  Finalize symbols with their correct target information and
		 * flatten */
		if (ret_val != 0)
			ret_val = priv_tramp_sym_finalize(dlthis);

		/*  Finalize all trampoline packets.  This performs the
		 * relocation on the packets as well as writing them to target
		 * memory. */
		if (ret_val != 0)
			ret_val = priv_tramp_pkt_finalize(dlthis);

		/*  Perform a 2nd pass relocation on the dup list. */
		if (ret_val != 0)
			ret_val = priv_dup_pkt_finalize(dlthis);
	}

	return ret_val;
}

/*
 * Function:	dload_tramp_cleanup
 * Description: Release all temporary resources used in the trampoline layer.
 *	  Note that the target memory which may have been allocated and
 *	  written to store the trampolines is NOT RELEASED HERE since it
 *	  is potentially still in use.  It is automatically released
 *	  when the module is unloaded.
 */
void dload_tramp_cleanup(struct dload_state *dlthis)
{
	struct tramp_info *tramp = &dlthis->tramp;
	struct tramp_sym *cur_sym;
	struct tramp_string *cur_string;
	struct tramp_img_pkt *cur_tramp_pkt;
	struct tramp_img_dup_pkt *cur_dup_pkt;
	struct tramp_img_dup_relo *cur_dup_relo;

	/*  If there were no tramps generated, just return */
	if (tramp->tramp_sect_next_addr == 0)
		return;

	/*  Destroy all tramp information */
	for (cur_sym = tramp->symbol_head;
	     cur_sym != NULL; cur_sym = tramp->symbol_head) {
		tramp->symbol_head = cur_sym->next;
		if (tramp->symbol_tail == cur_sym)
			tramp->symbol_tail = NULL;

		dlthis->mysym->dload_deallocate(dlthis->mysym, cur_sym);
	}

	if (tramp->final_sym_table != NULL)
		dlthis->mysym->dload_deallocate(dlthis->mysym,
						tramp->final_sym_table);

	for (cur_string = tramp->string_head;
	     cur_string != NULL; cur_string = tramp->string_head) {
		tramp->string_head = cur_string->next;
		if (tramp->string_tail == cur_string)
			tramp->string_tail = NULL;

		dlthis->mysym->dload_deallocate(dlthis->mysym, cur_string);
	}

	if (tramp->final_string_table != NULL)
		dlthis->mysym->dload_deallocate(dlthis->mysym,
						tramp->final_string_table);

	for (cur_tramp_pkt = tramp->tramp_pkts;
	     cur_tramp_pkt != NULL; cur_tramp_pkt = tramp->tramp_pkts) {
		tramp->tramp_pkts = cur_tramp_pkt->next;
		dlthis->mysym->dload_deallocate(dlthis->mysym, cur_tramp_pkt);
	}

	for (cur_dup_pkt = tramp->dup_pkts;
	     cur_dup_pkt != NULL; cur_dup_pkt = tramp->dup_pkts) {
		tramp->dup_pkts = cur_dup_pkt->next;

		for (cur_dup_relo = cur_dup_pkt->relo_chain;
		     cur_dup_relo != NULL;
		     cur_dup_relo = cur_dup_pkt->relo_chain) {
			cur_dup_pkt->relo_chain = cur_dup_relo->next;
			dlthis->mysym->dload_deallocate(dlthis->mysym,
							cur_dup_relo);
		}

		dlthis->mysym->dload_deallocate(dlthis->mysym, cur_dup_pkt);
	}
}
