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:
447 theseven 648
				case R_ARM_V4BX:
445 theseven 649
					relocation_needed = 0;
650
					break;
651
				default:
652
					goto bad_resolved_reloc;
653
#elif defined(TARGET_m68k)
654
				case R_68K_32:
655
					goto good_32bit_resolved_reloc;
656
				case R_68K_PC32:
657
				case R_68K_PC16:
658
					/* The linker has already resolved
659
					   PC relocs for us.  In PIC links,
660
					   the symbol must be in the data
661
					   segment.  */
662
				case R_68K_NONE:
663
					continue;
664
				default:
665
					goto bad_resolved_reloc;
666
#elif defined TARGET_bfin
667
				case R_BFIN_RIMM16:
668
				case R_BFIN_LUIMM16:
669
				case R_BFIN_HUIMM16:
670
				    sym_vma = bfd_section_vma(abs_bfd, sym_section);
671
				    sym_addr += sym_vma + q->addend;
672
 
673
				    if (weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
674
					continue;
675
				    if (q->howto->type == R_BFIN_RIMM16 && (0xFFFF0000 & sym_addr)) {
676
					fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
677
					bad_relocs++;
678
				    }
679
				    if ((0xFFFF0000 & sym_addr) != persistent_data) {
680
				    flat_relocs = (uint32_t *)
681
					(realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
682
					    if (verbose)
683
						    printf ("New persistent data for %08lx\n", sym_addr);
684
					    persistent_data = 0xFFFF0000 & sym_addr;
685
					    flat_relocs[flat_reloc_count++]
686
						    = (sym_addr >> 16) | (3 << 26);
687
				    }
688
 
689
				    flat_relocs = (uint32_t *)
690
					(realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
691
				    if (bfin_set_reloc (flat_relocs + flat_reloc_count,
692
							sym_section->name, sym_name,
693
							(*(q->sym_ptr_ptr)),
694
							q->howto->type == R_BFIN_HUIMM16 ? 1 : 0,
695
							section_vma + q->address))
696
					bad_relocs++;
697
				    if (a->flags & SEC_CODE)
698
					text_has_relocs = 1;
699
				    flat_reloc_count++;
700
				    break;
701
 
702
				case R_BFIN_BYTE4_DATA:
703
				    sym_vma = bfd_section_vma(abs_bfd, sym_section);
704
				    sym_addr += sym_vma + q->addend;
705
 
706
				    if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
707
					continue;
708
 
709
				    flat_relocs = (uint32_t *)
710
					(realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t)));
711
				    if (bfin_set_reloc (flat_relocs + flat_reloc_count,
712
							sym_section->name, sym_name,
713
							(*(q->sym_ptr_ptr)),
714
							2, section_vma + q->address))
715
					bad_relocs++;
716
				    if (a->flags & SEC_CODE)
717
					text_has_relocs = 1;
718
 
719
				    flat_reloc_count++;
720
				    break;
721
#else
722
				default:
723
					/* The default is to assume that the
724
					   relocation is relative and has
725
					   already been fixed up by the
726
					   linker (perhaps we ought to make
727
					   give an error by default, and
728
					   require `safe' relocations to be
729
					   enumberated explicitly?).  */
730
					goto good_32bit_resolved_reloc;
731
#endif
732
				good_32bit_resolved_reloc:
733
					if (bfd_big_endian (abs_bfd))
734
						sym_addr =
735
							(r_mem[0] << 24)
736
							+ (r_mem[1] << 16)
737
							+ (r_mem[2] << 8) 
738
							+ r_mem[3];
739
					else
740
						sym_addr =
741
							r_mem[0]
742
							+ (r_mem[1] << 8)
743
							+ (r_mem[2] << 16)
744
							+ (r_mem[3] << 24);
745
					relocation_needed = 1;
746
					break;
747
 
748
				bad_resolved_reloc:
749
					printf("ERROR: reloc type %s unsupported in this context\n",
750
					       q->howto->name);
751
					bad_relocs++;
752
					break;
753
				}
754
			} else {
755
				/* Calculate the sym address ourselves.  */
756
				sym_reloc_size = bfd_get_reloc_size(q->howto);
757
 
758
#if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin) && !defined(TARGET_m68k)
759
				if (sym_reloc_size != 4) {
760
					printf("ERROR: bad reloc type %d size=%d for symbol=%s\n",
761
							(*p)->howto->type, sym_reloc_size, sym_name);
762
					bad_relocs++;
763
					rc = -1;
764
					continue;
765
				}
766
#endif
767
 
768
				switch ((*p)->howto->type) {
769
 
770
#if defined(TARGET_m68k)
771
				case R_68K_32:
772
					relocation_needed = 1;
773
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
774
					sym_addr += sym_vma + q->addend;
775
					break;
776
				case R_68K_PC16:
777
				case R_68K_PC32:
778
					sym_vma = 0;
779
					sym_addr += sym_vma + q->addend;
780
					sym_addr -= q->address;
781
					break;
782
#endif
783
 
784
#if defined(TARGET_arm)
785
				case R_ARM_ABS32:
786
					relocation_needed = 1;
787
					if (verbose)
788
						fprintf(stderr,
789
							"%s vma=0x%x, value=0x%x, address=0x%x "
790
							"sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
791
							"ABS32",
792
							sym_vma, (*(q->sym_ptr_ptr))->value,
793
							q->address, sym_addr,
794
							(*p)->howto->rightshift,
795
							*(uint32_t *)r_mem);
796
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
797
					sym_addr += sym_vma + q->addend;
798
					break;
799
				case R_ARM_GOT32:
800
				case R_ARM_GOTPC:
801
					/* Should be fine as is */
802
					break;
803
				case R_ARM_PLT32:
804
					if (verbose)
805
						fprintf(stderr,
806
							"%s vma=0x%x, value=0x%x, address=0x%x "
807
							"sym_addr=0x%x rs=0x%x, opcode=0x%x\n",
808
							"PLT32",
809
							sym_vma, (*(q->sym_ptr_ptr))->value,
810
							q->address, sym_addr,
811
							(*p)->howto->rightshift,
812
							*(uint32_t *)r_mem);
813
				case R_ARM_PC24:
814
					sym_vma = 0;
815
					sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;
816
					break;
817
#endif
818
 
819
#ifdef TARGET_v850
820
				case R_V850_32:
821
					relocation_needed = 1;
822
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
823
					sym_addr += sym_vma + q->addend;
824
					break;
825
#if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
826
#ifdef R_V850_ZDA_16_16_OFFSET
827
				case R_V850_ZDA_16_16_OFFSET:
828
#endif
829
#ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
830
				case R_V850_ZDA_16_16_SPLIT_OFFSET:
831
#endif
832
					/* Can't support zero-relocations.  */
833
					printf ("ERROR: %s+0x%x: zero relocations not supported\n",
834
							sym_name, q->addend);
835
					continue;
836
#endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
837
#endif /* TARGET_v850 */
838
 
839
#ifdef TARGET_h8300
840
				case R_H8_DIR24R8:
841
					if (sym_reloc_size != 4) {
842
						printf("R_H8_DIR24R8 size %d\n", sym_reloc_size);
843
						bad_relocs++;
844
						continue;
845
					}
846
					relocation_needed = 1;
847
					sym_addr = (*(q->sym_ptr_ptr))->value;
848
					q->address -= 1;
849
					r_mem -= 1; /* tracks q->address */
850
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
851
					sym_addr += sym_vma + q->addend;
852
					sym_addr |= (*(unsigned char *)r_mem<<24);
853
					break;
854
				case R_H8_DIR24A8:
855
					if (sym_reloc_size != 4) {
856
						printf("R_H8_DIR24A8 size %d\n", sym_reloc_size);
857
						bad_relocs++;
858
						continue;
859
					}
860
					/* Absolute symbol done not relocation */
861
					relocation_needed = !bfd_is_abs_section(sym_section);
862
					sym_addr = (*(q->sym_ptr_ptr))->value;
863
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
864
					sym_addr += sym_vma + q->addend;
865
					break;
866
				case R_H8_DIR32:
867
				case R_H8_DIR32A16: /* currently 32,  could be made 16 */
868
					if (sym_reloc_size != 4) {
869
						printf("R_H8_DIR32 size %d\n", sym_reloc_size);
870
						bad_relocs++;
871
						continue;
872
					}
873
					relocation_needed = 1;
874
					sym_addr = (*(q->sym_ptr_ptr))->value;
875
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
876
					sym_addr += sym_vma + q->addend;
877
					break;
878
				case R_H8_PCREL16:
879
					sym_vma = 0;
880
					sym_addr = (*(q->sym_ptr_ptr))->value;
881
					sym_addr += sym_vma + q->addend;
882
					sym_addr -= (q->address + 2);
883
					if (bfd_big_endian(abs_bfd))
884
					*(unsigned short *)r_mem =
885
						bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr;
886
					continue;
887
				case R_H8_PCREL8:
888
					sym_vma = 0;
889
					sym_addr = (*(q->sym_ptr_ptr))->value;
890
					sym_addr += sym_vma + q->addend;
891
					sym_addr -= (q->address + 1);
892
					*(unsigned char *)r_mem = sym_addr;
893
					continue;
894
#endif
895
 
896
#ifdef TARGET_microblaze
897
				case R_MICROBLAZE_64:
898
		/* The symbol is split over two consecutive instructions.  
899
		   Flag this to the flat loader by setting the high bit of 
900
		   the relocation symbol. */
901
				{
902
					unsigned char *p = r_mem;
903
					pflags=0x80000000;
904
 
905
					/* work out the relocation */
906
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
907
					sym_addr += sym_vma + q->addend;
908
					/* Write relocated pointer back */
909
					p[2] = (sym_addr >> 24) & 0xff;
910
					p[3] = (sym_addr >> 16) & 0xff;
911
					p[6] = (sym_addr >>  8) & 0xff;
912
					p[7] =  sym_addr        & 0xff;
913
 
914
					/* create a new reloc entry */
915
					flat_relocs = realloc(flat_relocs,
916
						(flat_reloc_count + 1) * sizeof(uint32_t));
917
					flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
918
					flat_reloc_count++;
919
					relocation_needed = 0;
920
					pflags = 0;
921
			sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
922
					 bfd_section_vma(abs_bfd, sym_section));
923
			if (verbose)
924
				printf("  RELOC[%d]: offset=0x%x symbol=%s%s "
925
					"section=%s size=%d "
926
					"fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
927
					q->address, sym_name, addstr,
928
					section_name, sym_reloc_size,
929
					sym_addr, section_vma + q->address);
930
			if (verbose)
931
				printf("reloc[%d] = 0x%x\n", flat_reloc_count,
932
					 section_vma + q->address);
933
 
934
					continue;
935
				}
936
				case R_MICROBLAZE_32:
937
				{	
938
					unsigned char *p = r_mem;
939
 
940
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
941
					sym_addr += sym_vma + q->addend;
942
					relocation_needed = 1;
943
					break;
944
				}
945
				case R_MICROBLAZE_64_PCREL:
946
					sym_vma = 0;
947
					sym_addr += sym_vma + q->addend;
948
					sym_addr -= (q->address + 4);
949
					sym_addr = htonl(sym_addr);
950
					/* insert 16 MSB */
951
					* ((unsigned short *) (r_mem+2)) = (sym_addr) & 0xFFFF;
952
					/* then 16 LSB */
953
					* ((unsigned short *) (r_mem+6)) = (sym_addr >> 16) & 0xFFFF;
954
					/* We've done all the work, so continue
955
					   to next reloc instead of break */
956
					continue;
957
 
958
#endif /* TARGET_microblaze */
959
 
960
#ifdef TARGET_nios2
961
#define  htoniosl(x)	(x)
962
#define  niostohl(x)	(x)
963
				case R_NIOS2_BFD_RELOC_32:
964
					relocation_needed = 1;
965
					pflags = (FLAT_NIOS2_R_32 << 28);
966
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
967
					sym_addr += sym_vma + q->addend;
968
					/* modify target, in target order */
969
					*(unsigned long *)r_mem = htoniosl(sym_addr);
970
					break;
971
				case R_NIOS2_CALL26:
972
				{
973
					unsigned long exist_val;
974
					relocation_needed = 1;
975
					pflags = (FLAT_NIOS2_R_CALL26 << 28);
976
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
977
					sym_addr += sym_vma + q->addend;
978
 
979
					/* modify target, in target order */
980
					// exist_val = niostohl(*(unsigned long *)r_mem);
981
					exist_val = ((sym_addr >> 2) << 6);
982
					*(unsigned long *)r_mem = htoniosl(exist_val);
983
					break;
984
				}
985
				case R_NIOS2_HIADJ16:
986
				case R_NIOS2_HI16:
987
				{
988
					unsigned long exist_val;
989
					int r2_type;
990
					/* handle the adjacent HI/LO pairs */
991
					if (relcount == 0)
992
						r2_type = R_NIOS2_NONE;
993
					else
994
						r2_type = p[1]->howto->type;
995
					if ((r2_type == R_NIOS2_LO16)
996
					    && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr)
997
					    && (p[0]->addend == p[1]->addend)) 
998
					    {
999
							unsigned char * r2_mem = sectionp + p[1]->address;
1000
							if (p[1]->address - q->address!=4)
1001
								printf("Err: HI/LO not adjacent %d\n", p[1]->address - q->address);
1002
							relocation_needed = 1;
1003
							pflags = (q->howto->type == R_NIOS2_HIADJ16) 
1004
								? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO;
1005
							pflags <<= 28;
1006
 
1007
							sym_vma = bfd_section_vma(abs_bfd, sym_section);
1008
							sym_addr += sym_vma + q->addend;
1009
 
1010
							/* modify high 16 bits, in target order */
1011
							exist_val = niostohl(*(unsigned long *)r_mem);
1012
							exist_val =  ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1013
							if (q->howto->type == R_NIOS2_HIADJ16)
1014
								exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6);
1015
							else
1016
								exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6);
1017
							*(unsigned long *)r_mem = htoniosl(exist_val);
1018
 
1019
							/* modify low 16 bits, in target order */
1020
							exist_val = niostohl(*(unsigned long *)r2_mem);
1021
							exist_val =  ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1022
							exist_val |= ((sym_addr & 0xFFFF) << 6);
1023
							*(unsigned long *)r2_mem = htoniosl(exist_val);
1024
 
1025
						} else 
1026
							goto NIOS2_RELOC_ERR;
1027
					}
1028
					break;
1029
 
1030
				case R_NIOS2_GPREL:
1031
				{
1032
					unsigned long exist_val, temp;
1033
					//long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols);
1034
					long gp = get_gp_value(symbols, number_of_symbols);
1035
					if (gp == -1) {
1036
						printf("Err: unresolved symbol _gp when relocating %s\n", sym_name);
1037
						goto NIOS2_RELOC_ERR;
1038
					}
1039
					/* _gp holds a absolute value, otherwise the ld cannot generate correct code */
1040
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
1041
					//printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp);
1042
					sym_addr += sym_vma + q->addend;
1043
					sym_addr -= gp;
1044
					//printf("sym - _gp=%x, %d\n", sym_addr, sym_addr);
1045
					/* modify the target, in target order (little_endian) */
1046
					exist_val = niostohl(*(unsigned long *)r_mem);
1047
					temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff);
1048
					temp <<= 6;
1049
					temp |= (exist_val & 0x3f);
1050
					*(unsigned long *)r_mem = htoniosl(temp);
1051
					if (verbose)
1052
						printf("omit: offset=0x%x symbol=%s%s "
1053
								"section=%s size=%d "
1054
								"fixup=0x%x (reloc=0x%x) GPREL\n", 
1055
								q->address, sym_name, addstr,
1056
								section_name, sym_reloc_size,
1057
								sym_addr, section_vma + q->address);
1058
					continue;
1059
				}
1060
				case R_NIOS2_PCREL16:
1061
				{
1062
					unsigned long exist_val;
1063
					sym_vma = 0;
1064
					sym_addr += sym_vma + q->addend;
1065
					sym_addr -= (q->address + 4);
1066
					/* modify the target, in target order (little_endian) */
1067
					exist_val = niostohl(*(unsigned long *)r_mem);
1068
					exist_val =  ((exist_val >> 22) << 22) | (exist_val & 0x3f);
1069
					exist_val |= ((sym_addr & 0xFFFF) << 6);
1070
					*(unsigned long *)r_mem = htoniosl(exist_val);
1071
					if (verbose)
1072
						printf("omit: offset=0x%x symbol=%s%s "
1073
								"section=%s size=%d "
1074
								"fixup=0x%x (reloc=0x%x) PCREL\n", 
1075
								q->address, sym_name, addstr,
1076
								section_name, sym_reloc_size,
1077
								sym_addr, section_vma + q->address);
1078
					continue;
1079
				}
1080
 
1081
				case R_NIOS2_LO16:
1082
					/* check if this is actually the 2nd half of a pair */
1083
					if ((p > relpp)
1084
						&& ((p[-1]->howto->type == R_NIOS2_HIADJ16) 
1085
							|| (p[-1]->howto->type == R_NIOS2_HI16))
1086
					    && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr)
1087
					    && (p[-1]->addend == p[0]->addend)) {
1088
						if (verbose)
1089
							printf("omit: offset=0x%x symbol=%s%s "
1090
								"section=%s size=%d LO16\n", 
1091
								q->address, sym_name, addstr,
1092
								section_name, sym_reloc_size);
1093
						continue;
1094
					}
1095
 
1096
					/* error, fall through */
1097
 
1098
				case R_NIOS2_S16:
1099
				case R_NIOS2_U16:
1100
				case R_NIOS2_CACHE_OPX:
1101
				case R_NIOS2_IMM5:
1102
				case R_NIOS2_IMM6:
1103
				case R_NIOS2_IMM8:
1104
				case R_NIOS2_BFD_RELOC_16:
1105
				case R_NIOS2_BFD_RELOC_8:
1106
				case R_NIOS2_GNU_VTINHERIT:
1107
				case R_NIOS2_GNU_VTENTRY:
1108
				case R_NIOS2_UJMP:
1109
				case R_NIOS2_CJMP:
1110
				case R_NIOS2_CALLR:
1111
NIOS2_RELOC_ERR:
1112
					printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type);
1113
					bad_relocs++;
1114
					continue;
1115
#endif /* TARGET_nios2 */
1116
 
1117
#ifdef TARGET_sparc
1118
				case R_SPARC_32:
1119
				case R_SPARC_UA32:
1120
					relocation_needed = 1;
1121
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
1122
					sym_addr += sym_vma + q->addend;
1123
					break;
1124
				case R_SPARC_PC22:
1125
					sym_vma = 0;
1126
					sym_addr += sym_vma + q->addend;
1127
					sym_addr -= q->address;
1128
					break;
1129
				case R_SPARC_WDISP30:
1130
					sym_addr = (((*(q->sym_ptr_ptr))->value-
1131
						q->address) >> 2) & 0x3fffffff;
1132
					sym_addr |= (
1133
						ntohl(*(uint32_t *)r_mem)
1134
						& 0xc0000000
1135
						);
1136
					break;
1137
				case R_SPARC_HI22:
1138
					relocation_needed = 1;
1139
					pflags = 0x80000000;
1140
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
1141
					sym_addr += sym_vma + q->addend;
1142
					sym_addr |= (
1143
						htonl(*(uint32_t *)r_mem)
1144
						& 0xffc00000
1145
						);
1146
					break;
1147
				case R_SPARC_LO10:
1148
					relocation_needed = 1;
1149
					pflags = 0x40000000;
1150
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
1151
					sym_addr += sym_vma + q->addend;
1152
					sym_addr &= 0x000003ff;
1153
					sym_addr |= (
1154
						htonl(*(uint32_t *)r_mem)
1155
						& 0xfffffc00
1156
						);
1157
					break;
1158
#endif /* TARGET_sparc */
1159
 
1160
 
1161
#ifdef TARGET_sh
1162
				case R_SH_DIR32:
1163
					relocation_needed = 1;
1164
					sym_vma = bfd_section_vma(abs_bfd, sym_section);
1165
					sym_addr += sym_vma + q->addend;
1166
					break;
1167
				case R_SH_REL32:
1168
					sym_vma = 0;
1169
					sym_addr += sym_vma + q->addend;
1170
					sym_addr -= q->address;
1171
					break;
1172
#endif /* TARGET_sh */
1173
 
1174
#ifdef TARGET_e1
1175
#define  htoe1l(x)              htonl(x)
1176
 
1177
#if 0 
1178
#define  DEBUG_E1
1179
#endif
1180
 
1181
#ifdef   DEBUG_E1
1182
#define  DBG_E1                 printf
1183
#else
1184
#define  DBG_E1(x, ...  )
1185
#endif
1186
 
1187
#define _32BITS_RELOC 0x00000000
1188
#define _30BITS_RELOC 0x80000000
1189
#define _28BITS_RELOC 0x40000000
1190
					{
1191
				char *p;
1192
				unsigned long   sec_vma, exist_val, S;
1193
				case R_E1_CONST31:
1194
						relocation_needed = 1;
1195
						DBG_E1("Handling Reloc <CONST31>\n");
1196
						sec_vma = bfd_section_vma(abs_bfd, sym_section);
1197
						DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1198
										sec_vma, sym_addr, q->address);
1199
						sym_addr = sec_vma + sym_addr;
1200
						exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);        
1201
						DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1202
						exist_val = htoe1l(exist_val);
1203
						DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1204
						sym_addr += exist_val;
1205
						pflags = _30BITS_RELOC;
1206
						break;
1207
				case R_E1_CONST31_PCREL:
1208
						relocation_needed = 0;
1209
						DBG_E1("Handling Reloc <CONST31_PCREL>\n");
1210
						DBG_E1("DONT RELOCATE AT LOADING\n");
1211
						sec_vma = bfd_section_vma(abs_bfd, sym_section);
1212
						DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1213
										sec_vma, sym_addr, q->address);
1214
						sym_addr =  sec_vma + sym_addr;
1215
						DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1216
 
1217
						DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1218
																		section_vma );
1219
						q->address = q->address + section_vma;
1220
						DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1221
 
1222
						if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1223
								DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1224
						DBG_E1( "sym_addr := sym_addr - q->address  - "
1225
								"sizeof(CONST31_PCREL): [0x%x]\n",
1226
								sym_addr );
1227
						exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);              
1228
						DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1229
						exist_val = htoe1l(exist_val);
1230
						DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1231
						sym_addr |= exist_val;
1232
						DBG_E1("sym_addr |=  exist_val) : [0x%x]\n", sym_addr );
1233
						break;
1234
				case R_E1_DIS29W_PCREL:
1235
						relocation_needed = 0;
1236
						DBG_E1("Handling Reloc <DIS29W_PCREL>\n");
1237
						DBG_E1("DONT RELOCATE AT LOADING\n");
1238
						sec_vma = bfd_section_vma(abs_bfd, sym_section);
1239
						DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n",
1240
										sec_vma, sym_addr, q->address);
1241
						sym_addr =  sec_vma + sym_addr;
1242
						DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1243
 
1244
						DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1245
																		section_vma );
1246
						q->address = q->address + section_vma;
1247
						DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1248
 
1249
						if( (sym_addr = (sym_addr - q->address - 6)) < 0 )
1250
								DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1251
						DBG_E1( "sym_addr := sym_addr - q->address  - "
1252
								"sizeof(CONST31_PCREL): [0x%x]\n",
1253
								sym_addr );
1254
						DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1255
						exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);       
1256
						DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1257
						exist_val = htoe1l(exist_val);
1258
						DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1259
						sym_addr += exist_val;
1260
						break;
1261
				case R_E1_DIS29W:
1262
						DBG_E1("Handling Reloc <DIS29W>\n");
1263
						goto DIS29_RELOCATION;
1264
				case R_E1_DIS29H:
1265
						DBG_E1("Handling Reloc <DIS29H>\n");
1266
						goto DIS29_RELOCATION;
1267
				case R_E1_DIS29B:
1268
						DBG_E1("Handling Reloc <DIS29B>\n");
1269
DIS29_RELOCATION:
1270
						relocation_needed = 1;
1271
						sec_vma = bfd_section_vma(abs_bfd, sym_section);
1272
						DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n",
1273
										sec_vma, sym_addr);
1274
						sym_addr =  sec_vma + sym_addr;
1275
						DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%08x]\n", sym_addr);
1276
						exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);                
1277
						DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1278
						exist_val = htoe1l(exist_val);
1279
						DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1280
						sym_addr +=  exist_val;
1281
						DBG_E1("sym_addr +=  exist_val : [0x%08x]\n", sym_addr);
1282
						pflags = _28BITS_RELOC;
1283
						break;
1284
				case R_E1_IMM32_PCREL:
1285
						relocation_needed = 0;
1286
						DBG_E1("Handling Reloc <IMM32_PCREL>\n");
1287
						DBG_E1("DONT RELOCATE AT LOADING\n");
1288
						sec_vma = bfd_section_vma(abs_bfd, sym_section);
1289
						DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1290
										sec_vma, sym_addr);
1291
						sym_addr =  sec_vma + sym_addr;
1292
 
1293
						DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1294
						DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address,
1295
																		section_vma );
1296
						q->address = q->address + section_vma;
1297
						DBG_E1("q->address += section_vma : 0x%x\n", q->address );
1298
 
1299
						if( (sym_addr = (sym_addr - q->address - 6 )) < 0 )
1300
								DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n");
1301
						DBG_E1( "sym_addr := sym_addr - q->address  - "
1302
								"sizeof(CONST31_PCREL): [0x%x]\n",
1303
								sym_addr );
1304
						DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1305
						exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);                 
1306
 						DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1307
						exist_val = htoe1l(exist_val);
1308
						DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1309
						sym_addr += exist_val;
1310
						break;
1311
				case R_E1_IMM32:
1312
						relocation_needed = 1;
1313
						DBG_E1("Handling Reloc <IMM32>\n");
1314
						sec_vma = bfd_section_vma(abs_bfd, sym_section);
1315
						DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1316
										sec_vma, sym_addr);
1317
						sym_addr =  sec_vma + sym_addr;
1318
						DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1319
						DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address );
1320
						exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2);                     
1321
	 					DBG_E1("Original:exist_val : [0x%08x]\n",exist_val);
1322
						exist_val = htoe1l(exist_val);
1323
						DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val);
1324
						sym_addr += exist_val;
1325
						pflags = _32BITS_RELOC;
1326
						break;
1327
				case R_E1_WORD:
1328
						relocation_needed = 1;
1329
						DBG_E1("Handling Reloc <WORD>\n");
1330
						sec_vma = bfd_section_vma(abs_bfd, sym_section);
1331
						DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n",
1332
										sec_vma, sym_addr);
1333
						sym_addr =  sec_vma + sym_addr;
1334
						DBG_E1("sym_addr =  sec_vma + sym_addr : [0x%x]\n", sym_addr );
1335
						exist_val = *(unsigned long*)((unsigned long)sectionp + q->address );
1336
						DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val);
1337
						exist_val = htoe1l(exist_val);
1338
						DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val);
1339
						sym_addr +=  exist_val;
1340
						DBG_E1("sym_addr +=  exist_val : [0x%08x]\n", sym_addr);
1341
						pflags = _32BITS_RELOC;
1342
						break;
1343
				}
1344
#undef _32BITS_RELOC
1345
#undef _30BITS_RELOC
1346
#undef _28BITS_RELOC
1347
#endif
1348
				default:
1349
					/* missing support for other types of relocs */
1350
					printf("ERROR: bad reloc type %d\n", (*p)->howto->type);
1351
					bad_relocs++;
1352
					continue;
1353
				}
1354
			}
1355
 
1356
			sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
1357
					 bfd_section_vma(abs_bfd, sym_section));
1358
 
1359
 
1360
			/*
1361
			 * for full elf relocation we have to write back the
1362
			 * start_code relative value to use.
1363
			 */
1364
			if (!pic_with_got) {
1365
#if defined(TARGET_arm)
1366
				union {
1367
					unsigned char c[4];
1368
					uint32_t l;
1369
				} tmp;
1370
				int32_t hl;
1371
				int i0, i1, i2, i3;
1372
 
1373
				/*
1374
				 * horrible nasty hack to support different endianess
1375
				 */
1376
				if (!bfd_big_endian(abs_bfd)) {
1377
					i0 = 0;
1378
					i1 = 1;
1379
					i2 = 2;
1380
					i3 = 3;
1381
				} else {
1382
					i0 = 3;
1383
					i1 = 2;
1384
					i2 = 1;
1385
					i3 = 0;
1386
				}
1387
 
1388
				tmp.l = *(uint32_t *)r_mem;
1389
				hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16);
1390
				if (use_resolved ||
1391
					(((*p)->howto->type != R_ARM_PC24) &&
1392
					((*p)->howto->type != R_ARM_PLT32)))
1393
					hl |= (tmp.c[i3] << 24);
1394
				else if (tmp.c[i2] & 0x80)
1395
					hl |= 0xff000000; /* sign extend */
1396
				if (!use_resolved)
1397
					hl += sym_addr;
1398
				tmp.c[i0] = hl & 0xff;
1399
				tmp.c[i1] = (hl >> 8) & 0xff;
1400
				tmp.c[i2] = (hl >> 16) & 0xff;
1401
				if (use_resolved ||
1402
					(((*p)->howto->type != R_ARM_PC24) &&
1403
					((*p)->howto->type != R_ARM_PLT32)))
1404
					tmp.c[i3] = (hl >> 24) & 0xff;
1405
				if ((*p)->howto->type == R_ARM_ABS32)
1406
					*(uint32_t *)r_mem = htonl(hl);
1407
				else
1408
					*(uint32_t *)r_mem = tmp.l;
1409
#elif defined(TARGET_e1)
1410
#define OPCODE_SIZE 2           /* Add 2 bytes, counting the opcode size*/
1411
				switch ((*p)->howto->type) {
1412
				case R_E1_CONST31:
1413
				case R_E1_CONST31_PCREL:
1414
				case R_E1_DIS29W_PCREL:
1415
				case R_E1_DIS29W:
1416
				case R_E1_DIS29H:
1417
				case R_E1_DIS29B:
1418
				case R_E1_IMM32_PCREL:
1419
				case R_E1_IMM32:
1420
						DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n",
1421
								(sectionp + q->address + 2), sym_addr );
1422
						*((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) =
1423
						htonl(sym_addr);
1424
				break;
1425
				case R_E1_WORD:
1426
						DBG_E1("In addr : [0x%x] <- write [0x%x]\n",
1427
								(sectionp + q->address), sym_addr );
1428
						*((unsigned long *) (sectionp + q->address )) = htonl(sym_addr);
1429
				break;
1430
				default:
1431
						printf("ERROR:Unhandled Relocation. Exiting...\n");
1432
						exit(0);
1433
				break;
1434
				}
1435
#elif defined TARGET_bfin
1436
				if ((*p)->howto->type == R_BFIN_RIMM16
1437
				    || (*p)->howto->type == R_BFIN_HUIMM16
1438
				    || (*p)->howto->type == R_BFIN_LUIMM16)
1439
				{
1440
					/* for l and h we set the lower 16 bits which is only when it will be used */
1441
					bfd_putl16 (sym_addr, sectionp + q->address);
1442
				} else if ((*p)->howto->type == R_BFIN_BYTE4_DATA) {
1443
					bfd_putl32 (sym_addr, sectionp + q->address);
1444
				}
1445
#else /* ! TARGET_arm && ! TARGET_e1 && ! TARGET_bfin */
1446
 
1447
				switch (q->howto->type) {
1448
#ifdef TARGET_v850
1449
				case R_V850_HI16_S:
1450
				case R_V850_HI16:
1451
				case R_V850_LO16:
1452
					/* Do nothing -- for cases we handle,
1453
					   the bits produced by the linker are
1454
					   what we want in the final flat file
1455
					   (and other cases are errors).  Note
1456
					   that unlike most relocated values,
1457
					   it is stored in little-endian order,
1458
					   but this is necessary to avoid
1459
					   trashing the low-bit, and the float
1460
					   loaders knows about it.  */
1461
					break;
1462
#endif /* TARGET_V850 */
1463
 
1464
#ifdef TARGET_nios2
1465
				case R_NIOS2_BFD_RELOC_32:
1466
				case R_NIOS2_CALL26:
1467
				case R_NIOS2_HIADJ16:
1468
				case R_NIOS2_HI16:
1469
					/* do nothing */
1470
					break;
1471
#endif /* TARGET_nios2 */
1472
 
1473
#if defined(TARGET_m68k)
1474
				case R_68K_PC16:
1475
					if (sym_addr < -0x8000 || sym_addr > 0x7fff) {
1476
						fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name);
1477
						bad_relocs++;
1478
					} else {
1479
						r_mem[0] = (sym_addr >>  8) & 0xff;
1480
						r_mem[1] =  sym_addr        & 0xff;
1481
					}
1482
					break;
1483
#endif
1484
 
1485
				default:
1486
					/* The alignment of the build host
1487
					   might be stricter than that of the
1488
					   target, so be careful.  We store in
1489
					   network byte order. */
1490
					r_mem[0] = (sym_addr >> 24) & 0xff;
1491
					r_mem[1] = (sym_addr >> 16) & 0xff;
1492
					r_mem[2] = (sym_addr >>  8) & 0xff;
1493
					r_mem[3] =  sym_addr        & 0xff;
1494
				}
1495
#endif /* !TARGET_arm */
1496
			}
1497
 
1498
			if (verbose)
1499
				printf("  RELOC[%d]: offset=0x%x symbol=%s%s "
1500
					"section=%s size=%d "
1501
					"fixup=0x%x (reloc=0x%x)\n", flat_reloc_count,
1502
					q->address, sym_name, addstr,
1503
					section_name, sym_reloc_size,
1504
					sym_addr, section_vma + q->address);
1505
 
1506
			/*
1507
			 *	Create relocation entry (PC relative doesn't need this).
1508
			 */
1509
			if (relocation_needed) {
1510
#ifndef TARGET_bfin
1511
				flat_relocs = realloc(flat_relocs,
1512
					(flat_reloc_count + 1) * sizeof(uint32_t));
1513
#ifndef TARGET_e1
1514
				flat_relocs[flat_reloc_count] = pflags |
1515
					(section_vma + q->address);
1516
 
1517
				if (verbose)
1518
					printf("reloc[%d] = 0x%x\n", flat_reloc_count,
1519
							section_vma + q->address);
1520
#else
1521
				switch ((*p)->howto->type) {
1522
				case R_E1_CONST31:
1523
				case R_E1_CONST31_PCREL:
1524
				case R_E1_DIS29W_PCREL:
1525
				case R_E1_DIS29W:
1526
				case R_E1_DIS29H:
1527
				case R_E1_DIS29B:
1528
				case R_E1_IMM32_PCREL:
1529
				case R_E1_IMM32:
1530
				flat_relocs[flat_reloc_count] = pflags |
1531
						(section_vma + q->address + OPCODE_SIZE);
1532
				if (verbose)
1533
						printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1534
										 flat_relocs[flat_reloc_count] );
1535
				break;
1536
				case R_E1_WORD:
1537
				flat_relocs[flat_reloc_count] = pflags |
1538
						(section_vma + q->address);
1539
				if (verbose)
1540
						printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count,
1541
										 flat_relocs[flat_reloc_count] );
1542
				break;
1543
				}
1544
#endif
1545
				flat_reloc_count++;
1546
#endif //TARGET_bfin
1547
				relocation_needed = 0;
1548
				pflags = 0;
1549
			}
1550
 
1551
#if 0
1552
printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n",
1553
	__FILE__, __LINE__, sym_name, q->address, section_name,
1554
	flat_relocs[flat_reloc_count]);
1555
#endif
1556
		}
1557
	}
1558
  }
1559
 
1560
  if (bad_relocs) {
1561
	  printf("%d bad relocs\n", bad_relocs);
1562
	  exit(1);
1563
  }
1564
 
1565
  if (rc < 0)
1566
	return(0);
1567
 
1568
  *n_relocs = flat_reloc_count;
1569
  return flat_relocs;
1570
}
1571
 
1572
 
1573
 
1574
static void usage(void)
1575
{
1576
    fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] "
1577
	"[-o <output-file>] <elf-file>\n\n"
1578
	"       -v              : verbose operation\n"
1579
	"       -r              : force load to RAM\n"
1580
	"       -k              : enable kernel trace on load (for debug)\n"
1581
	"       -z              : compress code/data/relocs\n"
1582
	"       -d              : compress data/relocs\n"
1583
	"       -a              : use existing symbol references\n"
1584
	"                         instead of recalculating from\n"
1585
	"                         relocation info\n"
1586
        "       -R reloc-file   : read relocations from a separate file\n"
1587
	"       -p abs-pic-file : GOT/PIC processing with files\n"
1588
	"       -s stacksize    : set application stack size\n"
1589
	"       -o output-file  : output file name\n\n",
1590
	elf2flt_progname);
1591
	fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
1592
    exit(2);
1593
}
1594
 
1595
 
1596
/* Write NUM zeroes to STREAM.  */
1597
static void write_zeroes (unsigned long num, stream *stream)
1598
{
1599
  char zeroes[1024];
1600
  if (num > 0) {
1601
    /* It'd be nice if we could just use fseek, but that doesn't seem to
1602
       work for stdio output files.  */
1603
    memset(zeroes, 0x00, 1024);
1604
    while (num > sizeof(zeroes)) {
1605
      fwrite_stream(zeroes, sizeof(zeroes), 1, stream);
1606
      num -= sizeof(zeroes);
1607
    }
1608
    if (num > 0)
1609
      fwrite_stream(zeroes, num, 1, stream);
1610
  }
1611
}
1612
 
1613
 
1614
int main(int argc, char *argv[])
1615
{
1616
  int fd;
1617
  bfd *rel_bfd, *abs_bfd;
1618
  asection *s;
1619
  char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL;
1620
  char *fname = NULL;
1621
  int opt;
1622
  int i;
1623
  int stack;
1624
  stream gf;
1625
 
1626
  asymbol **symbol_table;
1627
  long number_of_symbols;
1628
 
1629
  uint32_t data_len = 0;
1630
  uint32_t bss_len = 0;
1631
  uint32_t text_len = 0;
1632
  uint32_t reloc_len;
1633
 
1634
  uint32_t data_vma = ~0;
1635
  uint32_t bss_vma = ~0;
1636
  uint32_t text_vma = ~0;
1637
 
1638
  uint32_t text_offs;
1639
 
1640
  void *text;
1641
  void *data;
1642
  uint32_t *reloc;
1643
 
1644
  struct flat_hdr hdr;
1645
 
1646
  elf2flt_progname = argv[0];
1647
  xmalloc_set_program_name(elf2flt_progname);
1648
 
1649
  if (argc < 2)
1650
  	usage();
1651
 
1652
  if (sizeof(hdr) != 64)
1653
    fatal(
1654
	    "Potential flat header incompatibility detected\n"
1655
	    "header size should be 64 but is %d",
1656
	    sizeof(hdr));
1657
 
1658
#ifndef TARGET_e1
1659
  stack = 4096;
1660
#else /* We need plenty of stack for both of them (Aggregate and Register) */
1661
  stack = 0x2020;
1662
#endif
1663
 
1664
  while ((opt = getopt(argc, argv, "avzdrkp:s:o:R:")) != -1) {
1665
    switch (opt) {
1666
    case 'v':
1667
      verbose++;
1668
      break;
1669
    case 'r':
1670
      load_to_ram++;
1671
      break;
1672
    case 'k':
1673
      ktrace++;
1674
      break;
1675
    case 'z':
1676
      docompress = 1;
1677
      break;
1678
    case 'd':
1679
      docompress = 2;
1680
      break;
1681
    case 'p':
1682
      pfile = optarg;
1683
      break;
1684
    case 'o':
1685
      ofile = optarg;
1686
      break;
1687
    case 'a':
1688
      use_resolved = 1;
1689
      break;
1690
    case 's':
1691
      if (sscanf(optarg, "%i", &stack) != 1) {
1692
        fprintf(stderr, "%s invalid stack size %s\n", argv[0], optarg);
1693
        usage();
1694
      }
1695
      break;
1696
    case 'R':
1697
      rel_file = optarg;
1698
      break;
1699
    default:
1700
      fprintf(stderr, "%s Unknown option\n", argv[0]);
1701
      usage();
1702
      break;
1703
    }
1704
  }
1705
 
1706
  /*
1707
   * if neither the -r or -p options was given,  default to
1708
   * a RAM load as that is the only option that makes sense.
1709
   */
1710
  if (!load_to_ram && !pfile)
1711
    load_to_ram = 1;
1712
 
1713
  fname = argv[argc-1];
1714
 
1715
  if (pfile) {
1716
    pic_with_got = 1;
1717
    abs_file = pfile;
1718
  } else
1719
    abs_file = fname;
1720
 
1721
  if (! rel_file)
1722
    rel_file = fname;
1723
 
1724
  if (!(rel_bfd = bfd_openr(rel_file, 0)))
1725
    fatal_perror("Can't open '%s'", rel_file);
1726
 
1727
  if (bfd_check_format (rel_bfd, bfd_object) == 0)
1728
    fatal("File is not an object file");
1729
 
1730
  if (abs_file == rel_file)
1731
    abs_bfd = rel_bfd; /* one file does all */
1732
  else {
1733
    if (!(abs_bfd = bfd_openr(abs_file, 0)))
1734
      fatal_perror("Can't open '%s'", abs_file);
1735
 
1736
    if (bfd_check_format (abs_bfd, bfd_object) == 0)
1737
      fatal("File is not an object file");
1738
  }
1739
 
1740
  if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC))
1741
    fatal("%s: Input file contains no relocation info", rel_file);
1742
 
1743
  if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P))
1744
    /* `Absolute' file is not absolute, so neither are address
1745
       contained therein.  */
1746
    fatal("%s: `-a' option specified with non-fully-resolved input file",
1747
	     bfd_get_filename (abs_bfd));
1748
 
1749
  symbol_table = get_symbols(abs_bfd, &number_of_symbols);
1750
 
1751
  /* Group output sections into text, data, and bss, and calc their sizes.  */
1752
  for (s = abs_bfd->sections; s != NULL; s = s->next) {
1753
    uint32_t *vma, *len;
1754
    bfd_size_type sec_size;
1755
    bfd_vma sec_vma;
1756
 
1757
    if (s->flags & SEC_CODE) {
1758
      vma = &text_vma;
1759
      len = &text_len;
1760
    } else if (s->flags & SEC_DATA) {
1761
      vma = &data_vma;
1762
      len = &data_len;
1763
    } else if (s->flags & SEC_ALLOC) {
1764
      vma = &bss_vma;
1765
      len = &bss_len;
1766
    } else
1767
      continue;
1768
 
1769
    sec_size = bfd_section_size(abs_bfd, s);
1770
    sec_vma  = bfd_section_vma(abs_bfd, s);
1771
 
1772
    if (sec_vma < *vma) {
1773
      if (*len > 0)
1774
	*len += sec_vma - *vma;
1775
      else
1776
	*len = sec_size;
1777
      *vma = sec_vma;
1778
    } else if (sec_vma + sec_size > *vma + *len)
1779
      *len = sec_vma + sec_size - *vma;
1780
  }
1781
 
1782
  if (text_len == 0)
1783
    fatal("%s: no .text section", abs_file);
1784
 
1785
  text = xmalloc(text_len);
1786
 
1787
  if (verbose)
1788
    printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
1789
 
1790
  /* Read in all text sections.  */
1791
  for (s = abs_bfd->sections; s != NULL; s = s->next)
1792
    if (s->flags & SEC_CODE) 
1793
      if (!bfd_get_section_contents(abs_bfd, s,
1794
				   text + (s->vma - text_vma), 0,
1795
				   bfd_section_size(abs_bfd, s)))
1796
      {
1797
	fatal("read error section %s", s->name);
1798
      }
1799
 
1800
  if (data_len == 0)
1801
    fatal("%s: no .data section", abs_file);
1802
  data = xmalloc(data_len);
1803
 
1804
  if (verbose)
1805
    printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len);
1806
 
1807
  if ((text_vma + text_len) != data_vma) {
1808
    if ((text_vma + text_len) > data_vma) {
1809
      printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
1810
      exit(1);
1811
    }
1812
    if (verbose)
1813
      printf("WARNING: data=0x%x does not directly follow text=0x%x\n",
1814
	  		data_vma, text_len);
1815
    text_len = data_vma - text_vma;
1816
  }
1817
 
1818
  /* Read in all data sections.  */
1819
  for (s = abs_bfd->sections; s != NULL; s = s->next)
1820
    if (s->flags & SEC_DATA) 
1821
      if (!bfd_get_section_contents(abs_bfd, s,
1822
				   data + (s->vma - data_vma), 0,
1823
				   bfd_section_size(abs_bfd, s)))
1824
      {
1825
	fatal("read error section %s", s->name);
1826
      }
1827
 
1828
  if (bss_vma == ~0)
1829
    bss_vma = data_vma + data_len;
1830
 
1831
  /* Put common symbols in bss.  */
1832
  bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len);
1833
 
1834
  if (verbose)
1835
    printf("BSS  -> vma=0x%x len=0x%x\n", bss_vma, bss_len);
1836
 
1837
  if ((data_vma + data_len) != bss_vma) {
1838
    if ((data_vma + data_len) > bss_vma) {
1839
      printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
1840
	  		data_len, bss_vma);
1841
      exit(1);
1842
    }
1843
    if (verbose)
1844
      printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n",
1845
      		bss_vma, text_len, data_len, text_len + data_len);
1846
    data_len = bss_vma - data_vma;
1847
  }
1848
 
1849
  reloc = (uint32_t *)
1850
    output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len,
1851
		  text, text_len, text_vma, data, data_len, data_vma, rel_bfd);
1852
 
1853
  if (reloc == NULL && verbose)
1854
    printf("No relocations in code!\n");
1855
 
1856
  text_offs = real_address_bits(text_vma);
1857
 
1858
  /* Fill in the binflt_flat header */
1859
  memcpy(hdr.magic,"bFLT",4);
1860
  hdr.rev         = htonl(FLAT_VERSION);
1861
  hdr.entry       = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd));
1862
  hdr.data_start  = htonl(sizeof(hdr) + text_offs + text_len);
1863
  hdr.data_end    = htonl(sizeof(hdr) + text_offs + text_len +data_len);
1864
  hdr.bss_end     = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len);
1865
  hdr.stack_size  = htonl(stack); /* FIXME */
1866
  hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len);
1867
  hdr.reloc_count = htonl(reloc_len);
1868
  hdr.flags       = htonl(0
1869
	  | (load_to_ram || text_has_relocs ? FLAT_FLAG_RAM : 0)
1870
	  | (ktrace ? FLAT_FLAG_KTRACE : 0)
1871
	  | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
1872
	  | (docompress ? (docompress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
1873
	  );
1874
  hdr.build_date = htonl((uint32_t)time(NULL));
1875
  memset(hdr.filler, 0x00, sizeof(hdr.filler));
1876
 
1877
  for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
1878
 
1879
  if (verbose) {
1880
    printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
1881
	text_len, data_len, bss_len);
1882
    if (reloc)
1883
      printf(", relocs=0x%04x", reloc_len);
1884
    printf("\n");
1885
  }
1886
 
1887
  if (!ofile) {
1888
    ofile = xmalloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
1889
    strcpy(ofile, fname);
1890
    strcat(ofile, ".bflt");
1891
  }
1892
 
1893
  if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0)
1894
    fatal_perror("Can't open output file %s", ofile);
1895
 
1896
  write(fd, &hdr, sizeof(hdr));
1897
  close(fd);
1898
 
1899
  if (fopen_stream_u(&gf, ofile, "a" BINARY_FILE_OPTS))
1900
    fatal_perror("Can't open file %s for writing", ofile);
1901
 
1902
  if (docompress == 1)
1903
    reopen_stream_compressed(&gf);
1904
 
1905
  /* Fill in any hole at the beginning of the text segment.  */
1906
  if (verbose)
1907
    printf("ZERO before text len=0x%x\n", text_offs);
1908
  write_zeroes(text_offs, &gf);
1909
 
1910
  /* Write the text segment.  */
1911
  fwrite_stream(text, text_len, 1, &gf);
1912
 
1913
  if (docompress == 2)
1914
    reopen_stream_compressed(&gf);
1915
 
1916
  /* Write the data segment.  */
1917
  fwrite_stream(data, data_len, 1, &gf);
1918
 
1919
  if (reloc)
1920
    fwrite_stream(reloc, reloc_len * 4, 1, &gf);
1921
 
1922
  fclose_stream(&gf);
1923
 
1924
  exit(0);
1925
}
1926
 
1927
 
1928
/*
1929
 * this __MUST__ be at the VERY end of the file - do NOT move!!
1930
 *
1931
 * Local Variables:
1932
 * c-basic-offset: 4
1933
 * tab-width: 8
1934
 * end:
1935
 * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab
1936
 */