@@ -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