Back to index

cell-binutils  2.17cvs20070401
internal.h
Go to the documentation of this file.
00001 /* ELF support for BFD.
00002    Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002,
00003    2003, 2006 Free Software Foundation, Inc.
00004 
00005    Written by Fred Fish @ Cygnus Support, from information published
00006    in "UNIX System V Release 4, Programmers Guide: ANSI C and
00007    Programming Support Tools".
00008 
00009 This file is part of BFD, the Binary File Descriptor library.
00010 
00011 This program is free software; you can redistribute it and/or modify
00012 it under the terms of the GNU General Public License as published by
00013 the Free Software Foundation; either version 2 of the License, or
00014 (at your option) any later version.
00015 
00016 This program is distributed in the hope that it will be useful,
00017 but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 GNU General Public License for more details.
00020 
00021 You should have received a copy of the GNU General Public License
00022 along with this program; if not, write to the Free Software
00023 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00024 
00025 
00026 /* This file is part of ELF support for BFD, and contains the portions
00027    that describe how ELF is represented internally in the BFD library.
00028    I.E. it describes the in-memory representation of ELF.  It requires
00029    the elf-common.h file which contains the portions that are common to
00030    both the internal and external representations. */
00031 
00032 
00033 /* NOTE that these structures are not kept in the same order as they appear
00034    in the object file.  In some cases they've been reordered for more optimal
00035    packing under various circumstances.  */
00036 
00037 #ifndef _ELF_INTERNAL_H
00038 #define _ELF_INTERNAL_H
00039 
00040 /* ELF Header */
00041 
00042 #define EI_NIDENT    16            /* Size of e_ident[] */
00043 
00044 typedef struct elf_internal_ehdr {
00045   unsigned char             e_ident[EI_NIDENT]; /* ELF "magic number" */
00046   bfd_vma            e_entry;      /* Entry point virtual address */
00047   bfd_size_type             e_phoff;      /* Program header table file offset */
00048   bfd_size_type             e_shoff;      /* Section header table file offset */
00049   unsigned long             e_version;    /* Identifies object file version */
00050   unsigned long             e_flags;      /* Processor-specific flags */
00051   unsigned short     e_type;              /* Identifies object file type */
00052   unsigned short     e_machine;    /* Specifies required architecture */
00053   unsigned int              e_ehsize;     /* ELF header size in bytes */
00054   unsigned int              e_phentsize;  /* Program header table entry size */
00055   unsigned int              e_phnum;      /* Program header table entry count */
00056   unsigned int              e_shentsize;  /* Section header table entry size */
00057   unsigned int              e_shnum;      /* Section header table entry count */
00058   unsigned int              e_shstrndx;   /* Section header string table index */
00059 } Elf_Internal_Ehdr;
00060 
00061 /* Program header */
00062 
00063 struct elf_internal_phdr {
00064   unsigned long      p_type;                     /* Identifies program segment type */
00065   unsigned long      p_flags;             /* Segment flags */
00066   bfd_vma     p_offset;            /* Segment file offset */
00067   bfd_vma     p_vaddr;             /* Segment virtual address */
00068   bfd_vma     p_paddr;             /* Segment physical address */
00069   bfd_vma     p_filesz;            /* Segment size in file */
00070   bfd_vma     p_memsz;             /* Segment size in memory */
00071   bfd_vma     p_align;             /* Segment alignment, file & memory */
00072 };
00073 
00074 typedef struct elf_internal_phdr Elf_Internal_Phdr;
00075 
00076 /* Section header */
00077 
00078 typedef struct elf_internal_shdr {
00079   unsigned int       sh_name;             /* Section name, index in string tbl */
00080   unsigned int       sh_type;             /* Type of section */
00081   bfd_vma     sh_flags;            /* Miscellaneous section attributes */
00082   bfd_vma     sh_addr;             /* Section virtual addr at execution */
00083   bfd_size_type      sh_size;             /* Size of section in bytes */
00084   bfd_size_type      sh_entsize;          /* Entry size if section holds table */
00085   unsigned long      sh_link;             /* Index of another section */
00086   unsigned long      sh_info;             /* Additional section information */
00087   file_ptr    sh_offset;           /* Section file offset */
00088   unsigned int       sh_addralign;        /* Section alignment */
00089 
00090   /* The internal rep also has some cached info associated with it. */
00091   asection *  bfd_section;         /* Associated BFD section.  */
00092   unsigned char *contents;         /* Section contents.  */
00093 } Elf_Internal_Shdr;
00094 
00095 /* Symbol table entry */
00096 
00097 struct elf_internal_sym {
00098   bfd_vma     st_value;            /* Value of the symbol */
00099   bfd_vma     st_size;             /* Associated symbol size */
00100   unsigned long      st_name;             /* Symbol name, index in string tbl */
00101   unsigned char      st_info;             /* Type and binding attributes */
00102   unsigned char      st_other;            /* Visibilty, and target specific */
00103   unsigned int  st_shndx;          /* Associated section index */
00104 };
00105 
00106 typedef struct elf_internal_sym Elf_Internal_Sym;
00107 
00108 /* Note segments */
00109 
00110 typedef struct elf_internal_note {
00111   unsigned long      namesz;                     /* Size of entry's owner string */
00112   unsigned long      descsz;                     /* Size of the note descriptor */
00113   unsigned long      type;                /* Interpretation of the descriptor */
00114   char *      namedata;            /* Start of the name+desc data */
00115   char *      descdata;            /* Start of the desc data */
00116   bfd_vma     descpos;             /* File offset of the descdata */
00117 } Elf_Internal_Note;
00118 
00119 /* Relocation Entries */
00120 
00121 typedef struct elf_internal_rela {
00122   bfd_vma     r_offset;     /* Location at which to apply the action */
00123   bfd_vma     r_info;              /* Index and Type of relocation */
00124   bfd_vma     r_addend;     /* Constant addend used to compute value */
00125 } Elf_Internal_Rela;
00126 
00127 /* dynamic section structure */
00128 
00129 typedef struct elf_internal_dyn {
00130   /* This needs to support 64-bit values in elf64.  */
00131   bfd_vma d_tag;            /* entry tag value */
00132   union {
00133     /* This needs to support 64-bit values in elf64.  */
00134     bfd_vma   d_val;
00135     bfd_vma   d_ptr;
00136   } d_un;
00137 } Elf_Internal_Dyn;
00138 
00139 /* This structure appears in a SHT_GNU_verdef section.  */
00140 
00141 typedef struct elf_internal_verdef {
00142   unsigned short vd_version;       /* Version number of structure.  */
00143   unsigned short vd_flags;  /* Flags (VER_FLG_*).  */
00144   unsigned short vd_ndx;    /* Version index.  */
00145   unsigned short vd_cnt;    /* Number of verdaux entries.  */
00146   unsigned long       vd_hash;     /* Hash of name.  */
00147   unsigned long       vd_aux;      /* Offset to verdaux entries.  */
00148   unsigned long       vd_next;     /* Offset to next verdef.  */
00149 
00150   /* These fields are set up when BFD reads in the structure.  FIXME:
00151      It would be cleaner to store these in a different structure.  */
00152   bfd                      *vd_bfd;              /* BFD.  */
00153   const char               *vd_nodename;  /* Version name.  */
00154   struct elf_internal_verdef  *vd_nextdef;       /* vd_next as pointer.  */
00155   struct elf_internal_verdaux *vd_auxptr; /* vd_aux as pointer.  */
00156   unsigned int                     vd_exp_refno; /* Used by the linker.  */
00157 } Elf_Internal_Verdef;
00158 
00159 /* This structure appears in a SHT_GNU_verdef section.  */
00160 
00161 typedef struct elf_internal_verdaux {
00162   unsigned long vda_name;   /* String table offset of name.  */
00163   unsigned long vda_next;   /* Offset to next verdaux.  */
00164 
00165   /* These fields are set up when BFD reads in the structure.  FIXME:
00166      It would be cleaner to store these in a different structure.  */
00167   const char *vda_nodename;               /* vda_name as pointer.  */
00168   struct elf_internal_verdaux *vda_nextptr;      /* vda_next as pointer.  */
00169 } Elf_Internal_Verdaux;
00170 
00171 /* This structure appears in a SHT_GNU_verneed section.  */
00172 
00173 typedef struct elf_internal_verneed {
00174   unsigned short vn_version;       /* Version number of structure.  */
00175   unsigned short vn_cnt;    /* Number of vernaux entries.  */
00176   unsigned long       vn_file;     /* String table offset of library name.  */
00177   unsigned long       vn_aux;      /* Offset to vernaux entries.  */
00178   unsigned long       vn_next;     /* Offset to next verneed.  */
00179 
00180   /* These fields are set up when BFD reads in the structure.  FIXME:
00181      It would be cleaner to store these in a different structure.  */
00182   bfd                      *vn_bfd;              /* BFD.  */
00183   const char                  *vn_filename;      /* vn_file as pointer.  */
00184   struct elf_internal_vernaux *vn_auxptr; /* vn_aux as pointer.  */
00185   struct elf_internal_verneed *vn_nextref;       /* vn_nextref as pointer.  */
00186 } Elf_Internal_Verneed;
00187 
00188 /* This structure appears in a SHT_GNU_verneed section.  */
00189 
00190 typedef struct elf_internal_vernaux {
00191   unsigned long       vna_hash;    /* Hash of dependency name.  */
00192   unsigned short vna_flags; /* Flags (VER_FLG_*).  */
00193   unsigned short vna_other; /* Unused.  */
00194   unsigned long       vna_name;    /* String table offset to version name.  */
00195   unsigned long       vna_next;    /* Offset to next vernaux.  */
00196 
00197   /* These fields are set up when BFD reads in the structure.  FIXME:
00198      It would be cleaner to store these in a different structure.  */
00199   const char                  *vna_nodename;     /* vna_name as pointer.  */
00200   struct elf_internal_vernaux *vna_nextptr;      /* vna_next as pointer.  */
00201 } Elf_Internal_Vernaux;
00202 
00203 /* This structure appears in a SHT_GNU_versym section.  This is not a
00204    standard ELF structure; ELF just uses Elf32_Half.  */
00205 
00206 typedef struct elf_internal_versym {
00207   unsigned short vs_vers;
00208 } Elf_Internal_Versym;
00209 
00210 /* Structure for syminfo section.  */
00211 typedef struct
00212 {
00213   unsigned short int        si_boundto;
00214   unsigned short int si_flags;
00215 } Elf_Internal_Syminfo;
00216 
00217 /* This structure appears on the stack and in NT_AUXV core file notes.  */
00218 typedef struct
00219 {
00220   bfd_vma a_type;
00221   bfd_vma a_val;
00222 } Elf_Internal_Auxv;
00223 
00224 
00225 /* This structure is used to describe how sections should be assigned
00226    to program segments.  */
00227 
00228 struct elf_segment_map
00229 {
00230   /* Next program segment.  */
00231   struct elf_segment_map *next;
00232   /* Program segment type.  */
00233   unsigned long p_type;
00234   /* Program segment flags.  */
00235   unsigned long p_flags;
00236   /* Program segment physical address.  */
00237   bfd_vma p_paddr;
00238   /* Program segment virtual address offset from section vma.  */
00239   bfd_vma p_vaddr_offset;
00240   /* Program segment alignment.  */
00241   bfd_vma p_align;
00242   /* Whether the p_flags field is valid; if not, the flags are based
00243      on the section flags.  */
00244   unsigned int p_flags_valid : 1;
00245   /* Whether the p_paddr field is valid; if not, the physical address
00246      is based on the section lma values.  */
00247   unsigned int p_paddr_valid : 1;
00248   /* Whether the p_align field is valid; if not, PT_LOAD segment
00249      alignment is based on the default maximum page size.  */
00250   unsigned int p_align_valid : 1;
00251   /* Whether this segment includes the file header.  */
00252   unsigned int includes_filehdr : 1;
00253   /* Whether this segment includes the program headers.  */
00254   unsigned int includes_phdrs : 1;
00255   /* Number of sections (may be 0).  */
00256   unsigned int count;
00257   /* Sections.  Actual number of elements is in count field.  */
00258   asection *sections[1];
00259 };
00260 
00261 /* .tbss is special.  It doesn't contribute memory space to normal
00262    segments and it doesn't take file space in normal segments.  */
00263 #define ELF_SECTION_SIZE(sec_hdr, segment)                     \
00264    (((sec_hdr->sh_flags & SHF_TLS) == 0                        \
00265      || sec_hdr->sh_type != SHT_NOBITS                         \
00266      || segment->p_type == PT_TLS) ? sec_hdr->sh_size : 0)
00267 
00268 /* Decide if the given sec_hdr is in the given segment.  PT_TLS segment
00269    contains only SHF_TLS sections.  Only PT_LOAD and PT_TLS segments
00270    can contain SHF_TLS sections.  */
00271 #define ELF_IS_SECTION_IN_SEGMENT(sec_hdr, segment)            \
00272   (((((sec_hdr->sh_flags & SHF_TLS) != 0)               \
00273      && (segment->p_type == PT_TLS                      \
00274         || segment->p_type == PT_LOAD))                 \
00275     || ((sec_hdr->sh_flags & SHF_TLS) == 0                     \
00276        && segment->p_type != PT_TLS))                          \
00277    /* Compare allocated sec_hdrs by VMA, unallocated sec_hdrs  \
00278       by file offset.  */                               \
00279    && (sec_hdr->sh_flags & SHF_ALLOC                           \
00280        ? (sec_hdr->sh_addr >= segment->p_vaddr                 \
00281          && (sec_hdr->sh_addr                                  \
00282              + ELF_SECTION_SIZE(sec_hdr, segment)              \
00283              <= segment->p_vaddr + segment->p_memsz))          \
00284        : ((bfd_vma) sec_hdr->sh_offset >= segment->p_offset    \
00285          && (sec_hdr->sh_offset                         \
00286              + ELF_SECTION_SIZE(sec_hdr, segment)              \
00287              <= segment->p_offset + segment->p_filesz))))
00288 
00289 /* Decide if the given sec_hdr is in the given segment in file.  */
00290 #define ELF_IS_SECTION_IN_SEGMENT_FILE(sec_hdr, segment)       \
00291   (sec_hdr->sh_size > 0                                        \
00292    && ELF_IS_SECTION_IN_SEGMENT (sec_hdr, segment))
00293 
00294 /* Decide if the given sec_hdr is in the given segment in memory.  */
00295 #define ELF_IS_SECTION_IN_SEGMENT_MEMORY(sec_hdr, segment)     \
00296   (ELF_SECTION_SIZE(sec_hdr, segment) > 0               \
00297    && ELF_IS_SECTION_IN_SEGMENT (sec_hdr, segment))
00298 
00299 #endif /* _ELF_INTERNAL_H */