Subversion Repositories freemyipod

Rev

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