Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT - DO NOT MERGE] Changes for SBFv3 #126

Draft
wants to merge 16 commits into
base: solana-rustc/18.1-2024-05-19
Choose a base branch
from
5 changes: 4 additions & 1 deletion lld/ELF/Arch/SBF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/Endian.h"
#include <iostream>

using namespace llvm;
using namespace llvm::object;
Expand All @@ -38,6 +39,9 @@ class SBF final : public TargetInfo {
SBF::SBF() {
relativeRel = R_SBF_64_RELATIVE;
symbolicRel = R_SBF_64_64;
defaultCommonPageSize = 8;
defaultMaxPageSize = 8;
defaultImageBase = 0;
}

RelExpr SBF::getRelExpr(RelType type, const Symbol &s,
Expand Down Expand Up @@ -78,7 +82,6 @@ int64_t SBF::getImplicitAddend(const uint8_t *buf, RelType type) const {
default:
return 0;
}
return 0;
}

void SBF::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
Expand Down
34 changes: 30 additions & 4 deletions lld/ELF/SyntheticSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
#include "llvm/Support/Parallel.h"
#include "llvm/Support/TimeProfiler.h"
#include <cstdlib>
#include <iostream>
#include <fstream>

using namespace llvm;
using namespace llvm::dwarf;
Expand Down Expand Up @@ -269,8 +271,9 @@ Defined *elf::addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
uint64_t size, InputSectionBase &section) {
Defined *s = makeDefined(section.file, name, STB_LOCAL, STV_DEFAULT, type,
value, size, &section);
if (in.symTab)
in.symTab->addSymbol(s);
if (in.symTab) {
in.symTab->addSymbol(s);
}

if (config->emachine == EM_ARM && !config->isLE && config->armBe8 &&
(section.flags & SHF_EXECINSTR))
Expand Down Expand Up @@ -2167,8 +2170,31 @@ void SymbolTableBaseSection::sortSymTabSymbols() {

void SymbolTableBaseSection::addSymbol(Symbol *b) {
// Adding a local symbol to a .dynsym is a bug.
assert(this->type != SHT_DYNSYM || !b->isLocal());
symbols.push_back({b, strTabSec.addString(b->getName(), false)});
// NOT for SBF :P
assert(this->type != SHT_DYNSYM ||
!b->isLocal() ||
(config->emachine == EM_SBF && config->eflags == 0x3));

unsigned Offset;
if (this->type == SHT_DYNSYM && b->isLocal()) {
const static unsigned LocalOffset = strTabSec.addString("hidden_func", false);
Offset = LocalOffset;
} else {
Offset = strTabSec.addString(b->getName(), false);
}

symbols.push_back({b, Offset});
}

void SymbolTableBaseSection::sortSymbolsByValue() {
llvm::stable_sort(symbols,
[](const SymbolTableEntry &a, const SymbolTableEntry &b) {
return a.sym->getVA() < b.sym->getVA();
});

symbols.erase(std::unique(symbols.begin(), symbols.end(), [](const SymbolTableEntry &a, const SymbolTableEntry &b) {
return a.sym->getVA() == b.sym->getVA();
}), symbols.end());
}

size_t SymbolTableBaseSection::getSymbolIndex(Symbol *sym) {
Expand Down
2 changes: 2 additions & 0 deletions lld/ELF/SyntheticSections.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "llvm/Support/Endian.h"
#include "llvm/Support/Parallel.h"
#include "llvm/Support/Threading.h"
#include <unordered_set>

namespace lld::elf {
class Defined;
Expand Down Expand Up @@ -643,6 +644,7 @@ class SymbolTableBaseSection : public SyntheticSection {
unsigned getNumSymbols() const { return symbols.size() + 1; }
size_t getSymbolIndex(Symbol *sym);
ArrayRef<SymbolTableEntry> getSymbols() const { return symbols; }
void sortSymbolsByValue();

protected:
void sortSymTabSymbols();
Expand Down
55 changes: 51 additions & 4 deletions lld/ELF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/xxhash.h"
#include <climits>
#include <iostream>
#include <fstream>

#define DEBUG_TYPE "lld"

Expand Down Expand Up @@ -320,6 +322,10 @@ static OutputSection *findSection(StringRef name, unsigned partition = 1) {
return nullptr;
}

static bool isSbfV3() {
return config->emachine == EM_SBF && config->eflags == 0x3;
}

template <class ELFT> void elf::createSyntheticSections() {
// Initialize all pointers with NULL. This is needed because
// you can call lld::elf::main more than once as a library.
Expand Down Expand Up @@ -347,6 +353,7 @@ template <class ELFT> void elf::createSyntheticSections() {
Out::programHeaders->addralign = config->wordsize;

if (config->strip != StripPolicy::All) {
// Let's create these tables and then discard everything later
in.strTab = std::make_unique<StringTableSection>(".strtab", false);
in.symTab = std::make_unique<SymbolTableSection<ELFT>>(*in.strTab);
in.symTabShndx = std::make_unique<SymtabShndxSection>();
Expand Down Expand Up @@ -690,6 +697,7 @@ template <class ELFT> static void markUsedLocalSymbols() {
// See MarkLive<ELFT>::resolveReloc().
if (config->gcSections)
return;

for (ELFFileBase *file : ctx.objectFiles) {
ObjFile<ELFT> *f = cast<ObjFile<ELFT>>(file);
for (InputSectionBase *s : f->getSections()) {
Expand Down Expand Up @@ -771,8 +779,19 @@ static void demoteAndCopyLocalSymbols() {

if (dr->section && !dr->section->isLive())
demoteDefined(*dr, sectionIndexMap);
else if (in.symTab && includeInSymtab(*b) && shouldKeepInSymtab(*dr))
in.symTab->addSymbol(b);
else if (in.symTab && includeInSymtab(*b) && shouldKeepInSymtab(*dr)) {
in.symTab->addSymbol(b);
}

if (isSbfV3() &&
includeInSymtab(*b) &&
shouldKeepInSymtab(*dr) &&
(b->used || (!config->gcSections && (!config->copyRelocs || config->discard == DiscardPolicy::None))) &&
b->type == STT_FUNC) {
// std::ofstream out("/Users/lucasste/Documents/solana-test/program/demote.txt", std::ios::app);
// out << "Adding sym: " << b->getName().str() << std::endl;
partitions[b->partition - 1].dynSymTab->addSymbol(b);
}
}
}
}
Expand Down Expand Up @@ -1692,6 +1711,7 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
AArch64Err843419Patcher a64p;
ARMErr657417Patcher a32p;
script->assignAddresses();
bool SbfDuplicateRemoval = false;
// .ARM.exidx and SHF_LINK_ORDER do not require precise addresses, but they
// do require the relative addresses of OutputSections because linker scripts
// can assign Virtual Addresses to OutputSections that are not monotonically
Expand Down Expand Up @@ -1742,6 +1762,15 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
}

const Defined *changedSym = script->assignAddresses();

if (!SbfDuplicateRemoval && isSbfV3()) {
for (Partition &part: partitions) {
part.dynSymTab->sortSymbolsByValue();
}
SbfDuplicateRemoval = true;
changed = true;
}

if (!changed) {
// Some symbols may be dependent on section addresses. When we break the
// loop, the symbol values are finalized because a previous
Expand Down Expand Up @@ -2060,19 +2089,32 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
llvm::TimeTraceScope timeScope("Add symbols to symtabs");
// Now that we have defined all possible global symbols including linker-
// synthesized ones. Visit all symbols to give the finishing touches.

for (Symbol *sym : symtab.getSymbols()) {
if (!sym->isUsedInRegularObj || !includeInSymtab(*sym))
continue;
if (!config->relocatable)
sym->binding = sym->computeBinding();
if (in.symTab)
in.symTab->addSymbol(sym);
if (in.symTab) {
in.symTab->addSymbol(sym);
}

// if (isSbfV3() && sym->used) {
// if ((sym->type & STT_FUNC) != 0) {
// std::ofstream out("/Users/lucasste/Documents/solana-test/program/for.txt", std::ios::app);
// out << sym->getName().str() << "\n";
// }
// }

if (sym->includeInDynsym()) {
partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
if (auto *file = dyn_cast_or_null<SharedFile>(sym->file))
if (file->isNeeded && !sym->isUndefined())
addVerneed(sym);
} else if (isSbfV3() &&
(sym->used || (!config->gcSections && (!config->copyRelocs || config->discard == DiscardPolicy::None))) &&
sym->type == STT_FUNC) {
partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
}
}

Expand Down Expand Up @@ -2268,6 +2310,11 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
addArmInputSectionMappingSymbols();
sortArmMappingSymbols();
}
// else if (isSbfV3()) {
// for (Partition &part: partitions) {
// part.dynSymTab->sortSymbolsByValue();
// }
// }
}

// Ensure data sections are not mixed with executable sections when
Expand Down
35 changes: 23 additions & 12 deletions llvm/lib/Target/SBF/SBFISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

#define DEBUG_TYPE "sbf-lower"
Expand All @@ -39,18 +40,6 @@ static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg) {
DiagnosticInfoUnsupported(MF.getFunction(), Msg, DL.getDebugLoc()));
}

static void fail(const SDLoc &DL, SelectionDAG &DAG, const char *Msg,
SDValue Val) {
MachineFunction &MF = DAG.getMachineFunction();
std::string Str;
raw_string_ostream OS(Str);
OS << Msg;
Val->print(OS);
OS.flush();
DAG.getContext()->diagnose(
DiagnosticInfoUnsupported(MF.getFunction(), Str, DL.getDebugLoc()));
}

SBFTargetLowering::SBFTargetLowering(const TargetMachine &TM,
const SBFSubtarget &STI)
: TargetLowering(TM), Subtarget(&STI) {
Expand All @@ -65,6 +54,9 @@ SBFTargetLowering::SBFTargetLowering(const TargetMachine &TM,

setStackPointerRegisterToSaveRestore(SBF::R10);

// if (STI.getHasStaticSyscalls())
// setOperationAction(ISD::TRAP, MVT::Other, Custom);

setOperationAction(ISD::BR_CC, MVT::i64, Custom);
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
setOperationAction(ISD::BRIND, MVT::Other, Expand);
Expand Down Expand Up @@ -97,6 +89,12 @@ SBFTargetLowering::SBFTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::ATOMIC_STORE, VT, Expand);
}


if (STI.getHasPqrClass() && STI.getHasAlu32()) {
setOperationAction(ISD::MULHU, MVT::i32, Expand);
setOperationAction(ISD::MULHS, MVT::i32, Expand);
}

for (auto VT : { MVT::i32, MVT::i64 }) {
if (VT == MVT::i32 && !STI.getHasAlu32())
continue;
Expand Down Expand Up @@ -333,6 +331,17 @@ SDValue SBFTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
return SDValue();
case ISD::DYNAMIC_STACKALLOC:
report_fatal_error("Unsupported dynamic stack allocation");
// case ISD::TRAP:
// {
// SDValue Callee = DAG.getConstant(1, SDLoc(Op), MVT::i64);
// SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
// SmallVector<SDValue, 2> Ops;
// Ops.push_back(Op.getOperand(0));
// Ops.push_back(Callee);
// SDValue call = DAG.getNode(SBFISD::CALL, SDLoc(Op), NodeTys, Ops);
// SDValue val = DAG.getNode(SBFISD::TRAP_RET, SDLoc(Op), MVT::Other, call);
// return val;
// }
default:
llvm_unreachable("unimplemented operation");
}
Expand Down Expand Up @@ -919,6 +928,8 @@ const char *SBFTargetLowering::getTargetNodeName(unsigned Opcode) const {
return "SBFISD::Wrapper";
case SBFISD::MEMCPY:
return "SBFISD::MEMCPY";
// case SBFISD::TRAP_RET:
// return "SBFISD::TRAP_RET";
}
return nullptr;
}
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/SBF/SBFISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ enum NodeType : unsigned {
BR_CC,
Wrapper,
MEMCPY,
// TRAP_RET,
};
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/SBF/SBFInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ def SDT_SBFMEMCPY : SDTypeProfile<0, 4, [SDTCisVT<0, i64>,
SDTCisVT<1, i64>,
SDTCisVT<2, i64>,
SDTCisVT<3, i64>]>;

def SBFcall : SDNode<"SBFISD::CALL", SDT_SBFCall,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
SDNPVariadic]>;
def SBFretglue : SDNode<"SBFISD::RET_GLUE", SDTNone,
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;

def SBFcallseq_start: SDNode<"ISD::CALLSEQ_START", SDT_SBFCallSeqStart,
[SDNPHasChain, SDNPOutGlue]>;
def SBFcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SBFCallSeqEnd,
Expand Down
32 changes: 31 additions & 1 deletion llvm/lib/Target/SBF/SBFMIPeephole.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Debug.h"
#include <set>
#include <iostream>

using namespace llvm;

Expand Down Expand Up @@ -131,6 +132,7 @@ struct SBFMIPreEmitPeephole : public MachineFunctionPass {
static char ID;
MachineFunction *MF;
const TargetRegisterInfo *TRI;
const SBFInstrInfo *TII;

SBFMIPreEmitPeephole() : MachineFunctionPass(ID) {
initializeSBFMIPreEmitPeepholePass(*PassRegistry::getPassRegistry());
Expand All @@ -141,6 +143,7 @@ struct SBFMIPreEmitPeephole : public MachineFunctionPass {
void initialize(MachineFunction &MFParm);

bool eliminateRedundantMov();
bool addReturn();

public:

Expand All @@ -151,17 +154,44 @@ struct SBFMIPreEmitPeephole : public MachineFunctionPass {

initialize(MF);

return eliminateRedundantMov();
bool Executed = false;
if (MF.getSubtarget<SBFSubtarget>().getHasStaticSyscalls())
Executed = addReturn();

return eliminateRedundantMov() || Executed;
}
};

// Initialize class variables.
void SBFMIPreEmitPeephole::initialize(MachineFunction &MFParm) {
MF = &MFParm;
TRI = MF->getSubtarget<SBFSubtarget>().getRegisterInfo();
TII = MF->getSubtarget<SBFSubtarget>().getInstrInfo();
LLVM_DEBUG(dbgs() << "*** SBF PreEmit peephole pass ***\n\n");
}

bool SBFMIPreEmitPeephole::addReturn() {
unsigned NumAdded = 0;

for (MachineBasicBlock &MBB : *MF) {
if (!MBB.succ_empty() || MBB.empty())
continue;

MachineInstr &I = MBB.back();

unsigned Opcode = I.getOpcode();
if (Opcode == SBF::JAL ||
Opcode == SBF::JALX ||
Opcode == SBF::JALX_v2 ||
Opcode == SBF::SYSCALL_v3) {
BuildMI(&MBB, I.getDebugLoc(), TII->get(SBF::RETURN_v3));
NumAdded++;
}
}

return NumAdded > 0;
}

bool SBFMIPreEmitPeephole::eliminateRedundantMov() {
MachineInstr* ToErase = nullptr;
bool Eliminated = false;
Expand Down
Loading