@@ -103,7 +103,10 @@ impl Layout { |
| 103 | 103 | segment: key.segment.clone(), |
| 104 | 104 | name: key.name.clone(), |
| 105 | 105 | kind: input_section.kind, |
| 106 | | - align_pow2: input_section.align_pow2.min(u8::MAX as u32) as u8, |
| 106 | + align_pow2: normalize_output_alignment( |
| 107 | + input_section.kind, |
| 108 | + input_section.align_pow2.min(u8::MAX as u32) as u8, |
| 109 | + ), |
| 107 | 110 | flags: input_section.flags, |
| 108 | 111 | reserved1: input_section.reserved1, |
| 109 | 112 | reserved2: input_section.reserved2, |
@@ -121,7 +124,10 @@ impl Layout { |
| 121 | 124 | }; |
| 122 | 125 | |
| 123 | 126 | let out = &mut sections[idx]; |
| 124 | | - out.align_pow2 = out.align_pow2.max(atom.align_pow2); |
| 127 | + out.align_pow2 = normalize_output_alignment( |
| 128 | + out.kind, |
| 129 | + out.align_pow2.max(atom.align_pow2), |
| 130 | + ); |
| 125 | 131 | out.atoms.push(OutputAtom { |
| 126 | 132 | atom: atom_id, |
| 127 | 133 | offset: 0, |
@@ -357,7 +363,10 @@ impl Layout { |
| 357 | 363 | fn merge_synthetic_section(existing: &mut OutputSection, synthetic: OutputSection) { |
| 358 | 364 | debug_assert_eq!(existing.segment, synthetic.segment); |
| 359 | 365 | debug_assert_eq!(existing.name, synthetic.name); |
| 360 | | - existing.align_pow2 = existing.align_pow2.max(synthetic.align_pow2); |
| 366 | + existing.align_pow2 = normalize_output_alignment( |
| 367 | + existing.kind, |
| 368 | + existing.align_pow2.max(synthetic.align_pow2), |
| 369 | + ); |
| 361 | 370 | existing.flags = synthetic.flags; |
| 362 | 371 | existing.reserved1 = synthetic.reserved1; |
| 363 | 372 | existing.reserved2 = synthetic.reserved2; |
@@ -369,6 +378,20 @@ fn merge_synthetic_section(existing: &mut OutputSection, synthetic: OutputSectio |
| 369 | 378 | } |
| 370 | 379 | } |
| 371 | 380 | |
| 381 | +fn normalize_output_alignment( |
| 382 | + kind: crate::section::SectionKind, |
| 383 | + align_pow2: u8, |
| 384 | +) -> u8 { |
| 385 | + match kind { |
| 386 | + crate::section::SectionKind::ThreadLocalRegular |
| 387 | + | crate::section::SectionKind::ThreadLocalZeroFill |
| 388 | + | crate::section::SectionKind::ThreadLocalVariables |
| 389 | + | crate::section::SectionKind::ThreadLocalVariablePointers |
| 390 | + | crate::section::SectionKind::ThreadLocalInitPointers => align_pow2.max(3), |
| 391 | + _ => align_pow2, |
| 392 | + } |
| 393 | +} |
| 394 | + |
| 372 | 395 | fn build_segments(kind: OutputKind, sections: &[OutputSection]) -> Vec<OutputSegment> { |
| 373 | 396 | let names: &[&str] = match kind { |
| 374 | 397 | OutputKind::Executable => &EXEC_SEGMENTS, |