Skip to content

Commit

Permalink
[XRay] Change Sled.Function to PC-relative for sled version 2 and mak…
Browse files Browse the repository at this point in the history
…e llvm-xray support sled version 2 addresses

Follow-up of D78082 and D78590.

Otherwise, because xray_instr_map is now read-only, the absolute
relocation used for Sled.Function will cause a text relocation.
  • Loading branch information
MaskRay committed Apr 24, 2020
1 parent fc02624 commit 10bc125
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 49 deletions.
4 changes: 2 additions & 2 deletions compiler-rt/lib/xray/xray_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ XRayPatchingStatus controlPatching(bool Enable) XRAY_NEVER_INSTRUMENT {

for (std::size_t I = 0; I < InstrMap.Entries; ++I) {
auto &Sled = InstrMap.Sleds[I];
auto F = Sled.Function;
auto F = Sled.function();
if (CurFun == 0)
CurFun = F;
if (F != CurFun) {
Expand Down Expand Up @@ -466,7 +466,7 @@ uintptr_t __xray_function_address(int32_t FuncId) XRAY_NEVER_INSTRUMENT {
SpinMutexLock Guard(&XRayInstrMapMutex);
if (FuncId <= 0 || static_cast<size_t>(FuncId) > XRayInstrMap.Functions)
return 0;
return XRayInstrMap.SledsIndex[FuncId - 1].Begin->Function
return XRayInstrMap.SledsIndex[FuncId - 1].Begin->function()
// On PPC, function entries are always aligned to 16 bytes. The beginning of a
// sled might be a local entry, which is always +8 based on the global entry.
// Always return the global entry.
Expand Down
12 changes: 12 additions & 0 deletions compiler-rt/lib/xray/xray_interface_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ struct XRaySledEntry {
unsigned char AlwaysInstrument;
unsigned char Version;
unsigned char Padding[13]; // Need 32 bytes
uint64_t function() const {
if (Version < 2)
return Function;
// The target address is relative to the location of the Function variable.
return reinterpret_cast<uint64_t>(&Function) + Function;
}
uint64_t address() const {
if (Version < 2)
return Address;
Expand All @@ -42,6 +48,12 @@ struct XRaySledEntry {
unsigned char AlwaysInstrument;
unsigned char Version;
unsigned char Padding[5]; // Need 16 bytes
uint32_t function() const {
if (Version < 2)
return Function;
// The target address is relative to the location of the Function variable.
return reinterpret_cast<uint32_t>(&Function) + Function;
}
uint32_t address() const {
if (Version < 2)
return Address;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/AsmPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ class AsmPrinter : public MachineFunctionPass {
const class Function *Fn;
uint8_t Version;

void emit(int, MCStreamer *, const MCExpr *, const MCSymbol *) const;
void emit(int, MCStreamer *) const;
};

// All the sleds to be emitted.
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/XRay/InstrumentationMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ struct SledEntry {

/// Whether the sled was annotated to always be instrumented.
bool AlwaysInstrument;

unsigned char Version;
};

struct YAMLXRaySledEntry {
Expand All @@ -59,6 +61,7 @@ struct YAMLXRaySledEntry {
SledEntry::FunctionKinds Kind;
bool AlwaysInstrument;
std::string FunctionName;
unsigned char Version;
};

/// The InstrumentationMap represents the computed function id's and indicated
Expand Down Expand Up @@ -120,6 +123,7 @@ template <> struct MappingTraits<xray::YAMLXRaySledEntry> {
IO.mapRequired("kind", Entry.Kind);
IO.mapRequired("always-instrument", Entry.AlwaysInstrument);
IO.mapOptional("function-name", Entry.FunctionName);
IO.mapOptional("version", Entry.Version, 0);
}

static constexpr bool flow = true;
Expand Down
35 changes: 21 additions & 14 deletions llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1767,6 +1767,8 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
CurExceptionSym = nullptr;
bool NeedsLocalForSize = MAI->needsLocalForSize();
if (F.hasFnAttribute("patchable-function-entry") ||
F.hasFnAttribute("function-instrument") ||
F.hasFnAttribute("xray-instruction-threshold") ||
needFuncLabelsForEHOrDebugInfo(MF, MMI) || NeedsLocalForSize ||
MF.getTarget().Options.EmitStackSizeSection) {
CurrentFnBegin = createTempSymbol("func_begin");
Expand Down Expand Up @@ -3174,14 +3176,7 @@ void AsmPrinterHandler::markFunctionEnd() {}
// In the binary's "xray_instr_map" section, an array of these function entries
// describes each instrumentation point. When XRay patches your code, the index
// into this table will be given to your handler as a patch point identifier.
void AsmPrinter::XRayFunctionEntry::emit(int Bytes, MCStreamer *Out,
const MCExpr *Location,
const MCSymbol *CurrentFnSym) const {
if (Location)
Out->emitValueImpl(Location, Bytes);
else
Out->emitSymbolValue(Sled, Bytes);
Out->emitSymbolValue(CurrentFnSym, Bytes);
void AsmPrinter::XRayFunctionEntry::emit(int Bytes, MCStreamer *Out) const {
auto Kind8 = static_cast<uint8_t>(Kind);
Out->emitBinaryData(StringRef(reinterpret_cast<const char *>(&Kind8), 1));
Out->emitBinaryData(
Expand Down Expand Up @@ -3234,19 +3229,31 @@ void AsmPrinter::emitXRayTable() {
// Now we switch to the instrumentation map section. Because this is done
// per-function, we are able to create an index entry that will represent the
// range of sleds associated with a function.
auto &Ctx = OutContext;
MCSymbol *SledsStart = OutContext.createTempSymbol("xray_sleds_start", true);
OutStreamer->SwitchSection(InstMap);
OutStreamer->emitLabel(SledsStart);
for (const auto &Sled : Sleds) {
const MCExpr *Location = nullptr;
if (PCRel) {
MCSymbol *Dot = OutContext.createTempSymbol();
MCSymbol *Dot = Ctx.createTempSymbol();
OutStreamer->emitLabel(Dot);
Location = MCBinaryExpr::createSub(
MCSymbolRefExpr::create(Sled.Sled, OutContext),
MCSymbolRefExpr::create(Dot, OutContext), OutContext);
OutStreamer->emitValueImpl(
MCBinaryExpr::createSub(MCSymbolRefExpr::create(Sled.Sled, Ctx),
MCSymbolRefExpr::create(Dot, Ctx), Ctx),
WordSizeBytes);
OutStreamer->emitValueImpl(
MCBinaryExpr::createSub(
MCSymbolRefExpr::create(CurrentFnBegin, Ctx),
MCBinaryExpr::createAdd(
MCSymbolRefExpr::create(Dot, Ctx),
MCConstantExpr::create(WordSizeBytes, Ctx), Ctx),
Ctx),
WordSizeBytes);
} else {
OutStreamer->emitSymbolValue(Sled.Sled, WordSizeBytes);
OutStreamer->emitSymbolValue(CurrentFnSym, WordSizeBytes);
}
Sled.emit(WordSizeBytes, OutStreamer.get(), Location, CurrentFnSym);
Sled.emit(WordSizeBytes, OutStreamer.get());
}
MCSymbol *SledsEnd = OutContext.createTempSymbol("xray_sleds_end", true);
OutStreamer->emitLabel(SledsEnd);
Expand Down
15 changes: 12 additions & 3 deletions llvm/lib/XRay/InstrumentationMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,13 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,

StringRef Contents = "";
const auto &Sections = ObjFile.getBinary()->sections();
uint64_t Address = 0;
auto I = llvm::find_if(Sections, [&](object::SectionRef Section) {
Expected<StringRef> NameOrErr = Section.getName();
if (NameOrErr)
if (NameOrErr) {
Address = Section.getAddress();
return *NameOrErr == "xray_instr_map";
}
consumeError(NameOrErr.takeError());
return false;
});
Expand Down Expand Up @@ -141,6 +144,7 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
return Address;
};

const int WordSize = 8;
int32_t FuncId = 1;
uint64_t CurFn = 0;
for (; C != Contents.bytes_end(); C += ELF64SledEntrySize) {
Expand All @@ -165,6 +169,11 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
std::make_error_code(std::errc::executable_format_error));
Entry.Kind = Kinds[Kind];
Entry.AlwaysInstrument = Extractor.getU8(&OffsetPtr) != 0;
Entry.Version = Extractor.getU8(&OffsetPtr);
if (Entry.Version >= 2) {
Entry.Address += C - Contents.bytes_begin() + Address;
Entry.Function += C - Contents.bytes_begin() + WordSize + Address;
}

// We do replicate the function id generation scheme implemented in the
// XRay runtime.
Expand Down Expand Up @@ -209,8 +218,8 @@ loadYAML(sys::fs::file_t Fd, size_t FileSize, StringRef Filename,
for (const auto &Y : YAMLSleds) {
FunctionAddresses[Y.FuncId] = Y.Function;
FunctionIds[Y.Function] = Y.FuncId;
Sleds.push_back(
SledEntry{Y.Address, Y.Function, Y.Kind, Y.AlwaysInstrument});
Sleds.push_back(SledEntry{Y.Address, Y.Function, Y.Kind, Y.AlwaysInstrument,
Y.Version});
}
return Error::success();
}
Expand Down
40 changes: 20 additions & 20 deletions llvm/test/CodeGen/Mips/xray-mips-attribute-instrumentation.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always"
; CHECK: .p2align 2
; CHECK-MIPS64-LABEL: .Lxray_sled_0:
; CHECK-MIPS32-LABEL: $xray_sled_0:
; CHECK-MIPS64: b .Ltmp0
; CHECK-MIPS32: b $tmp0
; CHECK-MIPS64: b .Ltmp1
; CHECK-MIPS32: b $tmp1
; CHECK-NEXT: nop
; CHECK-NEXT: nop
; CHECK-NEXT: nop
Expand All @@ -24,15 +24,15 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always"
; CHECK-MIPS64: nop
; CHECK-MIPS64: nop
; CHECK-MIPS64: nop
; CHECK-MIPS64-LABEL: .Ltmp0:
; CHECK-MIPS32-LABEL: $tmp0:
; CHECK-MIPS64-LABEL: .Ltmp1:
; CHECK-MIPS32-LABEL: $tmp1:
; CHECK-MIPS32: addiu $25, $25, 52
ret i32 0
; CHECK: .p2align 2
; CHECK-MIPS64-LABEL: .Lxray_sled_1:
; CHECK-MIPS64-NEXT: b .Ltmp2
; CHECK-MIPS32-LABEL: $xray_sled_1:
; CHECK-MIPS64: b .Ltmp1
; CHECK-MIPS32: b $tmp1
; CHECK-MIPS32-NEXT: b $tmp2
; CHECK-NEXT: nop
; CHECK-NEXT: nop
; CHECK-NEXT: nop
Expand All @@ -48,8 +48,8 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always"
; CHECK-MIPS64: nop
; CHECK-MIPS64: nop
; CHECK-MIPS64: nop
; CHECK-MIPS64-LABEL: .Ltmp1:
; CHECK-MIPS32-LABEL: $tmp1:
; CHECK-MIPS64-LABEL: .Ltmp2:
; CHECK-MIPS32-LABEL: $tmp2:
; CHECK-MIPS32: addiu $25, $25, 52
}
; CHECK: .section xray_instr_map,{{.*}}
Expand All @@ -63,9 +63,9 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always"
define i32 @bar(i32 %i) nounwind noinline uwtable "function-instrument"="xray-always" {
; CHECK: .p2align 2
; CHECK-MIPS64-LABEL: .Lxray_sled_2:
; CHECK-MIPS64-NEXT: b .Ltmp4
; CHECK-MIPS32-LABEL: $xray_sled_2:
; CHECK-MIPS64: b .Ltmp2
; CHECK-MIPS32: b $tmp2
; CHECK-MIPS32-NEXT: b $tmp4
; CHECK-NEXT: nop
; CHECK-NEXT: nop
; CHECK-NEXT: nop
Expand All @@ -81,8 +81,8 @@ define i32 @bar(i32 %i) nounwind noinline uwtable "function-instrument"="xray-al
; CHECK-MIPS64: nop
; CHECK-MIPS64: nop
; CHECK-MIPS64: nop
; CHECK-MIPS64-LABEL: .Ltmp2:
; CHECK-MIPS32-LABEL: $tmp2:
; CHECK-MIPS64-LABEL: .Ltmp4:
; CHECK-MIPS32-LABEL: $tmp4:
; CHECK-MIPS32: addiu $25, $25, 52
Test:
%cond = icmp eq i32 %i, 0
Expand All @@ -91,9 +91,9 @@ IsEqual:
ret i32 0
; CHECK: .p2align 2
; CHECK-MIPS64-LABEL: .Lxray_sled_3:
; CHECK-MIPS64-NEXT: b .Ltmp5
; CHECK-MIPS32-LABEL: $xray_sled_3:
; CHECK-MIPS64: b .Ltmp3
; CHECK-MIPS32: b $tmp3
; CHECK-MIPS32-NEXT: b $tmp5
; CHECK-NEXT: nop
; CHECK-NEXT: nop
; CHECK-NEXT: nop
Expand All @@ -109,16 +109,16 @@ IsEqual:
; CHECK-MIPS64: nop
; CHECK-MIPS64: nop
; CHECK-MIPS64: nop
; CHECK-MIPS64-LABEL: .Ltmp3:
; CHECK-MIPS32-LABEL: $tmp3:
; CHECK-MIPS64-LABEL: .Ltmp5:
; CHECK-MIPS32-LABEL: $tmp5:
; CHECK-MIPS32: addiu $25, $25, 52
NotEqual:
ret i32 1
; CHECK: .p2align 2
; CHECK-MIPS64-LABEL: .Lxray_sled_4:
; CHECK-MIPS64-NEXT: b .Ltmp6
; CHECK-MIPS32-LABEL: $xray_sled_4:
; CHECK-MIPS64: b .Ltmp4
; CHECK-MIPS32: b $tmp4
; CHECK-MIPS32-NEXT: b $tmp6
; CHECK-NEXT: nop
; CHECK-NEXT: nop
; CHECK-NEXT: nop
Expand All @@ -134,8 +134,8 @@ NotEqual:
; CHECK-MIPS64: nop
; CHECK-MIPS64: nop
; CHECK-MIPS64: nop
; CHECK-MIPS64-LABEL: .Ltmp4:
; CHECK-MIPS32-LABEL: $tmp4:
; CHECK-MIPS64-LABEL: .Ltmp6:
; CHECK-MIPS32-LABEL: $tmp6:
; CHECK-MIPS32: addiu $25, $25, 52
}
; CHECK: .section xray_instr_map,{{.*}}
Expand Down
6 changes: 4 additions & 2 deletions llvm/test/CodeGen/PowerPC/xray-attribute-instrumentation.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
; RUN: -relocation-model=pic < %s | FileCheck %s

define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" {
; CHECK-LABEL: foo:
; CHECK-NEXT: .Lfunc_begin0:
; CHECK-LABEL: .Ltmp0:
; CHECK: b .Ltmp1
; CHECK-NEXT: nop
Expand All @@ -26,14 +28,14 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always"
; CHECK: .Lxray_sleds_start0:
; CHECK-NEXT: .Ltmp3:
; CHECK-NEXT: .quad .Ltmp0-.Ltmp3
; CHECK-NEXT: .quad foo
; CHECK-NEXT: .quad .Lfunc_begin0-(.Ltmp3+8)
; CHECK-NEXT: .byte 0x00
; CHECK-NEXT: .byte 0x01
; CHECK-NEXT: .byte 0x02
; CHECK-NEXT: .space 13
; CHECK-NEXT: .Ltmp4:
; CHECK-NEXT: .quad .Ltmp2-.Ltmp4
; CHECK-NEXT: .quad foo
; CHECK-NEXT: .quad .Lfunc_begin0-(.Ltmp4+8)
; CHECK-NEXT: .byte 0x01
; CHECK-NEXT: .byte 0x01
; CHECK-NEXT: .byte 0x02
Expand Down
11 changes: 7 additions & 4 deletions llvm/test/CodeGen/X86/xray-log-args.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@
define i32 @callee(i32 %arg) nounwind noinline uwtable "function-instrument"="xray-always" "xray-log-args"="1" {
ret i32 %arg
}
; CHECK-LABEL: callee:
; CHECK-NEXT: Lfunc_begin0:

; CHECK-LABEL: Lxray_sleds_start0:
; CHECK-NEXT: Ltmp0:
; CHECK-NEXT: .quad {{\.?}}Lxray_sled_0-{{\.?}}Ltmp0
; CHECK-NEXT: .quad {{_?}}callee
; CHECK-NEXT: .quad {{\.?}}Lfunc_begin0-({{\.?}}Ltmp0+8)
; CHECK-NEXT: .byte 0x03
; CHECK-NEXT: .byte 0x01
; CHECK-NEXT: .byte 0x02
; CHECK: .{{(zero|space)}} 13
; CHECK: Ltmp1:
; CHECK-NEXT: .quad {{\.?}}Lxray_sled_1-{{\.?}}Ltmp1
; CHECK-NEXT: .quad {{_?}}callee
; CHECK-NEXT: .quad {{\.?}}Lfunc_begin0-({{\.?}}Ltmp1+8)
; CHECK-NEXT: .byte 0x01
; CHECK-NEXT: .byte 0x01
; CHECK-NEXT: .byte 0x02
Expand All @@ -29,14 +32,14 @@ define i32 @caller(i32 %arg) nounwind noinline uwtable "function-instrument"="xr
; CHECK-LABEL: Lxray_sleds_start1:
; CHECK-NEXT: Ltmp3:
; CHECK-NEXT: .quad {{\.?}}Lxray_sled_2-{{\.?}}Ltmp3
; CHECK-NEXT: .quad {{_?}}caller
; CHECK-NEXT: .quad {{\.?}}Lfunc_begin1-({{\.?}}Ltmp3+8)
; CHECK-NEXT: .byte 0x03
; CHECK-NEXT: .byte 0x01
; CHECK-NEXT: .byte 0x02
; CHECK: .{{(zero|space)}} 13
; CHECK: Ltmp4:
; CHECK-NEXT: .quad {{\.?}}Lxray_sled_3-{{\.?}}Ltmp4
; CHECK-NEXT: .quad {{_?}}caller
; CHECK-NEXT: .quad {{\.?}}Lfunc_begin1-({{\.?}}Ltmp4+8)
; CHECK-NEXT: .byte 0x02
; CHECK-NEXT: .byte 0x01
; CHECK-NEXT: .byte 0x02
Expand Down
6 changes: 3 additions & 3 deletions llvm/tools/llvm-xray/xray-extract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ void exportAsYAML(const InstrumentationMap &Map, raw_ostream &OS,
auto FuncId = Map.getFunctionId(Sled.Function);
if (!FuncId)
return;
YAMLSleds.push_back({*FuncId, Sled.Address, Sled.Function, Sled.Kind,
Sled.AlwaysInstrument,
ExtractSymbolize ? FH.SymbolOrNumber(*FuncId) : ""});
YAMLSleds.push_back(
{*FuncId, Sled.Address, Sled.Function, Sled.Kind, Sled.AlwaysInstrument,
ExtractSymbolize ? FH.SymbolOrNumber(*FuncId) : "", Sled.Version});
}
Output Out(OS, nullptr, 0);
Out << YAMLSleds;
Expand Down

0 comments on commit 10bc125

Please sign in to comment.