| OLD | NEW |
| 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 Loading... |
| 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(ByteVector* 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, const ByteVector& section); |
| 68 typedef void (*OutputPadder)(void* handle, int padding_size); | 68 typedef void (*OutputPadder)(void* handle, int padding_size); |
| 69 | 69 |
| 70 int AddString(ByteArray* buf, const char* str); | 70 int AddString(ByteVector* buf, const char* str); |
| 71 int AddSectionName(const char* str); | 71 int AddSectionName(const char* str); |
| 72 int AddName(const char* str); | 72 int AddName(const char* str); |
| 73 void AddELFHeader(int shoff); | 73 void AddELFHeader(int shoff); |
| 74 void AddSectionHeader(int section, int offset); | 74 void AddSectionHeader(int section, int offset); |
| 75 int PadSection(ByteArray* section, int offset, int alignment); | 75 int PadSection(ByteVector* section, int offset, int alignment); |
| 76 bool WriteOutput(void* handle, OutputWriter writer, OutputPadder padder); | 76 bool WriteOutput(void* handle, OutputWriter writer, OutputPadder padder); |
| 77 | 77 |
| 78 uword text_vma_; // text section vma | 78 uword text_vma_; // text section vma |
| 79 intptr_t text_size_; // text section size | 79 intptr_t text_size_; // text section size |
| 80 int text_padding_; // padding preceding text section | 80 int text_padding_; // padding preceding text section |
| 81 | 81 |
| 82 static const int kNumSections = 5; // we generate 5 sections | 82 static const int kNumSections = 5; // we generate 5 sections |
| 83 int section_name_[kNumSections]; // array of section name indices | 83 int section_name_[kNumSections]; // array of section name indices |
| 84 ByteArray section_buf_[kNumSections]; // array of section buffers | 84 ByteVector section_buf_[kNumSections]; // array of section buffers |
| 85 ByteArray header_; // ELF header buffer | 85 ByteVector header_; // ELF header buffer |
| 86 ByteArray sheaders_; // section header table buffer | 86 ByteVector sheaders_; // section header table buffer |
| 87 ByteArray lineprog_; // line statement program, part of '.debug_line' section | 87 ByteVector lineprog_; // line statement program, part of .debug_line section |
| 88 | 88 |
| 89 // current state of the DWARF line info generator | 89 // current state of the DWARF line info generator |
| 90 uintptr_t cur_addr_; // current pc | 90 uintptr_t cur_addr_; // current pc |
| 91 int map_offset_; | 91 int map_offset_; |
| 92 uword map_begin_; | 92 uword map_begin_; |
| 93 uword map_end_; | 93 uword map_end_; |
| 94 | 94 |
| 95 Mutex lock_; | 95 Mutex lock_; |
| 96 }; | 96 }; |
| 97 | 97 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 | 172 |
| 173 | 173 |
| 174 // Convenience function aligning an integer. | 174 // Convenience function aligning an integer. |
| 175 static inline uintptr_t Align(uintptr_t x, intptr_t size) { | 175 static inline uintptr_t Align(uintptr_t x, intptr_t size) { |
| 176 // size is a power of 2 | 176 // size is a power of 2 |
| 177 ASSERT((size & (size-1)) == 0); | 177 ASSERT((size & (size-1)) == 0); |
| 178 return (x + (size-1)) & ~(size-1); | 178 return (x + (size-1)) & ~(size-1); |
| 179 } | 179 } |
| 180 | 180 |
| 181 | 181 |
| 182 // Convenience function writing a single byte to a ByteArray. | 182 // Convenience function writing a single byte to a ByteVector. |
| 183 static inline void WriteByte(ByteArray* buf, uint8_t byte) { | 183 static inline void WriteByte(ByteVector* buf, uint8_t byte) { |
| 184 buf->Add(byte); | 184 buf->Add(byte); |
| 185 } | 185 } |
| 186 | 186 |
| 187 | 187 |
| 188 // Convenience function writing an unsigned native word to a ByteArray. | 188 // Convenience function writing an unsigned native word to a ByteVector. |
| 189 // The word is 32-bit wide in 32-bit mode and 64-bit wide in 64-bit mode. | 189 // 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) { | 190 static inline void WriteWord(ByteVector* buf, uword word) { |
| 191 uint8_t* p = reinterpret_cast<uint8_t*>(&word); | 191 uint8_t* p = reinterpret_cast<uint8_t*>(&word); |
| 192 for (size_t i = 0; i < sizeof(word); i++) { | 192 for (size_t i = 0; i < sizeof(word); i++) { |
| 193 buf->Add(p[i]); | 193 buf->Add(p[i]); |
| 194 } | 194 } |
| 195 } | 195 } |
| 196 | 196 |
| 197 static inline void WriteInt(ByteArray* buf, int word) { | 197 static inline void WriteInt(ByteVector* buf, int word) { |
| 198 uint8_t* p = reinterpret_cast<uint8_t*>(&word); | 198 uint8_t* p = reinterpret_cast<uint8_t*>(&word); |
| 199 for (size_t i = 0; i < sizeof(word); i++) { | 199 for (size_t i = 0; i < sizeof(word); i++) { |
| 200 buf->Add(p[i]); | 200 buf->Add(p[i]); |
| 201 } | 201 } |
| 202 } | 202 } |
| 203 | 203 |
| 204 static inline void WriteShort(ByteArray* buf, uint16_t word) { | 204 static inline void WriteShort(ByteVector* buf, uint16_t word) { |
| 205 uint8_t* p = reinterpret_cast<uint8_t*>(&word); | 205 uint8_t* p = reinterpret_cast<uint8_t*>(&word); |
| 206 for (size_t i = 0; i < sizeof(word); i++) { | 206 for (size_t i = 0; i < sizeof(word); i++) { |
| 207 buf->Add(p[i]); | 207 buf->Add(p[i]); |
| 208 } | 208 } |
| 209 } | 209 } |
| 210 | 210 |
| 211 static inline void WriteString(ByteArray* buf, const char* str) { | 211 static inline void WriteString(ByteVector* buf, const char* str) { |
| 212 for (size_t i = 0; i < strlen(str); i++) { | 212 for (size_t i = 0; i < strlen(str); i++) { |
| 213 buf->Add(static_cast<uint8_t>(str[i])); | 213 buf->Add(static_cast<uint8_t>(str[i])); |
| 214 } | 214 } |
| 215 } | 215 } |
| 216 | 216 |
| 217 static inline void Write(ByteArray* buf, const void* mem, int length) { | 217 static inline void Write(ByteVector* buf, const void* mem, int length) { |
| 218 const uint8_t* p = reinterpret_cast<const uint8_t*>(mem); | 218 const uint8_t* p = reinterpret_cast<const uint8_t*>(mem); |
| 219 for (int i = 0; i < length; i++) { | 219 for (int i = 0; i < length; i++) { |
| 220 buf->Add(p[i]); | 220 buf->Add(p[i]); |
| 221 } | 221 } |
| 222 } | 222 } |
| 223 | 223 |
| 224 | 224 |
| 225 // Write given section to file and return written size. | 225 // Write given section to file and return written size. |
| 226 static int WriteSectionToFile(void* handle, const ByteArray& section) { | 226 static int WriteSectionToFile(void* handle, const ByteVector& section) { |
| 227 #if 0 | 227 #if 0 |
| 228 File* fp = reinterpret_cast<File*>(handle); | 228 File* fp = reinterpret_cast<File*>(handle); |
| 229 int size = section.size(); | 229 int size = section.size(); |
| 230 fp->WriteFully(section.data(), size); | 230 fp->WriteFully(section.data(), size); |
| 231 return size; | 231 return size; |
| 232 #else | 232 #else |
| 233 return 0; | 233 return 0; |
| 234 #endif | 234 #endif |
| 235 } | 235 } |
| 236 | 236 |
| 237 | 237 |
| 238 // Pad output file to specified padding size. | 238 // Pad output file to specified padding size. |
| 239 static void PadFile(void* handle, int padding_size) { | 239 static void PadFile(void* handle, int padding_size) { |
| 240 #if 0 | 240 #if 0 |
| 241 File* fp = reinterpret_cast<File*>(handle); | 241 File* fp = reinterpret_cast<File*>(handle); |
| 242 for (int i = 0; i < padding_size; i++) { | 242 for (int i = 0; i < padding_size; i++) { |
| 243 fp->WriteFully("", 1); | 243 fp->WriteFully("", 1); |
| 244 } | 244 } |
| 245 #endif | 245 #endif |
| 246 } | 246 } |
| 247 | 247 |
| 248 | 248 |
| 249 // Write given section to specified memory region and return written size. | 249 // Write given section to specified memory region and return written size. |
| 250 static int WriteSectionToMemory(void* handle, const ByteArray& section) { | 250 static int WriteSectionToMemory(void* handle, const ByteVector& section) { |
| 251 ByteArray* buffer = reinterpret_cast<ByteArray*>(handle); | 251 ByteVector* buffer = reinterpret_cast<ByteVector*>(handle); |
| 252 int size = section.size(); | 252 int size = section.size(); |
| 253 for (int i = 0; i < size; i++) { | 253 for (int i = 0; i < size; i++) { |
| 254 buffer->Add(static_cast<uint8_t>(section.data()[i])); | 254 buffer->Add(static_cast<uint8_t>(section.data()[i])); |
| 255 } | 255 } |
| 256 return size; | 256 return size; |
| 257 } | 257 } |
| 258 | 258 |
| 259 | 259 |
| 260 // Pad memory to specified padding size. | 260 // Pad memory to specified padding size. |
| 261 static void PadMemory(void* handle, int padding_size) { | 261 static void PadMemory(void* handle, int padding_size) { |
| 262 ByteArray* buffer = reinterpret_cast<ByteArray*>(handle); | 262 ByteVector* buffer = reinterpret_cast<ByteVector*>(handle); |
| 263 for (int i = 0; i < padding_size; i++) { | 263 for (int i = 0; i < padding_size; i++) { |
| 264 buffer->Add(static_cast<uint8_t>(0)); | 264 buffer->Add(static_cast<uint8_t>(0)); |
| 265 } | 265 } |
| 266 } | 266 } |
| 267 | 267 |
| 268 | 268 |
| 269 // Constructor | 269 // Constructor |
| 270 ElfGen::ElfGen() | 270 ElfGen::ElfGen() |
| 271 : text_vma_(0), text_size_(0), text_padding_(0), map_offset_(0), lock_() { | 271 : text_vma_(0), text_size_(0), text_padding_(0), map_offset_(0), lock_() { |
| 272 for (int i = 0; i < kNumSections; i++) { | 272 for (int i = 0; i < kNumSections; i++) { |
| 273 ASSERT(section_attr[i].shndx == i); // Verify layout of sections. | 273 ASSERT(section_attr[i].shndx == i); // Verify layout of sections. |
| 274 section_name_[i] = AddSectionName(section_attr[i].name); | 274 section_name_[i] = AddSectionName(section_attr[i].name); |
| 275 } | 275 } |
| 276 // Section header string table always starts with an empty string, which is | 276 // Section header string table always starts with an empty string, which is |
| 277 // the name of the kUndef section. | 277 // the name of the kUndef section. |
| 278 ASSERT((section_attr[0].name[0] == '\0') && (section_name_[0] == 0)); | 278 ASSERT((section_attr[0].name[0] == '\0') && (section_name_[0] == 0)); |
| 279 | 279 |
| 280 // String table always starts with an empty string. | 280 // String table always starts with an empty string. |
| 281 AddName(""); | 281 AddName(""); |
| 282 ASSERT(section_buf_[kStrtab].size() == 1); | 282 ASSERT(section_buf_[kStrtab].size() == 1); |
| 283 | 283 |
| 284 // Symbol at index 0 in symtab is always STN_UNDEF (all zero): | 284 // Symbol at index 0 in symtab is always STN_UNDEF (all zero): |
| 285 ByteArray* symtab = §ion_buf_[kSymtab]; | 285 ByteVector* symtab = §ion_buf_[kSymtab]; |
| 286 while (symtab->size() < kSymbolSize) { | 286 while (symtab->size() < kSymbolSize) { |
| 287 WriteInt(symtab, 0); | 287 WriteInt(symtab, 0); |
| 288 } | 288 } |
| 289 ASSERT(symtab->size() == kSymbolSize); | 289 ASSERT(symtab->size() == kSymbolSize); |
| 290 } | 290 } |
| 291 | 291 |
| 292 | 292 |
| 293 // Destructor | 293 // Destructor |
| 294 ElfGen::~ElfGen() { | 294 ElfGen::~ElfGen() { |
| 295 } | 295 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 320 MutexLocker ml(&lock_); | 320 MutexLocker ml(&lock_); |
| 321 AddFunction(name, pc, size); | 321 AddFunction(name, pc, size); |
| 322 char end_name[256]; | 322 char end_name[256]; |
| 323 OS::SNPrint(end_name, sizeof(end_name), "%s_end", name); | 323 OS::SNPrint(end_name, sizeof(end_name), "%s_end", name); |
| 324 AddFunction(end_name, pc + size, 0); | 324 AddFunction(end_name, pc + size, 0); |
| 325 } | 325 } |
| 326 | 326 |
| 327 | 327 |
| 328 int ElfGen::AddFunction(const char* name, uword pc, intptr_t size) { | 328 int ElfGen::AddFunction(const char* name, uword pc, intptr_t size) { |
| 329 ASSERT(text_vma_ != 0); // code must have been added | 329 ASSERT(text_vma_ != 0); // code must have been added |
| 330 ByteArray* symtab = §ion_buf_[kSymtab]; | 330 ByteVector* symtab = §ion_buf_[kSymtab]; |
| 331 const int beg = symtab->size(); | 331 const int beg = symtab->size(); |
| 332 WriteInt(symtab, AddName(name)); // st_name | 332 WriteInt(symtab, AddName(name)); // st_name |
| 333 #if defined(TARGET_ARCH_X64) | 333 #if defined(TARGET_ARCH_X64) |
| 334 WriteShort(symtab, (kSTB_LOCAL << 4) + kSTT_FUNC); // st_info + (st_other<<8) | 334 WriteShort(symtab, (kSTB_LOCAL << 4) + kSTT_FUNC); // st_info + (st_other<<8) |
| 335 WriteShort(symtab, kText); // st_shndx | 335 WriteShort(symtab, kText); // st_shndx |
| 336 #endif | 336 #endif |
| 337 WriteWord(symtab, pc); // st_value | 337 WriteWord(symtab, pc); // st_value |
| 338 WriteWord(symtab, size); // st_size | 338 WriteWord(symtab, size); // st_size |
| 339 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) | 339 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) |
| 340 // st_info + (st_other<<8) | 340 // st_info + (st_other<<8) |
| 341 WriteShort(symtab, (kSTB_EXPORTED << 4) + kSTT_FUNC); | 341 WriteShort(symtab, (kSTB_EXPORTED << 4) + kSTT_FUNC); |
| 342 WriteShort(symtab, kText); // st_shndx | 342 WriteShort(symtab, kText); // st_shndx |
| 343 #endif | 343 #endif |
| 344 ASSERT(symtab->size() - beg == kSymbolSize); | 344 ASSERT(symtab->size() - beg == kSymbolSize); |
| 345 return beg / kSymbolSize; // symbol index in symtab | 345 return beg / kSymbolSize; // symbol index in symtab |
| 346 } | 346 } |
| 347 | 347 |
| 348 | 348 |
| 349 bool ElfGen::WriteToFile(File* handle) { | 349 bool ElfGen::WriteToFile(File* handle) { |
| 350 return WriteOutput(handle, WriteSectionToFile, PadFile); | 350 return WriteOutput(handle, WriteSectionToFile, PadFile); |
| 351 } | 351 } |
| 352 | 352 |
| 353 | 353 |
| 354 bool ElfGen::WriteToMemory(ByteArray* region) { | 354 bool ElfGen::WriteToMemory(ByteVector* region) { |
| 355 return WriteOutput(region, WriteSectionToMemory, PadMemory); | 355 return WriteOutput(region, WriteSectionToMemory, PadMemory); |
| 356 } | 356 } |
| 357 | 357 |
| 358 | 358 |
| 359 int ElfGen::AddString(ByteArray* buf, const char* str) { | 359 int ElfGen::AddString(ByteVector* buf, const char* str) { |
| 360 const int str_index = buf->size(); | 360 const int str_index = buf->size(); |
| 361 WriteString(buf, str); | 361 WriteString(buf, str); |
| 362 WriteByte(buf, 0); // terminating '\0' | 362 WriteByte(buf, 0); // terminating '\0' |
| 363 return str_index; | 363 return str_index; |
| 364 } | 364 } |
| 365 | 365 |
| 366 | 366 |
| 367 int ElfGen::AddSectionName(const char* str) { | 367 int ElfGen::AddSectionName(const char* str) { |
| 368 return AddString(§ion_buf_[kShStrtab], str); | 368 return AddString(§ion_buf_[kShStrtab], str); |
| 369 } | 369 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 WriteInt(&sheaders_, 0); | 423 WriteInt(&sheaders_, 0); |
| 424 WriteWord(&sheaders_, section_attr[section].sh_addralign); | 424 WriteWord(&sheaders_, section_attr[section].sh_addralign); |
| 425 WriteWord(&sheaders_, section_attr[section].sh_entsize); | 425 WriteWord(&sheaders_, section_attr[section].sh_entsize); |
| 426 ASSERT(sheaders_.size() == kSectionHeaderEntrySize * (section + 1)); | 426 ASSERT(sheaders_.size() == kSectionHeaderEntrySize * (section + 1)); |
| 427 } | 427 } |
| 428 | 428 |
| 429 | 429 |
| 430 // Pads the given section with zero bytes for the given aligment, assuming the | 430 // 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 | 431 // section starts at given file offset; returns file offset after padded |
| 432 // section. | 432 // section. |
| 433 int ElfGen::PadSection(ByteArray* section, int offset, int alignment) { | 433 int ElfGen::PadSection(ByteVector* section, int offset, int alignment) { |
| 434 offset += section->size(); | 434 offset += section->size(); |
| 435 int aligned_offset = Align(offset, alignment); | 435 int aligned_offset = Align(offset, alignment); |
| 436 while (offset++ < aligned_offset) { | 436 while (offset++ < aligned_offset) { |
| 437 WriteByte(section, 0); // one byte padding. | 437 WriteByte(section, 0); // one byte padding. |
| 438 } | 438 } |
| 439 return aligned_offset; | 439 return aligned_offset; |
| 440 } | 440 } |
| 441 | 441 |
| 442 | 442 |
| 443 bool ElfGen::WriteOutput(void* handle, | 443 bool ElfGen::WriteOutput(void* handle, |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 elf_gen->AddCode(pc, size); | 503 elf_gen->AddCode(pc, size); |
| 504 } | 504 } |
| 505 | 505 |
| 506 | 506 |
| 507 void DebugInfo::AddCodeRegion(const char* name, uword pc, intptr_t size) { | 507 void DebugInfo::AddCodeRegion(const char* name, uword pc, intptr_t size) { |
| 508 ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_); | 508 ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_); |
| 509 elf_gen->AddCodeRegion(name, pc, size); | 509 elf_gen->AddCodeRegion(name, pc, size); |
| 510 } | 510 } |
| 511 | 511 |
| 512 | 512 |
| 513 bool DebugInfo::WriteToMemory(ByteArray* region) { | 513 bool DebugInfo::WriteToMemory(ByteVector* region) { |
| 514 ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_); | 514 ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_); |
| 515 return elf_gen->WriteToMemory(region); | 515 return elf_gen->WriteToMemory(region); |
| 516 } | 516 } |
| 517 | 517 |
| 518 | 518 |
| 519 DebugInfo* DebugInfo::NewGenerator() { | 519 DebugInfo* DebugInfo::NewGenerator() { |
| 520 return new DebugInfo(); | 520 return new DebugInfo(); |
| 521 } | 521 } |
| 522 | 522 |
| 523 | 523 |
| 524 void DebugInfo::RegisterSection(const char* name, | 524 void DebugInfo::RegisterSection(const char* name, |
| 525 uword entry_point, | 525 uword entry_point, |
| 526 intptr_t size) { | 526 intptr_t size) { |
| 527 ElfGen* elf_section = new ElfGen(); | 527 ElfGen* elf_section = new ElfGen(); |
| 528 ASSERT(elf_section != NULL); | 528 ASSERT(elf_section != NULL); |
| 529 elf_section->AddCode(entry_point, size); | 529 elf_section->AddCode(entry_point, size); |
| 530 elf_section->AddCodeRegion(name, entry_point, size); | 530 elf_section->AddCodeRegion(name, entry_point, size); |
| 531 | 531 |
| 532 ByteArray* dynamic_region = new ByteArray(); | 532 ByteVector* dynamic_region = new ByteVector(); |
| 533 ASSERT(dynamic_region != NULL); | 533 ASSERT(dynamic_region != NULL); |
| 534 | 534 |
| 535 elf_section->WriteToMemory(dynamic_region); | 535 elf_section->WriteToMemory(dynamic_region); |
| 536 | 536 |
| 537 ::addDynamicSection(reinterpret_cast<const char*>(dynamic_region->data()), | 537 ::addDynamicSection(reinterpret_cast<const char*>(dynamic_region->data()), |
| 538 dynamic_region->size()); | 538 dynamic_region->size()); |
| 539 dynamic_region->set_data(NULL); | 539 dynamic_region->set_data(NULL); |
| 540 delete dynamic_region; | 540 delete dynamic_region; |
| 541 delete elf_section; | 541 delete elf_section; |
| 542 } | 542 } |
| 543 | 543 |
| 544 | 544 |
| 545 void DebugInfo::UnregisterAllSections() { | 545 void DebugInfo::UnregisterAllSections() { |
| 546 ::deleteDynamicSections(); | 546 ::deleteDynamicSections(); |
| 547 } | 547 } |
| 548 | 548 |
| 549 } // namespace dart | 549 } // namespace dart |
| OLD | NEW |