2

I am working on writing a static paging setup for a custom bare-metal ARM system. ARMv7a uses two-level paging, where entries in a top-level page table can point to a second-level table. I have a top-level table and a couple of second-level tables that I need to link together, both implemented in the same .S file and same section.

The "link entry" in the top-level table should have this value: (second_level_table_addr & 0xfffffc00) | 0x9 -- this takes the base address of the second-level table, and clears the low bits and replaces them with some configuration bits (see ARMv7a manual B3.5.1 for details).

My question is: can I use the symbol for the second-level table to generate the link entry in the top-level table, after relocation? If I try to write an expression like .word (second_level_table_sym & 0xfffffc00) | 0x9, I get the following error: invalid operands (.boot_data and *ABS* sections) for &.

Right now what I'm doing is manually setting absolute addresses for the second-level tables and hard-coding them in the link entries. This works, but I feel like it will be difficult to maintain as the mappings become more complicated, and in general I would like to leave binary layout to the toolchain as much as possible. This would also be pretty easy to fix up at runtime, but unfortunately the tables will be stored in read-only memory and so that isn't possible.

As I understand it, the address of second_level_table_sym is not known when assembling the individual file (the point where I get the error), but it is known at final link time after relocation. Is there a way to get the assembler (GNU arm-eabi-none-as) to use that knowledge to generate the table entry I want?

6
  • 2
    As you say, the assembler would need to pass that information to the linker and it can't because there is no such relocation type.
    – Jester
    Commented Sep 10, 2024 at 18:43
  • 4
    You could have second_level_table_sym aligned to 1k then the & 0xfffffc00 would not be needed and the | 0x9 could be done with + 0x9 which can be relocated.
    – Jester
    Commented Sep 10, 2024 at 19:29
  • Alternatively, you can build the address in a linker script.
    – fuz
    Commented Sep 10, 2024 at 21:09
  • 1
    @Jester's approach of changing OR to ADD works, since the second-level table addresses are required to be aligned to >1k anyway. Is there documentation somewhere describing the operations that are compatible with relocations? Commented Sep 10, 2024 at 21:49
  • 4
    Basically just addition. The various relocation types are for the different addressing modes and sizes. They are listed in the ELF ABI spec
    – Jester
    Commented Sep 10, 2024 at 21:53

1 Answer 1

-2

Use a relocation. Let the assembler emit the raw address of the second-level table and let the linker apply the mask and configuration bits.

1
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Sep 15, 2024 at 23:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.