[SPARC][MC] Fix %gdop_hix22() and %gdop_lox10() to use correct relocations (#137915)
1bfc5e7 introduced support for `%gdop_hix22()` and `%gdop_lox10()`.
However, it incorrectly mapped them to `R_SPARC_GOTDATA_HIX22` and
`R_SPARC_GOTDATA_LOX10`. They should in fact emit
`R_SPARC_GOTDATA_OP_HIX22` and `R_SPARC_GOTDATA_OP_LOX10`.
This became a problem when assembling glibc's PIC startup code:
```asm
sethi %gdop_hix22(main), %o0
xor %o0, %gdop_lox10(main), %o0
ldx [%l7 + %o0], %o0, %gdop(main)
```
After the `xor`, `%o0` should contain the GOT offset for `main`, but
because of the incorrect relocations, it actually ends up containing the
address of `main`, which of course makes the following `ldx` fail.
This commit is contained in:
committed by
GitHub
parent
4c587f549c
commit
c3ff3b2ba3
@@ -82,11 +82,6 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
|
||||
|
||||
case Sparc::fixup_sparc_hm:
|
||||
return (Value >> 32) & 0x3ff;
|
||||
|
||||
case Sparc::fixup_sparc_gotdata_lox10:
|
||||
case Sparc::fixup_sparc_gotdata_hix22:
|
||||
case Sparc::fixup_sparc_gotdata_op:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +132,7 @@ namespace {
|
||||
}
|
||||
|
||||
MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override {
|
||||
// clang-format off
|
||||
const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = {
|
||||
// name offset bits flags
|
||||
{ "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
|
||||
@@ -157,9 +153,6 @@ namespace {
|
||||
{ "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_hix22", 10, 22, 0 },
|
||||
{ "fixup_sparc_lox10", 19, 13, 0 },
|
||||
{ "fixup_sparc_gotdata_hix22", 0, 0, 0 },
|
||||
{ "fixup_sparc_gotdata_lox10", 0, 0, 0 },
|
||||
{ "fixup_sparc_gotdata_op", 0, 0, 0 },
|
||||
};
|
||||
|
||||
const static MCFixupKindInfo InfosLE[Sparc::NumTargetFixupKinds] = {
|
||||
@@ -182,10 +175,8 @@ namespace {
|
||||
{ "fixup_sparc_wplt30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_hix22", 0, 22, 0 },
|
||||
{ "fixup_sparc_lox10", 0, 13, 0 },
|
||||
{ "fixup_sparc_gotdata_hix22", 0, 0, 0 },
|
||||
{ "fixup_sparc_gotdata_lox10", 0, 0, 0 },
|
||||
{ "fixup_sparc_gotdata_op", 0, 0, 0 },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// Fixup kinds from .reloc directive are like R_SPARC_NONE. They do
|
||||
// not require any extra processing.
|
||||
|
||||
@@ -98,6 +98,7 @@ unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
switch(Fixup.getTargetKind()) {
|
||||
default:
|
||||
llvm_unreachable("Unimplemented fixup -> relocation");
|
||||
@@ -127,10 +128,8 @@ unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx,
|
||||
case Sparc::fixup_sparc_lm: return ELF::R_SPARC_LM22;
|
||||
case Sparc::fixup_sparc_hix22: return ELF::R_SPARC_HIX22;
|
||||
case Sparc::fixup_sparc_lox10: return ELF::R_SPARC_LOX10;
|
||||
case Sparc::fixup_sparc_gotdata_hix22: return ELF::R_SPARC_GOTDATA_HIX22;
|
||||
case Sparc::fixup_sparc_gotdata_lox10: return ELF::R_SPARC_GOTDATA_LOX10;
|
||||
case Sparc::fixup_sparc_gotdata_op: return ELF::R_SPARC_GOTDATA_OP;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
return ELF::R_SPARC_NONE;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
namespace llvm {
|
||||
namespace Sparc {
|
||||
// clang-format off
|
||||
enum Fixups {
|
||||
// fixup_sparc_call30 - 30-bit PC relative relocation for call
|
||||
fixup_sparc_call30 = FirstTargetFixupKind,
|
||||
@@ -70,17 +71,11 @@ namespace llvm {
|
||||
/// 13-bit fixup corresponding to %lox(foo)
|
||||
fixup_sparc_lox10,
|
||||
|
||||
/// 22-bit fixup corresponding to %gdop_hix22(foo)
|
||||
fixup_sparc_gotdata_hix22,
|
||||
/// 13-bit fixup corresponding to %gdop_lox10(foo)
|
||||
fixup_sparc_gotdata_lox10,
|
||||
/// 32-bit fixup corresponding to %gdop(foo)
|
||||
fixup_sparc_gotdata_op,
|
||||
|
||||
// Marker
|
||||
LastTargetFixupKind,
|
||||
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
|
||||
};
|
||||
// clang-format on
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,9 +80,9 @@ StringRef SparcMCExpr::getSpecifierName(SparcMCExpr::Specifier S) {
|
||||
case VK_TLS_LE_LOX10: return "tle_lox10";
|
||||
case VK_HIX22: return "hix";
|
||||
case VK_LOX10: return "lox";
|
||||
case VK_GOTDATA_HIX22: return "gdop_hix22";
|
||||
case VK_GOTDATA_LOX10: return "gdop_lox10";
|
||||
case VK_GOTDATA_OP: return "gdop";
|
||||
case VK_GOTDATA_OP_HIX22: return "gdop_hix22";
|
||||
case VK_GOTDATA_OP_LOX10: return "gdop_lox10";
|
||||
case VK_GOTDATA_OP: return "gdop";
|
||||
}
|
||||
// clang-format on
|
||||
llvm_unreachable("Unhandled SparcMCExpr::Specifier");
|
||||
@@ -126,8 +126,8 @@ SparcMCExpr::Specifier SparcMCExpr::parseSpecifier(StringRef name) {
|
||||
.Case("tle_lox10", VK_TLS_LE_LOX10)
|
||||
.Case("hix", VK_HIX22)
|
||||
.Case("lox", VK_LOX10)
|
||||
.Case("gdop_hix22", VK_GOTDATA_HIX22)
|
||||
.Case("gdop_lox10", VK_GOTDATA_LOX10)
|
||||
.Case("gdop_hix22", VK_GOTDATA_OP_HIX22)
|
||||
.Case("gdop_lox10", VK_GOTDATA_OP_LOX10)
|
||||
.Case("gdop", VK_GOTDATA_OP)
|
||||
.Default(VK_None);
|
||||
}
|
||||
@@ -172,9 +172,9 @@ uint16_t SparcMCExpr::getFixupKind() const {
|
||||
case VK_TLS_LE_LOX10: return ELF::R_SPARC_TLS_LE_LOX10;
|
||||
case VK_HIX22: return Sparc::fixup_sparc_hix22;
|
||||
case VK_LOX10: return Sparc::fixup_sparc_lox10;
|
||||
case VK_GOTDATA_HIX22: return Sparc::fixup_sparc_gotdata_hix22;
|
||||
case VK_GOTDATA_LOX10: return Sparc::fixup_sparc_gotdata_lox10;
|
||||
case VK_GOTDATA_OP: return Sparc::fixup_sparc_gotdata_op;
|
||||
case VK_GOTDATA_OP_HIX22: return ELF::R_SPARC_GOTDATA_OP_HIX22;
|
||||
case VK_GOTDATA_OP_LOX10: return ELF::R_SPARC_GOTDATA_OP_LOX10;
|
||||
case VK_GOTDATA_OP: return ELF::R_SPARC_GOTDATA_OP;
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@ public:
|
||||
VK_TLS_LE_LOX10,
|
||||
VK_HIX22,
|
||||
VK_LOX10,
|
||||
VK_GOTDATA_HIX22,
|
||||
VK_GOTDATA_LOX10,
|
||||
VK_GOTDATA_OP_HIX22,
|
||||
VK_GOTDATA_OP_LOX10,
|
||||
VK_GOTDATA_OP,
|
||||
};
|
||||
|
||||
|
||||
@@ -63,8 +63,8 @@ sethi %lm(sym), %l0
|
||||
# ASM-NEXT: ldx [%l7+%l1], %l2, %gdop(sym)
|
||||
# OBJDUMP: R_SPARC_HIX22 sym
|
||||
# OBJDUMP: R_SPARC_LOX10 sym
|
||||
# OBJDUMP: R_SPARC_GOTDATA_HIX22 sym
|
||||
# OBJDUMP: R_SPARC_GOTDATA_LOX10 sym
|
||||
# OBJDUMP: R_SPARC_GOTDATA_OP_HIX22 sym
|
||||
# OBJDUMP: R_SPARC_GOTDATA_OP_LOX10 sym
|
||||
# OBJDUMP: R_SPARC_GOTDATA_OP sym
|
||||
sethi %hix(sym), %g1
|
||||
xor %g1, %lox(sym), %g1
|
||||
|
||||
Reference in New Issue
Block a user