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 #define SysBase 0x0004
43 #if !defined(FALSE)&&!defined(TRUE)
48 #define HUNK_CODE 1001
49 #define HUNK_DATA 1002
51 #define HUNK_RELOC32 1004
52 #define HUNK_SYMBOL 1008
54 #define HUNK_HEADER 1011
56 #define SHT_PROGBITS 1
62 #define SHT_SYMTAB_SHNDX 18
71 #define EM_X86_64 62 /* AMD x86-64 */
77 /* AMD x86-64 relocations. */
78 #define R_X86_64_NONE 0 /* No reloc */
79 #define R_X86_64_64 1 /* Direct 64 bit */
80 #define R_X86_64_PC32 2 /* PC relative 32 bit signed */
81 #define R_X86_64_32 10
82 #define R_X86_64_32S 11
90 #define R_PPC_ADDR32 1
91 #define R_PPC_ADDR16_LO 4
92 #define R_PPC_ADDR16_HA 6
93 #define R_PPC_REL24 10
94 #define R_PPC_REL32 26
95 #define R_PPC_REL16_LO 250
96 #define R_PPC_REL16_HA 252
100 #define R_ARM_ABS32 2
101 #define R_ARM_CALL 28
102 #define R_ARM_JUMP24 29
103 #define R_ARM_V4BX 40
104 #define R_ARM_PREL31 42
105 #define R_ARM_MOVW_ABS_NC 43
106 #define R_ARM_MOVT_ABS 44
111 #define STT_SECTION 3
113 #define STT_LOPROC 13
114 #define STT_HIPROC 15
117 #define SHN_LORESERVE 0xff00
118 #define SHN_ABS 0xfff1
119 #define SHN_COMMON 0xfff2
120 #define SHN_XINDEX 0xffff
121 #define SHN_HIRESERVE 0xffff
123 #define SHF_WRITE (1 << 0)
124 #define SHF_ALLOC (1 << 1)
125 #define SHF_EXECINSTR (1 << 2)
127 #define ELF_ST_TYPE(i) ((i) & 0x0F)
133 #define ELFDATA2LSB 1
134 #define ELFDATA2MSB 2
138 #define ELFCLASS64 2 /* 64-bit objects */
141 #define EI_ABIVERSION 8
143 #define ELFOSABI_AROS 15
145 #define PF_X (1 << 0)
163 } __attribute__((packed
));
177 } __attribute__((packed
));
191 } __attribute__((packed
));
195 ULONG name
; /* Offset of the name string in the string table */
196 IPTR value
; /* Varies; eg. the offset of the symbol in its hunk */
197 IPTR size
; /* How much memory does the symbol occupy */
198 UBYTE info
; /* What kind of symbol is this ? (global, variable, etc) */
199 UBYTE other
; /* undefined */
200 UWORD shindex
; /* In which section is the symbol defined ? */
201 } __attribute__((packed
));
203 #define ELF_R_SYM(val) ((val) >> 8)
204 #define ELF_R_TYPE(val) ((val) & 0xff)
205 #define ELF_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
209 IPTR offset
; /* Address of the relocation relative to the section it refers to */
210 IPTR info
; /* Type of the relocation */
211 SIPTR addend
; /* Constant addend used to compute value */
214 /* convert section header number to array index */
216 ((n) < SHN_LORESERVE ? (n) : ((n) <= SHN_HIRESERVE ? 0 : (n) - (SHN_HIRESERVE + 1 - SHN_LORESERVE)))
218 /* convert section header array index to section number */
220 ((i) < SHN_LORESERVE ? (i) : (i) + (SHN_HIRESERVE + 1 - SHN_LORESERVE))
222 /* m68k Machine's native values */
223 #define AROS_ELF_CLASS ELFCLASS32
224 #define AROS_ELF_DATA ELFDATA2MSB
225 #define AROS_ELF_MACHINE EM_68K
226 #define AROS_ELF_REL SHT_RELA
229 #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
231 # define VA_START(args, lastarg) va_start(args, lastarg)
233 # include <varargs.h>
234 # define VA_START(args, lastarg) va_start(args)
240 # define PARAMS(x) ()
241 #endif /* PROTOTYPES */
243 static void set_error(int err
)
248 #if defined(DEBUG) && DEBUG
255 #define bug(fmt,args...) fprintf(stderr, fmt ,##args )
257 static int must_swap
= -1;
259 static void eh_fixup(struct elfheader
*eh
)
262 if (eh
->type
== 256) {
264 eh
->type
= ntohs(eh
->type
);
265 eh
->machine
= ntohs(eh
->machine
);
266 eh
->version
= ntohl(eh
->version
);
267 eh
->entry
= ntohl(eh
->entry
);
268 eh
->phoff
= ntohl(eh
->phoff
);
269 eh
->shoff
= ntohl(eh
->shoff
);
270 eh
->flags
= ntohl(eh
->flags
);
271 eh
->ehsize
= ntohs(eh
->ehsize
);
272 eh
->phentsize
= ntohs(eh
->phentsize
);
273 eh
->phnum
= ntohs(eh
->phnum
);
274 eh
->shentsize
= ntohs(eh
->shentsize
);
275 eh
->shnum
= ntohs(eh
->shnum
);
276 eh
->shstrndx
= ntohs(eh
->shstrndx
);
282 static void sh_fixup(struct sheader
*sh
, int n
)
287 for (; n
> 0; n
--, sh
++) {
288 sh
->name
= ntohl(sh
->name
);
289 sh
->type
= ntohl(sh
->type
);
290 sh
->flags
= ntohl(sh
->flags
);
291 sh
->addr
= ntohl(sh
->addr
);
292 sh
->offset
= ntohl(sh
->offset
);
293 sh
->size
= ntohl(sh
->size
);
294 sh
->link
= ntohl(sh
->link
);
295 sh
->info
= ntohl(sh
->info
);
296 sh
->addralign
= ntohl(sh
->addralign
);
297 sh
->entsize
= ntohl(sh
->entsize
);
301 static void rel_fixup(struct relo
*rel
)
306 rel
->offset
= ntohl(rel
->offset
);
307 rel
->info
= ntohl(rel
->info
);
308 rel
->addend
= ntohl(rel
->addend
);
311 void sym_fixup(struct symbol
*sym
)
316 sym
->name
= ntohl(sym
->name
);
317 sym
->value
= ntohl(sym
->value
);
318 sym
->size
= ntohl(sym
->size
);
319 sym
->shindex
= ntohs(sym
->shindex
);
322 static void *load_block (int file
,ULONG offset
,ULONG size
)
324 ULONG lsize
= (size
+ sizeof(ULONG
) - 1) / sizeof(ULONG
);
325 D(bug("[ELF2HUNK] Load Block\n"));
326 D(bug("[ELF2HUNK] (size=%d)\n",(int)size
));
327 void *block
= malloc(lsize
* sizeof(ULONG
));
329 lseek(file
, offset
, SEEK_SET
);
330 if (read(file
, block
, size
) == size
) {
342 static ULONG
read_shnum(int file
, struct elfheader
*eh
)
344 ULONG shnum
= eh
->shnum
;
346 /* the ELF header only uses 16 bits to store the count of section headers,
347 * so it can't handle more than 65535 headers. if the count is 0, and an
348 * offset is defined, then the real count can be found in the first
349 * section header (which always exists).
351 * similarly, if the string table index is SHN_XINDEX, then the actual
352 * index is found in the first section header also.
354 * see the System V ABI 2001-04-24 draft for more details.
360 if (eh
->shoff
== 0) {
365 lseek(file
, eh
->shoff
, SEEK_SET
);
366 if (read(file
, &sh
, sizeof(sh
)) != sizeof(sh
))
371 /* wider section header count is in the size field */
374 /* sanity, if they're still invalid then this isn't elf */
382 static int load_header(int file
, struct elfheader
*eh
)
384 lseek(file
, 0, SEEK_SET
);
385 if (read(file
, eh
, sizeof(struct elfheader
)) != sizeof(struct elfheader
)) {
386 D(bug("[ELF2HUNK] Can't read the %d byte ELF header\n", (int)sizeof(struct elfheader
)));
392 if (eh
->ident
[0] != 0x7f || eh
->ident
[1] != 'E' ||
393 eh
->ident
[2] != 'L' || eh
->ident
[3] != 'F') {
394 D(bug("[ELF2HUNK] Not an ELF object\n"));
397 D(bug("[ELF2HUNK] ELF object\n"));
399 /* WANT_CLASS should be defined for your target */
400 if (eh
->ident
[EI_CLASS
] != AROS_ELF_CLASS
||
401 eh
->ident
[EI_VERSION
] != EV_CURRENT
||
402 eh
->type
!= ET_REL
||
403 eh
->ident
[EI_DATA
] != AROS_ELF_DATA
||
404 eh
->machine
!= AROS_ELF_MACHINE
)
406 D(bug("[ELF2HUNK] Object is of wrong type\n"));
407 D(bug("[ELF2HUNK] EI_CLASS is %d - should be %d\n", eh
->ident
[EI_CLASS
] , AROS_ELF_CLASS
));
408 D(bug("[ELF2HUNK] EI_VERSION is %d - should be %d\n", eh
->ident
[EI_VERSION
], EV_CURRENT
));
409 D(bug("[ELF2HUNK] type is %d - should be %d\n", eh
->type
, ET_REL
));
410 D(bug("[ELF2HUNK] EI_DATA is %d - should be %d\n", eh
->ident
[EI_DATA
] , AROS_ELF_DATA
));
411 D(bug("[ELF2HUNK] machine is %d - should be %d\n", eh
->machine
, AROS_ELF_MACHINE
));
422 ULONG size
; /* Size in ULONGs */
425 int hunk
; /* Allocatable hunk ID */
427 ULONG shid
; /* ELF hunk base to add to... */
428 ULONG offset
; /* offset in this hunk. */
435 struct elfheader
*eh
,
440 struct hunkheader
**hh
443 struct sheader
*shrel
= &sh
[shrel_idx
];
444 struct sheader
*shsymtab
= &sh
[SHINDEX(shrel
->link
)];
445 struct sheader
*toreloc
= &sh
[SHINDEX(shrel
->info
)];
447 struct symbol
*symtab
= (struct symbol
*)hh
[SHINDEX(shrel
->link
)]->data
;
448 struct hunkheader
*h
= hh
[SHINDEX(shrel
->info
)];
451 * Ignore relocs if the target section has no allocation. that can happen
452 * eg. with a .debug PROGBITS and a .rel.debug section
454 D(bug("[ELF2HUNK] sh[%d].flags = 0x%x\n", (int)SHINDEX(shrel
->info
), (int)toreloc
->flags
));
455 if (!(toreloc
->flags
& SHF_ALLOC
))
458 ULONG numrel
= shrel
->size
/ shrel
->entsize
;
464 h
->reloc
= realloc(h
->reloc
, h
->relocs
* sizeof(struct hunkreloc
));
465 struct hunkreloc
*hrel
= &h
->reloc
[hrels
];
467 struct symbol
*SysBase_sym
= NULL
;
469 for (i
=0; i
<numrel
; i
++, rel
++)
482 * R_ARM_V4BX are actually special marks for the linker.
483 * They even never have a target (shindex == SHN_UNDEF),
484 * so we simply ignore them before doing any checks.
486 if (ELF_R_TYPE(rel
->info
) == R_ARM_V4BX
)
490 sym
= symtab
[ELF_R_SYM(rel
->info
)];
492 offset
= rel
->offset
;
493 symname
= (const char *)(hh
[SHINDEX(shsymtab
->link
)]->data
+ sym
.name
);
495 if (sym
.shindex
!= SHN_XINDEX
)
496 shindex
= sym
.shindex
;
499 if (symtab_shndx
< 0) {
500 D(bug("[ELF2HUNK] got symbol with shndx 0xfff, but there's no symtab shndx table\n"));
504 shindex
= ntohl(((ULONG
*)hh
[symtab_shndx
]->data
)[ELF_R_SYM(rel
->info
)]);
507 D(bug("[ELF2HUNK] Processing %d symbol %s\n", (int)shindex
, symname
));
513 D(bug("[ELF2HUNK] Undefined symbol '%s'\n", symname
));
518 D(bug("[ELF2HUNK] COMMON symbol '%s'\n", symname
));
524 if (SysBase_sym
== NULL
)
526 if (strncmp(symname
, "SysBase", 8) == 0)
532 if (SysBase_sym
== &sym
)
534 SysBase_yes
: hunk
= ~0; value
= SysBase
;
537 SysBase_no
: hunk
= ~0; value
= sym
.value
;
542 hunk
= SHINDEX(shindex
);
547 switch (ELF_R_TYPE(rel
->info
))
550 value
+= rel
->addend
;
554 value
+= rel
->addend
- offset
;
558 bug("[ELF2HUNK] Unsupported relocation type R_68K_PC16\n");
566 bug("[ELF2HUNK] Unrecognized relocation type %d %d\n", (int)i
, (int)ELF_R_TYPE(rel
->info
));
571 D(bug("[ELF2HUNK] Hunk %d, offset 0x%x: base 0x%x\n", (int)hunk
, (int)offset
, (int)value
));
572 *(ULONG
*)(h
->data
+ offset
) = htonl(value
+ ntohl(*(ULONG
*)(h
->data
+ offset
)));
578 hrel
->offset
= offset
;
579 hrel
->symbol
= symname
;
586 int reloc_cmp(const void *a
, const void *b
)
588 const struct hunkreloc
*ha
= a
, *hb
= b
;
590 if (ha
->shid
!= hb
->shid
)
591 return hb
->shid
- ha
->shid
;
592 return hb
->offset
- ha
->offset
;
595 static int wlong(int fd
, ULONG val
)
598 return write(fd
, &val
, sizeof(val
));
601 int sym_dump(int hunk_fd
, struct sheader
*sh
, struct hunkheader
**hh
, int shid
, int symtabndx
)
604 struct symbol
*sym
= hh
[symtabndx
]->data
;
605 struct sheader
*symtab
= &sh
[SHINDEX(symtabndx
)];
607 syms
= symtab
->size
/ sizeof(struct symbol
);
612 wlong(hunk_fd
, HUNK_SYMBOL
);
613 wlong(hunk_fd
, syms
);
615 /* Dump symbols for this hunk */
616 for (i
= 0; i
< syms
; i
++) {
624 if (SHINDEX(s
.shindex
) != shid
)
627 name
= (const char *)(hh
[SHINDEX(symtab
->link
)]->data
+ s
.name
);
628 D(bug("\t0x%08x: %s\n", (int)s
.value
, name
));
629 lsize
= (strlen(name
) + 4) / 4;
630 wlong(hunk_fd
, lsize
);
631 err
= write(hunk_fd
, name
, lsize
* 4);
634 wlong(hunk_fd
, s
.value
);
641 static void reloc_dump(int hunk_fd
, struct hunkheader
**hh
, int h
)
645 if (hh
[h
]->relocs
== 0)
648 /* Sort the relocations by reference hunk id */
649 qsort(hh
[h
]->reloc
, hh
[h
]->relocs
, sizeof(hh
[h
]->reloc
[0]), reloc_cmp
);
651 wlong(hunk_fd
, HUNK_RELOC32
);
652 D(bug("\tHUNK_RELOC32: %d relocations\n", (int)hh
[h
]->relocs
));
654 for (i
= 0; i
< hh
[h
]->relocs
; ) {
656 int shid
= hh
[h
]->reloc
[i
].shid
;
657 for (count
= i
; count
< hh
[h
]->relocs
; count
++)
658 if (hh
[h
]->reloc
[count
].shid
!= shid
)
661 wlong(hunk_fd
, count
);
662 D(bug("\t %d relocations relative to Hunk %d\n", count
, hh
[shid
]->hunk
));
663 /* Convert from ELF hunk ID to AOS hunk ID */
664 wlong(hunk_fd
, hh
[shid
]->hunk
);
665 for (; count
> 0; i
++, count
--) {
666 D(bug("\t\t%d: 0x%08x %s\n", i
, (int)hh
[h
]->reloc
[i
].offset
, hh
[h
]->reloc
[i
].symbol
));
667 wlong(hunk_fd
, hh
[h
]->reloc
[i
].offset
);
673 static int copy_to(int in
, int out
)
675 static char buff
[64*1024];
679 len
= read(in
, buff
, sizeof(buff
));
681 perror("Can't read from input file\n");
686 } while ((err
= write(out
, buff
, len
)) == len
);
689 perror("Can't write to output file\n");
696 int elf2hunk(int file
, int hunk_fd
, const char *libname
, int flags
)
698 struct hunkheader
**hh
;
701 int symtab_shndx
= -1;
704 BOOL exec_hunk_seen
= FALSE
;
708 /* load and validate ELF header */
709 D(bug("Load header\n"));
710 if ((flags
& F_NOCONVERT
) || !load_header(file
, &eh
)) {
711 /* If it's not an ELF, just copy it.
713 * This simplifies a number of mmakefiles
714 * for the m68k-amiga boot and ISO creation
716 lseek(file
, 0, SEEK_SET
);
717 return (copy_to(file
, hunk_fd
) == 0) ? EXIT_SUCCESS
: EXIT_FAILURE
;
720 D(bug("Read SHNum\n"));
721 int_shnum
= read_shnum(file
, &eh
);
725 /* load section headers */
726 D(bug("Load Section Headers @0x%08x\n", (int)eh
.shoff
));
727 if (!(sh
= load_block(file
, eh
.shoff
, int_shnum
* eh
.shentsize
)))
730 sh_fixup(sh
, int_shnum
);
732 /* Looks like we have a valid executable. Generate a
733 * HUNK header set. Not all may be filled in.
735 hh
= calloc(sizeof(*hh
), int_shnum
);
737 /* Iterate over the section headers in order to do some stuff... */
738 D(bug("Look for symbol tables\n"));
739 for (i
= 0; i
< int_shnum
; i
++)
742 Load the symbol and string table(s).
744 NOTICE: the ELF standard, at the moment (Nov 2002) explicitely states
745 that only one symbol table per file is allowed. However, it
746 also states that this may change in future... we already handle it.
748 D(bug("sh[%d].type = 0x%08x, .offset = 0x%08x, .size = 0x%08x\n",
749 (int)i
, (int)sh
[i
].type
, (int)sh
[i
].offset
, (int)sh
[i
].size
));
750 if (sh
[i
].type
== SHT_SYMTAB
|| sh
[i
].type
== SHT_STRTAB
|| sh
[i
].type
== SHT_SYMTAB_SHNDX
)
752 hh
[i
] = calloc(sizeof(struct hunkheader
), 1);
753 hh
[i
]->type
= (sh
[i
].type
== SHT_SYMTAB
) ? HUNK_SYMBOL
: 0;
755 hh
[i
]->data
= load_block(file
, sh
[i
].offset
, sh
[i
].size
);
759 if (sh
[i
].type
== SHT_SYMTAB_SHNDX
) {
760 if (symtab_shndx
== -1)
763 D(bug("[ELF2HUNK] file contains multiple symtab shndx tables. only using the first one\n"));
767 /* Load the section in memory if needed, and make an hunk out of it */
768 if (sh
[i
].flags
& SHF_ALLOC
&& sh
[i
].size
> 0)
770 hh
[i
] = calloc(sizeof(struct hunkheader
), 1);
771 hh
[i
]->size
= sh
[i
].size
;
772 hh
[i
]->hunk
= hunks
++;
774 if (sh
[i
].type
== SHT_NOBITS
) {
776 hh
[i
]->type
= HUNK_BSS
;
779 if (sh
[i
].flags
& SHF_EXECINSTR
) {
780 hh
[i
]->type
= HUNK_CODE
;
781 exec_hunk_seen
= TRUE
;
783 hh
[i
]->type
= HUNK_DATA
;
785 hh
[i
]->data
= load_block(file
, sh
[i
].offset
, sh
[i
].size
);
790 /* Relocate the sections */
791 D(bug("Convert relocation tables\n"));
792 for (i
= 0; i
< int_shnum
; i
++)
794 /* Does this relocation section refer to a hunk? If so, addr must be != 0 */
795 if ((sh
[i
].type
== AROS_ELF_REL
)
796 && hh
[SHINDEX(sh
[i
].info
)]
797 && hh
[SHINDEX(sh
[i
].info
)]->data
)
799 void *reloc
= load_block(file
, sh
[i
].offset
, sh
[i
].size
);
801 relocate(&eh
, sh
, i
, symtab_shndx
, reloc
, hh
);
807 D(bug("HUNK_HEADER: \"%s\", hunks=%d, first=%d, last=%d\n", libname
, hunks
, 0, hunks
-1));
809 wlong(hunk_fd
, HUNK_HEADER
);
810 if (libname
== NULL
) {
811 wlong(hunk_fd
, 0); /* No name */
813 int lsize
= (strlen(libname
) + 4) / 4;
814 wlong(hunk_fd
, lsize
);
815 err
= write(hunk_fd
, libname
, lsize
* 4);
819 wlong(hunk_fd
, hunks
);
820 wlong(hunk_fd
, 0); /* First hunk is #0 */
821 wlong(hunk_fd
, hunks
- 1); /* Last hunk is hunks-1 */
823 /* Write all allocatable hunk sizes */
824 for (i
= 0; i
< int_shnum
; i
++) {
825 const __attribute__((unused
)) char *names
[3]={ "CODE", "DATA", "BSS" };
826 if (hh
[i
]==NULL
|| hh
[i
]->hunk
< 0)
829 D(bug("\tHunk #%d, %s, lsize=%d\n", hh
[i
]->hunk
, names
[hh
[i
]->type
- HUNK_CODE
], (int)(hh
[i
]->size
+4)/4));
830 wlong(hunk_fd
, (hh
[i
]->size
+ 4) / 4);
833 /* Write all hunks */
834 for (i
= hunks
= 0; i
< int_shnum
; i
++) {
837 if (hh
[i
]==NULL
|| hh
[i
]->hunk
< 0)
840 switch (hh
[i
]->type
) {
842 D(bug("HUNK_BSS: %d longs\n", (int)((hh
[i
]->size
+ 4) / 4)));
843 wlong(hunk_fd
, hh
[i
]->type
);
844 wlong(hunk_fd
, (hh
[i
]->size
+ 4) / 4);
846 for (s
= 0; s
< int_shnum
; s
++) {
847 if (hh
[s
] && hh
[s
]->type
== HUNK_SYMBOL
)
848 sym_dump(hunk_fd
, sh
, hh
, i
, s
);
851 wlong(hunk_fd
, HUNK_END
);
856 D(bug("#%d HUNK_%s: %d longs\n", hh
[i
]->hunk
, hh
[i
]->type
== HUNK_CODE
? "CODE" : "DATA", (int)((hh
[i
]->size
+ 4) / 4)));
857 wlong(hunk_fd
, hh
[i
]->type
);
858 wlong(hunk_fd
, (hh
[i
]->size
+ 4)/4);
859 err
= write(hunk_fd
, hh
[i
]->data
, ((hh
[i
]->size
+ 4)/4)*4);
863 for (s
= 0; s
< int_shnum
; s
++) {
864 if (hh
[s
] && hh
[s
]->type
== HUNK_SYMBOL
)
865 sym_dump(hunk_fd
, sh
, hh
, i
, s
);
868 reloc_dump(hunk_fd
, hh
, i
);
869 wlong(hunk_fd
, HUNK_END
);
870 D(bug("\tHUNK_END\n"));
873 D(bug("Unsupported allocatable hunk type %d\n", (int)hh
[i
]->type
));
878 /* Free all blocks */
879 for (i
= 0; i
< int_shnum
; i
++) {
891 D(bug("All good, all done.\n"));
898 static int copy(const char *src
, const char *dst
, int flags
);
900 static int copy_dir(const char *src
, const char *dst
, int flags
)
904 char spath
[PATH_MAX
], dpath
[PATH_MAX
];
907 int err
= EXIT_SUCCESS
;
915 snprintf(spath
, sizeof(spath
), "%s/", src
);
916 spath
[sizeof(spath
)-1] = 0;
917 sp
= &spath
[strlen(spath
)];
918 sleft
= &spath
[sizeof(spath
)-1] - sp
;
920 snprintf(dpath
, sizeof(dpath
), "%s/", dst
);
921 dpath
[sizeof(dpath
)-1] = 0;
922 dp
= &dpath
[strlen(dpath
)];
923 dleft
= &dpath
[sizeof(dpath
)-1] - dp
;
925 while ((de
= readdir(sdir
)) != NULL
) {
928 if ((strcmp(de
->d_name
, ".") == 0) ||
929 (strcmp(de
->d_name
, "..") == 0))
932 /* Don't convert anything in a Development directory */
933 if (strcasecmp(de
->d_name
, "Development") == 0)
934 eflags
|= F_NOCONVERT
;
936 strncpy(sp
, de
->d_name
, sleft
);
938 strncpy(dp
, de
->d_name
, dleft
);
940 err
= copy(spath
, dpath
, flags
| eflags
);
941 if (err
!= EXIT_SUCCESS
)
950 static int copy(const char *src
, const char *dst
, int flags
)
956 if (flags
& F_VERBOSE
)
957 printf("%s ->\n %s\n", src
, dst
);
959 if (stat(src
, &st
) >= 0) {
968 return copy_dir(src
, dst
, flags
);
971 src_fd
= open(src
, O_RDONLY
);
977 hunk_fd
= open(dst
, O_RDWR
| O_CREAT
| O_TRUNC
, mode
);
983 ret
= elf2hunk(src_fd
, hunk_fd
, NULL
, flags
);
993 int main(int argc
, char **argv
)
997 if (argc
== 4 && strcmp(argv
[1],"-v") == 0) {
1004 fprintf(stderr
, "Usage:\n%s file.elf file.hunk\n", argv
[0]);
1005 fprintf(stderr
, "%s src-dir dest-dir\n", argv
[0]);
1006 return EXIT_FAILURE
;
1009 return copy(argv
[1], argv
[2], flags
);