@@ -58,29 +58,31 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {
58
58
if (GV->isThreadLocal ())
59
59
return false ;
60
60
61
+ // We should properly mark well-known section name prefixes as small/large,
62
+ // because otherwise the output section may have the wrong section flags and
63
+ // the linker will lay it out in an unexpected way.
64
+ StringRef Name = GV->getSection ();
65
+ if (!Name.empty ()) {
66
+ auto IsPrefix = [&](StringRef Prefix) {
67
+ StringRef S = Name;
68
+ return S.consume_front (Prefix) && (S.empty () || S[0 ] == ' .' );
69
+ };
70
+ if (IsPrefix (" .bss" ) || IsPrefix (" .data" ) || IsPrefix (" .rodata" ))
71
+ return false ;
72
+ if (IsPrefix (" .lbss" ) || IsPrefix (" .ldata" ) || IsPrefix (" .lrodata" ))
73
+ return true ;
74
+ }
75
+
61
76
// For x86-64, we treat an explicit GlobalVariable small code model to mean
62
77
// that the global should be placed in a small section, and ditto for large.
78
+ // Well-known section names above take precedence for correctness.
63
79
if (auto CM = GV->getCodeModel ()) {
64
80
if (*CM == CodeModel::Small)
65
81
return false ;
66
82
if (*CM == CodeModel::Large)
67
83
return true ;
68
84
}
69
85
70
- // Treat all globals in explicit sections as small, except for the standard
71
- // large sections of .lbss, .ldata, .lrodata. This reduces the risk of linking
72
- // together small and large sections, resulting in small references to large
73
- // data sections. The code model attribute overrides this above.
74
- if (GV->hasSection ()) {
75
- StringRef Name = GV->getSection ();
76
- auto IsPrefix = [&](StringRef Prefix) {
77
- StringRef S = Name;
78
- return S.consume_front (Prefix) && (S.empty () || S[0 ] == ' .' );
79
- };
80
- return IsPrefix (" .lbss" ) || IsPrefix (" .ldata" ) || IsPrefix (" .lrodata" );
81
- }
82
-
83
- // Respect large data threshold for medium and large code models.
84
86
if (getCodeModel () == CodeModel::Medium ||
85
87
getCodeModel () == CodeModel::Large) {
86
88
if (!GV->getValueType ()->isSized ())
0 commit comments