[haiku-commits] haiku: hrev50256 - src/apps/debugger/elf headers/os/kernel src/system/kernel/debug

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 27 Apr 2016 00:55:53 +0200 (CEST)

hrev50256 adds 1 changeset to branch 'master'
old head: 63a0065c835eaf155ca3f96719475147772ccadd
new head: 82185a52e22179ec842d2c5fb983b307b9ebc7d2
overview: 
http://cgit.haiku-os.org/haiku/log/?qt=range&q=82185a52e221+%5E63a0065c835e

----------------------------------------------------------------------------

82185a52e221: Future proofing core file format
  
  * The Haiku specific notes contain a structure size field, now.
  * Change the type of the count and size fields in the Haiku specific
    notes to uint32 also for 64 bit ELF. The size field for a note is a
    uint32 anyway.

                                    [ Ingo Weinhold <ingo_weinhold@xxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev50256
Commit:      82185a52e22179ec842d2c5fb983b307b9ebc7d2
URL:         http://cgit.haiku-os.org/haiku/commit/?id=82185a52e221
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue Apr 26 22:55:05 2016 UTC

----------------------------------------------------------------------------

4 files changed, 140 insertions(+), 74 deletions(-)
headers/os/kernel/elf.h               |  36 +++++--
src/apps/debugger/elf/CoreFile.cpp    | 152 ++++++++++++++++++------------
src/apps/debugger/elf/CoreFile.h      |   8 ++
src/system/kernel/debug/core_dump.cpp |  18 ++--

----------------------------------------------------------------------------

diff --git a/headers/os/kernel/elf.h b/headers/os/kernel/elf.h
index f25fc8b..b1ff0ca 100644
--- a/headers/os/kernel/elf.h
+++ b/headers/os/kernel/elf.h
@@ -611,7 +611,7 @@ typedef struct {
 #define NT_IMAGES                      0x696d6167      /* images */
 #define NT_THREADS                     0x74687264      /* threads */
 
-/* NT_TEAM: Elf32_Note_Team; char[] args */
+/* NT_TEAM: uint32 entrySize; Elf32_Note_Team; char[] args */
 typedef struct {
        int32           nt_id;                          /* team ID */
        int32           nt_uid;                         /* team owner ID */
@@ -620,7 +620,12 @@ typedef struct {
 
 typedef Elf32_Note_Team Elf64_Note_Team;
 
-/* NT_AREAS: uint32 count; Elf32_Note_Area_Entry[count]; char[] names */
+/* NT_AREAS:
+ * uint32 count;
+ * uint32 entrySize;
+ * Elf32_Note_Area_Entry[count];
+ * char[] names
+ */
 typedef struct {
        int32           na_id;                          /* area ID */
        uint32          na_lock;                        /* lock type 
(B_NO_LOCK, ...) */
@@ -630,7 +635,12 @@ typedef struct {
        uint32          na_ram_size;            /* physical memory used */
 } Elf32_Note_Area_Entry;
 
-/* NT_AREAS: uint64 count; Elf64_Note_Area_Entry[count]; char[] names */
+/* NT_AREAS:
+ * uint32 count;
+ * uint32 entrySize;
+ * Elf64_Note_Area_Entry[count];
+ * char[] names
+ */
 typedef struct {
        int32           na_id;                          /* area ID */
        uint32          na_lock;                        /* lock type 
(B_NO_LOCK, ...) */
@@ -641,7 +651,12 @@ typedef struct {
        uint64          na_ram_size;            /* physical memory used */
 } Elf64_Note_Area_Entry;
 
-/* NT_IMAGES: uint32 count; Elf32_Note_Image_Entry[count]; char[] names */
+/* NT_IMAGES:
+ * uint32 count;
+ * uint32 entrySize;
+ * Elf32_Note_Image_Entry[count];
+ * char[] names
+ */
 typedef struct {
        int32           ni_id;                          /* image ID */
        int32           ni_type;                        /* image type 
(B_APP_IMAGE, ...) */
@@ -655,7 +670,12 @@ typedef struct {
        uint32          ni_data_size;           /* size of data segment */
 } Elf32_Note_Image_Entry;
 
-/* NT_IMAGES: uint64 count; Elf64_Note_Image_Entry[count]; char[] names */
+/* NT_IMAGES:
+ * uint32 count;
+ * uint32 entrySize;
+ * Elf64_Note_Image_Entry[count];
+ * char[] names
+ */
 typedef struct {
        int32           ni_id;                          /* image ID */
        int32           ni_type;                        /* image type 
(B_APP_IMAGE, ...) */
@@ -672,6 +692,7 @@ typedef struct {
 
 /* NT_THREADS:
  * uint32 count;
+ * uint32 entrySize;
  * uint32 cpuStateSize;
  * {Elf32_Note_Thread_Entry, uint8[cpuStateSize] cpuState}[count];
  * char[] names
@@ -685,8 +706,9 @@ typedef struct {
 } Elf32_Note_Thread_Entry;
 
 /* NT_THREADS:
- * uint64 count;
- * uint64 cpuStateSize;
+ * uint32 count;
+ * uint32 entrySize;
+ * uint32 cpuStateSize;
  * {Elf64_Note_Thread_Entry, uint8[cpuStateSize] cpuState}[count];
  * char[] names
  */
diff --git a/src/apps/debugger/elf/CoreFile.cpp 
b/src/apps/debugger/elf/CoreFile.cpp
index dd8cf33..4f77ea3 100644
--- a/src/apps/debugger/elf/CoreFile.cpp
+++ b/src/apps/debugger/elf/CoreFile.cpp
@@ -8,6 +8,8 @@
 
 #include <errno.h>
 
+#include <algorithm>
+
 #include <OS.h>
 
 #include <AutoDeleter.h>
@@ -319,23 +321,34 @@ CoreFile::_ReadTeamNote(const void* data, uint32 dataSize)
 {
        typedef typename ElfClass::NoteTeam NoteTeam;
 
-       if (dataSize < sizeof(NoteTeam) + 1) {
+       if (dataSize < sizeof(uint32)) {
                WARNING("Team note too short\n");
                return B_BAD_DATA;
        }
-       const NoteTeam* note = (const NoteTeam*)data;
+       uint32 entrySize = Get(*(const uint32*)data);
+       data = (const uint32*)data + 1;
+       dataSize -= sizeof(uint32);
+
+       if (entrySize == 0 || dataSize == 0 || dataSize - 1 < entrySize) {
+               WARNING("Team note: too short or invalid entry size (%" 
B_PRIu32 ")\n",
+                       entrySize);
+               return B_BAD_DATA;
+       }
+
+       NoteTeam note = {};
+       _ReadEntry(data, dataSize, note, entrySize);
 
        // check, if args are null-terminated
-       const char* args = (const char*)(note + 1);
-       size_t argsSize = dataSize - sizeof(NoteTeam);
-       if (argsSize == 0 || args[argsSize - 1] != '\0') {
+       const char* args = (const char*)data;
+       size_t argsSize = dataSize;
+       if (args[argsSize - 1] != '\0') {
                WARNING("Team note args not terminated\n");
                return B_BAD_DATA;
        }
 
-       int32 id = Get(note->nt_id);
-       int32 uid = Get(note->nt_uid);
-       int32 gid = Get(note->nt_gid);
+       int32 id = Get(note.nt_id);
+       int32 uid = Get(note.nt_uid);
+       int32 gid = Get(note.nt_gid);
 
        BString copiedArgs(args);
        if (args[0] != '\0' && copiedArgs.Length() == 0)
@@ -350,29 +363,29 @@ template<typename ElfClass>
 status_t
 CoreFile::_ReadAreasNote(const void* data, uint32 dataSize)
 {
-       const size_t addressSize = sizeof(typename ElfClass::Size);
-       if (dataSize < addressSize) {
+       if (dataSize < 2 * sizeof(uint32)) {
                WARNING("Areas note too short\n");
                return B_BAD_DATA;
        }
-       uint64 areaCount = Get(*(const typename ElfClass::Size*)data);
+       uint32 areaCount = _ReadValue<uint32>(data, dataSize);
+       uint32 entrySize = _ReadValue<uint32>(data, dataSize);
 
        typedef typename ElfClass::NoteAreaEntry Entry;
-       const Entry* table = (Entry*)((const uint8*)data + addressSize);
-       dataSize -= addressSize;
 
        if (areaCount == 0)
                return B_OK;
 
-       // check area count
-       if (areaCount > dataSize || areaCount * sizeof(Entry) >= dataSize) {
-               WARNING("Areas note too short for area count\n");
+       // check entry size and area count
+       if (entrySize == 0 || dataSize == 0 || areaCount > dataSize
+                       || dataSize - 1 < entrySize || areaCount * entrySize >= 
dataSize) {
+               WARNING("Areas note: too short or invalid entry size (%" 
B_PRIu32 ")\n",
+                       entrySize);
                return B_BAD_DATA;
        }
 
        // check, if strings are null-terminated
-       const char* strings = (const char*)(table + areaCount);
-       size_t stringsSize = dataSize - areaCount * sizeof(Entry);
+       const char* strings = (const char*)data + areaCount * entrySize;
+       size_t stringsSize = dataSize - areaCount * entrySize;
        if (stringsSize == 0 || strings[stringsSize - 1] != '\0') {
                WARNING("Areas note strings not terminated\n");
                return B_BAD_DATA;
@@ -380,8 +393,8 @@ CoreFile::_ReadAreasNote(const void* data, uint32 dataSize)
 
        for (uint64 i = 0; i < areaCount; i++) {
                // get entry values
-               Entry entry;
-               memcpy(&entry, table, sizeof(entry));
+               Entry entry = {};
+               _ReadEntry(data, dataSize, entry, entrySize);
 
                int32 id = Get(entry.na_id);
                uint64 baseAddress = Get(entry.na_base);
@@ -413,8 +426,6 @@ CoreFile::_ReadAreasNote(const void* data, uint32 dataSize)
                        delete area;
                        return B_NO_MEMORY;
                }
-
-               table++;
        }
 
        return B_OK;
@@ -425,29 +436,29 @@ template<typename ElfClass>
 status_t
 CoreFile::_ReadImagesNote(const void* data, uint32 dataSize)
 {
-       const size_t addressSize = sizeof(typename ElfClass::Size);
-       if (dataSize < addressSize) {
+       if (dataSize < 2 * sizeof(uint32)) {
                WARNING("Images note too short\n");
                return B_BAD_DATA;
        }
-       uint64 imageCount = Get(*(const typename ElfClass::Size*)data);
+       uint32 imageCount = _ReadValue<uint32>(data, dataSize);
+       uint32 entrySize = _ReadValue<uint32>(data, dataSize);
 
        typedef typename ElfClass::NoteImageEntry Entry;
-       const Entry* table = (Entry*)((const uint8*)data + addressSize);
-       dataSize -= addressSize;
 
        if (imageCount == 0)
                return B_OK;
 
-       // check image count
-       if (imageCount > dataSize || imageCount * sizeof(Entry) >= dataSize) {
-               WARNING("Images note too short for image count\n");
+       // check entry size and image count
+       if (entrySize == 0 || dataSize == 0 || imageCount > dataSize
+                       || dataSize - 1 < entrySize || imageCount * entrySize 

= dataSize) {
+               WARNING("Images note: too short or invalid entry size (%" 
B_PRIu32
+                       ")\n", entrySize);
                return B_BAD_DATA;
        }
 
        // check, if strings are null-terminated
-       const char* strings = (const char*)(table + imageCount);
-       size_t stringsSize = dataSize - imageCount * sizeof(Entry);
+       const char* strings = (const char*)data + imageCount * entrySize;
+       size_t stringsSize = dataSize - imageCount * entrySize;
        if (stringsSize == 0 || strings[stringsSize - 1] != '\0') {
                WARNING("Images note strings not terminated\n");
                return B_BAD_DATA;
@@ -455,8 +466,8 @@ CoreFile::_ReadImagesNote(const void* data, uint32 dataSize)
 
        for (uint64 i = 0; i < imageCount; i++) {
                // get entry values
-               Entry entry;
-               memcpy(&entry, table, sizeof(entry));
+               Entry entry = {};
+               _ReadEntry(data, dataSize, entry, entrySize);
 
                int32 id = Get(entry.ni_id);
                int32 type = Get(entry.ni_type);
@@ -494,8 +505,6 @@ CoreFile::_ReadImagesNote(const void* data, uint32 dataSize)
                        delete image;
                        return B_NO_MEMORY;
                }
-
-               table++;
        }
 
        return B_OK;
@@ -506,40 +515,39 @@ template<typename ElfClass>
 status_t
 CoreFile::_ReadThreadsNote(const void* data, uint32 dataSize)
 {
-       const size_t addressSize = sizeof(typename ElfClass::Size);
-       if (dataSize < 2 * addressSize) {
+       if (dataSize < 3 * sizeof(uint32)) {
                WARNING("Threads note too short\n");
                return B_BAD_DATA;
        }
-
-       const typename ElfClass::Size* header
-               = (const typename ElfClass::Size*)data;
-       uint64 threadCount = Get(header[0]);
-       uint64 cpuStateSize = Get(header[1]);
+       uint32 threadCount = _ReadValue<uint32>(data, dataSize);
+       uint32 entrySize = _ReadValue<uint32>(data, dataSize);
+       uint32 cpuStateSize = _ReadValue<uint32>(data, dataSize);
 
        if (cpuStateSize > 1024 * 1024) {
-               WARNING("Threads note: unreasonable CPU state size: %" B_PRIu64 
"\n",
+               WARNING("Threads note: unreasonable CPU state size: %" B_PRIu32 
"\n",
                        cpuStateSize);
                return B_BAD_DATA;
        }
 
        typedef typename ElfClass::NoteThreadEntry Entry;
-       const uint8* table = (const uint8*)(header + 2);
-       dataSize -= 2 * addressSize;
 
-       size_t totalEntrySize = sizeof(Entry) + (size_t)cpuStateSize;
+       if (threadCount == 0)
+               return B_OK;
+
+       size_t totalEntrySize = entrySize + cpuStateSize;
 
-       // check thread count
-       if (threadCount > dataSize || threadCount * totalEntrySize >= dataSize) 
{
-               WARNING("Threads note too short for thread count\n");
+       // check entry size and thread count
+       if (entrySize == 0 || dataSize == 0 || threadCount > dataSize
+                       || entrySize > dataSize || cpuStateSize > dataSize
+                       || dataSize - 1 < totalEntrySize
+                       || threadCount * totalEntrySize >= dataSize) {
+               WARNING("Threads note: too short or invalid entry size (%" 
B_PRIu32
+                       ")\n", entrySize);
                return B_BAD_DATA;
        }
 
-       if (threadCount == 0)
-               return B_OK;
-
        // check, if strings are null-terminated
-       const char* strings = (const char*)(table + threadCount * 
totalEntrySize);
+       const char* strings = (const char*)data + threadCount * totalEntrySize;
        size_t stringsSize = dataSize - threadCount * totalEntrySize;
        if (stringsSize == 0 || strings[stringsSize - 1] != '\0') {
                WARNING("Threads note strings not terminated\n");
@@ -548,8 +556,8 @@ CoreFile::_ReadThreadsNote(const void* data, uint32 
dataSize)
 
        for (uint64 i = 0; i < threadCount; i++) {
                // get entry values
-               Entry entry;
-               memcpy(&entry, table, sizeof(entry));
+               Entry entry = {};
+               _ReadEntry(data, dataSize, entry, entrySize);
 
                int32 id = Get(entry.nth_id);
                int32 state = Get(entry.nth_state);
@@ -581,11 +589,9 @@ CoreFile::_ReadThreadsNote(const void* data, uint32 
dataSize)
                }
 
                // get CPU state
-               const void* cpuState = table + sizeof(Entry);
-               if (!thread->SetCpuState(cpuState, cpuStateSize))
+               if (!thread->SetCpuState(data, cpuStateSize))
                        return B_NO_MEMORY;
-
-               table += totalEntrySize;
+               _Advance(data, dataSize, cpuStateSize);
        }
 
        return B_OK;
@@ -622,3 +628,29 @@ CoreFile::_FindAreaSegment(uint64 address) const
 }
 
 
+template<typename Type>
+Type
+CoreFile::_ReadValue(const void*& data, uint32& dataSize)
+{
+       Type value = Get(*(const Type*)data);
+       _Advance(data, dataSize, sizeof(Type));
+       return value;
+}
+
+
+template<typename Entry>
+void
+CoreFile::_ReadEntry(const void*& data, uint32& dataSize, Entry& entry,
+       size_t entrySize)
+{
+       memcpy(&entry, data, std::min(sizeof(entry), entrySize));
+       _Advance(data, dataSize, entrySize);
+}
+
+
+void
+CoreFile::_Advance(const void*& data, uint32& dataSize, size_t by)
+{
+       data = (const uint8*)data + by;
+       dataSize -= by;
+}
diff --git a/src/apps/debugger/elf/CoreFile.h b/src/apps/debugger/elf/CoreFile.h
index b20b134..0cb067c 100644
--- a/src/apps/debugger/elf/CoreFile.h
+++ b/src/apps/debugger/elf/CoreFile.h
@@ -179,6 +179,14 @@ private:
                        CoreFileAreaInfo*       _FindArea(uint64 address) const;
                        ElfSegment*                     _FindAreaSegment(uint64 
address) const;
 
+                       template<typename Type>
+                       Type                            _ReadValue(const void*& 
data, uint32& dataSize);
+                       template<typename Entry>
+                       void                            _ReadEntry(const void*& 
data, uint32& dataSize,
+                                                                       Entry& 
entry, size_t entrySize);
+                       void                            _Advance(const void*& 
data, uint32& dataSize,
+                                                                       size_t 
by);
+
                        template<typename Value>
                        Value                           Get(const Value& value) 
const
                                                                        { 
return fElfFile.Get(value); }
diff --git a/src/system/kernel/debug/core_dump.cpp 
b/src/system/kernel/debug/core_dump.cpp
index 69857dc..bee04aa 100644
--- a/src/system/kernel/debug/core_dump.cpp
+++ b/src/system/kernel/debug/core_dump.cpp
@@ -1134,7 +1134,8 @@ private:
                note.nt_id = fTeamInfo.team;
                note.nt_uid = fTeamInfo.uid;
                note.nt_gid = fTeamInfo.gid;
-               writer.Write(&note, sizeof(note));
+               writer.Write((uint32)sizeof(note));
+               writer.Write(note);
 
                // write args
                const char* args = fTeamInfo.args;
@@ -1214,7 +1215,8 @@ private:
        void _WriteAreasNote(Writer& writer)
        {
                // area count
-               writer.Write(fAreaCount);
+               writer.Write((uint32)fAreaCount);
+               writer.Write((uint32)sizeof(elf_note_area_entry));
 
                // write table
                for (AreaInfoList::Iterator it = fAreaInfos.GetIterator();
@@ -1227,7 +1229,7 @@ private:
                        entry.na_base = areaInfo->Base();
                        entry.na_size = areaInfo->Size();
                        entry.na_ram_size = areaInfo->RamSize();
-                       writer.Write(&entry, sizeof(entry));
+                       writer.Write(entry);
                }
 
                // write strings
@@ -1261,7 +1263,8 @@ private:
        void _WriteImagesNote(Writer& writer)
        {
                // image count
-               writer.Write(fImageCount);
+               writer.Write((uint32)fImageCount);
+               writer.Write((uint32)sizeof(elf_note_image_entry));
 
                // write table
                for (ImageInfoList::Iterator it = fImageInfos.GetIterator();
@@ -1278,7 +1281,7 @@ private:
                        entry.ni_text_size = imageInfo->TextSize();
                        entry.ni_data_base = imageInfo->DataBase();
                        entry.ni_data_size = imageInfo->DataSize();
-                       writer.Write(&entry, sizeof(entry));
+                       writer.Write(entry);
                }
 
                // write strings
@@ -1312,8 +1315,9 @@ private:
        void _WriteThreadsNote(Writer& writer)
        {
                // thread count and size of CPU state
-               writer.Write(fThreadCount);
-               writer.Write(sizeof(debug_cpu_state));
+               writer.Write((uint32)fThreadCount);
+               writer.Write((uint32)sizeof(elf_note_thread_entry));
+               writer.Write((uint32)sizeof(debug_cpu_state));
 
                // write table
                for (ThreadStateList::Iterator it = fThreadStates.GetIterator();


Other related posts:

  • » [haiku-commits] haiku: hrev50256 - src/apps/debugger/elf headers/os/kernel src/system/kernel/debug - ingo_weinhold