Skip to content

Commit 48f4ebd

Browse files
authored
Merge pull request #11465 from jasonmolenda/r160384968-larger-va-offset-fields
[lldb][MachO] Local structs for larger VA offsets (llvm#159849)
2 parents 150d508 + e5afeda commit 48f4ebd

File tree

2 files changed

+171
-43
lines changed

2 files changed

+171
-43
lines changed

lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp

Lines changed: 33 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,10 +2161,10 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
21612161
LLDB_LOG(log, "Parsing symbol table for {0}", file_name);
21622162
Progress progress("Parsing symbol table", file_name);
21632163

2164-
llvm::MachO::linkedit_data_command function_starts_load_command = {0, 0, 0, 0};
2165-
llvm::MachO::linkedit_data_command exports_trie_load_command = {0, 0, 0, 0};
2166-
llvm::MachO::dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
2167-
llvm::MachO::dysymtab_command dysymtab = m_dysymtab;
2164+
LinkeditDataCommandLargeOffsets function_starts_load_command;
2165+
LinkeditDataCommandLargeOffsets exports_trie_load_command;
2166+
DyldInfoCommandLargeOffsets dyld_info;
2167+
DysymtabCommandLargeOffsets dysymtab(m_dysymtab);
21682168
SymtabCommandLargeOffsets symtab_load_command;
21692169
// The data element of type bool indicates that this entry is thumb
21702170
// code.
@@ -2201,32 +2201,24 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
22012201
break;
22022202
// Watch for the symbol table load command
22032203
switch (lc.cmd) {
2204-
case LC_SYMTAB:
2205-
// struct symtab_command {
2206-
// uint32_t cmd; /* LC_SYMTAB */
2207-
// uint32_t cmdsize; /* sizeof(struct symtab_command) */
2208-
// uint32_t symoff; /* symbol table offset */
2209-
// uint32_t nsyms; /* number of symbol table entries */
2210-
// uint32_t stroff; /* string table offset */
2211-
// uint32_t strsize; /* string table size in bytes */
2212-
// };
2213-
symtab_load_command.cmd = lc.cmd;
2214-
symtab_load_command.cmdsize = lc.cmdsize;
2215-
symtab_load_command.symoff = m_data.GetU32(&offset);
2216-
symtab_load_command.nsyms = m_data.GetU32(&offset);
2217-
symtab_load_command.stroff = m_data.GetU32(&offset);
2218-
symtab_load_command.strsize = m_data.GetU32(&offset);
2219-
break;
2204+
case LC_SYMTAB: {
2205+
llvm::MachO::symtab_command lc_obj;
2206+
if (m_data.GetU32(&offset, &lc_obj.symoff, 4)) {
2207+
lc_obj.cmd = lc.cmd;
2208+
lc_obj.cmdsize = lc.cmdsize;
2209+
symtab_load_command = lc_obj;
2210+
}
2211+
} break;
22202212

22212213
case LC_DYLD_INFO:
2222-
case LC_DYLD_INFO_ONLY:
2223-
if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10)) {
2224-
dyld_info.cmd = lc.cmd;
2225-
dyld_info.cmdsize = lc.cmdsize;
2226-
} else {
2227-
memset(&dyld_info, 0, sizeof(dyld_info));
2214+
case LC_DYLD_INFO_ONLY: {
2215+
llvm::MachO::dyld_info_command lc_obj;
2216+
if (m_data.GetU32(&offset, &lc_obj.rebase_off, 10)) {
2217+
lc_obj.cmd = lc.cmd;
2218+
lc_obj.cmdsize = lc.cmdsize;
2219+
dyld_info = lc_obj;
22282220
}
2229-
break;
2221+
} break;
22302222

22312223
case LC_LOAD_DYLIB:
22322224
case LC_LOAD_WEAK_DYLIB:
@@ -2250,22 +2242,20 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
22502242
}
22512243
} break;
22522244

2253-
case LC_DYLD_EXPORTS_TRIE:
2254-
exports_trie_load_command.cmd = lc.cmd;
2255-
exports_trie_load_command.cmdsize = lc.cmdsize;
2256-
if (m_data.GetU32(&offset, &exports_trie_load_command.dataoff, 2) ==
2257-
nullptr) // fill in offset and size fields
2258-
memset(&exports_trie_load_command, 0,
2259-
sizeof(exports_trie_load_command));
2260-
break;
2261-
case LC_FUNCTION_STARTS:
2262-
function_starts_load_command.cmd = lc.cmd;
2263-
function_starts_load_command.cmdsize = lc.cmdsize;
2264-
if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) ==
2265-
nullptr) // fill in data offset and size fields
2266-
memset(&function_starts_load_command, 0,
2267-
sizeof(function_starts_load_command));
2268-
break;
2245+
case LC_DYLD_EXPORTS_TRIE: {
2246+
llvm::MachO::linkedit_data_command lc_obj;
2247+
lc_obj.cmd = lc.cmd;
2248+
lc_obj.cmdsize = lc.cmdsize;
2249+
if (m_data.GetU32(&offset, &lc_obj.dataoff, 2))
2250+
exports_trie_load_command = lc_obj;
2251+
} break;
2252+
case LC_FUNCTION_STARTS: {
2253+
llvm::MachO::linkedit_data_command lc_obj;
2254+
lc_obj.cmd = lc.cmd;
2255+
lc_obj.cmdsize = lc.cmdsize;
2256+
if (m_data.GetU32(&offset, &lc_obj.dataoff, 2))
2257+
function_starts_load_command = lc_obj;
2258+
} break;
22692259

22702260
case LC_UUID: {
22712261
const uint8_t *uuid_bytes = m_data.PeekData(offset, 16);

lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,18 @@ class ObjectFileMachO : public lldb_private::ObjectFile {
263263
// in virtual address layout from the start of the TEXT segment, and
264264
// that span may be larger than 4GB.
265265
struct SymtabCommandLargeOffsets {
266+
SymtabCommandLargeOffsets() {}
267+
SymtabCommandLargeOffsets(const llvm::MachO::symtab_command &in)
268+
: cmd(in.cmd), cmdsize(in.cmdsize), symoff(in.symoff), nsyms(in.nsyms),
269+
stroff(in.stroff), strsize(in.strsize) {}
270+
void operator=(const llvm::MachO::symtab_command &in) {
271+
cmd = in.cmd;
272+
cmdsize = in.cmdsize;
273+
symoff = in.symoff;
274+
nsyms = in.nsyms;
275+
stroff = in.stroff;
276+
strsize = in.strsize;
277+
}
266278
uint32_t cmd = 0; /* LC_SYMTAB */
267279
uint32_t cmdsize = 0; /* sizeof(struct symtab_command) */
268280
lldb::offset_t symoff = 0; /* symbol table offset */
@@ -271,6 +283,132 @@ class ObjectFileMachO : public lldb_private::ObjectFile {
271283
uint32_t strsize = 0; /* string table size in bytes */
272284
};
273285

286+
// The LC_DYLD_INFO's dyld_info_command has 32-bit file offsets
287+
// that we will use as virtual address offsets, and may need to span
288+
// more than 4GB in virtual memory.
289+
struct DyldInfoCommandLargeOffsets {
290+
DyldInfoCommandLargeOffsets() {}
291+
DyldInfoCommandLargeOffsets(const llvm::MachO::dyld_info_command &in)
292+
: cmd(in.cmd), cmdsize(in.cmdsize), rebase_off(in.rebase_off),
293+
rebase_size(in.rebase_size), bind_off(in.bind_off),
294+
bind_size(in.bind_size), weak_bind_off(in.weak_bind_off),
295+
weak_bind_size(in.weak_bind_size), lazy_bind_off(in.lazy_bind_off),
296+
lazy_bind_size(in.lazy_bind_size), export_off(in.export_off),
297+
export_size(in.export_size) {}
298+
299+
void operator=(const llvm::MachO::dyld_info_command &in) {
300+
cmd = in.cmd;
301+
cmdsize = in.cmdsize;
302+
rebase_off = in.rebase_off;
303+
rebase_size = in.rebase_size;
304+
bind_off = in.bind_off;
305+
bind_size = in.bind_size;
306+
weak_bind_off = in.weak_bind_off;
307+
weak_bind_size = in.weak_bind_size;
308+
lazy_bind_off = in.lazy_bind_off;
309+
lazy_bind_size = in.lazy_bind_size;
310+
export_off = in.export_off;
311+
export_size = in.export_size;
312+
};
313+
314+
/// LC_DYLD_INFO or LC_DYLD_INFO_ONLY
315+
uint32_t cmd = 0;
316+
uint32_t cmdsize = 0; /* sizeof(struct dyld_info_command) */
317+
lldb::offset_t rebase_off = 0; /* file offset to rebase info */
318+
uint32_t rebase_size = 0; /* size of rebase info */
319+
lldb::offset_t bind_off = 0; /* file offset to binding info */
320+
uint32_t bind_size = 0; /* size of binding info */
321+
lldb::offset_t weak_bind_off = 0; /* file offset to weak binding info */
322+
uint32_t weak_bind_size = 0; /* size of weak binding info */
323+
lldb::offset_t lazy_bind_off = 0; /* file offset to lazy binding info */
324+
uint32_t lazy_bind_size = 0; /* size of lazy binding infs */
325+
lldb::offset_t export_off = 0; /* file offset to lazy binding info */
326+
uint32_t export_size = 0; /* size of lazy binding infs */
327+
};
328+
329+
/// The LC_DYSYMTAB's dysymtab_command has 32-bit file offsets
330+
/// that we will use as virtual address offsets, and may need to span
331+
/// more than 4GB in virtual memory.
332+
struct DysymtabCommandLargeOffsets {
333+
DysymtabCommandLargeOffsets() {}
334+
DysymtabCommandLargeOffsets(const llvm::MachO::dysymtab_command &in)
335+
: cmd(in.cmd), cmdsize(in.cmdsize), ilocalsym(in.ilocalsym),
336+
nlocalsym(in.nlocalsym), iextdefsym(in.iextdefsym),
337+
nextdefsym(in.nextdefsym), iundefsym(in.iundefsym),
338+
nundefsym(in.nundefsym), tocoff(in.tocoff), ntoc(in.ntoc),
339+
modtaboff(in.modtaboff), nmodtab(in.nmodtab),
340+
extrefsymoff(in.extrefsymoff), nextrefsyms(in.nextrefsyms),
341+
indirectsymoff(in.indirectsymoff), nindirectsyms(in.nindirectsyms),
342+
extreloff(in.extreloff), nextrel(in.nextrel), locreloff(in.locreloff),
343+
nlocrel(in.nlocrel) {}
344+
345+
void operator=(const llvm::MachO::dysymtab_command &in) {
346+
cmd = in.cmd;
347+
cmdsize = in.cmdsize;
348+
ilocalsym = in.ilocalsym;
349+
nlocalsym = in.nlocalsym;
350+
iextdefsym = in.iextdefsym;
351+
nextdefsym = in.nextdefsym;
352+
iundefsym = in.iundefsym;
353+
nundefsym = in.nundefsym;
354+
tocoff = in.tocoff;
355+
ntoc = in.ntoc;
356+
modtaboff = in.modtaboff;
357+
nmodtab = in.nmodtab;
358+
extrefsymoff = in.extrefsymoff;
359+
nextrefsyms = in.nextrefsyms;
360+
indirectsymoff = in.indirectsymoff;
361+
nindirectsyms = in.nindirectsyms;
362+
extreloff = in.extreloff;
363+
nextrel = in.nextrel;
364+
locreloff = in.locreloff;
365+
nlocrel = in.nlocrel;
366+
};
367+
368+
uint32_t cmd = 0; /* LC_DYSYMTAB */
369+
uint32_t cmdsize = 0; /* sizeof(struct dysymtab_command) */
370+
uint32_t ilocalsym = 0; /* index to local symbols */
371+
uint32_t nlocalsym = 0; /* number of local symbols */
372+
uint32_t iextdefsym = 0; /* index to externally defined symbols */
373+
uint32_t nextdefsym = 0; /* number of externally defined symbols */
374+
uint32_t iundefsym = 0; /* index to undefined symbols */
375+
uint32_t nundefsym = 0; /* number of undefined symbols */
376+
lldb::offset_t tocoff = 0; /* file offset to table of contents */
377+
uint32_t ntoc = 0; /* number of entries in table of contents */
378+
lldb::offset_t modtaboff = 0; /* file offset to module table */
379+
uint32_t nmodtab = 0; /* number of module table entries */
380+
lldb::offset_t extrefsymoff = 0; /* offset to referenced symbol table */
381+
uint32_t nextrefsyms = 0; /* number of referenced symbol table entries */
382+
lldb::offset_t indirectsymoff =
383+
0; /* file offset to the indirect symbol table */
384+
uint32_t nindirectsyms = 0; /* number of indirect symbol table entries */
385+
lldb::offset_t extreloff = 0; /* offset to external relocation entries */
386+
uint32_t nextrel = 0; /* number of external relocation entries */
387+
lldb::offset_t locreloff = 0; /* offset to local relocation entries */
388+
uint32_t nlocrel = 0; /* number of local relocation entries */
389+
};
390+
391+
// The linkedit_data_command is used in several load commands including
392+
// LC_FUNCTION_STARTS and LC_DYLD_EXPORTS_TRIE. It has a 32-bit file offset
393+
// that may need to span more than 4GB in real virtual addresses.
394+
struct LinkeditDataCommandLargeOffsets {
395+
LinkeditDataCommandLargeOffsets() {}
396+
LinkeditDataCommandLargeOffsets(
397+
const llvm::MachO::linkedit_data_command &in)
398+
: cmd(in.cmd), cmdsize(in.cmdsize), dataoff(in.dataoff),
399+
datasize(in.datasize) {}
400+
void operator=(const llvm::MachO::linkedit_data_command &in) {
401+
cmd = in.cmd;
402+
cmdsize = in.cmdsize;
403+
dataoff = in.dataoff;
404+
datasize = in.datasize;
405+
}
406+
uint32_t cmd = 0; /* LC_FUNCTION_STARTS, LC_DYLD_EXPORTS_TRIE, etc */
407+
uint32_t cmdsize = 0; /* sizeof(struct linkedit_data_command) */
408+
lldb::offset_t dataoff = 0; /* file offset of data in __LINKEDIT segment */
409+
uint32_t datasize = 0; /* file size of data in __LINKEDIT segment */
410+
};
411+
274412
/// Get the list of binary images that were present in the process
275413
/// when the corefile was produced.
276414
/// \return

0 commit comments

Comments
 (0)