forked from OSchip/llvm-project
[ELF][RISCV] Assign st_shndx of __global_pointer$ to 1 if .sdata does not exist
This essentially reverts the code change of D63132 and switches to a simpler approach. In an executable/shared object, st_shndx of a symbol can be: 1) SHN_UNDEF: undefined symbol (or canonical PLT) 2) SHN_ABS: absolute symbol 3) any other value (usually a regular section index) represents a relative symbol. The actual value does not matter. Many ld.so (musl, all archs except MIPS of FreeBSD rtld-elf) even treat 2) and 3) the same. If .sdata does not exist, it does not matter what value/section __global_pointer$ has, as long as it is relative (otherwise there will be a pedantic lld error. See D63132). Just set the st_shndx arbitrarily to 1. Dummy st_shndx=1 may be used by __rela_iplt_start, linker-script-defined symbols outside a section, __dso_handle, etc. Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D66798 llvm-svn: 370172
This commit is contained in:
parent
a761ba0f2d
commit
8fbe81fb29
|
@ -3506,23 +3506,6 @@ bool PPC64LongBranchTargetSection::isNeeded() const {
|
|||
return !finalized || !entries.empty();
|
||||
}
|
||||
|
||||
RISCVSdataSection::RISCVSdataSection()
|
||||
: SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, 1, ".sdata") {}
|
||||
|
||||
bool RISCVSdataSection::isNeeded() const {
|
||||
if (!ElfSym::riscvGlobalPointer)
|
||||
return false;
|
||||
|
||||
// __global_pointer$ is defined relative to .sdata . If the section does not
|
||||
// exist, create a dummy one.
|
||||
for (BaseCommand *base : getParent()->sectionCommands)
|
||||
if (auto *isd = dyn_cast<InputSectionDescription>(base))
|
||||
for (InputSection *isec : isd->sections)
|
||||
if (isec != this)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t getAbiVersion() {
|
||||
// MIPS non-PIC executable gets ABI version 1.
|
||||
if (config->emachine == EM_MIPS) {
|
||||
|
|
|
@ -1100,15 +1100,6 @@ public:
|
|||
void writeTo(uint8_t *buf) override;
|
||||
};
|
||||
|
||||
// Create a dummy .sdata for __global_pointer$ if .sdata does not exist.
|
||||
class RISCVSdataSection final : public SyntheticSection {
|
||||
public:
|
||||
RISCVSdataSection();
|
||||
size_t getSize() const override { return 0; }
|
||||
bool isNeeded() const override;
|
||||
void writeTo(uint8_t *buf) override {}
|
||||
};
|
||||
|
||||
InputSection *createInterpSection();
|
||||
MergeInputSection *createCommentSection();
|
||||
template <class ELFT> void splitSections();
|
||||
|
@ -1173,7 +1164,6 @@ struct InStruct {
|
|||
PltSection *plt;
|
||||
PltSection *iplt;
|
||||
PPC32Got2Section *ppc32Got2;
|
||||
RISCVSdataSection *riscvSdata;
|
||||
RelocationBaseSection *relaPlt;
|
||||
RelocationBaseSection *relaIplt;
|
||||
StringTableSection *shStrTab;
|
||||
|
|
|
@ -474,11 +474,6 @@ template <class ELFT> static void createSyntheticSections() {
|
|||
add(in.ppc64LongBranchTarget);
|
||||
}
|
||||
|
||||
if (config->emachine == EM_RISCV) {
|
||||
in.riscvSdata = make<RISCVSdataSection>();
|
||||
add(in.riscvSdata);
|
||||
}
|
||||
|
||||
in.gotPlt = make<GotPltSection>();
|
||||
add(in.gotPlt);
|
||||
in.igotPlt = make<IgotPltSection>();
|
||||
|
@ -1701,12 +1696,16 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
|||
// Define __rel[a]_iplt_{start,end} symbols if needed.
|
||||
addRelIpltSymbols();
|
||||
|
||||
// RISC-V's gp can address +/- 2 KiB, set it to .sdata + 0x800 if not defined.
|
||||
// This symbol should only be defined in an executable.
|
||||
if (config->emachine == EM_RISCV && !config->shared)
|
||||
// RISC-V's gp can address +/- 2 KiB, set it to .sdata + 0x800. This symbol
|
||||
// should only be defined in an executable. If .sdata does not exist, its
|
||||
// value/section does not matter but it has to be relative, so set its
|
||||
// st_shndx arbitrarily to 1 (Out::elfHeader).
|
||||
if (config->emachine == EM_RISCV && !config->shared) {
|
||||
OutputSection *sec = findSection(".sdata");
|
||||
ElfSym::riscvGlobalPointer =
|
||||
addOptionalRegular("__global_pointer$", findSection(".sdata"), 0x800,
|
||||
STV_DEFAULT, STB_GLOBAL);
|
||||
addOptionalRegular("__global_pointer$", sec ? sec : Out::elfHeader,
|
||||
0x800, STV_DEFAULT, STB_GLOBAL);
|
||||
}
|
||||
|
||||
if (config->emachine == EM_X86_64) {
|
||||
// On targets that support TLSDESC, _TLS_MODULE_BASE_ is defined in such a
|
||||
|
@ -1881,7 +1880,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
|||
finalizeSynthetic(in.plt);
|
||||
finalizeSynthetic(in.iplt);
|
||||
finalizeSynthetic(in.ppc32Got2);
|
||||
finalizeSynthetic(in.riscvSdata);
|
||||
finalizeSynthetic(in.partIndex);
|
||||
|
||||
// Dynamic section must be the last one in this list and dynamic
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
# REQUIRES: riscv
|
||||
# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.32.o
|
||||
# RUN: ld.lld -pie %t.32.o -o %t.32
|
||||
# RUN: llvm-readelf -S %t.32 | FileCheck --check-prefix=SEC %s
|
||||
# RUN: llvm-readelf -s %t.32 | FileCheck --check-prefix=SYM %s
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.64.o
|
||||
# RUN: ld.lld -pie %t.64.o -o %t.64
|
||||
# RUN: llvm-readelf -S %t.64 | FileCheck --check-prefix=SEC %s
|
||||
# RUN: llvm-readelf -s %t.64 | FileCheck --check-prefix=SYM %s
|
||||
|
||||
## If there is an undefined reference to __global_pointer$ but .sdata doesn't
|
||||
## exist, create a dummy one.
|
||||
|
||||
## __global_pointer$ = .sdata+0x800
|
||||
# SEC: [ 7] .sdata PROGBITS {{0*}}00003000
|
||||
# SYM: {{0*}}00003800 0 NOTYPE GLOBAL DEFAULT 7 __global_pointer$
|
||||
|
||||
## If __global_pointer$ is not used, don't create .sdata .
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=riscv32 /dev/null -o %t.32.o
|
||||
# RUN: ld.lld -pie %t.32.o -o %t.32
|
||||
# RUN: llvm-readelf -S %t.32 | FileCheck --implicit-check-not=.sdata /dev/null
|
||||
|
||||
lla gp, __global_pointer$
|
|
@ -0,0 +1,15 @@
|
|||
# REQUIRES: riscv
|
||||
# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.32.o
|
||||
# RUN: ld.lld -pie %t.32.o -o %t.32
|
||||
# RUN: llvm-readelf -s %t.32 | FileCheck --check-prefix=SYM %s
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.64.o
|
||||
# RUN: ld.lld -pie %t.64.o -o %t.64
|
||||
# RUN: llvm-readelf -s %t.64 | FileCheck --check-prefix=SYM %s
|
||||
|
||||
## If there is an undefined reference to __global_pointer$ but .sdata doesn't
|
||||
## exist, define __global_pointer$ and set its st_shndx arbitrarily to 1.
|
||||
|
||||
# SYM: {{0*}}00000800 0 NOTYPE GLOBAL DEFAULT 1 __global_pointer$
|
||||
|
||||
lla gp, __global_pointer$
|
Loading…
Reference in New Issue