blob: 379186a2352ebf1e085294d04b24bae7d37ce8d2 [file] [log] [blame]
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001//===-- ObjectFileELF.cpp ------------------------------------- -*- C++ -*-===//
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ObjectFileELF.h"
11
Stephen Wilsonf325ba92010-07-13 23:07:23 +000012#include <cassert>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000013#include <algorithm>
14
Stephen Wilson2ab0a582011-01-15 00:08:44 +000015#include "lldb/Core/ArchSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/DataBuffer.h"
17#include "lldb/Core/Error.h"
Stephen Wilsonf325ba92010-07-13 23:07:23 +000018#include "lldb/Core/FileSpecList.h"
Jim Ingham672e6f52011-03-07 23:44:08 +000019#include "lldb/Core/Module.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020#include "lldb/Core/PluginManager.h"
21#include "lldb/Core/Section.h"
22#include "lldb/Core/Stream.h"
Jim Ingham672e6f52011-03-07 23:44:08 +000023#include "lldb/Symbol/SymbolContext.h"
Greg Clayton64195a22011-02-23 00:35:02 +000024#include "lldb/Host/Host.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025
Stephen Wilsonf325ba92010-07-13 23:07:23 +000026#define CASE_AND_STREAM(s, def, width) \
27 case def: s->Printf("%-*s", width, #def); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029using namespace lldb;
30using namespace lldb_private;
Stephen Wilsonf325ba92010-07-13 23:07:23 +000031using namespace elf;
32using namespace llvm::ELF;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033
Stephen Wilsonf325ba92010-07-13 23:07:23 +000034//------------------------------------------------------------------
35// Static methods.
36//------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037void
38ObjectFileELF::Initialize()
39{
Stephen Wilsonf325ba92010-07-13 23:07:23 +000040 PluginManager::RegisterPlugin(GetPluginNameStatic(),
41 GetPluginDescriptionStatic(),
42 CreateInstance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043}
44
45void
46ObjectFileELF::Terminate()
47{
Stephen Wilsonf325ba92010-07-13 23:07:23 +000048 PluginManager::UnregisterPlugin(CreateInstance);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049}
50
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051const char *
52ObjectFileELF::GetPluginNameStatic()
53{
Stephen Wilsonf325ba92010-07-13 23:07:23 +000054 return "object-file.elf";
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055}
56
57const char *
58ObjectFileELF::GetPluginDescriptionStatic()
59{
Stephen Wilsonf325ba92010-07-13 23:07:23 +000060 return "ELF object file reader.";
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061}
62
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063ObjectFile *
Stephen Wilsonf325ba92010-07-13 23:07:23 +000064ObjectFileELF::CreateInstance(Module *module,
65 DataBufferSP &data_sp,
66 const FileSpec *file, addr_t offset,
67 addr_t length)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068{
Stephen Wilsonf325ba92010-07-13 23:07:23 +000069 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + offset))
Chris Lattner30fdc8d2010-06-08 16:52:24 +000070 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +000071 const uint8_t *magic = data_sp->GetBytes() + offset;
72 if (ELFHeader::MagicBytesMatch(magic))
73 {
74 unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
75 if (address_size == 4 || address_size == 8)
76 {
Stephen Wilson2ab0a582011-01-15 00:08:44 +000077 std::auto_ptr<ObjectFileELF> objfile_ap(
Stephen Wilsonf325ba92010-07-13 23:07:23 +000078 new ObjectFileELF(module, data_sp, file, offset, length));
Stephen Wilson3f4200fd2011-02-24 19:16:15 +000079 ArchSpec spec;
80 if (objfile_ap->GetArchitecture(spec) &&
81 objfile_ap->SetModulesArchitecture(spec))
Stephen Wilsonf325ba92010-07-13 23:07:23 +000082 return objfile_ap.release();
83 }
84 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000085 }
86 return NULL;
87}
88
Stephen Wilson2ab0a582011-01-15 00:08:44 +000089
Stephen Wilsonf325ba92010-07-13 23:07:23 +000090//------------------------------------------------------------------
91// PluginInterface protocol
92//------------------------------------------------------------------
93const char *
94ObjectFileELF::GetPluginName()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000095{
Stephen Wilsonf325ba92010-07-13 23:07:23 +000096 return "ObjectFileELF";
Chris Lattner30fdc8d2010-06-08 16:52:24 +000097}
98
Stephen Wilsonf325ba92010-07-13 23:07:23 +000099const char *
100ObjectFileELF::GetShortPluginName()
101{
102 return GetPluginNameStatic();
103}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000104
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000105uint32_t
106ObjectFileELF::GetPluginVersion()
107{
108 return m_plugin_version;
109}
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000110//------------------------------------------------------------------
111// ObjectFile protocol
112//------------------------------------------------------------------
113
114ObjectFileELF::ObjectFileELF(Module* module, DataBufferSP& dataSP,
115 const FileSpec* file, addr_t offset,
116 addr_t length)
117 : ObjectFile(module, file, offset, length, dataSP),
118 m_header(),
119 m_program_headers(),
120 m_section_headers(),
121 m_sections_ap(),
122 m_symtab_ap(),
123 m_filespec_ap(),
124 m_shstr_data()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000125{
126 if (file)
127 m_file = *file;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000128 ::memset(&m_header, 0, sizeof(m_header));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000129}
130
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131ObjectFileELF::~ObjectFileELF()
132{
133}
134
Jim Ingham5aee1622010-08-09 23:31:02 +0000135bool
136ObjectFileELF::IsExecutable() const
137{
Stephen Wilson7f3b57c2011-01-15 00:09:50 +0000138 return m_header.e_entry != 0;
Jim Ingham5aee1622010-08-09 23:31:02 +0000139}
140
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000141ByteOrder
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000142ObjectFileELF::GetByteOrder() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000143{
144 if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
145 return eByteOrderBig;
146 if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
147 return eByteOrderLittle;
148 return eByteOrderInvalid;
149}
150
151size_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000152ObjectFileELF::GetAddressByteSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153{
154 return m_data.GetAddressByteSize();
155}
156
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000157unsigned
158ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000160 return std::distance(m_section_headers.begin(), I) + 1;
161}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000163unsigned
164ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
165{
166 return std::distance(m_section_headers.begin(), I) + 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167}
168
169bool
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000170ObjectFileELF::ParseHeader()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000172 uint32_t offset = GetOffset();
173 return m_header.Parse(m_data, &offset);
174}
175
176bool
Greg Clayton60830262011-02-04 18:53:10 +0000177ObjectFileELF::GetUUID(lldb_private::UUID* uuid)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000178{
179 // FIXME: Return MD5 sum here. See comment in ObjectFile.h.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000180 return false;
181}
182
183uint32_t
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000184ObjectFileELF::GetDependentModules(FileSpecList &files)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000186 size_t num_modules = ParseDependentModules();
187 uint32_t num_specs = 0;
188
189 for (unsigned i = 0; i < num_modules; ++i)
190 {
191 if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
192 num_specs++;
193 }
194
195 return num_specs;
196}
197
Stephen Wilson2ab0a582011-01-15 00:08:44 +0000198Address
199ObjectFileELF::GetImageInfoAddress()
200{
201 if (!ParseSectionHeaders())
202 return Address();
203
204 user_id_t dynsym_id = 0;
205 for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
206 sh_pos != m_section_headers.end(); ++sh_pos)
207 {
208 if (sh_pos->sh_type == SHT_DYNAMIC)
209 {
210 dynsym_id = SectionIndex(sh_pos);
211 break;
212 }
213 }
214
215 if (!dynsym_id)
216 return Address();
217
218 SectionList *section_list = GetSectionList();
219 if (!section_list)
220 return Address();
221
222 // Resolve the dynamic table entries.
223 Section *dynsym = section_list->FindSectionByID(dynsym_id).get();
224 if (!dynsym)
225 return Address();
226
227 DataExtractor dynsym_data;
228 if (dynsym->ReadSectionDataFromObjectFile(this, dynsym_data))
229 {
230 ELFDynamic symbol;
231 const unsigned section_size = dynsym_data.GetByteSize();
232 unsigned offset = 0;
233 unsigned cursor = 0;
234
235 // Look for a DT_DEBUG entry.
236 while (cursor < section_size)
237 {
238 offset = cursor;
239 if (!symbol.Parse(dynsym_data, &cursor))
240 break;
241
242 if (symbol.d_tag != DT_DEBUG)
243 continue;
244
245 return Address(dynsym, offset + sizeof(symbol.d_tag));
246 }
247 }
248
249 return Address();
250}
251
Jim Ingham672e6f52011-03-07 23:44:08 +0000252lldb_private::Address
253ObjectFileELF::GetEntryPointAddress ()
254{
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000255 SectionList *sections;
256 addr_t offset;
Jim Ingham672e6f52011-03-07 23:44:08 +0000257
Stephen Wilsond126c8c2011-03-08 04:12:15 +0000258 if (m_entry_point_address.IsValid())
259 return m_entry_point_address;
260
261 if (!ParseHeader() || !IsExecutable())
262 return m_entry_point_address;
263
264 sections = GetSectionList();
265 offset = m_header.e_entry;
266
267 if (!sections)
268 {
269 m_entry_point_address.SetOffset(offset);
270 return m_entry_point_address;
271 }
272
273 m_entry_point_address.ResolveAddressUsingFileSections(offset, sections);
274
275 return m_entry_point_address;
Jim Ingham672e6f52011-03-07 23:44:08 +0000276}
277
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000278//----------------------------------------------------------------------
279// ParseDependentModules
280//----------------------------------------------------------------------
281size_t
282ObjectFileELF::ParseDependentModules()
283{
284 if (m_filespec_ap.get())
285 return m_filespec_ap->GetSize();
286
287 m_filespec_ap.reset(new FileSpecList());
288
289 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
290 return 0;
291
292 // Locate the dynamic table.
293 user_id_t dynsym_id = 0;
294 user_id_t dynstr_id = 0;
Greg Clayton450e3f32010-10-12 02:24:53 +0000295 for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
296 sh_pos != m_section_headers.end(); ++sh_pos)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000297 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000298 if (sh_pos->sh_type == SHT_DYNAMIC)
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000299 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000300 dynsym_id = SectionIndex(sh_pos);
301 dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000302 break;
303 }
304 }
305
306 if (!(dynsym_id && dynstr_id))
307 return 0;
308
309 SectionList *section_list = GetSectionList();
310 if (!section_list)
311 return 0;
312
313 // Resolve and load the dynamic table entries and corresponding string
314 // table.
315 Section *dynsym = section_list->FindSectionByID(dynsym_id).get();
316 Section *dynstr = section_list->FindSectionByID(dynstr_id).get();
317 if (!(dynsym && dynstr))
318 return 0;
319
320 DataExtractor dynsym_data;
321 DataExtractor dynstr_data;
322 if (dynsym->ReadSectionDataFromObjectFile(this, dynsym_data) &&
323 dynstr->ReadSectionDataFromObjectFile(this, dynstr_data))
324 {
325 ELFDynamic symbol;
326 const unsigned section_size = dynsym_data.GetByteSize();
327 unsigned offset = 0;
328
329 // The only type of entries we are concerned with are tagged DT_NEEDED,
330 // yielding the name of a required library.
331 while (offset < section_size)
332 {
333 if (!symbol.Parse(dynsym_data, &offset))
334 break;
335
336 if (symbol.d_tag != DT_NEEDED)
337 continue;
338
339 uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
340 const char *lib_name = dynstr_data.PeekCStr(str_index);
Greg Clayton274060b2010-10-20 20:54:39 +0000341 m_filespec_ap->Append(FileSpec(lib_name, true));
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000342 }
343 }
344
345 return m_filespec_ap->GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000346}
347
348//----------------------------------------------------------------------
349// ParseProgramHeaders
350//----------------------------------------------------------------------
351size_t
352ObjectFileELF::ParseProgramHeaders()
353{
354 // We have already parsed the program headers
355 if (!m_program_headers.empty())
356 return m_program_headers.size();
357
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000358 // If there are no program headers to read we are done.
359 if (m_header.e_phnum == 0)
360 return 0;
361
362 m_program_headers.resize(m_header.e_phnum);
363 if (m_program_headers.size() != m_header.e_phnum)
364 return 0;
365
366 const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
367 const elf_off ph_offset = m_offset + m_header.e_phoff;
368 DataBufferSP buffer_sp(m_file.ReadFileContents(ph_offset, ph_size));
369
370 if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != ph_size)
371 return 0;
372
373 DataExtractor data(buffer_sp, m_data.GetByteOrder(),
374 m_data.GetAddressByteSize());
375
376 uint32_t idx;
377 uint32_t offset;
378 for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000379 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000380 if (m_program_headers[idx].Parse(data, &offset) == false)
381 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382 }
383
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000384 if (idx < m_program_headers.size())
385 m_program_headers.resize(idx);
386
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000387 return m_program_headers.size();
388}
389
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390//----------------------------------------------------------------------
391// ParseSectionHeaders
392//----------------------------------------------------------------------
393size_t
394ObjectFileELF::ParseSectionHeaders()
395{
396 // We have already parsed the section headers
397 if (!m_section_headers.empty())
398 return m_section_headers.size();
399
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000400 // If there are no section headers we are done.
401 if (m_header.e_shnum == 0)
402 return 0;
403
404 m_section_headers.resize(m_header.e_shnum);
405 if (m_section_headers.size() != m_header.e_shnum)
406 return 0;
407
408 const size_t sh_size = m_header.e_shnum * m_header.e_shentsize;
409 const elf_off sh_offset = m_offset + m_header.e_shoff;
410 DataBufferSP buffer_sp(m_file.ReadFileContents(sh_offset, sh_size));
411
412 if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != sh_size)
413 return 0;
414
415 DataExtractor data(buffer_sp,
416 m_data.GetByteOrder(),
417 m_data.GetAddressByteSize());
418
419 uint32_t idx;
420 uint32_t offset;
421 for (idx = 0, offset = 0; idx < m_header.e_shnum; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000423 if (m_section_headers[idx].Parse(data, &offset) == false)
424 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000425 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000426 if (idx < m_section_headers.size())
427 m_section_headers.resize(idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000428
429 return m_section_headers.size();
430}
431
432size_t
433ObjectFileELF::GetSectionHeaderStringTable()
434{
435 if (m_shstr_data.GetByteSize() == 0)
436 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000437 const unsigned strtab_idx = m_header.e_shstrndx;
438
439 if (strtab_idx && strtab_idx < m_section_headers.size())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000440 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000441 const ELFSectionHeader &sheader = m_section_headers[strtab_idx];
442 const size_t byte_size = sheader.sh_size;
443 const Elf64_Off offset = m_offset + sheader.sh_offset;
444 DataBufferSP buffer_sp(m_file.ReadFileContents(offset, byte_size));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000445
446 if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != byte_size)
447 return 0;
448
449 m_shstr_data.SetData(buffer_sp);
450 }
451 }
452 return m_shstr_data.GetByteSize();
453}
454
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000455lldb::user_id_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456ObjectFileELF::GetSectionIndexByName(const char *name)
457{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000458 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
459 return 0;
460
461 // Search the collection of section headers for one with a matching name.
462 for (SectionHeaderCollIter I = m_section_headers.begin();
463 I != m_section_headers.end(); ++I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000464 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000465 const char *sectionName = m_shstr_data.PeekCStr(I->sh_name);
466
467 if (!sectionName)
468 return 0;
469
470 if (strcmp(name, sectionName) != 0)
471 continue;
472
473 return SectionIndex(I);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000474 }
475
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000476 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000477}
478
479SectionList *
480ObjectFileELF::GetSectionList()
481{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000482 if (m_sections_ap.get())
483 return m_sections_ap.get();
484
485 if (ParseSectionHeaders() && GetSectionHeaderStringTable())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000486 {
487 m_sections_ap.reset(new SectionList());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000488
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000489 for (SectionHeaderCollIter I = m_section_headers.begin();
490 I != m_section_headers.end(); ++I)
491 {
492 const ELFSectionHeader &header = *I;
493
494 ConstString name(m_shstr_data.PeekCStr(header.sh_name));
495 uint64_t size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
496
Greg Clayton4ceb9982010-07-21 22:54:26 +0000497 static ConstString g_sect_name_text (".text");
498 static ConstString g_sect_name_data (".data");
499 static ConstString g_sect_name_bss (".bss");
500 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev");
501 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges");
502 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame");
503 static ConstString g_sect_name_dwarf_debug_info (".debug_info");
504 static ConstString g_sect_name_dwarf_debug_line (".debug_line");
505 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc");
506 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo");
507 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames");
508 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes");
509 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
510 static ConstString g_sect_name_dwarf_debug_str (".debug_str");
511 static ConstString g_sect_name_eh_frame (".eh_frame");
512
513 SectionType sect_type = eSectionTypeOther;
514
515 if (name == g_sect_name_text) sect_type = eSectionTypeCode;
516 else if (name == g_sect_name_data) sect_type = eSectionTypeData;
517 else if (name == g_sect_name_bss) sect_type = eSectionTypeZeroFill;
518 else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev;
519 else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges;
520 else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame;
521 else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo;
522 else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine;
523 else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc;
524 else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo;
525 else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames;
526 else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes;
527 else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges;
528 else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr;
529 else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame;
530
531
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000532 SectionSP section(new Section(
Greg Clayton4ceb9982010-07-21 22:54:26 +0000533 0, // Parent section.
534 GetModule(), // Module to which this section belongs.
535 SectionIndex(I), // Section ID.
536 name, // Section name.
537 sect_type, // Section type.
538 header.sh_addr, // VM address.
539 header.sh_size, // VM size in bytes of this section.
540 header.sh_offset, // Offset of this section in the file.
541 size, // Size of the section as found in the file.
542 header.sh_flags)); // Flags for this section.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000543
544 m_sections_ap->AddSection(section);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000545 }
546 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000547
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000548 return m_sections_ap.get();
549}
550
551static void
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000552ParseSymbols(Symtab *symtab, SectionList *section_list,
553 const ELFSectionHeader &symtab_shdr,
554 const DataExtractor &symtab_data,
555 const DataExtractor &strtab_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000556{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000557 ELFSymbol symbol;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000558 uint32_t offset = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000559 const unsigned numSymbols =
560 symtab_data.GetByteSize() / symtab_shdr.sh_entsize;
561
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000562 static ConstString text_section_name(".text");
563 static ConstString init_section_name(".init");
564 static ConstString fini_section_name(".fini");
565 static ConstString ctors_section_name(".ctors");
566 static ConstString dtors_section_name(".dtors");
567
568 static ConstString data_section_name(".data");
569 static ConstString rodata_section_name(".rodata");
570 static ConstString rodata1_section_name(".rodata1");
571 static ConstString data2_section_name(".data1");
572 static ConstString bss_section_name(".bss");
573
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000574 for (unsigned i = 0; i < numSymbols; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000575 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000576 if (symbol.Parse(symtab_data, &offset) == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000577 break;
578
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000579 Section *symbol_section = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000580 SymbolType symbol_type = eSymbolTypeInvalid;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000581 Elf64_Half symbol_idx = symbol.st_shndx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000582
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000583 switch (symbol_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000584 {
585 case SHN_ABS:
586 symbol_type = eSymbolTypeAbsolute;
587 break;
588 case SHN_UNDEF:
589 symbol_type = eSymbolTypeUndefined;
590 break;
591 default:
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000592 symbol_section = section_list->GetSectionAtIndex(symbol_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000593 break;
594 }
595
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000596 switch (symbol.getType())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000597 {
598 default:
599 case STT_NOTYPE:
600 // The symbol's type is not specified.
601 break;
602
603 case STT_OBJECT:
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000604 // The symbol is associated with a data object, such as a variable,
605 // an array, etc.
606 symbol_type = eSymbolTypeData;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607 break;
608
609 case STT_FUNC:
610 // The symbol is associated with a function or other executable code.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000611 symbol_type = eSymbolTypeCode;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000612 break;
613
614 case STT_SECTION:
615 // The symbol is associated with a section. Symbol table entries of
616 // this type exist primarily for relocation and normally have
617 // STB_LOCAL binding.
618 break;
619
620 case STT_FILE:
621 // Conventionally, the symbol's name gives the name of the source
622 // file associated with the object file. A file symbol has STB_LOCAL
623 // binding, its section index is SHN_ABS, and it precedes the other
624 // STB_LOCAL symbols for the file, if it is present.
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000625 symbol_type = eSymbolTypeObjectFile;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000626 break;
627 }
628
629 if (symbol_type == eSymbolTypeInvalid)
630 {
631 if (symbol_section)
632 {
633 const ConstString &sect_name = symbol_section->GetName();
634 if (sect_name == text_section_name ||
635 sect_name == init_section_name ||
636 sect_name == fini_section_name ||
637 sect_name == ctors_section_name ||
638 sect_name == dtors_section_name)
639 {
640 symbol_type = eSymbolTypeCode;
641 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000642 else if (sect_name == data_section_name ||
643 sect_name == data2_section_name ||
644 sect_name == rodata_section_name ||
645 sect_name == rodata1_section_name ||
646 sect_name == bss_section_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000647 {
648 symbol_type = eSymbolTypeData;
649 }
650 }
651 }
652
653 uint64_t symbol_value = symbol.st_value;
654 if (symbol_section != NULL)
655 symbol_value -= symbol_section->GetFileAddress();
656 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000657 bool is_global = symbol.getBinding() == STB_GLOBAL;
658 uint32_t flags = symbol.st_other << 8 | symbol.st_info;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000659
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000660 Symbol dc_symbol(
661 i, // ID is the original symbol table index.
662 symbol_name, // Symbol name.
663 false, // Is the symbol name mangled?
664 symbol_type, // Type of this symbol
665 is_global, // Is this globally visible?
666 false, // Is this symbol debug info?
667 false, // Is this symbol a trampoline?
668 false, // Is this symbol artificial?
669 symbol_section, // Section in which this symbol is defined or null.
670 symbol_value, // Offset in section or symbol value.
671 symbol.st_size, // Size in bytes of this symbol.
672 flags); // Symbol flags.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000673 symtab->AddSymbol(dc_symbol);
674 }
675}
676
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000677void
678ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
679 const ELFSectionHeader &symtab_hdr,
680 user_id_t symtab_id)
681{
682 assert(symtab_hdr.sh_type == SHT_SYMTAB ||
683 symtab_hdr.sh_type == SHT_DYNSYM);
684
685 // Parse in the section list if needed.
686 SectionList *section_list = GetSectionList();
687 if (!section_list)
688 return;
689
690 // Section ID's are ones based.
691 user_id_t strtab_id = symtab_hdr.sh_link + 1;
692
693 Section *symtab = section_list->FindSectionByID(symtab_id).get();
694 Section *strtab = section_list->FindSectionByID(strtab_id).get();
695 if (symtab && strtab)
696 {
697 DataExtractor symtab_data;
698 DataExtractor strtab_data;
699 if (symtab->ReadSectionDataFromObjectFile(this, symtab_data) &&
700 strtab->ReadSectionDataFromObjectFile(this, strtab_data))
701 {
702 ParseSymbols(symbol_table, section_list, symtab_hdr,
703 symtab_data, strtab_data);
704 }
705 }
706}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000707
708Symtab *
709ObjectFileELF::GetSymtab()
710{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000711 if (m_symtab_ap.get())
712 return m_symtab_ap.get();
713
714 Symtab *symbol_table = new Symtab(this);
715 m_symtab_ap.reset(symbol_table);
716
Greg Clayton8087ca22010-10-08 04:20:14 +0000717 Mutex::Locker locker (symbol_table->GetMutex ());
718
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000719 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
720 return symbol_table;
721
722 // Locate and parse all linker symbol tables.
723 for (SectionHeaderCollIter I = m_section_headers.begin();
724 I != m_section_headers.end(); ++I)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000725 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000726 if (I->sh_type == SHT_SYMTAB)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000727 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000728 const ELFSectionHeader &symtab_section = *I;
729 user_id_t section_id = SectionIndex(I);
Greg Clayton8087ca22010-10-08 04:20:14 +0000730 ParseSymbolTable (symbol_table, symtab_section, section_id);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000731 }
732 }
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000733
734 return symbol_table;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000735}
736
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000737//===----------------------------------------------------------------------===//
738// Dump
739//
740// Dump the specifics of the runtime file container (such as any headers
741// segments, sections, etc).
742//----------------------------------------------------------------------
743void
744ObjectFileELF::Dump(Stream *s)
745{
746 DumpELFHeader(s, m_header);
747 s->EOL();
748 DumpELFProgramHeaders(s);
749 s->EOL();
750 DumpELFSectionHeaders(s);
751 s->EOL();
752 SectionList *section_list = GetSectionList();
753 if (section_list)
Greg Clayton10177aa2010-12-08 05:08:21 +0000754 section_list->Dump(s, NULL, true, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000755 Symtab *symtab = GetSymtab();
756 if (symtab)
Greg Claytone0d378b2011-03-24 21:19:54 +0000757 symtab->Dump(s, NULL, eSortOrderNone);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000758 s->EOL();
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000759 DumpDependentModules(s);
760 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000761}
762
763//----------------------------------------------------------------------
764// DumpELFHeader
765//
766// Dump the ELF header to the specified output stream
767//----------------------------------------------------------------------
768void
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000769ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000770{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000771 s->PutCString("ELF Header\n");
772 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
773 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n",
774 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
775 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n",
776 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
777 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n",
778 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000779
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000780 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
781 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000782 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
783 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
784 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
785
786 s->Printf("e_type = 0x%4.4x ", header.e_type);
787 DumpELFHeader_e_type(s, header.e_type);
788 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
789 s->Printf("e_version = 0x%8.8x\n", header.e_version);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000790 s->Printf("e_entry = 0x%8.8lx\n", header.e_entry);
791 s->Printf("e_phoff = 0x%8.8lx\n", header.e_phoff);
792 s->Printf("e_shoff = 0x%8.8lx\n", header.e_shoff);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000793 s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
794 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
795 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
796 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
797 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
798 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
799 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
800}
801
802//----------------------------------------------------------------------
803// DumpELFHeader_e_type
804//
805// Dump an token value for the ELF header member e_type
806//----------------------------------------------------------------------
807void
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000808ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000809{
810 switch (e_type)
811 {
812 case ET_NONE: *s << "ET_NONE"; break;
813 case ET_REL: *s << "ET_REL"; break;
814 case ET_EXEC: *s << "ET_EXEC"; break;
815 case ET_DYN: *s << "ET_DYN"; break;
816 case ET_CORE: *s << "ET_CORE"; break;
817 default:
818 break;
819 }
820}
821
822//----------------------------------------------------------------------
823// DumpELFHeader_e_ident_EI_DATA
824//
825// Dump an token value for the ELF header member e_ident[EI_DATA]
826//----------------------------------------------------------------------
827void
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000828ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000829{
830 switch (ei_data)
831 {
832 case ELFDATANONE: *s << "ELFDATANONE"; break;
833 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break;
834 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break;
835 default:
836 break;
837 }
838}
839
840
841//----------------------------------------------------------------------
842// DumpELFProgramHeader
843//
844// Dump a single ELF program header to the specified output stream
845//----------------------------------------------------------------------
846void
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000847ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000848{
849 DumpELFProgramHeader_p_type(s, ph.p_type);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000850 s->Printf(" %8.8lx %8.8lx %8.8lx", ph.p_offset, ph.p_vaddr, ph.p_paddr);
851 s->Printf(" %8.8lx %8.8lx %8.8lx (", ph.p_filesz, ph.p_memsz, ph.p_flags);
852
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000853 DumpELFProgramHeader_p_flags(s, ph.p_flags);
854 s->Printf(") %8.8x", ph.p_align);
855}
856
857//----------------------------------------------------------------------
858// DumpELFProgramHeader_p_type
859//
860// Dump an token value for the ELF program header member p_type which
861// describes the type of the program header
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000862// ----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000863void
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000864ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000865{
866 const int kStrWidth = 10;
867 switch (p_type)
868 {
869 CASE_AND_STREAM(s, PT_NULL , kStrWidth);
870 CASE_AND_STREAM(s, PT_LOAD , kStrWidth);
871 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth);
872 CASE_AND_STREAM(s, PT_INTERP , kStrWidth);
873 CASE_AND_STREAM(s, PT_NOTE , kStrWidth);
874 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth);
875 CASE_AND_STREAM(s, PT_PHDR , kStrWidth);
876 default:
877 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
878 break;
879 }
880}
881
882
883//----------------------------------------------------------------------
884// DumpELFProgramHeader_p_flags
885//
886// Dump an token value for the ELF program header member p_flags
887//----------------------------------------------------------------------
888void
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000889ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000890{
891 *s << ((p_flags & PF_X) ? "PF_X" : " ")
892 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
893 << ((p_flags & PF_W) ? "PF_W" : " ")
894 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
895 << ((p_flags & PF_R) ? "PF_R" : " ");
896}
897
898//----------------------------------------------------------------------
899// DumpELFProgramHeaders
900//
901// Dump all of the ELF program header to the specified output stream
902//----------------------------------------------------------------------
903void
904ObjectFileELF::DumpELFProgramHeaders(Stream *s)
905{
906 if (ParseProgramHeaders())
907 {
908 s->PutCString("Program Headers\n");
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000909 s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
910 "p_filesz p_memsz p_flags p_align\n");
911 s->PutCString("==== ---------- -------- -------- -------- "
912 "-------- -------- ------------------------- --------\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000913
914 uint32_t idx = 0;
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000915 for (ProgramHeaderCollConstIter I = m_program_headers.begin();
916 I != m_program_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000917 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000918 s->Printf("[%2u] ", idx);
919 ObjectFileELF::DumpELFProgramHeader(s, *I);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000920 s->EOL();
921 }
922 }
923}
924
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000925//----------------------------------------------------------------------
926// DumpELFSectionHeader
927//
928// Dump a single ELF section header to the specified output stream
929//----------------------------------------------------------------------
930void
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000931ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeader &sh)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000932{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000933 s->Printf("%8.8x ", sh.sh_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000934 DumpELFSectionHeader_sh_type(s, sh.sh_type);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000935 s->Printf(" %8.8lx (", sh.sh_flags);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000936 DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000937 s->Printf(") %8.8lx %8.8lx %8.8lx", sh.sh_addr, sh.sh_offset, sh.sh_size);
938 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
939 s->Printf(" %8.8lx %8.8lx", sh.sh_addralign, sh.sh_entsize);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000940}
941
942//----------------------------------------------------------------------
943// DumpELFSectionHeader_sh_type
944//
945// Dump an token value for the ELF section header member sh_type which
946// describes the type of the section
947//----------------------------------------------------------------------
948void
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000949ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000950{
951 const int kStrWidth = 12;
952 switch (sh_type)
953 {
954 CASE_AND_STREAM(s, SHT_NULL , kStrWidth);
955 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
956 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth);
957 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth);
958 CASE_AND_STREAM(s, SHT_RELA , kStrWidth);
959 CASE_AND_STREAM(s, SHT_HASH , kStrWidth);
960 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth);
961 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth);
962 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth);
963 CASE_AND_STREAM(s, SHT_REL , kStrWidth);
964 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth);
965 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth);
966 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth);
967 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth);
968 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth);
969 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth);
970 default:
971 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
972 break;
973 }
974}
975
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000976//----------------------------------------------------------------------
977// DumpELFSectionHeader_sh_flags
978//
979// Dump an token value for the ELF section header member sh_flags
980//----------------------------------------------------------------------
981void
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000982ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_word sh_flags)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000983{
984 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
985 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
986 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
987 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
988 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
989}
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000990
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000991//----------------------------------------------------------------------
992// DumpELFSectionHeaders
993//
994// Dump all of the ELF section header to the specified output stream
995//----------------------------------------------------------------------
996void
997ObjectFileELF::DumpELFSectionHeaders(Stream *s)
998{
Stephen Wilsonf325ba92010-07-13 23:07:23 +0000999 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
1000 return;
1001
1002 s->PutCString("Section Headers\n");
1003 s->PutCString("IDX name type flags "
1004 "addr offset size link info addralgn "
1005 "entsize Name\n");
1006 s->PutCString("==== -------- ------------ -------------------------------- "
1007 "-------- -------- -------- -------- -------- -------- "
1008 "-------- ====================\n");
1009
1010 uint32_t idx = 0;
1011 for (SectionHeaderCollConstIter I = m_section_headers.begin();
1012 I != m_section_headers.end(); ++I, ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001013 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001014 s->Printf("[%2u] ", idx);
1015 ObjectFileELF::DumpELFSectionHeader(s, *I);
1016 const char* section_name = m_shstr_data.PeekCStr(I->sh_name);
1017 if (section_name)
1018 *s << ' ' << section_name << "\n";
1019 }
1020}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001021
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001022void
1023ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
1024{
1025 size_t num_modules = ParseDependentModules();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001026
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001027 if (num_modules > 0)
1028 {
1029 s->PutCString("Dependent Modules:\n");
1030 for (unsigned i = 0; i < num_modules; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001031 {
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001032 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
1033 s->Printf(" %s\n", spec.GetFilename().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001034 }
1035 }
1036}
1037
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001038bool
Greg Clayton514487e2011-02-15 21:59:32 +00001039ObjectFileELF::GetArchitecture (ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001040{
Stephen Wilson3f4200fd2011-02-24 19:16:15 +00001041 if (!ParseHeader())
1042 return false;
1043
Greg Claytone0d378b2011-03-24 21:19:54 +00001044 arch.SetArchitecture (eArchTypeELF, m_header.e_machine, LLDB_INVALID_CPUTYPE);
Greg Clayton64195a22011-02-23 00:35:02 +00001045 arch.GetTriple().setOSName (Host::GetOSString().GetCString());
1046 arch.GetTriple().setVendorName(Host::GetVendorString().GetCString());
Stephen Wilsonf325ba92010-07-13 23:07:23 +00001047 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001048}
1049