Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: third_party/crazy_linker/crazy_linker/src/crazy_linker_util.h

Issue 23717023: Android: Add chrome-specific dynamic linker. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add new 'content_linker_unittests_apk' target + ensure ashmem regions are forced read-only Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef CRAZY_LINKER_UTIL_H
6 #define CRAZY_LINKER_UTIL_H
7
8 #include <fcntl.h>
9 #include <stdarg.h>
10 #include <stdio.h>
11 #include <unistd.h>
12
13 namespace crazy {
14
15 // Helper macro to loop around EINTR errors in syscalls.
16 #define HANDLE_EINTR(expr) TEMP_FAILURE_RETRY(expr)
17
18 // Helper macro to tag unused variables. Use in the declaration, between
19 // the type and name, as in:
20 // int CRAZY_UNUSED my_var = 0;
21 #define CRAZY_UNUSED __attribute__((unused))
22
23 // Helper scoped pointer class.
24 template <class T>
25 class ScopedPtr {
26 public:
27 ScopedPtr() : ptr_(NULL) {}
28 explicit ScopedPtr(T* ptr) : ptr_(ptr) {}
29 ~ScopedPtr() {
30 Reset(NULL);
31 }
32
33 T* Release() {
34 T* ret = ptr_;
35 ptr_ = NULL;
36 return ret;
37 }
38
39 void Reset(T* ptr) {
40 if (ptr_)
41 delete ptr_;
42 ptr_ = ptr;
43 }
44
45 T* Get() { return ptr_; }
46 T& operator*() { return *ptr_; }
47 T* operator->() { return ptr_; }
48 private:
49 T* ptr_;
50 };
51
52 // Return the base name from a file path. Important: this is a pointer
53 // into the original string.
54 const char* GetBaseNamePtr(const char* path);
55
56 // Helper class used to implement a string. Similar to std::string
57 // without all the crazy iterator / iostream stuff.
58 //
59 // Required because crazy linker should only link against the system
60 // libstdc++ that only provides new/delete.
61 //
62 class String {
63 public:
64 String();
65 String(const char* str, size_t len);
66 String(const String& other);
67 explicit String(const char* str);
68 explicit String(char ch);
69
70 ~String();
71
72 const char* c_str() const { return ptr_; }
73 char* ptr() { return ptr_; }
74 size_t size() const { return size_; }
75 size_t capacity() const { return capacity_; }
76
77 bool IsEmpty() const { return size_ == 0; }
78
79 char& operator[](size_t index) {
80 return ptr_[index];
81 }
82
83 String& operator =(const String& other) {
84 Assign(other.ptr_, other.size_);
85 return *this;
86 }
87
88 String& operator=(const char* str) {
89 Assign(str, strlen(str));
90 return *this;
91 }
92
93 String& operator=(char ch) {
94 Assign(&ch, 1);
95 return *this;
96 }
97
98 String& operator +=(const String& other) {
99 Append(other);
100 return *this;
101 }
102
103 String& operator +=(const char* str) {
104 Append(str, strlen(str));
105 return *this;
106 }
107
108 String& operator +=(char ch) {
109 Append(&ch, 1);
110 return *this;
111 }
112
113 void Resize(size_t new_size);
114
115 void Reserve(size_t new_capacity);
116
117 void Assign(const char* str, size_t len);
118
119 void Assign(const String& other) {
120 Assign(other.ptr_, other.size_);
121 }
122
123 void Assign(const char* str) {
124 Assign(str, strlen(str));
125 }
126
127 void Append(const char* str, size_t len);
128
129 void Append(const String& other) {
130 Append(other.ptr_, other.size_);
131 }
132
133 void Append(const char* str) {
134 Append(str, strlen(str));
135 }
136
137 private:
138 void Init(void) {
139 ptr_ = const_cast<char*>(kEmpty);
140 size_ = 0;
141 capacity_ = 0;
142 }
143
144 static const char kEmpty[];
145
146 char* ptr_;
147 size_t size_;
148 size_t capacity_;
149 };
150
151 // Helper template used to implement a simple vector or POD-struct items.
152 // I.e. this uses memmove() to move items during insertion / removal.
153 //
154 // Required because crazy linker should only link against the system
155 // libstdc++ which only provides new/delete.
156 //
157 template <class T>
158 class Vector {
159 public:
160 Vector() : items_(0), count_(0), capacity_(0) {}
161 ~Vector() {
162 free(items_);
163 }
164
165 T& operator[](size_t index) {
166 return items_[index];
167 }
168
169 bool IsEmpty() const {
170 return count_ == 0;
171 }
172
173 void PushBack(T item) {
174 InsertAt(static_cast<int>(count_), item);
175 }
176
177 T PopFirst() {
178 T result = items_[0];
179 RemoveAt(0);
180 return result;
181 }
182
183 T PopLast() {
184 T result = items_[count_ - 1];
185 Resize(count_ - 1);
186 return result;
187 }
188
189 void Remove(T item) {
190 int index = IndexOf(item);
191 if (index >= 0)
192 RemoveAt(index);
193 }
194
195 void InsertAt(int index, T item);
196
197 void RemoveAt(int index);
198
199 int IndexOf(T item) const;
200
201 bool Has(T item) const {
202 return IndexOf(item) >= 0;
203 }
204
205 size_t GetCount() const { return count_; }
206
207 void Reserve(size_t new_capacity);
208
209 void Resize(size_t new_count);
210
211 private:
212 T* items_;
213 size_t count_;
214 size_t capacity_;
215 };
216
217 template <class T>
218 int Vector<T>::IndexOf(T item) const {
219 for (size_t n = 0; n < count_; ++n) {
220 if (items_[n] == item)
221 return static_cast<int>(n);
222 }
223 return -1;
224 }
225
226 template <class T>
227 void Vector<T>::InsertAt(int index, T item) {
228 if (count_ >= capacity_)
229 Reserve(capacity_ + (capacity_ >> 1) + 4);
230
231 if (index < 0)
232 index = 0;
233 size_t n = static_cast<size_t>(index);
234 if (n > count_)
235 n = count_;
236 else
237 memmove(items_ + n + 1, items_ + n, (count_ - n) * sizeof(T));
238
239 items_[n] = item;
240 count_++;
241 }
242
243 template <class T>
244 void Vector<T>::RemoveAt(int index) {
245 if (index < 0)
246 return;
247
248 size_t n = static_cast<size_t>(index);
249 if (n >= count_)
250 return;
251
252 memmove(items_ + n, items_ + n + 1, (count_ - n - 1) * sizeof(T));
253 count_--;
254 }
255
256 template <class T>
257 void Vector<T>::Reserve(size_t new_capacity) {
258 items_ = reinterpret_cast<T*>(realloc(items_, new_capacity * sizeof(T)));
259 capacity_ = new_capacity;
260 if (count_ > capacity_)
261 count_ = capacity_;
262 }
263
264 template <class T>
265 void Vector<T>::Resize(size_t new_size) {
266 if (new_size > capacity_)
267 Reserve(new_size);
268
269 if (new_size > count_)
270 memset(items_ + count_, 0, (new_size - count_) * sizeof(T));
271
272 count_ = new_size;
273 }
274
275 // Helper template class to implement a set.
276 // Given that the crazy linker doesn't expect to deal with hundreds
277 // of libraries at the same time, implement it with a vector.
278 template <class T>
279 class Set {
280 public:
281 Set() : items_() {}
282 ~Set() {}
283
284 // Returns the number of items in the set.
285 size_t GetCount() const { return items_.GetCount(); }
286
287 bool IsEmpty() const { return items_.IsEmpty(); }
288
289 // Returns true iff the set contains a given item.
290 bool Has(T item) const {
291 return items_.Has(item);
292 }
293
294 // Add an item to the set. Returns false iff the item was already in it.
295 bool Add(T item);
296
297 // Delete an item from the set. Returns false iff the item was not in it.
298 bool Del(T item);
299
300 private:
301 Vector<T> items_;
302 };
303
304 template <class T>
305 bool Set<T>::Add(T item) {
306 int idx = items_.IndexOf(item);
307 if (idx >= 0)
308 return false;
309
310 items_.PushBack(item);
311 return true;
312 }
313
314 template <class T>
315 bool Set<T>::Del(T item) {
316 int idx = items_.IndexOf(item);
317 if (idx < 0)
318 return false;
319 items_.RemoveAt(idx);
320 return true;
321 }
322
323 } // namespace crazy
324
325 #endif // CRAZY_LINKER_UTIL_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698