Skip to content
Draft
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
39 changes: 0 additions & 39 deletions include/eld/Target/ARMEXIDXSection.h

This file was deleted.

3 changes: 0 additions & 3 deletions lib/Object/SectionMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#include "eld/Script/WildcardPattern.h"
#include "eld/Support/Memory.h"
#include "eld/Support/MsgHandling.h"
#include "eld/Target/ARMEXIDXSection.h"
#include "eld/Target/ELFSegment.h"
#include "eld/Target/GNULDBackend.h"
#include "llvm/ADT/Hashing.h"
Expand Down Expand Up @@ -537,8 +536,6 @@ ELFSection *SectionMap::createOutputSectionEntry(std::string Section,
ELFSection *SectionMap::createELFSection(const std::string &Name,
LDFileFormat::Kind K, uint32_t Type,
uint32_t Flags, uint32_t EntSize) {
if (Type == llvm::ELF::SHT_ARM_EXIDX && K == LDFileFormat::Target)
return make<ARMEXIDXSection>(Name, Flags, EntSize, /*Size=*/0, /*PAddr=*/0);
return make<ELFSection>(K, Name, Flags, EntSize, /*AddrAlign=*/0, Type,
/*Info=*/0,
/*Link=*/nullptr,
Expand Down
124 changes: 124 additions & 0 deletions lib/Target/ARM/ARMEXIDXFragment.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
//===- ARMEXIDXFragment.cpp------------------------------------------------===//
// Part of the eld Project, under the BSD License
// See https://github.com/qualcomm/eld/LICENSE.txt for license information.
// SPDX-License-Identifier: BSD-3-Clause
//===----------------------------------------------------------------------===//

#include "ARMEXIDXFragment.h"
#include "eld/Diagnostics/MsgHandler.h"
#include "eld/Readers/ELFSection.h"
#include "eld/Readers/Relocation.h"
#include "eld/SymbolResolver/ResolveInfo.h"
#include <cstring>

using namespace eld;

EXIDXPiece EXIDXFragment::getPiece(uint32_t Offset) const {
ASSERT(getOwningSection(), "EXIDX fragment must have an owning section");
ASSERT(Offset < getOwningSection()->size(),
"Exception on .ARM.exidx relocation handling");
for (const EXIDXPiece &P : Pieces)
if (P.InputOffset <= Offset && Offset < P.InputOffset + P.Size)
return P;
ASSERT(false, "Unable to map relocation to EXIDX piece range");
return {};
}

uint32_t EXIDXFragment::translateInputOffset(uint32_t InputOffset) const {
uint32_t OutputOffset = 0;
for (const EXIDXPiece &P : Pieces) {
if (P.InputOffset <= InputOffset && InputOffset < P.InputOffset + P.Size)
return OutputOffset + (InputOffset - P.InputOffset);
OutputOffset += P.Size;
}
ASSERT(false, "Unable to translate EXIDX relocation offset to piece");
return 0;
}

size_t EXIDXFragment::size() const {
size_t Total = 0;
for (const EXIDXPiece &P : Pieces)
Total += P.Size;
return Total;
}

void EXIDXFragment::dump(llvm::raw_ostream &OS) {
if (Pieces.empty())
return;

ELFSection *S = getOwningSection();
const bool IsGC = S && (S->isIgnore() || S->isDiscard());
ELFSection *OutSection = getOutputELFSection();
const uint64_t SectionAddr = OutSection ? OutSection->addr() : 0;
const uint64_t FragmentOutputOffset = hasOffset() ? getOffset() : 0;
const uint64_t FragmentOutputAddr = SectionAddr + FragmentOutputOffset;

OS << "#EXIDX";
OS << "\tsec=0x";
OS.write_hex(FragmentOutputAddr);
OS << "\tsz=0x";
OS.write_hex(size());
OS << "\tn=" << Pieces.size();
if (IsGC)
OS << "\t<GC>";
OS << "\n";

for (size_t I = 0; I < Pieces.size(); ++I) {
const EXIDXPiece &Piece = Pieces[I];
OS << "#P[" << I << "]";
OS << "\toff=0x";
OS.write_hex(Piece.InputOffset);
OS << "\taddr=0x";
OS.write_hex(FragmentOutputAddr + Piece.InputOffset);
OS << "\tsz=0x";
OS.write_hex(Piece.Size);
if (IsGC)
OS << "\t<GC>";
OS << "\n";

if (!S)
continue;

for (Relocation *R : S->getRelocations()) {
if (!R || !R->targetRef() || R->targetRef()->isNull())
continue;
if (R->targetRef()->frag() != this)
continue;

const uint32_t RelInputOffset = R->targetRef()->offset();
if (RelInputOffset < Piece.InputOffset ||
RelInputOffset >= Piece.InputOffset + Piece.Size)
continue;

OS << "#R";
if (ResolveInfo *Sym = R->symInfo())
OS << "\tsym=" << Sym->name();
OS << "\tadd=0x";
OS.write_hex(R->addend());
if (IsGC)
OS << "\t<GC>";
OS << "\n";
}
}
}

eld::Expected<void> EXIDXFragment::emit(MemoryRegion &Mr, Module &) {
if (Pieces.empty())
return {};

llvm::StringRef Region = getRegion();
uint32_t BaseOffset = getOffset();
uint32_t OutOffset = 0;
for (const EXIDXPiece &Piece : Pieces) {
const uint32_t Begin = Piece.InputOffset;
const uint32_t PieceSize = Piece.Size;
ASSERT(Begin + PieceSize <= Region.size(),
"Invalid EXIDX piece boundaries");
if (!PieceSize)
continue;
std::memcpy(Mr.begin() + BaseOffset + OutOffset, Region.data() + Begin,
PieceSize);
OutOffset += PieceSize;
}
return {};
}
45 changes: 45 additions & 0 deletions lib/Target/ARM/ARMEXIDXFragment.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//===- ARMEXIDXFragment.h--------------------------------------------------===//
// Part of the eld Project, under the BSD License
// See https://github.com/qualcomm/eld/LICENSE.txt for license information.
// SPDX-License-Identifier: BSD-3-Clause
//===----------------------------------------------------------------------===//

#ifndef TARGET_ARM_ARMEXIDXFRAGMENT_H
#define TARGET_ARM_ARMEXIDXFRAGMENT_H

#include "eld/Fragment/RegionFragment.h"
#include "llvm/ADT/SmallVector.h"
#include <cstdint>

namespace eld {

struct EXIDXPiece {
uint32_t InputOffset = UINT32_MAX;
uint32_t Size = 0;
};

class EXIDXFragment : public RegionFragment {
public:
EXIDXFragment(llvm::StringRef Region, ELFSection *O, uint32_t Align = 1)
: RegionFragment(Region, O, Fragment::Type::Region, Align) {}

~EXIDXFragment() override = default;

void addPiece(EXIDXPiece P) { Pieces.push_back(P); }

llvm::SmallVectorImpl<EXIDXPiece> &getPieces() { return Pieces; }
const llvm::SmallVectorImpl<EXIDXPiece> &getPieces() const { return Pieces; }

EXIDXPiece getPiece(uint32_t Offset) const;
uint32_t translateInputOffset(uint32_t InputOffset) const;
size_t size() const override;
void dump(llvm::raw_ostream &OS) override;
eld::Expected<void> emit(MemoryRegion &Mr, Module &M) override;

private:
llvm::SmallVector<EXIDXPiece, 0> Pieces;
};

} // namespace eld

#endif
25 changes: 0 additions & 25 deletions lib/Target/ARM/ARMEXIDXSection.cpp

This file was deleted.

Loading
Loading