Skip to content

Commit 97a6e02

Browse files
[Core][32 bit] AIX 32 bit coredump support (#97)
1 parent 6530bc3 commit 97a6e02

File tree

9 files changed

+352
-44
lines changed

9 files changed

+352
-44
lines changed

lldb/source/Plugins/DynamicLoader/AIX-DYLD/DynamicLoaderAIXDYLD.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,59 @@ void DynamicLoaderAIXDYLD::FillCoreLoaderData(lldb_private::DataExtractor &data,
289289
}
290290
}
291291

292+
void DynamicLoaderAIXDYLD::FillCoreLoader32Data(lldb_private::DataExtractor &data,
293+
uint64_t loader_offset, uint64_t loader_size ) {
294+
295+
Log *log = GetLog(LLDBLog::DynamicLoader);
296+
LLDB_LOGF(log, "DynamicLoaderAIXDYLD::%s()", __FUNCTION__);
297+
static char *buffer = (char *)malloc(loader_size);
298+
if (buffer == NULL) {
299+
LLDB_LOG(log, "Buffer allocation failed error: {0}", std::strerror(errno));
300+
return;
301+
}
302+
char *ptr = buffer, filename[PATH_MAX], membername[32];
303+
uint64_t dataorg, textorg, datasize, textsize, core_offset;
304+
int next = 1;
305+
lldb::offset_t base_offset = loader_offset;
306+
while (next != 0)
307+
{
308+
lldb::offset_t offset = base_offset;
309+
next = data.GetU32(&offset);
310+
core_offset = data.GetU32(&offset);
311+
textorg = data.GetU32(&offset);
312+
textsize = data.GetU32(&offset);
313+
dataorg = data.GetU32(&offset);
314+
datasize = data.GetU32(&offset);
315+
316+
size_t s1_index = 0, s2_index = 0;
317+
uint8_t byte;
318+
319+
while ((byte = data.GetU8(&offset)) != '\0') {
320+
filename[s1_index++] = static_cast<char>(byte);
321+
}
322+
filename[s1_index] = '\0';
323+
while ((byte = data.GetU8(&offset)) != '\0') {
324+
membername[s2_index++] = static_cast<char>(byte);
325+
}
326+
membername[s2_index] = '\0';
327+
base_offset += next;
328+
char pathWithMember[PATH_MAX] = {0};
329+
if (strlen(membername) > 0) {
330+
sprintf(pathWithMember, "%s(%s)", filename, membername);
331+
} else {
332+
sprintf(pathWithMember, "%s", filename);
333+
}
334+
335+
FileSpec file(pathWithMember);
336+
ModuleSpec module_spec(file, m_process->GetTarget().GetArchitecture());
337+
if (ModuleSP module_sp = m_process->GetTarget().GetOrCreateModule(module_spec, true /* notify */)) {
338+
UpdateLoadedSectionsByType(module_sp, LLDB_INVALID_ADDRESS, (lldb::addr_t)textorg, false, 1);
339+
UpdateLoadedSectionsByType(module_sp, LLDB_INVALID_ADDRESS, (lldb::addr_t)dataorg, false, 2);
340+
// FIXME: .tdata, .bss
341+
}
342+
}
343+
}
344+
292345
void DynamicLoaderAIXDYLD::DidAttach() {
293346
Log *log = GetLog(LLDBLog::DynamicLoader);
294347
LLDB_LOGF(log, "DynamicLoaderAIXDYLD::%s()", __FUNCTION__);

lldb/source/Plugins/DynamicLoader/AIX-DYLD/DynamicLoaderAIXDYLD.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class DynamicLoaderAIXDYLD : public DynamicLoader {
3535

3636
void FillCoreLoaderData(lldb_private::DataExtractor &data,
3737
uint64_t loader_offset, uint64_t loader_size);
38+
void FillCoreLoader32Data(lldb_private::DataExtractor &data,
39+
uint64_t loader_offset, uint64_t loader_size);
3840

3941
void DidAttach() override;
4042
void DidLaunch() override;

lldb/source/Plugins/ObjectFile/AIXCore/ObjectFileAIXCore.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,6 @@ static bool AIXCoreHeaderCheckFromMagic(uint32_t magic) {
126126
bool ret = false;
127127
switch (magic) {
128128
case AIXCORE32:
129-
LLDB_LOGF(log, "ObjectFileAIXCore: 32-bit not supported");
130-
break;
131129
case AIXCORE64:
132130
m_is_core = true;
133131
ret = true;

lldb/source/Plugins/Process/aix-core/AIXCore.cpp

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,96 @@ using namespace lldb;
2323
using namespace lldb_private;
2424

2525
AIXCore64Header::AIXCore64Header() { memset(this, 0, sizeof(AIXCore64Header)); }
26+
AIXCore32Header::AIXCore32Header() { memset(this, 0, sizeof(AIXCore32Header)); }
2627

2728

29+
bool AIXCore32Header::ParseRegisterContext(lldb_private::DataExtractor &data,
30+
lldb::offset_t *offset) {
31+
*offset += 20; // skip till curid in mstsave32
32+
Fault.context.excp_type = data.GetU32(offset);
33+
Fault.context.pc = data.GetU32(offset);
34+
Fault.context.msr = data.GetU32(offset);
35+
Fault.context.cr = data.GetU32(offset);
36+
Fault.context.lr = data.GetU32(offset);
37+
Fault.context.ctr = data.GetU32(offset);
38+
Fault.context.xer = data.GetU32(offset);
39+
// need to skip 0-39 U32s after this upto gpr
40+
/* *offset += 8; // mq, tid
41+
Fault.context.fpscr = data.GetU32(offset);
42+
Fault.context.fpeu = data.GetU8(offset);
43+
Fault.context.fpinfo = data.GetU8(offset);
44+
Fault.context.fpscr24_31 = data.GetU8(offset);
45+
*/
46+
// Skipping unneeded data
47+
for(int i = 0; i < 40; i++)
48+
data.GetU32(offset);
49+
for(int i = 0; i < 32; i++) {
50+
Fault.context.gpr[i] = data.GetU32(offset);
51+
}
52+
for(int i = 0; i < 32; i++)
53+
Fault.context.fpr[i] = data.GetU32(offset);
54+
return true;
55+
}
56+
57+
bool AIXCore32Header::ParseThreadContext(lldb_private::DataExtractor &data,
58+
lldb::offset_t *offset) {
59+
lldb::offset_t offset_to_regctx = *offset;
60+
offset_to_regctx += sizeof(thrdsinfo64);
61+
Fault.thread.ti_tid = data.GetU32(offset);
62+
Fault.thread.ti_pid = data.GetU32(offset);
63+
int ret = ParseRegisterContext(data, &offset_to_regctx);
64+
return true;
65+
}
66+
67+
bool AIXCore32Header::ParseUserData(lldb_private::DataExtractor &data,
68+
lldb::offset_t *offset) {
69+
User.process.pi_pid = data.GetU32(offset);
70+
User.process.pi_ppid = data.GetU32(offset);
71+
User.process.pi_sid = data.GetU32(offset);
72+
User.process.pi_pgrp = data.GetU32(offset);
73+
User.process.pi_uid = data.GetU32(offset);
74+
User.process.pi_suid = data.GetU32(offset);
75+
*offset += 728;
76+
77+
ByteOrder byteorder = data.GetByteOrder();
78+
size_t size = 33;
79+
data.ExtractBytes(*offset, size, byteorder, User.process.pi_comm);
80+
offset += size;
81+
82+
return true;
83+
}
84+
85+
bool AIXCore32Header::ParseCoreHeader(lldb_private::DataExtractor &data,
86+
lldb::offset_t *offset) {
87+
SignalNum = data.GetU8(offset);
88+
Flag = data.GetU8(offset);
89+
Entries = data.GetU16(offset);
90+
Version = data.GetU32(offset);
91+
FDInfo = data.GetU64(offset);
92+
93+
LoaderOffset = data.GetU64(offset);
94+
LoaderSize = data.GetU64(offset);
95+
NumberOfThreads = data.GetU32(offset);
96+
Reserved0 = data.GetU32(offset);
97+
ThreadContextOffset = data.GetU64(offset);
98+
NumSegRegion = data.GetU64(offset);
99+
SegRegionOffset = data.GetU64(offset);
100+
StackOffset = data.GetU64(offset);
101+
StackBaseAddr = data.GetU64(offset);
102+
StackSize = data.GetU64(offset);
103+
DataRegionOffset = data.GetU64(offset);
104+
DataBaseAddr = data.GetU64(offset);
105+
DataSize = data.GetU64(offset);
106+
107+
*offset += 104;
108+
lldb::offset_t offset_to_user = (*offset + sizeof(mstsave32) +
109+
sizeof(thrdsinfo64));
110+
int ret = 0;
111+
ret = ParseThreadContext(data, offset);
112+
ret = ParseUserData(data, &offset_to_user);
113+
return true;
114+
}
115+
28116
bool AIXCore64Header::ParseRegisterContext(lldb_private::DataExtractor &data,
29117
lldb::offset_t *offset) {
30118
// The data is arranged in this order in this coredump file
@@ -53,7 +141,6 @@ bool AIXCore64Header::ParseRegisterContext(lldb_private::DataExtractor &data,
53141
}
54142
bool AIXCore64Header::ParseThreadContext(lldb_private::DataExtractor &data,
55143
lldb::offset_t *offset) {
56-
57144
lldb::offset_t offset_to_regctx = *offset;
58145
offset_to_regctx += sizeof(thrdentry64);
59146
Fault.thread.ti_tid = data.GetU64(offset);
@@ -83,7 +170,6 @@ bool AIXCore64Header::ParseUserData(lldb_private::DataExtractor &data,
83170

84171
bool AIXCore64Header::ParseCoreHeader(lldb_private::DataExtractor &data,
85172
lldb::offset_t *offset) {
86-
87173
SignalNum = data.GetU8(offset);
88174
Flag = data.GetU8(offset);
89175
Entries = data.GetU16(offset);
@@ -105,7 +191,6 @@ bool AIXCore64Header::ParseCoreHeader(lldb_private::DataExtractor &data,
105191
DataSize = data.GetU64(offset);
106192

107193
*offset += 104;
108-
109194
// This offset calculation is due to the difference between
110195
// AIX register size and LLDB register variables order.
111196
// __context64 does not match RegContext

lldb/source/Plugins/Process/aix-core/AIXCore.h

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
namespace AIXCORE {
2323

24+
enum CoreVersion : uint64_t {AIXCORE32 = 0xFEEDDB1, AIXCORE64 = 0xFEEDDB2};
2425
struct RegContext {
2526
// The data is arranged in order as filled by AIXCore.cpp in this coredump file
2627
// so we have to fetch in that exact order, refer there.
@@ -52,12 +53,21 @@ struct RegContext {
5253
struct RegContext context;
5354
};
5455

55-
struct UserData {
56+
struct ThreadContext32 {
57+
struct thrdsinfo64 thread;
58+
struct RegContext context; // This one saves mstsave32 and not context64
59+
};
5660

61+
struct UserData {
5762
struct procentry64 process;
5863
unsigned long long reserved[16];
5964
};
6065

66+
struct UserData32 {
67+
struct procsinfo64 process;
68+
unsigned long long reserved[16];
69+
};
70+
6171
struct AIXCore64Header {
6272

6373
int8_t SignalNum; /* signal number (cause of error) */
@@ -119,6 +129,66 @@ struct RegContext {
119129

120130
};
121131

132+
struct AIXCore32Header {
133+
134+
int8_t SignalNum; /* signal number (cause of error) */
135+
int8_t Flag; /* flag to describe core dump type */
136+
uint16_t Entries; /* number of core dump modules */
137+
uint32_t Version; /* core file format number */
138+
uint64_t FDInfo; /* offset to fd region in file */
139+
140+
uint64_t LoaderOffset; /* offset to loader region in file */
141+
uint64_t LoaderSize; /* size of loader region */
142+
143+
uint32_t NumberOfThreads ; /* number of elements in thread table */
144+
uint32_t Reserved0; /* Padding */
145+
uint64_t ThreadContextOffset; /* offset to thread context table */
146+
147+
uint64_t NumSegRegion; /* n of elements in segregion */
148+
uint64_t SegRegionOffset; /* offset to start of segregion table */
149+
150+
uint64_t StackOffset; /* offset of user stack in file */
151+
uint64_t StackBaseAddr; /* base address of user stack region */
152+
uint64_t StackSize; /* size of user stack region */
153+
154+
uint64_t DataRegionOffset; /* offset to user data region */
155+
uint64_t DataBaseAddr; /* base address of user data region */
156+
uint64_t DataSize; /* size of user data region */
157+
uint64_t SDataBase; /* base address of sdata region */
158+
uint64_t SDataSize; /* size of sdata region */
159+
160+
uint64_t NumVMRegions; /* number of anonymously mapped areas */
161+
uint64_t VMOffset; /* offset to start of vm_infox table */
162+
163+
int32_t ProcessorImplementation; /* processor implementation */
164+
uint32_t NumElementsCTX; /* n of elements in extended ctx table*/
165+
uint64_t CPRSOffset; /* Checkpoint/Restart offset */
166+
uint64_t ExtendedContextOffset; /* extended context offset */
167+
uint64_t OffsetUserKey; /* Offset to user-key exception data */
168+
uint64_t OffsetLoaderTLS; /* offset to the loader region in file
169+
when a process uses TLS data */
170+
uint64_t TLSLoaderSize; /* size of the above loader region */
171+
uint64_t ExtendedProcEntry; /* Extended procentry64 information */
172+
uint64_t Reserved[2];
173+
174+
struct ThreadContext32 Fault;
175+
176+
struct UserData32 User;
177+
178+
AIXCore32Header();
179+
180+
bool ParseCoreHeader(lldb_private::DataExtractor &data,
181+
lldb::offset_t *offset);
182+
bool ParseThreadContext(lldb_private::DataExtractor &data,
183+
lldb::offset_t *offset);
184+
bool ParseUserData(lldb_private::DataExtractor &data,
185+
lldb::offset_t *offset);
186+
bool ParseRegisterContext(lldb_private::DataExtractor &data,
187+
lldb::offset_t *offset);
188+
bool ParseLoaderData(lldb_private::DataExtractor &data,
189+
lldb::offset_t *offset);
190+
191+
};
122192

123193
}
124194

0 commit comments

Comments
 (0)