Skip to content

Commit fd2cce5

Browse files
author
Alex B
committed
Fix issue with incorrect header struct size
1 parent a3d14ff commit fd2cce5

File tree

3 files changed

+16
-8
lines changed

3 files changed

+16
-8
lines changed

lld/MachO/SyntheticSections.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,8 +1990,7 @@ void ObjCMethListSection::setUp() {
19901990
for (const ConcatInputSection *isec : inputs) {
19911991
uint32_t structSizeAndFlags = 0, structCount = 0;
19921992
readMethodListHeader(isec->data.data(), structSizeAndFlags, structCount);
1993-
uint32_t structSize = structSizeAndFlags & m_structSizeMask;
1994-
1993+
uint32_t originalStructSize = structSizeAndFlags & structSizeMask;
19951994
// Method name is immediately after header
19961995
uint32_t methodNameOff = methodListHeaderSize;
19971996

@@ -2008,7 +2007,7 @@ void ObjCMethListSection::setUp() {
20082007
ObjCSelRefsHelper::makeSelRef(methname);
20092008

20102009
// Jump to method name offset in next struct
2011-
methodNameOff += structSize;
2010+
methodNameOff += originalStructSize;
20122011
}
20132012
}
20142013
}
@@ -2137,8 +2136,15 @@ ObjCMethListSection::writeRelativeMethodList(const ConcatInputSection *isec,
21372136
// value flag
21382137
uint32_t structSizeAndFlags = 0, structCount = 0;
21392138
readMethodListHeader(isec->data.data(), structSizeAndFlags, structCount);
2140-
structSizeAndFlags |= relMethodHeaderFlag;
2141-
writeMethodListHeader(buf, structSizeAndFlags, structCount);
2139+
// Set the struct size for the relative method list
2140+
uint32_t relativeStructSizeAndFlags =
2141+
(relativeOffsetSize * pointersPerStruct) & structSizeMask;
2142+
// Carry over the old flags from the input struct
2143+
relativeStructSizeAndFlags |= structSizeAndFlags & structFlagsMask;
2144+
// Set the relative method list flag
2145+
relativeStructSizeAndFlags |= relMethodHeaderFlag;
2146+
2147+
writeMethodListHeader(buf, relativeStructSizeAndFlags, structCount);
21422148

21432149
assert(methodListHeaderSize +
21442150
(structCount * pointersPerStruct * target->wordSize) ==

lld/MachO/SyntheticSections.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,9 @@ class ObjCMethListSection final : public SyntheticSection {
720720
// The runtime identifies relative method lists via this magic value
721721
static constexpr uint32_t relMethodHeaderFlag = 0x80000000;
722722
// In the method list header, the first 2 bytes are the size of struct
723-
static constexpr uint32_t m_structSizeMask = 0xFFFF;
723+
static constexpr uint32_t structSizeMask = 0x0000FFFF;
724+
// In the method list header, the last 2 bytes are the flags for the struct
725+
static constexpr uint32_t structFlagsMask = 0xFFFF0000;
724726
// Relative method lists have 4 byte alignment as all data in the InputSection
725727
// is 4 byte
726728
static constexpr uint32_t relativeOffsetSize = sizeof(uint32_t);

lld/test/MachO/objc-relative-method-lists-simple.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
CHK_REL: Contents of (__DATA_CONST,__objc_classlist) section
1717
CHK_REL-NEXT: _OBJC_CLASS_$_MyClass
1818
CHK_REL: baseMethods
19-
CHK_REL-NEXT: entsize 24 (relative)
19+
CHK_REL-NEXT: entsize 12 (relative)
2020
CHK_REL-NEXT: count 3
2121
CHK_REL-NEXT: name 0x{{[0-9a-f]*}} (0x{{[0-9a-f]*}}) instance_method_00
2222
CHK_REL-NEXT: types 0x{{[0-9a-f]*}} (0x{{[0-9a-f]*}}) v16@0:8
@@ -31,7 +31,7 @@ CHK_REL-NEXT: imp 0x{{[0-9a-f]*}} (0x{{[0-9a-f]*}}) -[MyClass instance_method
3131
CHK_REL: Meta Class
3232
CHK_REL-NEXT: isa 0x{{[0-9a-f]*}} _OBJC_METACLASS_$_MyClass
3333
CHK_REL: baseMethods 0x{{[0-9a-f]*}} (struct method_list_t *)
34-
CHK_REL-NEXT: entsize 24 (relative)
34+
CHK_REL-NEXT: entsize 12 (relative)
3535
CHK_REL-NEXT: count 3
3636
CHK_REL-NEXT: name 0x{{[0-9a-f]*}} (0x{{[0-9a-f]*}}) class_method_00
3737
CHK_REL-NEXT: types 0x{{[0-9a-f]*}} (0x{{[0-9a-f]*}}) v16@0:8

0 commit comments

Comments
 (0)