Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | /*
* dload_internal.h
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Copyright (C) 2005-2006 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.
*/
#ifndef _DLOAD_INTERNAL_
#define _DLOAD_INTERNAL_
#include <linux/types.h>
/*
* Internal state definitions for the dynamic loader
*/
/* type used for relocation intermediate results */
typedef s32 rvalue;
/* unsigned version of same; must have at least as many bits */
typedef u32 urvalue;
/*
* Dynamic loader configuration constants
*/
/* error issued if input has more sections than this limit */
#define REASONABLE_SECTION_LIMIT 100
/* (Addressable unit) value used to clear BSS section */
#define DLOAD_FILL_BSS 0
/*
* Reorder maps explained (?)
*
* The doff file format defines a 32-bit pattern used to determine the
* byte order of an image being read. That value is
* BYTE_RESHUFFLE_VALUE == 0x00010203
* For purposes of the reorder routine, we would rather have the all-is-OK
* for 32-bits pattern be 0x03020100. This first macro makes the
* translation from doff file header value to MAP value: */
#define REORDER_MAP(rawmap) ((rawmap) ^ 0x3030303)
/* This translation is made in dload_headers. Thereafter, the all-is-OK
* value for the maps stored in dlthis is REORDER_MAP(BYTE_RESHUFFLE_VALUE).
* But sadly, not all bits of the doff file are 32-bit integers.
* The notable exceptions are strings and image bits.
* Strings obey host byte order: */
#if defined(_BIG_ENDIAN)
#define HOST_BYTE_ORDER(cookedmap) ((cookedmap) ^ 0x3030303)
#else
#define HOST_BYTE_ORDER(cookedmap) (cookedmap)
#endif
/* Target bits consist of target AUs (could be bytes, or 16-bits,
* or 32-bits) stored as an array in host order. A target order
* map is defined by: */
#if !defined(_BIG_ENDIAN) || TARGET_AU_BITS > 16
#define TARGET_ORDER(cookedmap) (cookedmap)
#elif TARGET_AU_BITS > 8
#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x2020202)
#else
#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x3030303)
#endif
/* forward declaration for handle returned by dynamic loader */
struct my_handle;
/*
* a list of module handles, which mirrors the debug list on the target
*/
struct dbg_mirror_root {
/* must be same as dbg_mirror_list; __DLModules address on target */
u32 dbthis;
struct my_handle *next; /* must be same as dbg_mirror_list */
u16 changes; /* change counter */
u16 refcount; /* number of modules referencing this root */
};
struct dbg_mirror_list {
u32 dbthis;
struct my_handle *next, *prev;
struct dbg_mirror_root *root;
u16 dbsiz;
u32 context; /* Save context for .dllview memory allocation */
};
#define VARIABLE_SIZE 1
/*
* the structure we actually return as an opaque module handle
*/
struct my_handle {
struct dbg_mirror_list dm; /* !!! must be first !!! */
/* sections following << 1, LSB is set for big-endian target */
u16 secn_count;
struct ldr_section_info secns[VARIABLE_SIZE];
};
#define MY_HANDLE_SIZE (sizeof(struct my_handle) -\
sizeof(struct ldr_section_info))
/* real size of my_handle */
/*
* reduced symbol structure used for symbols during relocation
*/
struct local_symbol {
s32 value; /* Relocated symbol value */
s32 delta; /* Original value in input file */
s16 secnn; /* section number */
s16 sclass; /* symbol class */
};
/*
* Trampoline data structures
*/
#define TRAMP_NO_GEN_AVAIL 65535
#define TRAMP_SYM_PREFIX "__$dbTR__"
#define TRAMP_SECT_NAME ".dbTR"
/* MUST MATCH THE LENGTH ABOVE!! */
#define TRAMP_SYM_PREFIX_LEN 9
/* Includes NULL termination */
#define TRAMP_SYM_HEX_ASCII_LEN 9
#define GET_CONTAINER(ptr, type, field) ((type *)((unsigned long)ptr -\
(unsigned long)(&((type *)0)->field)))
#ifndef FIELD_OFFSET
#define FIELD_OFFSET(type, field) ((unsigned long)(&((type *)0)->field))
#endif
/*
The trampoline code for the target is located in a table called
"tramp_gen_info" with is indexed by looking up the index in the table
"tramp_map". The tramp_map index is acquired using the target
HASH_FUNC on the relocation type that caused the trampoline. Each
trampoline code table entry MUST follow this format:
|----------------------------------------------|
| tramp_gen_code_hdr |
|----------------------------------------------|
| Trampoline image code |
| (the raw instruction code for the target) |
|----------------------------------------------|
| Relocation entries for the image code |
|----------------------------------------------|
This is very similar to how image data is laid out in the DOFF file
itself.
*/
struct tramp_gen_code_hdr {
u32 tramp_code_size; /* in BYTES */
u32 num_relos;
u32 relo_offset; /* in BYTES */
};
struct tramp_img_pkt {
struct tramp_img_pkt *next; /* MUST BE FIRST */
u32 base;
struct tramp_gen_code_hdr hdr;
u8 payload[VARIABLE_SIZE];
};
struct tramp_img_dup_relo {
struct tramp_img_dup_relo *next;
struct reloc_record_t relo;
};
struct tramp_img_dup_pkt {
struct tramp_img_dup_pkt *next; /* MUST BE FIRST */
s16 secnn;
u32 offset;
struct image_packet_t img_pkt;
struct tramp_img_dup_relo *relo_chain;
/* PAYLOAD OF IMG PKT FOLLOWS */
};
struct tramp_sym {
struct tramp_sym *next; /* MUST BE FIRST */
u32 index;
u32 str_index;
struct local_symbol sym_info;
};
struct tramp_string {
struct tramp_string *next; /* MUST BE FIRST */
u32 index;
char str[VARIABLE_SIZE]; /* NULL terminated */
};
struct tramp_info {
u32 tramp_sect_next_addr;
struct ldr_section_info sect_info;
struct tramp_sym *symbol_head;
struct tramp_sym *symbol_tail;
u32 tramp_sym_next_index;
struct local_symbol *final_sym_table;
struct tramp_string *string_head;
struct tramp_string *string_tail;
u32 tramp_string_next_index;
u32 tramp_string_size;
char *final_string_table;
struct tramp_img_pkt *tramp_pkts;
struct tramp_img_dup_pkt *dup_pkts;
};
/*
* States of the .cinit state machine
*/
enum cinit_mode {
CI_COUNT = 0, /* expecting a count */
CI_ADDRESS, /* expecting an address */
#if CINIT_ALIGN < CINIT_ADDRESS /* handle case of partial address field */
CI_PARTADDRESS, /* have only part of the address */
#endif
CI_COPY, /* in the middle of copying data */
CI_DONE /* end of .cinit table */
};
/*
* The internal state of the dynamic loader, which is passed around as
* an object
*/
struct dload_state {
struct dynamic_loader_stream *strm; /* The module input stream */
struct dynamic_loader_sym *mysym; /* Symbols for this session */
/* target memory allocator */
struct dynamic_loader_allocate *myalloc;
struct dynamic_loader_initialize *myio; /* target memory initializer */
unsigned myoptions; /* Options parameter dynamic_load_module */
char *str_head; /* Pointer to string table */
#if BITS_PER_AU > BITS_PER_BYTE
char *str_temp; /* Pointer to temporary buffer for strings */
/* big enough to hold longest string */
unsigned temp_len; /* length of last temporary string */
char *xstrings; /* Pointer to buffer for expanded */
/* strings for sec names */
#endif
/* Total size of strings for DLLView section names */
unsigned debug_string_size;
/* Pointer to parallel section info for allocated sections only */
struct doff_scnhdr_t *sect_hdrs; /* Pointer to section table */
struct ldr_section_info *ldr_sections;
#if TMS32060
/* The address of the start of the .bss section */
ldr_addr bss_run_base;
#endif
struct local_symbol *local_symtab; /* Relocation symbol table */
/* pointer to DL section info for the section being relocated */
struct ldr_section_info *image_secn;
/* change in run address for current section during relocation */
ldr_addr delta_runaddr;
ldr_addr image_offset; /* offset of current packet in section */
enum cinit_mode cinit_state; /* current state of cload_cinit() */
int cinit_count; /* the current count */
ldr_addr cinit_addr; /* the current address */
s16 cinit_page; /* the current page */
/* Handle to be returned by dynamic_load_module */
struct my_handle *myhandle;
unsigned dload_errcount; /* Total # of errors reported so far */
/* Number of target sections that require allocation and relocation */
unsigned allocated_secn_count;
#ifndef TARGET_ENDIANNESS
int big_e_target; /* Target data in big-endian format */
#endif
/* map for reordering bytes, 0 if not needed */
u32 reorder_map;
struct doff_filehdr_t dfile_hdr; /* DOFF file header structure */
struct doff_verify_rec_t verify; /* Verify record */
struct tramp_info tramp; /* Trampoline data, if needed */
int relstkidx; /* index into relocation value stack */
/* relocation value stack used in relexp.c */
rvalue relstk[STATIC_EXPR_STK_SIZE];
};
#ifdef TARGET_ENDIANNESS
#define TARGET_BIG_ENDIAN TARGET_ENDIANNESS
#else
#define TARGET_BIG_ENDIAN (dlthis->big_e_target)
#endif
/*
* Exports from cload.c to rest of the world
*/
extern void dload_error(struct dload_state *dlthis, const char *errtxt, ...);
extern void dload_syms_error(struct dynamic_loader_sym *syms,
const char *errtxt, ...);
extern void dload_headers(struct dload_state *dlthis);
extern void dload_strings(struct dload_state *dlthis, bool sec_names_only);
extern void dload_sections(struct dload_state *dlthis);
extern void dload_reorder(void *data, int dsiz, u32 map);
extern u32 dload_checksum(void *data, unsigned siz);
#if HOST_ENDIANNESS
extern uint32_t dload_reverse_checksum(void *data, unsigned siz);
#if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32)
extern uint32_t dload_reverse_checksum16(void *data, unsigned siz);
#endif
#endif
/*
* exported by reloc.c
*/
extern void dload_relocate(struct dload_state *dlthis, tgt_au_t *data,
struct reloc_record_t *rp, bool *tramps_generated,
bool second_pass);
extern rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t *data,
int fieldsz, int offset, unsigned sgn);
extern int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t *data,
int fieldsz, int offset, unsigned sgn);
/*
* exported by tramp.c
*/
extern bool dload_tramp_avail(struct dload_state *dlthis,
struct reloc_record_t *rp);
int dload_tramp_generate(struct dload_state *dlthis, s16 secnn,
u32 image_offset, struct image_packet_t *ipacket,
struct reloc_record_t *rp);
extern int dload_tramp_pkt_udpate(struct dload_state *dlthis,
s16 secnn, u32 image_offset,
struct image_packet_t *ipacket);
extern int dload_tramp_finalize(struct dload_state *dlthis);
extern void dload_tramp_cleanup(struct dload_state *dlthis);
#endif /* _DLOAD_INTERNAL_ */
|