ELFSectionBits.hxx revision 58611fc8193e7386698178f167a2e0cbdd6a4f6f
1#ifndef ELF_SECTION_BITS_HXX
2#define ELF_SECTION_BITS_HXX
3
4#include "utils/flush_cpu_cache.h"
5#include "utils/helper.h"
6
7#include <llvm/Support/raw_ostream.h>
8
9#include <sys/mman.h>
10
11#ifndef MAP_32BIT
12#define MAP_32BIT 0
13// Note: If the <sys/mman.h> does not come with MAP_32BIT, then we
14// define it as zero, so that it won't manipulate the flags.
15#endif
16
17
18template <unsigned Bitwidth>
19ELFSectionBits<Bitwidth>::~ELFSectionBits() {
20  if (buf) {
21    munmap(buf, buf_size);
22  }
23}
24
25template <unsigned Bitwidth>
26template <typename Archiver, typename ConcreteELFSectionBits>
27inline ConcreteELFSectionBits *
28ELFSectionBits<Bitwidth>::read(Archiver &AR,
29                               ELFSectionHeader<Bitwidth> const *sh,
30                               ConcreteELFSectionBits *concrete) {
31  llvm::OwningPtr<ConcreteELFSectionBits> result(concrete);
32  // TODO: Align.
33  result->buf_size = sh->getSize();
34  if (result->buf_size > 0) {
35    result->buf = (unsigned char *)mmap(0, result->buf_size,
36                                        PROT_READ | PROT_WRITE,
37                                        MAP_PRIVATE |
38                                        MAP_ANONYMOUS |
39                                        MAP_32BIT, -1, 0);
40  }
41
42  // Check map success.
43  if (result->buf == MAP_FAILED) {
44    assert(0 && "MAP_FAILED");
45    return 0;
46  }
47
48  // Save section_header
49  result->section_header = sh;
50
51  // Read the buffer from string tab
52  if (!result->serialize(AR)) {
53    // Unable to read the structure.  Return NULL.
54    return 0;
55  }
56
57  if (!AR) {
58    // Unable to read the progbits tab
59    return 0;
60  }
61
62  return result.take();
63}
64
65template <unsigned Bitwidth>
66inline unsigned char const *
67ELFSectionBits<Bitwidth>::memory_protect() const {
68  int protect_type = PROT_READ;
69
70  if (section_header->getFlags() & SHF_WRITE) {
71    protect_type |= PROT_WRITE;
72  }
73
74  if (section_header->getFlags() & SHF_EXECINSTR) {
75    protect_type |= PROT_EXEC;
76  }
77
78  if (buf_size > 0) {
79    int ret = mprotect((void *)buf, buf_size, protect_type);
80    if (ret == -1) {
81      llvm::errs() << "Error: Can't mprotect.\n";
82      return 0;
83    }
84
85    if (protect_type & PROT_EXEC) {
86      FLUSH_CPU_CACHE(buf, buf + buf_size);
87    }
88  }
89
90  return buf;
91}
92
93#endif // ELF_SECTION_BITS_HXX
94