[Lldb-commits] [lldb] r147358 - in /lldb/trunk: include/lldb/Core/DataExtractor.h source/Core/DataExtractor.cpp source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
Greg Clayton
gclayton at apple.com
Thu Dec 29 16:32:24 PST 2011
Author: gclayton
Date: Thu Dec 29 18:32:24 2011
New Revision: 147358
URL: http://llvm.org/viewvc/llvm-project?rev=147358&view=rev
Log:
<rdar://problem/10368163>
Watch for empty symbol tables by doing a lot more error checking on
all mach-o symbol table load command values and data that is obtained.
This avoids a crash that was happening when there was no string table.
Modified:
lldb/trunk/include/lldb/Core/DataExtractor.h
lldb/trunk/source/Core/DataExtractor.cpp
lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
Modified: lldb/trunk/include/lldb/Core/DataExtractor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/DataExtractor.h?rev=147358&r1=147357&r2=147358&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/DataExtractor.h (original)
+++ lldb/trunk/include/lldb/Core/DataExtractor.h Thu Dec 29 18:32:24 2011
@@ -354,6 +354,9 @@
//------------------------------------------------------------------
uint64_t
GetAddress (uint32_t *offset_ptr) const;
+
+ uint64_t
+ GetAddress_unchecked (uint32_t *offset_ptr) const;
//------------------------------------------------------------------
/// Get the current address size.
@@ -629,6 +632,9 @@
uint64_t
GetMaxU64 (uint32_t *offset_ptr, uint32_t byte_size) const;
+ uint64_t
+ GetMaxU64_unchecked (uint32_t *offset_ptr, uint32_t byte_size) const;
+
//------------------------------------------------------------------
/// Extract an signed integer of size \a byte_size from \a *offset_ptr.
///
Modified: lldb/trunk/source/Core/DataExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataExtractor.cpp?rev=147358&r1=147357&r2=147358&view=diff
==============================================================================
--- lldb/trunk/source/Core/DataExtractor.cpp (original)
+++ lldb/trunk/source/Core/DataExtractor.cpp Thu Dec 29 18:32:24 2011
@@ -659,6 +659,22 @@
return 0;
}
+uint64_t
+DataExtractor::GetMaxU64_unchecked (uint32_t *offset_ptr, uint32_t size) const
+{
+ switch (size)
+ {
+ case 1: return GetU8_unchecked (offset_ptr); break;
+ case 2: return GetU16_unchecked (offset_ptr); break;
+ case 4: return GetU32_unchecked (offset_ptr); break;
+ case 8: return GetU64_unchecked (offset_ptr); break;
+ default:
+ assert(!"GetMax64 unhandled case!");
+ break;
+ }
+ return 0;
+}
+
int64_t
DataExtractor::GetMaxS64 (uint32_t *offset_ptr, uint32_t size) const
{
@@ -803,6 +819,12 @@
return GetMaxU64 (offset_ptr, m_addr_size);
}
+uint64_t
+DataExtractor::GetAddress_unchecked (uint32_t *offset_ptr) const
+{
+ return GetMaxU64_unchecked (offset_ptr, m_addr_size);
+}
+
//------------------------------------------------------------------
// Extract a single pointer from the data and update the offset
// pointed to by "offset_ptr". The size of the extracted pointer
Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=147358&r1=147357&r2=147358&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Thu Dec 29 18:32:24 2011
@@ -752,6 +752,9 @@
struct symtab_command symtab_load_command;
uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t i;
+
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
+
for (i=0; i<m_header.ncmds; ++i)
{
const uint32_t cmd_offset = offset;
@@ -764,16 +767,67 @@
// Read in the rest of the symtab load command
if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4)) // fill in symoff, nsyms, stroff, strsize fields
{
+ if (symtab_load_command.symoff == 0)
+ {
+ if (log)
+ GetModule()->LogMessage(log.get(), "LC_SYMTAB.symoff == 0");
+ return 0;
+ }
+
+ if (symtab_load_command.stroff == 0)
+ {
+ if (log)
+ GetModule()->LogMessage(log.get(), "LC_SYMTAB.stroff == 0");
+ return 0;
+ }
+
+ if (symtab_load_command.nsyms == 0)
+ {
+ if (log)
+ GetModule()->LogMessage(log.get(), "LC_SYMTAB.nsyms == 0");
+ return 0;
+ }
+
+ if (symtab_load_command.strsize == 0)
+ {
+ if (log)
+ GetModule()->LogMessage(log.get(), "LC_SYMTAB.strsize == 0");
+ return 0;
+ }
+
Symtab *symtab = m_symtab_ap.get();
SectionList *section_list = GetSectionList();
- assert(section_list);
- const size_t addr_size = m_data.GetAddressByteSize();
- const ByteOrder endian = m_data.GetByteOrder();
- bool bit_width_32 = addr_size == 4;
- const size_t nlist_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
+ if (section_list == NULL)
+ return 0;
+
+ const size_t addr_byte_size = m_data.GetAddressByteSize();
+ const ByteOrder byte_order = m_data.GetByteOrder();
+ bool bit_width_32 = addr_byte_size == 4;
+ const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
+
+ DataBufferSP symtab_data_sp(m_file.ReadFileContents (m_offset + symtab_load_command.symoff,
+ symtab_load_command.nsyms * nlist_byte_size));
+
+ if (symtab_data_sp.get() == NULL ||
+ symtab_data_sp->GetBytes() == NULL ||
+ symtab_data_sp->GetByteSize() == 0)
+ {
+ if (log)
+ GetModule()->LogMessage(log.get(), "failed to read nlist data");
+ return 0;
+ }
+
+ DataBufferSP strtab_data_sp(m_file.ReadFileContents (m_offset + symtab_load_command.stroff,
+ symtab_load_command.strsize));
- DataBufferSP symtab_data_sp(m_file.ReadFileContents(m_offset + symtab_load_command.symoff, symtab_load_command.nsyms * nlist_size));
- DataBufferSP strtab_data_sp(m_file.ReadFileContents(m_offset + symtab_load_command.stroff, symtab_load_command.strsize));
+ if (strtab_data_sp.get() == NULL ||
+ strtab_data_sp->GetBytes() == NULL ||
+ strtab_data_sp->GetByteSize() == 0)
+ {
+ if (log)
+ GetModule()->LogMessage(log.get(), "failed to read strtab data");
+ return 0;
+ }
const char *strtab_data = (const char *)strtab_data_sp->GetBytes();
const size_t strtab_data_len = strtab_data_sp->GetByteSize();
@@ -793,15 +847,11 @@
uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
//uint32_t symtab_offset = 0;
- const uint8_t* nlist_data = symtab_data_sp->GetBytes();
- assert (symtab_data_sp->GetByteSize()/nlist_size >= symtab_load_command.nsyms);
+ assert (symtab_data_sp->GetByteSize()/nlist_byte_size >= symtab_load_command.nsyms);
+ uint32_t nlist_data_offset = 0;
+ DataExtractor nlist_data (symtab_data_sp, byte_order, addr_byte_size);
- if (endian != lldb::endian::InlHostByteOrder())
- {
- // ...
- assert (!"UNIMPLEMENTED: Swap all nlist entries");
- }
uint32_t N_SO_index = UINT32_MAX;
MachSymtabSectionInfo section_info (section_list);
@@ -828,19 +878,14 @@
for (nlist_idx = 0; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
{
struct nlist_64 nlist;
- if (bit_width_32)
- {
- struct nlist* nlist32_ptr = (struct nlist*)(nlist_data + (nlist_idx * nlist_size));
- nlist.n_strx = nlist32_ptr->n_strx;
- nlist.n_type = nlist32_ptr->n_type;
- nlist.n_sect = nlist32_ptr->n_sect;
- nlist.n_desc = nlist32_ptr->n_desc;
- nlist.n_value = nlist32_ptr->n_value;
- }
- else
- {
- nlist = *((struct nlist_64*)(nlist_data + (nlist_idx * nlist_size)));
- }
+ if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
+ break;
+
+ nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset);
+ nlist.n_type = nlist_data.GetU8_unchecked (&nlist_data_offset);
+ nlist.n_sect = nlist_data.GetU8_unchecked (&nlist_data_offset);
+ nlist.n_desc = nlist_data.GetU16_unchecked (&nlist_data_offset);
+ nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);
SymbolType type = eSymbolTypeInvalid;
if (nlist.n_strx >= strtab_data_len)
@@ -1556,9 +1601,6 @@
}
}
}
-
-
-
return symtab->GetNumSymbols();
}
}
More information about the lldb-commits
mailing list