1*3d8817e4Smiod /* ELF support for BFD. 2*3d8817e4Smiod Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, 3*3d8817e4Smiod 2003 Free Software Foundation, Inc. 4*3d8817e4Smiod 5*3d8817e4Smiod Written by Fred Fish @ Cygnus Support, from information published 6*3d8817e4Smiod in "UNIX System V Release 4, Programmers Guide: ANSI C and 7*3d8817e4Smiod Programming Support Tools". 8*3d8817e4Smiod 9*3d8817e4Smiod This file is part of BFD, the Binary File Descriptor library. 10*3d8817e4Smiod 11*3d8817e4Smiod This program is free software; you can redistribute it and/or modify 12*3d8817e4Smiod it under the terms of the GNU General Public License as published by 13*3d8817e4Smiod the Free Software Foundation; either version 2 of the License, or 14*3d8817e4Smiod (at your option) any later version. 15*3d8817e4Smiod 16*3d8817e4Smiod This program is distributed in the hope that it will be useful, 17*3d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of 18*3d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19*3d8817e4Smiod GNU General Public License for more details. 20*3d8817e4Smiod 21*3d8817e4Smiod You should have received a copy of the GNU General Public License 22*3d8817e4Smiod along with this program; if not, write to the Free Software 23*3d8817e4Smiod Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 24*3d8817e4Smiod 25*3d8817e4Smiod 26*3d8817e4Smiod /* This file is part of ELF support for BFD, and contains the portions 27*3d8817e4Smiod that describe how ELF is represented internally in the BFD library. 28*3d8817e4Smiod I.E. it describes the in-memory representation of ELF. It requires 29*3d8817e4Smiod the elf-common.h file which contains the portions that are common to 30*3d8817e4Smiod both the internal and external representations. */ 31*3d8817e4Smiod 32*3d8817e4Smiod 33*3d8817e4Smiod /* NOTE that these structures are not kept in the same order as they appear 34*3d8817e4Smiod in the object file. In some cases they've been reordered for more optimal 35*3d8817e4Smiod packing under various circumstances. */ 36*3d8817e4Smiod 37*3d8817e4Smiod #ifndef _ELF_INTERNAL_H 38*3d8817e4Smiod #define _ELF_INTERNAL_H 39*3d8817e4Smiod 40*3d8817e4Smiod /* ELF Header */ 41*3d8817e4Smiod 42*3d8817e4Smiod #define EI_NIDENT 16 /* Size of e_ident[] */ 43*3d8817e4Smiod 44*3d8817e4Smiod typedef struct elf_internal_ehdr { 45*3d8817e4Smiod unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */ 46*3d8817e4Smiod bfd_vma e_entry; /* Entry point virtual address */ 47*3d8817e4Smiod bfd_size_type e_phoff; /* Program header table file offset */ 48*3d8817e4Smiod bfd_size_type e_shoff; /* Section header table file offset */ 49*3d8817e4Smiod unsigned long e_version; /* Identifies object file version */ 50*3d8817e4Smiod unsigned long e_flags; /* Processor-specific flags */ 51*3d8817e4Smiod unsigned short e_type; /* Identifies object file type */ 52*3d8817e4Smiod unsigned short e_machine; /* Specifies required architecture */ 53*3d8817e4Smiod unsigned int e_ehsize; /* ELF header size in bytes */ 54*3d8817e4Smiod unsigned int e_phentsize; /* Program header table entry size */ 55*3d8817e4Smiod unsigned int e_phnum; /* Program header table entry count */ 56*3d8817e4Smiod unsigned int e_shentsize; /* Section header table entry size */ 57*3d8817e4Smiod unsigned int e_shnum; /* Section header table entry count */ 58*3d8817e4Smiod unsigned int e_shstrndx; /* Section header string table index */ 59*3d8817e4Smiod } Elf_Internal_Ehdr; 60*3d8817e4Smiod 61*3d8817e4Smiod /* Program header */ 62*3d8817e4Smiod 63*3d8817e4Smiod struct elf_internal_phdr { 64*3d8817e4Smiod unsigned long p_type; /* Identifies program segment type */ 65*3d8817e4Smiod unsigned long p_flags; /* Segment flags */ 66*3d8817e4Smiod bfd_vma p_offset; /* Segment file offset */ 67*3d8817e4Smiod bfd_vma p_vaddr; /* Segment virtual address */ 68*3d8817e4Smiod bfd_vma p_paddr; /* Segment physical address */ 69*3d8817e4Smiod bfd_vma p_filesz; /* Segment size in file */ 70*3d8817e4Smiod bfd_vma p_memsz; /* Segment size in memory */ 71*3d8817e4Smiod bfd_vma p_align; /* Segment alignment, file & memory */ 72*3d8817e4Smiod }; 73*3d8817e4Smiod 74*3d8817e4Smiod typedef struct elf_internal_phdr Elf_Internal_Phdr; 75*3d8817e4Smiod 76*3d8817e4Smiod /* Section header */ 77*3d8817e4Smiod 78*3d8817e4Smiod typedef struct elf_internal_shdr { 79*3d8817e4Smiod unsigned int sh_name; /* Section name, index in string tbl */ 80*3d8817e4Smiod unsigned int sh_type; /* Type of section */ 81*3d8817e4Smiod bfd_vma sh_flags; /* Miscellaneous section attributes */ 82*3d8817e4Smiod bfd_vma sh_addr; /* Section virtual addr at execution */ 83*3d8817e4Smiod bfd_size_type sh_size; /* Size of section in bytes */ 84*3d8817e4Smiod bfd_size_type sh_entsize; /* Entry size if section holds table */ 85*3d8817e4Smiod unsigned long sh_link; /* Index of another section */ 86*3d8817e4Smiod unsigned long sh_info; /* Additional section information */ 87*3d8817e4Smiod file_ptr sh_offset; /* Section file offset */ 88*3d8817e4Smiod unsigned int sh_addralign; /* Section alignment */ 89*3d8817e4Smiod 90*3d8817e4Smiod /* The internal rep also has some cached info associated with it. */ 91*3d8817e4Smiod asection * bfd_section; /* Associated BFD section. */ 92*3d8817e4Smiod unsigned char *contents; /* Section contents. */ 93*3d8817e4Smiod } Elf_Internal_Shdr; 94*3d8817e4Smiod 95*3d8817e4Smiod /* Symbol table entry */ 96*3d8817e4Smiod 97*3d8817e4Smiod struct elf_internal_sym { 98*3d8817e4Smiod bfd_vma st_value; /* Value of the symbol */ 99*3d8817e4Smiod bfd_vma st_size; /* Associated symbol size */ 100*3d8817e4Smiod unsigned long st_name; /* Symbol name, index in string tbl */ 101*3d8817e4Smiod unsigned char st_info; /* Type and binding attributes */ 102*3d8817e4Smiod unsigned char st_other; /* Visibilty, and target specific */ 103*3d8817e4Smiod unsigned int st_shndx; /* Associated section index */ 104*3d8817e4Smiod }; 105*3d8817e4Smiod 106*3d8817e4Smiod typedef struct elf_internal_sym Elf_Internal_Sym; 107*3d8817e4Smiod 108*3d8817e4Smiod /* Note segments */ 109*3d8817e4Smiod 110*3d8817e4Smiod typedef struct elf_internal_note { 111*3d8817e4Smiod unsigned long namesz; /* Size of entry's owner string */ 112*3d8817e4Smiod unsigned long descsz; /* Size of the note descriptor */ 113*3d8817e4Smiod unsigned long type; /* Interpretation of the descriptor */ 114*3d8817e4Smiod char * namedata; /* Start of the name+desc data */ 115*3d8817e4Smiod char * descdata; /* Start of the desc data */ 116*3d8817e4Smiod bfd_vma descpos; /* File offset of the descdata */ 117*3d8817e4Smiod } Elf_Internal_Note; 118*3d8817e4Smiod 119*3d8817e4Smiod /* Relocation Entries */ 120*3d8817e4Smiod 121*3d8817e4Smiod typedef struct elf_internal_rela { 122*3d8817e4Smiod bfd_vma r_offset; /* Location at which to apply the action */ 123*3d8817e4Smiod bfd_vma r_info; /* Index and Type of relocation */ 124*3d8817e4Smiod bfd_vma r_addend; /* Constant addend used to compute value */ 125*3d8817e4Smiod } Elf_Internal_Rela; 126*3d8817e4Smiod 127*3d8817e4Smiod /* dynamic section structure */ 128*3d8817e4Smiod 129*3d8817e4Smiod typedef struct elf_internal_dyn { 130*3d8817e4Smiod /* This needs to support 64-bit values in elf64. */ 131*3d8817e4Smiod bfd_vma d_tag; /* entry tag value */ 132*3d8817e4Smiod union { 133*3d8817e4Smiod /* This needs to support 64-bit values in elf64. */ 134*3d8817e4Smiod bfd_vma d_val; 135*3d8817e4Smiod bfd_vma d_ptr; 136*3d8817e4Smiod } d_un; 137*3d8817e4Smiod } Elf_Internal_Dyn; 138*3d8817e4Smiod 139*3d8817e4Smiod /* This structure appears in a SHT_GNU_verdef section. */ 140*3d8817e4Smiod 141*3d8817e4Smiod typedef struct elf_internal_verdef { 142*3d8817e4Smiod unsigned short vd_version; /* Version number of structure. */ 143*3d8817e4Smiod unsigned short vd_flags; /* Flags (VER_FLG_*). */ 144*3d8817e4Smiod unsigned short vd_ndx; /* Version index. */ 145*3d8817e4Smiod unsigned short vd_cnt; /* Number of verdaux entries. */ 146*3d8817e4Smiod unsigned long vd_hash; /* Hash of name. */ 147*3d8817e4Smiod unsigned long vd_aux; /* Offset to verdaux entries. */ 148*3d8817e4Smiod unsigned long vd_next; /* Offset to next verdef. */ 149*3d8817e4Smiod 150*3d8817e4Smiod /* These fields are set up when BFD reads in the structure. FIXME: 151*3d8817e4Smiod It would be cleaner to store these in a different structure. */ 152*3d8817e4Smiod bfd *vd_bfd; /* BFD. */ 153*3d8817e4Smiod const char *vd_nodename; /* Version name. */ 154*3d8817e4Smiod struct elf_internal_verdef *vd_nextdef; /* vd_next as pointer. */ 155*3d8817e4Smiod struct elf_internal_verdaux *vd_auxptr; /* vd_aux as pointer. */ 156*3d8817e4Smiod unsigned int vd_exp_refno; /* Used by the linker. */ 157*3d8817e4Smiod } Elf_Internal_Verdef; 158*3d8817e4Smiod 159*3d8817e4Smiod /* This structure appears in a SHT_GNU_verdef section. */ 160*3d8817e4Smiod 161*3d8817e4Smiod typedef struct elf_internal_verdaux { 162*3d8817e4Smiod unsigned long vda_name; /* String table offset of name. */ 163*3d8817e4Smiod unsigned long vda_next; /* Offset to next verdaux. */ 164*3d8817e4Smiod 165*3d8817e4Smiod /* These fields are set up when BFD reads in the structure. FIXME: 166*3d8817e4Smiod It would be cleaner to store these in a different structure. */ 167*3d8817e4Smiod const char *vda_nodename; /* vda_name as pointer. */ 168*3d8817e4Smiod struct elf_internal_verdaux *vda_nextptr; /* vda_next as pointer. */ 169*3d8817e4Smiod } Elf_Internal_Verdaux; 170*3d8817e4Smiod 171*3d8817e4Smiod /* This structure appears in a SHT_GNU_verneed section. */ 172*3d8817e4Smiod 173*3d8817e4Smiod typedef struct elf_internal_verneed { 174*3d8817e4Smiod unsigned short vn_version; /* Version number of structure. */ 175*3d8817e4Smiod unsigned short vn_cnt; /* Number of vernaux entries. */ 176*3d8817e4Smiod unsigned long vn_file; /* String table offset of library name. */ 177*3d8817e4Smiod unsigned long vn_aux; /* Offset to vernaux entries. */ 178*3d8817e4Smiod unsigned long vn_next; /* Offset to next verneed. */ 179*3d8817e4Smiod 180*3d8817e4Smiod /* These fields are set up when BFD reads in the structure. FIXME: 181*3d8817e4Smiod It would be cleaner to store these in a different structure. */ 182*3d8817e4Smiod bfd *vn_bfd; /* BFD. */ 183*3d8817e4Smiod const char *vn_filename; /* vn_file as pointer. */ 184*3d8817e4Smiod struct elf_internal_vernaux *vn_auxptr; /* vn_aux as pointer. */ 185*3d8817e4Smiod struct elf_internal_verneed *vn_nextref; /* vn_nextref as pointer. */ 186*3d8817e4Smiod } Elf_Internal_Verneed; 187*3d8817e4Smiod 188*3d8817e4Smiod /* This structure appears in a SHT_GNU_verneed section. */ 189*3d8817e4Smiod 190*3d8817e4Smiod typedef struct elf_internal_vernaux { 191*3d8817e4Smiod unsigned long vna_hash; /* Hash of dependency name. */ 192*3d8817e4Smiod unsigned short vna_flags; /* Flags (VER_FLG_*). */ 193*3d8817e4Smiod unsigned short vna_other; /* Unused. */ 194*3d8817e4Smiod unsigned long vna_name; /* String table offset to version name. */ 195*3d8817e4Smiod unsigned long vna_next; /* Offset to next vernaux. */ 196*3d8817e4Smiod 197*3d8817e4Smiod /* These fields are set up when BFD reads in the structure. FIXME: 198*3d8817e4Smiod It would be cleaner to store these in a different structure. */ 199*3d8817e4Smiod const char *vna_nodename; /* vna_name as pointer. */ 200*3d8817e4Smiod struct elf_internal_vernaux *vna_nextptr; /* vna_next as pointer. */ 201*3d8817e4Smiod } Elf_Internal_Vernaux; 202*3d8817e4Smiod 203*3d8817e4Smiod /* This structure appears in a SHT_GNU_versym section. This is not a 204*3d8817e4Smiod standard ELF structure; ELF just uses Elf32_Half. */ 205*3d8817e4Smiod 206*3d8817e4Smiod typedef struct elf_internal_versym { 207*3d8817e4Smiod unsigned short vs_vers; 208*3d8817e4Smiod } Elf_Internal_Versym; 209*3d8817e4Smiod 210*3d8817e4Smiod /* Structure for syminfo section. */ 211*3d8817e4Smiod typedef struct 212*3d8817e4Smiod { 213*3d8817e4Smiod unsigned short int si_boundto; 214*3d8817e4Smiod unsigned short int si_flags; 215*3d8817e4Smiod } Elf_Internal_Syminfo; 216*3d8817e4Smiod 217*3d8817e4Smiod /* This structure appears on the stack and in NT_AUXV core file notes. */ 218*3d8817e4Smiod typedef struct 219*3d8817e4Smiod { 220*3d8817e4Smiod bfd_vma a_type; 221*3d8817e4Smiod bfd_vma a_val; 222*3d8817e4Smiod } Elf_Internal_Auxv; 223*3d8817e4Smiod 224*3d8817e4Smiod 225*3d8817e4Smiod /* This structure is used to describe how sections should be assigned 226*3d8817e4Smiod to program segments. */ 227*3d8817e4Smiod 228*3d8817e4Smiod struct elf_segment_map 229*3d8817e4Smiod { 230*3d8817e4Smiod /* Next program segment. */ 231*3d8817e4Smiod struct elf_segment_map *next; 232*3d8817e4Smiod /* Program segment type. */ 233*3d8817e4Smiod unsigned long p_type; 234*3d8817e4Smiod /* Program segment flags. */ 235*3d8817e4Smiod unsigned long p_flags; 236*3d8817e4Smiod /* Program segment physical address. */ 237*3d8817e4Smiod bfd_vma p_paddr; 238*3d8817e4Smiod /* Whether the p_flags field is valid; if not, the flags are based 239*3d8817e4Smiod on the section flags. */ 240*3d8817e4Smiod unsigned int p_flags_valid : 1; 241*3d8817e4Smiod /* Whether the p_paddr field is valid; if not, the physical address 242*3d8817e4Smiod is based on the section lma values. */ 243*3d8817e4Smiod unsigned int p_paddr_valid : 1; 244*3d8817e4Smiod /* Whether this segment includes the file header. */ 245*3d8817e4Smiod unsigned int includes_filehdr : 1; 246*3d8817e4Smiod /* Whether this segment includes the program headers. */ 247*3d8817e4Smiod unsigned int includes_phdrs : 1; 248*3d8817e4Smiod /* Number of sections (may be 0). */ 249*3d8817e4Smiod unsigned int count; 250*3d8817e4Smiod /* Sections. Actual number of elements is in count field. */ 251*3d8817e4Smiod asection *sections[1]; 252*3d8817e4Smiod }; 253*3d8817e4Smiod 254*3d8817e4Smiod /* Decide if the given sec_hdr is in the given segment in file. */ 255*3d8817e4Smiod #define ELF_IS_SECTION_IN_SEGMENT_FILE(sec_hdr, segment) \ 256*3d8817e4Smiod (sec_hdr->sh_size > 0 \ 257*3d8817e4Smiod /* PT_TLS segment contains only SHF_TLS sections. */ \ 258*3d8817e4Smiod && (segment->p_type != PT_TLS \ 259*3d8817e4Smiod || (sec_hdr->sh_flags & SHF_TLS) != 0) \ 260*3d8817e4Smiod /* Compare allocated sec_hdrs by VMA, unallocated sec_hdrs \ 261*3d8817e4Smiod by file offset. */ \ 262*3d8817e4Smiod && (sec_hdr->sh_flags & SHF_ALLOC \ 263*3d8817e4Smiod ? (sec_hdr->sh_addr >= segment->p_vaddr \ 264*3d8817e4Smiod && sec_hdr->sh_addr + sec_hdr->sh_size \ 265*3d8817e4Smiod <= segment->p_vaddr + segment->p_memsz) \ 266*3d8817e4Smiod : ((bfd_vma) sec_hdr->sh_offset >= segment->p_offset \ 267*3d8817e4Smiod && (sec_hdr->sh_offset + sec_hdr->sh_size \ 268*3d8817e4Smiod <= segment->p_offset + segment->p_filesz)))) 269*3d8817e4Smiod 270*3d8817e4Smiod /* Decide if the given sec_hdr is in the given segment in memory. */ 271*3d8817e4Smiod #define ELF_IS_SECTION_IN_SEGMENT_MEMORY(sec_hdr, segment) \ 272*3d8817e4Smiod (ELF_IS_SECTION_IN_SEGMENT_FILE (sec_hdr, segment) \ 273*3d8817e4Smiod /* .tbss is special. It doesn't contribute memory space to \ 274*3d8817e4Smiod normal segments. */ \ 275*3d8817e4Smiod && (!((sec_hdr->sh_flags & SHF_TLS) != 0 \ 276*3d8817e4Smiod && sec_hdr->sh_type == SHT_NOBITS) \ 277*3d8817e4Smiod || segment->p_type == PT_TLS)) 278*3d8817e4Smiod 279*3d8817e4Smiod #endif /* _ELF_INTERNAL_H */ 280