blob: 85c337f7ae19f54ac20b68341608db01a4859b4f [file] [log] [blame]
Stephen Wilsonddd29622010-07-13 23:07:23 +00001//===-- ObjectFileELF.cpp ------------------------------------- -*- C++ -*-===//
Chris Lattner24943d22010-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 Wilsonddd29622010-07-13 23:07:23 +000012#include <cassert>
Chris Lattner24943d22010-06-08 16:52:24 +000013#include <algorithm>
14
Chris Lattner24943d22010-06-08 16:52:24 +000015#include "lldb/Core/DataBuffer.h"
16#include "lldb/Core/Error.h"
Stephen Wilsonddd29622010-07-13 23:07:23 +000017#include "lldb/Core/FileSpecList.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/Core/PluginManager.h"
19#include "lldb/Core/Section.h"
20#include "lldb/Core/Stream.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021
Stephen Wilsonddd29622010-07-13 23:07:23 +000022#define CASE_AND_STREAM(s, def, width) \
23 case def: s->Printf("%-*s", width, #def); break;
Chris Lattner24943d22010-06-08 16:52:24 +000024
Chris Lattner24943d22010-06-08 16:52:24 +000025using namespace lldb;
26using namespace lldb_private;
Stephen Wilsonddd29622010-07-13 23:07:23 +000027using namespace elf;
28using namespace llvm::ELF;
Chris Lattner24943d22010-06-08 16:52:24 +000029
Stephen Wilsonddd29622010-07-13 23:07:23 +000030//------------------------------------------------------------------
31// Static methods.
32//------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +000033void
34ObjectFileELF::Initialize()
35{
Stephen Wilsonddd29622010-07-13 23:07:23 +000036 PluginManager::RegisterPlugin(GetPluginNameStatic(),
37 GetPluginDescriptionStatic(),
38 CreateInstance);
Chris Lattner24943d22010-06-08 16:52:24 +000039}
40
41void
42ObjectFileELF::Terminate()
43{
Stephen Wilsonddd29622010-07-13 23:07:23 +000044 PluginManager::UnregisterPlugin(CreateInstance);
Chris Lattner24943d22010-06-08 16:52:24 +000045}
46
Chris Lattner24943d22010-06-08 16:52:24 +000047const char *
48ObjectFileELF::GetPluginNameStatic()
49{
Stephen Wilsonddd29622010-07-13 23:07:23 +000050 return "object-file.elf";
Chris Lattner24943d22010-06-08 16:52:24 +000051}
52
53const char *
54ObjectFileELF::GetPluginDescriptionStatic()
55{
Stephen Wilsonddd29622010-07-13 23:07:23 +000056 return "ELF object file reader.";
Chris Lattner24943d22010-06-08 16:52:24 +000057}
58
Chris Lattner24943d22010-06-08 16:52:24 +000059ObjectFile *
Stephen Wilsonddd29622010-07-13 23:07:23 +000060ObjectFileELF::CreateInstance(Module *module,
61 DataBufferSP &data_sp,
62 const FileSpec *file, addr_t offset,
63 addr_t length)
Chris Lattner24943d22010-06-08 16:52:24 +000064{
Stephen Wilsonddd29622010-07-13 23:07:23 +000065 if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + offset))
Chris Lattner24943d22010-06-08 16:52:24 +000066 {
Stephen Wilsonddd29622010-07-13 23:07:23 +000067 const uint8_t *magic = data_sp->GetBytes() + offset;
68 if (ELFHeader::MagicBytesMatch(magic))
69 {
70 unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
71 if (address_size == 4 || address_size == 8)
72 {
73 std::auto_ptr<ObjectFile> objfile_ap(
74 new ObjectFileELF(module, data_sp, file, offset, length));
75 if (objfile_ap->ParseHeader())
76 return objfile_ap.release();
77 }
78 }
Chris Lattner24943d22010-06-08 16:52:24 +000079 }
80 return NULL;
81}
82
Stephen Wilsonddd29622010-07-13 23:07:23 +000083//------------------------------------------------------------------
84// PluginInterface protocol
85//------------------------------------------------------------------
86const char *
87ObjectFileELF::GetPluginName()
Chris Lattner24943d22010-06-08 16:52:24 +000088{
Stephen Wilsonddd29622010-07-13 23:07:23 +000089 return "ObjectFileELF";
Chris Lattner24943d22010-06-08 16:52:24 +000090}
91
Stephen Wilsonddd29622010-07-13 23:07:23 +000092const char *
93ObjectFileELF::GetShortPluginName()
94{
95 return GetPluginNameStatic();
96}
Chris Lattner24943d22010-06-08 16:52:24 +000097
Stephen Wilsonddd29622010-07-13 23:07:23 +000098uint32_t
99ObjectFileELF::GetPluginVersion()
100{
101 return m_plugin_version;
102}
103
104void
105ObjectFileELF::GetPluginCommandHelp(const char *command, Stream *strm)
106{
107}
108
109Error
110ObjectFileELF::ExecutePluginCommand(Args &command, Stream *strm)
111{
112 Error error;
113 error.SetErrorString("No plug-in commands are currently supported.");
114 return error;
115}
116
117Log *
118ObjectFileELF::EnablePluginLogging(Stream *strm, Args &command)
119{
120 return NULL;
121}
122
123//------------------------------------------------------------------
124// ObjectFile protocol
125//------------------------------------------------------------------
126
127ObjectFileELF::ObjectFileELF(Module* module, DataBufferSP& dataSP,
128 const FileSpec* file, addr_t offset,
129 addr_t length)
130 : ObjectFile(module, file, offset, length, dataSP),
131 m_header(),
132 m_program_headers(),
133 m_section_headers(),
134 m_sections_ap(),
135 m_symtab_ap(),
136 m_filespec_ap(),
137 m_shstr_data()
Chris Lattner24943d22010-06-08 16:52:24 +0000138{
139 if (file)
140 m_file = *file;
Stephen Wilsonddd29622010-07-13 23:07:23 +0000141 ::memset(&m_header, 0, sizeof(m_header));
Chris Lattner24943d22010-06-08 16:52:24 +0000142}
143
Chris Lattner24943d22010-06-08 16:52:24 +0000144ObjectFileELF::~ObjectFileELF()
145{
146}
147
Jim Ingham7508e732010-08-09 23:31:02 +0000148bool
149ObjectFileELF::IsExecutable() const
150{
Jim Ingham1240b912010-08-10 01:36:46 +0000151 return m_header.e_type == ET_EXEC;
Jim Ingham7508e732010-08-09 23:31:02 +0000152}
153
Chris Lattner24943d22010-06-08 16:52:24 +0000154ByteOrder
Stephen Wilsonddd29622010-07-13 23:07:23 +0000155ObjectFileELF::GetByteOrder() const
Chris Lattner24943d22010-06-08 16:52:24 +0000156{
157 if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
158 return eByteOrderBig;
159 if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
160 return eByteOrderLittle;
161 return eByteOrderInvalid;
162}
163
164size_t
Stephen Wilsonddd29622010-07-13 23:07:23 +0000165ObjectFileELF::GetAddressByteSize() const
Chris Lattner24943d22010-06-08 16:52:24 +0000166{
167 return m_data.GetAddressByteSize();
168}
169
Stephen Wilsonddd29622010-07-13 23:07:23 +0000170unsigned
171ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
Chris Lattner24943d22010-06-08 16:52:24 +0000172{
Stephen Wilsonddd29622010-07-13 23:07:23 +0000173 return std::distance(m_section_headers.begin(), I) + 1;
174}
Chris Lattner24943d22010-06-08 16:52:24 +0000175
Stephen Wilsonddd29622010-07-13 23:07:23 +0000176unsigned
177ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
178{
179 return std::distance(m_section_headers.begin(), I) + 1;
Chris Lattner24943d22010-06-08 16:52:24 +0000180}
181
182bool
Stephen Wilsonddd29622010-07-13 23:07:23 +0000183ObjectFileELF::ParseHeader()
Chris Lattner24943d22010-06-08 16:52:24 +0000184{
Stephen Wilsonddd29622010-07-13 23:07:23 +0000185 uint32_t offset = GetOffset();
186 return m_header.Parse(m_data, &offset);
187}
188
189bool
190ObjectFileELF::GetUUID(UUID* uuid)
191{
192 // FIXME: Return MD5 sum here. See comment in ObjectFile.h.
Chris Lattner24943d22010-06-08 16:52:24 +0000193 return false;
194}
195
196uint32_t
Stephen Wilsonddd29622010-07-13 23:07:23 +0000197ObjectFileELF::GetDependentModules(FileSpecList &files)
Chris Lattner24943d22010-06-08 16:52:24 +0000198{
Stephen Wilsonddd29622010-07-13 23:07:23 +0000199 size_t num_modules = ParseDependentModules();
200 uint32_t num_specs = 0;
201
202 for (unsigned i = 0; i < num_modules; ++i)
203 {
204 if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
205 num_specs++;
206 }
207
208 return num_specs;
209}
210
211//----------------------------------------------------------------------
212// ParseDependentModules
213//----------------------------------------------------------------------
214size_t
215ObjectFileELF::ParseDependentModules()
216{
217 if (m_filespec_ap.get())
218 return m_filespec_ap->GetSize();
219
220 m_filespec_ap.reset(new FileSpecList());
221
222 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
223 return 0;
224
225 // Locate the dynamic table.
226 user_id_t dynsym_id = 0;
227 user_id_t dynstr_id = 0;
Greg Claytonad60bf42010-10-12 02:24:53 +0000228 for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
229 sh_pos != m_section_headers.end(); ++sh_pos)
Stephen Wilsonddd29622010-07-13 23:07:23 +0000230 {
Greg Claytonad60bf42010-10-12 02:24:53 +0000231 if (sh_pos->sh_type == SHT_DYNAMIC)
Stephen Wilsonddd29622010-07-13 23:07:23 +0000232 {
Greg Claytonad60bf42010-10-12 02:24:53 +0000233 dynsym_id = SectionIndex(sh_pos);
234 dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based.
Stephen Wilsonddd29622010-07-13 23:07:23 +0000235 break;
236 }
237 }
238
239 if (!(dynsym_id && dynstr_id))
240 return 0;
241
242 SectionList *section_list = GetSectionList();
243 if (!section_list)
244 return 0;
245
246 // Resolve and load the dynamic table entries and corresponding string
247 // table.
248 Section *dynsym = section_list->FindSectionByID(dynsym_id).get();
249 Section *dynstr = section_list->FindSectionByID(dynstr_id).get();
250 if (!(dynsym && dynstr))
251 return 0;
252
253 DataExtractor dynsym_data;
254 DataExtractor dynstr_data;
255 if (dynsym->ReadSectionDataFromObjectFile(this, dynsym_data) &&
256 dynstr->ReadSectionDataFromObjectFile(this, dynstr_data))
257 {
258 ELFDynamic symbol;
259 const unsigned section_size = dynsym_data.GetByteSize();
260 unsigned offset = 0;
261
262 // The only type of entries we are concerned with are tagged DT_NEEDED,
263 // yielding the name of a required library.
264 while (offset < section_size)
265 {
266 if (!symbol.Parse(dynsym_data, &offset))
267 break;
268
269 if (symbol.d_tag != DT_NEEDED)
270 continue;
271
272 uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
273 const char *lib_name = dynstr_data.PeekCStr(str_index);
Greg Clayton537a7a82010-10-20 20:54:39 +0000274 m_filespec_ap->Append(FileSpec(lib_name, true));
Stephen Wilsonddd29622010-07-13 23:07:23 +0000275 }
276 }
277
278 return m_filespec_ap->GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000279}
280
281//----------------------------------------------------------------------
282// ParseProgramHeaders
283//----------------------------------------------------------------------
284size_t
285ObjectFileELF::ParseProgramHeaders()
286{
287 // We have already parsed the program headers
288 if (!m_program_headers.empty())
289 return m_program_headers.size();
290
Stephen Wilsonddd29622010-07-13 23:07:23 +0000291 // If there are no program headers to read we are done.
292 if (m_header.e_phnum == 0)
293 return 0;
294
295 m_program_headers.resize(m_header.e_phnum);
296 if (m_program_headers.size() != m_header.e_phnum)
297 return 0;
298
299 const size_t ph_size = m_header.e_phnum * m_header.e_phentsize;
300 const elf_off ph_offset = m_offset + m_header.e_phoff;
301 DataBufferSP buffer_sp(m_file.ReadFileContents(ph_offset, ph_size));
302
303 if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != ph_size)
304 return 0;
305
306 DataExtractor data(buffer_sp, m_data.GetByteOrder(),
307 m_data.GetAddressByteSize());
308
309 uint32_t idx;
310 uint32_t offset;
311 for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000312 {
Stephen Wilsonddd29622010-07-13 23:07:23 +0000313 if (m_program_headers[idx].Parse(data, &offset) == false)
314 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000315 }
316
Stephen Wilsonddd29622010-07-13 23:07:23 +0000317 if (idx < m_program_headers.size())
318 m_program_headers.resize(idx);
319
Chris Lattner24943d22010-06-08 16:52:24 +0000320 return m_program_headers.size();
321}
322
Chris Lattner24943d22010-06-08 16:52:24 +0000323//----------------------------------------------------------------------
324// ParseSectionHeaders
325//----------------------------------------------------------------------
326size_t
327ObjectFileELF::ParseSectionHeaders()
328{
329 // We have already parsed the section headers
330 if (!m_section_headers.empty())
331 return m_section_headers.size();
332
Stephen Wilsonddd29622010-07-13 23:07:23 +0000333 // If there are no section headers we are done.
334 if (m_header.e_shnum == 0)
335 return 0;
336
337 m_section_headers.resize(m_header.e_shnum);
338 if (m_section_headers.size() != m_header.e_shnum)
339 return 0;
340
341 const size_t sh_size = m_header.e_shnum * m_header.e_shentsize;
342 const elf_off sh_offset = m_offset + m_header.e_shoff;
343 DataBufferSP buffer_sp(m_file.ReadFileContents(sh_offset, sh_size));
344
345 if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != sh_size)
346 return 0;
347
348 DataExtractor data(buffer_sp,
349 m_data.GetByteOrder(),
350 m_data.GetAddressByteSize());
351
352 uint32_t idx;
353 uint32_t offset;
354 for (idx = 0, offset = 0; idx < m_header.e_shnum; ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000355 {
Stephen Wilsonddd29622010-07-13 23:07:23 +0000356 if (m_section_headers[idx].Parse(data, &offset) == false)
357 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000358 }
Stephen Wilsonddd29622010-07-13 23:07:23 +0000359 if (idx < m_section_headers.size())
360 m_section_headers.resize(idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000361
362 return m_section_headers.size();
363}
364
365size_t
366ObjectFileELF::GetSectionHeaderStringTable()
367{
368 if (m_shstr_data.GetByteSize() == 0)
369 {
Stephen Wilsonddd29622010-07-13 23:07:23 +0000370 const unsigned strtab_idx = m_header.e_shstrndx;
371
372 if (strtab_idx && strtab_idx < m_section_headers.size())
Chris Lattner24943d22010-06-08 16:52:24 +0000373 {
Stephen Wilsonddd29622010-07-13 23:07:23 +0000374 const ELFSectionHeader &sheader = m_section_headers[strtab_idx];
375 const size_t byte_size = sheader.sh_size;
376 const Elf64_Off offset = m_offset + sheader.sh_offset;
377 DataBufferSP buffer_sp(m_file.ReadFileContents(offset, byte_size));
Chris Lattner24943d22010-06-08 16:52:24 +0000378
379 if (buffer_sp.get() == NULL || buffer_sp->GetByteSize() != byte_size)
380 return 0;
381
382 m_shstr_data.SetData(buffer_sp);
383 }
384 }
385 return m_shstr_data.GetByteSize();
386}
387
Stephen Wilsonddd29622010-07-13 23:07:23 +0000388lldb::user_id_t
Chris Lattner24943d22010-06-08 16:52:24 +0000389ObjectFileELF::GetSectionIndexByName(const char *name)
390{
Stephen Wilsonddd29622010-07-13 23:07:23 +0000391 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
392 return 0;
393
394 // Search the collection of section headers for one with a matching name.
395 for (SectionHeaderCollIter I = m_section_headers.begin();
396 I != m_section_headers.end(); ++I)
Chris Lattner24943d22010-06-08 16:52:24 +0000397 {
Stephen Wilsonddd29622010-07-13 23:07:23 +0000398 const char *sectionName = m_shstr_data.PeekCStr(I->sh_name);
399
400 if (!sectionName)
401 return 0;
402
403 if (strcmp(name, sectionName) != 0)
404 continue;
405
406 return SectionIndex(I);
Chris Lattner24943d22010-06-08 16:52:24 +0000407 }
408
Stephen Wilsonddd29622010-07-13 23:07:23 +0000409 return 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000410}
411
412SectionList *
413ObjectFileELF::GetSectionList()
414{
Stephen Wilsonddd29622010-07-13 23:07:23 +0000415 if (m_sections_ap.get())
416 return m_sections_ap.get();
417
418 if (ParseSectionHeaders() && GetSectionHeaderStringTable())
Chris Lattner24943d22010-06-08 16:52:24 +0000419 {
420 m_sections_ap.reset(new SectionList());
Chris Lattner24943d22010-06-08 16:52:24 +0000421
Stephen Wilsonddd29622010-07-13 23:07:23 +0000422 for (SectionHeaderCollIter I = m_section_headers.begin();
423 I != m_section_headers.end(); ++I)
424 {
425 const ELFSectionHeader &header = *I;
426
427 ConstString name(m_shstr_data.PeekCStr(header.sh_name));
428 uint64_t size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
429
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000430 static ConstString g_sect_name_text (".text");
431 static ConstString g_sect_name_data (".data");
432 static ConstString g_sect_name_bss (".bss");
433 static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev");
434 static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges");
435 static ConstString g_sect_name_dwarf_debug_frame (".debug_frame");
436 static ConstString g_sect_name_dwarf_debug_info (".debug_info");
437 static ConstString g_sect_name_dwarf_debug_line (".debug_line");
438 static ConstString g_sect_name_dwarf_debug_loc (".debug_loc");
439 static ConstString g_sect_name_dwarf_debug_macinfo (".debug_macinfo");
440 static ConstString g_sect_name_dwarf_debug_pubnames (".debug_pubnames");
441 static ConstString g_sect_name_dwarf_debug_pubtypes (".debug_pubtypes");
442 static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
443 static ConstString g_sect_name_dwarf_debug_str (".debug_str");
444 static ConstString g_sect_name_eh_frame (".eh_frame");
445
446 SectionType sect_type = eSectionTypeOther;
447
448 if (name == g_sect_name_text) sect_type = eSectionTypeCode;
449 else if (name == g_sect_name_data) sect_type = eSectionTypeData;
450 else if (name == g_sect_name_bss) sect_type = eSectionTypeZeroFill;
451 else if (name == g_sect_name_dwarf_debug_abbrev) sect_type = eSectionTypeDWARFDebugAbbrev;
452 else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges;
453 else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame;
454 else if (name == g_sect_name_dwarf_debug_info) sect_type = eSectionTypeDWARFDebugInfo;
455 else if (name == g_sect_name_dwarf_debug_line) sect_type = eSectionTypeDWARFDebugLine;
456 else if (name == g_sect_name_dwarf_debug_loc) sect_type = eSectionTypeDWARFDebugLoc;
457 else if (name == g_sect_name_dwarf_debug_macinfo) sect_type = eSectionTypeDWARFDebugMacInfo;
458 else if (name == g_sect_name_dwarf_debug_pubnames) sect_type = eSectionTypeDWARFDebugPubNames;
459 else if (name == g_sect_name_dwarf_debug_pubtypes) sect_type = eSectionTypeDWARFDebugPubTypes;
460 else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges;
461 else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr;
462 else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame;
463
464
Stephen Wilsonddd29622010-07-13 23:07:23 +0000465 SectionSP section(new Section(
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000466 0, // Parent section.
467 GetModule(), // Module to which this section belongs.
468 SectionIndex(I), // Section ID.
469 name, // Section name.
470 sect_type, // Section type.
471 header.sh_addr, // VM address.
472 header.sh_size, // VM size in bytes of this section.
473 header.sh_offset, // Offset of this section in the file.
474 size, // Size of the section as found in the file.
475 header.sh_flags)); // Flags for this section.
Stephen Wilsonddd29622010-07-13 23:07:23 +0000476
477 m_sections_ap->AddSection(section);
Chris Lattner24943d22010-06-08 16:52:24 +0000478 }
479 }
Stephen Wilsonddd29622010-07-13 23:07:23 +0000480
Chris Lattner24943d22010-06-08 16:52:24 +0000481 return m_sections_ap.get();
482}
483
484static void
Stephen Wilsonddd29622010-07-13 23:07:23 +0000485ParseSymbols(Symtab *symtab, SectionList *section_list,
486 const ELFSectionHeader &symtab_shdr,
487 const DataExtractor &symtab_data,
488 const DataExtractor &strtab_data)
Chris Lattner24943d22010-06-08 16:52:24 +0000489{
Stephen Wilsonddd29622010-07-13 23:07:23 +0000490 ELFSymbol symbol;
Chris Lattner24943d22010-06-08 16:52:24 +0000491 uint32_t offset = 0;
Stephen Wilsonddd29622010-07-13 23:07:23 +0000492 const unsigned numSymbols =
493 symtab_data.GetByteSize() / symtab_shdr.sh_entsize;
494
Chris Lattner24943d22010-06-08 16:52:24 +0000495 static ConstString text_section_name(".text");
496 static ConstString init_section_name(".init");
497 static ConstString fini_section_name(".fini");
498 static ConstString ctors_section_name(".ctors");
499 static ConstString dtors_section_name(".dtors");
500
501 static ConstString data_section_name(".data");
502 static ConstString rodata_section_name(".rodata");
503 static ConstString rodata1_section_name(".rodata1");
504 static ConstString data2_section_name(".data1");
505 static ConstString bss_section_name(".bss");
506
Stephen Wilsonddd29622010-07-13 23:07:23 +0000507 for (unsigned i = 0; i < numSymbols; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000508 {
Stephen Wilsonddd29622010-07-13 23:07:23 +0000509 if (symbol.Parse(symtab_data, &offset) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000510 break;
511
Stephen Wilsonddd29622010-07-13 23:07:23 +0000512 Section *symbol_section = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000513 SymbolType symbol_type = eSymbolTypeInvalid;
Stephen Wilsonddd29622010-07-13 23:07:23 +0000514 Elf64_Half symbol_idx = symbol.st_shndx;
Chris Lattner24943d22010-06-08 16:52:24 +0000515
Stephen Wilsonddd29622010-07-13 23:07:23 +0000516 switch (symbol_idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000517 {
518 case SHN_ABS:
519 symbol_type = eSymbolTypeAbsolute;
520 break;
521 case SHN_UNDEF:
522 symbol_type = eSymbolTypeUndefined;
523 break;
524 default:
Stephen Wilsonddd29622010-07-13 23:07:23 +0000525 symbol_section = section_list->GetSectionAtIndex(symbol_idx).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000526 break;
527 }
528
Stephen Wilsonddd29622010-07-13 23:07:23 +0000529 switch (symbol.getType())
Chris Lattner24943d22010-06-08 16:52:24 +0000530 {
531 default:
532 case STT_NOTYPE:
533 // The symbol's type is not specified.
534 break;
535
536 case STT_OBJECT:
Stephen Wilsonddd29622010-07-13 23:07:23 +0000537 // The symbol is associated with a data object, such as a variable,
538 // an array, etc.
539 symbol_type = eSymbolTypeData;
Chris Lattner24943d22010-06-08 16:52:24 +0000540 break;
541
542 case STT_FUNC:
543 // The symbol is associated with a function or other executable code.
Stephen Wilsonddd29622010-07-13 23:07:23 +0000544 symbol_type = eSymbolTypeCode;
Chris Lattner24943d22010-06-08 16:52:24 +0000545 break;
546
547 case STT_SECTION:
548 // The symbol is associated with a section. Symbol table entries of
549 // this type exist primarily for relocation and normally have
550 // STB_LOCAL binding.
551 break;
552
553 case STT_FILE:
554 // Conventionally, the symbol's name gives the name of the source
555 // file associated with the object file. A file symbol has STB_LOCAL
556 // binding, its section index is SHN_ABS, and it precedes the other
557 // STB_LOCAL symbols for the file, if it is present.
Stephen Wilsonddd29622010-07-13 23:07:23 +0000558 symbol_type = eSymbolTypeObjectFile;
Chris Lattner24943d22010-06-08 16:52:24 +0000559 break;
560 }
561
562 if (symbol_type == eSymbolTypeInvalid)
563 {
564 if (symbol_section)
565 {
566 const ConstString &sect_name = symbol_section->GetName();
567 if (sect_name == text_section_name ||
568 sect_name == init_section_name ||
569 sect_name == fini_section_name ||
570 sect_name == ctors_section_name ||
571 sect_name == dtors_section_name)
572 {
573 symbol_type = eSymbolTypeCode;
574 }
Stephen Wilsonddd29622010-07-13 23:07:23 +0000575 else if (sect_name == data_section_name ||
576 sect_name == data2_section_name ||
577 sect_name == rodata_section_name ||
578 sect_name == rodata1_section_name ||
579 sect_name == bss_section_name)
Chris Lattner24943d22010-06-08 16:52:24 +0000580 {
581 symbol_type = eSymbolTypeData;
582 }
583 }
584 }
585
586 uint64_t symbol_value = symbol.st_value;
587 if (symbol_section != NULL)
588 symbol_value -= symbol_section->GetFileAddress();
589 const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
Stephen Wilsonddd29622010-07-13 23:07:23 +0000590 bool is_global = symbol.getBinding() == STB_GLOBAL;
591 uint32_t flags = symbol.st_other << 8 | symbol.st_info;
Chris Lattner24943d22010-06-08 16:52:24 +0000592
Stephen Wilsonddd29622010-07-13 23:07:23 +0000593 Symbol dc_symbol(
594 i, // ID is the original symbol table index.
595 symbol_name, // Symbol name.
596 false, // Is the symbol name mangled?
597 symbol_type, // Type of this symbol
598 is_global, // Is this globally visible?
599 false, // Is this symbol debug info?
600 false, // Is this symbol a trampoline?
601 false, // Is this symbol artificial?
602 symbol_section, // Section in which this symbol is defined or null.
603 symbol_value, // Offset in section or symbol value.
604 symbol.st_size, // Size in bytes of this symbol.
605 flags); // Symbol flags.
Chris Lattner24943d22010-06-08 16:52:24 +0000606 symtab->AddSymbol(dc_symbol);
607 }
608}
609
Stephen Wilsonddd29622010-07-13 23:07:23 +0000610void
611ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
612 const ELFSectionHeader &symtab_hdr,
613 user_id_t symtab_id)
614{
615 assert(symtab_hdr.sh_type == SHT_SYMTAB ||
616 symtab_hdr.sh_type == SHT_DYNSYM);
617
618 // Parse in the section list if needed.
619 SectionList *section_list = GetSectionList();
620 if (!section_list)
621 return;
622
623 // Section ID's are ones based.
624 user_id_t strtab_id = symtab_hdr.sh_link + 1;
625
626 Section *symtab = section_list->FindSectionByID(symtab_id).get();
627 Section *strtab = section_list->FindSectionByID(strtab_id).get();
628 if (symtab && strtab)
629 {
630 DataExtractor symtab_data;
631 DataExtractor strtab_data;
632 if (symtab->ReadSectionDataFromObjectFile(this, symtab_data) &&
633 strtab->ReadSectionDataFromObjectFile(this, strtab_data))
634 {
635 ParseSymbols(symbol_table, section_list, symtab_hdr,
636 symtab_data, strtab_data);
637 }
638 }
639}
Chris Lattner24943d22010-06-08 16:52:24 +0000640
641Symtab *
642ObjectFileELF::GetSymtab()
643{
Stephen Wilsonddd29622010-07-13 23:07:23 +0000644 if (m_symtab_ap.get())
645 return m_symtab_ap.get();
646
647 Symtab *symbol_table = new Symtab(this);
648 m_symtab_ap.reset(symbol_table);
649
Greg Clayton8d3802d2010-10-08 04:20:14 +0000650 Mutex::Locker locker (symbol_table->GetMutex ());
651
Stephen Wilsonddd29622010-07-13 23:07:23 +0000652 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
653 return symbol_table;
654
655 // Locate and parse all linker symbol tables.
656 for (SectionHeaderCollIter I = m_section_headers.begin();
657 I != m_section_headers.end(); ++I)
Chris Lattner24943d22010-06-08 16:52:24 +0000658 {
Stephen Wilsonddd29622010-07-13 23:07:23 +0000659 if (I->sh_type == SHT_SYMTAB)
Chris Lattner24943d22010-06-08 16:52:24 +0000660 {
Stephen Wilsonddd29622010-07-13 23:07:23 +0000661 const ELFSectionHeader &symtab_section = *I;
662 user_id_t section_id = SectionIndex(I);
Greg Clayton8d3802d2010-10-08 04:20:14 +0000663 ParseSymbolTable (symbol_table, symtab_section, section_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000664 }
665 }
Stephen Wilsonddd29622010-07-13 23:07:23 +0000666
667 return symbol_table;
Chris Lattner24943d22010-06-08 16:52:24 +0000668}
669
Chris Lattner24943d22010-06-08 16:52:24 +0000670//===----------------------------------------------------------------------===//
671// Dump
672//
673// Dump the specifics of the runtime file container (such as any headers
674// segments, sections, etc).
675//----------------------------------------------------------------------
676void
677ObjectFileELF::Dump(Stream *s)
678{
679 DumpELFHeader(s, m_header);
680 s->EOL();
681 DumpELFProgramHeaders(s);
682 s->EOL();
683 DumpELFSectionHeaders(s);
684 s->EOL();
685 SectionList *section_list = GetSectionList();
686 if (section_list)
687 section_list->Dump(s, NULL, true);
688 Symtab *symtab = GetSymtab();
689 if (symtab)
Greg Clayton8d3802d2010-10-08 04:20:14 +0000690 symtab->Dump(s, NULL, lldb::eSortOrderNone);
Chris Lattner24943d22010-06-08 16:52:24 +0000691 s->EOL();
Stephen Wilsonddd29622010-07-13 23:07:23 +0000692 DumpDependentModules(s);
693 s->EOL();
Chris Lattner24943d22010-06-08 16:52:24 +0000694}
695
696//----------------------------------------------------------------------
697// DumpELFHeader
698//
699// Dump the ELF header to the specified output stream
700//----------------------------------------------------------------------
701void
Stephen Wilsonddd29622010-07-13 23:07:23 +0000702ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)
Chris Lattner24943d22010-06-08 16:52:24 +0000703{
Stephen Wilsonddd29622010-07-13 23:07:23 +0000704 s->PutCString("ELF Header\n");
705 s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
706 s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n",
707 header.e_ident[EI_MAG1], header.e_ident[EI_MAG1]);
708 s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n",
709 header.e_ident[EI_MAG2], header.e_ident[EI_MAG2]);
710 s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n",
711 header.e_ident[EI_MAG3], header.e_ident[EI_MAG3]);
Chris Lattner24943d22010-06-08 16:52:24 +0000712
Stephen Wilsonddd29622010-07-13 23:07:23 +0000713 s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
714 s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
Chris Lattner24943d22010-06-08 16:52:24 +0000715 DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
716 s->Printf ("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
717 s->Printf ("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
718
719 s->Printf("e_type = 0x%4.4x ", header.e_type);
720 DumpELFHeader_e_type(s, header.e_type);
721 s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
722 s->Printf("e_version = 0x%8.8x\n", header.e_version);
Stephen Wilsonddd29622010-07-13 23:07:23 +0000723 s->Printf("e_entry = 0x%8.8lx\n", header.e_entry);
724 s->Printf("e_phoff = 0x%8.8lx\n", header.e_phoff);
725 s->Printf("e_shoff = 0x%8.8lx\n", header.e_shoff);
Chris Lattner24943d22010-06-08 16:52:24 +0000726 s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
727 s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
728 s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
729 s->Printf("e_phnum = 0x%4.4x\n", header.e_phnum);
730 s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
731 s->Printf("e_shnum = 0x%4.4x\n", header.e_shnum);
732 s->Printf("e_shstrndx = 0x%4.4x\n", header.e_shstrndx);
733}
734
735//----------------------------------------------------------------------
736// DumpELFHeader_e_type
737//
738// Dump an token value for the ELF header member e_type
739//----------------------------------------------------------------------
740void
Stephen Wilsonddd29622010-07-13 23:07:23 +0000741ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000742{
743 switch (e_type)
744 {
745 case ET_NONE: *s << "ET_NONE"; break;
746 case ET_REL: *s << "ET_REL"; break;
747 case ET_EXEC: *s << "ET_EXEC"; break;
748 case ET_DYN: *s << "ET_DYN"; break;
749 case ET_CORE: *s << "ET_CORE"; break;
750 default:
751 break;
752 }
753}
754
755//----------------------------------------------------------------------
756// DumpELFHeader_e_ident_EI_DATA
757//
758// Dump an token value for the ELF header member e_ident[EI_DATA]
759//----------------------------------------------------------------------
760void
Stephen Wilsonddd29622010-07-13 23:07:23 +0000761ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, unsigned char ei_data)
Chris Lattner24943d22010-06-08 16:52:24 +0000762{
763 switch (ei_data)
764 {
765 case ELFDATANONE: *s << "ELFDATANONE"; break;
766 case ELFDATA2LSB: *s << "ELFDATA2LSB - Little Endian"; break;
767 case ELFDATA2MSB: *s << "ELFDATA2MSB - Big Endian"; break;
768 default:
769 break;
770 }
771}
772
773
774//----------------------------------------------------------------------
775// DumpELFProgramHeader
776//
777// Dump a single ELF program header to the specified output stream
778//----------------------------------------------------------------------
779void
Stephen Wilsonddd29622010-07-13 23:07:23 +0000780ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
Chris Lattner24943d22010-06-08 16:52:24 +0000781{
782 DumpELFProgramHeader_p_type(s, ph.p_type);
Stephen Wilsonddd29622010-07-13 23:07:23 +0000783 s->Printf(" %8.8lx %8.8lx %8.8lx", ph.p_offset, ph.p_vaddr, ph.p_paddr);
784 s->Printf(" %8.8lx %8.8lx %8.8lx (", ph.p_filesz, ph.p_memsz, ph.p_flags);
785
Chris Lattner24943d22010-06-08 16:52:24 +0000786 DumpELFProgramHeader_p_flags(s, ph.p_flags);
787 s->Printf(") %8.8x", ph.p_align);
788}
789
790//----------------------------------------------------------------------
791// DumpELFProgramHeader_p_type
792//
793// Dump an token value for the ELF program header member p_type which
794// describes the type of the program header
Stephen Wilsonddd29622010-07-13 23:07:23 +0000795// ----------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +0000796void
Stephen Wilsonddd29622010-07-13 23:07:23 +0000797ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000798{
799 const int kStrWidth = 10;
800 switch (p_type)
801 {
802 CASE_AND_STREAM(s, PT_NULL , kStrWidth);
803 CASE_AND_STREAM(s, PT_LOAD , kStrWidth);
804 CASE_AND_STREAM(s, PT_DYNAMIC , kStrWidth);
805 CASE_AND_STREAM(s, PT_INTERP , kStrWidth);
806 CASE_AND_STREAM(s, PT_NOTE , kStrWidth);
807 CASE_AND_STREAM(s, PT_SHLIB , kStrWidth);
808 CASE_AND_STREAM(s, PT_PHDR , kStrWidth);
809 default:
810 s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
811 break;
812 }
813}
814
815
816//----------------------------------------------------------------------
817// DumpELFProgramHeader_p_flags
818//
819// Dump an token value for the ELF program header member p_flags
820//----------------------------------------------------------------------
821void
Stephen Wilsonddd29622010-07-13 23:07:23 +0000822ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)
Chris Lattner24943d22010-06-08 16:52:24 +0000823{
824 *s << ((p_flags & PF_X) ? "PF_X" : " ")
825 << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
826 << ((p_flags & PF_W) ? "PF_W" : " ")
827 << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
828 << ((p_flags & PF_R) ? "PF_R" : " ");
829}
830
831//----------------------------------------------------------------------
832// DumpELFProgramHeaders
833//
834// Dump all of the ELF program header to the specified output stream
835//----------------------------------------------------------------------
836void
837ObjectFileELF::DumpELFProgramHeaders(Stream *s)
838{
839 if (ParseProgramHeaders())
840 {
841 s->PutCString("Program Headers\n");
Stephen Wilsonddd29622010-07-13 23:07:23 +0000842 s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
843 "p_filesz p_memsz p_flags p_align\n");
844 s->PutCString("==== ---------- -------- -------- -------- "
845 "-------- -------- ------------------------- --------\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000846
847 uint32_t idx = 0;
Stephen Wilsonddd29622010-07-13 23:07:23 +0000848 for (ProgramHeaderCollConstIter I = m_program_headers.begin();
849 I != m_program_headers.end(); ++I, ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000850 {
Stephen Wilsonddd29622010-07-13 23:07:23 +0000851 s->Printf("[%2u] ", idx);
852 ObjectFileELF::DumpELFProgramHeader(s, *I);
Chris Lattner24943d22010-06-08 16:52:24 +0000853 s->EOL();
854 }
855 }
856}
857
Chris Lattner24943d22010-06-08 16:52:24 +0000858//----------------------------------------------------------------------
859// DumpELFSectionHeader
860//
861// Dump a single ELF section header to the specified output stream
862//----------------------------------------------------------------------
863void
Stephen Wilsonddd29622010-07-13 23:07:23 +0000864ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeader &sh)
Chris Lattner24943d22010-06-08 16:52:24 +0000865{
Stephen Wilsonddd29622010-07-13 23:07:23 +0000866 s->Printf("%8.8x ", sh.sh_name);
Chris Lattner24943d22010-06-08 16:52:24 +0000867 DumpELFSectionHeader_sh_type(s, sh.sh_type);
Stephen Wilsonddd29622010-07-13 23:07:23 +0000868 s->Printf(" %8.8lx (", sh.sh_flags);
Chris Lattner24943d22010-06-08 16:52:24 +0000869 DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
Stephen Wilsonddd29622010-07-13 23:07:23 +0000870 s->Printf(") %8.8lx %8.8lx %8.8lx", sh.sh_addr, sh.sh_offset, sh.sh_size);
871 s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
872 s->Printf(" %8.8lx %8.8lx", sh.sh_addralign, sh.sh_entsize);
Chris Lattner24943d22010-06-08 16:52:24 +0000873}
874
875//----------------------------------------------------------------------
876// DumpELFSectionHeader_sh_type
877//
878// Dump an token value for the ELF section header member sh_type which
879// describes the type of the section
880//----------------------------------------------------------------------
881void
Stephen Wilsonddd29622010-07-13 23:07:23 +0000882ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000883{
884 const int kStrWidth = 12;
885 switch (sh_type)
886 {
887 CASE_AND_STREAM(s, SHT_NULL , kStrWidth);
888 CASE_AND_STREAM(s, SHT_PROGBITS , kStrWidth);
889 CASE_AND_STREAM(s, SHT_SYMTAB , kStrWidth);
890 CASE_AND_STREAM(s, SHT_STRTAB , kStrWidth);
891 CASE_AND_STREAM(s, SHT_RELA , kStrWidth);
892 CASE_AND_STREAM(s, SHT_HASH , kStrWidth);
893 CASE_AND_STREAM(s, SHT_DYNAMIC , kStrWidth);
894 CASE_AND_STREAM(s, SHT_NOTE , kStrWidth);
895 CASE_AND_STREAM(s, SHT_NOBITS , kStrWidth);
896 CASE_AND_STREAM(s, SHT_REL , kStrWidth);
897 CASE_AND_STREAM(s, SHT_SHLIB , kStrWidth);
898 CASE_AND_STREAM(s, SHT_DYNSYM , kStrWidth);
899 CASE_AND_STREAM(s, SHT_LOPROC , kStrWidth);
900 CASE_AND_STREAM(s, SHT_HIPROC , kStrWidth);
901 CASE_AND_STREAM(s, SHT_LOUSER , kStrWidth);
902 CASE_AND_STREAM(s, SHT_HIUSER , kStrWidth);
903 default:
904 s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
905 break;
906 }
907}
908
Chris Lattner24943d22010-06-08 16:52:24 +0000909//----------------------------------------------------------------------
910// DumpELFSectionHeader_sh_flags
911//
912// Dump an token value for the ELF section header member sh_flags
913//----------------------------------------------------------------------
914void
Stephen Wilsonddd29622010-07-13 23:07:23 +0000915ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_word sh_flags)
Chris Lattner24943d22010-06-08 16:52:24 +0000916{
917 *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
918 << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
919 << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
920 << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
921 << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
922}
Stephen Wilsonddd29622010-07-13 23:07:23 +0000923
Chris Lattner24943d22010-06-08 16:52:24 +0000924//----------------------------------------------------------------------
925// DumpELFSectionHeaders
926//
927// Dump all of the ELF section header to the specified output stream
928//----------------------------------------------------------------------
929void
930ObjectFileELF::DumpELFSectionHeaders(Stream *s)
931{
Stephen Wilsonddd29622010-07-13 23:07:23 +0000932 if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
933 return;
934
935 s->PutCString("Section Headers\n");
936 s->PutCString("IDX name type flags "
937 "addr offset size link info addralgn "
938 "entsize Name\n");
939 s->PutCString("==== -------- ------------ -------------------------------- "
940 "-------- -------- -------- -------- -------- -------- "
941 "-------- ====================\n");
942
943 uint32_t idx = 0;
944 for (SectionHeaderCollConstIter I = m_section_headers.begin();
945 I != m_section_headers.end(); ++I, ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000946 {
Stephen Wilsonddd29622010-07-13 23:07:23 +0000947 s->Printf("[%2u] ", idx);
948 ObjectFileELF::DumpELFSectionHeader(s, *I);
949 const char* section_name = m_shstr_data.PeekCStr(I->sh_name);
950 if (section_name)
951 *s << ' ' << section_name << "\n";
952 }
953}
Chris Lattner24943d22010-06-08 16:52:24 +0000954
Stephen Wilsonddd29622010-07-13 23:07:23 +0000955void
956ObjectFileELF::DumpDependentModules(lldb_private::Stream *s)
957{
958 size_t num_modules = ParseDependentModules();
Chris Lattner24943d22010-06-08 16:52:24 +0000959
Stephen Wilsonddd29622010-07-13 23:07:23 +0000960 if (num_modules > 0)
961 {
962 s->PutCString("Dependent Modules:\n");
963 for (unsigned i = 0; i < num_modules; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000964 {
Stephen Wilsonddd29622010-07-13 23:07:23 +0000965 const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
966 s->Printf(" %s\n", spec.GetFilename().GetCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000967 }
968 }
969}
970
Chris Lattner24943d22010-06-08 16:52:24 +0000971bool
Stephen Wilsonddd29622010-07-13 23:07:23 +0000972ObjectFileELF::GetTargetTriple(ConstString &target_triple)
Chris Lattner24943d22010-06-08 16:52:24 +0000973{
974 static ConstString g_target_triple;
975
976 if (g_target_triple)
977 {
978 target_triple = g_target_triple;
Stephen Wilsonddd29622010-07-13 23:07:23 +0000979 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000980 }
Stephen Wilsonddd29622010-07-13 23:07:23 +0000981
982 std::string triple;
983 switch (m_header.e_machine)
Chris Lattner24943d22010-06-08 16:52:24 +0000984 {
Stephen Wilsonddd29622010-07-13 23:07:23 +0000985 default:
986 assert(false && "Unexpected machine type.");
987 break;
988 case EM_SPARC: triple.assign("sparc-"); break;
989 case EM_386: triple.assign("i386-"); break;
990 case EM_68K: triple.assign("68k-"); break;
991 case EM_88K: triple.assign("88k-"); break;
992 case EM_860: triple.assign("i860-"); break;
993 case EM_MIPS: triple.assign("mips-"); break;
994 case EM_PPC: triple.assign("powerpc-"); break;
995 case EM_PPC64: triple.assign("powerpc64-"); break;
996 case EM_ARM: triple.assign("arm-"); break;
997 case EM_X86_64: triple.assign("x86_64-"); break;
Chris Lattner24943d22010-06-08 16:52:24 +0000998 }
Stephen Wilsonddd29622010-07-13 23:07:23 +0000999 // TODO: determine if there is a vendor in the ELF? Default to "linux" for now
1000 triple += "linux-";
1001 // TODO: determine if there is an OS in the ELF? Default to "gnu" for now
1002 triple += "gnu";
1003 g_target_triple.SetCString(triple.c_str());
1004 target_triple = g_target_triple;
1005
1006 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00001007}
1008