abi-aa icon indicating copy to clipboard operation
abi-aa copied to clipboard

aaelf32 and aaelf64 missing information required by generic ELF

Open john-brawn-arm opened this issue 2 years ago • 4 comments

Some parts of ELF are described in the generic ELF specification (http://www.sco.com/developers/devspecs/gabi41.pdf) as being described in specific sections of the processor supplement, but the aaelf32 and aaelf64 documents don't describe them, or do describe them but not in the section the gabi says. The places I've noticed this are:

e_flags This member holds processor-specific flags associated with the file. Flag names take the form EF_machine_flag. See ‘‘Machine Information’’ in the processor supplement for flag definitions

We describe the e_flags field, but not in a section named "Machine Information".

.got This section holds the global offset table. See ‘‘Coding Examples’’ in Chapter 3, ‘‘Special Sections’’ in Chapter 4, and ‘‘Global Offset Table’’ in Chapter 5 of the processor supplement for more informa- tion.

It looks like we say some things about the GOT in the section "Proxy Generating Relocations" in both aaelf32 and aaelf64, but don't have a specific "Global Offset Table" section. AC6 armlink and aarch64-none-elf-ld both appear to place the address of the .dynamic section at the start of the GOT, but I don't know if that's something that should be required by the ABI or if they just happen to do this (if so we should have some wording saying that a toolchain can put toolchain-specific stuff in the GOT).

.plt This section holds the procedure linkage table. See ‘‘Special Sec- tions’’ in Chapter 4 and ‘‘Procedure Linkage Table’’ in Chapter 5 of the processor supplement for more information.

aaelf32 describes the plt in "PLT Sequences and Usage Models", aaelf64 describes it in "Program Linkage Table (PLT) Sequences and Usage Models" (though that's an example and the section says the platform standard should define it) but neither has a specific "Procedure Linkage Table" section.

DT_PLTGOT This element holds an address associated with the procedure link- age table and/or the global offset table. See this section in the processor supplement for details.

AC6 armlink appears to set this to the address of the .got section, aarch64-none-elf-ld appears to set this to the address of the .got.plt section, but neither aaelf32 nor aaelf64 say anything about what it should be set to.

john-brawn-arm avatar Jun 28 '22 13:06 john-brawn-arm

Documenting this would be more natural in the sysvabi as that has a dedicated section on the ToDo list on Program Loading and Dynamic Linking (https://github.com/ARM-software/abi-aa/issues/152).

The reserved contents of The GOT for example are a convention between the dynamic loader and static linker.

Whether the .got or .got.plt are in separate sections is to some degree convention. In AArch32 the GNU ld default linker script merges the two: .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } but on AArch64 it keeps them separate as the .got can be made RELRO but the .got.plt cannot (with lazy binding) .got : { *(.got) *(.igot) } . = DATA_SEGMENT_RELRO_END (24, .); .got.plt : { *(.got.plt) *(.igot.plt) }

It isn't compulsary to have a single .got in AArch32, lld keeps the .got and .got.plt separate in its default layout. I think the important part to document is the value of the _GLOBAL_OFFSET_TABLE_ symbol which the compiler sometimes refers to by convention as meaning base of the GOT, it is important to know whether that is the base of the .got or .got.plt.

smithp35 avatar Jun 28 '22 14:06 smithp35

Defining _GLOBAL_OFFSET_TABLE_ (the start of .got) will be nice. On x86, the lack of clarity caused https://reviews.llvm.org/D59594 to lld.

Note that we should not require .got[0] == _DYNAMIC. GNU ld's aarch64 port reserves the entry for glibc rtld but ld.lld does not reserve the entry. I have removed glibc 2.35's reliance on _GLOBAL_OFFSET_TABLE_[0] for arm/aarch64.

MaskRay avatar Jun 28 '22 21:06 MaskRay

Why does it need to be defined? It's just a hook for the linker to calculate offsets against. Indeed, on AArch32 there's the potential to put the GLOBAL_OFFSET_TABLE in the middle of the GOT and then you can use negative offsets as well as positive ones to double the useful size of the GOT with instructions like LDR.

rearnsha avatar Jul 07 '22 13:07 rearnsha

From memory it is because there are some code-sequences where it can matter. For example GCC will generate for -fpic

// aarch64-linux-gnu -c -fpic file.c
// int foo;
// int func() { return foo; }
       0: 00 00 00 90   adrp    x0, 0x0 <func>
                0000000000000000:  R_AARCH64_ADR_PREL_PG_HI21   _GLOBAL_OFFSET_TABLE_
       4: 00 00 40 f9   ldr     x0, [x0]
                0000000000000004:  R_AARCH64_LD64_GOTPAGE_LO15  foo
       8: 00 00 40 b9   ldr     w0, [x0]
       c: c0 03 5f d6   ret

The ldr x0, [x0] // R_AARCH64_LD64_GOTPAGE_LO15 foo is unsigned so GLOBAL_OFFSET_TABLE can't be above the GOT.

smithp35 avatar Jul 07 '22 15:07 smithp35

W.r.t. the part of the issue around the gABI referencing section names in the processor supplement (which don't match our section names). I've got the impression from this thread that we're not concerned about that, is that correct?

W.r.t. the fact that we do not describe what is stored in DT_PLTGOT in any of our documents. That seems like something we should address if it's not specified in any generic ABI specification. The description of "an address associated with the procedure linkage table and/or the global offset table" which is what the generic ABI uses doesn't seem sufficient. I think we should add mention of it in the sysvabi -- does that sound right?

mmalcomson avatar Oct 17 '22 17:10 mmalcomson

I agree that the sysvabi is the right place for a description of DT_PLTGOT. I can send a patch for that later this week.

On Arm and AArch64 it is just the address of the .got.plt section. This is the case for most architectures I think. Looking at the linker code there are some differences on some targets, such as with Sparc where it is expected to point at the start of the .plt section. This difference for some processors probably prevented the gABI from defining it.

smithp35 avatar Oct 17 '22 17:10 smithp35

https://github.com/ARM-software/abi-aa/pull/173 created to add definition of DT_PLTGOT to sysvabi64

smithp35 avatar Oct 18 '22 14:10 smithp35

https://github.com/ARM-software/abi-aa/pull/173 has been merged and does contain a definition of DT_PLTGOT. I'm closing this issue for now. If there's anything we've missed we can reopen or raise a new issue.

smithp35 avatar Mar 07 '23 17:03 smithp35