Change how we handle section symbols on ELF.

On ELF every section can have a corresponding section symbol. When in
an assembly file we have

.quad .text

the '.text' refers to that symbol.

The way we used to handle them is to leave .text an undefined symbol
until the very end when the object writer would map them to the
actual section symbol.

The problem with that is that anything before the end would see an
undefined symbol. This could result in bad diagnostics
(test/MC/AArch64/label-arithmetic-diags-elf.s), or incorrect results
when using the asm streamer (est/MC/Mips/expansion-jal-sym-pic.s).

Fixing this will also allow using the section symbol earlier for
setting sh_link of SHF_METADATA sections.

This patch includes a few hacks to avoid changing our behaviour when
handling conflicts between section symbols and other symbols. I
reported pr31850 to track that.

llvm-svn: 293936
This commit is contained in:
Rafael Espindola 2017-02-02 21:26:06 +00:00
parent 59c3e0d946
commit f20f8d830f
18 changed files with 103 additions and 140 deletions

View File

@ -83,10 +83,6 @@ namespace llvm {
/// Bindings of names to symbols.
SymbolTable Symbols;
/// Sections can have a corresponding symbol. This maps one to the
/// other.
DenseMap<const MCSection *, MCSymbol *> SectionSymbols;
/// A mapping from a local label number and an instance count to a symbol.
/// For example, in the assembly
/// 1:
@ -232,6 +228,13 @@ namespace llvm {
MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
unsigned Instance);
MCSectionELF *createELFSectionImpl(StringRef Section, unsigned Type,
unsigned Flags, SectionKind K,
unsigned EntrySize,
const MCSymbolELF *Group,
unsigned UniqueID,
const MCSectionELF *Associated);
public:
explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI,
const MCObjectFileInfo *MOFI,
@ -288,8 +291,6 @@ namespace llvm {
/// \param Name - The symbol name, which must be unique across all symbols.
MCSymbol *getOrCreateSymbol(const Twine &Name);
MCSymbolELF *getOrCreateSectionSymbol(const MCSectionELF &Section);
/// Gets a symbol that will be defined to the final stack offset of a local
/// variable after codegen.
///
@ -340,43 +341,22 @@ namespace llvm {
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags) {
return getELFSection(Section, Type, Flags, nullptr);
}
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, const char *BeginSymName) {
return getELFSection(Section, Type, Flags, 0, "", BeginSymName);
return getELFSection(Section, Type, Flags, 0, "");
}
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const Twine &Group) {
return getELFSection(Section, Type, Flags, EntrySize, Group, nullptr);
return getELFSection(Section, Type, Flags, EntrySize, Group, ~0);
}
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const Twine &Group, const char *BeginSymName) {
return getELFSection(Section, Type, Flags, EntrySize, Group, ~0,
BeginSymName);
}
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const Twine &Group, unsigned UniqueID) {
return getELFSection(Section, Type, Flags, EntrySize, Group, UniqueID,
nullptr);
}
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const Twine &Group, unsigned UniqueID,
const char *BeginSymName);
const Twine &Group, unsigned UniqueID);
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *Group, unsigned UniqueID,
const char *BeginSymName,
const MCSectionELF *Associated);
/// Get a section with the provided group identifier. This section is

View File

@ -371,22 +371,6 @@ uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym,
void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) {
// Section symbols are used as definitions for undefined symbols with matching
// names. If there are multiple sections with the same name, the first one is
// used.
for (const MCSection &Sec : Asm) {
const MCSymbol *Begin = Sec.getBeginSymbol();
if (!Begin)
continue;
const MCSymbol *Alias = Asm.getContext().lookupSymbol(Begin->getName());
if (!Alias || !Alias->isUndefined())
continue;
Renames.insert(
std::make_pair(cast<MCSymbolELF>(Alias), cast<MCSymbolELF>(Begin)));
}
// The presence of symbol versions causes undefined symbols and
// versions declared with @@@ to be renamed.
for (const MCSymbol &A : Asm.symbols()) {

View File

@ -80,7 +80,6 @@ void MCContext::reset() {
MCSubtargetAllocator.DestroyAll();
UsedNames.clear();
Symbols.clear();
SectionSymbols.clear();
Allocator.Reset();
Instances.clear();
CompilationDir.clear();
@ -124,18 +123,6 @@ MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) {
return Sym;
}
MCSymbolELF *MCContext::getOrCreateSectionSymbol(const MCSectionELF &Section) {
MCSymbol *&Sym = SectionSymbols[&Section];
if (Sym)
return cast<MCSymbolELF>(Sym);
StringRef Name = Section.getSectionName();
auto NameIter = UsedNames.insert(std::make_pair(Name, false)).first;
Sym = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false);
return cast<MCSymbolELF>(Sym);
}
MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName,
unsigned Idx) {
return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
@ -316,6 +303,38 @@ void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) {
const_cast<MCSectionELF *>(Section)->setSectionName(CachedName);
}
MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
unsigned Flags, SectionKind K,
unsigned EntrySize,
const MCSymbolELF *Group,
unsigned UniqueID,
const MCSectionELF *Associated) {
MCSymbolELF *R;
MCSymbol *&Sym = Symbols[Section];
if (Sym && Sym->isUndefined()) {
R = cast<MCSymbolELF>(Sym);
} else {
auto NameIter = UsedNames.insert(std::make_pair(Section, false)).first;
R = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false);
if (!Sym)
Sym = R;
}
R->setBinding(ELF::STB_LOCAL);
R->setType(ELF::STT_SECTION);
R->setRedefinable(true);
auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF(
Section, Type, Flags, K, EntrySize, Group, UniqueID, R, Associated);
auto *F = new MCDataFragment();
Ret->getFragmentList().insert(Ret->begin(), F);
F->setParent(Ret);
R->setFragment(F);
return Ret;
}
MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *Group,
@ -325,9 +344,9 @@ MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type,
std::tie(I, Inserted) =
ELFRelSecNames.insert(std::make_pair(Name.str(), true));
return new (ELFAllocator.Allocate())
MCSectionELF(I->getKey(), Type, Flags, SectionKind::getReadOnly(),
EntrySize, Group, true, nullptr, Associated);
return createELFSectionImpl(I->getKey(), Type, Flags,
SectionKind::getReadOnly(), EntrySize, Group,
true, Associated);
}
MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,
@ -339,21 +358,19 @@ MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,
MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const Twine &Group, unsigned UniqueID,
const char *BeginSymName) {
const Twine &Group, unsigned UniqueID) {
MCSymbolELF *GroupSym = nullptr;
if (!Group.isTriviallyEmpty() && !Group.str().empty())
GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group));
return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID,
BeginSymName, nullptr);
nullptr);
}
MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *GroupSym,
unsigned UniqueID,
const char *BeginSymName,
const MCSectionELF *Associated) {
StringRef Group = "";
if (GroupSym)
@ -375,22 +392,16 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
else
Kind = SectionKind::getReadOnly();
MCSymbol *Begin = nullptr;
if (BeginSymName)
Begin = createTempSymbol(BeginSymName, false);
MCSectionELF *Result = new (ELFAllocator.Allocate())
MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID,
Begin, Associated);
MCSectionELF *Result = createELFSectionImpl(
CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID, Associated);
Entry.second = Result;
return Result;
}
MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group) {
MCSectionELF *Result = new (ELFAllocator.Allocate())
MCSectionELF(".group", ELF::SHT_GROUP, 0, SectionKind::getReadOnly(), 4,
Group, ~0, nullptr, nullptr);
return Result;
return createELFSectionImpl(".group", ELF::SHT_GROUP, 0,
SectionKind::getReadOnly(), 4, Group, ~0,
nullptr);
}
MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,

View File

@ -148,16 +148,7 @@ void MCELFStreamer::ChangeSection(MCSection *Section,
Asm.registerSymbol(*Grp);
this->MCObjectStreamer::ChangeSection(Section, Subsection);
MCContext &Ctx = getContext();
auto *Begin = cast_or_null<MCSymbolELF>(Section->getBeginSymbol());
if (!Begin) {
Begin = Ctx.getOrCreateSectionSymbol(*SectionELF);
Section->setBeginSymbol(Begin);
}
if (Begin->isUndefined()) {
Asm.registerSymbol(*Begin);
Begin->setType(ELF::STT_SECTION);
}
Asm.registerSymbol(*Section->getBeginSymbol());
}
void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {

View File

@ -506,10 +506,9 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T) {
COFFDebugTypesSection = nullptr;
// Debug Info Sections.
DwarfAbbrevSection = Ctx->getELFSection(".debug_abbrev", ELF::SHT_PROGBITS, 0,
"section_abbrev");
DwarfInfoSection =
Ctx->getELFSection(".debug_info", ELF::SHT_PROGBITS, 0, "section_info");
DwarfAbbrevSection =
Ctx->getELFSection(".debug_abbrev", ELF::SHT_PROGBITS, 0);
DwarfInfoSection = Ctx->getELFSection(".debug_info", ELF::SHT_PROGBITS, 0);
DwarfLineSection = Ctx->getELFSection(".debug_line", ELF::SHT_PROGBITS, 0);
DwarfFrameSection = Ctx->getELFSection(".debug_frame", ELF::SHT_PROGBITS, 0);
DwarfPubNamesSection =
@ -527,21 +526,21 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T) {
DwarfARangesSection =
Ctx->getELFSection(".debug_aranges", ELF::SHT_PROGBITS, 0);
DwarfRangesSection =
Ctx->getELFSection(".debug_ranges", ELF::SHT_PROGBITS, 0, "debug_range");
DwarfMacinfoSection = Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS,
0, "debug_macinfo");
Ctx->getELFSection(".debug_ranges", ELF::SHT_PROGBITS, 0);
DwarfMacinfoSection =
Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS, 0);
// DWARF5 Experimental Debug Info
// Accelerator Tables
DwarfAccelNamesSection =
Ctx->getELFSection(".apple_names", ELF::SHT_PROGBITS, 0, "names_begin");
Ctx->getELFSection(".apple_names", ELF::SHT_PROGBITS, 0);
DwarfAccelObjCSection =
Ctx->getELFSection(".apple_objc", ELF::SHT_PROGBITS, 0, "objc_begin");
DwarfAccelNamespaceSection = Ctx->getELFSection(
".apple_namespaces", ELF::SHT_PROGBITS, 0, "namespac_begin");
Ctx->getELFSection(".apple_objc", ELF::SHT_PROGBITS, 0);
DwarfAccelNamespaceSection =
Ctx->getELFSection(".apple_namespaces", ELF::SHT_PROGBITS, 0);
DwarfAccelTypesSection =
Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0, "types_begin");
Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0);
// Fission Sections
DwarfInfoDWOSection =
@ -556,11 +555,10 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T) {
DwarfLineDWOSection =
Ctx->getELFSection(".debug_line.dwo", ELF::SHT_PROGBITS, 0);
DwarfLocDWOSection =
Ctx->getELFSection(".debug_loc.dwo", ELF::SHT_PROGBITS, 0, "skel_loc");
Ctx->getELFSection(".debug_loc.dwo", ELF::SHT_PROGBITS, 0);
DwarfStrOffDWOSection =
Ctx->getELFSection(".debug_str_offsets.dwo", ELF::SHT_PROGBITS, 0);
DwarfAddrSection =
Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0, "addr_sec");
DwarfAddrSection = Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0);
// DWP Sections
DwarfCUIndexSection =

View File

@ -4417,6 +4417,7 @@ bool AsmParser::parseDirectiveComm(bool IsLocal) {
return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
"alignment, can't be less than zero");
Sym->redefineIfPossible();
if (!Sym->isUndefined())
return Error(IDLoc, "invalid symbol redefinition");

View File

@ -42,6 +42,8 @@ enum {
void MCSymbolELF::setBinding(unsigned Binding) const {
setIsBindingSet();
if (getType() == ELF::STT_SECTION && Binding != ELF::STB_LOCAL)
setType(ELF::STT_NOTYPE);
unsigned Val;
switch (Binding) {
default:
@ -93,6 +95,8 @@ unsigned MCSymbolELF::getBinding() const {
void MCSymbolELF::setType(unsigned Type) const {
unsigned Val;
if (Type == ELF::STT_SECTION && getBinding() != ELF::STB_LOCAL)
return;
switch (Type) {
default:
llvm_unreachable("Unsupported Binding");

View File

@ -1138,9 +1138,8 @@ inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix,
const MCSymbolELF *Group = FnSection.getGroup();
if (Group)
Flags |= ELF::SHF_GROUP;
MCSectionELF *EHSection =
getContext().getELFSection(EHSecName, Type, Flags, 0, Group,
FnSection.getUniqueID(), nullptr, &FnSection);
MCSectionELF *EHSection = getContext().getELFSection(
EHSecName, Type, Flags, 0, Group, FnSection.getUniqueID(), &FnSection);
assert(EHSection && "Failed to get the required EH section");

View File

@ -1,7 +1,7 @@
; RUN: %llc_dwarf -O2 %s -o - | FileCheck %s
; Check struct X for dead variable xyz from inlined function foo.
; CHECK: section_info
; CHECK: .section .debug_info,"",@progbits
; CHECK: DW_TAG_structure_type
; CHECK-NEXT: DW_AT_name

View File

@ -25,7 +25,7 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone
!7 = distinct !DILexicalBlock(line: 3, column: 12, file: !14, scope: !0)
!8 = !DICompositeType(tag: DW_TAG_array_type, align: 32, file: !14, scope: !2, baseType: !5, elements: !9)
!9 = !{!10}
;CHECK: section_info:
;CHECK: .section .debug_info,"",@progbits
;CHECK: DW_TAG_subrange_type
;CHECK-NEXT: DW_AT_type
;CHECK-NOT: DW_AT_lower_bound

View File

@ -1,7 +1,7 @@
; RUN: llc -mtriple mips-linux-gnu -O2 %s -o - | FileCheck %s
; Check struct X for dead variable xyz from inlined function foo.
; CHECK: section_info
; CHECK: .section .debug_info,"",@progbits
; CHECK: DW_TAG_structure_type
; CHECK-NEXT: info_string

View File

@ -13,8 +13,7 @@
; DW_OP_GNU_push_tls_address
; CHECK-NEXT: .byte 224
; check that the expected TLS address description is the first thing in the debug_addr section
; CHECK: debug_addr
; CHECK-NEXT: .Laddr_sec:
; CHECK: .section .debug_addr,"",@progbits
; CHECK-NEXT: .quad tls@DTPREL+32768
source_filename = "test/DebugInfo/PowerPC/tls-fission.ll"

View File

@ -46,7 +46,7 @@
; CHECK: DW_TAG_variable
; Make sure this is relocatable.
; and test that we don't create the labels to emit a correct COFF relocation
; ELF-ASM: .quad .Lsection_info+[[TYPE]] # DW_AT_type
; ELF-ASM: .quad .debug_info+[[TYPE]] # DW_AT_type
; COFF-ASM: .secrel32 .Lsection_info+[[TYPE]] # DW_AT_type
; DARWIN-ASM2: .quad [[TYPE]] ## DW_AT_type
; DARWIN-ASM4: .long [[TYPE]] ## DW_AT_type

View File

@ -78,7 +78,6 @@
; check that the expected TLS address description is the first thing in the debug_addr section
; FISSION: .section .debug_addr
; FISSION: addr_sec:
; FISSION-NEXT: .quad tls@DTPOFF
; FISSION-NEXT: .quad glbl
; FISSION-NOT: .quad glbl

View File

@ -63,9 +63,9 @@ end_across_sec:
add w0, w1, #(sec_y - sec_x)
cmp w0, #(sec_y - sec_x)
// CHECK: error: symbol 'sec_x' can not be undefined in a subtraction expression
// CHECK: error: Cannot represent a difference across sections
// CHECK-NEXT: add w0, w1, #(sec_y - sec_x)
// CHECK-NEXT: ^
// CHECK: error: symbol 'sec_x' can not be undefined in a subtraction expression
// CHECK: error: Cannot represent a difference across sections
// CHECK-NEXT: cmp w0, #(sec_y - sec_x)
// CHECK-NEXT: ^

View File

@ -34,7 +34,6 @@ foo:
// ASM: .section .debug_info
// ASM: .section .debug_abbrev
// ASM-NEXT: .Lsection_abbrev:
// ASM-NEXT: [[ABBREV_LABEL:.Ltmp[0-9]+]]
// Second instance of the section has the CU

View File

@ -87,11 +87,11 @@ local_label:
# MICRO: b .text # encoding: [0x94,0x00,A,A]
# MICRO: # fixup A - offset: 0, value: .text, kind: fixup_MICROMIPS_PC16_S1
# ELF-O32: 10 00 ff ff b 0
# ELF-O32-NEXT: 00000018: R_MIPS_PC16 .text
# ELF-O32: 10 00 ff f9 b -24 <local_label>
# ELF-O32-NEXT: 00 00 00 00 nop
# ELF-NXX: 10 00 00 00 b 4
# ELF-NXX-NEXT: R_MIPS_PC16/R_MIPS_NONE/R_MIPS_NONE .text
# ELF-NXX: 10 00 ff f9 b -24 <local_label>
# ELF-NXX-NEXT: 00 00 00 00 nop
j 1f
nop

View File

@ -151,37 +151,35 @@ local_label:
jal .text
nop
# FIXME: The .text section MCSymbol isn't created when printing assembly. However,
# it is created when generating an ELF object file.
# Expanding "jal .text":
# O32-FIXME: lw $25, %call16(.text)($gp) # encoding: [0x8f,0x99,A,A]
# O32-FIXME: # fixup A - offset: 0, value: %got(.text), kind: fixup_Mips_GOT_CALL
# O32: lw $25, %got(.text)($gp) # encoding: [0x8f,0x99,A,A]
# O32-NEXT: # fixup A - offset: 0, value: %got(.text), kind: fixup_Mips_GOT
# ELF-O32: 8f 99 00 00 lw $25, 0($gp)
# ELF-O32-NEXT: R_MIPS_CALL16 .text
# ELF-O32-NEXT: R_MIPS_GOT16 .text
# N32-FIXME: lw $25, %call16(.text)($gp) # encoding: [0x8f,0x99,A,A]
# N32-FIXME: # fixup A - offset: 0, value: %call16(.text), kind: fixup_Mips_GOT_DISP
# N32: lw $25, %got_disp(.text)($gp) # encoding: [0x8f,0x99,A,A]
# N32-NEXT: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_Mips_GOT_DISP
# ELF-N32: 8f 99 00 00 lw $25, 0($gp)
# ELF-N32-NEXT: R_MIPS_CALL16/R_MIPS_NONE/R_MIPS_NONE .text
# ELF-N32-NEXT: R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE .text
# N64-FIXME: ld $25, %call16(.text)($gp) # encoding: [0xdf,0x99,A,A]
# N64-FIXME: # fixup A - offset: 0, value: %call16(.text), kind: fixup_Mips_GOT_DISP
# N64: ld $25, %got_disp(.text)($gp) # encoding: [0xdf,0x99,A,A]
# N64-NEXT: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_Mips_GOT_DISP
# ELF-N64: df 99 00 00 ld $25, 0($gp)
# ELF-N64-NEXT: R_MIPS_CALL16/R_MIPS_NONE/R_MIPS_NONE .text
# ELF-N64-NEXT: R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE .text
# O32-MM-FIXME: lw $25, %got(.text)($gp) # encoding: [0xff,0x3c,A,A]
# O32-MM-FIXME: # fixup A - offset: 0, value: %got(.text), kind: fixup_MICROMIPS_GOT16
# O32-MM-FIXME: addiu $25, $25, %lo(.text) # encoding: [0x33,0x39,A,A]
# O32-MM-FIXME: # fixup A - offset: 0, value: %lo(.text), kind: fixup_MICROMIPS_LO16
# O32-MM: lw $25, %got(.text)($gp) # encoding: [0xff,0x3c,A,A]
# O32-MM-NEXT: # fixup A - offset: 0, value: %got(.text), kind: fixup_MICROMIPS_GOT16
# O32-MM-NEXT: addiu $25, $25, %lo(.text) # encoding: [0x33,0x39,A,A]
# O32-MM-NEXT: # fixup A - offset: 0, value: %lo(.text), kind: fixup_MICROMIPS_LO16
# N32-MM-FIXME: lw $25, %got_disp(.text)($gp) # encoding: [0xff,0x3c,A,A]
# N32-MM-FIXME: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_MICROMIPS_GOT_DISP
# N32-MM: lw $25, %got_disp(.text)($gp) # encoding: [0xff,0x3c,A,A]
# N32-MM-NEXT: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_MICROMIPS_GOT_DISP
# N64-MM-FIXME: ld $25, %got_disp(.text)($gp) # encoding: [0xdf,0x99,A,A]
# N64-MM-FIXME: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_MICROMIPS_GOT_DISP
# N64-MM: ld $25, %got_disp(.text)($gp) # encoding: [0xdf,0x99,A,A]
# N64-MM-NEXT: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_MICROMIPS_GOT_DISP
# MIPS: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
# MM: jalr $ra, $25 # encoding: [0x03,0xf9,0x0f,0x3c]
@ -199,7 +197,7 @@ local_label:
# ELF-O32: 8f 99 00 00 lw $25, 0($gp)
# ELF-O32-NEXT: R_MIPS_GOT16 .text
# ELF-O32-NEXT: 27 39 00 54 addiu $25, $25, 84
# ELF-O32-NEXT: 27 39 00 58 addiu $25, $25, 88
# ELF-O32-NEXT: R_MIPS_LO16 .text
# N32: lw $25, %got_disp($tmp0)($gp) # encoding: [0x8f,0x99,A,A]
@ -241,7 +239,7 @@ local_label:
# ELF-O32: 8f 99 00 00 lw $25, 0($gp)
# ELF-O32-NEXT: R_MIPS_GOT16 .text
# ELF-O32-NEXT: 27 39 00 60 addiu $25, $25, 96
# ELF-O32-NEXT: 27 39 00 64 addiu $25, $25, 100
# ELF-O32-NEXT: R_MIPS_LO16 .text
# N32-FIXME: lw $25, %got_disp(forward_local)($gp) # encoding: [0x8f,0x99,A,A]