Skip to content

Commit 84c9a57

Browse files
author
Alex B
committed
Address Feedback #1
1 parent 99921f3 commit 84c9a57

File tree

4 files changed

+79
-47
lines changed

4 files changed

+79
-47
lines changed

lld/MachO/SyntheticSections.cpp

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,7 +1979,7 @@ void InitOffsetsSection::setUp() {
19791979
ObjCMethListSection::ObjCMethListSection()
19801980
: SyntheticSection(segment_names::text, section_names::objcMethList) {
19811981
flags = S_ATTR_NO_DEAD_STRIP;
1982-
align = m_align;
1982+
align = relativeOffsetSize;
19831983
}
19841984

19851985
// Go through all input method lists and ensure that we have selrefs for all
@@ -1993,7 +1993,7 @@ void ObjCMethListSection::setUp() {
19931993
uint32_t structSize = structSizeAndFlags & m_structSizeMask;
19941994

19951995
// Method name is immediately after header
1996-
uint32_t methodNameOff = m_methodListHeaderSize;
1996+
uint32_t methodNameOff = methodListHeaderSize;
19971997

19981998
// Loop through all methods, and ensure a selref for each of them exists.
19991999
while (methodNameOff < isec->data.size()) {
@@ -2016,19 +2016,19 @@ void ObjCMethListSection::setUp() {
20162016
// Calculate section size and final offsets for where InputSection's need to be
20172017
// written.
20182018
void ObjCMethListSection::finalize() {
2019-
// m_size will be the total size of the __objc_methlist section
2020-
m_size = 0;
2019+
// sectionSize will be the total size of the __objc_methlist section
2020+
sectionSize = 0;
20212021
for (ConcatInputSection *isec : inputs) {
2022-
// We can also use m_size as write offset for isec
2023-
assert(m_size == alignToPowerOf2(m_size, m_align) &&
2022+
// We can also use sectionSize as write offset for isec
2023+
assert(sectionSize == alignToPowerOf2(sectionSize, relativeOffsetSize) &&
20242024
"expected __objc_methlist to be aligned by default with the "
20252025
"required section alignment");
2026-
isec->outSecOff = m_size;
2026+
isec->outSecOff = sectionSize;
20272027

20282028
isec->isFinal = true;
20292029
uint32_t relativeListSize =
2030-
methodListSizeToRelativeMethodListSize(isec->data.size());
2031-
m_size += relativeListSize;
2030+
computeRelativeMethodListSize(isec->data.size());
2031+
sectionSize += relativeListSize;
20322032

20332033
// If encoding the method list in relative offset format shrinks the size,
20342034
// then we also need to adjust symbol sizes to match the new size. Note that
@@ -2061,7 +2061,7 @@ void ObjCMethListSection::writeTo(uint8_t *bufStart) const {
20612061
uint32_t writtenSize = writeRelativeMethodList(isec, buf);
20622062
buf += writtenSize;
20632063
}
2064-
assert(buf - bufStart == m_size &&
2064+
assert(buf - bufStart == sectionSize &&
20652065
"Written size does not match expected section size");
20662066
}
20672067

@@ -2122,8 +2122,10 @@ void ObjCMethListSection::writeRelativeOffsetForIsec(
21222122
uint32_t delta = symVA - currentVA;
21232123
write32le(buf + outSecOff, delta);
21242124

2125+
// Move one pointer forward in the absolute method list
21252126
inSecOff += target->wordSize;
2126-
outSecOff += sizeof(uint32_t);
2127+
// Move one relative offset forward in the relative method list (32 bits)
2128+
outSecOff += relativeOffsetSize;
21272129
}
21282130

21292131
// Write a relative method list to buf, return the size of the written
@@ -2135,16 +2137,16 @@ ObjCMethListSection::writeRelativeMethodList(const ConcatInputSection *isec,
21352137
// value flag
21362138
uint32_t structSizeAndFlags = 0, structCount = 0;
21372139
readMethodListHeader(isec->data.data(), structSizeAndFlags, structCount);
2138-
structSizeAndFlags |= m_relMethodHeaderFlag;
2140+
structSizeAndFlags |= relMethodHeaderFlag;
21392141
writeMethodListHeader(buf, structSizeAndFlags, structCount);
21402142

2141-
assert(m_methodListHeaderSize +
2142-
(structCount * m_pointersPerStruct * target->wordSize) ==
2143+
assert(methodListHeaderSize +
2144+
(structCount * pointersPerStruct * target->wordSize) ==
21432145
isec->data.size() &&
21442146
"Invalid computed ObjC method list size");
21452147

2146-
uint32_t inSecOff = m_methodListHeaderSize;
2147-
uint32_t outSecOff = m_methodListHeaderSize;
2148+
uint32_t inSecOff = methodListHeaderSize;
2149+
uint32_t outSecOff = methodListHeaderSize;
21482150

21492151
// Go through the method list and encode input absolute pointers as relative
21502152
// offsets. writeRelativeOffsetForIsec will be incrementing inSecOff and
@@ -2162,27 +2164,26 @@ ObjCMethListSection::writeRelativeMethodList(const ConcatInputSection *isec,
21622164
assert(inSecOff == isec->data.size() &&
21632165
"Invalid actual ObjC method list size");
21642166
assert(
2165-
outSecOff == methodListSizeToRelativeMethodListSize(inSecOff) &&
2167+
outSecOff == computeRelativeMethodListSize(inSecOff) &&
21662168
"Mismatch between input & output size when writing relative method list");
21672169
return outSecOff;
21682170
}
21692171

21702172
// Given the size of an ObjC method list InputSection, return the size of the
21712173
// method list when encoded in relative offsets format. We can do this without
2172-
// decoding the actual data, as it can be directly infered from the size of the
2174+
// decoding the actual data, as it can be directly inferred from the size of the
21732175
// isec.
2174-
uint32_t
2175-
ObjCMethListSection::methodListSizeToRelativeMethodListSize(uint32_t iSecSize) {
2176-
uint32_t oldPointersSize = iSecSize - m_methodListHeaderSize;
2176+
uint32_t ObjCMethListSection::computeRelativeMethodListSize(
2177+
uint32_t absoluteMethodListSize) const {
2178+
uint32_t oldPointersSize = absoluteMethodListSize - methodListHeaderSize;
21772179
uint32_t pointerCount = oldPointersSize / target->wordSize;
2178-
assert(((pointerCount % m_pointersPerStruct) == 0) &&
2180+
assert(((pointerCount % pointersPerStruct) == 0) &&
21792181
"__objc_methlist expects method lists to have multiple-of-3 pointers");
21802182

2181-
constexpr uint32_t sizeOfRelativeOffset = sizeof(uint32_t);
2182-
uint32_t newPointersSize = pointerCount * sizeOfRelativeOffset;
2183-
uint32_t newTotalSize = m_methodListHeaderSize + newPointersSize;
2183+
uint32_t newPointersSize = pointerCount * relativeOffsetSize;
2184+
uint32_t newTotalSize = methodListHeaderSize + newPointersSize;
21842185

2185-
assert((newTotalSize <= iSecSize) &&
2186+
assert((newTotalSize <= absoluteMethodListSize) &&
21862187
"Expected relative method list size to be smaller or equal than "
21872188
"original size");
21882189
return newTotalSize;
@@ -2191,15 +2192,15 @@ ObjCMethListSection::methodListSizeToRelativeMethodListSize(uint32_t iSecSize) {
21912192
// Read a method list header from buf
21922193
void ObjCMethListSection::readMethodListHeader(const uint8_t *buf,
21932194
uint32_t &structSizeAndFlags,
2194-
uint32_t &structCount) {
2195+
uint32_t &structCount) const {
21952196
structSizeAndFlags = read32le(buf);
21962197
structCount = read32le(buf + sizeof(uint32_t));
21972198
}
21982199

21992200
// Write a method list header to buf
22002201
void ObjCMethListSection::writeMethodListHeader(uint8_t *buf,
22012202
uint32_t structSizeAndFlags,
2202-
uint32_t structCount) {
2203+
uint32_t structCount) const {
22032204
write32le(buf, structSizeAndFlags);
22042205
write32le(buf + sizeof(structSizeAndFlags), structCount);
22052206
}

lld/MachO/SyntheticSections.h

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -697,37 +697,36 @@ class ObjCMethListSection final : public SyntheticSection {
697697
void setUp();
698698
void finalize() override;
699699
bool isNeeded() const override { return !inputs.empty(); }
700-
uint64_t getSize() const override { return m_size; }
700+
uint64_t getSize() const override { return sectionSize; }
701701
void writeTo(uint8_t *bufStart) const override;
702702

703703
private:
704-
static void readMethodListHeader(const uint8_t *buf,
705-
uint32_t &structSizeAndFlags,
706-
uint32_t &structCount);
707-
static void writeMethodListHeader(uint8_t *buf, uint32_t structSizeAndFlags,
708-
uint32_t structCount);
709-
static uint32_t methodListSizeToRelativeMethodListSize(uint32_t iSecSize);
704+
void readMethodListHeader(const uint8_t *buf, uint32_t &structSizeAndFlags,
705+
uint32_t &structCount) const;
706+
void writeMethodListHeader(uint8_t *buf, uint32_t structSizeAndFlags,
707+
uint32_t structCount) const;
708+
uint32_t computeRelativeMethodListSize(uint32_t absoluteMethodListSize) const;
710709
void writeRelativeOffsetForIsec(const ConcatInputSection *isec, uint8_t *buf,
711710
uint32_t &inSecOff, uint32_t &outSecOff,
712711
bool useSelRef) const;
713712
uint32_t writeRelativeMethodList(const ConcatInputSection *isec,
714713
uint8_t *buf) const;
715714

716-
static constexpr uint32_t m_methodListHeaderSize =
715+
static constexpr uint32_t methodListHeaderSize =
717716
/*structSizeAndFlags*/ sizeof(uint32_t) +
718717
/*structCount*/ sizeof(uint32_t);
719718
// Relative method lists are supported only for 3-pointer method lists
720-
static constexpr uint32_t m_pointersPerStruct = 3;
719+
static constexpr uint32_t pointersPerStruct = 3;
721720
// The runtime identifies relative method lists via this magic value
722-
static constexpr uint32_t m_relMethodHeaderFlag = 0x80000000;
721+
static constexpr uint32_t relMethodHeaderFlag = 0x80000000;
723722
// In the method list header, the first 2 bytes are the size of struct
724723
static constexpr uint32_t m_structSizeMask = 0xFFFF;
725724
// Relative method lists have 4 byte alignment as all data in the InputSection
726725
// is 4 byte
727-
static constexpr uint32_t m_align = 4;
726+
static constexpr uint32_t relativeOffsetSize = sizeof(uint32_t);
728727

729728
// The output size of the __objc_methlist section, computed during finalize()
730-
uint32_t m_size = 0;
729+
uint32_t sectionSize = 0;
731730
std::vector<ConcatInputSection *> inputs;
732731
};
733732

lld/MachO/Writer.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,7 +1292,7 @@ template <class LP> void Writer::run() {
12921292
scanSymbols();
12931293
if (in.objcStubs->isNeeded())
12941294
in.objcStubs->setUp();
1295-
if (in.objcMethList)
1295+
if (in.objcMethList->isNeeded())
12961296
in.objcMethList->setUp();
12971297
scanRelocations();
12981298
if (in.initOffsets->isNeeded())
@@ -1365,9 +1365,7 @@ void macho::createSyntheticSections() {
13651365
in.unwindInfo = makeUnwindInfoSection();
13661366
in.objCImageInfo = make<ObjCImageInfoSection>();
13671367
in.initOffsets = make<InitOffsetsSection>();
1368-
// Only create ObjCMethListSection if we need it
1369-
if (config->emitRelativeMethodLists)
1370-
in.objcMethList = make<ObjCMethListSection>();
1368+
in.objcMethList = make<ObjCMethListSection>();
13711369

13721370
// This section contains space for just a single word, and will be used by
13731371
// dyld to cache an address to the image loader it uses.

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

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@
55
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o a64_rel_dylib.o a64_simple_class.s
66

77
## Test arm64 + relative method lists
8-
# RUN: ld64.lld a64_rel_dylib.o -o a64_rel_dylib.dylib -map a64_rel_dylib.map -dylib -arch arm64 -platform_version macos 11.0.0 11.0.0 -objc_relative_method_lists
8+
# RUN: %no-lsystem-lld a64_rel_dylib.o -o a64_rel_dylib.dylib -map a64_rel_dylib.map -dylib -arch arm64 -objc_relative_method_lists
99
# RUN: llvm-objdump --macho --objc-meta-data a64_rel_dylib.dylib | FileCheck %s --check-prefix=CHK_REL
1010

1111
## Test arm64 + traditional method lists (no relative offsets)
12-
# RUN: ld64.lld a64_rel_dylib.o -o a64_rel_dylib.dylib -map a64_rel_dylib.map -dylib -arch arm64 -platform_version macos 11.0.0 11.0.0 -no_objc_relative_method_lists
12+
# RUN: %no-lsystem-lld a64_rel_dylib.o -o a64_rel_dylib.dylib -map a64_rel_dylib.map -dylib -arch arm64 -no_objc_relative_method_lists
1313
# RUN: llvm-objdump --macho --objc-meta-data a64_rel_dylib.dylib | FileCheck %s --check-prefix=CHK_NO_REL
1414

15-
CHK_NO_REL-NOT: (relative)
1615

1716
CHK_REL: Contents of (__DATA_CONST,__objc_classlist) section
1817
CHK_REL-NEXT: _OBJC_CLASS_$_MyClass
@@ -45,6 +44,41 @@ CHK_REL-NEXT: types 0x{{[0-9a-f]*}} (0x{{[0-9a-f]*}}) v16@0:8
4544
CHK_REL-NEXT: imp 0x{{[0-9a-f]*}} (0x{{[0-9a-f]*}}) +[MyClass class_method_02]
4645

4746

47+
CHK_NO_REL-NOT: (relative)
48+
49+
CHK_NO_REL: Contents of (__DATA_CONST,__objc_classlist) section
50+
CHK_NO_REL-NEXT: _OBJC_CLASS_$_MyClass
51+
52+
CHK_NO_REL: baseMethods 0x80e8 (struct method_list_t *)
53+
CHK_NO_REL-NEXT: entsize 24
54+
CHK_NO_REL-NEXT: count 3
55+
CHK_NO_REL-NEXT: name 0x5b8 instance_method_00
56+
CHK_NO_REL-NEXT: types 0x580 v16@0:8
57+
CHK_NO_REL-NEXT: imp -[MyClass instance_method_00]
58+
CHK_NO_REL-NEXT: name 0x5cb instance_method_01
59+
CHK_NO_REL-NEXT: types 0x580 v16@0:8
60+
CHK_NO_REL-NEXT: imp -[MyClass instance_method_01]
61+
CHK_NO_REL-NEXT: name 0x5de instance_method_02
62+
CHK_NO_REL-NEXT: types 0x580 v16@0:8
63+
CHK_NO_REL-NEXT: imp -[MyClass instance_method_02]
64+
65+
66+
CHK_NO_REL: Meta Class
67+
CHK_NO_REL-NEXT: _OBJC_METACLASS_$_MyClass
68+
69+
CHK_NO_REL: baseMethods 0x8050 (struct method_list_t *)
70+
CHK_NO_REL-NEXT: entsize 24
71+
CHK_NO_REL-NEXT: count 3
72+
CHK_NO_REL-NEXT: name 0x588 class_method_00
73+
CHK_NO_REL-NEXT: types 0x580 v16@0:8
74+
CHK_NO_REL-NEXT: imp +[MyClass class_method_00]
75+
CHK_NO_REL-NEXT: name 0x598 class_method_01
76+
CHK_NO_REL-NEXT: types 0x580 v16@0:8
77+
CHK_NO_REL-NEXT: imp +[MyClass class_method_01]
78+
CHK_NO_REL-NEXT: name 0x5a8 class_method_02
79+
CHK_NO_REL-NEXT: types 0x580 v16@0:8
80+
CHK_NO_REL-NEXT: imp +[MyClass class_method_02]
81+
4882

4983
######################## Generate a64_simple_class.s #########################
5084
# clang -c simple_class.mm -s -o a64_simple_class.s -target arm64-apple-macos -arch arm64 -Oz

0 commit comments

Comments
 (0)