
#include "../libasmir/config.h"
#if SIZEOF_BFD_VMA == 4
typedef [int64] unsigned long address_t;
#else
typedef  unsigned long long int address_t; 
#endif

// From bfd.h
enum bfd_architecture
{
  bfd_arch_unknown,   /* File arch not known.   */
  bfd_arch_obscure,   /* Arch known, not one of these.   */
  bfd_arch_m68k,      /* Motorola 68xxx */
  bfd_arch_vax,       /* DEC Vax */
  bfd_arch_i960,      /* Intel 960 */
  bfd_arch_or32,      /* OpenRISC 32 */
  bfd_arch_sparc,     /* SPARC */
  bfd_arch_spu,       /* PowerPC SPU */
  bfd_arch_mips,      /* MIPS Rxxxx */
  bfd_arch_i386,      /* Intel 386 */
  bfd_arch_we32k,     /* AT&T WE32xxx */
  bfd_arch_tahoe,     /* CCI/Harris Tahoe */
  bfd_arch_i860,      /* Intel 860 */
  bfd_arch_i370,      /* IBM 360/370 Mainframes */
  bfd_arch_romp,      /* IBM ROMP PC/RT */
  bfd_arch_convex,    /* Convex */
  bfd_arch_m88k,      /* Motorola 88xxx */
  bfd_arch_m98k,      /* Motorola 98xxx */
  bfd_arch_pyramid,   /* Pyramid Technology */
  bfd_arch_h8300,     /* Renesas H8/300 (formerly Hitachi H8/300) */
  bfd_arch_pdp11,     /* DEC PDP-11 */
  bfd_arch_powerpc,   /* PowerPC */
  bfd_arch_rs6000,    /* IBM RS/6000 */
  bfd_arch_hppa,      /* HP PA RISC */
  bfd_arch_d10v,      /* Mitsubishi D10V */
  bfd_arch_d30v,      /* Mitsubishi D30V */
  bfd_arch_dlx,       /* DLX */
  bfd_arch_m68hc11,   /* Motorola 68HC11 */
  bfd_arch_m68hc12,   /* Motorola 68HC12 */
  bfd_arch_z8k,       /* Zilog Z8000 */
  bfd_arch_h8500,     /* Renesas H8/500 (formerly Hitachi H8/500) */
  bfd_arch_sh,        /* Renesas / SuperH SH (formerly Hitachi SH) */
  bfd_arch_alpha,     /* Dec Alpha */
  bfd_arch_arm,       /* Advanced Risc Machines ARM.   */
  bfd_arch_ns32k,     /* National Semiconductors ns32000 */
  bfd_arch_w65,       /* WDC 65816 */
  bfd_arch_tic30,     /* Texas Instruments TMS320C30 */
  bfd_arch_tic4x,     /* Texas Instruments TMS320C3X/4X */
  bfd_arch_tic54x,    /* Texas Instruments TMS320C54X */
  bfd_arch_tic80,     /* TI TMS320c80 (MVP) */
  bfd_arch_v850,      /* NEC V850 */
  bfd_arch_arc,       /* ARC Cores */
  bfd_arch_m32c,     /* Renesas M16C/M32C.  */
  bfd_arch_m32r,      /* Renesas M32R (formerly Mitsubishi M32R/D) */
  bfd_arch_mn10200,   /* Matsushita MN10200 */
  bfd_arch_mn10300,   /* Matsushita MN10300 */
  bfd_arch_fr30,
  bfd_arch_frv,
  bfd_arch_mcore,
  bfd_arch_mep,
  bfd_arch_ia64,      /* HP/Intel ia64 */
  bfd_arch_ip2k,      /* Ubicom IP2K microcontrollers. */ 
  bfd_arch_iq2000,     /* Vitesse IQ2000.   */
  bfd_arch_mt,
  bfd_arch_pj,
  bfd_arch_avr,       /* Atmel AVR microcontrollers.   */
  bfd_arch_bfin,        /* ADI Blackfin */
  bfd_arch_cr16,       /* National Semiconductor CompactRISC (ie CR16). */ 
  bfd_arch_cr16c,       /* National Semiconductor CompactRISC. */ 
  bfd_arch_crx,       /*  National Semiconductor CRX.   */
  bfd_arch_cris,      /* Axis CRIS */
  bfd_arch_s390,      /* IBM s390 */
  bfd_arch_score,     /* Sunplus score */ 
  bfd_arch_openrisc,  /* OpenRISC */
  bfd_arch_mmix,      /* Donald Knuth's educational processor.   */
  bfd_arch_xstormy16,
  bfd_arch_msp430,    /* Texas Instruments MSP430 architecture.   */
  bfd_arch_xc16x,     /* Infineon's XC16X Series.                */
  bfd_arch_xtensa,    /* Tensilica's Xtensa cores.   */
  bfd_arch_maxq,     /* Dallas MAXQ 10/20 */
  bfd_arch_z80,
  bfd_arch_last
};

struct bfd;

typedef [abstract] struct bfd* bfdp;

struct bfd_section /*{
  [string] const char *name;
  int id;
  int index;
  [ignore] struct bfd_section *next, *prev;
  int flags;
  int bitfields;
  address_t vma;
  address_t lma;
  address_t size, rawsize;
  // more stuff we don't care about
  }*/;
typedef [abstract,ref] struct bfd_section *section_ptr;

struct notreally {
  [string] const char * name;
};

struct bfd_symbol {
  /*[ignore]*/ bfdp the_bfd;
  [string] const char *name;
  __int64 value;
  int flags;
  section_ptr section;
  // more stuff, but we don't care
};

typedef [ref] struct bfd_symbol *asymbol;


/*
typedef struct bfd_section *asection;
asection bfd_sections( bfdp abfd);
asection bfd_next_section( asection *s);
*/

typedef int bfd_boolean;
typedef long long file_ptr;
typedef unsigned long long bfd_size_type;

bfd_boolean bfd_get_section_contents
(bfdp abfd, section_ptr section, [out, length_is(count), bigarray] char location[], file_ptr offset,
 bfd_size_type count);

address_t bfd_section_get_vma(section_ptr s);
bfd_size_type bfd_section_get_size(section_ptr s);
[string] const char* bfd_section_get_name(section_ptr s);
__int64 bfd_section_get_flags(section_ptr s);




// From /usr/include/bfd.h

const __int64 SEC_NO_FLAGS   = 0x000;

  /* Tells the OS to allocate space for this section when loading. 
     This is clear for a section containing debug information only.   */
const __int64 SEC_ALLOC      = 0x001;

  /* Tells the OS to load the section from the file when loading. 
     This is clear for a .bss section.   */
const __int64 SEC_LOAD       = 0x002;

  /* The section contains data still to be relocated, so there is
     some relocation information too.   */
const __int64 SEC_RELOC      = 0x004;

  /* A signal to the OS that the section contains read only data.   */
const __int64 SEC_READONLY   = 0x008;

  /* The section contains code only.   */
const __int64 SEC_CODE       = 0x010;

  /* The section contains data only.   */
const __int64 SEC_DATA       = 0x020;

  /* The section will reside in ROM.   */
const __int64 SEC_ROM        = 0x040;

  /* The section contains constructor information.  This section
     type is used by the linker to create lists of constructors and
     destructors used by <<g++>>.  When a back end sees a symbol
     which should be used in a constructor list, it creates a new
     section for the type of name (e.g., <<__CTOR_LIST__>>), attaches
     the symbol to it, and builds a relocation.  To build the lists
     of constructors, all the linker has to do is catenate all the
     sections called <<__CTOR_LIST__>> and relocate the data
     contained within - exactly the operations it would peform on
     standard data.   */
const __int64 SEC_CONSTRUCTOR = 0x080;

  /* The section has contents - a data section could be
     <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>; a debug section could be
     <<SEC_HAS_CONTENTS>>  */
const __int64 SEC_HAS_CONTENTS = 0x100;

  /* An instruction to the linker to not output the section
     even if it has information which would normally be written.   */
const __int64 SEC_NEVER_LOAD = 0x200;

  /* The section contains thread local data.   */
const __int64 SEC_THREAD_LOCAL = 0x400;

  /* The section has GOT references.   This flag is only for the
     linker, and is currently only used by the elf32-hppa back end. 
     It will be set if global offset table references were detected
     in this section, which indicate to the linker that the section
     contains PIC code, and must be handled specially when doing a
     static link.   */
const __int64 SEC_HAS_GOT_REF = 0x800;

  /* The section contains common symbols (symbols may be defined
     multiple times, the value of a symbol is the amount of
     space it requires, and the largest symbol value is the one
     used).   Most targets have exactly one of these (which we
     translate to bfd_com_section_ptr), but ECOFF has two.   */
const __int64 SEC_IS_COMMON = 0x1000;

  /* The section contains only debugging information.   For
     example, this is set for ELF .debug and .stab sections. 
     strip tests this flag to see if a section can be
     discarded.   */
const __int64 SEC_DEBUGGING = 0x2000;

  /* The contents of this section are held in memory pointed to
     by the contents field.   This is checked by bfd_get_section_contents,
     and the data is retrieved from memory if appropriate.   */
const __int64 SEC_IN_MEMORY = 0x4000;

  /* The contents of this section are to be excluded by the
     linker for executable and shared objects unless those
     objects are to be further relocated.   */
const __int64 SEC_EXCLUDE = 0x8000;

  /* The contents of this section are to be sorted based on the sum of
     the symbol and addend values specified by the associated relocation
     entries.   Entries without associated relocation entries will be
     appended to the end of the section in an unspecified order.   */
const __int64 SEC_SORT_ENTRIES = 0x10000;

  /* When linking, duplicate sections of the same name should be
     discarded, rather than being combined into a single section as
     is usually done.   This is similar to how common symbols are
     handled.   See SEC_LINK_DUPLICATES below.   */
const __int64 SEC_LINK_ONCE = 0x20000;

  /* If SEC_LINK_ONCE is set, this bitfield describes how the linker
     should handle duplicate sections.   */
const __int64 SEC_LINK_DUPLICATES = 0xc0000;

  /* This value for SEC_LINK_DUPLICATES means that duplicate
     sections with the same name should simply be discarded.   */
const __int64 SEC_LINK_DUPLICATES_DISCARD = 0x0;

  /* This value for SEC_LINK_DUPLICATES means that the linker
     should warn if there are any duplicate sections, although
     it should still only link one copy.   */
const __int64 SEC_LINK_DUPLICATES_ONE_ONLY = 0x40000;

  /* This value for SEC_LINK_DUPLICATES means that the linker
     should warn if any duplicate sections are a different size.   */
const __int64 SEC_LINK_DUPLICATES_SAME_SIZE = 0x80000;

  /* This value for SEC_LINK_DUPLICATES means that the linker
     should warn if any duplicate sections contain different
     contents.   */
const __int64 SEC_LINK_DUPLICATES_SAME_CONTENTS =
  (SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE);

  /* This section was created by the linker as part of dynamic
     relocation or other arcane processing.   It is skipped when
     going through the first-pass output, trusting that someone
     else up the line will take care of it later.   */
const __int64 SEC_LINKER_CREATED = 0x100000;

  /* This section should not be subject to garbage collection. 
     Also set to inform the linker that this section should not be
     listed in the link map as discarded.   */
const __int64 SEC_KEEP = 0x200000;

  /* This section contains "short" data, and should be placed
     "near" the GP.   */
const __int64 SEC_SMALL_DATA = 0x400000;

  /* Attempt to merge identical entities in the section. 
     Entity size is given in the entsize field.   */
const __int64 SEC_MERGE = 0x800000;

  /* If given with SEC_MERGE, entities to merge are zero terminated
     strings where entsize specifies character size instead of fixed
     size entries.   */
const __int64 SEC_STRINGS = 0x1000000;

  /* This section contains data about section groups.   */
const __int64 SEC_GROUP = 0x2000000;

  /* The section is a COFF shared library section.   This flag is
     only for the linker.   If this type of section appears in
     the input file, the linker must copy it to the output file
     without changing the vma or size.   FIXME: Although this
     was originally intended to be general, it really is COFF
     specific (and the flag was renamed to indicate this).   It
     might be cleaner to have some more general mechanism to
     allow the back end to control what the linker does with
     sections.   */
const __int64 SEC_COFF_SHARED_LIBRARY = 0x4000000;

  /* This section contains data which may be shared with other
     executables or shared objects.  This is for COFF only.   */
const __int64 SEC_COFF_SHARED = 0x8000000;

  /* When a section with this flag is being linked, then if the size of
     the input section is less than a page, it should not cross a page
     boundary.   If the size of the input section is one page or more,
     it should be aligned on a page boundary.   This is for TI
     TMS320C54X only.   */
const __int64 SEC_TIC54X_BLOCK = 0x10000000;

  /* Conditionally link this section; do not link if there are no
     references found to any symbol in the section.   This is for TI
     TMS320C54X only.   */
const __int64 SEC_TIC54X_CLINK = 0x20000000;

  /* Indicate that section has the no read flag set.  This happens
     when memory read flag isn't set. */ 
const __int64 SEC_COFF_NOREAD = 0x40000000;

  /*  End of section flags.   */
