Subversion Repositories freemyipod

Rev

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

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