1/* Copyright (C) 2021 Free Software Foundation, Inc.
2   Contributed by Oracle.
3
4   This file is part of GNU Binutils.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, 51 Franklin Street - Fifth Floor, Boston,
19   MA 02110-1301, USA.  */
20
21#ifndef _Elf_h_
22#define	_Elf_h_
23
24#include <string.h>
25#include "ansidecl.h"
26#include "bfd.h"
27#include "elf/common.h"
28#include "elf/internal.h"
29
30#include "Data_window.h"
31#include "Emsg.h"
32
33class Symbol;
34class DbeFile;
35template <class ITEM> class Vector;
36template <typename Key_t, typename Value_t> class Map;
37
38#define GELF_R_SYM(info)    ((info)>>32)
39#define GELF_ST_TYPE(info)  ((info) & 0xf)
40#define GELF_ST_BIND(info)  ((info) >> 4)
41#define GELF_R_TYPE(info)   ((((uint64_t)(info))<<56)>>56)
42
43#define	SHF_SUNW_ABSENT		0x00200000	/* section data not present */
44
45// Ancillary values.
46#define ANC_SUNW_NULL       0
47#define ANC_SUNW_CHECKSUM   1   /* elf checksum */
48#define ANC_SUNW_MEMBER     2   /* name of ancillary group object */
49#define ANC_SUNW_NUM        3
50
51
52typedef struct S_Elf64_Dyn Elf64_Dyn;
53typedef struct S_Elf64_Ancillary Elf64_Ancillary;
54
55typedef struct
56{
57  void *d_buf;
58  uint64_t d_flags;
59  uint64_t d_size;
60  uint64_t d_off;       // offset into section
61  uint64_t d_align;     // alignment in section
62} Elf_Data;
63
64class Elf : public DbeMessages, public Data_window
65{
66public:
67  enum Elf_status
68  {
69    ELF_ERR_NONE,
70    ELF_ERR_CANT_OPEN_FILE,
71    ELF_ERR_CANT_MMAP,
72    ELF_ERR_BIG_FILE,
73    ELF_ERR_BAD_ELF_FORMAT,
74    ELF_ERR_READ_FILE
75  };
76
77  Elf (char *_fname);
78  ~Elf ();
79
80  static void elf_init ();
81  static unsigned elf_version (unsigned ver);
82  static Elf *elf_begin (char *_fname, Elf_status *stp = NULL);
83
84  unsigned int elf_get_sec_num (const char *sec_name);
85  char *get_sec_name (unsigned int sec);
86  Elf_Internal_Ehdr *elf_getehdr ();
87  Elf_Internal_Phdr *get_phdr (unsigned int ndx);
88  Elf_Internal_Shdr *get_shdr (unsigned int ndx);
89  Elf64_Dyn *elf_getdyn (Elf_Internal_Phdr *phdr, unsigned int ndx, Elf64_Dyn *pdyn);
90  Elf_Data *elf_getdata (unsigned int sec);
91  int64_t elf_checksum ();
92  uint64_t get_baseAddr();
93  char *elf_strptr (unsigned int sec, uint64_t off);
94  Elf_Internal_Sym *elf_getsym (Elf_Data *edta, unsigned int ndx, Elf_Internal_Sym *dst);
95  Elf_Internal_Rela *elf_getrel (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst);
96  Elf_Internal_Rela *elf_getrela (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst);
97  Elf64_Ancillary *elf_getancillary (Elf_Data *edta, unsigned int ndx, Elf64_Ancillary *dst);
98  Elf *find_ancillary_files (char *lo_name); // read the .gnu_debuglink and .SUNW_ancillary seections
99  char *get_location ();
100  char *dump ();
101  void dump_elf_sec ();
102
103  static inline int64_t
104  normalize_checksum (int64_t chk)
105  {
106    return (chk == 0xffffffff || chk == -1) ? 0 : chk;
107  };
108
109  inline bool
110  is_Intel ()
111  {
112    return elf_datatype == ELFDATA2LSB;
113  };
114
115  inline int
116  elf_getclass ()
117  {
118    return elf_class;
119  };
120
121  inline int
122  elf_getdatatype ()
123  {
124    return elf_datatype;
125  };
126
127  Elf_status status;
128  Vector<Elf*> *ancillary_files;
129  Elf *gnu_debug_file;
130  DbeFile *dbeFile;
131  Map<const char*, Symbol*> *elfSymbols;
132  unsigned int gnuLink, analyzerInfo, SUNW_ldynsym, stab, stabStr, symtab, dynsym;
133  unsigned int stabIndex, stabIndexStr, stabExcl, stabExclStr, info, plt;
134  bool dwarf;
135
136protected:
137  Elf *get_related_file (const char *lo_name, const char *nm);
138  int elf_class;
139  int elf_datatype;
140  Elf_Internal_Ehdr *ehdrp;
141  Elf_Data **data;
142  bfd *abfd;
143  static int bfd_status;
144};
145
146
147class ElfReloc
148{
149public:
150  struct Sreloc
151  {
152    long long offset;
153    long long value;
154    int stt_type;
155  };
156
157  static ElfReloc *get_elf_reloc (Elf *elf, char *sec_name, ElfReloc *rlc);
158  ElfReloc (Elf *_elf);
159  ~ElfReloc ();
160  long long get_reloc_addr (long long offset);
161  void dump ();
162  void dump_rela_debug_sec (int sec);
163
164private:
165  Elf *elf;
166  Vector<Sreloc *> *reloc;
167  int cur_reloc_ind;
168};
169
170#endif
171