/* $VER: vlink vlink.h V0.6d (13.02.99)
 *
 * This file is part of vlink, a portable linker for multiple
 * object formats.
 * Copyright (c) 1997-99  Frank Wille
 *
 * vlink is freeware and part of the portable and retargetable ANSI C
 * compiler vbcc, copyright (c) 1995-99 by Volker Barthelmann.
 * vlink may be freely redistributed as long as no modifications are
 * made and nothing is charged for it. Non-commercial usage is allowed
 * without any restrictions.
 * EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
 * SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
 *
 *
 * v0.6b (16.01.99) phx
 *       big_endian has to be "signed char" to compile under Irix 5.3.
 * v0.6a (19.12.98) phx
 *       Endianess of linking process will be determined by the type
 *       of the first object.
 *       Support for little endian object file formats.
 *       New macros read16, write16, read32, write32 (replacing the old
 *       macros with the same name) for reading/writing data in the
 *       current endian format.
 * v0.6  (24.10.98) phx
 *       baserel_off disappeared. Each target should know about its
 *       own small data section offset for the base register. The new
 *       field baseoff in FFFuncs was created for this purpose.
 *       New target elf32powerup, which supports the PPC coprocessor
 *       boards from Phase5.
 * v0.5e (05.10.98) phx
 *       Artificial sections and objects, containing longwords sorted
 *       by priority, may be generated using new_priptr().
 *       Reduced hash table size for objects to 1/8 (32 entries).
 * v0.5d (22.08.98) phx
 *       Faster memory allocation can be activated by #define FASTALLOC.
 *       Directories are only scanned if needed (AmigaOS filesystem is
 *       too slow).
 * v0.5c (08.07.98) phx
 *       Automagic generation of @__xxx symbols for amigaehf.
 * v0.5b (05.07.98) phx
 *       Linker symbols for elf32ppcbe.
 *       SYMX_SPECIAL in Symbol->extra flags a linker symbol as
 *       being target-specific
 * v0.5  (27.06.98) phx
 *       Target-specific linker symbol support.
 * v0.4  (05.06.98) phx
 *       New global vars for options: -sc, -sd, -multibase.
 *       New target-specific function targetlink(), which decides whether
 *       two sections must or must not be linked together for a target.
 *       find/create_lnksect() from linker.c are no longer global.
 *       linker_relrefs() finds all relative references between sections.
 *       The sections contain a RelRef-list afterwards, which can be
 *       used to link sections with relative references automatically
 *       together.
 * v0.3b (25.04.98) phx
 *       t_elf.c was split into t_elf32.c and t_elf64.c
 *       New header files: elf64.h and rel_elfalpha.h
 *       Some experimental code for target elf64alpha in t_elf64.c
 * v0.3a (18.04.98) phx
 *       Updated help text.
 * v0.3  (17.04.98) phx
 *       ELF PowerPC 32Bit Big Endian support. Input: objects and
 *       library archives. Output: relocatabable objects.
 *       Full support for little endian file formats by defining new
 *       macros: LECH,LECW,LECVH,LECVW,read16le,read32le,write16le,
 *       write32le (although currently no LE formats are supported).
 *       Replaced l2bh(),l2bw(),read16(),read32(),write16(),write32()
 *       by swap16(),swap32(),read16sw(),read32sw(),write16sw(),write32sw().
 *       fwrite32() is now called fwrite32be().
 *       Section.id may contain a unique identification value.
 *       Included objname in struct LinkFile (useful for ELF archives).
 *       New option -F for reading a list of input files.
 *       Support for ar library archives.
 * v0.2  (07.03.98) phx
 *       Linking of EHF and ADOS seems quite stable. Library units
 *       are linked immediately and are no longer always the last
 *       units in an output file.
 *       insertnode().
 * v0.1  (27.02.98) phx
 *       First version that seems to link AmigaOS ADOS and EHF
 *       objects and libraries. Many common features, like linking
 *       sections together which have relative references, are
 *       still missing. Also, PowerPC-ELF32 support is about to come.
 * v0.0  (04.08.97) phx
 *       File created. Project started on a beautiful summer-day
 *       at the North Sea beach of Cuxhaven. :)
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>

#ifdef HAVE_CONFIG
#include "config.h"
#endif

/* program's name */
#define PNAME "vlink"

/* version/revision */
#define VERSION 0
#define REVISION 6
#define PLEVEL 4


/* integer types */
#if defined (TYPES32BIT)
typedef signed char int8;
typedef unsigned char uint8;
typedef signed short int int16;
typedef unsigned short int uint16;
typedef signed long int int32;
typedef unsigned long int uint32;
typedef signed char bool;
#elif defined (TYPES64BIT)
typedef signed char int8;
typedef unsigned char uint8;
typedef signed short int16;
typedef unsigned short uint16;
typedef signed int int32;
typedef unsigned int uint32;
typedef int bool;
#else
#error Unsupported architecture! Define either TYPES32BIT or TYPES64BIT.
#endif


/* endian conversion */
#if defined (BIGENDIAN)
#define ECH(x) x
#define ECW(x) x
#define ECVH(x) x
#define ECVW(x) x
#define read16be(x) (*(uint16 *)(x))
#define read32be(x) (*(uint32 *)(x))
#define write16be(x,y) (*(uint16 *)(x)=(y))
#define write32be(x,y) (*(uint32 *)(x)=(y))
#define LECH(x) (((x)&0xff)<<8|((x)&0xff00)>>8)
#define LECW(x) (((x)&0xff)<<24|((x)&0xff00)<<8|((x)&0xff0000)>>8|((x)&0xff000000)>>24)
#define LECVH(x) swap16(x)
#define LECVW(x) swap32(x)
#define read16le(x) read16sw(x)
#define read32le(x) read32sw(x)
#define write16le(x,y) write16sw(x,y)
#define write32le(x,y) write32sw(x,y)

#elif defined (LITTLEENDIAN)
#define ECH(x) (((x)&0xff)<<8|((x)&0xff00)>>8)
#define ECW(x) (((x)&0xff)<<24|((x)&0xff00)<<8|((x)&0xff0000)>>8|((x)&0xff000000)>>24)
#define ECVH(x) swap16(x)
#define ECVW(x) swap32(x)
#define read16be(x) read16sw(x)
#define read32be(x) read32sw(x)
#define write16be(x,y) write16sw(x,y)
#define write32be(x,y) write32sw(x,y)
#define LECH(x) x
#define LECW(x) x
#define LECVH(x) x
#define LECVW(x) x
#define read16le(x) (*(uint16 *)(x))
#define read32le(x) (*(uint32 *)(x))
#define write16le(x,y) (*(uint16 *)(x)=(y))
#define write32le(x,y) (*(uint32 *)(x)=(y))
#else
#error You have to define either BIGENDIAN or LITTLEENDIAN.
#endif

/* read/write data in current endianess */
#define read16(e,x) ((e)?(read16be(x)):(read16le(x)))
#define read32(e,x) ((e)?(read32be(x)):(read32le(x)))
#define write16(e,x,y) if(e) write16be(x,y); else write16le(x,y)
#define write32(e,x,y) if(e) write32be(x,y); else write32le(x,y)

/* program constants */

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif

#define FNAMEBUFSIZE 1024       /* buffer size for file names */
#define MAX_FWALIGN 8192        /* max. aligment, when writing target file */


/* structures */

struct node {
  struct node *next;
  struct node *pred;
};

struct list {
  struct node *first;
  struct node *dummy;
  struct node *last;
};


struct LibPath {                /* libpaths list. */
  struct node n;                /* Here we search for library archives */
  char *path;                   /* and shared objects. */
};


struct InputFile {              /* inputlist nodes */
  struct node n;                /* contains names & flags of all inp. files */
  char *name;
  bool lib;                     /* search library */
  bool dynamic;                 /* try to link dynamic first */
  int so_ver;                   /* minimum version of shared object */
};


struct LinkFile {
  struct node n;
  char *pathname;               /* full path: /usr/lib/libm.a */
  char *filename;               /* file name: libm.a */
  char *objname;                /* current obj. name: sin.o (archives only)*/
  uint8 *data;                  /* pointer to file data */
  unsigned long length;         /* length of file */
  uint8 format;                 /* file format - index into targets table */
  uint8 type;                   /* ID_OBJECT/SHAREDOBJ/LIBARCH */
};


struct ObjectUnit {
  struct node n;
  struct LinkFile *lnkfile;     /* LinkFile, where the obj. belongs to */
  char *objname;                /* name of object, if available, e.g. sin.o */
  struct list sections;         /* list of all sections in this object */
  struct Symbol **objsyms;      /* all symbols from this object unit */
  uint16 flags;
  struct list pripointers;      /* PriPointers of this unit */
};

#define OUF_LINKED 0x0001       /* object unit is marked as linked */
#define OBJSYMHTABSIZE 0x20     /* number of entries in symbol hash table */

struct RelRef {
  struct RelRef *next;
  struct Section *refsec;       /* relative referenced sections */
};

struct Section {
  struct node n;
  struct ObjectUnit *obj;       /* link to ObjectUnit */
  struct LinkedSection *lnksec; /* ptr to joined sections */
  char *name;                   /* section's name, e.g. .text, .data, ... */
  uint32 id;                    /* unique section id - target dependant */
  uint8 type;                   /* type: code, data, bss */
  uint8 flags;
  uint8 protection;             /* readable, writable, executable, ... */
  uint8 alignment;              /* number of bits, which have to be zero */
  unsigned long va;             /* the section's virtual address */
  unsigned long offset;         /* offset relative to 1st sec. of same type */
  uint8 *data;                  /* the section's contents */
  unsigned long size;           /* the section's size in bytes (+alignment) */
  struct list relocs;           /* the section's 32-bit relocations */
  struct list xrefs;            /* external references to unknown symbols */
  struct RelRef *relrefs;       /* all sections which are referenced rel. */
};

/* section types */
#define ST_UNDEFINED 0
#define ST_CODE 1               /* section contains code */
#define ST_DATA 2               /* section contains initialized data */
#define ST_UDATA 3              /* section contains uninitialized data */
#define ST_LAST 3               /* last section type */

/* section flags */
#define SF_DISCARD 0x1          /* can be discarded */
#define SF_UNINITIALIZED 0x2    /* section has uninitialized contents */
#define SF_SMALLDATA 0x4        /* section is referenced base-relative */
#define SF_PORTABLE_MASK 0x0f   /* mask for target-independant flags */
/* target specific section flags */
#define SF_EHFPPC 0x20          /* target ehf: section contains PPC code */
#define SF_CHIP 0x40            /* target amigaos: Chip-RAM section */
#define SF_FAST 0x80            /* target amigaos: Fast-RAM section */

/* protection */
#define SP_READ 1
#define SP_WRITE 2
#define SP_EXEC 4
#define SP_SHARE 8


struct Reloc {
  struct node n;
  union {
    uint32 id;                  /* section index */
    struct Section *ptr;        /* base addr of this sect. has to be added */
    struct LinkedSection *lnk;  /* base addr of joined sections */
  } relocsect;
  unsigned long offset;         /* section-offset of relocation */
  int32 addend;                 /* add this to relocation value */
  uint8 type;
};

/* relocation types */
#define R_NONE 0
#define R_ADDR32 1              /* 32-bit relocation */
#define R_ADDR26 2              /* PPC 26-bit relocation */
#define R_ADDR16 3              /* 16-bit relocation */
#define R_ADDR16_LO 4           /* relocation of the lower 16-bit word */
#define R_ADDR16_HI 5           /* relocation of the higher 16-bit word */
#define R_ADDR16_HA 6           /* as HI, but add 1 if lower word is neg. */
#define R_ADDR14 7              /* PPC/BC-instruction, 16-bit absolute */
#define R_ADDR14_BRTAKEN 8
#define R_ADDR14_BRNTAKEN 9
#define R_ADDR8 10              /* 8-bit relocation */

#define R_REL32 32              /* relative 32-bit */
#define R_REL26 33              /* relative PPC 26-bit */
#define R_REL16 34              /* relative 16-bit */
#define R_REL14 35              /* PPC/BC-instruction, 16-bit relative */
#define R_REL14_BRTAKEN 36
#define R_REL14_BRNTAKEN 37
#define R_REL8 38               /* relative 8-bit */

#define R_BASEREL32 64          /* base register relative 32-bit */
#define R_BASEREL26 65          /* base register relative 26-bit (PPC) */
#define R_BASEREL16 66          /* base register relative 16-bit */
#define R_BASEREL8 67           /* base register relative 8-bit */

#define R_MASK 0x60
#define R_ADDR 0x00
#define R_REL 0x20
#define R_BASEREL 0x40

struct Symbol {
  struct node n;
  struct Symbol *glob_chain;    /* next symbol in global hash chain */
  struct Symbol *obj_chain;     /* next symbol in object hash chain */
  char *name;                   /* symbol's name */
  uint32 value;                 /* abs. value, reloc. offset or alignment */
  struct Section *relsect;      /* symbol def. relative to this section */
  /* SYM_ABS are rel. to 1st section, SYM_COMMON rel. to a BSS section */
  uint8 type;                   /* absolute, relocatable or extern */
  uint8 flags;
  uint8 info;                   /* section, function or object */
  uint8 bind;                   /* local, global or weak binding */
  uint32 size;                  /* symbol's size in bytes */
  uint32 extra;                 /* extra data, used by some targets */
};

/* symbol type */
#define SYM_UNDEF 0
#define SYM_ABS 1               /* absolute value */
#define SYM_RELOC 2             /* relocation offset, relative to section */
#define SYM_COMMON 3            /* alignment constraints in value */

/* symbol flags */
#define SYMF_LNKSYM 1           /* a linker-generated symbol */

/* object type */
#define SYMI_NOTYPE 0
#define SYMI_OBJECT 1
#define SYMI_FUNC 2
#define SYMI_SECTION 3
#define SYMI_FILE 4

/* symbol bind */
#define SYMB_NONE 0
#define SYMB_LOCAL 1
#define SYMB_GLOBAL 2
#define SYMB_WEAK 3

/* extra */
#define SYMX_SPECIAL 0x80000000 /* Bit 31 = target-specific lnk. symbol */

struct XReference {
  struct node n;
  struct Symbol *symbol;        /* symbol-pointer, if x-ref. was resolved */
  char *name;
  unsigned long offset;         /* section offset of reference */
  int32 addend;
  uint8 type;                   /* relocation type, see struct Reloc */
  uint8 size;                   /* size of reference in bytes (3 = 26bit) */
};


struct SymNames {
  struct SymNames *next;        /* next symbol name in hash chain */
  char *name;                   /* symbol's name */
};


struct SecBase {                /* definition of section base address */
  struct SecBase *next;
  char *name;
  unsigned long base;
};


struct LinkedSection {          /* linked sections of same type and name */
  struct node n;
  int index;                    /* section index 0..gv->nsecs */
  char *name;                   /* section's name, e.g. .text, .data, ... */
  uint8 type;                   /* type: code, data, bss */
  uint8 flags;
  uint8 protection;             /* readable, writable, executable, ... */
  uint8 alignment;              /* number of bits, which have to be zero */
  unsigned long base;           /* the section's virtual address */
  unsigned long size;           /* the section's size in bytes */
  unsigned long filesize;       /* size in file, rest ist filled with '0' */
  struct list sections;         /* s. which have been linked together */
  struct RelRef *relrefs;       /* all sections which are referenced rel. */
  uint8 *data;                  /* the section's contents */
  struct list relocs;           /* the section's 32-bit relocations */
  struct list xrefs;            /* external references to unknown symbols */
  struct list symbols;          /* the section's symbol definitions */
};


struct FFFuncs {                /* file format specific functions and data */
  const char *tname;            /* name of file format */
  int (*identify)();            /* format identification */
  void (*readconv)();           /* read file and convert into internal fmt. */
  unsigned long (*secbase)();   /* default base address of a section */
  uint8 (*cmpsecflags)();       /* compare target-specific section flags */
  struct Section *(*bssdefault)(); /* create a default bss section */
  int (*targetlink)();          /* chk. if target requires linking of sect.*/
  struct Symbol *(*lnksymbol)();/* resolve linker-symbol reference */
  void (*setlnksym)();          /* init sym structure during resolve_xref() */
  void (*writeobject)();        /* write object file */
  void (*writeshared)();        /* write shared object file */
  void (*writeexec)();          /* write executable file */
  int32 baseoff;                /* sec. offset in bytes for base registers */
  struct Symbol **lnksyms;      /* linker symbols, supported by this target */
  signed char big_endian;       /* 1=bigEndian, 0=littleEndian */
};

/* Return codes from identify() */
#define ID_UNKNOWN 0            /* unknown file format */
#define ID_OBJECT 1             /* object file in current format */
#define ID_EXECUTABLE 2         /* executable file in current format */
#define ID_ARTIFICIAL 3         /* an art. object, created by the linker */
/* ^ objects and executables must have a smaller id-value! */
#define ID_LIBBASE 4            /* all ids >= 4 are libraries (s.o. or .a) */
#define ID_SHAREDBASE 4
#define ID_SHAREDOBJ 4          /* shared object file in current format */
#define ID_ARCHBASE 8
#define ID_LIBARCH 8            /* linker library archive in curr. format */
/* number of entries in linker symbol hash table */
#define LNKSYMHTABSIZE 0x10


/* List of artificially generated pointers or long words, which are */
/* sorted by ObjectUnit-name, section-name and priority. */
struct PriPointer {
  struct node n;
  char *objname;
  char *secname;
  int priority;
  char *xrefname;
  uint32 addend;
};



/* Global defines */
#define DEF_MAXERRORS 999999    /* don't want this feature now... */
#define STRIP_NONE 0
#define STRIP_DEBUG 1           /* strip debugger symbols only */
#define STRIP_ALL 2             /* strip all symbols */
#define DISLOC_NONE 0
#define DISLOC_TMP 1            /* discard temporary local symbols */
#define DISLOC_ALL 2            /* discard all local symbols */


struct GlobalVars {
  /* options */
  struct list libpaths;         /* paths where to search for libraries */
  struct list inputlist;        /* list of input files */
  char *dest_name;              /* output (executable) file name */
  uint8 dest_format;            /* output file format */
  bool dest_object;             /* output file is a relocatable object */
  bool dest_sharedobj;          /* output as shared object */
  bool alloc_common;            /* force allocation of common symbols */
  bool whole_archive;           /* always link with whole archives */
  uint8 strip_symbols;          /* strip symbols */
  uint8 discard_local;          /* discard local symbols */
  bool short_rel;               /* use short form for relocations */
  bool small_code;              /* combine all code sections */
  bool small_data;              /* combine all data sections */
  bool multibase;               /* don't merge all base-rel. accessed sect.*/
  FILE *map_file;               /* map file */
  FILE *trace_file;             /* linker trace output */
  struct SymNames **trace_syms; /* trace-symbol hash table */
  struct SecBase *secbases;     /* section base addr., as defined by -T */

  /* errors */
  bool dontwarn;                /* suppress warnings */
  bool errflag;                 /* if true, don't create output file */
  int maxerrors;                /* # of errors to display, before aborting */
  int errcnt;                   /* number of errors displayed */
  int returncode;               /* return code for exit() */

  /* linking process */
  struct list linkfiles;        /* list of all link files (obj., libs,...)*/
  struct list selobjects;       /* list of included object units */
  struct list libobjects;       /* list of non-included library-objects */
  struct list sharedobjects;    /* list of shared objects */
  struct Symbol **symbols;      /* global symbol hash table */
  struct list pripointers;      /* list of PriPointer nodes */
  struct list lnksec;           /* list of linked sections */
  int nsecs;                    /* total number of sections in lnksec */
  signed char big_endian;       /* linking in big endian mode (1), */
                                /*  little endian (0), undefined (-1) */
};

#define SYMHTABSIZE 0x10000     /* number of entries in symbol hash table */
#define TRSYMHTABSIZE 0x40


/* global functions */
#include "ar.h"

/* main.c */
#ifndef MAIN_C
extern struct GlobalVars gvars;
extern void cleanup(struct GlobalVars *);
#endif

/* version.c */
#ifndef VERSION_C
extern void show_version(void);
extern void show_usage(void);
#endif

/* support.c */
#ifndef SUPPORT_C
#ifdef FASTALLOC
extern void init_mem(void);
#endif
extern void *alloc(size_t);
extern void *alloczero(size_t);
extern char *allocstring(char *);
extern void *alloc_hashtable(size_t);
extern void initlist(struct list *);
extern void insertbefore(struct node *,struct node *);
extern void insertbehind(struct node *,struct node *);
extern void addhead(struct list *,struct node *);
extern void addtail(struct list *,struct node *);
extern struct node *remhead(struct list *);
extern struct node *remnode(struct node *);
extern char *mapfile(char *);
extern char *base_name(char *);
extern char *check_name(char *);
extern int checkrange(uint32,int,bool);
extern uint16 swap16(uint16);
extern uint32 swap32(uint32);
extern uint16 read16sw(uint8 *);
extern uint32 read32sw(uint8 *);
extern void write16sw(uint8 *,uint16);
extern void write32sw(uint8 *,uint32);
extern void fwritex(FILE *,void *,size_t);
extern void fwrite32be(FILE *,uint32);
extern void fwrite_align(FILE *,uint32,uint32);
extern unsigned long elf_hash(unsigned char *);
extern unsigned long align(unsigned long,unsigned long);
extern int shiftval(uint32);
#endif
#define listempty(x) ((x)->first->next==NULL)

/* errors.c */
#ifndef ERRORS_C
extern void error(int,...);
extern void ierror(char *,...);
#endif

/* linker.c */
#ifndef LINKER_C
extern void linker_init(struct GlobalVars *);
extern void linker_load(struct GlobalVars *);
extern void linker_resolve(struct GlobalVars *);
extern void linker_relrefs(struct GlobalVars *);
extern void linker_join(struct GlobalVars *);
extern void linker_copy(struct GlobalVars *);
extern void linker_relocate(struct GlobalVars *);
extern void linker_write(struct GlobalVars *);
extern void linker_cleanup(struct GlobalVars *);
extern char *getobjname(struct ObjectUnit *);
extern void print_function_name(struct Section *,unsigned long);
extern bool trace_sym_access(struct GlobalVars *,char *);
#endif

/* targets.c */
#ifndef TARGETS_C
extern struct FFFuncs *fff[];
extern const char *sym_type[];
extern const char *sym_info[];
extern const char *sym_bind[];
extern unsigned long findsecbase(struct GlobalVars *,char *);
extern struct Symbol *findsymbol(struct GlobalVars *,char *name);
extern struct Symbol *addsymbol(struct GlobalVars *,struct Section *,
                                char *,uint32,uint8,uint8,uint8,uint8,uint32);
extern void addlocsymbol(struct GlobalVars *,struct Section *,char *,uint32,
                         uint8,uint8,uint8,uint32);
extern void addglobsym(struct GlobalVars *,struct Symbol *);
extern struct Symbol *addlnksymbol(struct FFFuncs *,struct Section *,char *,
                                   uint32,uint8,uint8,uint8,uint8,uint32);
extern struct Symbol *findlnksymbol(struct FFFuncs *,char *);
extern void addreloc(struct Section *,struct Section *,uint32,uint32,
                     uint8,int32);
extern void addxref(struct GlobalVars *,struct Section *,char *,uint32,
                    uint8,uint8,int32);
extern int32 readsection(struct GlobalVars *,uint8 *,uint8);
extern void writesection(struct GlobalVars *,uint8 *,uint8,uint32);
extern uint8 relocsize(uint8);
extern struct Section *create_section(struct ObjectUnit *,char *,
                                      uint8 *,unsigned long);
extern struct Section *find_sect_type(struct ObjectUnit *,uint8,uint8);
extern struct Section *find_sect_id(struct ObjectUnit *,uint32);
extern struct LinkedSection *find_lnksec(struct GlobalVars *,char *,uint8,
                                         uint8,uint8);
extern struct LinkedSection *smalldata_section(struct GlobalVars *);
extern void add_objunit(struct GlobalVars *,struct ObjectUnit *,bool);
extern struct ObjectUnit *create_objunit(struct LinkFile *,char *);
extern struct ObjectUnit *art_objunit(char *,uint8 *,unsigned long,uint8);
extern void new_priptr(struct ObjectUnit *,char *,char *,int,char *,uint32);
extern void add_priptrs(struct GlobalVars *,struct ObjectUnit *);
extern void make_priptr_objects(struct GlobalVars *);
extern bool ar_init(struct ar_info *,char *,unsigned long,char *);
extern bool ar_extract(struct ar_info *);
#endif

/* t_amigaos.c */
#if defined(AMIGAOS) || defined(EHF)
#ifndef T_AMIGAOS_C
extern struct FFFuncs fff_amigaos;
extern struct FFFuncs fff_ehf;
#endif
#endif

/* dir.c */
#ifndef DIR_C
extern char *open_dir(char *);
extern char *read_dir(char *);
extern void close_dir(char *);
extern bool chk_file(char *);
#endif

/* relocnames.c */
extern char *reloc_name[];

/* t_elf32.c */
#if defined(ELF32_PPC_BE)
#ifndef T_ELF32_C
extern struct FFFuncs fff_elf32ppcbe;
#endif
#endif
#if defined(ELF32_POWERUP)
#ifndef T_ELF32_C
extern struct FFFuncs fff_elf32powerup;
#endif
#endif

/* t_elf64.c */
#if defined(ELF64_ALPHA)
#ifndef T_ELF64_C
extern struct FFFuncs fff_elf64alpha;
#endif
#endif
