Mercurial > hg > CbC > CbC_llvm
diff lld/MachO/InputSection.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | 5f17cb93ff66 |
line wrap: on
line diff
--- a/lld/MachO/InputSection.cpp Mon May 25 11:55:54 2020 +0900 +++ b/lld/MachO/InputSection.cpp Tue Jun 08 06:07:14 2021 +0900 @@ -7,12 +7,16 @@ //===----------------------------------------------------------------------===// #include "InputSection.h" +#include "InputFiles.h" #include "OutputSegment.h" #include "Symbols.h" +#include "SyntheticSections.h" #include "Target.h" +#include "Writer.h" #include "lld/Common/Memory.h" #include "llvm/Support/Endian.h" +using namespace llvm; using namespace llvm::MachO; using namespace llvm::support; using namespace lld; @@ -24,27 +28,86 @@ return parent->fileOff + outSecFileOff; } +uint64_t InputSection::getFileSize() const { + return isZeroFill(flags) ? 0 : getSize(); +} + uint64_t InputSection::getVA() const { return parent->addr + outSecOff; } +static uint64_t resolveSymbolVA(const Symbol *sym, uint8_t type) { + const RelocAttrs &relocAttrs = target->getRelocAttrs(type); + if (relocAttrs.hasAttr(RelocAttrBits::BRANCH)) + return sym->resolveBranchVA(); + else if (relocAttrs.hasAttr(RelocAttrBits::GOT)) + return sym->resolveGotVA(); + else if (relocAttrs.hasAttr(RelocAttrBits::TLV)) + return sym->resolveTlvVA(); + return sym->getVA(); +} + void InputSection::writeTo(uint8_t *buf) { - if (!data.empty()) - memcpy(buf, data.data(), data.size()); + assert(!shouldOmitFromOutput()); + + if (getFileSize() == 0) + return; + + memcpy(buf, data.data(), data.size()); - for (Reloc &r : relocs) { - uint64_t va = 0; - if (auto *s = r.target.dyn_cast<Symbol *>()) { - if (auto *dylibSymbol = dyn_cast<DylibSymbol>(s)) { - va = target->getDylibSymbolVA(*dylibSymbol, r.type); - } else { - va = s->getVA(); + for (size_t i = 0; i < relocs.size(); i++) { + const Reloc &r = relocs[i]; + uint8_t *loc = buf + r.offset; + uint64_t referentVA = 0; + if (target->hasAttr(r.type, RelocAttrBits::SUBTRAHEND)) { + const Symbol *fromSym = r.referent.get<Symbol *>(); + const Reloc &minuend = relocs[++i]; + uint64_t minuendVA; + if (const Symbol *toSym = minuend.referent.dyn_cast<Symbol *>()) + minuendVA = toSym->getVA(); + else { + auto *referentIsec = minuend.referent.get<InputSection *>(); + assert(!referentIsec->shouldOmitFromOutput()); + minuendVA = referentIsec->getVA(); } - } else if (auto *isec = r.target.dyn_cast<InputSection *>()) { - va = isec->getVA(); - } + referentVA = minuendVA - fromSym->getVA() + minuend.addend; + } else if (auto *referentSym = r.referent.dyn_cast<Symbol *>()) { + if (target->hasAttr(r.type, RelocAttrBits::LOAD) && + !referentSym->isInGot()) + target->relaxGotLoad(loc, r.type); + referentVA = resolveSymbolVA(referentSym, r.type); - uint64_t val = va + r.addend; - if (r.pcrel) - val -= getVA() + r.offset; - target->relocateOne(buf + r.offset, r.type, val); + if (isThreadLocalVariables(flags)) { + // References from thread-local variable sections are treated as offsets + // relative to the start of the thread-local data memory area, which + // is initialized via copying all the TLV data sections (which are all + // contiguous). + if (isa<Defined>(referentSym)) + referentVA -= firstTLVDataSection->addr; + } + } else if (auto *referentIsec = r.referent.dyn_cast<InputSection *>()) { + assert(!referentIsec->shouldOmitFromOutput()); + referentVA = referentIsec->getVA(); + } + target->relocateOne(loc, r, referentVA + r.addend, getVA() + r.offset); } } + +bool macho::isCodeSection(const InputSection *isec) { + uint32_t type = isec->flags & SECTION_TYPE; + if (type != S_REGULAR && type != S_COALESCED) + return false; + + uint32_t attr = isec->flags & SECTION_ATTRIBUTES_USR; + if (attr == S_ATTR_PURE_INSTRUCTIONS) + return true; + + if (isec->segname == segment_names::text) + return StringSwitch<bool>(isec->name) + .Cases(section_names::textCoalNt, section_names::staticInit, true) + .Default(false); + + return false; +} + +std::string lld::toString(const InputSection *isec) { + return (toString(isec->file) + ":(" + isec->name + ")").str(); +}