[llvm] r369755 - [mips] Do not include offset into `%got` expression for global symbols

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 23 06:36:14 PDT 2019


Author: atanasyan
Date: Fri Aug 23 06:36:14 2019
New Revision: 369755

URL: http://llvm.org/viewvc/llvm-project?rev=369755&view=rev
Log:
[mips] Do not include offset into `%got` expression for global symbols

Now pseudo instruction `la $6, symbol+8($6)` is expanding into the following
chain of commands:
```
lw    $1, %got(symbol+8)($gp)
addiu $1, $1, 8
addu  $6, $1, $6
```

This is incorrect. When a linker handles the `R_MIPS_GOT16` relocation,
it does not expect to get any addend and breaks on assertion. Otherwise
it has to create new GOT entry for each unique "sym + offset" pair.
Offset for a global symbol should be added to result of loading GOT
entry by a separate `add` command.

The patch fixes the problem by stripping off an offset from the expression
passed to the `%got`. That's interesting that even current code inserts
a separate `add` command.

Differential Revision: https://reviews.llvm.org/D66552

Modified:
    llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
    llvm/trunk/test/MC/Mips/macro-la-pic.s
    llvm/trunk/test/MC/Mips/mips-expansions.s

Modified: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp?rev=369755&r1=369754&r2=369755&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Fri Aug 23 06:36:14 2019
@@ -2884,16 +2884,18 @@ bool MipsAsmParser::loadAndAddSymbolAddr
       return true;
     }
 
+    bool IsLocalSym =
+        Res.getSymA()->getSymbol().isInSection() ||
+        Res.getSymA()->getSymbol().isTemporary() ||
+        (Res.getSymA()->getSymbol().isELF() &&
+         cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
+             ELF::STB_LOCAL);
+
     // The case where the result register is $25 is somewhat special. If the
     // symbol in the final relocation is external and not modified with a
     // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
     if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
-        Res.getConstant() == 0 &&
-        !(Res.getSymA()->getSymbol().isInSection() ||
-          Res.getSymA()->getSymbol().isTemporary() ||
-          (Res.getSymA()->getSymbol().isELF() &&
-           cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
-               ELF::STB_LOCAL))) {
+        Res.getConstant() == 0 && !IsLocalSym) {
       const MCExpr *CallExpr =
           MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
       TOut.emitRRX(Mips::LW, DstReg, GPReg, MCOperand::createExpr(CallExpr),
@@ -2902,8 +2904,8 @@ bool MipsAsmParser::loadAndAddSymbolAddr
     }
 
     // The remaining cases are:
-    //   External GOT: lw $tmp, %got(symbol+offset)($gp)
-    //                >addiu $tmp, $tmp, %lo(offset)
+    //   External GOT: lw $tmp, %got(symbol)($gp)
+    //                >addiu $tmp, $tmp, offset
     //                >addiu $rd, $tmp, $rs
     //   Local GOT:    lw $tmp, %got(symbol+offset)($gp)
     //                 addiu $tmp, $tmp, %lo(symbol+offset)($gp)
@@ -2911,17 +2913,19 @@ bool MipsAsmParser::loadAndAddSymbolAddr
     // The addiu's marked with a '>' may be omitted if they are redundant. If
     // this happens then the last instruction must use $rd as the result
     // register.
-    const MipsMCExpr *GotExpr =
-        MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
+    const MipsMCExpr *GotExpr = nullptr;
     const MCExpr *LoExpr = nullptr;
-    if (Res.getSymA()->getSymbol().isInSection() ||
-        Res.getSymA()->getSymbol().isTemporary())
+    if (IsLocalSym) {
+      GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
       LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
-    else if (Res.getConstant() != 0) {
+    } else {
       // External symbols fully resolve the symbol with just the %got(symbol)
       // but we must still account for any offset to the symbol for expressions
       // like symbol+8.
-      LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
+      GotExpr =
+          MipsMCExpr::create(MipsMCExpr::MEK_GOT, Res.getSymA(), getContext());
+      if (Res.getConstant() != 0)
+        LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
     }
 
     unsigned TmpReg = DstReg;

Modified: llvm/trunk/test/MC/Mips/macro-la-pic.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/macro-la-pic.s?rev=369755&r1=369754&r2=369755&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/macro-la-pic.s (original)
+++ llvm/trunk/test/MC/Mips/macro-la-pic.s Fri Aug 23 06:36:14 2019
@@ -14,13 +14,15 @@ la $5, symbol($6)     # CHECK: lw $5, %g
 la $6, symbol($6)     # CHECK: lw $1, %got(symbol)($gp)    # encoding: [0x8f,0x81,A,A]
                       # CHECK:                             #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
                       # CHECK: addu $6, $1, $6             # encoding: [0x00,0x26,0x30,0x21]
-la $5, symbol+8       # CHECK: lw $5, %got(symbol+8)($gp)  # encoding: [0x8f,0x85,A,A]
-                      # CHECK:                             #   fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
-la $5, symbol+8($6)   # CHECK: lw $5, %got(symbol+8)($gp)  # encoding: [0x8f,0x85,A,A]
-                      # CHECK:                             #   fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
+la $5, symbol+8       # CHECK: lw $5, %got(symbol)($gp)    # encoding: [0x8f,0x85,A,A]
+                      # CHECK:                             #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
+                      # CHECK: addiu $5, $5, 8             # encoding: [0x24,0xa5,0x00,0x08]
+la $5, symbol+8($6)   # CHECK: lw $5, %got(symbol)($gp)    # encoding: [0x8f,0x85,A,A]
+                      # CHECK:                             #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
+                      # CHECK: addiu $5, $5, 8             # encoding: [0x24,0xa5,0x00,0x08]
                       # CHECK: addu $5, $5, $6             # encoding: [0x00,0xa6,0x28,0x21]
-la $6, symbol+8($6)   # CHECK: lw $1, %got(symbol+8)($gp)  # encoding: [0x8f,0x81,A,A]
-                      # CHECK:                             #   fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
+la $6, symbol+8($6)   # CHECK: lw $1, %got(symbol)($gp)    # encoding: [0x8f,0x81,A,A]
+                      # CHECK:                             #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
                       # CHECK: addiu $1, $1, 8             # encoding: [0x24,0x21,0x00,0x08]
                       # CHECK: addu $6, $1, $6             # encoding: [0x00,0x26,0x30,0x21]
 la $5, 1f             # CHECK: lw $5, %got($tmp0)($gp)     # encoding: [0x8f,0x85,A,A]
@@ -38,13 +40,15 @@ la $25, symbol($6)    # CHECK: lw $25, %
 la $25, symbol($25)   # CHECK: lw $1, %got(symbol)($gp)     # encoding: [0x8f,0x81,A,A]
                       # CHECK:                              #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
                       # CHECK: addu $25, $1, $25            # encoding: [0x00,0x39,0xc8,0x21]
-la $25, symbol+8      # CHECK: lw $25, %got(symbol+8)($gp)  # encoding: [0x8f,0x99,A,A]
-                      # CHECK:                              #   fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
-la $25, symbol+8($6)  # CHECK: lw $25, %got(symbol+8)($gp)  # encoding: [0x8f,0x99,A,A]
-                      # CHECK:                              #   fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
+la $25, symbol+8      # CHECK: lw $25, %got(symbol)($gp)    # encoding: [0x8f,0x99,A,A]
+                      # CHECK:                              #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
+                      # CHECK: addiu $25, $25, 8            # encoding: [0x27,0x39,0x00,0x08]
+la $25, symbol+8($6)  # CHECK: lw $25, %got(symbol)($gp)    # encoding: [0x8f,0x99,A,A]
+                      # CHECK:                              #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
+                      # CHECK: addiu $25, $25, 8            # encoding: [0x27,0x39,0x00,0x08]
                       # CHECK: addu $25, $25, $6            # encoding: [0x03,0x26,0xc8,0x21]
-la $25, symbol+8($25) # CHECK: lw $1, %got(symbol+8)($gp)   # encoding: [0x8f,0x81,A,A]
-                      # CHECK:                              #   fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
+la $25, symbol+8($25) # CHECK: lw $1, %got(symbol)($gp)     # encoding: [0x8f,0x81,A,A]
+                      # CHECK:                              #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
                       # CHECK: addiu $1, $1, 8              # encoding: [0x24,0x21,0x00,0x08]
                       # CHECK: addu $25, $1, $25            # encoding: [0x00,0x39,0xc8,0x21]
 la $25, 1f            # CHECK: lw $25, %got($tmp1)($gp)     # encoding: [0x8f,0x99,A,A]

Modified: llvm/trunk/test/MC/Mips/mips-expansions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips-expansions.s?rev=369755&r1=369754&r2=369755&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/mips-expansions.s (original)
+++ llvm/trunk/test/MC/Mips/mips-expansions.s Fri Aug 23 06:36:14 2019
@@ -144,13 +144,13 @@
 # CHECK-LE: sw      $10, -7616($1)            # encoding: [0x40,0xe2,0x2a,0xac]
 
   lw $8, symbol+8
-# CHECK-LE: lw      $8, %got(symbol+8)($gp)   # encoding: [A,A,0x88,0x8f]
-# CHECK-LE:                                   #   fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
+# CHECK-LE: lw      $8, %got(symbol)($gp)     # encoding: [A,A,0x88,0x8f]
+# CHECK-LE:                                   #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
 # CHECK-LE: addiu   $8, $8, 8                 # encoding: [0x08,0x00,0x08,0x25]
 # CHECK-LE: lw      $8, 0($8)                 # encoding: [0x00,0x00,0x08,0x8d]
   sw $8, symbol+8
-# CHECK-LE: lw      $1, %got(symbol+8)($gp)   # encoding: [A,A,0x81,0x8f]
-# CHECK-LE:                                   #   fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
+# CHECK-LE: lw      $1, %got(symbol)($gp)     # encoding: [A,A,0x81,0x8f]
+# CHECK-LE:                                   #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
 # CHECK-LE: addiu   $1, $1, 8                 # encoding: [0x08,0x00,0x21,0x24]
 # CHECK-LE: sw      $8, 0($1)                 # encoding: [0x00,0x00,0x28,0xac]
 




More information about the llvm-commits mailing list