Revert D114783 [ELF] Split scanRelocations into scanRelocations/postScanRelocations

May cause a failure for non-preemptible `bcmp` in a glibc -static link.
This commit is contained in:
Fangrui Song 2021-12-14 14:33:50 -08:00
parent 8bd106a891
commit ea15b862d7
28 changed files with 265 additions and 303 deletions

View File

@ -690,11 +690,11 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
};
const uint8_t nopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop
// needsCopy indicates a non-ifunc canonical PLT entry whose address may
// needsPltAddr indicates a non-ifunc canonical PLT entry whose address may
// escape to shared objects. isInIplt indicates a non-preemptible ifunc. Its
// address may escape if referenced by a direct relocation. The condition is
// conservative.
bool hasBti = btiHeader && (sym.needsCopy || sym.isInIplt);
bool hasBti = btiHeader && (sym.needsPltAddr || sym.isInIplt);
if (hasBti) {
memcpy(buf, btiData, sizeof(btiData));
buf += sizeof(btiData);

View File

@ -58,7 +58,7 @@ static std::vector<Defined *> getSymbols() {
for (Symbol *b : file->getSymbols())
if (auto *dr = dyn_cast<Defined>(b))
if (!dr->isSection() && dr->section && dr->section->isLive() &&
(dr->file == file || dr->needsCopy || dr->section->bss))
(dr->file == file || dr->needsPltAddr || dr->section->bss))
v.push_back(dr);
return v;
}

View File

@ -307,8 +307,6 @@ static void replaceWithDefined(Symbol &sym, SectionBase *sec, uint64_t value,
sym.verdefIndex = old.verdefIndex;
sym.exportDynamic = true;
sym.isUsedInRegularObj = true;
// A copy relocated alias may need a GOT entry.
sym.needsGot = old.needsGot;
}
// Reserve space in .bss or .bss.rel.ro for copy relocation.
@ -353,7 +351,7 @@ static void replaceWithDefined(Symbol &sym, SectionBase *sec, uint64_t value,
// to the variable in .bss. This kind of issue is sometimes very hard to
// debug. What's a solution? Instead of exporting a variable V from a DSO,
// define an accessor getV().
template <class ELFT> static void addCopyRelSymbolImpl(SharedSymbol &ss) {
template <class ELFT> static void addCopyRelSymbol(SharedSymbol &ss) {
// Copy relocation against zero-sized symbol doesn't make sense.
uint64_t symSize = ss.getSize();
if (symSize == 0 || ss.alignment == 0)
@ -384,26 +382,6 @@ template <class ELFT> static void addCopyRelSymbolImpl(SharedSymbol &ss) {
mainPart->relaDyn->addSymbolReloc(target->copyRel, sec, 0, ss);
}
static void addCopyRelSymbol(SharedSymbol &ss) {
const SharedFile &file = ss.getFile();
switch (file.ekind) {
case ELF32LEKind:
addCopyRelSymbolImpl<ELF32LE>(ss);
break;
case ELF32BEKind:
addCopyRelSymbolImpl<ELF32BE>(ss);
break;
case ELF64LEKind:
addCopyRelSymbolImpl<ELF64LE>(ss);
break;
case ELF64BEKind:
addCopyRelSymbolImpl<ELF64BE>(ss);
break;
default:
llvm_unreachable("");
}
}
// MIPS has an odd notion of "paired" relocations to calculate addends.
// For example, if a relocation is of R_MIPS_HI16, there must be a
// R_MIPS_LO16 relocation after that, and an addend is calculated using
@ -1067,7 +1045,7 @@ static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type,
" against symbol '" + toString(*ss) +
"'; recompile with -fPIC or remove '-z nocopyreloc'" +
getLocation(sec, sym, offset));
sym.needsCopy = true;
addCopyRelSymbol<ELFT>(*ss);
}
sec.relocations.push_back({expr, type, offset, addend, &sym});
return;
@ -1105,8 +1083,20 @@ static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type,
errorOrWarn("symbol '" + toString(sym) +
"' cannot be preempted; recompile with -fPIE" +
getLocation(sec, sym, offset));
sym.needsCopy = true;
sym.needsPlt = true;
if (!sym.isInPlt())
addPltEntry(in.plt, in.gotPlt, in.relaPlt, target->pltRel, sym);
if (!sym.isDefined()) {
replaceWithDefined(
sym, in.plt,
target->pltHeaderSize + target->pltEntrySize * sym.pltIndex, 0);
if (config->emachine == EM_PPC) {
// PPC32 canonical PLT entries are at the beginning of .glink
cast<Defined>(sym).value = in.plt->headerSize;
in.plt->headerSize += 16;
cast<PPC32GlinkSection>(in.plt)->canonical_plts.push_back(&sym);
}
}
sym.needsPltAddr = true;
sec.relocations.push_back({expr, type, offset, addend, &sym});
return;
}
@ -1435,6 +1425,14 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
return;
}
// Non-preemptible ifuncs require special handling. First, handle the usual
// case where the symbol isn't one of these.
if (!sym.isGnuIFunc() || sym.isPreemptible) {
// If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
if (needsPlt(expr) && !sym.isInPlt())
addPltEntry(in.plt, in.gotPlt, in.relaPlt, target->pltRel, sym);
// Create a GOT slot if a relocation needs GOT.
if (needsGot(expr)) {
if (config->emachine == EM_MIPS) {
// MIPS ABI has special rules to process GOT entries and doesn't
@ -1445,13 +1443,98 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
// for detailed description:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
in.mipsGot->addEntry(*sec.file, sym, addend, expr);
} else {
sym.needsGot = true;
} else if (!sym.isInGot()) {
addGotEntry(sym);
}
}
} else if (needsPlt(expr)) {
sym.needsPlt = true;
} else {
sym.hasDirectReloc = true;
// Handle a reference to a non-preemptible ifunc. These are special in a
// few ways:
//
// - Unlike most non-preemptible symbols, non-preemptible ifuncs do not have
// a fixed value. But assuming that all references to the ifunc are
// GOT-generating or PLT-generating, the handling of an ifunc is
// relatively straightforward. We create a PLT entry in Iplt, which is
// usually at the end of .plt, which makes an indirect call using a
// matching GOT entry in igotPlt, which is usually at the end of .got.plt.
// The GOT entry is relocated using an IRELATIVE relocation in relaIplt,
// which is usually at the end of .rela.plt. Unlike most relocations in
// .rela.plt, which may be evaluated lazily without -z now, dynamic
// loaders evaluate IRELATIVE relocs eagerly, which means that for
// IRELATIVE relocs only, GOT-generating relocations can point directly to
// .got.plt without requiring a separate GOT entry.
//
// - Despite the fact that an ifunc does not have a fixed value, compilers
// that are not passed -fPIC will assume that they do, and will emit
// direct (non-GOT-generating, non-PLT-generating) relocations to the
// symbol. This means that if a direct relocation to the symbol is
// seen, the linker must set a value for the symbol, and this value must
// be consistent no matter what type of reference is made to the symbol.
// This can be done by creating a PLT entry for the symbol in the way
// described above and making it canonical, that is, making all references
// point to the PLT entry instead of the resolver. In lld we also store
// the address of the PLT entry in the dynamic symbol table, which means
// that the symbol will also have the same value in other modules.
// Because the value loaded from the GOT needs to be consistent with
// the value computed using a direct relocation, a non-preemptible ifunc
// may end up with two GOT entries, one in .got.plt that points to the
// address returned by the resolver and is used only by the PLT entry,
// and another in .got that points to the PLT entry and is used by
// GOT-generating relocations.
//
// - The fact that these symbols do not have a fixed value makes them an
// exception to the general rule that a statically linked executable does
// not require any form of dynamic relocation. To handle these relocations
// correctly, the IRELATIVE relocations are stored in an array which a
// statically linked executable's startup code must enumerate using the
// linker-defined symbols __rela?_iplt_{start,end}.
if (!sym.isInPlt()) {
// Create PLT and GOTPLT slots for the symbol.
sym.isInIplt = true;
// Create a copy of the symbol to use as the target of the IRELATIVE
// relocation in the igotPlt. This is in case we make the PLT canonical
// later, which would overwrite the original symbol.
//
// FIXME: Creating a copy of the symbol here is a bit of a hack. All
// that's really needed to create the IRELATIVE is the section and value,
// so ideally we should just need to copy those.
auto *directSym = make<Defined>(cast<Defined>(sym));
addPltEntry(in.iplt, in.igotPlt, in.relaIplt, target->iRelativeRel,
*directSym);
sym.pltIndex = directSym->pltIndex;
}
if (needsGot(expr)) {
// Redirect GOT accesses to point to the Igot.
//
// This field is also used to keep track of whether we ever needed a GOT
// entry. If we did and we make the PLT canonical later, we'll need to
// create a GOT entry pointing to the PLT entry for Sym.
sym.gotInIgot = true;
} else if (!needsPlt(expr)) {
// Make the ifunc's PLT entry canonical by changing the value of its
// symbol to redirect all references to point to it.
auto &d = cast<Defined>(sym);
d.section = in.iplt;
d.value = sym.pltIndex * target->ipltEntrySize;
d.size = 0;
// It's important to set the symbol type here so that dynamic loaders
// don't try to call the PLT as if it were an ifunc resolver.
d.type = STT_FUNC;
if (sym.gotInIgot) {
// We previously encountered a GOT generating reference that we
// redirected to the Igot. Now that the PLT entry is canonical we must
// clear the redirection to the Igot and add a GOT entry. As we've
// changed the symbol type to STT_FUNC future GOT generating references
// will naturally use this GOT entry.
//
// We don't need to worry about creating a MIPS GOT here because ifuncs
// aren't a thing on MIPS.
sym.gotInIgot = false;
addGotEntry(sym);
}
}
}
processRelocAux<ELFT>(sec, expr, type, offset, sym, addend);
@ -1532,121 +1615,6 @@ template <class ELFT> void elf::scanRelocations(InputSectionBase &s) {
scanRelocs<ELFT>(s, rels.relas);
}
static bool handleNonPreemptibleIfunc(Symbol &sym) {
// Handle a reference to a non-preemptible ifunc. These are special in a
// few ways:
//
// - Unlike most non-preemptible symbols, non-preemptible ifuncs do not have
// a fixed value. But assuming that all references to the ifunc are
// GOT-generating or PLT-generating, the handling of an ifunc is
// relatively straightforward. We create a PLT entry in Iplt, which is
// usually at the end of .plt, which makes an indirect call using a
// matching GOT entry in igotPlt, which is usually at the end of .got.plt.
// The GOT entry is relocated using an IRELATIVE relocation in relaIplt,
// which is usually at the end of .rela.plt. Unlike most relocations in
// .rela.plt, which may be evaluated lazily without -z now, dynamic
// loaders evaluate IRELATIVE relocs eagerly, which means that for
// IRELATIVE relocs only, GOT-generating relocations can point directly to
// .got.plt without requiring a separate GOT entry.
//
// - Despite the fact that an ifunc does not have a fixed value, compilers
// that are not passed -fPIC will assume that they do, and will emit
// direct (non-GOT-generating, non-PLT-generating) relocations to the
// symbol. This means that if a direct relocation to the symbol is
// seen, the linker must set a value for the symbol, and this value must
// be consistent no matter what type of reference is made to the symbol.
// This can be done by creating a PLT entry for the symbol in the way
// described above and making it canonical, that is, making all references
// point to the PLT entry instead of the resolver. In lld we also store
// the address of the PLT entry in the dynamic symbol table, which means
// that the symbol will also have the same value in other modules.
// Because the value loaded from the GOT needs to be consistent with
// the value computed using a direct relocation, a non-preemptible ifunc
// may end up with two GOT entries, one in .got.plt that points to the
// address returned by the resolver and is used only by the PLT entry,
// and another in .got that points to the PLT entry and is used by
// GOT-generating relocations.
//
// - The fact that these symbols do not have a fixed value makes them an
// exception to the general rule that a statically linked executable does
// not require any form of dynamic relocation. To handle these relocations
// correctly, the IRELATIVE relocations are stored in an array which a
// statically linked executable's startup code must enumerate using the
// linker-defined symbols __rela?_iplt_{start,end}.
if (!sym.isGnuIFunc() || sym.isPreemptible || config->zIfuncNoplt)
return false;
sym.isInIplt = true;
// Create an Iplt and the associated IRELATIVE relocation pointing to the
// original section/value pairs. For non-GOT non-PLT relocation case below, we
// may alter section/value, so create a copy of the symbol to make
// section/value fixed.
auto *directSym = make<Defined>(cast<Defined>(sym));
addPltEntry(in.iplt, in.igotPlt, in.relaIplt, target->iRelativeRel,
*directSym);
sym.pltIndex = directSym->pltIndex;
if (sym.hasDirectReloc) {
// Change the value to the IPLT and redirect all references to it.
auto &d = cast<Defined>(sym);
d.section = in.iplt;
d.value = sym.pltIndex * target->ipltEntrySize;
d.size = 0;
// It's important to set the symbol type here so that dynamic loaders
// don't try to call the PLT as if it were an ifunc resolver.
d.type = STT_FUNC;
if (sym.needsGot)
addGotEntry(sym);
} else if (sym.needsGot) {
// Redirect GOT accesses to point to the Igot.
sym.gotInIgot = true;
}
return true;
}
void elf::postScanRelocations() {
auto fn = [](Symbol &sym) {
if (handleNonPreemptibleIfunc(sym))
return;
if (sym.needsGot)
addGotEntry(sym);
if (sym.needsPlt)
addPltEntry(in.plt, in.gotPlt, in.relaPlt, target->pltRel, sym);
if (sym.needsCopy) {
if (sym.isObject()) {
addCopyRelSymbol(cast<SharedSymbol>(sym));
// needsCopy is cleared for sym and its aliases so that in later
// iterations aliases won't cause redundant copies.
assert(!sym.needsCopy);
} else {
assert(sym.isFunc() && sym.needsPlt);
if (!sym.isDefined()) {
replaceWithDefined(
sym, in.plt,
target->pltHeaderSize + target->pltEntrySize * sym.pltIndex, 0);
sym.needsCopy = true;
if (config->emachine == EM_PPC) {
// PPC32 canonical PLT entries are at the beginning of .glink
cast<Defined>(sym).value = in.plt->headerSize;
in.plt->headerSize += 16;
cast<PPC32GlinkSection>(in.plt)->canonical_plts.push_back(&sym);
}
}
}
}
};
for (Symbol *sym : symtab->symbols())
fn(*sym);
// Local symbols may need the aforementioned non-preemptible ifunc and GOT
// handling. They don't need regular PLT.
for (InputFile *file : objectFiles)
for (Symbol *sym : cast<ELFFileBase>(file)->getLocalSymbols())
fn(*sym);
}
static bool mergeCmp(const InputSection *a, const InputSection *b) {
// std::merge requires a strict weak ordering.
if (a->outSecOff < b->outSecOff)

View File

@ -126,7 +126,6 @@ struct JumpInstrMod {
// Call reportUndefinedSymbols() after calling scanRelocations() to emit
// the diagnostics.
template <class ELFT> void scanRelocations(InputSectionBase &);
void postScanRelocations();
template <class ELFT> void reportUndefinedSymbols();

View File

@ -120,7 +120,7 @@ static uint64_t getSymVA(const Symbol &sym, int64_t addend) {
// field etc) do the same trick as compiler uses to mark microMIPS
// for CPU - set the less-significant bit.
if (config->emachine == EM_MIPS && isMicroMips() &&
((sym.stOther & STO_MIPS_MICROMIPS) || sym.needsCopy))
((sym.stOther & STO_MIPS_MICROMIPS) || sym.needsPltAddr))
va |= 1;
if (d.isTls() && !config->relocatable) {

View File

@ -245,12 +245,16 @@ protected:
type(type), stOther(stOther), symbolKind(k), visibility(stOther & 3),
isUsedInRegularObj(!file || file->kind() == InputFile::ObjKind),
exportDynamic(isExportDynamic(k, visibility)), inDynamicList(false),
canInline(false), referenced(false), traced(false), isInIplt(false),
gotInIgot(false), isPreemptible(false), used(!config->gcSections),
needsTocRestore(false), scriptDefined(false), needsCopy(false),
needsGot(false), needsPlt(false), hasDirectReloc(false) {}
canInline(false), referenced(false), traced(false), needsPltAddr(false),
isInIplt(false), gotInIgot(false), isPreemptible(false),
used(!config->gcSections), needsTocRestore(false),
scriptDefined(false) {}
public:
// True the symbol should point to its PLT entry.
// For SharedSymbol only.
uint8_t needsPltAddr : 1;
// True if this symbol is in the Iplt sub-section of the Plt and the Igot
// sub-section of the .got.plt or .got.
uint8_t isInIplt : 1;
@ -275,16 +279,6 @@ public:
// True if this symbol is defined by a linker script.
uint8_t scriptDefined : 1;
// True if this symbol needs a canonical PLT entry, or (during
// postScanRelocations) a copy relocation.
uint8_t needsCopy : 1;
// Temporary flags used to communicate which symbol entries need PLT and GOT
// entries during postScanRelocations();
uint8_t needsGot : 1;
uint8_t needsPlt : 1;
uint8_t hasDirectReloc : 1;
// The partition whose dynamic symbol table contains this symbol's definition.
uint8_t partition = 1;

View File

@ -2175,8 +2175,7 @@ static BssSection *getCommonSec(Symbol *sym) {
static uint32_t getSymSectionIndex(Symbol *sym) {
if (getCommonSec(sym))
return SHN_COMMON;
assert(!(sym->needsCopy && sym->isObject()));
if (!isa<Defined>(sym) || sym->needsCopy)
if (!isa<Defined>(sym) || sym->needsPltAddr)
return SHN_UNDEF;
if (const OutputSection *os = sym->getOutputSection())
return os->sectionIndex >= SHN_LORESERVE ? (uint32_t)SHN_XINDEX
@ -2251,7 +2250,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
for (SymbolTableEntry &ent : symbols) {
Symbol *sym = ent.sym;
if (sym->isInPlt() && sym->needsCopy)
if (sym->isInPlt() && sym->needsPltAddr)
eSym->st_other |= STO_MIPS_PLT;
if (isMicroMips()) {
// We already set the less-significant bit for symbols
@ -2262,7 +2261,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
// like `objdump` will be able to deal with a correct
// symbol position.
if (sym->isDefined() &&
((sym->stOther & STO_MIPS_MICROMIPS) || sym->needsCopy)) {
((sym->stOther & STO_MIPS_MICROMIPS) || sym->needsPltAddr)) {
if (!strTabSec.isDynamic())
eSym->st_value &= ~1;
eSym->st_other |= STO_MIPS_MICROMIPS;

View File

@ -1947,7 +1947,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (!config->relocatable) {
forEachRelSec(scanRelocations<ELFT>);
reportUndefinedSymbols<ELFT>();
postScanRelocations();
}
}

View File

@ -35,13 +35,16 @@
# CHECK-EMPTY:
## The address of ifunc1@plt does not escape so it does not need `bti c`,
## but having bti is not wrong.
# CHECK-NEXT: 00000000000103e0 <ifunc2>:
# CHECK-NEXT: 00000000000103e0 <.iplt>:
# CHECK-NEXT: 103e0: bti c
# CHECK-NEXT: adrp x16, 0x30000
# CHECK-NEXT: ldr x17, [x16, #1360]
# CHECK-NEXT: add x16, x16, #1360
# CHECK-NEXT: br x17
# CHECK-NEXT: nop
# CHECK-EMPTY:
## The address of ifunc2 (STT_FUNC) escapes, so it must have `bti c`.
# CHECK-NEXT: 00000000000103f8 <ifunc2>:
# CHECK-NEXT: 103f8: bti c
# CHECK-NEXT: adrp x16, 0x30000
# CHECK-NEXT: ldr x17, [x16, #1368]
@ -49,11 +52,10 @@
# CHECK-NEXT: br x17
# CHECK-NEXT: nop
## The address of ifunc2 (STT_FUNC) escapes, so it must have `bti c`.
# SHARED: <ifunc2>:
# SHARED: <.iplt>:
# SHARED-NEXT: bti c
# SHARED: nop
# SHARED: <ifunc2>:
# SHARED-NEXT: bti c
.section ".note.gnu.property", "a"

View File

@ -36,7 +36,7 @@ low_target2:
// adrp calculation is (PC + signed immediate) & (!0xfff)
// CHECK: <__AArch64ADRPThunk_high_target>:
// CHECK-NEXT: 14: adrp x16, 0x10000000
// CHECK-NEXT: add x16, x16, #0x50
// CHECK-NEXT: add x16, x16, #0x40
// CHECK-NEXT: br x16
// CHECK: <__AArch64ADRPThunk_high_target2>:
// CHECK-NEXT: 20: adrp x16, 0x10000000
@ -57,7 +57,7 @@ high_target:
bl low_target
ret
// CHECK: <high_target>:
// CHECK-NEXT: 10000000: bl 0x10000040 <low_target@plt>
// CHECK-NEXT: 10000000: bl 0x10000050 <low_target@plt>
// CHECK-NEXT: ret
.hidden high_target2
@ -90,13 +90,13 @@ high_target2:
// CHECK-NEXT: nop
// CHECK-NEXT: nop
// CHECK-EMPTY:
// CHECK-NEXT: <low_target@plt>:
// CHECK-NEXT: <high_target@plt>:
// CHECK-NEXT: 10000040: adrp x16, 0x10000000
// CHECK-NEXT: ldr x17, [x16, #0x200]
// CHECK-NEXT: add x16, x16, #0x200
// CHECK-NEXT: br x17
// CHECK-EMPTY:
// CHECK-NEXT: <high_target@plt>:
// CHECK-NEXT: <low_target@plt>:
// CHECK-NEXT: 10000050: adrp x16, 0x10000000
// CHECK-NEXT: ldr x17, [x16, #0x208]
// CHECK-NEXT: add x16, x16, #0x208

View File

@ -27,10 +27,10 @@ _start:
// CHECK-NEXT: 201e4: 00 00 00 ea b 0x201ec <__ARMv7ABSLongThunk_undefined_weak_we_expect_a_plt_entry_for>
// CHECK-NEXT: 201e8: 02 00 00 eb bl 0x201f8 <__ARMv7ABSLongThunk_bar2>
// CHECK: <__ARMv7ABSLongThunk_undefined_weak_we_expect_a_plt_entry_for>:
// CHECK-NEXT: 201ec: 40 c2 00 e3 movw r12, #576
// CHECK-NEXT: 201ec: 30 c2 00 e3 movw r12, #560
// CHECK-NEXT: 201f0: 02 c2 40 e3 movt r12, #514
// CHECK-NEXT: 201f4: 1c ff 2f e1 bx r12
// CHECK: <__ARMv7ABSLongThunk_bar2>:
// CHECK-NEXT: 201f8: 30 c2 00 e3 movw r12, #560
// CHECK-NEXT: 201f8: 40 c2 00 e3 movw r12, #576
// CHECK-NEXT: 201fc: 02 c2 40 e3 movt r12, #514
// CHECK-NEXT: 20200: 1c ff 2f e1 bx r12

View File

@ -118,8 +118,8 @@ _start:
// DISASM: <bar>:
// DISASM-NEXT: 20108: bx lr
// DISASM: <_start>:
// DISASM-NEXT: 2010c: bl 0x20140
// DISASM-NEXT: 20110: bl 0x20130
// DISASM-NEXT: 2010c: bl 0x20130
// DISASM-NEXT: 20110: bl 0x20140
// 1 * 65536 + 244 = 0x100f4 __rel_iplt_start
// DISASM-NEXT: 20114: movw r0, #244
// DISASM-NEXT: 20118: movt r0, #1

View File

@ -139,15 +139,15 @@ arm_caller:
// CHECK-ARM-PLT: Disassembly of section .arm_caller:
// CHECK-ARM-PLT-EMPTY:
// CHECK-ARM-PLT-NEXT: <arm_caller>:
// CHECK-ARM-PLT-NEXT: 1300: bl 0x1630
// CHECK-ARM-PLT-NEXT: 1304: bl 0x1630
// CHECK-ARM-PLT-NEXT: 1308: b 0x1630
// CHECK-ARM-PLT-NEXT: 130c: b 0x1630
// CHECK-ARM-PLT-NEXT: 1300: bl 0x1650
// CHECK-ARM-PLT-NEXT: 1304: bl 0x1650
// CHECK-ARM-PLT-NEXT: 1308: b 0x1650
// CHECK-ARM-PLT-NEXT: 130c: b 0x1650
// CHECK-ARM-PLT-NEXT: 1310: b 0x1660
// CHECK-ARM-PLT-NEXT: 1314: b 0x1670
// CHECK-ARM-PLT-NEXT: 1318: b 0x1640
// CHECK-ARM-PLT-NEXT: 131c: beq 0x1680
// CHECK-ARM-PLT-NEXT: 1320: bne 0x1690
// CHECK-ARM-PLT-NEXT: 1318: b 0x1680
// CHECK-ARM-PLT-NEXT: 131c: beq 0x1690
// CHECK-ARM-PLT-NEXT: 1320: bne 0x16a0
// CHECK-ARM-PLT-NEXT: 1324: bx lr
.section .thumb_caller, "ax", %progbits
@ -229,8 +229,8 @@ thumb_caller:
// CHECK-ARM-PLT: Disassembly of section .thumb_caller:
// CHECK-ARM-PLT-EMPTY:
// CHECK-ARM-PLT-NEXT: <thumb_caller>:
// CHECK-ARM-PLT-NEXT: 1400: blx 0x1640
// CHECK-ARM-PLT-NEXT: 1404: blx 0x1640
// CHECK-ARM-PLT-NEXT: 1400: blx 0x1680
// CHECK-ARM-PLT-NEXT: 1404: blx 0x1680
// CHECK-ARM-PLT-NEXT: 1408: b.w 0x1420 <__ThumbV7PILongThunk_arm_callee1>
// CHECK-ARM-PLT-NEXT: 140c: b.w 0x142c <__ThumbV7PILongThunk_arm_callee2>
// CHECK-ARM-PLT-NEXT: 1410: b.w 0x1438 <__ThumbV7PILongThunk_arm_callee3>
@ -365,11 +365,11 @@ _start:
// CHECK-ARM-PLT-NEXT: 000016ac <$d>:
// CHECK-ARM-PLT-NEXT: 16ac: d4 d4 d4 d4 .word 0xd4d4d4d4
// CHECK-DSO-REL: 0x18C0 R_ARM_JUMP_SLOT thumb_callee1
// CHECK-DSO-REL-NEXT: 0x18C4 R_ARM_JUMP_SLOT arm_callee1
// CHECK-DSO-REL-NEXT: 0x18C8 R_ARM_JUMP_SLOT arm_caller
// CHECK-DSO-REL: 0x18C0 R_ARM_JUMP_SLOT arm_caller
// CHECK-DSO-REL-NEXT: 0x18C4 R_ARM_JUMP_SLOT thumb_caller
// CHECK-DSO-REL-NEXT: 0x18C8 R_ARM_JUMP_SLOT thumb_callee1
// CHECK-DSO-REL-NEXT: 0x18CC R_ARM_JUMP_SLOT thumb_callee2
// CHECK-DSO-REL-NEXT: 0x18D0 R_ARM_JUMP_SLOT thumb_callee3
// CHECK-DSO-REL-NEXT: 0x18D4 R_ARM_JUMP_SLOT arm_callee2
// CHECK-DSO-REL-NEXT: 0x18D8 R_ARM_JUMP_SLOT arm_callee3
// CHECK-DSO-REL-NEXT: 0x18DC R_ARM_JUMP_SLOT thumb_caller
// CHECK-DSO-REL-NEXT: 0x18D4 R_ARM_JUMP_SLOT arm_callee1
// CHECK-DSO-REL-NEXT: 0x18D8 R_ARM_JUMP_SLOT arm_callee2
// CHECK-DSO-REL-NEXT: 0x18DC R_ARM_JUMP_SLOT arm_callee3

View File

@ -41,9 +41,9 @@
# REL_DEF-NEXT: }
# REL_DEF-NEXT: .rela.plt {
# REL_DEF-NEXT: R_X86_64_JUMP_SLOT default
# REL_DEF-NEXT: R_X86_64_JUMP_SLOT notype_default
# REL_DEF-NEXT: R_X86_64_JUMP_SLOT weak_default
# REL_DEF-NEXT: R_X86_64_JUMP_SLOT ext_default
# REL_DEF-NEXT: R_X86_64_JUMP_SLOT notype_default
# REL_DEF-NEXT: R_X86_64_JUMP_SLOT undef
# REL_DEF-NEXT: }
@ -62,8 +62,8 @@
# REL_GFUN-NEXT: R_X86_64_64 data_default
# REL_GFUN-NEXT: }
# REL_GFUN-NEXT: .rela.plt {
# REL_GFUN-NEXT: R_X86_64_JUMP_SLOT notype_default
# REL_GFUN-NEXT: R_X86_64_JUMP_SLOT weak_default
# REL_GFUN-NEXT: R_X86_64_JUMP_SLOT notype_default
# REL_GFUN-NEXT: R_X86_64_JUMP_SLOT undef
# REL_GFUN-NEXT: }

View File

@ -62,7 +62,7 @@
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar
// CHECK-NEXT: Value: 0x401100
// CHECK-NEXT: Value: 0x401110
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
// CHECK-NEXT: Type: Function
@ -80,7 +80,7 @@
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo
// CHECK-NEXT: Value: 0x401110
// CHECK-NEXT: Value: 0x401100
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
// CHECK-NEXT: Type: Function
@ -114,18 +114,18 @@
// DISASM: <foo_resolver>:
// DISASM-NEXT: 4010e5: retl
// DISASM: <_start>:
// DISASM-NEXT: 4010e6: calll 0x401110 <foo>
// DISASM-NEXT: calll 0x401100 <bar>
// DISASM-NEXT: 4010e6: calll 0x401100 <foo>
// DISASM-NEXT: calll 0x401110 <bar>
// DISASM-NEXT: movl $4194516, %edx
// DISASM-NEXT: movl $4194532, %edx
// DISASM-EMPTY:
// DISASM-NEXT: Disassembly of section .iplt:
// DISASM-EMPTY:
// DISASM-NEXT: <bar>:
// DISASM-NEXT: <foo>:
// DISASM-NEXT: 401100: jmpl *4202784
// DISASM-NEXT: pushl $0
// DISASM-NEXT: jmp 0x0
// DISASM: <foo>:
// DISASM: <bar>:
// DISASM-NEXT: 401110: jmpl *4202788
// DISASM-NEXT: pushl $8
// DISASM-NEXT: jmp 0x0

View File

@ -24,28 +24,28 @@
## st_value points to the canonical PLT entry in .glink
# SYM: Symbol table '.dynsym'
# SYM: 1001022c 0 FUNC GLOBAL DEFAULT UND func
# SYM: 1001023c 0 FUNC GLOBAL DEFAULT UND func2
# SYM: 1001023c 0 FUNC GLOBAL DEFAULT UND func
# SYM: 1001022c 0 FUNC GLOBAL DEFAULT UND func2
# SYM: 1001024c 0 FUNC GLOBAL DEFAULT UND ifunc
# SYM: Symbol table '.symtab'
# SYM: 1001022c 0 FUNC GLOBAL DEFAULT UND func
# SYM: 1001023c 0 FUNC GLOBAL DEFAULT UND func2
# SYM: 1001023c 0 FUNC GLOBAL DEFAULT UND func
# SYM: 1001022c 0 FUNC GLOBAL DEFAULT UND func2
# SYM: 1001024c 0 FUNC GLOBAL DEFAULT UND ifunc
# HEX: 0x10030318 1001025c 10010260 10010264
## Canonical PLT entry of func.
## 0x10030318 = 65536*4099+792
## Canonical PLT entry of func2.
## 0x1003031C = 65536*4099+796
# CHECK: 1001022c <.glink>:
# CHECK-NEXT: lis 11, 4099
# CHECK-NEXT: lwz 11, 792(11)
# CHECK-NEXT: lwz 11, 796(11)
# CHECK-NEXT: mtctr 11
# CHECK-NEXT: bctr
## Canonical PLT entry of func2.
## 0x1003031C = 65536*4099+796
## Canonical PLT entry of func.
## 0x10030318 = 65536*4099+792
# CHECK-NEXT: 1001023c: lis 11, 4099
# CHECK-NEXT: lwz 11, 796(11)
# CHECK-NEXT: lwz 11, 792(11)
# CHECK-NEXT: mtctr 11
# CHECK-NEXT: bctr

View File

@ -7,13 +7,12 @@
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
# RELOC: .rela.dyn {
# RELOC-NEXT: 0x3024C R_PPC_RELATIVE - 0x101A0
# RELOC-NEXT: 0x30250 R_PPC_IRELATIVE - 0x10188
# RELOC-NEXT: 0x30254 R_PPC_RELATIVE - 0x101A8
# RELOC-NEXT: 0x30258 R_PPC_IRELATIVE - 0x10188
# RELOC-NEXT: }
# SYM: 000101a0 0 FUNC GLOBAL DEFAULT {{.*}} func
# HEX: Hex dump of section '.got2':
# HEX-NEXT: 0x0003024c 00000000 ....
# SYM: 000101a8 0 FUNC GLOBAL DEFAULT {{.*}} func
# HEX: 0x00030254 00000000
.section .got2,"aw"
.long func
@ -22,7 +21,9 @@
# CHECK: <.text>:
# CHECK-NEXT: 10188: blr
# CHECK: <_start>:
# CHECK-NEXT: bl 0x10190
# CHECK-NEXT: bl 0x10198
# CHECK-NEXT: lis 9, 1
# CHECK-NEXT: addi 9, 9, 424
# CHECK-EMPTY:
# CHECK-NEXT: <00008000.got2.plt_pic32.func>:
## 0x10020114 = 65536*4098+276
@ -40,3 +41,6 @@ func:
.globl _start
_start:
bl func+0x8000@plt
lis 9, func@ha
la 9, func@l(9)

View File

@ -12,21 +12,19 @@
## Check we can handle R_PPC_GOT16, which may be generated by -fpic code.
# RELOC: .rela.dyn {
# RELOC-NEXT: 0x10020218 R_PPC_GLOB_DAT b 0x0
# RELOC-NEXT: 0x1002021C R_PPC_GLOB_DAT b 0x0
# RELOC-NEXT: }
# NM: 1002020c d _GLOBAL_OFFSET_TABLE_
# NM: 10030220 d a
## The GOT slot of a can be filled at link time.
# HEX: section '.got':
# HEX: 0x1002020c [[#%x,]] 00000000 00000000 00000000
# HEX-NEXT: 0x1002021c 10030220
# HEX: 0x1002020c {{[0-9a-f]+}} 00000000 00000000 10030220
## a: &.got[4] - _GLOBAL_OFFSET_TABLE_ = 0x1002021c - 0x1002020c = 16
## b: &.got[3] - _GLOBAL_OFFSET_TABLE_ = 0x10020218 - 0x1002020c = 12
# CHECK: lwz 3, 16(30)
# CHECK: lwz 4, 12(30)
## a: &.got[3] - _GLOBAL_OFFSET_TABLE_ = 12
## b: &.got[4] - _GLOBAL_OFFSET_TABLE_ = 16
# CHECK: lwz 3, 12(30)
# CHECK: lwz 4, 16(30)
lwz 3,a@got(30)
lwz 4,b@got(30)

View File

@ -16,9 +16,9 @@
# SYM: Value Size Type Bind Vis Ndx
# SYM: 0000000010028298 0 NOTYPE LOCAL HIDDEN 4 .TOC.
# SYM: 0000000010010268 0 FUNC GLOBAL DEFAULT 3 ifunc1
# SYM: 0000000010010288 0 FUNC GLOBAL DEFAULT 3 ifunc1
# SYM: 0000000010010210 0 IFUNC GLOBAL DEFAULT 2 ifunc2
# SYM: 0000000010010288 0 FUNC GLOBAL DEFAULT 3 ifunc3
# SYM: 0000000010010278 0 FUNC GLOBAL DEFAULT 3 ifunc3
# SECTIONS: .plt NOBITS 00000000100302a0 0002a0 000018 00 WA 0 0 8
@ -32,23 +32,23 @@
# CHECK-NEXT: 10010224: bl 0x10010254
# CHECK-NEXT: ld 2, 24(1)
# CHECK-NEXT: addis 3, 2, -2
# CHECK-NEXT: addi 3, 3, 32720
# CHECK-NEXT: addis 3, 2, -2
# CHECK-NEXT: addi 3, 3, 32752
# CHECK-NEXT: addis 3, 2, -2
# CHECK-NEXT: addi 3, 3, 32736
# .plt[1] - .TOC. = 0x100302a0+8 - 0x10028298 = (1<<16) - 32752
# .plt[0] - .TOC. = 0x100302a0 - 0x10028298 = (1<<16) - 32760
# CHECK: <__plt_ifunc2>:
# CHECK-NEXT: std 2, 24(1)
# CHECK-NEXT: addis 12, 2, 1
# CHECK-NEXT: ld 12, -32752(12)
# CHECK-NEXT: ld 12, -32760(12)
# CHECK-NEXT: mtctr 12
# CHECK-NEXT: bctr
# .plt[2] - .TOC. = 0x100302a0+16 - 0x10028298 = (1<<16) - 32744
# .plt[1] - .TOC. = 0x100302a0+8 - 0x10028298 = (1<<16) - 32752
# CHECK: <__plt_ifunc3>:
# CHECK-NEXT: std 2, 24(1)
# CHECK-NEXT: addis 12, 2, 1
# CHECK-NEXT: ld 12, -32744(12)
# CHECK-NEXT: ld 12, -32752(12)
# CHECK-NEXT: mtctr 12
# CHECK-NEXT: bctr
# CHECK-EMPTY:
@ -57,17 +57,19 @@
## ifunc2 and ifunc3 have the same code sequence as their PLT call stubs.
# CHECK: Disassembly of section .glink:
# CHECK-EMPTY:
# CHECK-NEXT: 0000000010010268 <ifunc1>:
# CHECK-NEXT: 0000000010010268 <.glink>:
# CHECK-NEXT: addis 12, 2, 1
# CHECK-NEXT: ld 12, -32760(12)
# CHECK-NEXT: mtctr 12
# CHECK-NEXT: bctr
# CHECK-EMPTY:
# CHECK-NEXT: 0000000010010278 <ifunc3>:
# CHECK-NEXT: addis 12, 2, 1
# CHECK-NEXT: ld 12, -32752(12)
# CHECK-NEXT: mtctr 12
# CHECK-NEXT: bctr
# CHECK-EMPTY:
# CHECK-NEXT: 0000000010010288 <ifunc3>:
# CHECK-NEXT: 0000000010010288 <ifunc1>:
# CHECK-NEXT: addis 12, 2, 1
# CHECK-NEXT: ld 12, -32744(12)
# CHECK-NEXT: mtctr 12

View File

@ -7,9 +7,6 @@
// CHECK: unresolvable relocation R_X86_64_32S against symbol 'x'
// CHECK: unresolvable relocation R_X86_64_32S against symbol 'y'
// CHECK: unresolvable relocation R_X86_64_32S against symbol 'z'
// CHECK: unresolvable relocation R_X86_64_32 against symbol 'x'
// CHECK: unresolvable relocation R_X86_64_32 against symbol 'y'
// CHECK: unresolvable relocation R_X86_64_32 against symbol 'z'
.text
.global _start

View File

@ -25,39 +25,39 @@
# SEC64: .got PROGBITS 0000000000012358 000358 000018
# RELOC32: .rela.dyn {
# RELOC32-NEXT: 0x12210 R_RISCV_32 b 0x0
# RELOC32-NEXT: 0x12214 R_RISCV_32 b 0x0
# RELOC32-NEXT: }
# RELOC64: .rela.dyn {
# RELOC64-NEXT: 0x12360 R_RISCV_64 b 0x0
# RELOC64-NEXT: 0x12368 R_RISCV_64 b 0x0
# RELOC64-NEXT: }
# NM32: 00013218 d a
# NM64: 0000000000013370 d a
## .got[0] = _DYNAMIC
## .got[1] = 0 (relocated by R_RISCV_32/64 at runtime)
## .got[2] = a (filled at link time)
## .got[1] = a (filled at link time)
## .got[2] = 0 (relocated by R_RISCV_64 at runtime)
# HEX32: section '.got':
# HEX32: 0x0001220c ac210100 00000000 18320100
# HEX32: 0x0001220c ac210100 18320100 00000000
# HEX64: section '.got':
# HEX64: 0x00012358 98220100 00000000 00000000 00000000
# HEX64: 0x00012368 70330100 00000000
# HEX64: 0x00012358 98220100 00000000 70330100 00000000
# HEX64: 0x00012368 00000000 00000000
## &.got[2]-. = 0x12214-0x1119c = 4096*1+120
## &.got[1]-. = 0x12210-0x1119c = 4096*1+116
# DIS32: 1119c: auipc a0, 1
# DIS32-NEXT: lw a0, 120(a0)
## &.got[1]-. = 0x12210-0x111a4 = 4096*1+108
# DIS32-NEXT: lw a0, 116(a0)
## &.got[2]-. = 0x12214-0x111a4 = 4096*1+112
# DIS32: 111a4: auipc a0, 1
# DIS32-NEXT: lw a0, 108(a0)
# DIS32-NEXT: lw a0, 112(a0)
## &.got[2]-. = 0x12368-0x11288 = 4096*1+224
## &.got[1]-. = 0x12360-0x11288 = 4096*1+216
# DIS64: 11288: auipc a0, 1
# DIS64-NEXT: ld a0, 224(a0)
## &.got[1]-. = 0x12360-0x11290 = 4096*1+208
# DIS64-NEXT: ld a0, 216(a0)
## &.got[2]-. = 0x12368-0x11290 = 4096*1+216
# DIS64: 11290: auipc a0, 1
# DIS64-NEXT: ld a0, 208(a0)
# DIS64-NEXT: ld a0, 216(a0)
la a0,a
la a0,b

View File

@ -105,8 +105,8 @@
# RUN: llvm-objdump -d --no-show-raw-insn %t.w1 | FileCheck %s --check-prefix=W1DIS
# W1REL: .rela.plt {
# W1REL-NEXT: R_X86_64_JUMP_SLOT foo@@v1 0x0
# W1REL-NEXT: R_X86_64_JUMP_SLOT __wrap_foo 0x0
# W1REL-NEXT: R_X86_64_JUMP_SLOT foo@@v1 0x0
# W1REL-NEXT: }
# W1DIS-LABEL: <.text>:
@ -121,8 +121,8 @@
# RUN: llvm-objdump -d --no-show-raw-insn %t.w2 | FileCheck %s --check-prefix=W2DIS
# W2REL: .rela.plt {
# W2REL-NEXT: R_X86_64_JUMP_SLOT foo@v1 0x0
# W2REL-NEXT: R_X86_64_JUMP_SLOT __wrap_foo 0x0
# W2REL-NEXT: R_X86_64_JUMP_SLOT foo@v1 0x0
# W2REL-NEXT: }
# W2DIS-LABEL: <.text>:

View File

@ -42,8 +42,8 @@
# RUN: ld.lld --version-script %t4.script -shared %t.o %tref.o -o %t5.so
# RUN: llvm-readelf -r %t5.so | FileCheck --check-prefix=RELOC %s
# RELOC: R_X86_64_JUMP_SLOT {{.*}} foo4@@v2 + 0
# RELOC: R_X86_64_JUMP_SLOT {{.*}} foo3@v1 + 0
# RELOC: R_X86_64_JUMP_SLOT {{.*}} foo4@@v2 + 0
.globl foo1; foo1: ret
.globl foo2; foo2: ret

View File

@ -9,23 +9,23 @@
// RUN: llvm-readelf -s -x .got %t | FileCheck --check-prefix=READELF --implicit-check-not=__real_ %s
// CHECK: <_start>:
// CHECK-NEXT: movq {{.*}}(%rip), %rax # 0x2021b0
// CHECK-NEXT: movq {{.*}}(%rip), %rbx # 0x2021b0
// CHECK-NEXT: movq {{.*}}(%rip), %rcx # 0x2021a8
// CHECK-NEXT: movq {{.*}}(%rip), %rax # 0x2021a8
// CHECK-NEXT: movq {{.*}}(%rip), %rbx # 0x2021a8
// CHECK-NEXT: movq {{.*}}(%rip), %rcx # 0x2021b0
// READELF: 0000000000011000 0 NOTYPE GLOBAL DEFAULT ABS foo
// READELF: 0000000000011010 0 NOTYPE GLOBAL DEFAULT ABS __wrap_foo
// READELF: Hex dump of section '.got':
// READELF-NEXT: 0x[[#%x,ADDR:]] 00100100 00000000 10100100 00000000
// READELF-NEXT: 0x[[#%x,ADDR:]] 10100100 00000000 00100100 00000000
// RUN: ld.lld -o %t2 %t1.o %t2.o %t3.so --wrap foo
// RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=CHECK2 %s
// RUN: llvm-readelf -s -x .got %t2 | FileCheck --check-prefix=READELF --implicit-check-not=__real_ %s
// CHECK2: <_start>:
// CHECK2-NEXT: movq {{.*}}(%rip), %rax # 0x2022e8
// CHECK2-NEXT: movq {{.*}}(%rip), %rbx # 0x2022e8
// CHECK2-NEXT: movq {{.*}}(%rip), %rcx # 0x2022e0
// CHECK2-NEXT: movq {{.*}}(%rip), %rax # 0x2022e0
// CHECK2-NEXT: movq {{.*}}(%rip), %rbx # 0x2022e0
// CHECK2-NEXT: movq {{.*}}(%rip), %rcx # 0x2022e8
.global _start
_start:

View File

@ -10,8 +10,8 @@
// CHECK: Relocations [
// CHECK-NEXT: Section ({{.*}}) .rela.plt {
// CHECK-NEXT: R_X86_64_JUMP_SLOT foo 0x0
// CHECK-NEXT: R_X86_64_JUMP_SLOT __wrap_foo 0x0
// CHECK-NEXT: R_X86_64_JUMP_SLOT foo 0x0
// CHECK-NEXT: R_X86_64_JUMP_SLOT _start 0x0
// CHECK-NEXT: }
// CHECK-NEXT: ]

View File

@ -23,22 +23,22 @@
# DISASM: <hid>:
# DISASM-NEXT: nop
# DISASM: <_start>:
# DISASM-NEXT: movq 4375(%rip), %rax
# DISASM-NEXT: movq 4368(%rip), %rax
# DISASM-NEXT: movq 4369(%rip), %rax
# DISASM-NEXT: movq 4362(%rip), %rax
# DISASM-NEXT: movq 4367(%rip), %rax
# DISASM-NEXT: movq 4360(%rip), %rax
# DISASM-NEXT: movq 4361(%rip), %rax
# DISASM-NEXT: movq 4354(%rip), %rax
# DISASM-NEXT: leaq -36(%rip), %rax
# DISASM-NEXT: leaq -43(%rip), %rax
# DISASM-NEXT: movq 4325(%rip), %rax
# DISASM-NEXT: movq 4318(%rip), %rax
# DISASM-NEXT: movq 4319(%rip), %rax
# DISASM-NEXT: movq 4312(%rip), %rax
# DISASM-NEXT: movq 4313(%rip), %rax
# DISASM-NEXT: movq 4306(%rip), %rax
# DISASM-NEXT: movq 4341(%rip), %rax
# DISASM-NEXT: movq 4334(%rip), %rax
# DISASM-NEXT: movq 4311(%rip), %rax
# DISASM-NEXT: movq 4304(%rip), %rax
# DISASM-NEXT: movq 4305(%rip), %rax
# DISASM-NEXT: movq 4298(%rip), %rax
# DISASM-NEXT: leaq -92(%rip), %rax
# DISASM-NEXT: leaq -99(%rip), %rax
# DISASM-NEXT: movq 4269(%rip), %rax
# DISASM-NEXT: movq 4262(%rip), %rax
# DISASM-NEXT: movq 4285(%rip), %rax
# DISASM-NEXT: movq 4278(%rip), %rax
.text
.globl foo

View File

@ -14,15 +14,15 @@
# CHECK1: .plt PROGBITS 00000000002012e0 0002e0 000030 00 AX 0 0 16
# CHECK1: .got.plt PROGBITS 00000000002033e0 0003e0 000028 00 WA 0 0 8
# CHECK1: Relocation section '.rela.plt' at offset {{.*}} contains 2 entries:
# CHECK1: 00000000002033f8 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 weak + 0
# CHECK1-NEXT: 0000000000203400 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 bar + 0
# CHECK1: 00000000002033f8 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 bar + 0
# CHECK1-NEXT: 0000000000203400 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 weak + 0
# CHECK2: Name Type Address Off Size ES Flg Lk Inf Al
# CHECK2: .plt PROGBITS 0000000000001310 000310 000030 00 AX 0 0 16
# CHECK2: .got.plt PROGBITS 0000000000003400 000400 000028 00 WA 0 0 8
# CHECK2: Relocation section '.rela.plt' at offset {{.*}} contains 2 entries:
# CHECK2: 0000000000003418 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 weak + 0
# CHECK2-NEXT: 0000000000003420 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 bar + 0
# CHECK2: 0000000000003418 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 bar + 0
# CHECK2-NEXT: 0000000000003420 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 weak + 0
# DISASM: <_start>:
# DISASM-NEXT: callq {{.*}} <local>
@ -37,12 +37,12 @@
# DISASM1-NEXT: jmpq *8452(%rip) # 0x2033f0
# DISASM1-NEXT: nopl (%rax)
# DISASM1-EMPTY:
# DISASM1-NEXT: <weak@plt>:
# DISASM1-NEXT: <bar@plt>:
# DISASM1-NEXT: 2012f0: jmpq *8450(%rip) # 0x2033f8
# DISASM1-NEXT: pushq $0
# DISASM1-NEXT: jmp 0x2012e0 <.plt>
# DISASM1-EMPTY:
# DISASM1-NEXT: <bar@plt>:
# DISASM1-NEXT: <weak@plt>:
# DISASM1-NEXT: 201300: jmpq *8442(%rip) # 0x203400
# DISASM1-NEXT: pushq $1
# DISASM1-NEXT: jmp 0x2012e0 <.plt>
@ -55,12 +55,12 @@
# DISASM2-NEXT: jmpq *8436(%rip) # 0x3410
# DISASM2-NEXT: nopl (%rax)
# DISASM2-EMPTY:
# DISASM2-NEXT: <weak@plt>:
# DISASM2-NEXT: <bar@plt>:
# DISASM2-NEXT: 1320: jmpq *8434(%rip) # 0x3418
# DISASM2-NEXT: pushq $0
# DISASM2-NEXT: jmp 0x1310 <.plt>
# DISASM2-EMPTY:
# DISASM2-NEXT: <bar@plt>:
# DISASM2-NEXT: <weak@plt>:
# DISASM2-NEXT: 1330: jmpq *8426(%rip) # 0x3420
# DISASM2-NEXT: pushq $1
# DISASM2-NEXT: jmp 0x1310 <.plt>

View File

@ -11,8 +11,8 @@
# CHECK: .plt PROGBITS 002011e0 0001e0 000030 00 AX 0 0 16
# CHECK: .got.plt PROGBITS 00203278 000278 000028 00 WA 0 0 8
# CHECK: Relocation section '.rela.plt' at offset {{.*}} contains 2 entries:
# CHECK: 00203290 {{.*}} R_X86_64_JUMP_SLOT 00000000 weak + 0
# CHECK-NEXT: 00203298 {{.*}} R_X86_64_JUMP_SLOT 00000000 bar + 0
# CHECK: 00203290 {{.*}} R_X86_64_JUMP_SLOT 00000000 bar + 0
# CHECK-NEXT: 00203298 {{.*}} R_X86_64_JUMP_SLOT 00000000 weak + 0
# DISASM: <_start>:
# DISASM-NEXT: callq {{.*}} <local>
@ -27,12 +27,12 @@
# DISASM-NEXT: jmpq *8348(%rip) # 0x203288
# DISASM-NEXT: nopl (%rax)
# DISASM-EMPTY:
# DISASM-NEXT: <weak@plt>:
# DISASM-NEXT: <bar@plt>:
# DISASM-NEXT: 2011f0: jmpq *8346(%rip) # 0x203290
# DISASM-NEXT: pushq $0
# DISASM-NEXT: jmp 0x2011e0 <.plt>
# DISASM-EMPTY:
# DISASM-NEXT: <bar@plt>:
# DISASM-NEXT: <weak@plt>:
# DISASM-NEXT: 201200: jmpq *8338(%rip) # 0x203298
# DISASM-NEXT: pushq $1
# DISASM-NEXT: jmp 0x2011e0 <.plt>