From fd4df20da61d93f6bdc87486ad9ca9853c32c2f5 Mon Sep 17 00:00:00 2001 From: Edward Jones Date: Tue, 16 Jul 2019 12:23:12 +0100 Subject: [PATCH 1/3] Add a description of DWARF exception handling --- riscv-elf.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/riscv-elf.md b/riscv-elf.md index d47e4e43..bad1e904 100644 --- a/riscv-elf.md +++ b/riscv-elf.md @@ -21,7 +21,11 @@ * [Note Sections](#note-sections) * [Dynamic Table](#dynamic-table) * [Hash Table](#hash-table) -4. [DWARF](#dwarf) +4. [Exception Handling](#exception-handling) + * [Frame Descriptor Entry (FDE) encoding](#fde-encoding) + * [Language Specific Data Area (LSDA) encoding](#lsda-encoding) + * [Personality Function encoding](#personality-encoding) +5. [DWARF](#dwarf) * [Dwarf Register Numbers](#dwarf-register-numbers) ## Copyright and license information @@ -791,6 +795,69 @@ typedef struct ## Hash Table +# Exception Handling + +Exception handling is achieved using C++ exceptions based on DWARF-derived +CIE (Common Information Entry) and FDE (Frame Descriptor Entry) data +structures saved in `.eh_frame`, plus additional data +structures in the `.gcc_except_table` section of the ELF. Some relevant +fields in these data structures are defined below: + +## Frame Descriptor Entry (FDE) encoding + +Used to encode the range of code addresses which the current Frame +Descriptor Entry applies to. Generally encoded as: + +``` +DW_EH_PE_pcrel | DW_EH_PE_sdata4 +``` + +This encoding is used both to specify the start address for the code +that the FDE is applicable to, and the length of the code which +the FDE applies to. In the first instance, a 32-bit signed offset +is emitted from the current position in the FDE to the code address +itself, and this generates a `R_RISCV_32_PCREL` relocation. In the +second instance, a `R_RISCV_ADD32` and `R_RISCV_SUB32` pair is +emitted which encodes the difference between the end address and +start address in the code. + +## Language Specific Data Area (LSDA) encoding + +Encodes refences to the LSDA for the current FDE. Like the FDE encoding +this is generally encoded as: + +``` +DW_EH_PE_pcrel | DW_EH_PE_sdata4 +``` + +This causes a `R_RISCV_ADD32` and `R_RISCV_SUB32` relocation pair +to be emitted, encoding the offset from the position the LSDA is +encoded in the FDE (in the `.eh_frame` section) to the LSDA data +structure itself (which is found in the `.gcc_except_table` section). + +## Personality Function encoding + +Use to encode references to the personality function for the current +CIE. Unlike the LSDA and FDE, the personality function is encoded +with an additional level of indirection. + +``` +DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4 +``` + +This is also encoded as a `R_RISCV_ADD32` and `R_RISCV_SUB32` pair, +however the target is not the direct address of the +`__gxx_personality_v0` function, but instead references a temporary +symbol `DW.ref.__gxx_personality_v0` which contains the full address +of `__gxx_personality_v0` and is found in a special section +`.sdata.DW.ref.__gxx_personality_v0`. + +The reason for this is that it allows the `.eh_frame` section to +contain no dynamic relocations - since `__gxx_personality_v0` may +be in a shared object - and mean the `.eh_frame` section does not +need to be writeable at runtime. Instead, only the new temporary +`.sdata.DW.ref.__gxx_personality_v0` section is writeable. + # DWARF Dwarf Register Numbers From e701d04f9b5ad9774ad85f21d655d92ca04cb5b2 Mon Sep 17 00:00:00 2001 From: Edward Jones Date: Tue, 16 Jul 2019 12:31:49 +0100 Subject: [PATCH 2/3] Document R_RISCV_PCREL_32 relocation --- riscv-elf.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/riscv-elf.md b/riscv-elf.md index bad1e904..303a1e3e 100644 --- a/riscv-elf.md +++ b/riscv-elf.md @@ -440,7 +440,8 @@ Enum | ELF Reloc Type | Description | Details 54 | R_RISCV_SET8 | Local label subtraction | 55 | R_RISCV_SET16 | Local label subtraction | 56 | R_RISCV_SET32 | Local label subtraction | -57-191 | *Reserved* | Reserved for future standard use | +57 | R_RISCV_32_PCREL | PC-relative 32-bit offset | Primarily used for FDE start location in .eh_frame +58-191 | *Reserved* | Reserved for future standard use | 192-255 | *Reserved* | Reserved for nonstandard ABI extensions | Nonstandard extensions are free to use relocation numbers 192-255 for any From cd796678303082b5882aaf4d49a186d065791c2b Mon Sep 17 00:00:00 2001 From: Edward Jones Date: Thu, 18 Jul 2019 15:37:16 +0100 Subject: [PATCH 3/3] Describe registers used when passing values through to a landing pad --- riscv-elf.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/riscv-elf.md b/riscv-elf.md index 303a1e3e..5c34ad23 100644 --- a/riscv-elf.md +++ b/riscv-elf.md @@ -22,9 +22,8 @@ * [Dynamic Table](#dynamic-table) * [Hash Table](#hash-table) 4. [Exception Handling](#exception-handling) - * [Frame Descriptor Entry (FDE) encoding](#fde-encoding) - * [Language Specific Data Area (LSDA) encoding](#lsda-encoding) - * [Personality Function encoding](#personality-encoding) + * [Encodings](#exception-handling-encodings) + * [Registers](#exception-handling-registers) 5. [DWARF](#dwarf) * [Dwarf Register Numbers](#dwarf-register-numbers) @@ -804,7 +803,9 @@ structures saved in `.eh_frame`, plus additional data structures in the `.gcc_except_table` section of the ELF. Some relevant fields in these data structures are defined below: -## Frame Descriptor Entry (FDE) encoding +## Encodings + +### Frame Descriptor Entry (FDE) encoding Used to encode the range of code addresses which the current Frame Descriptor Entry applies to. Generally encoded as: @@ -822,7 +823,7 @@ second instance, a `R_RISCV_ADD32` and `R_RISCV_SUB32` pair is emitted which encodes the difference between the end address and start address in the code. -## Language Specific Data Area (LSDA) encoding +### Language Specific Data Area (LSDA) encoding Encodes refences to the LSDA for the current FDE. Like the FDE encoding this is generally encoded as: @@ -836,7 +837,7 @@ to be emitted, encoding the offset from the position the LSDA is encoded in the FDE (in the `.eh_frame` section) to the LSDA data structure itself (which is found in the `.gcc_except_table` section). -## Personality Function encoding +### Personality Function encoding Use to encode references to the personality function for the current CIE. Unlike the LSDA and FDE, the personality function is encoded @@ -859,6 +860,14 @@ be in a shared object - and mean the `.eh_frame` section does not need to be writeable at runtime. Instead, only the new temporary `.sdata.DW.ref.__gxx_personality_v0` section is writeable. +## Registers + +When an exception is caught, data needs to be passed from the +personality function to the landing pad. Four scratch registers are +used for this purpose, and these parameters are passed to the landing +pad according to the integer calling convention; they are passed in +registers `a0`, `a1`, `a2` and `a3`. + # DWARF Dwarf Register Numbers