Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 66 additions & 51 deletions include/eld/Fragment/EhFrameFragment.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,24 @@
#ifndef ELD_FRAGMENT_EHFRAMEFRAGMENT_H
#define ELD_FRAGMENT_EHFRAMEFRAGMENT_H

#include "eld/Fragment/Fragment.h"
#include "eld/Readers/EhFrameSection.h"
#include "eld/Fragment/RegionFragment.h"
#include "llvm/ADT/ArrayRef.h"
#include <string>
#include <vector>

namespace eld {

class DiagnosticEngine;
class EhFrameSection;
class EhFrameFragment;
class ELFSection;
class FDEPiece;
class LinkerConfig;
class Relocation;

class EhFramePiece {
public:
EhFramePiece(size_t Off, size_t Sz, Relocation *R, EhFrameSection *O)
: MOffset(Off), ThisSize(Sz), MRelocation(R), MSection(O) {}
EhFramePiece(size_t Off, size_t Sz, Relocation *R)
: MOffset(Off), ThisSize(Sz), MRelocation(R) {}

size_t getSize() const { return ThisSize; }

Expand All @@ -37,98 +38,112 @@ class EhFramePiece {

Relocation *getRelocation() const { return MRelocation; }

EhFrameSection *getOwningSection() const { return MSection; }
llvm::ArrayRef<uint8_t> getData(llvm::StringRef Region) const;

llvm::ArrayRef<uint8_t> getData();
uint8_t readByte(DiagnosticEngine *DiagEngine, const ELFSection &S);

uint8_t readByte(DiagnosticEngine *DiagEngine);
void skipBytes(size_t Count, DiagnosticEngine *DiagEngine,
const ELFSection &S);

void skipBytes(size_t Count, DiagnosticEngine *DiagEngine);
llvm::StringRef readString(DiagnosticEngine *DiagEngine, const ELFSection &S);

llvm::StringRef readString(DiagnosticEngine *DiagEngine);

void skipLeb128(DiagnosticEngine *DiagEngine);
void skipLeb128(DiagnosticEngine *DiagEngine, const ELFSection &S);

size_t getAugPSize(unsigned Enc, bool Is64Bit, DiagnosticEngine *DiagEngine);

void skipAugP(bool Is64Bit, DiagnosticEngine *DiagEngine);
void skipAugP(bool Is64Bit, DiagnosticEngine *DiagEngine,
const ELFSection &S);

uint8_t getFdeEncoding(bool Is64Bit, DiagnosticEngine *DiagEngine);
uint8_t getFdeEncoding(llvm::StringRef Region, bool Is64Bit,
DiagnosticEngine *DiagEngine, const ELFSection &S);

private:
llvm::ArrayRef<uint8_t> D;
size_t MOffset = 0;
size_t MOutputOffset = -1;
size_t ThisSize = 0;
Relocation *MRelocation = nullptr;
EhFrameSection *MSection = nullptr;
};

class FDEFragment : public Fragment {
class EhFrameCIE {
public:
FDEFragment(EhFramePiece &P, EhFrameSection *O);
explicit EhFrameCIE(EhFramePiece &P) : CIE(P) {}

virtual ~FDEFragment();
const std::string name() const { return "CIE"; }

/// name - name of this stub
const std::string name() const;
size_t size() const;

virtual size_t size() const override;
EhFramePiece &getCIE() { return CIE; }

llvm::ArrayRef<uint8_t> getContent() const;
const EhFramePiece &getCIE() const { return CIE; }

static bool classof(const Fragment *F) {
return F->getKind() == Fragment::Type::FDE;
}
llvm::ArrayRef<uint8_t> getContent(const EhFrameFragment &F) const;

virtual eld::Expected<void> emit(MemoryRegion &Mr, Module &M) override;
eld::Expected<void> emit(MemoryRegion &Mr, Module &M, uint32_t CieOff,
const EhFrameFragment &F);

virtual void dump(llvm::raw_ostream &OS) override;
void dump(llvm::raw_ostream &OS) {}

EhFramePiece &getFDE() { return FDE; }
void appendFDE(FDEPiece *F) { FDEs.push_back(F); }

const std::vector<FDEPiece *> &getFDEs() const { return FDEs; }

void setOffset(uint32_t CieOff);

size_t getSize() const;
size_t getNumFDE() const { return FDEs.size(); }

uint8_t getFdeEncoding(const EhFrameFragment &F, bool Is64Bit,
DiagnosticEngine *DiagEngine);

private:
EhFramePiece &FDE;
EhFramePiece &CIE;
std::vector<FDEPiece *> FDEs;
};

class CIEFragment : public Fragment {
class EhFrameFragment : public RegionFragment {
public:
CIEFragment(EhFramePiece &P, EhFrameSection *O);
EhFrameFragment(llvm::StringRef Region, ELFSection *O, uint32_t Align = 1)
: RegionFragment(Region, O, Fragment::Type::Region, Align) {}

virtual ~CIEFragment();
EhFramePiece &addPiece(size_t Off, size_t Sz, Relocation *R);

/// name - name of this stub
const std::string name() const;
std::vector<EhFramePiece> &getPieces() { return Pieces; }
const std::vector<EhFramePiece> &getPieces() const { return Pieces; }

virtual size_t size() const override;
std::vector<EhFrameCIE *> &getCIEs() { return CIEs; }
const std::vector<EhFrameCIE *> &getCIEs() const { return CIEs; }

llvm::ArrayRef<uint8_t> getContent() const;
size_t size() const override;

static bool classof(const Fragment *F) {
return F->getKind() == Fragment::CIE;
}
void setOffset(uint32_t O) override;

static bool classof(const CIEFragment *) { return true; }
eld::Expected<void> emit(MemoryRegion &Mr, Module &M) override;

virtual eld::Expected<void> emit(MemoryRegion &Mr, Module &M) override;
void dump(llvm::raw_ostream &OS) override;

virtual void dump(llvm::raw_ostream &OS) override;
private:
std::vector<EhFramePiece> Pieces;
std::vector<EhFrameCIE *> CIEs;
};

void appendFragment(FDEFragment *F) { FDEs.push_back(F); }
class FDEPiece {
public:
explicit FDEPiece(EhFramePiece &P) : FDE(P) {}

const std::vector<FDEFragment *> &getFDEs() const { return FDEs; }
size_t size() const { return FDE.getSize(); }

void setOffset(uint32_t Offset) override;
llvm::ArrayRef<uint8_t> getContent(const EhFrameFragment &F) const {
return FDE.getData(F.getRegion());
}

size_t getNumFDE() const { return FDEs.size(); }
eld::Expected<void> emit(MemoryRegion &Mr, Module &M,
const EhFrameFragment &F);

uint8_t getFdeEncoding(bool Is64Bit, DiagnosticEngine *DiagEngine);
EhFramePiece &getFDE() { return FDE; }
const EhFramePiece &getFDE() const { return FDE; }

protected:
EhFramePiece &CIE;
std::vector<FDEFragment *> FDEs;
private:
EhFramePiece &FDE;
};

} // namespace eld
Expand Down
6 changes: 3 additions & 3 deletions include/eld/Fragment/EhFrameHdrFragment.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
namespace eld {

class DiagnosticEngine;
class EhFrameFragment;
class EhFrameHdrSection;
class LinkerConfig;
class CIEFragment;
class FDEFragment;
class FDEPiece;
class Relocation;

class EhFrameHdrFragment : public Fragment {
Expand Down Expand Up @@ -56,7 +56,7 @@ class EhFrameHdrFragment : public Fragment {

uint64_t readFdeAddr(uint8_t *Buf, int Size, DiagnosticEngine *DiagEngine);

uint64_t getFdePc(uint8_t *, FDEFragment *, uint8_t Enc,
uint64_t getFdePc(uint8_t *, const EhFrameFragment &, FDEPiece *, uint8_t Enc,
DiagnosticEngine *DiagEngine);

bool Is64Bit = false;
Expand Down
8 changes: 4 additions & 4 deletions include/eld/Readers/EhFrameHdrSection.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace eld {

class DiagnosticEngine;
class ELFSection;
class CIEFragment;
class EhFrameFragment;
class EhFrameHdrFragment;

class EhFrameHdrSection : public ELFSection {
Expand All @@ -27,18 +27,18 @@ class EhFrameHdrSection : public ELFSection {
return S->getSectionKind() == Section::Kind::EhFrameHdr;
}

void addCIE(std::vector<CIEFragment *> &C);
void addEhFrame(EhFrameFragment &F);

size_t getNumCIE() const { return NumCIE; }

size_t getNumFDE() const { return NumFDE; }

size_t sizeOfHeader() const { return 12; }

std::vector<CIEFragment *> &getCIEs() { return m_CIEs; }
const std::vector<EhFrameFragment *> &getEhFrames() const { return EhFrames; }

private:
std::vector<CIEFragment *> m_CIEs;
std::vector<EhFrameFragment *> EhFrames;
size_t NumCIE = 0;
size_t NumFDE = 0;
};
Expand Down
22 changes: 6 additions & 16 deletions include/eld/Readers/EhFrameSection.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ class DiagnosticPrinter;
class ELFSection;
class Module;
class Relocation;
class RegionFragment;
class EhFrameSection;
class CIEFragment;
class EhFrameCIE;
class EhFramePiece;
class EhFrameFragment;

class EhFrameSection : public ELFSection {
public:
Expand All @@ -36,34 +36,24 @@ class EhFrameSection : public ELFSection {

Relocation *getReloc(size_t Off, size_t Size);

RegionFragment *getEhFrameFragment() const { return m_EhFrame; }
EhFrameFragment *getEhFrameFragment() const { return m_EhFrame; }

llvm::ArrayRef<uint8_t> getData() const { return Data; }
llvm::ArrayRef<uint8_t> getData() const;

bool createCIEAndFDEFragments();

CIEFragment *addCie(EhFramePiece &P);
EhFrameCIE *addCie(EhFramePiece &P);

bool isFdeLive(EhFramePiece &P);

std::vector<EhFramePiece> &getPieces() { return m_EhFramePieces; }

std::vector<CIEFragment *> &getCIEs() { return m_CIEFragments; }

void finishAddingFragments(Module &M);

private:
size_t readEhRecordSize(size_t Off);
DiagnosticPrinter *getDiagPrinter();

private:
RegionFragment *m_EhFrame = nullptr;
llvm::ArrayRef<uint8_t> Data;
std::vector<EhFramePiece> m_EhFramePieces;
llvm::DenseMap<size_t, CIEFragment *> m_OffsetToCie;
std::vector<CIEFragment *> m_CIEFragments;
size_t NumCie = 0;
size_t NumFDE = 0;
EhFrameFragment *m_EhFrame = nullptr;
DiagnosticEngine *m_DiagEngine = nullptr;
};
} // namespace eld
Expand Down
Loading
Loading