Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

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