Skip to content

Commit e738b90

Browse files
committed
Refactor to combine similar functions into one
1 parent a91d261 commit e738b90

File tree

1 file changed

+56
-76
lines changed

1 file changed

+56
-76
lines changed

src/link/section.cpp

Lines changed: 56 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -25,91 +25,71 @@ void sect_ForEach(void (*callback)(Section &)) {
2525
}
2626
}
2727

28-
static void checkAgainstFixedAddress(Section const &target, Section const &other, uint16_t org) {
29-
if (target.isAddressFixed) {
30-
if (target.org != org) {
31-
fatalTwoAt(
32-
target,
33-
other,
34-
"Section \"%s\" is defined with address $%04" PRIx16
35-
", but also with address $%04" PRIx16,
36-
target.name.c_str(),
37-
target.org,
38-
other.org
39-
);
28+
static void checkPieceCompat(Section &target, Section const &other, size_t delta) {
29+
assume(other.modifier != SECTION_UNION || delta == 0);
30+
31+
if (other.isAddressFixed) {
32+
uint16_t org = other.org - delta;
33+
34+
if (target.isAddressFixed) {
35+
if (target.org != org) {
36+
fatalTwoAt(
37+
target,
38+
other,
39+
"Section \"%s\" is defined with address $%04" PRIx16
40+
", but also with address $%04" PRIx16,
41+
target.name.c_str(),
42+
target.org,
43+
other.org
44+
);
45+
}
46+
} else if (target.isAlignFixed) {
47+
if ((org - target.alignOfs) & target.alignMask) {
48+
fatalTwoAt(
49+
target,
50+
other,
51+
"Section \"%s\" is defined with %d-byte alignment (offset %" PRIu16
52+
"), but also with address $%04" PRIx16,
53+
target.name.c_str(),
54+
target.alignMask + 1,
55+
target.alignOfs,
56+
other.org
57+
);
58+
}
4059
}
41-
} else if (target.isAlignFixed) {
42-
if ((org - target.alignOfs) & target.alignMask) {
60+
61+
target.isAddressFixed = true;
62+
target.org = org;
63+
} else if (other.isAlignFixed) {
64+
uint32_t ofs = (other.alignOfs - delta) & other.alignMask;
65+
66+
if (target.isAddressFixed) {
67+
if ((target.org - ofs) & other.alignMask) {
68+
fatalTwoAt(
69+
target,
70+
other,
71+
"Section \"%s\" is defined with address $%04" PRIx16
72+
", but also with %d-byte alignment (offset %" PRIu16 ")",
73+
target.name.c_str(),
74+
target.org,
75+
other.alignMask + 1,
76+
other.alignOfs
77+
);
78+
}
79+
} else if (target.isAlignFixed
80+
&& (other.alignMask & target.alignOfs) != (target.alignMask & ofs)) {
4381
fatalTwoAt(
4482
target,
4583
other,
4684
"Section \"%s\" is defined with %d-byte alignment (offset %" PRIu16
47-
"), but also with address $%04" PRIx16,
85+
"), but also with %d-byte alignment (offset %" PRIu16 ")",
4886
target.name.c_str(),
4987
target.alignMask + 1,
5088
target.alignOfs,
51-
other.org
52-
);
53-
}
54-
}
55-
}
56-
57-
static bool checkAgainstFixedAlign(Section const &target, Section const &other, uint32_t ofs) {
58-
if (target.isAddressFixed) {
59-
if ((target.org - ofs) & other.alignMask) {
60-
fatalTwoAt(
61-
target,
62-
other,
63-
"Section \"%s\" is defined with address $%04" PRIx16
64-
", but also with %d-byte alignment (offset %" PRIu16 ")",
65-
target.name.c_str(),
66-
target.org,
6789
other.alignMask + 1,
6890
other.alignOfs
6991
);
70-
}
71-
return false;
72-
} else if (target.isAlignFixed
73-
&& (other.alignMask & target.alignOfs) != (target.alignMask & ofs)) {
74-
fatalTwoAt(
75-
target,
76-
other,
77-
"Section \"%s\" is defined with %d-byte alignment (offset %" PRIu16
78-
"), but also with %d-byte alignment (offset %" PRIu16 ")",
79-
target.name.c_str(),
80-
target.alignMask + 1,
81-
target.alignOfs,
82-
other.alignMask + 1,
83-
other.alignOfs
84-
);
85-
} else {
86-
return !target.isAlignFixed || (other.alignMask > target.alignMask);
87-
}
88-
}
89-
90-
static void checkSectUnionCompat(Section &target, Section &other) {
91-
if (other.isAddressFixed) {
92-
checkAgainstFixedAddress(target, other, other.org);
93-
target.isAddressFixed = true;
94-
target.org = other.org;
95-
} else if (other.isAlignFixed) {
96-
if (checkAgainstFixedAlign(target, other, other.alignOfs)) {
97-
target.isAlignFixed = true;
98-
target.alignMask = other.alignMask;
99-
target.alignOfs = other.alignOfs;
100-
}
101-
}
102-
}
103-
104-
static void checkFragmentCompat(Section &target, Section &other) {
105-
if (other.isAddressFixed) {
106-
uint16_t org = other.org - target.size;
107-
checkAgainstFixedAddress(target, other, org);
108-
target.isAddressFixed = true;
109-
target.org = org;
110-
} else if (other.isAlignFixed) {
111-
uint32_t ofs = (other.alignOfs - target.size) & other.alignMask;
112-
if (checkAgainstFixedAlign(target, other, ofs)) {
92+
} else if (!target.isAlignFixed || other.alignMask > target.alignMask) {
11393
target.isAlignFixed = true;
11494
target.alignMask = other.alignMask;
11595
target.alignOfs = ofs;
@@ -158,14 +138,14 @@ static void mergeSections(Section &target, std::unique_ptr<Section> &&other) {
158138

159139
switch (other->modifier) {
160140
case SECTION_UNION:
161-
checkSectUnionCompat(target, *other);
141+
checkPieceCompat(target, *other, 0);
162142
if (other->size > target.size) {
163143
target.size = other->size;
164144
}
165145
break;
166146

167147
case SECTION_FRAGMENT:
168-
checkFragmentCompat(target, *other);
148+
checkPieceCompat(target, *other, target.size);
169149
// Append `other` to `target`
170150
other->offset = target.size;
171151
target.size += other->size;

0 commit comments

Comments
 (0)