summaryrefslogtreecommitdiff
path: root/include/libelfu/types.h
blob: c1fbfda217da10e155d6cd2b451360f6a4b85016 (plain)
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
/*!
 * @file types.h
 * @brief libelfu's Elfu* types.
 *
 * libelfu provides an abstraction of the data in ELF files
 * to more closely model the dependencies between them, and
 * thus to facilitate consistent editing.
 */

#ifndef __LIBELFU_TYPES_H__
#define __LIBELFU_TYPES_H__

#include <sys/queue.h>

#include <elf.h>
#include <gelf.h>


/*!
 * ELFU model of a symbol table entry.
 */
typedef struct ElfuSym {
  /*! Offset into linked string table */
  GElf_Word name;


  /*! Explicit value */
  GElf_Addr value;

  /*! Size of object referenced */
  GElf_Word size;


  /*! Binding type (GLOBAL, LOCAL, ...) */
  unsigned char bind;

  /*! Type (FUNC, SECTION, ...) */
  unsigned char type;

  /*! Always 0, currently meaningless (see ELF spec) */
  unsigned char other;


  /*! If non-null, the section referenced. */
  struct ElfuScn *scnptr;

  /*! If scnptr is invalid, then this is ABS, COMMON, or UNDEF. */
  int shndx;


  /*! Entry in a symbol table */
  CIRCLEQ_ENTRY(ElfuSym) elem;
} ElfuSym;



/*!
 * ELFU model of a symbol table.
 */
typedef struct ElfuSymtab {
  /*! All parsed symbols */
  CIRCLEQ_HEAD(Syms, ElfuSym) syms;
} ElfuSymtab;





/*!
 * ELFU model of a relocation entry.
 */
typedef struct ElfuRel {
  /*! Location to patch */
  GElf_Addr offset;


  /*! Symbol to calculate value for */
  GElf_Word sym;

  /*! Relocation type (machine specific) */
  unsigned char type;


  /*! addendUsed == 0: Use addend from relocation destination (REL).
   *  addendUsed != 0: Use explicit addend (RELA). */
  int addendUsed;

  /*! Explicit addend in RELA tables */
  GElf_Sword addend;


  /*! Element in table */
  CIRCLEQ_ENTRY(ElfuRel) elem;
} ElfuRel;



/*!
 * ELFU model of a relocation table.
 */
typedef struct ElfuReltab {
  /*! All parsed relocation entries */
  CIRCLEQ_HEAD(Rels, ElfuRel) rels;
} ElfuReltab;







/*!
 * ELFU model of an ELF section.
 *
 * Several members of the SHDR are repeated in abstract form and take
 * precedence if present. For example, if linkptr is non-NULL then
 * it points to another section and the SHDR's numeric sh_link member
 * is to be ignored and recomputed by the layouter.
 */
typedef struct ElfuScn {
  /*! SHDR as per ELF specification.
   *  Several values are ignored or recomputed from other members of
   *  ElfuScn. */
  GElf_Shdr shdr;

  /*! malloc()ed buffer containing this section's flat data backbuffer.
   *  Present for all sections that occupy space in the file. */
  char *databuf;


  /*! Pointer to a section, meaning dependent on sh_type.
   *  Preferred over sh_link if non-null. */
  struct ElfuScn *linkptr;

  /*! Pointer to a section, meaning dependent on sh_type.
   *  Preferred over sh_info if non-null. */
  struct ElfuScn *infoptr;


  /*! If this section is a clone of another section, then this
   *  points to that other section.
   *  Used during code injection to facilitate relocation. */
  struct ElfuScn *oldptr;


  /*! Translated contents of a symbol table. */
  struct ElfuSymtab symtab;

  /*! Translated contents of a relocation table. */
  struct ElfuReltab reltab;


  /*! Element linking this section into an ElfuPhdr's childScnList,
   *  or into an ElfuElf's orphanScnList. */
  CIRCLEQ_ENTRY(ElfuScn) elemChildScn;
} ElfuScn;



/*!
 * ELFU model of an ELF PHDR.
 */
typedef struct ElfuPhdr {
  /*! PHDR as per ELF specification. */
  GElf_Phdr phdr;


  /*! Sections to be shifted in file/memory together with this PHDR */
  CIRCLEQ_HEAD(ChildScnList, ElfuScn) childScnList;

  /*! PHDRs to be shifted in file/memory together with this PHDR */
  CIRCLEQ_HEAD(ChildPhdrList, ElfuPhdr) childPhdrList;


  /*! Element linking this section into an ElfuPhdr's childPhdrList */
  CIRCLEQ_ENTRY(ElfuPhdr) elemChildPhdr;

  /*! Element linking this section into an ElfuElf's phdrList */
  CIRCLEQ_ENTRY(ElfuPhdr) elem;
} ElfuPhdr;



/*!
 * ELFU model of an ELF file header
 */
typedef struct {
  /*! The ELF class -- ELFCLASS32/ELFCLASS64 */
  int elfclass;

  /*! EHDR as per ELF specification */
  GElf_Ehdr ehdr;


  /*! PHDRs that are not dependent on others.
   *  Usually, LOAD and GNU_STACK. */
  CIRCLEQ_HEAD(PhdrList, ElfuPhdr) phdrList;

  /*! Sections not in any PHDR, and thus not loaded at runtime.
   *  Usually .symtab, .strtab, .shstrtab, .debug_*, ... */
  CIRCLEQ_HEAD(OrphanScnList, ElfuScn) orphanScnList;


  /*! Pointer to ElfuScn containing .shstrtab.
   *  Parsed from EHDR for convenience. */
  ElfuScn *shstrtab;

  /*! Pointer to ElfuScn containing .symtab.
   *  Parsed from list of sections for convenience. */
  ElfuScn *symtab;
} ElfuElf;

#endif