1 /*
2  * Copyright 2011, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ELF_SECTION_HEADER_H
18 #define ELF_SECTION_HEADER_H
19 
20 #include "ELFTypes.h"
21 
22 #include <stdint.h>
23 
24 class ELFSectionHeaderHelperMixin {
25 protected:
26   static char const *getSectionTypeStr(uint32_t type);
27 };
28 
29 template <unsigned Bitwidth>
30 class ELFSectionHeader_CRTP : private ELFSectionHeaderHelperMixin {
31 public:
32   ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth);
33 
34 protected:
35   ELFObjectTy const *owner;
36 
37   size_t index;
38 
39   word_t sh_name;
40   word_t sh_type;
41   addr_t sh_addr;
42   offset_t sh_offset;
43   word_t sh_link;
44   word_t sh_info;
45 
46 protected:
ELFSectionHeader_CRTP()47   ELFSectionHeader_CRTP() { }
~ELFSectionHeader_CRTP()48   ~ELFSectionHeader_CRTP() { }
49 
50 public:
getIndex()51   size_t getIndex() const {
52     return index;
53   }
54 
getNameIndex()55   word_t getNameIndex() const {
56     return sh_name;
57   }
58 
59   char const *getName() const;
60 
getType()61   word_t getType() const {
62     return sh_type;
63   }
64 
getAddress()65   addr_t getAddress() const {
66     return sh_addr;
67   }
68 
getOffset()69   offset_t getOffset() const {
70     return sh_offset;
71   }
72 
getLink()73   word_t getLink() const {
74     return sh_link;
75   }
76 
getExtraInfo()77   word_t getExtraInfo() const {
78     return sh_info;
79   }
80 
isValid()81   bool isValid() const {
82     // FIXME: Should check the correctness of the section header.
83     return true;
84   }
85 
86   template <typename Archiver>
87   static ELFSectionHeaderTy *
88   read(Archiver &AR, ELFObjectTy const *owner, size_t index = 0);
89 
90   void print(bool shouldPrintHeader = false) const;
91 
92 private:
concrete()93   ELFSectionHeaderTy *concrete() {
94     return static_cast<ELFSectionHeaderTy *>(this);
95   }
96 
concrete()97   ELFSectionHeaderTy const *concrete() const {
98     return static_cast<ELFSectionHeaderTy const *>(this);
99   }
100 };
101 
102 
103 #include "impl/ELFSectionHeader.hxx"
104 
105 template <>
106 class ELFSectionHeader<32> : public ELFSectionHeader_CRTP<32> {
107   friend class ELFSectionHeader_CRTP<32>;
108 
109 private:
110   word_t sh_flags;
111   word_t sh_size;
112   word_t sh_addralign;
113   word_t sh_entsize;
114 
115 private:
ELFSectionHeader()116   ELFSectionHeader() {
117   }
118 
119   template <typename Archiver>
serialize(Archiver & AR)120   bool serialize(Archiver &AR) {
121     AR.prologue(TypeTraits<ELFSectionHeader>::size);
122 
123     AR & sh_name;
124     AR & sh_type;
125     AR & sh_flags;
126     AR & sh_addr;
127     AR & sh_offset;
128     AR & sh_size;
129     AR & sh_link;
130     AR & sh_info;
131     AR & sh_addralign;
132     AR & sh_entsize;
133 
134     AR.epilogue(TypeTraits<ELFSectionHeader>::size);
135     return AR;
136   }
137 
138 public:
getFlags()139   word_t getFlags() const {
140     return sh_flags;
141   }
142 
getSize()143   word_t getSize() const {
144     return sh_size;
145   }
146 
getAddressAlign()147   word_t getAddressAlign() const {
148     return sh_addralign;
149   }
150 
getEntrySize()151   word_t getEntrySize() const {
152     return sh_entsize;
153   }
154 };
155 
156 template <>
157 class ELFSectionHeader<64> : public ELFSectionHeader_CRTP<64> {
158   friend class ELFSectionHeader_CRTP<64>;
159 
160 private:
161   xword_t sh_flags;
162   xword_t sh_size;
163   xword_t sh_addralign;
164   xword_t sh_entsize;
165 
166 private:
ELFSectionHeader()167   ELFSectionHeader() {
168   }
169 
170   template <typename Archiver>
serialize(Archiver & AR)171   bool serialize(Archiver &AR) {
172     AR.prologue(TypeTraits<ELFSectionHeader>::size);
173 
174     AR & sh_name;
175     AR & sh_type;
176     AR & sh_flags;
177     AR & sh_addr;
178     AR & sh_offset;
179     AR & sh_size;
180     AR & sh_link;
181     AR & sh_info;
182     AR & sh_addralign;
183     AR & sh_entsize;
184 
185     AR.epilogue(TypeTraits<ELFSectionHeader>::size);
186     return AR;
187   }
188 
189 public:
getFlags()190   xword_t getFlags() const {
191     return sh_flags;
192   }
193 
getSize()194   xword_t getSize() const {
195     return sh_size;
196   }
197 
getAddressAlign()198   xword_t getAddressAlign() const {
199     return sh_addralign;
200   }
201 
getEntrySize()202   xword_t getEntrySize() const {
203     return sh_entsize;
204   }
205 };
206 
207 #endif // ELF_SECTION_HEADER_H
208