Subversion Repositories freemyipod

Rev

Rev 449 | Rev 466 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
445 theseven 1
/*
450 theseven 2
 * elf2emcoreapp.c: Convert ELF (or any BFD format) to emCORE executable format
3
 *
4
 * (c) 2011, Michael Sparmann <theseven@gmx.net>
5
 *
6
 * Based on:
445 theseven 7
 * elf2flt.c: Convert ELF (or any BFD format) to FLAT binary format
8
 *
9
 * (c) 1999-2002, Greg Ungerer <gerg@snapgear.com>
10
 * Created elf2flt from coff2flt (see copyrights below). Added all the
11
 * ELF format file handling. Extended relocation support for all of
12
 * text and data.
13
 *
14
 * (c) 2006  Support the -a (use_resolved) option for TARGET_arm.
15
 *           Shaun Jackman <sjackman@gmail.com>
16
 * (c) 2004, Nios II support, Wentao Xu <wentao@microtronix.com>
17
 * (c) 2003, H8 support, ktrace <davidm@snapgear.com>
18
 * (c) 2003-2004, MicroBlaze support, John Williams <jwilliams@itee.uq.edu.au>
19
 * (c) 2001-2003, arm/arm-pic/arm-big-endian support <davidm@snapgear.com>
20
 * (c) 2001, v850 changes, Mile Bader <miles@lsi.nec.co.jp>
21
 * (c) 2003, SuperH support, Paul Mundt <lethal@linux-sh.org>
22
 * (c) 2001, zflat support <davidm@snapgear.com>
23
 * (c) 2001, Changes for GOT entries Paul Dale <pauli@snapgear.com> and
24
 *           David McCullough <davidm@snapgear.com>
25
 *
26
 * Now supports PIC with GOT tables.  This works by taking a '.elf' file
27
 * and a fully linked elf executable (at address 0) and produces a flat
28
 * file that can be loaded with some fixups.  It still supports the old
29
 * style fully relocatable elf format files.
30
 *
31
 * Originally obj-res.c
32
 *
33
 * (c) 1998, Kenneth Albanowski <kjahds@kjahds.com>
34
 * (c) 1998, D. Jeff Dionne
35
 * (c) 1998, The Silver Hammer Group Ltd.
36
 * (c) 1996, 1997 Dionne & Associates <jeff@ryeham.ee.ryerson.ca>
37
 *
38
 * This is Free Software, under the GNU Public Licence v2 or greater.
39
 *
40
 * Relocation added March 1997, Kresten Krab Thorup 
41
 * krab@california.daimi.aau.dk
42
 */
43
 
44
#include <stdio.h>    /* Userland pieces of the ANSI C standard I/O package  */
45
#include <stdlib.h>   /* Userland prototypes of the ANSI C std lib functions */
46
#include <stdarg.h>   /* Allows va_list to exist in the these namespaces     */
47
#include <string.h>   /* Userland prototypes of the string handling funcs    */
48
#include <strings.h>
49
#include <unistd.h>   /* Userland prototypes of the Unix std system calls    */
50
#include <fcntl.h>    /* Flag value for file handling functions              */
51
#include <time.h>
52
 
53
/* from $(INSTALLDIR)/include       */
54
#include <bfd.h>      /* Main header file for the BFD library                */
55
#include <libiberty.h>
56
 
57
#include "stubs.h"
58
const char *elf2flt_progname;
59
 
60
#if defined(TARGET_h8300)
61
#include <elf/h8.h>      /* TARGET_* ELF support for the BFD library            */
62
#elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(TARGET_nios) || defined(TARGET_nios2)
63
#include "cygwin-elf.h"	/* Cygwin uses a local copy */
64
#elif defined(TARGET_microblaze)
65
#include <elf/microblaze.h>	/* TARGET_* ELF support for the BFD library */
66
#else
67
#include <elf.h>      /* TARGET_* ELF support for the BFD library            */
68
#endif
69
 
70
/* Always include Blackfin-specific defines in addition to common ELF stuff
71
 * above as the common elf headers often do not have our relocs.
72
 */
73
#if defined(TARGET_bfin) && !defined(R_BFIN_RIMM16)
74
#include "elf/bfin.h"
75
#endif
76
 
77
#if defined(__MINGW32__)
78
#include <getopt.h>
79
#endif
80
 
450 theseven 81
#define _TOOL
82
#include "../../emcore/trunk/execimage.h"
445 theseven 83
#include "compress.h"
84
 
85
#ifdef TARGET_e1
86
#include <e1.h>
87
#endif
88
 
89
#ifdef TARGET_v850e
90
#define TARGET_v850
91
#endif
92
 
93
#if defined(TARGET_m68k)
94
#define	ARCH	"m68k/coldfire"
95
#elif defined(TARGET_arm)
96
#define	ARCH	"arm"
97
#elif defined(TARGET_sparc)
98
#define	ARCH	"sparc"
99
#elif defined(TARGET_v850)
100
#define	ARCH	"v850"
101
#elif defined(TARGET_sh)
102
#define	ARCH	"sh"
103
#elif defined(TARGET_h8300)
104
#define	ARCH	"h8300"
105
#elif defined(TARGET_microblaze)
106
#define ARCH	"microblaze"
107
#elif defined(TARGET_e1)
108
#define ARCH    "e1-coff"
109
#elif defined(TARGET_bfin)
110
#define ARCH	"bfin"
111
#elif defined(TARGET_nios)
112
#define ARCH	"nios"
113
#elif defined(TARGET_nios2)
114
#define ARCH	"nios2"
115
#else
116
#error "Don't know how to support your CPU architecture??"
117
#endif
118
 
450 theseven 119
#ifndef R_ARM_V4BX
120
#define R_ARM_V4BX 40
121
#endif
122
#ifndef R_ARM_JUMP24
123
#define R_ARM_JUMP24 29
124
#endif
125
 
445 theseven 126
#if defined(TARGET_m68k) || defined(TARGET_h8300) || defined(TARGET_bfin)
127
/*
128
 * Define a maximum number of bytes allowed in the offset table.
129
 * We'll fail if the table is larger than this.
130
 *
131
 * This limit may be different for platforms other than m68k, but
132
 * 8000 entries is a lot,  trust me :-) (davidm)
133
 */
134
#define GOT_LIMIT 32767
135
/*
136
 * we have to mask out the shared library id here and there,  this gives
137
 * us the real address bits when needed
138
 */
139
#define	real_address_bits(x)	(pic_with_got ? ((x) & 0xffffff) : (x))
140
#else
141
#define	real_address_bits(x)	(x)
142
#endif
143
 
144
#ifndef O_BINARY
145
#define O_BINARY 0
146
#endif
147
 
148
 
149
int verbose = 0;      /* extra output when running */
150
int pic_with_got = 0; /* do elf/got processing with PIC code */
151
int load_to_ram = 0;  /* instruct loader to allocate everything into RAM */
152
int ktrace = 0;       /* instruct loader output kernel trace on load */
153
int docompress = 0;   /* 1 = compress everything, 2 = compress data only */
154
int use_resolved = 0; /* If true, get the value of symbol references from */
155
		      /* the program contents, not from the relocation table. */
156
		      /* In this case, the input ELF file must be already */
157
		      /* fully resolved (using the `-q' flag with recent */
158
		      /* versions of GNU ld will give you a fully resolved */
159
		      /* output file with relocation entries).  */
160
 
161
/* Set if the text section contains any relocations.  If it does, we must
162
   set the load_to_ram flag.  */
163
int text_has_relocs = 0;
164
 
165
asymbol**
166
get_symbols (bfd *abfd, long *num)
167
{
168
  int32_t storage_needed;
169
  asymbol **symbol_table;
170
  long number_of_symbols;
171
 
172
  storage_needed = bfd_get_symtab_upper_bound (abfd);
173
 
174
  if (storage_needed < 0)
175
    abort ();
176
 
177
  if (storage_needed == 0)
178
    return NULL;
179
 
180
  symbol_table = xmalloc (storage_needed);
181
 
182
  number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
183
 
184
  if (number_of_symbols < 0) 
185
    abort ();
186
 
187
  *num = number_of_symbols;
188
  return symbol_table;
189
}
190
 
191
 
192
 
193
int
194
dump_symbols(asymbol **symbol_table, long number_of_symbols)
195
{
196
  long i;
197
  printf("SYMBOL TABLE:\n");
198
  for (i=0; i<number_of_symbols; i++) {
199
	printf("  NAME=%s  VALUE=0x%x\n", symbol_table[i]->name,
200
		symbol_table[i]->value);
201
  }
202
  printf("\n");
203
  return(0);
204
}  
205
 
206
 
207
 
208
long
209
get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols)
210
{
211
  long i;
212
  for (i=0; i<number_of_symbols; i++) {
213
    if (symbol_table[i]->section == sec) {
214
      if (!strcmp(symbol_table[i]->name, name)) {
215
        return symbol_table[i]->value;
216
      }
217
    }
218
  }
219
  return -1;
220
}  
221
 
222
 
223
 
224
#ifdef TARGET_nios2
225
long
226
get_gp_value(asymbol **symbol_table, long number_of_symbols)
227
{
228
  long i;
229
  for (i=0; i<number_of_symbols; i++) {
230
      if (!strcmp(symbol_table[i]->name, "_gp"))
231
		return symbol_table[i]->value;
232
  }
233
  return -1;
234
}
235
#endif
236
 
237
 
238
 
239
int32_t
240
add_com_to_bss(asymbol **symbol_table, int32_t number_of_symbols, int32_t bss_len)
241
{
242
  int32_t i, comsize;
243
  int32_t offset;
244
 
245
  comsize = 0;
246
  for (i=0; i<number_of_symbols; i++) {
247
    if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {
248
      offset = bss_len + comsize;
249
      comsize += symbol_table[i]->value;
250
      symbol_table[i]->value = offset;
251
    }
252
  }
253
  return comsize;
254
}  
255
 
256
#ifdef TARGET_bfin
257
/* FUNCTION : weak_und_symbol
258
   ABSTRACT : return true if symbol is weak and undefined.
259
*/
260
static int
261
weak_und_symbol(const char *reloc_section_name,
262
                struct bfd_symbol *symbol)
263
{
264
    if (!(strstr (reloc_section_name, "text")
265
	  || strstr (reloc_section_name, "data")
266
	  || strstr (reloc_section_name, "bss"))) {
267
	if (symbol->flags & BSF_WEAK) {
268
#ifdef DEBUG_BFIN
269
	    fprintf(stderr, "found weak undefined symbol %s\n", symbol->name);
270
#endif
271
	    return TRUE;
272
	}
273
    }
274
    return FALSE;
275
}
276
 
277
static int
278
bfin_set_reloc (uint32_t *reloc,
279
		const char *reloc_section_name,
280
		const char *sym_name,
281
		struct bfd_symbol *symbol,
282
		int sp, int32_t offset)
283
{
284
    unsigned int type = 0;
285
    uint32_t val;
286
 
287
    if (strstr (reloc_section_name, "stack")) {
288
	    if (verbose)
289
		    printf ("Stack-relative reloc, offset %08lx\n", offset);
290
	    /* This must be a stack_start reloc for stack checking.  */
291
	    type = 1;
292
    }
293
    val = (offset & ((1 << 26) - 1));
294
    val |= (sp & (1 << 3) - 1) << 26;
295
    val |= type << 29;
296
    *reloc = val;
297
    return 0;
298
}
299
 
300
static bfd *compare_relocs_bfd;
301
 
302
static int
303
compare_relocs (const void *pa, const void *pb)
304
{
305
	const arelent *const *a = pa, *const *b = pb;
306
	const arelent *ra = *a, *rb = *b;
307
	unsigned long va, vb;
308
	uint32_t a_vma, b_vma;
309
 
310
	if (!ra->sym_ptr_ptr || !*ra->sym_ptr_ptr)
311
		return -1;
312
	else if (!rb->sym_ptr_ptr || !*rb->sym_ptr_ptr)
313
		return 1;
314
 
315
	a_vma = bfd_section_vma(compare_relocs_bfd,
316
				(*(ra->sym_ptr_ptr))->section);
317
	b_vma = bfd_section_vma(compare_relocs_bfd,
318
				(*(rb->sym_ptr_ptr))->section);
319
	va = (*(ra->sym_ptr_ptr))->value + a_vma + ra->addend;
320
	vb = (*(rb->sym_ptr_ptr))->value + b_vma + rb->addend;
321
	return va - vb;
322
}
323
#endif
324
 
325
uint32_t *
326
output_relocs (
327
  bfd *abs_bfd,
328
  asymbol **symbols,
329
  int number_of_symbols,
330
  uint32_t *n_relocs,
331
  unsigned char *text, int text_len, uint32_t text_vma,
332
  unsigned char *data, int data_len, uint32_t data_vma,
333
  bfd *rel_bfd)
334
{
335
  uint32_t		*flat_relocs;
336
  asection		*a, *sym_section, *r;
337
  arelent		**relpp, **p, *q;
338
  const char		*sym_name, *section_name;
339
  unsigned char		*sectionp;
340
  unsigned long		pflags;
341
  char			addstr[16];
342
  uint32_t		sym_addr, sym_vma, section_vma;
343
  int			relsize, relcount;
344
  int			flat_reloc_count;
345
  int			sym_reloc_size, rc;
346
  int			got_size = 0;
347
  int			bad_relocs = 0;
348
  asymbol		**symb;
349
  long			nsymb;
350
#ifdef TARGET_bfin
351
  unsigned long		persistent_data = 0;
352
#endif
353
 
354
#if 0
355
  printf("%s(%d): output_relocs(abs_bfd=%d,synbols=0x%x,number_of_symbols=%d"
356
	"n_relocs=0x%x,text=0x%x,text_len=%d,data=0x%x,data_len=%d)\n",
357
	__FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,
358
	text, text_len, data, data_len);
359
#endif
360
 
361
#if 0
362
dump_symbols(symbols, number_of_symbols);
363
#endif
364
 
365
  *n_relocs = 0;
366
  flat_relocs = NULL;
367
  flat_reloc_count = 0;
368
  rc = 0;
369
  pflags = 0;
370
 
371
  /* Determine how big our offset table is in bytes.
372
   * This isn't too difficult as we've terminated the table with -1.
373
   * Also note that both the relocatable and absolute versions have this
374
   * terminator even though the relocatable one doesn't have the GOT!
375
   */
376
  if (pic_with_got && !use_resolved) {
377
    uint32_t *lp = (uint32_t *)data;
378
    /* Should call ntohl(*lp) here but is isn't going to matter */
379
    while (*lp != 0xffffffff) lp++;
380
    got_size = ((unsigned char *)lp) - data;
381
    if (verbose)
382
	    printf("GOT table contains %d entries (%d bytes)\n",
383
			    got_size/sizeof(uint32_t), got_size);
384
#ifdef TARGET_m68k
385
    if (got_size > GOT_LIMIT)
386
	    fatal("GOT too large: %d bytes (limit = %d bytes)",
387
			got_size, GOT_LIMIT);
388
#endif
389
  }
390
 
391
  for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
392
  	section_vma = bfd_section_vma(abs_bfd, a);
393
 
394
	if (verbose)
395
		printf("SECTION: %s [0x%x]: flags=0x%x vma=0x%x\n", a->name, a,
396
			a->flags, section_vma);
397
 
398
//	if (bfd_is_abs_section(a))
399
//		continue;
400
	if (bfd_is_und_section(a))
401
		continue;
402
	if (bfd_is_com_section(a))
403
		continue;
404
//	if ((a->flags & SEC_RELOC) == 0)
405
//		continue;
406
 
407
	/*
408
	 *	Only relocate things in the data sections if we are PIC/GOT.
409
	 *	otherwise do text as well
410
	 */
411
	if ((!pic_with_got || ALWAYS_RELOC_TEXT) && (a->flags & SEC_CODE))
412
		sectionp = text + (a->vma - text_vma);
413
	else if (a->flags & SEC_DATA)
414
		sectionp = data + (a->vma - data_vma);
415
	else
416
		continue;
417
 
418
	/* Now search for the equivalent section in the relocation binary
419
	 * and use that relocation information to build reloc entries
420
	 * for this one.
421
	 */
422
	for (r=rel_bfd->sections; r != NULL; r=r->next)
423
		if (strcmp(a->name, r->name) == 0)
424
			break;
425
	if (r == NULL)
426
	  continue;
427
	if (verbose)
428
	  printf(" RELOCS: %s [0x%x]: flags=0x%x vma=0x%x\n", r->name, r,
429
			r->flags, bfd_section_vma(abs_bfd, r));
430
  	if ((r->flags & SEC_RELOC) == 0)
431
  	  continue;
432
	relsize = bfd_get_reloc_upper_bound(rel_bfd, r);
433
	if (relsize <= 0) {
434
		if (verbose)
435
			printf("%s(%d): no relocation entries section=0x%x\n",
436
				__FILE__, __LINE__, r->name);
437
		continue;
438
	}
439
 
440
	symb = get_symbols(rel_bfd, &nsymb);
441
	relpp = xmalloc(relsize);
442
 
443
	relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);
444
	if (relcount <= 0) {
445
		if (verbose)
446
			printf("%s(%d): no relocation entries section=%s\n",
447
			__FILE__, __LINE__, r->name);
448
		continue;
449
	} else {
450
#ifdef TARGET_bfin
451
		compare_relocs_bfd = abs_bfd;
452
		qsort (relpp, relcount, sizeof *relpp, compare_relocs);
453
#endif
454
		for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
455
			unsigned char *r_mem;
456
			int relocation_needed = 0;
457
 
458
#ifdef TARGET_microblaze
459
			/* The MICROBLAZE_XX_NONE relocs can be skipped.
460
			   They represent PC relative branches that the
461
			   linker has already resolved */
462
 
463
			switch ((*p)->howto->type) 
464
			{
465
			case R_MICROBLAZE_NONE:
466
			case R_MICROBLAZE_64_NONE:
467
			case R_MICROBLAZE_32_PCREL_LO:
468
				continue;
469
			}
470
#endif /* TARGET_microblaze */
471
 
472
#ifdef TARGET_v850
473
			/* Skip this relocation entirely if possible (we
474
			   do this early, before doing any other
475
			   processing on it).  */
476
			switch ((*p)->howto->type) {
477
#ifdef R_V850_9_PCREL
478
			case R_V850_9_PCREL:
479
#endif
480
#ifdef R_V850_22_PCREL
481
			case R_V850_22_PCREL:
482
#endif
483
#ifdef R_V850_SDA_16_16_OFFSET
484
			case R_V850_SDA_16_16_OFFSET:
485
#endif
486
#ifdef R_V850_SDA_15_16_OFFSET
487
			case R_V850_SDA_15_16_OFFSET:
488
#endif
489
#ifdef R_V850_ZDA_15_16_OFFSET
490
			case R_V850_ZDA_15_16_OFFSET:
491
#endif
492
#ifdef R_V850_TDA_6_8_OFFSET
493
			case R_V850_TDA_6_8_OFFSET:
494
#endif
495
#ifdef R_V850_TDA_7_8_OFFSET
496
			case R_V850_TDA_7_8_OFFSET:
497
#endif
498
#ifdef R_V850_TDA_7_7_OFFSET
499
			case R_V850_TDA_7_7_OFFSET:
500
#endif
501
#ifdef R_V850_TDA_16_16_OFFSET
502
			case R_V850_TDA_16_16_OFFSET:
503
#endif
504
#ifdef R_V850_TDA_4_5_OFFSET
505
			case R_V850_TDA_4_5_OFFSET:
506
#endif
507
#ifdef R_V850_TDA_4_4_OFFSET
508
			case R_V850_TDA_4_4_OFFSET:
509
#endif
510
#ifdef R_V850_SDA_16_16_SPLIT_OFFSET
511
			case R_V850_SDA_16_16_SPLIT_OFFSET:
512
#endif
513
#ifdef R_V850_CALLT_6_7_OFFSET
514
			case R_V850_CALLT_6_7_OFFSET:
515
#endif
516
#ifdef R_V850_CALLT_16_16_OFFSET
517
			case R_V850_CALLT_16_16_OFFSET:
518
#endif
519
				/* These are relative relocations, which
520
				   have already been fixed up by the
521
				   linker at this point, so just ignore
522
				   them.  */ 
523
				continue;
524
			}
525
#endif /* USE_V850_RELOCS */
526
 
527
			q = *p;
528
			if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {
529
				sym_name = (*(q->sym_ptr_ptr))->name;
530
				sym_section = (*(q->sym_ptr_ptr))->section;
531
				section_name=(*(q->sym_ptr_ptr))->section->name;
532
			} else {
533
				printf("ERROR: undefined relocation entry\n");
534
				rc = -1;
535
				continue;
536
			}
537
#ifndef TARGET_bfin
538
			/* Adjust the address to account for the GOT table which wasn't
539
			 * present in the relative file link.
540
			 */
541
			if (pic_with_got && !use_resolved)
542
			  q->address += got_size;
543
#endif
544
 
545
			/* A pointer to what's being relocated, used often
546
			   below.  */
547
			r_mem = sectionp + q->address;
548
 
549
			/*
550
			 *	Fixup offset in the actual section.
551
			 */
552
			addstr[0] = 0;
553
#if !defined TARGET_e1 && !defined TARGET_bfin
554
  			if ((sym_addr = get_symbol_offset((char *) sym_name,
555
			    sym_section, symbols, number_of_symbols)) == -1) {
556
				sym_addr = 0;
557
			}
558
#else
559
			sym_addr = (*(q->sym_ptr_ptr))->value;
560
#endif			
561
			if (use_resolved) {
562
				/* Use the address of the symbol already in
563
				   the program text.  How this is handled may
564
				   still depend on the particular relocation
565
				   though.  */
566
				switch (q->howto->type) {
567
					int r2_type;
568
#ifdef TARGET_v850
569
				case R_V850_HI16_S:
570
					/* We specially handle adjacent
571
					   HI16_S/ZDA_15_16_OFFSET and
572
					   HI16_S/LO16 pairs that reference the
573
					   same address (these are usually
574
					   movhi/ld and movhi/movea pairs,
575
					   respectively).  */
576
					if (relcount == 0)
577
						r2_type = R_V850_NONE;
578
					else
579
						r2_type = p[1]->howto->type;
580
					if ((r2_type == R_V850_ZDA_15_16_OFFSET
581
					     || r2_type == R_V850_LO16)
582
					    && (p[0]->sym_ptr_ptr
583
						== p[1]->sym_ptr_ptr)
584
					    && (p[0]->addend == p[1]->addend))
585
					{
586
						relocation_needed = 1;
587
 
588
						switch (r2_type) {
589
						case R_V850_ZDA_15_16_OFFSET:
590
							pflags = 0x10000000;
591
							break;
592
						case R_V850_LO16:
593
							pflags = 0x20000000;
594
							break;
595
						}
596
 
597
						/* We don't really need the
598
						   actual value -- the bits
599
						   produced by the linker are
600
						   what we want in the final
601
						   flat file -- but get it
602
						   anyway if useful for
603
						   debugging.  */
604
						if (verbose) {
605
							unsigned char *r2_mem =
606
								sectionp
607
								+ p[1]->address;
608
							/* little-endian */
609
							int hi = r_mem[0]
610
								+ (r_mem[1] << 8);
611
							int lo = r2_mem[0]
612
								+ (r2_mem[1] << 8);
613
							/* Sign extend LO.  */
614
							lo = (lo ^ 0x8000)
615
								- 0x8000;
616
 
617
							/* Maybe ignore the LSB
618
							   of LO, which is
619
							   actually part of the
620
							   instruction.  */
621
							if (r2_type != R_V850_LO16)
622
								lo &= ~1;
623
 
624
							sym_addr =
625
								(hi << 16)
626
								+ lo;
627
						}
628
					} else
629
						goto bad_resolved_reloc;
630
					break;
631
 
632
				case R_V850_LO16:
633
					/* See if this is actually the
634
					   2nd half of a pair.  */
635
					if (p > relpp
636
					    && (p[-1]->howto->type
637
						== R_V850_HI16_S)
638
					    && (p[-1]->sym_ptr_ptr
639
						== p[0]->sym_ptr_ptr)
640
					    && (p[-1]->addend == p[0]->addend))
641
						break; /* not an error */
642
					else
643
						goto bad_resolved_reloc;
644
 
645
				case R_V850_HI16:
646
					goto bad_resolved_reloc;
647
				default:
648
					goto good_32bit_resolved_reloc;
649
#elif defined(TARGET_arm)
650
				case R_ARM_ABS32:
651
					relocation_needed = 1;
652
					break;
653
				case R_ARM_REL32:
654
				case R_ARM_THM_PC11:
655
				case R_ARM_THM_PC22:
656
				case R_ARM_PC24:
657
				case R_ARM_PLT32:
658
				case R_ARM_GOTPC:
659
				case R_ARM_GOT32:
447 theseven 660
				case R_ARM_V4BX:
445 theseven 661
					relocation_needed = 0;
662
					break;
663
				default:
664
					goto bad_resolved_reloc;
665
#elif defined(TARGET_m68k)
666
				case R_68K_32:
667
					goto good_32bit_resolved_reloc;
668
				case R_68K_PC32:
669
				case R_68K_PC16:
670
					/* The linker has already resolved
671
					   PC relocs for us.  In PIC links,
672
					   the symbol must be in the data
673
					   segment.  */
674
				case R_68K_NONE:
675
					continue;
676
				default:
677
					goto bad_resolved_reloc;
678
#elif defined TARGET_bfin
679
				case R_BFIN_RIMM16:
680
				case R_BFIN_LUIMM16:
681
				case R_BFIN_HUIMM16:
682
				    sym_vma = bfd_section_vma(abs_bfd, sym_section);
683
				    sym_addr += sym_vma + q->addend;
684
 
685
				    if (weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
686
					continue;
687
				    if (q->howto->type == R_BFIN_RIMM16 && (0xFFFF0000 & sym_addr)) {
688
					fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
689
					bad_relocs++;
690
				    }
691
				    if ((0xFFFF0000 & sym_addr) != persistent_data) {
692
				    flat_relocs = (uint32_t *)
693
					(realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
694
					    if (verbose)
695
						    printf ("New persistent data for %08lx\n", sym_addr);
696
					    persistent_data = 0xFFFF0000 & sym_addr;
697
					    flat_relocs[flat_reloc_count++]
698
						    = (sym_addr >> 16) | (3 << 26);
699
				    }
700
 
701
				    flat_relocs = (uint32_t *)
702
					(realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
703
				    if (bfin_set_reloc (flat_relocs + flat_reloc_count,
704
							sym_section->name, sym_name,
705
							(*(q->sym_ptr_ptr)),
706
							q->howto->type == R_BFIN_HUIMM16 ? 1 : 0,
707
							section_vma + q->address))
708
					bad_relocs++;
709
				    if (a->flags & SEC_CODE)
710
					text_has_relocs = 1;
711
				    flat_reloc_count++;
712
				    break;
713
 
714
				case R_BFIN_BYTE4_DATA:
715
				    sym_vma = bfd_section_vma(abs_bfd, sym_section);
716
				    sym_addr += sym_vma + q->addend;
717
 
718
				    if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
719
					continue;
720
 
721
				    flat_relocs = (uint32_t *)
722
					(realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
723
				    if (bfin_set_reloc (flat_relocs + flat_reloc_count,
724
							sym_section->name, sym_name,
725
							(*(q->sym_ptr_ptr)),
726
							2, section_vma + q->address))
727
					bad_relocs++;
728
				    if (a->flags & SEC_CODE)
729
					text_has_relocs = 1;
730
 
731
				    flat_reloc_count++;
732
				    break;
733
#else
734
				default:
735
					/* The default is to assume that the
736
					   relocation is relative and has
737
					   already been fixed up by the
738
					   linker (perhaps we ought to make
739
					   give an error by default, and
740
					   require `safe' relocations to be
741
					   enumberated explicitly?).  */
742
					goto good_32bit_resolved_reloc;
743
#endif
744
				good_32bit_resolved_reloc:
745
					if (bfd_big_endian (abs_bfd))
746
						sym_addr =
747
							(r_mem[0] << 24)
748
							+ (r_mem[1] << 16)
749
							+ (r_mem[2] << 8) 
750
							+ r_mem[3];
751
					else
752
						sym_addr =
753
							r_mem[0]
754
							+ (r_mem[1] << 8)
755
							+ (r_mem[2] << 16)
756
							+ (r_mem[3] << 24);
757
					relocation_needed = 1;
758
					break;
759
 
760
				bad_resolved_reloc:
761
					printf("ERROR: reloc type %s unsupported in this context\n",
762
					       q->howto->name);
763
					bad_relocs++;
764
					break;
765
				}
766
			} else {
767
				/* Calculate the sym address ourselves.  */
768
				sym_reloc_size = bfd_get_reloc_size(q->howto);
769
 
770
#if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin) && !defined(TARGET_m68k)
771
				if (sym_reloc_size != 4) {
772
					printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
773
							(*p)->howto->type, sym_reloc_size, sym_name);
774
					bad_relocs++;
775
					rc = -1;
776
					continue;
777
				}
778
#endif
779
 
780
				switch ((*p)->howto->type) {
781
 
782
#if defined(TARGET_m68k)
783
				case R_68K_32:
784
					relocation_needed = 1;
785
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
786
					sym_addr += sym_vma + q->addend;
787
					break;
788
				case R_68K_PC16:
789
				case R_68K_PC32:
790
					sym_vma = 0;
791
					sym_addr += sym_vma + q->addend;
792
					sym_addr -= q->address;
793
					break;
794
#endif
795
 
796
#if defined(TARGET_arm)
797
				case R_ARM_ABS32:
798
					relocation_needed = 1;
450 theseven 799
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
800
					sym_addr += sym_vma + q->addend;
445 theseven 801
					if (verbose)
802
						fprintf(stderr,
803
							"%s vma=0x%x, value=0x%x, address=0x%x "
804
							"sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
805
							"ABS32",
806
							sym_vma, (*(q->sym_ptr_ptr))->value,
807
							q->address, sym_addr,
808
							(*p)->howto->rightshift,
809
							*(uint32_t *)r_mem);
810
					break;
811
				case R_ARM_GOT32:
812
				case R_ARM_GOTPC:
449 theseven 813
                case R_ARM_V4BX:
445 theseven 814
					/* Should be fine as is */
815
					break;
816
				case R_ARM_PLT32:
817
					if (verbose)
818
						fprintf(stderr,
819
							"%s vma=0x%x, value=0x%x, address=0x%x "
820
							"sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
821
							"PLT32",
450 theseven 822
							0, (*(q->sym_ptr_ptr))->value,
823
							q->address, (sym_addr-q->address)>>(*p)->howto->rightshift,
445 theseven 824
							(*p)->howto->rightshift,
825
							*(uint32_t *)r_mem);
826
				case R_ARM_PC24:
449 theseven 827
                case R_ARM_JUMP24:
445 theseven 828
					sym_vma = 0;
829
					sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
830
					break;
831
#endif
832
 
833
#ifdef TARGET_v850
834
				case R_V850_32:
835
					relocation_needed = 1;
836
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
837
					sym_addr += sym_vma + q->addend;
838
					break;
839
#if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
840
#ifdef R_V850_ZDA_16_16_OFFSET
841
				case R_V850_ZDA_16_16_OFFSET:
842
#endif
843
#ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
844
				case R_V850_ZDA_16_16_SPLIT_OFFSET:
845
#endif
846
					/* Can't support zero-relocations.  */
847
					printf ("ERROR: %s+0x%x: zero relocations not supported\n",
848
							sym_name, q->addend);
849
					continue;
850
#endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
851
#endif /* TARGET_v850 */
852
 
853
#ifdef TARGET_h8300
854
				case R_H8_DIR24R8:
855
					if (sym_reloc_size != 4) {
856
						printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
857
						bad_relocs++;
858
						continue;
859
					}
860
					relocation_needed = 1;
861
					sym_addr = (*(q->sym_ptr_ptr))->value;
862
					q->address -= 1;
863
					r_mem -= 1; /* tracks q->address */
864
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
865
					sym_addr += sym_vma + q->addend;
866
					sym_addr |= (*(unsigned char *)r_mem<<24);
867
					break;
868
				case R_H8_DIR24A8:
869
					if (sym_reloc_size != 4) {
870
						printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
871
						bad_relocs++;
872
						continue;
873
					}
874
					/* Absolute symbol done not relocation */
875
					relocation_needed = !bfd_is_abs_section(sym_section);
876
					sym_addr = (*(q->sym_ptr_ptr))->value;
877
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
878
					sym_addr += sym_vma + q->addend;
879
					break;
880
				case R_H8_DIR32:
881
				case R_H8_DIR32A16: /* currently 32,  could be made 16 */
882
					if (sym_reloc_size != 4) {
883
						printf("R_H8_DIR32 size %d\n", sym_reloc_size);
884
						bad_relocs++;
885
						continue;
886
					}
887
					relocation_needed = 1;
888
					sym_addr = (*(q->sym_ptr_ptr))->value;
889
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
890
					sym_addr += sym_vma + q->addend;
891
					break;
892
				case R_H8_PCREL16:
893
					sym_vma = 0;
894
					sym_addr = (*(q->sym_ptr_ptr))->value;
895
					sym_addr += sym_vma + q->addend;
896
					sym_addr -= (q->address + 2);
897
					if (bfd_big_endian(abs_bfd))
898
					*(unsigned short *)r_mem =
899
						bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
900
					continue;
901
				case R_H8_PCREL8:
902
					sym_vma = 0;
903
					sym_addr = (*(q->sym_ptr_ptr))->value;
904
					sym_addr += sym_vma + q->addend;
905
					sym_addr -= (q->address + 1);
906
					*(unsigned char *)r_mem = sym_addr;
907
					continue;
908
#endif
909
 
910
#ifdef TARGET_microblaze
911
				case R_MICROBLAZE_64:
912
		/* The symbol is split over two consecutive instructions.  
913
		   Flag this to the flat loader by setting the high bit of 
914
		   the relocation symbol. */
915
				{
916
					unsigned char *p = r_mem;
917
					pflags=0x80000000;
918
 
919
					/* work out the relocation */
920
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
921
					sym_addr += sym_vma + q->addend;
922
					/* Write relocated pointer back */
923
					p[2] = (sym_addr >> 24) & 0xff;
924
					p[3] = (sym_addr >> 16) & 0xff;
925
					p[6] = (sym_addr >>  8) & 0xff;
926
					p[7] =  sym_addr        & 0xff;
927
 
928
					/* create a new reloc entry */
929
					flat_relocs = realloc(flat_relocs,
930
						(flat_reloc_count + 1) * sizeof(uint32_t));
931
					flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
932
					flat_reloc_count++;
933
					relocation_needed = 0;
934
					pflags = 0;
935
			sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
936
					 bfd_section_vma(abs_bfd, sym_section));
937
			if (verbose)
938
				printf("  RELOC[%d]: offset=0x%x symbol=%s%s "
939
					"section=%s size=%d "
940
					"fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
941
					q->address, sym_name, addstr,
942
					section_name, sym_reloc_size,
943
					sym_addr, section_vma + q->address);
944
			if (verbose)
945
				printf("reloc[%d] = 0x%x\n", flat_reloc_count,
946
					 section_vma + q->address);
947
 
948
					continue;
949
				}
950
				case R_MICROBLAZE_32:
951
				{	
952
					unsigned char *p = r_mem;
953
 
954
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
955
					sym_addr += sym_vma + q->addend;
956
					relocation_needed = 1;
957
					break;
958
				}
959
				case R_MICROBLAZE_64_PCREL:
960
					sym_vma = 0;
961
					sym_addr += sym_vma + q->addend;
962
					sym_addr -= (q->address + 4);
963
					sym_addr = htonl(sym_addr);
964
					/* insert 16 MSB */
965
					* ((unsigned short *) (r_mem+2)) = (sym_addr) & 0xFFFF;
966
					/* then 16 LSB */
967
					* ((unsigned short *) (r_mem+6)) = (sym_addr >> 16) & 0xFFFF;
968
					/* We've done all the work, so continue
969
					   to next reloc instead of break */
970
					continue;
971
 
972
#endif /* TARGET_microblaze */
973
 
974
#ifdef TARGET_nios2
975
#define  htoniosl(x)	(x)
976
#define  niostohl(x)	(x)
977
				case R_NIOS2_BFD_RELOC_32:
978
					relocation_needed = 1;
979
					pflags = (FLAT_NIOS2_R_32 << 28);
980
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
981
					sym_addr += sym_vma + q->addend;
982
					/* modify target, in target order */
983
					*(unsigned long *)r_mem = htoniosl(sym_addr);
984
					break;
985
				case R_NIOS2_CALL26:
986
				{
987
					unsigned long exist_val;
988
					relocation_needed = 1;
989
					pflags = (FLAT_NIOS2_R_CALL26 << 28);
990
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
991
					sym_addr += sym_vma + q->addend;
992
 
993
					/* modify target, in target order */
994
					// exist_val = niostohl(*(unsigned long *)r_mem);
995
					exist_val = ((sym_addr >> 2) << 6);
996
					*(unsigned long *)r_mem = htoniosl(exist_val);
997
					break;
998
				}
999
				case R_NIOS2_HIADJ16:
1000
				case R_NIOS2_HI16:
1001
				{
1002
					unsigned long exist_val;
1003
					int r2_type;
1004
					/* handle the adjacent HI/LO pairs */
1005
					if (relcount == 0)
1006
						r2_type = R_NIOS2_NONE;
1007
					else
1008
						r2_type = p[1]->howto->type;
1009
					if ((r2_type == R_NIOS2_LO16)
1010
					    && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
1011
					    && (p[0]->addend == p[1]->addend)) 
1012
					    {
1013
							unsigned char * r2_mem = sectionp + p[1]->address;
1014
							if (p[1]->address - q->address!=4)
1015
								printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1016
							relocation_needed = 1;
1017
							pflags = (q->howto->type == R_NIOS2_HIADJ16) 
1018
								? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1019
							pflags <<= 28;
1020
 
1021
							sym_vma = bfd_section_vma(abs_bfd, sym_section);
1022
							sym_addr += sym_vma + q->addend;
1023
 
1024
							/* modify high 16 bits, in target order */
1025
							exist_val = niostohl(*(unsigned long *)r_mem);
1026
							exist_val =  ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1027
							if (q->howto->type == R_NIOS2_HIADJ16)
1028
								exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1029
							else
1030
								exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1031
							*(unsigned long *)r_mem = htoniosl(exist_val);
1032
 
1033
							/* modify low 16 bits, in target order */
1034
							exist_val = niostohl(*(unsigned long *)r2_mem);
1035
							exist_val =  ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1036
							exist_val |= ((sym_addr & 0xFFFF) << 6);
1037
							*(unsigned long *)r2_mem = htoniosl(exist_val);
1038
 
1039
						} else 
1040
							goto NIOS2_RELOC_ERR;
1041
					}
1042
					break;
1043
 
1044
				case R_NIOS2_GPREL:
1045
				{
1046
					unsigned long exist_val, temp;
1047
					//long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1048
					long gp = get_gp_value(symbols, number_of_symbols);
1049
					if (gp == -1) {
1050
						printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1051
						goto NIOS2_RELOC_ERR;
1052
					}
1053
					/* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1054
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
1055
					//printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1056
					sym_addr += sym_vma + q->addend;
1057
					sym_addr -= gp;
1058
					//printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1059
					/* modify the target, in target order (little_endian) */
1060
					exist_val = niostohl(*(unsigned long *)r_mem);
1061
					temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1062
					temp <<= 6;
1063
					temp |= (exist_val & 0x3f);
1064
					*(unsigned long *)r_mem = htoniosl(temp);
1065
					if (verbose)
1066
						printf("omit: offset=0x%x symbol=%s%s "
1067
								"section=%s size=%d "
1068
								"fixup=0x%x (reloc=0x%x) GPREL\n", 
1069
								q->address, sym_name, addstr,
1070
								section_name, sym_reloc_size,
1071
								sym_addr, section_vma + q->address);
1072
					continue;
1073
				}
1074
				case R_NIOS2_PCREL16:
1075
				{
1076
					unsigned long exist_val;
1077
					sym_vma = 0;
1078
					sym_addr += sym_vma + q->addend;
1079
					sym_addr -= (q->address + 4);
1080
					/* modify the target, in target order (little_endian) */
1081
					exist_val = niostohl(*(unsigned long *)r_mem);
1082
					exist_val =  ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1083
					exist_val |= ((sym_addr & 0xFFFF) << 6);
1084
					*(unsigned long *)r_mem = htoniosl(exist_val);
1085
					if (verbose)
1086
						printf("omit: offset=0x%x symbol=%s%s "
1087
								"section=%s size=%d "
1088
								"fixup=0x%x (reloc=0x%x) PCREL\n", 
1089
								q->address, sym_name, addstr,
1090
								section_name, sym_reloc_size,
1091
								sym_addr, section_vma + q->address);
1092
					continue;
1093
				}
1094
 
1095
				case R_NIOS2_LO16:
1096
					/* check if this is actually the 2nd half of a pair */
1097
					if ((p > relpp)
1098
						&& ((p[-1]->howto->type == R_NIOS2_HIADJ16) 
1099
							|| (p[-1]->howto->type == R_NIOS2_HI16))
1100
					    && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1101
					    && (p[-1]->addend == p[0]->addend)) {
1102
						if (verbose)
1103
							printf("omit: offset=0x%x symbol=%s%s "
1104
								"section=%s size=%d LO16\n", 
1105
								q->address, sym_name, addstr,
1106
								section_name, sym_reloc_size);
1107
						continue;
1108
					}
1109
 
1110
					/* error, fall through */
1111
 
1112
				case R_NIOS2_S16:
1113
				case R_NIOS2_U16:
1114
				case R_NIOS2_CACHE_OPX:
1115
				case R_NIOS2_IMM5:
1116
				case R_NIOS2_IMM6:
1117
				case R_NIOS2_IMM8:
1118
				case R_NIOS2_BFD_RELOC_16:
1119
				case R_NIOS2_BFD_RELOC_8:
1120
				case R_NIOS2_GNU_VTINHERIT:
1121
				case R_NIOS2_GNU_VTENTRY:
1122
				case R_NIOS2_UJMP:
1123
				case R_NIOS2_CJMP:
1124
				case R_NIOS2_CALLR:
1125
NIOS2_RELOC_ERR:
1126
					printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1127
					bad_relocs++;
1128
					continue;
1129
#endif /* TARGET_nios2 */
1130
 
1131
#ifdef TARGET_sparc
1132
				case R_SPARC_32:
1133
				case R_SPARC_UA32:
1134
					relocation_needed = 1;
1135
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
1136
					sym_addr += sym_vma + q->addend;
1137
					break;
1138
				case R_SPARC_PC22:
1139
					sym_vma = 0;
1140
					sym_addr += sym_vma + q->addend;
1141
					sym_addr -= q->address;
1142
					break;
1143
				case R_SPARC_WDISP30:
1144
					sym_addr = (((*(q->sym_ptr_ptr))->value-
1145
						q->address) >> 2) & 0x3fffffff;
1146
					sym_addr |= (
1147
						ntohl(*(uint32_t *)r_mem)
1148
						& 0xc0000000
1149
						);
1150
					break;
1151
				case R_SPARC_HI22:
1152
					relocation_needed = 1;
1153
					pflags = 0x80000000;
1154
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
1155
					sym_addr += sym_vma + q->addend;
1156
					sym_addr |= (
1157
						htonl(*(uint32_t *)r_mem)
1158
						& 0xffc00000
1159
						);
1160
					break;
1161
				case R_SPARC_LO10:
1162
					relocation_needed = 1;
1163
					pflags = 0x40000000;
1164
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
1165
					sym_addr += sym_vma + q->addend;
1166
					sym_addr &= 0x000003ff;
1167
					sym_addr |= (
1168
						htonl(*(uint32_t *)r_mem)
1169
						& 0xfffffc00
1170
						);
1171
					break;
1172
#endif /* TARGET_sparc */
1173
 
1174
 
1175
#ifdef TARGET_sh
1176
				case R_SH_DIR32:
1177
					relocation_needed = 1;
1178
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
1179
					sym_addr += sym_vma + q->addend;
1180
					break;
1181
				case R_SH_REL32:
1182
					sym_vma = 0;
1183
					sym_addr += sym_vma + q->addend;
1184
					sym_addr -= q->address;
1185
					break;
1186
#endif /* TARGET_sh */
1187
 
1188
#ifdef TARGET_e1
1189
#define  htoe1l(x)              htonl(x)
1190
 
1191
#if 0 
1192
#define  DEBUG_E1
1193
#endif
1194
 
1195
#ifdef   DEBUG_E1
1196
#define  DBG_E1                 printf
1197
#else
1198
#define  DBG_E1(x, ...  )
1199
#endif
1200
 
1201
#define _32BITS_RELOC 0x00000000
1202
#define _30BITS_RELOC 0x80000000
1203
#define _28BITS_RELOC 0x40000000
1204
					{
1205
				char *p;
1206
				unsigned long   sec_vma, exist_val, S;
1207
				case R_E1_CONST31:
1208
						relocation_needed = 1;
1209
						DBG_E1("Handling Reloc <CONST31>\n");
1210
						sec_vma = bfd_section_vma(abs_bfd, sym_section);
1211
						DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1212
										sec_vma, sym_addr, q->address);
1213
						sym_addr = sec_vma + sym_addr;
1214
						exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);        
1215
						DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1216
						exist_val = htoe1l(exist_val);
1217
						DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1218
						sym_addr += exist_val;
1219
						pflags = _30BITS_RELOC;
1220
						break;
1221
				case R_E1_CONST31_PCREL:
1222
						relocation_needed = 0;
1223
						DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1224
						DBG_E1("DONT RELOCATE AT LOADING\n");
1225
						sec_vma = bfd_section_vma(abs_bfd, sym_section);
1226
						DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1227
										sec_vma, sym_addr, q->address);
1228
						sym_addr =  sec_vma + sym_addr;
1229
						DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1230
 
1231
						DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1232
																		section_vma );
1233
						q->address = q->address + section_vma;
1234
						DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1235
 
1236
						if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1237
								DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1238
						DBG_E1( "sym_addr := sym_addr - q->address  - "
1239
								"sizeof(CONST31_PCREL): [0x%x]\n",
1240
								sym_addr );
1241
						exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);              
1242
						DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1243
						exist_val = htoe1l(exist_val);
1244
						DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1245
						sym_addr |= exist_val;
1246
						DBG_E1("sym_addr |=  exist_val) : [0x%x]\n", sym_addr );
1247
						break;
1248
				case R_E1_DIS29W_PCREL:
1249
						relocation_needed = 0;
1250
						DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1251
						DBG_E1("DONT RELOCATE AT LOADING\n");
1252
						sec_vma = bfd_section_vma(abs_bfd, sym_section);
1253
						DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1254
										sec_vma, sym_addr, q->address);
1255
						sym_addr =  sec_vma + sym_addr;
1256
						DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1257
 
1258
						DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1259
																		section_vma );
1260
						q->address = q->address + section_vma;
1261
						DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1262
 
1263
						if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1264
								DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1265
						DBG_E1( "sym_addr := sym_addr - q->address  - "
1266
								"sizeof(CONST31_PCREL): [0x%x]\n",
1267
								sym_addr );
1268
						DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1269
						exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);       
1270
						DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1271
						exist_val = htoe1l(exist_val);
1272
						DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1273
						sym_addr += exist_val;
1274
						break;
1275
				case R_E1_DIS29W:
1276
						DBG_E1("Handling Reloc <DIS29W>\n");
1277
						goto DIS29_RELOCATION;
1278
				case R_E1_DIS29H:
1279
						DBG_E1("Handling Reloc <DIS29H>\n");
1280
						goto DIS29_RELOCATION;
1281
				case R_E1_DIS29B:
1282
						DBG_E1("Handling Reloc <DIS29B>\n");
1283
DIS29_RELOCATION:
1284
						relocation_needed = 1;
1285
						sec_vma = bfd_section_vma(abs_bfd, sym_section);
1286
						DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1287
										sec_vma, sym_addr);
1288
						sym_addr =  sec_vma + sym_addr;
1289
						DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1290
						exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);                
1291
						DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1292
						exist_val = htoe1l(exist_val);
1293
						DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1294
						sym_addr +=  exist_val;
1295
						DBG_E1("sym_addr +=  exist_val : [0x%08x]\n", sym_addr);
1296
						pflags = _28BITS_RELOC;
1297
						break;
1298
				case R_E1_IMM32_PCREL:
1299
						relocation_needed = 0;
1300
						DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1301
						DBG_E1("DONT RELOCATE AT LOADING\n");
1302
						sec_vma = bfd_section_vma(abs_bfd, sym_section);
1303
						DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1304
										sec_vma, sym_addr);
1305
						sym_addr =  sec_vma + sym_addr;
1306
 
1307
						DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1308
						DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1309
																		section_vma );
1310
						q->address = q->address + section_vma;
1311
						DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1312
 
1313
						if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1314
								DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1315
						DBG_E1( "sym_addr := sym_addr - q->address  - "
1316
								"sizeof(CONST31_PCREL): [0x%x]\n",
1317
								sym_addr );
1318
						DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1319
						exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);                 
1320
 						DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1321
						exist_val = htoe1l(exist_val);
1322
						DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1323
						sym_addr += exist_val;
1324
						break;
1325
				case R_E1_IMM32:
1326
						relocation_needed = 1;
1327
						DBG_E1("Handling Reloc <IMM32>\n");
1328
						sec_vma = bfd_section_vma(abs_bfd, sym_section);
1329
						DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1330
										sec_vma, sym_addr);
1331
						sym_addr =  sec_vma + sym_addr;
1332
						DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1333
						DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1334
						exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);                     
1335
	 					DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1336
						exist_val = htoe1l(exist_val);
1337
						DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1338
						sym_addr += exist_val;
1339
						pflags = _32BITS_RELOC;
1340
						break;
1341
				case R_E1_WORD:
1342
						relocation_needed = 1;
1343
						DBG_E1("Handling Reloc <WORD>\n");
1344
						sec_vma = bfd_section_vma(abs_bfd, sym_section);
1345
						DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1346
										sec_vma, sym_addr);
1347
						sym_addr =  sec_vma + sym_addr;
1348
						DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1349
						exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1350
						DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1351
						exist_val = htoe1l(exist_val);
1352
						DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1353
						sym_addr +=  exist_val;
1354
						DBG_E1("sym_addr +=  exist_val : [0x%08x]\n", sym_addr);
1355
						pflags = _32BITS_RELOC;
1356
						break;
1357
				}
1358
#undef _32BITS_RELOC
1359
#undef _30BITS_RELOC
1360
#undef _28BITS_RELOC
1361
#endif
1362
				default:
1363
					/* missing support for other types of relocs */
1364
					printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1365
					bad_relocs++;
1366
					continue;
1367
				}
1368
			}
1369
 
1370
			sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1371
					 bfd_section_vma(abs_bfd, sym_section));
1372
 
1373
 
1374
			/*
1375
			 * for full elf relocation we have to write back the
1376
			 * start_code relative value to use.
1377
			 */
1378
			if (!pic_with_got) {
1379
#if defined(TARGET_arm)
1380
				union {
1381
					unsigned char c[4];
1382
					uint32_t l;
1383
				} tmp;
1384
				int32_t hl;
1385
				int i0, i1, i2, i3;
1386
 
1387
				/*
1388
				 * horrible nasty hack to support different endianess
1389
				 */
1390
				if (!bfd_big_endian(abs_bfd)) {
1391
					i0 = 0;
1392
					i1 = 1;
1393
					i2 = 2;
1394
					i3 = 3;
1395
				} else {
1396
					i0 = 3;
1397
					i1 = 2;
1398
					i2 = 1;
1399
					i3 = 0;
1400
				}
1401
 
1402
				tmp.l = *(uint32_t *)r_mem;
1403
				hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1404
				if (use_resolved ||
1405
					(((*p)->howto->type != R_ARM_PC24) &&
1406
					((*p)->howto->type != R_ARM_PLT32)))
1407
					hl |= (tmp.c[i3] << 24);
1408
				else if (tmp.c[i2] & 0x80)
1409
					hl |= 0xff000000; /* sign extend */
1410
				if (!use_resolved)
1411
					hl += sym_addr;
1412
				tmp.c[i0] = hl & 0xff;
1413
				tmp.c[i1] = (hl >> 8) & 0xff;
1414
				tmp.c[i2] = (hl >> 16) & 0xff;
1415
				if (use_resolved ||
1416
					(((*p)->howto->type != R_ARM_PC24) &&
1417
					((*p)->howto->type != R_ARM_PLT32)))
1418
					tmp.c[i3] = (hl >> 24) & 0xff;
1419
				if ((*p)->howto->type == R_ARM_ABS32)
449 theseven 1420
					*(uint32_t *)r_mem = hl;
445 theseven 1421
				else
1422
					*(uint32_t *)r_mem = tmp.l;
1423
#elif defined(TARGET_e1)
1424
#define OPCODE_SIZE 2           /* Add 2 bytes, counting the opcode size*/
1425
				switch ((*p)->howto->type) {
1426
				case R_E1_CONST31:
1427
				case R_E1_CONST31_PCREL:
1428
				case R_E1_DIS29W_PCREL:
1429
				case R_E1_DIS29W:
1430
				case R_E1_DIS29H:
1431
				case R_E1_DIS29B:
1432
				case R_E1_IMM32_PCREL:
1433
				case R_E1_IMM32:
1434
						DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1435
								(sectionp + q->address + 2), sym_addr );
1436
						*((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1437
						htonl(sym_addr);
1438
				break;
1439
				case R_E1_WORD:
1440
						DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1441
								(sectionp + q->address), sym_addr );
1442
						*((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1443
				break;
1444
				default:
1445
						printf("ERROR:Unhandled Relocation. Exiting...\n");
1446
						exit(0);
1447
				break;
1448
				}
1449
#elif defined TARGET_bfin
1450
				if ((*p)->howto->type == R_BFIN_RIMM16
1451
				    || (*p)->howto->type == R_BFIN_HUIMM16
1452
				    || (*p)->howto->type == R_BFIN_LUIMM16)
1453
				{
1454
					/* for l and h we set the lower 16 bits which is only when it will be used */
1455
					bfd_putl16 (sym_addr, sectionp + q->address);
1456
				} else if ((*p)->howto->type == R_BFIN_BYTE4_DATA) {
1457
					bfd_putl32 (sym_addr, sectionp + q->address);
1458
				}
1459
#else /* ! TARGET_arm && ! TARGET_e1 && ! TARGET_bfin */
1460
 
1461
				switch (q->howto->type) {
1462
#ifdef TARGET_v850
1463
				case R_V850_HI16_S:
1464
				case R_V850_HI16:
1465
				case R_V850_LO16:
1466
					/* Do nothing -- for cases we handle,
1467
					   the bits produced by the linker are
1468
					   what we want in the final flat file
1469
					   (and other cases are errors).  Note
1470
					   that unlike most relocated values,
1471
					   it is stored in little-endian order,
1472
					   but this is necessary to avoid
1473
					   trashing the low-bit, and the float
1474
					   loaders knows about it.  */
1475
					break;
1476
#endif /* TARGET_V850 */
1477
 
1478
#ifdef TARGET_nios2
1479
				case R_NIOS2_BFD_RELOC_32:
1480
				case R_NIOS2_CALL26:
1481
				case R_NIOS2_HIADJ16:
1482
				case R_NIOS2_HI16:
1483
					/* do nothing */
1484
					break;
1485
#endif /* TARGET_nios2 */
1486
 
1487
#if defined(TARGET_m68k)
1488
				case R_68K_PC16:
1489
					if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1490
						fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1491
						bad_relocs++;
1492
					} else {
1493
						r_mem[0] = (sym_addr >>  8) & 0xff;
1494
						r_mem[1] =  sym_addr        & 0xff;
1495
					}
1496
					break;
1497
#endif
1498
 
1499
				default:
1500
					/* The alignment of the build host
1501
					   might be stricter than that of the
1502
					   target, so be careful.  We store in
1503
					   network byte order. */
1504
					r_mem[0] = (sym_addr >> 24) & 0xff;
1505
					r_mem[1] = (sym_addr >> 16) & 0xff;
1506
					r_mem[2] = (sym_addr >>  8) & 0xff;
1507
					r_mem[3] =  sym_addr        & 0xff;
1508
				}
1509
#endif /* !TARGET_arm */
1510
			}
1511
 
1512
			if (verbose)
1513
				printf("  RELOC[%d]: offset=0x%x symbol=%s%s "
1514
					"section=%s size=%d "
1515
					"fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1516
					q->address, sym_name, addstr,
1517
					section_name, sym_reloc_size,
1518
					sym_addr, section_vma + q->address);
1519
 
1520
			/*
1521
			 *	Create relocation entry (PC relative doesn't need this).
1522
			 */
1523
			if (relocation_needed) {
1524
#ifndef TARGET_bfin
1525
				flat_relocs = realloc(flat_relocs,
1526
					(flat_reloc_count + 1) * sizeof(uint32_t));
1527
#ifndef TARGET_e1
1528
				flat_relocs[flat_reloc_count] = pflags |
1529
					(section_vma + q->address);
1530
 
1531
				if (verbose)
1532
					printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1533
							section_vma + q->address);
1534
#else
1535
				switch ((*p)->howto->type) {
1536
				case R_E1_CONST31:
1537
				case R_E1_CONST31_PCREL:
1538
				case R_E1_DIS29W_PCREL:
1539
				case R_E1_DIS29W:
1540
				case R_E1_DIS29H:
1541
				case R_E1_DIS29B:
1542
				case R_E1_IMM32_PCREL:
1543
				case R_E1_IMM32:
1544
				flat_relocs[flat_reloc_count] = pflags |
1545
						(section_vma + q->address + OPCODE_SIZE);
1546
				if (verbose)
1547
						printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1548
										 flat_relocs[flat_reloc_count] );
1549
				break;
1550
				case R_E1_WORD:
1551
				flat_relocs[flat_reloc_count] = pflags |
1552
						(section_vma + q->address);
1553
				if (verbose)
1554
						printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1555
										 flat_relocs[flat_reloc_count] );
1556
				break;
1557
				}
1558
#endif
1559
				flat_reloc_count++;
1560
#endif //TARGET_bfin
1561
				relocation_needed = 0;
1562
				pflags = 0;
1563
			}
1564
 
1565
#if 0
1566
printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1567
	__FILE__, __LINE__, sym_name, q->address, section_name,
1568
	flat_relocs[flat_reloc_count]);
1569
#endif
1570
		}
1571
	}
1572
  }
1573
 
1574
  if (bad_relocs) {
1575
	  printf("%d bad relocs\n", bad_relocs);
1576
	  exit(1);
1577
  }
1578
 
1579
  if (rc < 0)
1580
	return(0);
1581
 
1582
  *n_relocs = flat_reloc_count;
1583
  return flat_relocs;
1584
}
1585
 
1586
 
1587
 
1588
static void usage(void)
1589
{
1590
    fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1591
	"[-o <output-file>] <elf-file>\n\n"
1592
	"       -v              : verbose operation\n"
1593
	"       -r              : force load to RAM\n"
1594
	"       -k              : enable kernel trace on load (for debug)\n"
1595
	"       -z              : compress code/data/relocs\n"
1596
	"       -d              : compress data/relocs\n"
1597
	"       -a              : use existing symbol references\n"
1598
	"                         instead of recalculating from\n"
1599
	"                         relocation info\n"
450 theseven 1600
    "       -R reloc-file   : read relocations from a separate file\n"
445 theseven 1601
	"       -p abs-pic-file : GOT/PIC processing with files\n"
1602
	"       -s stacksize    : set application stack size\n"
1603
	"       -o output-file  : output file name\n\n",
1604
	elf2flt_progname);
1605
	fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1606
    exit(2);
1607
}
1608
 
1609
 
1610
/* Write NUM zeroes to STREAM.  */
1611
static void write_zeroes (unsigned long num, stream *stream)
1612
{
1613
  char zeroes[1024];
1614
  if (num > 0) {
1615
    /* It'd be nice if we could just use fseek, but that doesn't seem to
1616
       work for stdio output files.  */
1617
    memset(zeroes, 0x00, 1024);
1618
    while (num > sizeof(zeroes)) {
1619
      fwrite_stream(zeroes, sizeof(zeroes), 1, stream);
1620
      num -= sizeof(zeroes);
1621
    }
1622
    if (num > 0)
1623
      fwrite_stream(zeroes, num, 1, stream);
1624
  }
1625
}
1626
 
1627
 
1628
int main(int argc, char *argv[])
1629
{
1630
  int fd;
1631
  bfd *rel_bfd, *abs_bfd;
1632
  asection *s;
1633
  char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1634
  char *fname = NULL;
1635
  int opt;
1636
  int i;
1637
  int stack;
1638
  stream gf;
1639
 
1640
  asymbol **symbol_table;
1641
  long number_of_symbols;
1642
 
1643
  uint32_t data_len = 0;
1644
  uint32_t bss_len = 0;
1645
  uint32_t text_len = 0;
1646
  uint32_t reloc_len;
1647
 
1648
  uint32_t data_vma = ~0;
1649
  uint32_t bss_vma = ~0;
1650
  uint32_t text_vma = ~0;
1651
 
1652
  uint32_t text_offs;
1653
 
1654
  void *text;
1655
  void *data;
1656
  uint32_t *reloc;
1657
 
450 theseven 1658
  struct emcoreapp_header hdr;
445 theseven 1659
 
1660
  elf2flt_progname = argv[0];
1661
  xmalloc_set_program_name(elf2flt_progname);
1662
 
1663
  if (argc < 2)
1664
  	usage();
1665
 
1666
#ifndef TARGET_e1
1667
  stack = 4096;
1668
#else /* We need plenty of stack for both of them (Aggregate and Register) */
1669
  stack = 0x2020;
1670
#endif
1671
 
1672
  while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1673
    switch (opt) {
1674
    case 'v':
1675
      verbose++;
1676
      break;
1677
    case 'r':
1678
      load_to_ram++;
1679
      break;
1680
    case 'k':
1681
      ktrace++;
1682
      break;
1683
    case 'z':
1684
      docompress = 1;
1685
      break;
1686
    case 'd':
1687
      docompress = 2;
1688
      break;
1689
    case 'p':
1690
      pfile = optarg;
1691
      break;
1692
    case 'o':
1693
      ofile = optarg;
1694
      break;
1695
    case 'a':
1696
      use_resolved = 1;
1697
      break;
1698
    case 's':
1699
      if (sscanf(optarg, "%i", &stack) != 1) {
1700
        fprintf(stderr, "%s invalid stack size %s\n", argv[0], optarg);
1701
        usage();
1702
      }
1703
      break;
1704
    case 'R':
1705
      rel_file = optarg;
1706
      break;
1707
    default:
1708
      fprintf(stderr, "%s Unknown option\n", argv[0]);
1709
      usage();
1710
      break;
1711
    }
1712
  }
1713
 
1714
  /*
1715
   * if neither the -r or -p options was given,  default to
1716
   * a RAM load as that is the only option that makes sense.
1717
   */
1718
  if (!load_to_ram && !pfile)
1719
    load_to_ram = 1;
1720
 
1721
  fname = argv[argc-1];
1722
 
1723
  if (pfile) {
1724
    pic_with_got = 1;
1725
    abs_file = pfile;
1726
  } else
1727
    abs_file = fname;
1728
 
1729
  if (! rel_file)
1730
    rel_file = fname;
1731
 
1732
  if (!(rel_bfd = bfd_openr(rel_file, 0)))
1733
    fatal_perror("Can't open '%s'", rel_file);
1734
 
1735
  if (bfd_check_format (rel_bfd, bfd_object) == 0)
1736
    fatal("File is not an object file");
1737
 
1738
  if (abs_file == rel_file)
1739
    abs_bfd = rel_bfd; /* one file does all */
1740
  else {
1741
    if (!(abs_bfd = bfd_openr(abs_file, 0)))
1742
      fatal_perror("Can't open '%s'", abs_file);
1743
 
1744
    if (bfd_check_format (abs_bfd, bfd_object) == 0)
1745
      fatal("File is not an object file");
1746
  }
1747
 
1748
  if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC))
1749
    fatal("%s: Input file contains no relocation info", rel_file);
1750
 
1751
  if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P))
1752
    /* `Absolute' file is not absolute, so neither are address
1753
       contained therein.  */
1754
    fatal("%s: `-a' option specified with non-fully-resolved input file",
1755
	     bfd_get_filename (abs_bfd));
1756
 
1757
  symbol_table = get_symbols(abs_bfd, &number_of_symbols);
1758
 
1759
  /* Group output sections into text, data, and bss, and calc their sizes.  */
1760
  for (s = abs_bfd->sections; s != NULL; s = s->next) {
1761
    uint32_t *vma, *len;
1762
    bfd_size_type sec_size;
1763
    bfd_vma sec_vma;
1764
 
1765
    if (s->flags & SEC_CODE) {
1766
      vma = &text_vma;
1767
      len = &text_len;
1768
    } else if (s->flags & SEC_DATA) {
1769
      vma = &data_vma;
1770
      len = &data_len;
1771
    } else if (s->flags & SEC_ALLOC) {
1772
      vma = &bss_vma;
1773
      len = &bss_len;
1774
    } else
1775
      continue;
1776
 
1777
    sec_size = bfd_section_size(abs_bfd, s);
1778
    sec_vma  = bfd_section_vma(abs_bfd, s);
1779
 
1780
    if (sec_vma < *vma) {
1781
      if (*len > 0)
1782
	*len += sec_vma - *vma;
1783
      else
1784
	*len = sec_size;
1785
      *vma = sec_vma;
1786
    } else if (sec_vma + sec_size > *vma + *len)
1787
      *len = sec_vma + sec_size - *vma;
1788
  }
1789
 
1790
  if (text_len == 0)
1791
    fatal("%s: no .text section", abs_file);
1792
 
1793
  text = xmalloc(text_len);
1794
 
1795
  if (verbose)
1796
    printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
1797
 
1798
  /* Read in all text sections.  */
1799
  for (s = abs_bfd->sections; s != NULL; s = s->next)
1800
    if (s->flags & SEC_CODE) 
1801
      if (!bfd_get_section_contents(abs_bfd, s,
1802
				   text + (s->vma - text_vma), 0,
1803
				   bfd_section_size(abs_bfd, s)))
1804
      {
1805
	fatal("read error section %s", s->name);
1806
      }
1807
 
1808
  if (data_len == 0)
1809
    fatal("%s: no .data section", abs_file);
1810
  data = xmalloc(data_len);
1811
 
1812
  if (verbose)
1813
    printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
1814
 
1815
  if ((text_vma + text_len) != data_vma) {
1816
    if ((text_vma + text_len) > data_vma) {
1817
      printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
1818
      exit(1);
1819
    }
1820
    if (verbose)
1821
      printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
1822
	  		data_vma, text_len);
1823
    text_len = data_vma - text_vma;
1824
  }
1825
 
1826
  /* Read in all data sections.  */
1827
  for (s = abs_bfd->sections; s != NULL; s = s->next)
1828
    if (s->flags & SEC_DATA) 
1829
      if (!bfd_get_section_contents(abs_bfd, s,
1830
				   data + (s->vma - data_vma), 0,
1831
				   bfd_section_size(abs_bfd, s)))
1832
      {
1833
	fatal("read error section %s", s->name);
1834
      }
1835
 
1836
  if (bss_vma == ~0)
1837
    bss_vma = data_vma + data_len;
1838
 
1839
  /* Put common symbols in bss.  */
1840
  bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
1841
 
1842
  if (verbose)
1843
    printf("BSS  -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
1844
 
1845
  if ((data_vma + data_len) != bss_vma) {
1846
    if ((data_vma + data_len) > bss_vma) {
1847
      printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
1848
	  		data_len, bss_vma);
1849
      exit(1);
1850
    }
1851
    if (verbose)
1852
      printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
1853
      		bss_vma, text_len, data_len, text_len + data_len);
1854
    data_len = bss_vma - data_vma;
1855
  }
1856
 
1857
  reloc = (uint32_t *)
1858
    output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
1859
		  text, text_len, text_vma, data, data_len, data_vma, rel_bfd);
1860
 
1861
  if (reloc == NULL && verbose)
1862
    printf("No relocations in code!\n");
1863
 
1864
  text_offs = real_address_bits(text_vma);
1865
 
1866
  /* Fill in the binflt_flat header */
450 theseven 1867
  memcpy(hdr.signature, "emCOexec", 8);
1868
  hdr.version = EMCOREAPP_HEADER_VERSION;
1869
  hdr.textstart = sizeof(hdr);
1870
  hdr.textsize = text_len + data_len;
1871
  hdr.bsssize = bss_len;
1872
  hdr.stacksize = stack;
1873
  hdr.entrypoint = bfd_get_start_address(abs_bfd);
1874
  hdr.relocstart = sizeof(hdr) + text_len + data_len;
1875
  hdr.reloccount = reloc_len;
1876
  hdr.flags = docompress ? EMCOREAPP_FLAG_COMPRESSED : 0;
1877
  hdr.creationtime = (uint32_t)time(NULL);
445 theseven 1878
 
449 theseven 1879
  for (i=0; i<reloc_len; i++) reloc[i] = reloc[i];
445 theseven 1880
 
1881
  if (verbose) {
1882
    printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
1883
	text_len, data_len, bss_len);
1884
    if (reloc)
1885
      printf(", relocs=0x%04x", reloc_len);
1886
    printf("\n");
1887
  }
1888
 
1889
  if (!ofile) {
450 theseven 1890
    ofile = xmalloc(strlen(fname) + 10 + 1); /* 10 to add suffix */
445 theseven 1891
    strcpy(ofile, fname);
450 theseven 1892
    strcat(ofile, ".emcoreapp");
445 theseven 1893
  }
1894
 
1895
  if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0)
1896
    fatal_perror("Can't open output file %s", ofile);
1897
 
1898
  write(fd, &hdr, sizeof(hdr));
1899
  close(fd);
1900
 
1901
  if (fopen_stream_u(&gf, ofile, "a" BINARY_FILE_OPTS))
1902
    fatal_perror("Can't open file %s for writing", ofile);
1903
 
1904
  if (docompress == 1)
1905
    reopen_stream_compressed(&gf);
1906
 
1907
  /* Fill in any hole at the beginning of the text segment.  */
1908
  if (verbose)
1909
    printf("ZERO before text len=0x%x\n", text_offs);
1910
  write_zeroes(text_offs, &gf);
1911
 
1912
  /* Write the text segment.  */
1913
  fwrite_stream(text, text_len, 1, &gf);
1914
 
1915
  if (docompress == 2)
1916
    reopen_stream_compressed(&gf);
1917
 
1918
  /* Write the data segment.  */
1919
  fwrite_stream(data, data_len, 1, &gf);
1920
 
1921
  if (reloc)
1922
    fwrite_stream(reloc, reloc_len * 4, 1, &gf);
1923
 
1924
  fclose_stream(&gf);
1925
 
1926
  exit(0);
1927
}
1928
 
1929
 
1930
/*
1931
 * this __MUST__ be at the VERY end of the file - do NOT move!!
1932
 *
1933
 * Local Variables:
1934
 * c-basic-offset: 4
1935
 * tab-width: 8
1936
 * end:
1937
 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab
1938
 */