Skip to content

#[repr(align(x))] is limited to 32768 #42960

Closed
@Ekleog

Description

@Ekleog

In some cases, the hardware imposes natural alignment for some data (ie. data aligned to its length). For example, the ARM Memory Protection Unit.

This can happen even when handling large structs (eg. 0x10000-sized buffers). These buffers would thus require an alignment of 0x10000. Which appears not to be possible with #[repr(align(x))], that appears limited to 32768.

I'm currently using the following (ugly, esp. because of the absence of type-level integers) workaround to get the aligned data I need:

pub struct Aligned {                                                        
   unaligned: [u8; 0x100000]                                                    
}                                                                                
pub static mut DATA: Aligned = Aligned { unaligned: [0; 0x100000] };
impl Aligned {                                                              
   pub fn get(&self) -> &[u8] {                                                  
       let begin_addr = &self.unaligned[0] as *const _ as usize;                
       let aligned_begin_addr = (begin_addr & !0x7FFFF) + 0x80000;              
       let offset = aligned_begin_addr - begin_addr;                            
       &self.unaligned[offset..(offset+0x80000)]                                
   }                                                                            
   pub fn get_mut(&mut self) -> &mut [u8] {                                      
       let begin_addr = &self.unaligned[0] as *const _ as usize;                
       let aligned_begin_addr = (begin_addr & !0x7FFFF) + 0x80000;              
       let offset = aligned_begin_addr - begin_addr;                            
       &mut self.unaligned[offset..(offset+0x80000)]                            
   }                                                                            
}  

If I can manually do it, I don't really get why rustc wouldn't be able to do it (esp. with http://www.cs.brandeis.edu/~cs146a/rust/doc-02-21-2015/rustc/lib/llvm/fn.LLVMSetAlignment.html taking an u32 as input)?

Is there a technical issue or is this just a current implementation limitation?

As this behaviour is not specified in RFC1358, cc'ing #33626

Disclaimer: I'm not actually running this code on an ARM MPU-enabled chip, but explaining the actual use case would be too long and complex and the issue is exactly the same, so I just picked this example.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions