how to align an instruction or a function’s start address to a specific value(2^n and less than 4K bytes) which might be neither 8 nor 16?

437 views
Skip to first unread message

Fannie Zhang (Arm Technology China)

unread,
Nov 13, 2019, 10:30:10 PM11/13/19
to golan...@googlegroups.com

 

Hello,

 

Recently, the gVisor project needs an instruction’s address with 128 bytes alignment and a function’s start address with 2K bytes to fit the architecture requirement for interrupt table.

Please refer to the gVsior project related codes.

https://github.com/google/gvisor/blob/eedea52db451bf62722759009a9f14c54a69c55f/pkg/sentry/platform/kvm/machine_arm64_unsafe.go#L84

https://github.com/lubinszARM/gvisor/blob/2cee0669299cd2b980aa9ae253c24107a4813b26/pkg/sentry/platform/ring0/entry_arm64.s#L496

 

We found current go has a PCALIGN directive, which indicates that the next instruction should be aligned to the specified value.

We have added the assembler support for the PCALIGN on arm64 (the CL: https://go-review.googlesource.com/c/go/+/207117),  however, this CL can only align the instructions’ address with 8 bytes or 16 bytes.

Because an instruction’s address =  function’s address + instruction’s offset, at the moment, an instruction’s offset can be  any 2^n (less than 4K bytes) alignment, but by default,  the function’s address is 16 bytes aligned on arm64.

Please see the following example.

<1>. The Add() of sum.s:

TEXT ·Add(SB),$0

        MOVD    a+0(FP), R0

        PCALIGN $16

        MOVD    b+8(FP), R1

        PCALIGN $32

        ADD     R0, R1, R1

        PCALIGN $8

        SUB     R2, R0, R0

equal:

        MOVD    R0, ret+16(FP)

        RET

 

<2>. Objdump to see the physical address.

TEXT alignadd.Add(SB) /home/fanzha02/work/asm_demo/src/alignadd/sum.s

 0x6aad0               f94007e0                MOVD 8(RSP), R0                     // the function’s address 0x6aad0  is aligned to 16 bytes.             

  0x6aad4               d503201f                NOP

  0x6aad8               d503201f                NOP

  0x6aadc               d503201f                NOP

  0x6aae0               f9400be1                MOVD 16(RSP), R1            // this instruction’s address(0x6aae0) is aligned to 16 bytes.

  0x6aae4               d503201f                NOP

  0x6aae8               d503201f                NOP

  0x6aaec               d503201f                NOP

  0x6aaf0               8b000021                ADD R0, R1, R1                // this instruction’s address (0x6aaf0)  = the function’s address(0x6aad0) + this instruction’s offset(32) , it  is not aligned to 32bytes.

  0x6aaf4               d503201f                NOP

  0x6aaf8               cb020000                SUB R2, R0, R0                // this instruction’s address (0x6aaf8) is aligned to 8 bytes.          

  0x6aafc               f9000fe0                 MOVD R0, 24(RSP)

  0x6ab00               d65f03c0                RET

 

From the output of objdump, the address of the instruction ADD R0, R1, R1 is not 32bytes aligned, because of the function’s address is not 32 bytes aligned.

If we want to support the requirement to align the address of an instruction or a function to any power-of-two value(less than 4K bytes), we need to pass alignment information from assembler to linker.

And we  found the LSym (is defined in cmd/internal/obj/link.go) written to an object file has no elements that can indicate alignment information.

// An LSym is the sort of symbol that is written to an object file.

// It represents Go symbols in a flat pkg+"."+name namespace.

type LSym struct {

                Name string

                Type objabi.SymKind

                Attribute

 

                RefIdx int // Index of this symbol in the symbol reference list.

                Size   int64

                Gotype *LSym

                P      []byte

                R      []Reloc

 

                Func *FuncInfo

}

 

From the results of our current research, we may need to add a new element in the LSym structure to pass the alignment information, but this will break the current object file format.

Is this method feasible? Or is there any better solution?  Looking forward to your reply. Thank you.

 

Best regards

Fannie

 

fannie zhang

unread,
Jan 16, 2020, 12:58:04 AM1/16/20
to golang-dev
I have submitted a CL to align an instruction or a function's start address to a specific value. https://go-review.googlesource.com/c/go/+/212767.

Michal Derkacz

unread,
Jan 20, 2020, 11:52:58 AM1/20/20
to golang-dev
I don't know if I understood you correctly. Are you defining pseudo-function Vectors which is indeed an interrupt vector table?

fannie zhang

unread,
Apr 1, 2020, 3:59:50 AM4/1/20
to golang-dev
Sorry, I just saw your message. I am not very familiar with the implementation details in gVisor. The requirement of gVisor is that they want to use a directive to align the address of a function to 2048 bytes, just like the c/c++ .align directive.
Reply all
Reply to author
Forward
0 new messages