@@ -59,7 +59,7 @@ TargetInfo *Target;
5959static void or32le (uint8_t *P, int32_t V) { write32le (P, read32le (P) | V); }
6060static void or32be (uint8_t *P, int32_t V) { write32be (P, read32be (P) | V); }
6161
62- template <class ELFT > static std::string getErrorLoc (uint8_t *Loc) {
62+ template <class ELFT > static std::string getErrorLoc (const uint8_t *Loc) {
6363 for (InputSectionBase *D : InputSections) {
6464 auto *IS = dyn_cast_or_null<InputSection>(D);
6565 if (!IS || !IS->OutSec )
@@ -72,7 +72,7 @@ template <class ELFT> static std::string getErrorLoc(uint8_t *Loc) {
7272 return " " ;
7373}
7474
75- static std::string getErrorLocation (uint8_t *Loc) {
75+ static std::string getErrorLocation (const uint8_t *Loc) {
7676 switch (Config->EKind ) {
7777 case ELF32LEKind:
7878 return getErrorLoc<ELF32LE>(Loc);
@@ -119,7 +119,8 @@ namespace {
119119class X86TargetInfo final : public TargetInfo {
120120public:
121121 X86TargetInfo ();
122- RelExpr getRelExpr (uint32_t Type, const SymbolBody &S) const override ;
122+ RelExpr getRelExpr (uint32_t Type, const SymbolBody &S,
123+ const uint8_t *Loc) const override ;
123124 int64_t getImplicitAddend (const uint8_t *Buf, uint32_t Type) const override ;
124125 void writeGotPltHeader (uint8_t *Buf) const override ;
125126 uint32_t getDynRel (uint32_t Type) const override ;
@@ -143,7 +144,8 @@ class X86TargetInfo final : public TargetInfo {
143144template <class ELFT > class X86_64TargetInfo final : public TargetInfo {
144145public:
145146 X86_64TargetInfo ();
146- RelExpr getRelExpr (uint32_t Type, const SymbolBody &S) const override ;
147+ RelExpr getRelExpr (uint32_t Type, const SymbolBody &S,
148+ const uint8_t *Loc) const override ;
147149 bool isPicRel (uint32_t Type) const override ;
148150 bool isTlsLocalDynamicRel (uint32_t Type) const override ;
149151 bool isTlsInitialExecRel (uint32_t Type) const override ;
@@ -171,13 +173,15 @@ class PPCTargetInfo final : public TargetInfo {
171173public:
172174 PPCTargetInfo ();
173175 void relocateOne (uint8_t *Loc, uint32_t Type, uint64_t Val) const override ;
174- RelExpr getRelExpr (uint32_t Type, const SymbolBody &S) const override ;
176+ RelExpr getRelExpr (uint32_t Type, const SymbolBody &S,
177+ const uint8_t *Loc) const override ;
175178};
176179
177180class PPC64TargetInfo final : public TargetInfo {
178181public:
179182 PPC64TargetInfo ();
180- RelExpr getRelExpr (uint32_t Type, const SymbolBody &S) const override ;
183+ RelExpr getRelExpr (uint32_t Type, const SymbolBody &S,
184+ const uint8_t *Loc) const override ;
181185 void writePlt (uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
182186 int32_t Index, unsigned RelOff) const override ;
183187 void relocateOne (uint8_t *Loc, uint32_t Type, uint64_t Val) const override ;
@@ -186,7 +190,8 @@ class PPC64TargetInfo final : public TargetInfo {
186190class AArch64TargetInfo final : public TargetInfo {
187191public:
188192 AArch64TargetInfo ();
189- RelExpr getRelExpr (uint32_t Type, const SymbolBody &S) const override ;
193+ RelExpr getRelExpr (uint32_t Type, const SymbolBody &S,
194+ const uint8_t *Loc) const override ;
190195 bool isPicRel (uint32_t Type) const override ;
191196 bool isTlsInitialExecRel (uint32_t Type) const override ;
192197 void writeGotPlt (uint8_t *Buf, const SymbolBody &S) const override ;
@@ -206,13 +211,15 @@ class AMDGPUTargetInfo final : public TargetInfo {
206211public:
207212 AMDGPUTargetInfo ();
208213 void relocateOne (uint8_t *Loc, uint32_t Type, uint64_t Val) const override ;
209- RelExpr getRelExpr (uint32_t Type, const SymbolBody &S) const override ;
214+ RelExpr getRelExpr (uint32_t Type, const SymbolBody &S,
215+ const uint8_t *Loc) const override ;
210216};
211217
212218class ARMTargetInfo final : public TargetInfo {
213219public:
214220 ARMTargetInfo ();
215- RelExpr getRelExpr (uint32_t Type, const SymbolBody &S) const override ;
221+ RelExpr getRelExpr (uint32_t Type, const SymbolBody &S,
222+ const uint8_t *Loc) const override ;
216223 bool isPicRel (uint32_t Type) const override ;
217224 uint32_t getDynRel (uint32_t Type) const override ;
218225 int64_t getImplicitAddend (const uint8_t *Buf, uint32_t Type) const override ;
@@ -233,7 +240,8 @@ class ARMTargetInfo final : public TargetInfo {
233240template <class ELFT > class MipsTargetInfo final : public TargetInfo {
234241public:
235242 MipsTargetInfo ();
236- RelExpr getRelExpr (uint32_t Type, const SymbolBody &S) const override ;
243+ RelExpr getRelExpr (uint32_t Type, const SymbolBody &S,
244+ const uint8_t *Loc) const override ;
237245 int64_t getImplicitAddend (const uint8_t *Buf, uint32_t Type) const override ;
238246 bool isPicRel (uint32_t Type) const override ;
239247 uint32_t getDynRel (uint32_t Type) const override ;
@@ -353,7 +361,8 @@ X86TargetInfo::X86TargetInfo() {
353361 TrapInstr = 0xcccccccc ;
354362}
355363
356- RelExpr X86TargetInfo::getRelExpr (uint32_t Type, const SymbolBody &S) const {
364+ RelExpr X86TargetInfo::getRelExpr (uint32_t Type, const SymbolBody &S,
365+ const uint8_t *Loc) const {
357366 switch (Type) {
358367 case R_386_8:
359368 case R_386_16:
@@ -376,6 +385,24 @@ RelExpr X86TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const {
376385 return R_GOT;
377386 case R_386_GOT32:
378387 case R_386_GOT32X:
388+ // These relocations can be calculated in two different ways.
389+ // Usual calculation is G + A - GOT what means an offset in GOT table
390+ // (R_GOT_FROM_END). When instruction pointed by relocation has no base
391+ // register, then relocations can be used when PIC code is disabled. In that
392+ // case calculation is G + A, it resolves to an address of entry in GOT
393+ // (R_GOT) and not an offset.
394+ //
395+ // To check that instruction has no base register we scan ModR/M byte.
396+ // See "Table 2-2. 32-Bit Addressing Forms with the ModR/M Byte"
397+ // (http://www.intel.com/content/dam/www/public/us/en/documents/manuals/
398+ // 64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf)
399+ if ((Loc[-1 ] & 0xc7 ) != 0x5 )
400+ return R_GOT_FROM_END;
401+ if (Config->Pic )
402+ error (toString (S.File ) + " : relocation " + toString (Type) + " against '" +
403+ S.getName () +
404+ " ' without base register can not be used when PIC enabled" );
405+ return R_GOT;
379406 case R_386_TLS_GOTIE:
380407 return R_GOT_FROM_END;
381408 case R_386_GOTOFF:
@@ -654,8 +681,8 @@ template <class ELFT> X86_64TargetInfo<ELFT>::X86_64TargetInfo() {
654681}
655682
656683template <class ELFT >
657- RelExpr X86_64TargetInfo<ELFT>::getRelExpr(uint32_t Type,
658- const SymbolBody &S ) const {
684+ RelExpr X86_64TargetInfo<ELFT>::getRelExpr(uint32_t Type, const SymbolBody &S,
685+ const uint8_t *Loc ) const {
659686 switch (Type) {
660687 case R_X86_64_8:
661688 case R_X86_64_16:
@@ -1093,7 +1120,8 @@ void PPCTargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
10931120 }
10941121}
10951122
1096- RelExpr PPCTargetInfo::getRelExpr (uint32_t Type, const SymbolBody &S) const {
1123+ RelExpr PPCTargetInfo::getRelExpr (uint32_t Type, const SymbolBody &S,
1124+ const uint8_t *Loc) const {
10971125 switch (Type) {
10981126 case R_PPC_REL24:
10991127 case R_PPC_REL32:
@@ -1142,7 +1170,8 @@ uint64_t getPPC64TocBase() {
11421170 return TocVA + PPC64TocOffset;
11431171}
11441172
1145- RelExpr PPC64TargetInfo::getRelExpr (uint32_t Type, const SymbolBody &S) const {
1173+ RelExpr PPC64TargetInfo::getRelExpr (uint32_t Type, const SymbolBody &S,
1174+ const uint8_t *Loc) const {
11461175 switch (Type) {
11471176 default :
11481177 return R_ABS;
@@ -1290,8 +1319,8 @@ AArch64TargetInfo::AArch64TargetInfo() {
12901319 TcbSize = 16 ;
12911320}
12921321
1293- RelExpr AArch64TargetInfo::getRelExpr (uint32_t Type,
1294- const SymbolBody &S ) const {
1322+ RelExpr AArch64TargetInfo::getRelExpr (uint32_t Type, const SymbolBody &S,
1323+ const uint8_t *Loc ) const {
12951324 switch (Type) {
12961325 default :
12971326 return R_ABS;
@@ -1634,7 +1663,8 @@ void AMDGPUTargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
16341663 }
16351664}
16361665
1637- RelExpr AMDGPUTargetInfo::getRelExpr (uint32_t Type, const SymbolBody &S) const {
1666+ RelExpr AMDGPUTargetInfo::getRelExpr (uint32_t Type, const SymbolBody &S,
1667+ const uint8_t *Loc) const {
16381668 switch (Type) {
16391669 case R_AMDGPU_ABS32:
16401670 case R_AMDGPU_ABS64:
@@ -1671,7 +1701,8 @@ ARMTargetInfo::ARMTargetInfo() {
16711701 NeedsThunks = true ;
16721702}
16731703
1674- RelExpr ARMTargetInfo::getRelExpr (uint32_t Type, const SymbolBody &S) const {
1704+ RelExpr ARMTargetInfo::getRelExpr (uint32_t Type, const SymbolBody &S,
1705+ const uint8_t *Loc) const {
16751706 switch (Type) {
16761707 default :
16771708 return R_ABS;
@@ -2065,8 +2096,8 @@ template <class ELFT> MipsTargetInfo<ELFT>::MipsTargetInfo() {
20652096}
20662097
20672098template <class ELFT >
2068- RelExpr MipsTargetInfo<ELFT>::getRelExpr(uint32_t Type,
2069- const SymbolBody &S ) const {
2099+ RelExpr MipsTargetInfo<ELFT>::getRelExpr(uint32_t Type, const SymbolBody &S,
2100+ const uint8_t *Loc ) const {
20702101 // See comment in the calculateMipsRelChain.
20712102 if (ELFT::Is64Bits || Config->MipsN32Abi )
20722103 Type &= 0xff ;
0 commit comments