Subversion Repositories freemyipod

Rev

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