reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
  230
  231
  232
  233
  234
  235
  236
  237
  238
  239
  240
  241
  242
  243
  244
  245
  246
  247
  248
  249
  250
  251
  252
  253
  254
  255
  256
  257
  258
  259
  260
  261
  262
  263
  264
  265
  266
  267
  268
  269
  270
  271
  272
  273
  274
  275
  276
  277
  278
  279
  280
  281
  282
  283
  284
  285
  286
  287
  288
  289
  290
  291
  292
  293
  294
  295
  296
  297
  298
  299
  300
  301
  302
  303
  304
  305
  306
  307
  308
  309
  310
  311
  312
  313
  314
  315
  316
  317
  318
  319
  320
  321
  322
  323
  324
  325
  326
  327
  328
  329
  330
  331
  332
  333
  334
  335
  336
  337
  338
  339
  340
  341
  342
  343
  344
  345
  346
  347
  348
  349
  350
  351
  352
  353
  354
  355
  356
  357
  358
  359
  360
  361
  362
  363
  364
  365
  366
  367
  368
  369
  370
  371
  372
  373
  374
  375
  376
  377
  378
  379
  380
  381
  382
  383
  384
  385
  386
  387
  388
  389
  390
  391
  392
  393
  394
//===-- ELFHeader.h ------------------------------------------- -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Generic structures and typedefs for ELF files.
///
/// This file provides definitions for the various entities comprising an ELF
/// file.  The structures are generic in the sense that they do not correspond
/// to the exact binary layout of an ELF, but can be used to hold the
/// information present in both 32 and 64 bit variants of the format.  Each
/// entity provides a \c Parse method which is capable of transparently
/// reading both 32 and 64 bit instances of the object.
//===----------------------------------------------------------------------===//

#ifndef liblldb_ELFHeader_h_
#define liblldb_ELFHeader_h_

#include "llvm/BinaryFormat/ELF.h"

#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-types.h"

namespace lldb_private {
class DataExtractor;
} // End namespace lldb_private.

namespace elf {

/// \name ELF type definitions.
///
/// Types used to represent the various components of ELF structures.  All
/// types are signed or unsigned integral types wide enough to hold values
/// from both
/// 32 and 64 bit ELF variants.
//@{
typedef uint64_t elf_addr;
typedef uint64_t elf_off;
typedef uint16_t elf_half;
typedef uint32_t elf_word;
typedef int32_t elf_sword;
typedef uint64_t elf_size;
typedef uint64_t elf_xword;
typedef int64_t elf_sxword;
//@}

/// \class ELFHeader
/// Generic representation of an ELF file header.
///
/// This object is used to identify the general attributes on an ELF file and
/// to locate additional sections within the file.
struct ELFHeader {
  unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification.
  elf_addr e_entry;     ///< Virtual address program entry point.
  elf_off e_phoff;      ///< File offset of program header table.
  elf_off e_shoff;      ///< File offset of section header table.
  elf_word e_flags;     ///< Processor specific flags.
  elf_word e_version;   ///< Version of object file (always 1).
  elf_half e_type;      ///< Object file type.
  elf_half e_machine;   ///< Target architecture.
  elf_half e_ehsize;    ///< Byte size of the ELF header.
  elf_half e_phentsize; ///< Size of a program header table entry.
  elf_half e_phnum_hdr; ///< Number of program header entries.
  elf_half e_shentsize; ///< Size of a section header table entry.
  elf_half e_shnum_hdr; ///< Number of section header entries.
  elf_half e_shstrndx_hdr; ///< String table section index.

  // In some cases these numbers do not fit in 16 bits and they are
  // stored outside of the header in section #0. Here are the actual
  // values.
  elf_word e_phnum;     ///< Number of program header entries.
  elf_word e_shnum;     ///< Number of section header entries.
  elf_word e_shstrndx;  ///< String table section index.

  ELFHeader();

  /// Returns true if this is a 32 bit ELF file header.
  ///
  /// \return
  ///    True if this is a 32 bit ELF file header.
  bool Is32Bit() const {
    return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32;
  }

  /// Returns true if this is a 64 bit ELF file header.
  ///
  /// \return
  ///   True if this is a 64 bit ELF file header.
  bool Is64Bit() const {
    return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;
  }

  /// The byte order of this ELF file header.
  ///
  /// \return
  ///    The byte order of this ELF file as described by the header.
  lldb::ByteOrder GetByteOrder() const;

  /// The jump slot relocation type of this ELF.
  unsigned GetRelocationJumpSlotType() const;

  /// Check if there should be header extension in section header #0
  ///
  /// \return
  ///    True if parsing the ELFHeader requires reading header extension
  ///    and false otherwise.
  bool HasHeaderExtension() const;

  /// Parse an ELFHeader entry starting at position \p offset and update the
  /// data extractor with the address size and byte order attributes as
  /// defined by the header.
  ///
  /// \param[in,out] data
  ///    The DataExtractor to read from.  Updated with the address size and
  ///    byte order attributes appropriate to this header.
  ///
  /// \param[in,out] offset
  ///    Pointer to an offset in the data.  On return the offset will be
  ///    advanced by the number of bytes read.
  ///
  /// \return
  ///    True if the ELFHeader was successfully read and false
  ///    otherwise.
  bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset);

  /// Examines at most EI_NIDENT bytes starting from the given pointer and
  /// determines if the magic ELF identification exists.
  ///
  /// \return
  ///    True if the given sequence of bytes identifies an ELF file.
  static bool MagicBytesMatch(const uint8_t *magic);

  /// Examines at most EI_NIDENT bytes starting from the given address and
  /// determines the address size of the underlying ELF file.  This function
  /// should only be called on an pointer for which MagicBytesMatch returns
  /// true.
  ///
  /// \return
  ///    The number of bytes forming an address in the ELF file (either 4 or
  ///    8), else zero if the address size could not be determined.
  static unsigned AddressSizeInBytes(const uint8_t *magic);

private:

  /// Parse an ELFHeader header extension entry.  This method is called by
  /// Parse().
  ///
  /// \param[in] data
  ///    The DataExtractor to read from.
  void ParseHeaderExtension(lldb_private::DataExtractor &data);
};

/// \class ELFSectionHeader
/// Generic representation of an ELF section header.
struct ELFSectionHeader {
  elf_word sh_name;       ///< Section name string index.
  elf_word sh_type;       ///< Section type.
  elf_xword sh_flags;     ///< Section attributes.
  elf_addr sh_addr;       ///< Virtual address of the section in memory.
  elf_off sh_offset;      ///< Start of section from beginning of file.
  elf_xword sh_size;      ///< Number of bytes occupied in the file.
  elf_word sh_link;       ///< Index of associated section.
  elf_word sh_info;       ///< Extra section info (overloaded).
  elf_xword sh_addralign; ///< Power of two alignment constraint.
  elf_xword sh_entsize;   ///< Byte size of each section entry.

  ELFSectionHeader();

  /// Parse an ELFSectionHeader entry from the given DataExtracter starting at
  /// position \p offset.
  ///
  /// \param[in] data
  ///    The DataExtractor to read from.  The address size of the extractor
  ///    determines if a 32 or 64 bit object should be read.
  ///
  /// \param[in,out] offset
  ///    Pointer to an offset in the data.  On return the offset will be
  ///    advanced by the number of bytes read.
  ///
  /// \return
  ///    True if the ELFSectionHeader was successfully read and false
  ///    otherwise.
  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
};

/// \class ELFProgramHeader
/// Generic representation of an ELF program header.
struct ELFProgramHeader {
  elf_word p_type;    ///< Type of program segment.
  elf_word p_flags;   ///< Segment attributes.
  elf_off p_offset;   ///< Start of segment from beginning of file.
  elf_addr p_vaddr;   ///< Virtual address of segment in memory.
  elf_addr p_paddr;   ///< Physical address (for non-VM systems).
  elf_xword p_filesz; ///< Byte size of the segment in file.
  elf_xword p_memsz;  ///< Byte size of the segment in memory.
  elf_xword p_align;  ///< Segment alignment constraint.

  ELFProgramHeader();

  /// Parse an ELFProgramHeader entry from the given DataExtractor starting at
  /// position \p offset.  The address size of the DataExtractor determines if
  /// a 32 or 64 bit object is to be parsed.
  ///
  /// \param[in] data
  ///    The DataExtractor to read from.  The address size of the extractor
  ///    determines if a 32 or 64 bit object should be read.
  ///
  /// \param[in,out] offset
  ///    Pointer to an offset in the data.  On return the offset will be
  ///    advanced by the number of bytes read.
  ///
  /// \return
  ///    True if the ELFProgramHeader was successfully read and false
  ///    otherwise.
  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
};

/// \class ELFSymbol
/// Represents a symbol within an ELF symbol table.
struct ELFSymbol {
  elf_addr st_value;      ///< Absolute or relocatable address.
  elf_xword st_size;      ///< Size of the symbol or zero.
  elf_word st_name;       ///< Symbol name string index.
  unsigned char st_info;  ///< Symbol type and binding attributes.
  unsigned char st_other; ///< Reserved for future use.
  elf_half st_shndx;      ///< Section to which this symbol applies.

  ELFSymbol();

  /// Returns the binding attribute of the st_info member.
  unsigned char getBinding() const { return st_info >> 4; }

  /// Returns the type attribute of the st_info member.
  unsigned char getType() const { return st_info & 0x0F; }

  /// Sets the binding and type of the st_info member.
  void setBindingAndType(unsigned char binding, unsigned char type) {
    st_info = (binding << 4) + (type & 0x0F);
  }

  static const char *bindingToCString(unsigned char binding);

  static const char *typeToCString(unsigned char type);

  static const char *
  sectionIndexToCString(elf_half shndx,
                        const lldb_private::SectionList *section_list);

  /// Parse an ELFSymbol entry from the given DataExtractor starting at
  /// position \p offset.  The address size of the DataExtractor determines if
  /// a 32 or 64 bit object is to be parsed.
  ///
  /// \param[in] data
  ///    The DataExtractor to read from.  The address size of the extractor
  ///    determines if a 32 or 64 bit object should be read.
  ///
  /// \param[in,out] offset
  ///    Pointer to an offset in the data.  On return the offset will be
  ///    advanced by the number of bytes read.
  ///
  /// \return
  ///    True if the ELFSymbol was successfully read and false otherwise.
  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);

  void Dump(lldb_private::Stream *s, uint32_t idx,
            const lldb_private::DataExtractor *strtab_data,
            const lldb_private::SectionList *section_list);
};

/// \class ELFDynamic
/// Represents an entry in an ELF dynamic table.
struct ELFDynamic {
  elf_sxword d_tag; ///< Type of dynamic table entry.
  union {
    elf_xword d_val; ///< Integer value of the table entry.
    elf_addr d_ptr;  ///< Pointer value of the table entry.
  };

  ELFDynamic();

  /// Parse an ELFDynamic entry from the given DataExtractor starting at
  /// position \p offset.  The address size of the DataExtractor determines if
  /// a 32 or 64 bit object is to be parsed.
  ///
  /// \param[in] data
  ///    The DataExtractor to read from.  The address size of the extractor
  ///    determines if a 32 or 64 bit object should be read.
  ///
  /// \param[in,out] offset
  ///    Pointer to an offset in the data.  On return the offset will be
  ///    advanced by the number of bytes read.
  ///
  /// \return
  ///    True if the ELFDynamic entry was successfully read and false
  ///    otherwise.
  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
};

/// \class ELFRel
/// Represents a relocation entry with an implicit addend.
struct ELFRel {
  elf_addr r_offset; ///< Address of reference.
  elf_xword r_info;  ///< symbol index and type of relocation.

  ELFRel();

  /// Parse an ELFRel entry from the given DataExtractor starting at position
  /// \p offset.  The address size of the DataExtractor determines if a 32 or
  /// 64 bit object is to be parsed.
  ///
  /// \param[in] data
  ///    The DataExtractor to read from.  The address size of the extractor
  ///    determines if a 32 or 64 bit object should be read.
  ///
  /// \param[in,out] offset
  ///    Pointer to an offset in the data.  On return the offset will be
  ///    advanced by the number of bytes read.
  ///
  /// \return
  ///    True if the ELFRel entry was successfully read and false otherwise.
  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);

  /// Returns the type when the given entry represents a 32-bit relocation.
  static unsigned RelocType32(const ELFRel &rel) { return rel.r_info & 0x0ff; }

  /// Returns the type when the given entry represents a 64-bit relocation.
  static unsigned RelocType64(const ELFRel &rel) {
    return rel.r_info & 0xffffffff;
  }

  /// Returns the symbol index when the given entry represents a 32-bit
  /// relocation.
  static unsigned RelocSymbol32(const ELFRel &rel) { return rel.r_info >> 8; }

  /// Returns the symbol index when the given entry represents a 64-bit
  /// relocation.
  static unsigned RelocSymbol64(const ELFRel &rel) { return rel.r_info >> 32; }
};

/// \class ELFRela
/// Represents a relocation entry with an explicit addend.
struct ELFRela {
  elf_addr r_offset;   ///< Address of reference.
  elf_xword r_info;    ///< Symbol index and type of relocation.
  elf_sxword r_addend; ///< Constant part of expression.

  ELFRela();

  /// Parse an ELFRela entry from the given DataExtractor starting at position
  /// \p offset.  The address size of the DataExtractor determines if a 32 or
  /// 64 bit object is to be parsed.
  ///
  /// \param[in] data
  ///    The DataExtractor to read from.  The address size of the extractor
  ///    determines if a 32 or 64 bit object should be read.
  ///
  /// \param[in,out] offset
  ///    Pointer to an offset in the data.  On return the offset will be
  ///    advanced by the number of bytes read.
  ///
  /// \return
  ///    True if the ELFRela entry was successfully read and false otherwise.
  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);

  /// Returns the type when the given entry represents a 32-bit relocation.
  static unsigned RelocType32(const ELFRela &rela) {
    return rela.r_info & 0x0ff;
  }

  /// Returns the type when the given entry represents a 64-bit relocation.
  static unsigned RelocType64(const ELFRela &rela) {
    return rela.r_info & 0xffffffff;
  }

  /// Returns the symbol index when the given entry represents a 32-bit
  /// relocation.
  static unsigned RelocSymbol32(const ELFRela &rela) {
    return rela.r_info >> 8;
  }

  /// Returns the symbol index when the given entry represents a 64-bit
  /// relocation.
  static unsigned RelocSymbol64(const ELFRela &rela) {
    return rela.r_info >> 32;
  }
};

} // End namespace elf.

#endif // #ifndef liblldb_ELFHeader_h_