1 : /* ***** BEGIN LICENSE BLOCK *****
2 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 : *
4 : * The contents of this file are subject to the Mozilla Public License Version
5 : * 1.1 (the "License"); you may not use this file except in compliance with
6 : * the License. You may obtain a copy of the License at
7 : * http://www.mozilla.org/MPL/
8 : *
9 : * Software distributed under the License is distributed on an "AS IS" basis,
10 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 : * for the specific language governing rights and limitations under the
12 : * License.
13 : *
14 : * The Original Code is elfhack.
15 : *
16 : * The Initial Developer of the Original Code is
17 : * Mozilla Foundation.
18 : * Portions created by the Initial Developer are Copyright (C) 2010
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : * Mike Hommey <mh@glandium.org>
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either the GNU General Public License Version 2 or later (the "GPL"), or
26 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #include <stdexcept>
39 : #include <list>
40 : #include <vector>
41 : #include <cstring>
42 : #include <iostream>
43 : #include <fstream>
44 : #include <algorithm>
45 : #include <elf.h>
46 : #include <asm/byteorder.h>
47 :
48 : // Technically, __*_to_cpu and __cpu_to* function are equivalent,
49 : // so swap can use either of both.
50 : #define def_swap(endian, type, bits) \
51 : static inline type ## bits ## _t swap(type ## bits ## _t i) { \
52 : return __ ## endian ## bits ## _to_cpu(i); \
53 : }
54 :
55 : class little_endian {
56 : public:
57 788311 : def_swap(le, uint, 16);
58 3135342 : def_swap(le, uint, 32);
59 0 : def_swap(le, uint, 64);
60 : def_swap(le, int, 16);
61 895 : def_swap(le, int, 32);
62 0 : def_swap(le, int, 64);
63 : };
64 :
65 : class big_endian {
66 : public:
67 0 : def_swap(be, uint, 16);
68 0 : def_swap(be, uint, 32);
69 0 : def_swap(be, uint, 64);
70 : def_swap(be, int, 16);
71 0 : def_swap(be, int, 32);
72 0 : def_swap(be, int, 64);
73 : };
74 :
75 : // forward declaration
76 : class ElfSection;
77 : class ElfSegment;
78 : // TODO: Rename Elf_* types
79 : class Elf_Ehdr;
80 : class Elf_Phdr;
81 : class Elf;
82 : class ElfDynamic_Section;
83 : class ElfStrtab_Section;
84 :
85 : class Elf_Ehdr_Traits {
86 : public:
87 : typedef Elf32_Ehdr Type32;
88 : typedef Elf64_Ehdr Type64;
89 :
90 : template <class endian, typename R, typename T>
91 : static void swap(T &t, R &r);
92 : };
93 :
94 : class Elf_Phdr_Traits {
95 : public:
96 : typedef Elf32_Phdr Type32;
97 : typedef Elf64_Phdr Type64;
98 :
99 : template <class endian, typename R, typename T>
100 : static void swap(T &t, R &r);
101 : };
102 :
103 : class Elf_Shdr_Traits {
104 : public:
105 : typedef Elf32_Shdr Type32;
106 : typedef Elf64_Shdr Type64;
107 :
108 : template <class endian, typename R, typename T>
109 : static void swap(T &t, R &r);
110 : };
111 :
112 : class Elf_Dyn_Traits {
113 : public:
114 : typedef Elf32_Dyn Type32;
115 : typedef Elf64_Dyn Type64;
116 :
117 : template <class endian, typename R, typename T>
118 : static void swap(T &t, R &r);
119 : };
120 :
121 : class Elf_Sym_Traits {
122 : public:
123 : typedef Elf32_Sym Type32;
124 : typedef Elf64_Sym Type64;
125 :
126 : template <class endian, typename R, typename T>
127 : static void swap(T &t, R &r);
128 : };
129 :
130 : class Elf_Rel_Traits {
131 : public:
132 : typedef Elf32_Rel Type32;
133 : typedef Elf64_Rel Type64;
134 :
135 : template <class endian, typename R, typename T>
136 : static void swap(T &t, R &r);
137 : };
138 :
139 : class Elf_Rela_Traits {
140 : public:
141 : typedef Elf32_Rela Type32;
142 : typedef Elf64_Rela Type64;
143 :
144 : template <class endian, typename R, typename T>
145 : static void swap(T &t, R &r);
146 : };
147 :
148 812816 : class ElfValue {
149 : public:
150 20 : virtual unsigned int getValue() { return 0; }
151 0 : virtual ElfSection *getSection() { return NULL; }
152 : };
153 :
154 : class ElfPlainValue: public ElfValue {
155 : unsigned int value;
156 : public:
157 338 : ElfPlainValue(unsigned int val): value(val) {};
158 65 : unsigned int getValue() { return value; }
159 : };
160 :
161 405949 : class ElfLocation: public ElfValue {
162 : ElfSection *section;
163 : unsigned int offset;
164 : public:
165 : enum position { ABSOLUTE, RELATIVE };
166 105 : ElfLocation(): section(NULL), offset(0) {};
167 : ElfLocation(ElfSection *section, unsigned int off, enum position pos = RELATIVE);
168 : ElfLocation(unsigned int location, Elf *elf);
169 : unsigned int getValue();
170 382190 : ElfSection *getSection() { return section; }
171 : };
172 :
173 : class ElfSize: public ElfValue {
174 : ElfSection *section;
175 : public:
176 63 : ElfSize(ElfSection *s): section(s) {};
177 : unsigned int getValue();
178 0 : ElfSection *getSection() { return section; }
179 : };
180 :
181 : class ElfEntSize: public ElfValue {
182 : ElfSection *section;
183 : public:
184 42 : ElfEntSize(ElfSection *s): section(s) {};
185 : unsigned int getValue();
186 0 : ElfSection *getSection() { return section; }
187 : };
188 :
189 : template <typename T>
190 0 : class serializable: public T::Type32 {
191 : public:
192 382231 : serializable() {};
193 44 : serializable(const typename T::Type32 &p): T::Type32(p) {};
194 :
195 : private:
196 : template <typename R>
197 0 : void init(const char *buf, size_t len, char ei_data)
198 : {
199 : R e;
200 0 : assert(len <= sizeof(e));
201 0 : memcpy(&e, buf, sizeof(e));
202 0 : if (ei_data == ELFDATA2LSB) {
203 0 : T::template swap<little_endian>(e, *this);
204 0 : return;
205 0 : } else if (ei_data == ELFDATA2MSB) {
206 0 : T::template swap<big_endian>(e, *this);
207 0 : return;
208 : }
209 0 : throw std::runtime_error("Unsupported ELF data encoding");
210 : }
211 :
212 : public:
213 0 : serializable(const char *buf, size_t len, char ei_class, char ei_data)
214 0 : {
215 0 : if (ei_class == ELFCLASS32) {
216 0 : init<typename T::Type32>(buf, len, ei_data);
217 0 : return;
218 0 : } else if (ei_class == ELFCLASS64) {
219 0 : init<typename T::Type64>(buf, len, ei_data);
220 0 : return;
221 : }
222 0 : throw std::runtime_error("Unsupported ELF class");
223 : }
224 :
225 735082 : serializable(std::ifstream &file, char ei_class, char ei_data)
226 735082 : {
227 735082 : if (ei_class == ELFCLASS32) {
228 : typename T::Type32 e;
229 735082 : file.read((char *)&e, sizeof(e));
230 735082 : if (ei_data == ELFDATA2LSB) {
231 735082 : T::template swap<little_endian>(e, *this);
232 735082 : return;
233 0 : } else if (ei_data == ELFDATA2MSB) {
234 0 : T::template swap<big_endian>(e, *this);
235 0 : return;
236 : }
237 0 : } else if (ei_class == ELFCLASS64) {
238 : typename T::Type64 e;
239 0 : file.read((char *)&e, sizeof(e));
240 0 : if (ei_data == ELFDATA2LSB) {
241 0 : T::template swap<little_endian>(e, *this);
242 0 : return;
243 0 : } else if (ei_data == ELFDATA2MSB) {
244 0 : T::template swap<big_endian>(e, *this);
245 0 : return;
246 : }
247 : }
248 0 : throw std::runtime_error("Unsupported ELF class or data encoding");
249 : }
250 :
251 433935 : void serialize(std::ofstream &file, char ei_class, char ei_data)
252 : {
253 433935 : if (ei_class == ELFCLASS32) {
254 : typename T::Type32 e;
255 433935 : if (ei_data == ELFDATA2LSB) {
256 433935 : T::template swap<little_endian>(*this, e);
257 433935 : file.write((char *)&e, sizeof(e));
258 433935 : return;
259 0 : } else if (ei_data == ELFDATA2MSB) {
260 0 : T::template swap<big_endian>(*this, e);
261 0 : file.write((char *)&e, sizeof(e));
262 0 : return;
263 : }
264 0 : } else if (ei_class == ELFCLASS64) {
265 : typename T::Type64 e;
266 0 : if (ei_data == ELFDATA2LSB) {
267 0 : T::template swap<little_endian>(*this, e);
268 0 : file.write((char *)&e, sizeof(e));
269 0 : return;
270 0 : } else if (ei_data == ELFDATA2MSB) {
271 0 : T::template swap<big_endian>(*this, e);
272 0 : file.write((char *)&e, sizeof(e));
273 0 : return;
274 : }
275 : }
276 0 : throw std::runtime_error("Unsupported ELF class or data encoding");
277 : }
278 :
279 281 : static inline unsigned int size(char ei_class)
280 : {
281 281 : if (ei_class == ELFCLASS32)
282 281 : return sizeof(typename T::Type32);
283 0 : else if (ei_class == ELFCLASS64)
284 0 : return sizeof(typename T::Type64);
285 0 : return 0;
286 : }
287 : };
288 :
289 : typedef serializable<Elf_Shdr_Traits> Elf_Shdr;
290 :
291 : class Elf {
292 : public:
293 : Elf(std::ifstream &file);
294 : ~Elf();
295 :
296 : /* index == -1 is treated as index == ehdr.e_shstrndx */
297 : ElfSection *getSection(int index);
298 :
299 : ElfSection *getSectionAt(unsigned int offset);
300 :
301 : ElfSegment *getSegmentByType(unsigned int type);
302 :
303 : ElfDynamic_Section *getDynSection();
304 :
305 : void write(std::ofstream &file);
306 :
307 : char getClass();
308 : char getData();
309 : char getType();
310 : char getMachine();
311 : unsigned int getSize();
312 : private:
313 : Elf_Ehdr *ehdr;
314 : ElfLocation eh_entry;
315 : ElfStrtab_Section *eh_shstrndx;
316 : ElfSection **sections;
317 : std::vector<ElfSegment *> segments;
318 : ElfSection *shdr_section, *phdr_section;
319 : /* Values used only during initialization */
320 : Elf_Shdr **tmp_shdr;
321 : std::ifstream *tmp_file;
322 : };
323 :
324 : class ElfSection {
325 : public:
326 : typedef union {
327 : ElfSection *section;
328 : int index;
329 : } SectionInfo;
330 :
331 : ElfSection(Elf_Shdr &s, std::ifstream *file, Elf *parent);
332 :
333 3126 : virtual ~ElfSection() {
334 1154 : delete[] data;
335 1972 : }
336 :
337 1678 : const char *getName() { return name; }
338 28268 : unsigned int getType() { return shdr.sh_type; }
339 12958836 : unsigned int getFlags() { return shdr.sh_flags; }
340 : unsigned int getAddr();
341 6041958 : unsigned int getSize() { return shdr.sh_size; }
342 1140 : unsigned int getAddrAlign() { return shdr.sh_addralign; }
343 33 : unsigned int getEntSize() { return shdr.sh_entsize; }
344 31417 : const char *getData() { return data; }
345 184 : ElfSection *getLink() { return link; }
346 36 : SectionInfo getInfo() { return info; }
347 :
348 21 : void shrink(unsigned int newsize) {
349 21 : if (newsize < shdr.sh_size) {
350 21 : shdr.sh_size = newsize;
351 21 : if (next)
352 21 : next->markDirty();
353 : }
354 21 : }
355 :
356 : unsigned int getOffset();
357 : int getIndex();
358 : Elf_Shdr &getShdr();
359 :
360 2929 : ElfSection *getNext() { return next; }
361 1069 : ElfSection *getPrevious() { return previous; }
362 :
363 2326 : virtual bool isRelocatable() {
364 2326 : return ((getType() == SHT_SYMTAB) ||
365 2247 : (getType() == SHT_STRTAB) ||
366 2073 : (getType() == SHT_RELA) ||
367 2073 : (getType() == SHT_HASH) ||
368 2057 : (getType() == SHT_NOTE) ||
369 2057 : (getType() == SHT_REL) ||
370 1944 : (getType() == SHT_DYNSYM) ||
371 1928 : (getType() == SHT_GNU_HASH) ||
372 1928 : (getType() == SHT_GNU_verdef) ||
373 1928 : (getType() == SHT_GNU_verneed) ||
374 1912 : (getType() == SHT_GNU_versym) ||
375 1896 : isInSegmentType(PT_INTERP)) &&
376 24369 : (getFlags() & SHF_ALLOC);
377 : }
378 :
379 1112 : void insertAfter(ElfSection *section, bool dirty = true) {
380 1112 : if (previous != NULL)
381 0 : previous->next = next;
382 1112 : if (next != NULL)
383 0 : next->previous = previous;
384 1112 : previous = section;
385 1112 : if (section != NULL) {
386 1112 : next = section->next;
387 1112 : section->next = this;
388 : } else
389 0 : next = NULL;
390 1112 : if (next != NULL)
391 42 : next->previous = this;
392 1112 : if (dirty)
393 42 : markDirty();
394 1112 : }
395 :
396 2352 : void markDirty() {
397 2352 : if (link != NULL)
398 261 : shdr.sh_link = -1;
399 2352 : if (info.index)
400 166 : shdr.sh_info = -1;
401 2352 : shdr.sh_offset = -1;
402 2352 : if (isRelocatable())
403 219 : shdr.sh_addr = -1;
404 2352 : if (next)
405 2273 : next->markDirty();
406 2352 : }
407 :
408 111 : virtual void serialize(std::ofstream &file, char ei_class, char ei_data)
409 : {
410 111 : if (getType() == SHT_NOBITS)
411 6 : return;
412 105 : file.seekp(getOffset());
413 105 : file.write(data, getSize());
414 : }
415 :
416 : private:
417 : friend class ElfSegment;
418 :
419 569 : void addToSegment(ElfSegment *segment) {
420 569 : segments.push_back(segment);
421 569 : }
422 :
423 28 : void removeFromSegment(ElfSegment *segment) {
424 28 : std::vector<ElfSegment *>::iterator i = std::find(segments.begin(), segments.end(), segment);
425 28 : segments.erase(i, i + 1);
426 28 : }
427 :
428 : bool isInSegmentType(unsigned int type);
429 : protected:
430 : Elf_Shdr shdr;
431 : char *data;
432 : const char *name;
433 : private:
434 : ElfSection *link;
435 : SectionInfo info;
436 : ElfSection *next, *previous;
437 : int index;
438 : std::vector<ElfSegment *> segments;
439 : };
440 :
441 94 : class ElfSegment {
442 : public:
443 : ElfSegment(Elf_Phdr *phdr);
444 :
445 1452 : unsigned int getType() { return type; }
446 25 : unsigned int getFlags() { return flags; }
447 547 : unsigned int getAlign() { return align; }
448 :
449 126 : ElfSection *getFirstSection() { return sections.empty() ? NULL : sections.front(); }
450 25 : int getVPDiff() { return v_p_diff; }
451 : unsigned int getFileSize();
452 : unsigned int getMemSize();
453 : unsigned int getOffset();
454 : unsigned int getAddr();
455 :
456 : void addSection(ElfSection *section);
457 :
458 12 : std::list<ElfSection *>::iterator begin() { return sections.begin(); }
459 100 : std::list<ElfSection *>::iterator end() { return sections.end(); }
460 :
461 : ElfSegment *splitBefore(ElfSection *section);
462 : private:
463 : unsigned int type;
464 : int v_p_diff; // Difference between physical and virtual address
465 : unsigned int flags;
466 : unsigned int align;
467 : std::list<ElfSection *> sections;
468 : // The following are only really used for PT_GNU_RELRO until something
469 : // better is found.
470 : unsigned int vaddr;
471 : unsigned int filesz, memsz;
472 : };
473 :
474 84 : class Elf_Ehdr: public serializable<Elf_Ehdr_Traits>, public ElfSection {
475 : public:
476 : Elf_Ehdr(std::ifstream &file, char ei_class, char ei_data);
477 4 : void serialize(std::ofstream &file, char ei_class, char ei_data)
478 : {
479 4 : serializable<Elf_Ehdr_Traits>::serialize(file, ei_class, ei_data);
480 4 : }
481 : };
482 :
483 : class Elf_Phdr: public serializable<Elf_Phdr_Traits> {
484 : public:
485 29 : Elf_Phdr() {};
486 90 : Elf_Phdr(std::ifstream &file, char ei_class, char ei_data)
487 90 : : serializable<Elf_Phdr_Traits>(file, ei_class, ei_data) {};
488 3236 : bool contains(ElfSection *section)
489 : {
490 3236 : unsigned int size = section->getSize();
491 3236 : unsigned int addr = section->getAddr();
492 : // This may be biased, but should work in most cases
493 3236 : if ((section->getFlags() & SHF_ALLOC) == 0)
494 1202 : return false;
495 : // Special case for PT_DYNAMIC. Eventually, this should
496 : // be better handled than special cases
497 2034 : if ((p_type == PT_DYNAMIC) && (section->getType() != SHT_DYNAMIC))
498 452 : return false;
499 : // Special case for PT_TLS.
500 1582 : if ((p_type == PT_TLS) && !(section->getFlags() & SHF_TLS))
501 45 : return false;
502 : return (addr >= p_vaddr) &&
503 1537 : (addr + size <= p_vaddr + p_memsz);
504 :
505 : }
506 : };
507 :
508 : typedef serializable<Elf_Dyn_Traits> Elf_Dyn;
509 :
510 0 : struct Elf_DynValue {
511 : unsigned int tag;
512 : ElfValue *value;
513 : };
514 :
515 : class ElfDynamic_Section: public ElfSection {
516 : public:
517 : ElfDynamic_Section(Elf_Shdr &s, std::ifstream *file, Elf *parent);
518 : ~ElfDynamic_Section();
519 :
520 : void serialize(std::ofstream &file, char ei_class, char ei_data);
521 :
522 : ElfValue *getValueForType(unsigned int tag);
523 : ElfSection *getSectionForType(unsigned int tag);
524 : void setValueForType(unsigned int tag, ElfValue *val);
525 : private:
526 : std::vector<Elf_DynValue> dyns;
527 : };
528 :
529 : typedef serializable<Elf_Sym_Traits> Elf_Sym;
530 :
531 406012 : struct Elf_SymValue {
532 : const char *name;
533 : unsigned char info;
534 : unsigned char other;
535 : ElfLocation value;
536 : unsigned int size;
537 : bool defined;
538 : };
539 :
540 : #define STT(type) (1 << STT_ ##type)
541 :
542 126 : class ElfSymtab_Section: public ElfSection {
543 : public:
544 : ElfSymtab_Section(Elf_Shdr &s, std::ifstream *file, Elf *parent);
545 :
546 : void serialize(std::ofstream &file, char ei_class, char ei_data);
547 :
548 : Elf_SymValue *lookup(const char *name, unsigned int type_filter = STT(OBJECT) | STT(FUNC));
549 :
550 : //private: // Until we have a real API
551 : std::vector<Elf_SymValue> syms;
552 : };
553 :
554 0 : class Elf_Rel: public serializable<Elf_Rel_Traits> {
555 : public:
556 327223 : Elf_Rel(std::ifstream &file, char ei_class, char ei_data)
557 327223 : : serializable<Elf_Rel_Traits>(file, ei_class, ei_data) {};
558 :
559 : static const unsigned int sh_type = SHT_REL;
560 : static const unsigned int d_tag = DT_REL;
561 : static const unsigned int d_tag_count = DT_RELCOUNT;
562 : };
563 :
564 0 : class Elf_Rela: public serializable<Elf_Rela_Traits> {
565 : public:
566 0 : Elf_Rela(std::ifstream &file, char ei_class, char ei_data)
567 0 : : serializable<Elf_Rela_Traits>(file, ei_class, ei_data) {};
568 :
569 : static const unsigned int sh_type = SHT_RELA;
570 : static const unsigned int d_tag = DT_RELA;
571 : static const unsigned int d_tag_count = DT_RELACOUNT;
572 : };
573 :
574 : template <class Rel>
575 126 : class ElfRel_Section: public ElfSection {
576 : public:
577 63 : ElfRel_Section(Elf_Shdr &s, std::ifstream *file, Elf *parent)
578 63 : : ElfSection(s, file, parent)
579 : {
580 63 : int pos = file->tellg();
581 63 : file->seekg(shdr.sh_offset);
582 327286 : for (unsigned int i = 0; i < s.sh_size / s.sh_entsize; i++) {
583 327223 : Rel r(*file, parent->getClass(), parent->getData());
584 327223 : rels.push_back(r);
585 : }
586 63 : file->seekg(pos);
587 63 : }
588 :
589 8 : void serialize(std::ofstream &file, char ei_class, char ei_data)
590 : {
591 15577 : for (typename std::vector<Rel>::iterator i = rels.begin();
592 : i != rels.end(); ++i)
593 15569 : (*i).serialize(file, ei_class, ei_data);
594 8 : }
595 : //private: // Until we have a real API
596 : std::vector<Rel> rels;
597 : };
598 :
599 : class ElfStrtab_Section: public ElfSection {
600 : public:
601 105 : ElfStrtab_Section(Elf_Shdr &s, std::ifstream *file, Elf *parent)
602 105 : : ElfSection(s, file, parent)
603 : {
604 105 : table.push_back(table_storage(data, shdr.sh_size));
605 105 : }
606 :
607 210 : ~ElfStrtab_Section()
608 210 : {
609 218 : for (std::vector<table_storage>::iterator t = table.begin() + 1;
610 109 : t != table.end(); t++)
611 4 : delete[] t->buf;
612 210 : }
613 :
614 : const char *getStr(unsigned int index);
615 :
616 : const char *getStr(const char *string);
617 :
618 : unsigned int getStrIndex(const char *string);
619 :
620 : void serialize(std::ofstream &file, char ei_class, char ei_data);
621 : private:
622 0 : struct table_storage {
623 : unsigned int size, used;
624 : char *buf;
625 :
626 4 : table_storage(): size(4096), used(0), buf(new char[4096]) {}
627 105 : table_storage(const char *data, unsigned int sz)
628 105 : : size(sz), used(sz), buf(const_cast<char *>(data)) {}
629 : };
630 : std::vector<table_storage> table;
631 : };
632 :
633 733985 : inline char Elf::getClass() {
634 733985 : return ehdr->e_ident[EI_CLASS];
635 : }
636 :
637 733922 : inline char Elf::getData() {
638 733922 : return ehdr->e_ident[EI_DATA];
639 : }
640 :
641 42 : inline char Elf::getType() {
642 42 : return ehdr->e_type;
643 : }
644 :
645 108 : inline char Elf::getMachine() {
646 108 : return ehdr->e_machine;
647 : }
648 :
649 42 : inline unsigned int Elf::getSize() {
650 : ElfSection *section;
651 168 : for (section = shdr_section /* It's usually not far from the end */;
652 126 : section->getNext() != NULL; section = section->getNext());
653 42 : return section->getOffset() + section->getSize();
654 : }
655 :
656 1896 : inline bool ElfSection::isInSegmentType(unsigned int type) {
657 3082 : for (std::vector<ElfSegment *>::iterator seg = segments.begin(); seg != segments.end(); seg++)
658 1186 : if ((*seg)->getType() == type)
659 0 : return true;
660 1896 : return false;
661 : }
662 :
663 405970 : inline ElfLocation::ElfLocation(ElfSection *section, unsigned int off, enum position pos)
664 405970 : : section(section) {
665 405970 : if ((pos == ABSOLUTE) && section)
666 392843 : offset = off - section->getAddr();
667 : else
668 13127 : offset = off;
669 405970 : }
670 :
671 239 : inline ElfLocation::ElfLocation(unsigned int location, Elf *elf) {
672 239 : section = elf->getSectionAt(location);
673 239 : offset = location - (section ? section->getAddr() : 0);
674 239 : }
675 :
676 382063 : inline unsigned int ElfLocation::getValue() {
677 382063 : return (section ? section->getAddr() : 0) + offset;
678 : }
679 :
680 12 : inline unsigned int ElfSize::getValue() {
681 12 : return section->getSize();
682 : }
683 :
684 8 : inline unsigned int ElfEntSize::getValue() {
685 8 : return section->getEntSize();
686 : }
|