996625ec58
There is a problem with the current elf loader for risc-v: when a pair of PCREL_HI20 / LO12 relocations are encountered, it is assumed that these will follow each other immediately, as follows: label: auipc a0, %pcrel_hi(symbol) // R_RISCV_PCREL_HI20 load/store a0, %pcrel_lo(label)(a0) // R_RISCV_PCREL_LO12_I/S With this assumption, the hi/lo relocations are both done when a hi20 relocation entry is encountered, first to the current instruction (addr) and to the next instruction (addr + 4). However, this assumption is wrong. There is nothing in the elf relocation specification[1] that mandates this. Thus, the hi/lo relocation always needs to first fixup the hi-part, and when the lo-part is encountered, it needs to find the corresponding hi relocation entry, via the given "label". This necessitates (re-)visiting the relocation entries for the current section as well as looking for "label" in the symbol table. The NuttX elf loader does not allow such operations to be done in the machine specific part, so this patch fixes the relocation issue by introducing an architecture specific cache for the hi20 relocation and symbol table entries. When a lo12 relocation is encountered, the cache can be consulted to find the hi20 part. [1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc
108 lines
3.5 KiB
C
108 lines
3.5 KiB
C
/****************************************************************************
|
|
* arch/risc-v/include/elf.h
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership. The
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef __ARCH_RISCV_INCLUDE_ELF_H
|
|
#define __ARCH_RISCV_INCLUDE_ELF_H
|
|
|
|
/****************************************************************************
|
|
* Pre-processor Definitions
|
|
****************************************************************************/
|
|
|
|
/* https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md */
|
|
|
|
#define R_RISCV_NONE 0
|
|
#define R_RISCV_32 1
|
|
#define R_RISCV_64 2
|
|
#define R_RISCV_RELATIVE 3
|
|
#define R_RISCV_COPY 4
|
|
#define R_RISCV_JUMP_SLOT 5
|
|
#define R_RISCV_TLS_DTPMOD32 6
|
|
#define R_RISCV_TLS_DTPMOD64 7
|
|
#define R_RISCV_TLS_DTPREL32 8
|
|
#define R_RISCV_TLS_DTPREL64 9
|
|
#define R_RISCV_TLS_TPREL32 10
|
|
#define R_RISCV_TLS_TPREL64 11
|
|
|
|
#define R_RISCV_BRANCH 16
|
|
#define R_RISCV_JAL 17
|
|
#define R_RISCV_CALL 18
|
|
#define R_RISCV_CALL_PLT 19
|
|
#define R_RISCV_GOT_HI20 20
|
|
#define R_RISCV_TLS_GOT_HI20 21
|
|
#define R_RISCV_TLS_GD_HI20 22
|
|
#define R_RISCV_PCREL_HI20 23
|
|
#define R_RISCV_PCREL_LO12_I 24
|
|
#define R_RISCV_PCREL_LO12_S 25
|
|
#define R_RISCV_HI20 26
|
|
#define R_RISCV_LO12_I 27
|
|
#define R_RISCV_LO12_S 28
|
|
#define R_RISCV_TPREL_HI20 29
|
|
#define R_RISCV_TPREL_LO12_I 30
|
|
#define R_RISCV_TPREL_LO12_S 31
|
|
#define R_RISCV_TPREL_ADD 32
|
|
#define R_RISCV_ADD8 33
|
|
#define R_RISCV_ADD16 34
|
|
#define R_RISCV_ADD32 35
|
|
#define R_RISCV_ADD64 36
|
|
#define R_RISCV_SUB8 37
|
|
#define R_RISCV_SUB16 38
|
|
#define R_RISCV_SUB32 39
|
|
#define R_RISCV_SUB64 40
|
|
#define R_RISCV_GNU_VTINHERIT 41
|
|
#define R_RISCV_GNU_VTENTRY 42
|
|
#define R_RISCV_ALIGN 43
|
|
#define R_RISCV_RVC_BRANCH 44
|
|
#define R_RISCV_RVC_JUMP 45
|
|
#define R_RISCV_RVC_LUI 46
|
|
#define R_RISCV_GPREL_I 47
|
|
#define R_RISCV_GPREL_S 48
|
|
#define R_RISCV_TPREL_I 49
|
|
#define R_RISCV_TPREL_S 50
|
|
#define R_RISCV_RELAX 51
|
|
#define R_RISCV_SUB6 52
|
|
#define R_RISCV_SET6 53
|
|
#define R_RISCV_SET8 54
|
|
#define R_RISCV_SET16 55
|
|
#define R_RISCV_SET32 56
|
|
#define R_RISCV_32_PCREL 57
|
|
|
|
#define ARCH_ELFDATA 1
|
|
#define ARCH_ELF_RELCNT 8
|
|
|
|
/****************************************************************************
|
|
* Public Types
|
|
****************************************************************************/
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
struct arch_elfdata_s
|
|
{
|
|
struct hi20_rels_s
|
|
{
|
|
uintptr_t hi20_rel;
|
|
uintptr_t hi20_offset;
|
|
}
|
|
hi20_rels[ARCH_ELF_RELCNT];
|
|
};
|
|
typedef struct arch_elfdata_s arch_elfdata_t;
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
#endif /* __ARCH_RISCV_INCLUDE_ELF_H */
|