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

Side by Side Diff: runtime/vm/debuginfo_linux.cc

Issue 9139080: Rename the VM internal class ByteArray to ByteVector. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: new strategy Created 8 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/debuginfo.h ('k') | runtime/vm/debuginfo_macos.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/debuginfo.h" 5 #include "vm/debuginfo.h"
6 6
7 #include "vm/gdbjit_linux.h" 7 #include "vm/gdbjit_linux.h"
8 #include "vm/os.h" 8 #include "vm/os.h"
9 #include "vm/utils.h" 9 #include "vm/utils.h"
10 #include "vm/thread.h" 10 #include "vm/thread.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 45
46 // Add symbol information for a region (includes the start and end symbol), 46 // Add symbol information for a region (includes the start and end symbol),
47 // does not add the actual code. 47 // does not add the actual code.
48 void AddCodeRegion(const char* name, uword pc, intptr_t size); 48 void AddCodeRegion(const char* name, uword pc, intptr_t size);
49 49
50 // Add specified symbol information, does not add the actual code. 50 // Add specified symbol information, does not add the actual code.
51 int AddFunction(const char* name, uword pc, intptr_t size); 51 int AddFunction(const char* name, uword pc, intptr_t size);
52 52
53 // Write out all the Elf information using the specified handle. 53 // Write out all the Elf information using the specified handle.
54 bool WriteToFile(File* handle); 54 bool WriteToFile(File* handle);
55 bool WriteToMemory(ByteArray* region); 55 bool WriteToMemory(DebugInfo::ByteBuffer* region);
56 56
57 // Register this generated section with GDB using the JIT interface. 57 // Register this generated section with GDB using the JIT interface.
58 static void RegisterSectionWithGDB(const char* name, 58 static void RegisterSectionWithGDB(const char* name,
59 uword entry_point, 59 uword entry_point,
60 intptr_t size); 60 intptr_t size);
61 61
62 // Unregister all generated section from GDB. 62 // Unregister all generated section from GDB.
63 static void UnregisterAllSectionsWithGDB(); 63 static void UnregisterAllSectionsWithGDB();
64 64
65 private: 65 private:
66 // ELF helpers 66 // ELF helpers
67 typedef int (*OutputWriter)(void* handle, const ByteArray& section); 67 typedef int (*OutputWriter)(void* handle,
68 const DebugInfo::ByteBuffer& section);
68 typedef void (*OutputPadder)(void* handle, int padding_size); 69 typedef void (*OutputPadder)(void* handle, int padding_size);
69 70
70 int AddString(ByteArray* buf, const char* str); 71 int AddString(DebugInfo::ByteBuffer* buf, const char* str);
71 int AddSectionName(const char* str); 72 int AddSectionName(const char* str);
72 int AddName(const char* str); 73 int AddName(const char* str);
73 void AddELFHeader(int shoff); 74 void AddELFHeader(int shoff);
74 void AddSectionHeader(int section, int offset); 75 void AddSectionHeader(int section, int offset);
75 int PadSection(ByteArray* section, int offset, int alignment); 76 int PadSection(DebugInfo::ByteBuffer* section, int offset, int alignment);
76 bool WriteOutput(void* handle, OutputWriter writer, OutputPadder padder); 77 bool WriteOutput(void* handle, OutputWriter writer, OutputPadder padder);
77 78
78 uword text_vma_; // text section vma 79 uword text_vma_; // text section vma
79 intptr_t text_size_; // text section size 80 intptr_t text_size_; // text section size
80 int text_padding_; // padding preceding text section 81 int text_padding_; // padding preceding text section
81 82
82 static const int kNumSections = 5; // we generate 5 sections 83 static const int kNumSections = 5; // we generate 5 sections
83 int section_name_[kNumSections]; // array of section name indices 84 int section_name_[kNumSections]; // array of section name indices
84 ByteArray section_buf_[kNumSections]; // array of section buffers 85 DebugInfo::ByteBuffer section_buf_[kNumSections]; // array of section buffers
85 ByteArray header_; // ELF header buffer 86 DebugInfo::ByteBuffer header_; // ELF header buffer
86 ByteArray sheaders_; // section header table buffer 87 DebugInfo::ByteBuffer sheaders_; // section header table buffer
87 ByteArray lineprog_; // line statement program, part of '.debug_line' section 88 DebugInfo::ByteBuffer lineprog_; // line statement program, part of
89 // '.debug_line' section
88 90
89 // current state of the DWARF line info generator 91 // current state of the DWARF line info generator
90 uintptr_t cur_addr_; // current pc 92 uintptr_t cur_addr_; // current pc
91 int map_offset_; 93 int map_offset_;
92 uword map_begin_; 94 uword map_begin_;
93 uword map_end_; 95 uword map_end_;
94 96
95 Mutex lock_; 97 Mutex lock_;
96 }; 98 };
97 99
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 174
173 175
174 // Convenience function aligning an integer. 176 // Convenience function aligning an integer.
175 static inline uintptr_t Align(uintptr_t x, intptr_t size) { 177 static inline uintptr_t Align(uintptr_t x, intptr_t size) {
176 // size is a power of 2 178 // size is a power of 2
177 ASSERT((size & (size-1)) == 0); 179 ASSERT((size & (size-1)) == 0);
178 return (x + (size-1)) & ~(size-1); 180 return (x + (size-1)) & ~(size-1);
179 } 181 }
180 182
181 183
182 // Convenience function writing a single byte to a ByteArray. 184 // Convenience function writing a single byte to a ByteBuffer.
183 static inline void WriteByte(ByteArray* buf, uint8_t byte) { 185 static inline void WriteByte(DebugInfo::ByteBuffer* buf, uint8_t byte) {
184 buf->Add(byte); 186 buf->Add(byte);
185 } 187 }
186 188
187 189
188 // Convenience function writing an unsigned native word to a ByteArray. 190 // Convenience function writing an unsigned native word to a ByteBuffer.
189 // The word is 32-bit wide in 32-bit mode and 64-bit wide in 64-bit mode. 191 // The word is 32-bit wide in 32-bit mode and 64-bit wide in 64-bit mode.
190 static inline void WriteWord(ByteArray* buf, uword word) { 192 static inline void WriteWord(DebugInfo::ByteBuffer* buf, uword word) {
191 uint8_t* p = reinterpret_cast<uint8_t*>(&word); 193 uint8_t* p = reinterpret_cast<uint8_t*>(&word);
192 for (size_t i = 0; i < sizeof(word); i++) { 194 for (size_t i = 0; i < sizeof(word); i++) {
193 buf->Add(p[i]); 195 buf->Add(p[i]);
194 } 196 }
195 } 197 }
196 198
197 static inline void WriteInt(ByteArray* buf, int word) { 199 static inline void WriteInt(DebugInfo::ByteBuffer* buf, int word) {
198 uint8_t* p = reinterpret_cast<uint8_t*>(&word); 200 uint8_t* p = reinterpret_cast<uint8_t*>(&word);
199 for (size_t i = 0; i < sizeof(word); i++) { 201 for (size_t i = 0; i < sizeof(word); i++) {
200 buf->Add(p[i]); 202 buf->Add(p[i]);
201 } 203 }
202 } 204 }
203 205
204 static inline void WriteShort(ByteArray* buf, uint16_t word) { 206 static inline void WriteShort(DebugInfo::ByteBuffer* buf, uint16_t word) {
205 uint8_t* p = reinterpret_cast<uint8_t*>(&word); 207 uint8_t* p = reinterpret_cast<uint8_t*>(&word);
206 for (size_t i = 0; i < sizeof(word); i++) { 208 for (size_t i = 0; i < sizeof(word); i++) {
207 buf->Add(p[i]); 209 buf->Add(p[i]);
208 } 210 }
209 } 211 }
210 212
211 static inline void WriteString(ByteArray* buf, const char* str) { 213 static inline void WriteString(DebugInfo::ByteBuffer* buf, const char* str) {
212 for (size_t i = 0; i < strlen(str); i++) { 214 for (size_t i = 0; i < strlen(str); i++) {
213 buf->Add(static_cast<uint8_t>(str[i])); 215 buf->Add(static_cast<uint8_t>(str[i]));
214 } 216 }
215 } 217 }
216 218
217 static inline void Write(ByteArray* buf, const void* mem, int length) { 219 static inline void Write(DebugInfo::ByteBuffer* buf,
220 const void* mem,
221 int length) {
218 const uint8_t* p = reinterpret_cast<const uint8_t*>(mem); 222 const uint8_t* p = reinterpret_cast<const uint8_t*>(mem);
219 for (int i = 0; i < length; i++) { 223 for (int i = 0; i < length; i++) {
220 buf->Add(p[i]); 224 buf->Add(p[i]);
221 } 225 }
222 } 226 }
223 227
224 228
225 // Write given section to file and return written size. 229 // Write given section to file and return written size.
226 static int WriteSectionToFile(void* handle, const ByteArray& section) { 230 static int WriteSectionToFile(void* handle,
231 const DebugInfo::ByteBuffer& section) {
227 #if 0 232 #if 0
228 File* fp = reinterpret_cast<File*>(handle); 233 File* fp = reinterpret_cast<File*>(handle);
229 int size = section.size(); 234 int size = section.size();
230 fp->WriteFully(section.data(), size); 235 fp->WriteFully(section.data(), size);
231 return size; 236 return size;
232 #else 237 #else
233 return 0; 238 return 0;
234 #endif 239 #endif
235 } 240 }
236 241
237 242
238 // Pad output file to specified padding size. 243 // Pad output file to specified padding size.
239 static void PadFile(void* handle, int padding_size) { 244 static void PadFile(void* handle, int padding_size) {
240 #if 0 245 #if 0
241 File* fp = reinterpret_cast<File*>(handle); 246 File* fp = reinterpret_cast<File*>(handle);
242 for (int i = 0; i < padding_size; i++) { 247 for (int i = 0; i < padding_size; i++) {
243 fp->WriteFully("", 1); 248 fp->WriteFully("", 1);
244 } 249 }
245 #endif 250 #endif
246 } 251 }
247 252
248 253
249 // Write given section to specified memory region and return written size. 254 // Write given section to specified memory region and return written size.
250 static int WriteSectionToMemory(void* handle, const ByteArray& section) { 255 static int WriteSectionToMemory(void* handle,
251 ByteArray* buffer = reinterpret_cast<ByteArray*>(handle); 256 const DebugInfo::ByteBuffer& section) {
257 DebugInfo::ByteBuffer* buffer =
258 reinterpret_cast<DebugInfo::ByteBuffer*>(handle);
252 int size = section.size(); 259 int size = section.size();
253 for (int i = 0; i < size; i++) { 260 for (int i = 0; i < size; i++) {
254 buffer->Add(static_cast<uint8_t>(section.data()[i])); 261 buffer->Add(static_cast<uint8_t>(section.data()[i]));
255 } 262 }
256 return size; 263 return size;
257 } 264 }
258 265
259 266
260 // Pad memory to specified padding size. 267 // Pad memory to specified padding size.
261 static void PadMemory(void* handle, int padding_size) { 268 static void PadMemory(void* handle, int padding_size) {
262 ByteArray* buffer = reinterpret_cast<ByteArray*>(handle); 269 DebugInfo::ByteBuffer* buffer =
270 reinterpret_cast<DebugInfo::ByteBuffer*>(handle);
263 for (int i = 0; i < padding_size; i++) { 271 for (int i = 0; i < padding_size; i++) {
264 buffer->Add(static_cast<uint8_t>(0)); 272 buffer->Add(static_cast<uint8_t>(0));
265 } 273 }
266 } 274 }
267 275
268 276
269 // Constructor 277 // Constructor
270 ElfGen::ElfGen() 278 ElfGen::ElfGen()
271 : text_vma_(0), text_size_(0), text_padding_(0), map_offset_(0), lock_() { 279 : text_vma_(0), text_size_(0), text_padding_(0), map_offset_(0), lock_() {
272 for (int i = 0; i < kNumSections; i++) { 280 for (int i = 0; i < kNumSections; i++) {
273 ASSERT(section_attr[i].shndx == i); // Verify layout of sections. 281 ASSERT(section_attr[i].shndx == i); // Verify layout of sections.
274 section_name_[i] = AddSectionName(section_attr[i].name); 282 section_name_[i] = AddSectionName(section_attr[i].name);
275 } 283 }
276 // Section header string table always starts with an empty string, which is 284 // Section header string table always starts with an empty string, which is
277 // the name of the kUndef section. 285 // the name of the kUndef section.
278 ASSERT((section_attr[0].name[0] == '\0') && (section_name_[0] == 0)); 286 ASSERT((section_attr[0].name[0] == '\0') && (section_name_[0] == 0));
279 287
280 // String table always starts with an empty string. 288 // String table always starts with an empty string.
281 AddName(""); 289 AddName("");
282 ASSERT(section_buf_[kStrtab].size() == 1); 290 ASSERT(section_buf_[kStrtab].size() == 1);
283 291
284 // Symbol at index 0 in symtab is always STN_UNDEF (all zero): 292 // Symbol at index 0 in symtab is always STN_UNDEF (all zero):
285 ByteArray* symtab = &section_buf_[kSymtab]; 293 DebugInfo::ByteBuffer* symtab = &section_buf_[kSymtab];
286 while (symtab->size() < kSymbolSize) { 294 while (symtab->size() < kSymbolSize) {
287 WriteInt(symtab, 0); 295 WriteInt(symtab, 0);
288 } 296 }
289 ASSERT(symtab->size() == kSymbolSize); 297 ASSERT(symtab->size() == kSymbolSize);
290 } 298 }
291 299
292 300
293 // Destructor 301 // Destructor
294 ElfGen::~ElfGen() { 302 ElfGen::~ElfGen() {
295 } 303 }
(...skipping 24 matching lines...) Expand all
320 MutexLocker ml(&lock_); 328 MutexLocker ml(&lock_);
321 AddFunction(name, pc, size); 329 AddFunction(name, pc, size);
322 char end_name[256]; 330 char end_name[256];
323 OS::SNPrint(end_name, sizeof(end_name), "%s_end", name); 331 OS::SNPrint(end_name, sizeof(end_name), "%s_end", name);
324 AddFunction(end_name, pc + size, 0); 332 AddFunction(end_name, pc + size, 0);
325 } 333 }
326 334
327 335
328 int ElfGen::AddFunction(const char* name, uword pc, intptr_t size) { 336 int ElfGen::AddFunction(const char* name, uword pc, intptr_t size) {
329 ASSERT(text_vma_ != 0); // code must have been added 337 ASSERT(text_vma_ != 0); // code must have been added
330 ByteArray* symtab = &section_buf_[kSymtab]; 338 DebugInfo::ByteBuffer* symtab = &section_buf_[kSymtab];
331 const int beg = symtab->size(); 339 const int beg = symtab->size();
332 WriteInt(symtab, AddName(name)); // st_name 340 WriteInt(symtab, AddName(name)); // st_name
333 #if defined(TARGET_ARCH_X64) 341 #if defined(TARGET_ARCH_X64)
334 WriteShort(symtab, (kSTB_LOCAL << 4) + kSTT_FUNC); // st_info + (st_other<<8) 342 WriteShort(symtab, (kSTB_LOCAL << 4) + kSTT_FUNC); // st_info + (st_other<<8)
335 WriteShort(symtab, kText); // st_shndx 343 WriteShort(symtab, kText); // st_shndx
336 #endif 344 #endif
337 WriteWord(symtab, pc); // st_value 345 WriteWord(symtab, pc); // st_value
338 WriteWord(symtab, size); // st_size 346 WriteWord(symtab, size); // st_size
339 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) 347 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
340 // st_info + (st_other<<8) 348 // st_info + (st_other<<8)
341 WriteShort(symtab, (kSTB_EXPORTED << 4) + kSTT_FUNC); 349 WriteShort(symtab, (kSTB_EXPORTED << 4) + kSTT_FUNC);
342 WriteShort(symtab, kText); // st_shndx 350 WriteShort(symtab, kText); // st_shndx
343 #endif 351 #endif
344 ASSERT(symtab->size() - beg == kSymbolSize); 352 ASSERT(symtab->size() - beg == kSymbolSize);
345 return beg / kSymbolSize; // symbol index in symtab 353 return beg / kSymbolSize; // symbol index in symtab
346 } 354 }
347 355
348 356
349 bool ElfGen::WriteToFile(File* handle) { 357 bool ElfGen::WriteToFile(File* handle) {
350 return WriteOutput(handle, WriteSectionToFile, PadFile); 358 return WriteOutput(handle, WriteSectionToFile, PadFile);
351 } 359 }
352 360
353 361
354 bool ElfGen::WriteToMemory(ByteArray* region) { 362 bool ElfGen::WriteToMemory(DebugInfo::ByteBuffer* region) {
355 return WriteOutput(region, WriteSectionToMemory, PadMemory); 363 return WriteOutput(region, WriteSectionToMemory, PadMemory);
356 } 364 }
357 365
358 366
359 int ElfGen::AddString(ByteArray* buf, const char* str) { 367 int ElfGen::AddString(DebugInfo::ByteBuffer* buf, const char* str) {
360 const int str_index = buf->size(); 368 const int str_index = buf->size();
361 WriteString(buf, str); 369 WriteString(buf, str);
362 WriteByte(buf, 0); // terminating '\0' 370 WriteByte(buf, 0); // terminating '\0'
363 return str_index; 371 return str_index;
364 } 372 }
365 373
366 374
367 int ElfGen::AddSectionName(const char* str) { 375 int ElfGen::AddSectionName(const char* str) {
368 return AddString(&section_buf_[kShStrtab], str); 376 return AddString(&section_buf_[kShStrtab], str);
369 } 377 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 WriteInt(&sheaders_, 0); 431 WriteInt(&sheaders_, 0);
424 WriteWord(&sheaders_, section_attr[section].sh_addralign); 432 WriteWord(&sheaders_, section_attr[section].sh_addralign);
425 WriteWord(&sheaders_, section_attr[section].sh_entsize); 433 WriteWord(&sheaders_, section_attr[section].sh_entsize);
426 ASSERT(sheaders_.size() == kSectionHeaderEntrySize * (section + 1)); 434 ASSERT(sheaders_.size() == kSectionHeaderEntrySize * (section + 1));
427 } 435 }
428 436
429 437
430 // Pads the given section with zero bytes for the given aligment, assuming the 438 // Pads the given section with zero bytes for the given aligment, assuming the
431 // section starts at given file offset; returns file offset after padded 439 // section starts at given file offset; returns file offset after padded
432 // section. 440 // section.
433 int ElfGen::PadSection(ByteArray* section, int offset, int alignment) { 441 int ElfGen::PadSection(DebugInfo::ByteBuffer* section,
442 int offset,
443 int alignment) {
434 offset += section->size(); 444 offset += section->size();
435 int aligned_offset = Align(offset, alignment); 445 int aligned_offset = Align(offset, alignment);
436 while (offset++ < aligned_offset) { 446 while (offset++ < aligned_offset) {
437 WriteByte(section, 0); // one byte padding. 447 WriteByte(section, 0); // one byte padding.
438 } 448 }
439 return aligned_offset; 449 return aligned_offset;
440 } 450 }
441 451
442 452
443 bool ElfGen::WriteOutput(void* handle, 453 bool ElfGen::WriteOutput(void* handle,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 elf_gen->AddCode(pc, size); 513 elf_gen->AddCode(pc, size);
504 } 514 }
505 515
506 516
507 void DebugInfo::AddCodeRegion(const char* name, uword pc, intptr_t size) { 517 void DebugInfo::AddCodeRegion(const char* name, uword pc, intptr_t size) {
508 ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_); 518 ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_);
509 elf_gen->AddCodeRegion(name, pc, size); 519 elf_gen->AddCodeRegion(name, pc, size);
510 } 520 }
511 521
512 522
513 bool DebugInfo::WriteToMemory(ByteArray* region) { 523 bool DebugInfo::WriteToMemory(ByteBuffer* region) {
514 ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_); 524 ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_);
515 return elf_gen->WriteToMemory(region); 525 return elf_gen->WriteToMemory(region);
516 } 526 }
517 527
518 528
519 DebugInfo* DebugInfo::NewGenerator() { 529 DebugInfo* DebugInfo::NewGenerator() {
520 return new DebugInfo(); 530 return new DebugInfo();
521 } 531 }
522 532
523 533
524 void DebugInfo::RegisterSection(const char* name, 534 void DebugInfo::RegisterSection(const char* name,
525 uword entry_point, 535 uword entry_point,
526 intptr_t size) { 536 intptr_t size) {
527 ElfGen* elf_section = new ElfGen(); 537 ElfGen* elf_section = new ElfGen();
528 ASSERT(elf_section != NULL); 538 ASSERT(elf_section != NULL);
529 elf_section->AddCode(entry_point, size); 539 elf_section->AddCode(entry_point, size);
530 elf_section->AddCodeRegion(name, entry_point, size); 540 elf_section->AddCodeRegion(name, entry_point, size);
531 541
532 ByteArray* dynamic_region = new ByteArray(); 542 ByteBuffer* dynamic_region = new ByteBuffer();
533 ASSERT(dynamic_region != NULL); 543 ASSERT(dynamic_region != NULL);
534 544
535 elf_section->WriteToMemory(dynamic_region); 545 elf_section->WriteToMemory(dynamic_region);
536 546
537 ::addDynamicSection(reinterpret_cast<const char*>(dynamic_region->data()), 547 ::addDynamicSection(reinterpret_cast<const char*>(dynamic_region->data()),
538 dynamic_region->size()); 548 dynamic_region->size());
539 dynamic_region->set_data(NULL); 549 dynamic_region->set_data(NULL);
540 delete dynamic_region; 550 delete dynamic_region;
541 delete elf_section; 551 delete elf_section;
542 } 552 }
543 553
544 554
545 void DebugInfo::UnregisterAllSections() { 555 void DebugInfo::UnregisterAllSections() {
546 ::deleteDynamicSections(); 556 ::deleteDynamicSections();
547 } 557 }
548 558
549 } // namespace dart 559 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debuginfo.h ('k') | runtime/vm/debuginfo_macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698