Subversion Repositories freemyipod

Rev

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