Subversion Repositories freemyipod

Rev

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