}
uint64_t patchOff = 0;
- const uint8_t *buf = isec->data().begin();
+ const uint8_t *buf = isec->rawData.begin();
const ulittle32_t *instBuf = reinterpret_cast<const ulittle32_t *>(buf + off);
uint32_t instr1 = *instBuf++;
uint32_t instr2 = *instBuf++;
void Patch843419Section::writeTo(uint8_t *buf) {
// Copy the instruction that we will be replacing with a branch in the
// patchee Section.
- write32le(buf, read32le(patchee->data().begin() + patcheeOffset));
+ write32le(buf, read32le(patchee->rawData.begin() + patcheeOffset));
// Apply any relocation transferred from the original patchee section.
relocateAlloc(buf, buf + getSize());
auto dataSym = std::next(codeSym);
uint64_t off = (*codeSym)->value;
uint64_t limit =
- (dataSym == mapSyms.end()) ? isec->data().size() : (*dataSym)->value;
+ (dataSym == mapSyms.end()) ? isec->rawData.size() : (*dataSym)->value;
while (off < limit) {
uint64_t startAddr = isec->getVA(off);
}
ScanResult scanRes = {0, 0, nullptr};
- const uint8_t *buf = isec->data().begin();
+ const uint8_t *buf = isec->rawData.begin();
// ARMv7-A Thumb 32-bit instructions are encoded 2 consecutive
// little-endian halfwords.
const ulittle16_t *instBuf = reinterpret_cast<const ulittle16_t *>(buf + off);
while (thumbSym != mapSyms.end()) {
auto nonThumbSym = std::next(thumbSym);
uint64_t off = (*thumbSym)->value;
- uint64_t limit = (nonThumbSym == mapSyms.end()) ? isec->data().size()
+ uint64_t limit = (nonThumbSym == mapSyms.end()) ? isec->rawData.size()
: (*nonThumbSym)->value;
while (off < limit) {
Relocation &r = is.relocations[rIndex];
// Check if the relocation corresponds to a direct jmp.
- const uint8_t *secContents = is.data().data();
+ const uint8_t *secContents = is.rawData.data();
// If it is not a direct jmp instruction, there is nothing to do here.
if (*(secContents + r.offset - 1) != 0xe9)
return false;
if (!isa<Defined>(sym) || !sym->includeInDynsym())
return;
- StringRef partName = reinterpret_cast<const char *>(s->data().data());
+ StringRef partName = reinterpret_cast<const char *>(s->rawData.data());
for (Partition &part : partitions) {
if (part.name == partName) {
sym->partition = part.getNumber();
private:
template <class P> void failOn(const P *loc, const Twine &msg) {
fatal("corrupted .eh_frame: " + msg + "\n>>> defined in " +
- isec->getObjMsg((const uint8_t *)loc - isec->data().data()));
+ isec->getObjMsg((const uint8_t *)loc - isec->rawData.data()));
}
uint8_t readByte();
template <class ELFT>
bool ICF<ELFT>::equalsConstant(const InputSection *a, const InputSection *b) {
if (a->flags != b->flags || a->getSize() != b->getSize() ||
- a->data() != b->data())
+ a->rawData != b->rawData)
return false;
// If two sections have different output sections, we cannot merge them.
// Initially, we use hash values to partition sections.
parallelForEach(sections, [&](InputSection *s) {
// Set MSB to 1 to avoid collisions with unique IDs.
- s->eqClass[0] = xxHash64(s->data()) | (1U << 31);
+ s->eqClass[0] = xxHash64(s->rawData) | (1U << 31);
});
// Perform 2 rounds of relocation hash propagation. 2 is an empirical value to
using Elf_Note = typename ELFT::Note;
uint32_t featuresSet = 0;
- ArrayRef<uint8_t> data = sec.data();
+ ArrayRef<uint8_t> data = sec.rawData;
auto reportFatal = [&](const uint8_t *place, const char *msg) {
fatal(toString(sec.file) + ":(" + sec.name + "+0x" +
- Twine::utohexstr(place - sec.data().data()) + "): " + msg);
+ Twine::utohexstr(place - sec.rawData.data()) + "): " + msg);
};
while (!data.empty()) {
// Read one NOTE record.
void InputSection::copyRelocations(uint8_t *buf, ArrayRef<RelTy> rels) {
const TargetInfo &target = *elf::target;
InputSectionBase *sec = getRelocatedSection();
+ (void)sec->data(); // uncompress if needed
for (const RelTy &rel : rels) {
RelType type = rel.getType(config->isMips64EL);
}
int64_t addend = getAddend<ELFT>(rel);
- const uint8_t *bufLoc = sec->data().begin() + rel.r_offset;
+ const uint8_t *bufLoc = sec->rawData.begin() + rel.r_offset;
if (!RelTy::IsRela)
addend = target.getImplicitAddend(bufLoc, type);
}
SectionPiece *MergeInputSection::getSectionPiece(uint64_t offset) {
- if (this->data().size() <= offset)
+ if (this->rawData.size() <= offset)
fatal(toString(this) + ": offset is outside the section");
// If Offset is not at beginning of a section piece, it is not in the map.
template <typename T> llvm::ArrayRef<T> getDataAs() const {
- size_t s = data().size();
+ size_t s = rawData.size();
assert(s % sizeof(T) == 0);
- return llvm::makeArrayRef<T>((const T *)data().data(), s / sizeof(T));
+ return llvm::makeArrayRef<T>((const T *)rawData.data(), s / sizeof(T));
}
+ mutable ArrayRef<uint8_t> rawData;
+
protected:
template <typename ELFT>
void parseCompressedHeader();
void uncompress() const;
- mutable ArrayRef<uint8_t> rawData;
-
// This field stores the uncompressed size of the compressed data in rawData,
// or -1 if rawData is not compressed (either because the section wasn't
// compressed in the first place, or because we ended up uncompressing it).
llvm::CachedHashStringRef getData(size_t i) const {
size_t begin = pieces[i].inputOff;
size_t end =
- (pieces.size() - 1 == i) ? data().size() : pieces[i + 1].inputOff;
- return {toStringRef(data().slice(begin, end - begin)), pieces[i].hash};
+ (pieces.size() - 1 == i) ? rawData.size() : pieces[i + 1].inputOff;
+ return {toStringRef(rawData.slice(begin, end - begin)), pieces[i].hash};
}
// Returns the SectionPiece at a given input section offset.
: inputOff(off), sec(sec), size(size), firstRelocation(firstRelocation) {}
ArrayRef<uint8_t> data() const {
- return {sec->data().data() + this->inputOff, size};
+ return {sec->rawData.data() + this->inputOff, size};
}
size_t inputOff;
template <class ELFT>
static uint64_t getAddend(InputSectionBase &sec,
const typename ELFT::Rel &rel) {
- return target->getImplicitAddend(sec.data().begin() + rel.r_offset,
+ return target->getImplicitAddend(sec.rawData.begin() + rel.r_offset,
rel.getType(config->isMips64EL));
}
if (pairTy == R_MIPS_NONE)
return 0;
- const uint8_t *buf = sec.data().data();
+ const uint8_t *buf = sec.rawData.data();
uint32_t symIndex = rel.getSymbol(config->isMips64EL);
// To make things worse, paired relocations might not be contiguous in
if (RelTy::IsRela) {
addend = getAddend<ELFT>(rel);
} else {
- const uint8_t *buf = sec.data().data();
+ const uint8_t *buf = sec.rawData.data();
addend = target.getImplicitAddend(buf + rel.r_offset, type);
}
maybeReportUndefined(cast<Undefined>(sym), sec, offset))
return;
- const uint8_t *relocatedAddr = sec.data().begin() + offset;
+ const uint8_t *relocatedAddr = sec.rawData.begin() + offset;
RelExpr expr = target.getRelExpr(type, sym, relocatedAddr);
// Ignore R_*_NONE and other marker relocations.
create = true;
std::string filename = toString(sec->file);
- const size_t size = sec->data().size();
+ const size_t size = sec->rawData.size();
// Older version of BFD (such as the default FreeBSD linker) concatenate
// .MIPS.abiflags instead of merging. To allow for this case (or potential
// zero padding) we ignore everything after the first Elf_Mips_ABIFlags
Twine(size) + " instead of " + Twine(sizeof(Elf_Mips_ABIFlags)));
return nullptr;
}
- auto *s = reinterpret_cast<const Elf_Mips_ABIFlags *>(sec->data().data());
+ auto *s = reinterpret_cast<const Elf_Mips_ABIFlags *>(sec->rawData.data());
if (s->version != 0) {
error(filename + ": unexpected .MIPS.abiflags version " +
Twine(s->version));
sec->markDead();
std::string filename = toString(sec->file);
- ArrayRef<uint8_t> d = sec->data();
+ ArrayRef<uint8_t> d = sec->rawData;
while (!d.empty()) {
if (d.size() < sizeof(Elf_Mips_Options)) {
for (InputSectionBase *sec : sections) {
sec->markDead();
- if (sec->data().size() != sizeof(Elf_Mips_RegInfo)) {
+ if (sec->rawData.size() != sizeof(Elf_Mips_RegInfo)) {
error(toString(sec->file) + ": invalid size of .reginfo section");
return nullptr;
}
- auto *r = reinterpret_cast<const Elf_Mips_RegInfo *>(sec->data().data());
+ auto *r = reinterpret_cast<const Elf_Mips_RegInfo *>(sec->rawData.data());
reginfo.ri_gprmask |= r->ri_gprmask;
sec->getFile<ELFT>()->mipsGp0 = r->ri_gp_value;
};
for (InputSection *isec : executableSections) {
assert(isec->getParent() != nullptr);
if (InputSection *d = findExidxSection(isec)) {
- memcpy(buf + offset, d->data().data(), d->data().size());
+ memcpy(buf + offset, d->rawData.data(), d->rawData.size());
d->relocateAlloc(buf + d->outSecOff, buf + d->outSecOff + d->getSize());
offset += d->getSize();
} else {
if (!inputSec || !inputSec->bytesDropped)
return;
- const size_t OldSize = inputSec->data().size();
+ const size_t OldSize = inputSec->rawData.size();
const size_t NewSize = OldSize - inputSec->bytesDropped;
if (def->value > NewSize && def->value <= OldSize) {