Changeset View
Changeset View
Standalone View
Standalone View
compiler/nativeGen/X86/Ppr.hs
Show First 20 Lines • Show All 164 Lines • ▼ Show 20 Line(s) | |||||
165 | 165 | | |||
166 | pprData (CmmStaticLit lit) = pprDataItem lit | 166 | pprData (CmmStaticLit lit) = pprDataItem lit | ||
167 | 167 | | |||
168 | pprGloblDecl :: CLabel -> SDoc | 168 | pprGloblDecl :: CLabel -> SDoc | ||
169 | pprGloblDecl lbl | 169 | pprGloblDecl lbl | ||
170 | | not (externallyVisibleCLabel lbl) = empty | 170 | | not (externallyVisibleCLabel lbl) = empty | ||
171 | | otherwise = text ".globl " <> ppr lbl | 171 | | otherwise = text ".globl " <> ppr lbl | ||
172 | 172 | | |||
173 | pprTypeAndSizeDecl :: CLabel -> SDoc | 173 | pprLabelType' :: DynFlags -> CLabel -> SDoc | ||
174 | pprTypeAndSizeDecl lbl | 174 | pprLabelType' dflags lbl = | ||
175 | if isCFunctionLabel lbl || functionOkInfoTable then | ||||
176 | text "@function" | ||||
bgamari: Why not just use `text` here? | |||||
177 | else | ||||
178 | text "@object" | ||||
179 | where | ||||
180 | {- | ||||
181 | NOTE: This is a bit hacky. | ||||
bgamari: This should be a Note. | |||||
182 | | ||||
183 | With the `tablesNextToCode` info tables look like this: | ||||
184 | ``` | ||||
185 | <info table data> | ||||
186 | label_info: | ||||
I'm having a bit of trouble following this comment. Do you think you could do a syntax/grammar pass over it? bgamari: I'm having a bit of trouble following this comment. Do you think you could do a syntax/grammar… | |||||
187 | <info table code> | ||||
188 | ``` | ||||
189 | So actually info table label points exactly to the code and we can mark | ||||
190 | the label as @function. (This is required to make perf and potentially other | ||||
Yeah, the reasoning is a bit subtle so we'll want to expand this comment, and also include an example as @bgamari suggested above. The reasoning goes like this, if I'm not mistaken:
So, the only info table symbols that we might refer to from the data segment of another shared object are con_info symbols, so those are the ones we need to exclude from getting the @function treatment. simonmar: Yeah, the reasoning is a bit subtle so we'll want to expand this comment, and also include an… | |||||
191 | tools to work on Haskell binaries). | ||||
192 | This usually works well but it can cause issues with a linker. | ||||
193 | A linker uses different algorithms for the relocation depending on | ||||
194 | the symbol type.For some reason, a linker will generate JUMP_SLOT relocation | ||||
195 | when constructor info table is referenced from a data section. | ||||
196 | This only happens with static constructor call so | ||||
197 | we mark _con_info symbols as `@object` to avoid the issue with relocations. | ||||
198 | | ||||
bgamari: Perhaps you could give a concrete example? I'm rather lost. | |||||
199 | @SimonMarlow hack explanation: | ||||
200 | "The reasoning goes like this: | ||||
201 | | ||||
202 | * The danger when we mark a symbol as `@function` is that the linker will | ||||
203 | redirect it to point to the PLT and use a `JUMP_SLOT` relocation when | ||||
204 | the symbol refers to something outside the current shared object. | ||||
205 | A PLT / JUMP_SLOT reference only works for symbols that we jump to, not | ||||
206 | for symbols representing data,, nor for info table symbol references which | ||||
207 | we expect to point directly to the info table. | ||||
208 | * GHC generates code that might refer to any info table symbol from the text | ||||
209 | segment, but that's OK, because those will be explicit GOT references | ||||
210 | generated by the code generator. | ||||
211 | * When we refer to info tables from the data segment, it's either | ||||
212 | * a FUN_STATIC/THUNK_STATIC local to this module | ||||
213 | * a `con_info` that could be from anywhere | ||||
214 | | ||||
215 | So, the only info table symbols that we might refer to from the data segment | ||||
216 | of another shared object are `con_info` symbols, so those are the ones we | ||||
217 | need to exclude from getting the @function treatment. | ||||
218 | " | ||||
219 | | ||||
220 | A good place to check for more | ||||
221 | https://ghc.haskell.org/trac/ghc/wiki/Commentary/PositionIndependentCode | ||||
222 | | ||||
223 | Another possible hack is to create an extra local function symbol for | ||||
224 | every code-like thing to give the needed information for to the tools | ||||
225 | but mess up with the relocation. https://phabricator.haskell.org/D4730 | ||||
226 | -} | ||||
227 | functionOkInfoTable = tablesNextToCode dflags && | ||||
228 | isInfoTableLabel lbl && not (isConInfoTableLabel lbl) | ||||
229 | | ||||
230 | | ||||
231 | pprTypeDecl :: CLabel -> SDoc | ||||
232 | pprTypeDecl lbl | ||||
175 | = sdocWithPlatform $ \platform -> | 233 | = sdocWithPlatform $ \platform -> | ||
176 | if osElfTarget (platformOS platform) && externallyVisibleCLabel lbl | 234 | if osElfTarget (platformOS platform) && externallyVisibleCLabel lbl | ||
177 | then text ".type " <> ppr lbl <> ptext (sLit ", @object") | 235 | then | ||
236 | sdocWithDynFlags $ \df -> | ||||
237 | text ".type " <> ppr lbl <> ptext (sLit ", ") <> pprLabelType' df lbl | ||||
178 | else empty | 238 | else empty | ||
179 | 239 | | |||
180 | pprLabel :: CLabel -> SDoc | 240 | pprLabel :: CLabel -> SDoc | ||
181 | pprLabel lbl = pprGloblDecl lbl | 241 | pprLabel lbl = pprGloblDecl lbl | ||
182 | $$ pprTypeAndSizeDecl lbl | 242 | $$ pprTypeDecl lbl | ||
183 | $$ (ppr lbl <> char ':') | 243 | $$ (ppr lbl <> char ':') | ||
184 | 244 | | |||
185 | {- | 245 | {- | ||
186 | Note [Pretty print ASCII when AsmCodeGen] | 246 | Note [Pretty print ASCII when AsmCodeGen] | ||
187 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 247 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
188 | Previously, when generating assembly code, we created SDoc with | 248 | Previously, when generating assembly code, we created SDoc with | ||
189 | `(ptext . sLit)` for every bytes in literal bytestring, then | 249 | `(ptext . sLit)` for every bytes in literal bytestring, then | ||
190 | combine them using `hcat`. | 250 | combine them using `hcat`. | ||
▲ Show 20 Lines • Show All 1150 Lines • ▼ Show 20 Line(s) | 1399 | = hcat [ char '\t', ptext name, pprFormat format1, pprFormat format2, space, | |||
1341 | comma, | 1401 | comma, | ||
1342 | pprOperand format2 op2 | 1402 | pprOperand format2 op2 | ||
1343 | ] | 1403 | ] | ||
1344 | 1404 | | |||
1345 | 1405 | | |||
1346 | pprCondInstr :: LitString -> Cond -> SDoc -> SDoc | 1406 | pprCondInstr :: LitString -> Cond -> SDoc -> SDoc | ||
1347 | pprCondInstr name cond arg | 1407 | pprCondInstr name cond arg | ||
1348 | = hcat [ char '\t', ptext name, pprCond cond, space, arg] | 1408 | = hcat [ char '\t', ptext name, pprCond cond, space, arg] | ||
1349 | |
Why not just use text here?