2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
21 #include <sys/types.h>
24 #define F_VERBOSE (1 << 0)
25 #define F_NOCONVERT (1 << 1)
27 #if defined(__GNUC__)&&defined(WIN32)
29 #define mkdir(path, mode) mkdir(path)
31 #include <arpa/inet.h>
32 typedef uint32_t ULONG
;
35 typedef uint8_t UBYTE
;
36 typedef uint16_t UWORD
;
37 typedef uint32_t IPTR
;
38 typedef int32_t SIPTR
;
39 typedef char * STRPTR
;
41 #if !defined(FALSE)&&!defined(TRUE)
46 /* Memory allocation flags */
48 #define MEMF_PUBLIC (1L<<0)
49 #define MEMF_CHIP (1L<<1)
50 #define MEMF_FAST (1L<<2)
51 #define MEMF_EXECUTABLE (1L<<4) /* AmigaOS v4 compatible */
52 #define MEMF_LOCAL (1L<<8)
53 #define MEMF_24BITDMA (1L<<9)
54 #define MEMF_KICK (1L<<10)
55 #define MEMF_31BIT (1L<<12) /* Low address space (<2GB). Effective only on 64 bit machines. */
56 #define MEMF_CLEAR (1L<<16) /* Explicitly clear memory after allocation */
57 #define MEMF_LARGEST (1L<<17)
58 #define MEMF_REVERSE (1L<<18)
59 #define MEMF_TOTAL (1L<<19)
60 #define MEMF_HWALIGNED (1L<<20) /* For AllocMem() - align address and size to physical page boundary */
61 #define MEMF_SEM_PROTECTED (1L<<20) /* For CreatePool() - add semaphore protection to the pool */
62 #define MEMF_NO_EXPUNGE (1L<<31)
64 #define HUNKF_ADVISORY (1L<<29)
65 #define HUNKF_CHIP (1L<<30)
66 #define HUNKF_FAST (1L<<31)
67 #define HUNKF_MEMFLAGS (HUNKF_CHIP | HUNKF_FAST)
70 #define HUNK_CODE 1001
71 #define HUNK_DATA 1002
73 #define HUNK_RELOC32 1004
74 #define HUNK_SYMBOL 1008
76 #define HUNK_HEADER 1011
78 #define SHT_PROGBITS 1
84 #define SHT_SYMTAB_SHNDX 18
93 #define EM_X86_64 62 /* AMD x86-64 */
99 /* AMD x86-64 relocations. */
100 #define R_X86_64_NONE 0 /* No reloc */
101 #define R_X86_64_64 1 /* Direct 64 bit */
102 #define R_X86_64_PC32 2 /* PC relative 32 bit signed */
103 #define R_X86_64_32 10
104 #define R_X86_64_32S 11
112 #define R_PPC_ADDR32 1
113 #define R_PPC_ADDR16_LO 4
114 #define R_PPC_ADDR16_HA 6
115 #define R_PPC_REL24 10
116 #define R_PPC_REL32 26
117 #define R_PPC_REL16_LO 250
118 #define R_PPC_REL16_HA 252
122 #define R_ARM_ABS32 2
123 #define R_ARM_CALL 28
124 #define R_ARM_JUMP24 29
125 #define R_ARM_V4BX 40
126 #define R_ARM_PREL31 42
127 #define R_ARM_MOVW_ABS_NC 43
128 #define R_ARM_MOVT_ABS 44
133 #define STT_SECTION 3
135 #define STT_LOPROC 13
136 #define STT_HIPROC 15
139 #define SHN_LORESERVE 0xff00
140 #define SHN_ABS 0xfff1
141 #define SHN_COMMON 0xfff2
142 #define SHN_XINDEX 0xffff
143 #define SHN_HIRESERVE 0xffff
145 #define SHF_WRITE (1 << 0)
146 #define SHF_ALLOC (1 << 1)
147 #define SHF_EXECINSTR (1 << 2)
149 #define ELF_ST_TYPE(i) ((i) & 0x0F)
155 #define ELFDATA2LSB 1
156 #define ELFDATA2MSB 2
160 #define ELFCLASS64 2 /* 64-bit objects */
163 #define EI_ABIVERSION 8
165 #define ELFOSABI_AROS 15
167 #define PF_X (1 << 0)
185 } __attribute__((packed
));
199 } __attribute__((packed
));
213 } __attribute__((packed
));
217 ULONG name
; /* Offset of the name string in the string table */
218 IPTR value
; /* Varies; eg. the offset of the symbol in its hunk */
219 IPTR size
; /* How much memory does the symbol occupy */
220 UBYTE info
; /* What kind of symbol is this ? (global, variable, etc) */
221 UBYTE other
; /* undefined */
222 UWORD shindex
; /* In which section is the symbol defined ? */
223 } __attribute__((packed
));
225 #define ELF_R_SYM(val) ((val) >> 8)
226 #define ELF_R_TYPE(val) ((val) & 0xff)
227 #define ELF_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
231 IPTR offset
; /* Address of the relocation relative to the section it refers to */
232 IPTR info
; /* Type of the relocation */
233 SIPTR addend
; /* Constant addend used to compute value */
236 /* convert section header number to array index */
238 ((n) < SHN_LORESERVE ? (n) : ((n) <= SHN_HIRESERVE ? 0 : (n) - (SHN_HIRESERVE + 1 - SHN_LORESERVE)))
240 /* convert section header array index to section number */
242 ((i) < SHN_LORESERVE ? (i) : (i) + (SHN_HIRESERVE + 1 - SHN_LORESERVE))
244 /* m68k Machine's native values */
245 #define AROS_ELF_CLASS ELFCLASS32
246 #define AROS_ELF_DATA ELFDATA2MSB
247 #define AROS_ELF_MACHINE EM_68K
248 #define AROS_ELF_REL SHT_RELA
251 #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
253 # define VA_START(args, lastarg) va_start(args, lastarg)
255 # include <varargs.h>
256 # define VA_START(args, lastarg) va_start(args)
262 # define PARAMS(x) ()
263 #endif /* PROTOTYPES */
265 static void set_error(int err
)
270 #if defined(DEBUG) && DEBUG
277 #define bug(fmt,args...) fprintf(stderr, fmt ,##args )
279 static int must_swap
= -1;
281 static void eh_fixup(struct elfheader
*eh
)
284 if (eh
->type
== 256) {
286 eh
->type
= ntohs(eh
->type
);
287 eh
->machine
= ntohs(eh
->machine
);
288 eh
->version
= ntohl(eh
->version
);
289 eh
->entry
= ntohl(eh
->entry
);
290 eh
->phoff
= ntohl(eh
->phoff
);
291 eh
->shoff
= ntohl(eh
->shoff
);
292 eh
->flags
= ntohl(eh
->flags
);
293 eh
->ehsize
= ntohs(eh
->ehsize
);
294 eh
->phentsize
= ntohs(eh
->phentsize
);
295 eh
->phnum
= ntohs(eh
->phnum
);
296 eh
->shentsize
= ntohs(eh
->shentsize
);
297 eh
->shnum
= ntohs(eh
->shnum
);
298 eh
->shstrndx
= ntohs(eh
->shstrndx
);
304 static void sh_fixup(struct sheader
*sh
, int n
)
309 for (; n
> 0; n
--, sh
++) {
310 sh
->name
= ntohl(sh
->name
);
311 sh
->type
= ntohl(sh
->type
);
312 sh
->flags
= ntohl(sh
->flags
);
313 sh
->addr
= ntohl(sh
->addr
);
314 sh
->offset
= ntohl(sh
->offset
);
315 sh
->size
= ntohl(sh
->size
);
316 sh
->link
= ntohl(sh
->link
);
317 sh
->info
= ntohl(sh
->info
);
318 sh
->addralign
= ntohl(sh
->addralign
);
319 sh
->entsize
= ntohl(sh
->entsize
);
323 static void rel_fixup(struct relo
*rel
)
328 rel
->offset
= ntohl(rel
->offset
);
329 rel
->info
= ntohl(rel
->info
);
330 rel
->addend
= ntohl(rel
->addend
);
333 void sym_fixup(struct symbol
*sym
)
338 sym
->name
= ntohl(sym
->name
);
339 sym
->value
= ntohl(sym
->value
);
340 sym
->size
= ntohl(sym
->size
);
341 sym
->shindex
= ntohs(sym
->shindex
);
344 static void *load_block (int file
,ULONG offset
,ULONG size
)
346 ULONG lsize
= (size
+ sizeof(ULONG
) - 1) / sizeof(ULONG
);
347 D(bug("[ELF2HUNK] Load Block\n"));
348 D(bug("[ELF2HUNK] (size=%d)\n",(int)size
));
349 void *block
= malloc(lsize
* sizeof(ULONG
));
351 lseek(file
, offset
, SEEK_SET
);
352 if (read(file
, block
, size
) == size
) {
364 static ULONG
read_shnum(int file
, struct elfheader
*eh
)
366 ULONG shnum
= eh
->shnum
;
368 /* the ELF header only uses 16 bits to store the count of section headers,
369 * so it can't handle more than 65535 headers. if the count is 0, and an
370 * offset is defined, then the real count can be found in the first
371 * section header (which always exists).
373 * similarly, if the string table index is SHN_XINDEX, then the actual
374 * index is found in the first section header also.
376 * see the System V ABI 2001-04-24 draft for more details.
382 if (eh
->shoff
== 0) {
387 lseek(file
, eh
->shoff
, SEEK_SET
);
388 if (read(file
, &sh
, sizeof(sh
)) != sizeof(sh
))
393 /* wider section header count is in the size field */
396 /* sanity, if they're still invalid then this isn't elf */
404 static int load_header(int file
, struct elfheader
*eh
)
406 lseek(file
, 0, SEEK_SET
);
407 if (read(file
, eh
, sizeof(struct elfheader
)) != sizeof(struct elfheader
)) {
408 D(bug("[ELF2HUNK] Can't read the %d byte ELF header\n", (int)sizeof(struct elfheader
)));
414 if (eh
->ident
[0] != 0x7f || eh
->ident
[1] != 'E' ||
415 eh
->ident
[2] != 'L' || eh
->ident
[3] != 'F') {
416 D(bug("[ELF2HUNK] Not an ELF object\n"));
419 D(bug("[ELF2HUNK] ELF object\n"));
421 /* WANT_CLASS should be defined for your target */
422 if (eh
->ident
[EI_CLASS
] != AROS_ELF_CLASS
||
423 eh
->ident
[EI_VERSION
] != EV_CURRENT
||
424 eh
->type
!= ET_REL
||
425 eh
->ident
[EI_DATA
] != AROS_ELF_DATA
||
426 eh
->machine
!= AROS_ELF_MACHINE
)
428 D(bug("[ELF2HUNK] Object is of wrong type\n"));
429 D(bug("[ELF2HUNK] EI_CLASS is %d - should be %d\n", eh
->ident
[EI_CLASS
] , AROS_ELF_CLASS
));
430 D(bug("[ELF2HUNK] EI_VERSION is %d - should be %d\n", eh
->ident
[EI_VERSION
], EV_CURRENT
));
431 D(bug("[ELF2HUNK] type is %d - should be %d\n", eh
->type
, ET_REL
));
432 D(bug("[ELF2HUNK] EI_DATA is %d - should be %d\n", eh
->ident
[EI_DATA
] , AROS_ELF_DATA
));
433 D(bug("[ELF2HUNK] machine is %d - should be %d\n", eh
->machine
, AROS_ELF_MACHINE
));
444 ULONG memflags
; /* Memory flags */
445 ULONG size
; /* Size in ULONGs */
448 int hunk
; /* Allocatable hunk ID */
450 ULONG shid
; /* ELF hunk base to add to... */
451 ULONG offset
; /* offset in this hunk. */
458 struct elfheader
*eh
,
463 struct hunkheader
**hh
466 struct sheader
*shrel
= &sh
[shrel_idx
];
467 struct sheader
*shsymtab
= &sh
[SHINDEX(shrel
->link
)];
468 struct sheader
*toreloc
= &sh
[SHINDEX(shrel
->info
)];
470 struct symbol
*symtab
= (struct symbol
*)hh
[SHINDEX(shrel
->link
)]->data
;
471 struct hunkheader
*h
= hh
[SHINDEX(shrel
->info
)];
474 * Ignore relocs if the target section has no allocation. that can happen
475 * eg. with a .debug PROGBITS and a .rel.debug section
477 D(bug("[ELF2HUNK] sh[%d].flags = 0x%x\n", (int)SHINDEX(shrel
->info
), (int)toreloc
->flags
));
478 if (!(toreloc
->flags
& SHF_ALLOC
))
481 ULONG numrel
= shrel
->size
/ shrel
->entsize
;
487 h
->reloc
= realloc(h
->reloc
, h
->relocs
* sizeof(struct hunkreloc
));
488 struct hunkreloc
*hrel
= &h
->reloc
[hrels
];
490 for (i
=0; i
<numrel
; i
++, rel
++)
503 * R_ARM_V4BX are actually special marks for the linker.
504 * They even never have a target (shindex == SHN_UNDEF),
505 * so we simply ignore them before doing any checks.
507 if (ELF_R_TYPE(rel
->info
) == R_ARM_V4BX
)
511 sym
= symtab
[ELF_R_SYM(rel
->info
)];
513 offset
= rel
->offset
;
514 symname
= (const char *)(hh
[SHINDEX(shsymtab
->link
)]->data
+ sym
.name
);
516 if (sym
.shindex
!= SHN_XINDEX
)
517 shindex
= sym
.shindex
;
520 if (symtab_shndx
< 0) {
521 bug("[ELF2HUNK] got symbol with shndx 0xfff, but there's no symtab shndx table\n");
525 shindex
= ntohl(((ULONG
*)hh
[symtab_shndx
]->data
)[ELF_R_SYM(rel
->info
)]);
528 D(bug("[ELF2HUNK] Processing %d symbol %s\n", (int)shindex
, symname
));
534 if (ELF_R_TYPE(rel
->info
) != 0) {
535 bug("[ELF2HUNK] SHN_UNDEF symbol '%s', type %d unsupported\n", symname
, ELF_R_TYPE(rel
->info
));
542 bug("[ELF2HUNK] SHN_COMMON symbol '%s' unsupported\n", symname
);
548 hunk
= ~0; value
= sym
.value
;
552 hunk
= SHINDEX(shindex
);
557 switch (ELF_R_TYPE(rel
->info
))
560 value
+= rel
->addend
;
564 value
+= rel
->addend
- offset
;
568 bug("[ELF2HUNK] Unsupported relocation type R_68K_PC16\n");
577 bug("[ELF2HUNK] Unrecognized relocation type %d %d\n", (int)i
, (int)ELF_R_TYPE(rel
->info
));
582 D(bug("[ELF2HUNK] Hunk %d, offset 0x%x: base 0x%x\n", (int)hunk
, (int)offset
, (int)value
));
583 *(ULONG
*)(h
->data
+ offset
) = htonl(value
+ ntohl(*(ULONG
*)(h
->data
+ offset
)));
589 hrel
->offset
= offset
;
590 hrel
->symbol
= symname
;
597 int reloc_cmp(const void *a
, const void *b
)
599 const struct hunkreloc
*ha
= a
, *hb
= b
;
601 if (ha
->shid
!= hb
->shid
)
602 return hb
->shid
- ha
->shid
;
603 return hb
->offset
- ha
->offset
;
606 static int wlong(int fd
, ULONG val
)
609 return write(fd
, &val
, sizeof(val
));
612 int sym_dump(int hunk_fd
, struct sheader
*sh
, struct hunkheader
**hh
, int shid
, int symtabndx
)
615 struct symbol
*sym
= hh
[symtabndx
]->data
;
616 struct sheader
*symtab
= &sh
[SHINDEX(symtabndx
)];
618 syms
= symtab
->size
/ sizeof(struct symbol
);
623 wlong(hunk_fd
, HUNK_SYMBOL
);
624 wlong(hunk_fd
, syms
);
626 /* Dump symbols for this hunk */
627 for (i
= 0; i
< syms
; i
++) {
635 if (SHINDEX(s
.shindex
) != shid
)
638 name
= (const char *)(hh
[SHINDEX(symtab
->link
)]->data
+ s
.name
);
639 D(bug("\t0x%08x: %s\n", (int)s
.value
, name
));
640 lsize
= (strlen(name
) + 4) / 4;
641 wlong(hunk_fd
, lsize
);
642 err
= write(hunk_fd
, name
, lsize
* 4);
645 wlong(hunk_fd
, s
.value
);
652 static void reloc_dump(int hunk_fd
, struct hunkheader
**hh
, int h
)
656 if (hh
[h
]->relocs
== 0)
659 /* Sort the relocations by reference hunk id */
660 qsort(hh
[h
]->reloc
, hh
[h
]->relocs
, sizeof(hh
[h
]->reloc
[0]), reloc_cmp
);
662 wlong(hunk_fd
, HUNK_RELOC32
);
663 D(bug("\tHUNK_RELOC32: %d relocations\n", (int)hh
[h
]->relocs
));
665 for (i
= 0; i
< hh
[h
]->relocs
; ) {
667 int shid
= hh
[h
]->reloc
[i
].shid
;
668 for (count
= i
; count
< hh
[h
]->relocs
; count
++)
669 if (hh
[h
]->reloc
[count
].shid
!= shid
)
672 wlong(hunk_fd
, count
);
673 D(bug("\t %d relocations relative to Hunk %d\n", count
, hh
[shid
]->hunk
));
674 /* Convert from ELF hunk ID to AOS hunk ID */
675 wlong(hunk_fd
, hh
[shid
]->hunk
);
676 for (; count
> 0; i
++, count
--) {
677 D(bug("\t\t%d: 0x%08x %s\n", i
, (int)hh
[h
]->reloc
[i
].offset
, hh
[h
]->reloc
[i
].symbol
));
678 wlong(hunk_fd
, hh
[h
]->reloc
[i
].offset
);
684 static int copy_to(int in
, int out
)
686 static char buff
[64*1024];
690 len
= read(in
, buff
, sizeof(buff
));
692 perror("Can't read from input file\n");
697 } while ((err
= write(out
, buff
, len
)) == len
);
700 perror("Can't write to output file\n");
707 int elf2hunk(int file
, int hunk_fd
, const char *libname
, int flags
)
709 const __attribute__((unused
)) char *names
[3]={ "CODE", "DATA", "BSS" };
710 struct hunkheader
**hh
;
714 int symtab_shndx
= -1;
717 BOOL exec_hunk_seen
= FALSE
;
721 /* load and validate ELF header */
722 D(bug("Load header\n"));
723 if ((flags
& F_NOCONVERT
) || !load_header(file
, &eh
)) {
724 /* If it's not an ELF, just copy it.
726 * This simplifies a number of mmakefiles
727 * for the m68k-amiga boot and ISO creation
729 lseek(file
, 0, SEEK_SET
);
730 return (copy_to(file
, hunk_fd
) == 0) ? EXIT_SUCCESS
: EXIT_FAILURE
;
733 D(bug("Read SHNum\n"));
734 int_shnum
= read_shnum(file
, &eh
);
738 /* load section headers */
739 D(bug("Load %d Section Headers @0x%08x\n", int_shnum
, (int)eh
.shoff
));
740 if (!(sh
= load_block(file
, eh
.shoff
, int_shnum
* eh
.shentsize
)))
743 sh_fixup(sh
, int_shnum
);
745 /* Looks like we have a valid executable. Generate a
746 * HUNK header set. Not all may be filled in.
748 hh
= calloc(sizeof(*hh
), int_shnum
);
750 /* Look for the string table */
751 D(bug("Look for string table\n"));
752 for (i
= 0; i
< int_shnum
; i
++) {
753 if (sh
[i
].type
== SHT_STRTAB
) {
754 strtab
= load_block(file
, sh
[i
].offset
, sh
[i
].size
);
759 /* Iterate over the section headers in order to do some stuff... */
760 D(bug("Look for symbol tables\n"));
761 for (i
= 0; i
< int_shnum
; i
++)
764 Load the symbol and string table(s).
766 NOTICE: the ELF standard, at the moment (Nov 2002) explicitely states
767 that only one symbol table per file is allowed. However, it
768 also states that this may change in future... we already handle it.
770 D(bug("sh[%d].type = 0x%08x, .offset = 0x%08x, .size = 0x%08x\n",
771 (int)i
, (int)sh
[i
].type
, (int)sh
[i
].offset
, (int)sh
[i
].size
));
772 if (sh
[i
].type
== SHT_SYMTAB
|| sh
[i
].type
== SHT_STRTAB
|| sh
[i
].type
== SHT_SYMTAB_SHNDX
)
774 hh
[i
] = calloc(sizeof(struct hunkheader
), 1);
775 hh
[i
]->type
= (sh
[i
].type
== SHT_SYMTAB
) ? HUNK_SYMBOL
: 0;
778 hh
[i
]->data
= load_block(file
, sh
[i
].offset
, sh
[i
].size
);
782 if (sh
[i
].type
== SHT_SYMTAB_SHNDX
) {
783 if (symtab_shndx
== -1)
786 D(bug("[ELF2HUNK] file contains multiple symtab shndx tables. only using the first one\n"));
790 /* Load the section in memory if needed, and make an hunk out of it */
791 if (sh
[i
].flags
& SHF_ALLOC
&& sh
[i
].size
> 0)
793 hh
[i
] = calloc(sizeof(struct hunkheader
), 1);
794 hh
[i
]->size
= sh
[i
].size
;
795 hh
[i
]->hunk
= hunks
++;
797 if (sh
[i
].type
== SHT_NOBITS
) {
799 hh
[i
]->type
= HUNK_BSS
;
803 if (sh
[i
].flags
& SHF_EXECINSTR
) {
804 hh
[i
]->type
= HUNK_CODE
;
805 exec_hunk_seen
= TRUE
;
807 hh
[i
]->type
= HUNK_DATA
;
809 hh
[i
]->data
= load_block(file
, sh
[i
].offset
, sh
[i
].size
);
815 D(bug("section %s\n", strtab
+ sh
[i
].name
));
816 nameext
= strrchr(strtab
+ sh
[i
].name
, '.');
818 if (strcmp(nameext
, ".MEMF_CHIP")==0) {
819 hh
[i
]->memflags
|= MEMF_CHIP
;
820 } else if (strcmp(nameext
, ".MEMF_LOCAL")==0) {
821 hh
[i
]->memflags
|= MEMF_LOCAL
;
822 } else if (strcmp(nameext
, ".MEMF_KICK")==0) {
823 hh
[i
]->memflags
|= MEMF_KICK
;
824 } else if (strcmp(nameext
, ".MEMF_FAST")==0) {
825 hh
[i
]->memflags
|= MEMF_FAST
;
832 /* Relocate the sections */
833 D(bug("Convert relocation tables\n"));
834 for (i
= 0; i
< int_shnum
; i
++)
836 /* Does this relocation section refer to a hunk? If so, addr must be != 0 */
837 if ((sh
[i
].type
== AROS_ELF_REL
)
838 && hh
[SHINDEX(sh
[i
].info
)]
839 && hh
[SHINDEX(sh
[i
].info
)]->data
)
841 void *reloc
= load_block(file
, sh
[i
].offset
, sh
[i
].size
);
843 if (!relocate(&eh
, sh
, i
, symtab_shndx
, reloc
, hh
))
850 D(bug("HUNK_HEADER: \"%s\", hunks=%d, first=%d, last=%d\n", libname
, hunks
, 0, hunks
-1));
852 wlong(hunk_fd
, HUNK_HEADER
);
853 if (libname
== NULL
) {
854 wlong(hunk_fd
, 0); /* No name */
856 int lsize
= (strlen(libname
) + 4) / 4;
857 wlong(hunk_fd
, lsize
);
858 err
= write(hunk_fd
, libname
, lsize
* 4);
862 wlong(hunk_fd
, hunks
);
863 wlong(hunk_fd
, 0); /* First hunk is #0 */
864 wlong(hunk_fd
, hunks
- 1); /* Last hunk is hunks-1 */
866 /* Write all allocatable hunk sizes */
867 for (i
= 0; i
< int_shnum
; i
++) {
870 if (hh
[i
]==NULL
|| hh
[i
]->hunk
< 0)
873 count
= (hh
[i
]->size
+ 4) / 4;
874 switch (hh
[i
]->memflags
) {
884 count
|= HUNKF_MEMFLAGS
;
888 D(bug("\tHunk #%d, %s, lsize=%d\n", hh
[i
]->hunk
, names
[hh
[i
]->type
- HUNK_CODE
], (int)(hh
[i
]->size
+4)/4));
889 wlong(hunk_fd
, count
);
891 if ((count
& HUNKF_MEMFLAGS
) == HUNKF_MEMFLAGS
)
892 wlong(hunk_fd
, hh
[i
]->memflags
| MEMF_PUBLIC
| MEMF_CLEAR
);
895 /* Write all hunks */
896 for (i
= hunks
= 0; i
< int_shnum
; i
++) {
899 if (hh
[i
]==NULL
|| hh
[i
]->hunk
< 0)
902 wlong(hunk_fd
, hh
[i
]->type
);
903 wlong(hunk_fd
, (hh
[i
]->size
+ 4) / 4);
905 switch (hh
[i
]->type
) {
907 D(bug("HUNK_BSS: %d longs\n", (int)((hh
[i
]->size
+ 4) / 4)));
909 for (s
= 0; s
< int_shnum
; s
++) {
910 if (hh
[s
] && hh
[s
]->type
== HUNK_SYMBOL
)
911 sym_dump(hunk_fd
, sh
, hh
, i
, s
);
914 wlong(hunk_fd
, HUNK_END
);
919 D(bug("#%d HUNK_%s: %d longs\n", hh
[i
]->hunk
, hh
[i
]->type
== HUNK_CODE
? "CODE" : "DATA", (int)((hh
[i
]->size
+ 4) / 4)));
920 err
= write(hunk_fd
, hh
[i
]->data
, ((hh
[i
]->size
+ 4)/4)*4);
924 for (s
= 0; s
< int_shnum
; s
++) {
925 if (hh
[s
] && hh
[s
]->type
== HUNK_SYMBOL
)
926 sym_dump(hunk_fd
, sh
, hh
, i
, s
);
929 reloc_dump(hunk_fd
, hh
, i
);
930 wlong(hunk_fd
, HUNK_END
);
931 D(bug("\tHUNK_END\n"));
934 D(bug("Unsupported allocatable hunk type %d\n", (int)hh
[i
]->type
));
939 /* Free all blocks */
940 for (i
= 0; i
< int_shnum
; i
++) {
955 D(bug("All good, all done.\n"));
962 static int copy(const char *src
, const char *dst
, int flags
);
964 static int copy_dir(const char *src
, const char *dst
, int flags
)
968 char spath
[PATH_MAX
], dpath
[PATH_MAX
];
971 int err
= EXIT_SUCCESS
;
979 snprintf(spath
, sizeof(spath
), "%s/", src
);
980 spath
[sizeof(spath
)-1] = 0;
981 sp
= &spath
[strlen(spath
)];
982 sleft
= &spath
[sizeof(spath
)-1] - sp
;
984 snprintf(dpath
, sizeof(dpath
), "%s/", dst
);
985 dpath
[sizeof(dpath
)-1] = 0;
986 dp
= &dpath
[strlen(dpath
)];
987 dleft
= &dpath
[sizeof(dpath
)-1] - dp
;
989 while ((de
= readdir(sdir
)) != NULL
) {
992 if ((strcmp(de
->d_name
, ".") == 0) ||
993 (strcmp(de
->d_name
, "..") == 0))
996 /* Don't convert anything in a Development directory */
997 if (strcasecmp(de
->d_name
, "Development") == 0)
998 eflags
|= F_NOCONVERT
;
1000 strncpy(sp
, de
->d_name
, sleft
);
1002 strncpy(dp
, de
->d_name
, dleft
);
1004 err
= copy(spath
, dpath
, flags
| eflags
);
1005 if (err
!= EXIT_SUCCESS
)
1014 static int copy(const char *src
, const char *dst
, int flags
)
1016 int src_fd
, hunk_fd
;
1020 if (flags
& F_VERBOSE
)
1021 printf("%s ->\n %s\n", src
, dst
);
1023 if (stat(src
, &st
) >= 0) {
1029 if (S_ISDIR(mode
)) {
1032 return copy_dir(src
, dst
, flags
);
1035 src_fd
= open(src
, O_RDONLY
);
1038 return EXIT_FAILURE
;
1041 if (strcmp(dst
,"-") == 0)
1042 hunk_fd
= 1; /* stdout */
1044 hunk_fd
= open(dst
, O_RDWR
| O_CREAT
| O_TRUNC
, mode
);
1047 return EXIT_FAILURE
;
1050 ret
= elf2hunk(src_fd
, hunk_fd
, NULL
, flags
);
1061 int main(int argc
, char **argv
)
1065 if (argc
== 4 && strcmp(argv
[1],"-v") == 0) {
1072 fprintf(stderr
, "Usage:\n%s file.elf file.hunk\n", argv
[0]);
1073 fprintf(stderr
, "%s src-dir dest-dir\n", argv
[0]);
1074 return EXIT_FAILURE
;
1077 return copy(argv
[1], argv
[2], flags
);