-
Notifications
You must be signed in to change notification settings - Fork 179
Document exception handling, add R_RISCV_32_PCREL description #110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,7 +21,10 @@ | |
| * [Note Sections](#note-sections) | ||
| * [Dynamic Table](#dynamic-table) | ||
| * [Hash Table](#hash-table) | ||
| 4. [DWARF](#dwarf) | ||
| 4. [Exception Handling](#exception-handling) | ||
| * [Encodings](#exception-handling-encodings) | ||
| * [Registers](#exception-handling-registers) | ||
| 5. [DWARF](#dwarf) | ||
| * [Dwarf Register Numbers](#dwarf-register-numbers) | ||
|
|
||
| ## Copyright and license information | ||
|
|
@@ -436,7 +439,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 | ||
|
|
@@ -791,6 +795,79 @@ typedef struct | |
|
|
||
| ## <a name=hash-table></a>Hash Table | ||
|
|
||
| # <a name=exception-handling></a>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: | ||
|
|
||
| ## <a name=exception-handling-encodings></a>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: | ||
|
|
||
| ``` | ||
| 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 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically, the R_RISCV_ADD32 and R_RISCV_SUB32 relocations are only required when linker relaxation is enabled, since otherwise we can't know the size of the function until after linker relaxation. Unfortunately, the toolchain currently emits the relocs always. There is an open bug report somewhere asking us to fix this, so in the future these relocs may not be present when linker relaxation is disabled. |
||
| 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. | ||
|
|
||
| ## <a name=exception-handling-registers></a>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`. | ||
|
|
||
| # <a name=dwarf></a>DWARF | ||
|
|
||
| Dwarf Register Numbers <a name=dwarf-register-numbers> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have support for 64-bit DWARF in the gcc RISC-V port, so yes, this is always DW_EH_PE_sdata4 currently. I don't anticipate that we will ever need 64-bit DWARF. If someone does insist on adding support for that, then we will need a R_RISCV_64_PCREL relocation which does not exist yet. Most gcc ports don't bother to support 64-bit DWARF. It is only useful if you have binaries over 4GB in size, and if you do have binaries that big then you probably have other more important problems than unwind info.