ELFSectionBits.hxx revision cf6522329b7a93193fbef761386bdaa4a07206f8
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>::
29read(Archiver &AR,
30     ELFSectionHeader<Bitwidth> const *sh,
31     ConcreteELFSectionBits *concrete) {
32  llvm::OwningPtr<ConcreteELFSectionBits> result(concrete);
33  // TODO: Align.
34  result->buf_size = sh->getSize();
35  if (result->buf_size > 0) {
36    result->buf = (unsigned char *)mmap(0, result->buf_size,
37                                        PROT_READ | PROT_WRITE,
38                                        MAP_PRIVATE |
39                                        MAP_ANONYMOUS |
40                                        MAP_32BIT, -1, 0);
41  }
42
43  // Check map success.
44  if (result->buf == MAP_FAILED) {
45    assert(0 && "MAP_FAILED");
46    return 0;
47  }
48
49  // Save section_header
50  result->section_header = sh;
51
52  // Read the buffer from string tab
53  if (!result->serialize(AR)) {
54    // Unable to read the structure.  Return NULL.
55    return 0;
56  }
57
58  if (!AR) {
59    // Unable to read the progbits tab
60    return 0;
61  }
62
63  return result.take();
64}
65
66template <unsigned Bitwidth>
67inline unsigned char const *
68ELFSectionBits<Bitwidth>::memory_protect() const {
69  int protect_type = PROT_READ;
70
71  if (section_header->getFlags() & SHF_WRITE) {
72    protect_type |= PROT_WRITE;
73  }
74
75  if (section_header->getFlags() & SHF_EXECINSTR) {
76    protect_type |= PROT_EXEC;
77  }
78
79  if (buf_size > 0) {
80    int ret = mprotect((void *)buf, buf_size, protect_type);
81    if (ret == -1) {
82      llvm::errs() << "Error: Can't mprotect.\n";
83      return 0;
84    }
85
86    if (protect_type & PROT_EXEC) {
87      FLUSH_CPU_CACHE(buf, buf + buf_size);
88    }
89  }
90
91  return buf;
92}
93
94#endif // ELF_SECTION_BITS_HXX
95