unsigned BytesRemaining = S.Size;
if (StartPadding) {
- dbgs() << "\n" << format("0x%016" PRIx64, LoadAddr & ~(ColsPerRow - 1)) << ":";
+ dbgs() << "\n" << format("0x%016" PRIx64,
+ LoadAddr & ~(uint64_t)(ColsPerRow - 1)) << ":";
while (StartPadding--)
dbgs() << " ";
}
// entry provides the section to which the relocation will be applied.
uint64_t Addr = Sections[i].LoadAddress;
DEBUG(dbgs() << "Resolving relocations Section #" << i << "\t"
- << format("0x%x", Addr) << "\n");
+ << format("%p", (uintptr_t)Addr) << "\n");
DEBUG(dumpSectionMemory(Sections[i], "before relocations"));
resolveRelocationList(Relocations[i], Addr);
DEBUG(dumpSectionMemory(Sections[i], "after relocations"));
}
static std::error_code getOffset(const SymbolRef &Sym, uint64_t &Result) {
- uint64_t Address;
- if (std::error_code EC = Sym.getAddress(Address))
+ ErrorOr<uint64_t> AddressOrErr = Sym.getAddress();
+ if (std::error_code EC = AddressOrErr.getError())
return EC;
+ uint64_t Address = *AddressOrErr;
- if (Address == UnknownAddressOrSize) {
- Result = UnknownAddressOrSize;
- return object_error::success;
+ if (Address == UnknownAddress) {
+ Result = UnknownAddress;
+ return std::error_code();
}
const ObjectFile *Obj = Sym.getObject();
return EC;
if (SecI == Obj->section_end()) {
- Result = UnknownAddressOrSize;
- return object_error::success;
+ Result = UnknownAddress;
+ return std::error_code();
}
uint64_t SectionAddress = SecI->getAddress();
Result = Address - SectionAddress;
- return object_error::success;
+ return std::error_code();
}
std::pair<unsigned, unsigned>
// Save information about our target
Arch = (Triple::ArchType)Obj.getArch();
IsTargetLittleEndian = Obj.isLittleEndian();
+ setMipsABI(Obj);
// Compute the memory size required to load all sections to be loaded
// and pass this information to the memory manager
if (IsCommon)
CommonSymbols.push_back(*I);
else {
- object::SymbolRef::Type SymType;
- Check(I->getType(SymType));
+ object::SymbolRef::Type SymType = I->getType();
if (SymType == object::SymbolRef::ST_Function ||
SymType == object::SymbolRef::ST_Data ||
SymType == object::SymbolRef::ST_Unknown) {
- StringRef Name;
+ ErrorOr<StringRef> NameOrErr = I->getName();
+ Check(NameOrErr.getError());
+ StringRef Name = *NameOrErr;
uint64_t SectOffset;
- Check(I->getName(Name));
Check(getOffset(*I, SectOffset));
section_iterator SI = Obj.section_end();
Check(I->getSection(SI));
return TotalSize;
}
-static bool isRequiredForExecution(const SectionRef &Section) {
+static bool isRequiredForExecution(const SectionRef Section) {
const ObjectFile *Obj = Section.getObject();
- if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj))
- return ELFObj->getSectionFlags(Section) & ELF::SHF_ALLOC;
+ if (isa<object::ELFObjectFileBase>(Obj))
+ return ELFSectionRef(Section).getFlags() & ELF::SHF_ALLOC;
if (auto *COFFObj = dyn_cast<object::COFFObjectFile>(Obj)) {
const coff_section *CoffSection = COFFObj->getCOFFSection(Section);
// Avoid loading zero-sized COFF sections.
assert(isa<MachOObjectFile>(Obj));
return true;
- }
+}
-static bool isReadOnlyData(const SectionRef &Section) {
+static bool isReadOnlyData(const SectionRef Section) {
const ObjectFile *Obj = Section.getObject();
- if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj))
- return !(ELFObj->getSectionFlags(Section) &
+ if (isa<object::ELFObjectFileBase>(Obj))
+ return !(ELFSectionRef(Section).getFlags() &
(ELF::SHF_WRITE | ELF::SHF_EXECINSTR));
if (auto *COFFObj = dyn_cast<object::COFFObjectFile>(Obj))
return ((COFFObj->getCOFFSection(Section)->Characteristics &
return false;
}
-static bool isZeroInit(const SectionRef &Section) {
+static bool isZeroInit(const SectionRef Section) {
const ObjectFile *Obj = Section.getObject();
- if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj))
- return ELFObj->getSectionType(Section) == ELF::SHT_NOBITS;
+ if (isa<object::ELFObjectFileBase>(Obj))
+ return ELFSectionRef(Section).getType() == ELF::SHT_NOBITS;
if (auto *COFFObj = dyn_cast<object::COFFObjectFile>(Obj))
return COFFObj->getCOFFSection(Section)->Characteristics &
COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
if (Name == ".eh_frame")
SectionSize += 4;
- if (SectionSize > 0) {
- // save the total size of the section
- if (IsCode) {
- CodeSectionSizes.push_back(SectionSize);
- } else if (IsReadOnly) {
- ROSectionSizes.push_back(SectionSize);
- } else {
- RWSectionSizes.push_back(SectionSize);
- }
- // update the max alignment
- if (Alignment > MaxAlignment) {
- MaxAlignment = Alignment;
- }
+ if (!SectionSize)
+ SectionSize = 1;
+
+ if (IsCode) {
+ CodeSectionSizes.push_back(SectionSize);
+ } else if (IsReadOnly) {
+ ROSectionSizes.push_back(SectionSize);
+ } else {
+ RWSectionSizes.push_back(SectionSize);
+ }
+
+ // update the max alignment
+ if (Alignment > MaxAlignment) {
+ MaxAlignment = Alignment;
}
}
}
uint32_t Flags = I->getFlags();
if (Flags & SymbolRef::SF_Common) {
// Add the common symbols to a list. We'll allocate them all below.
- uint64_t Size = 0;
- Check(I->getSize(Size));
+ uint64_t Size = I->getCommonSize();
CommonSize += Size;
}
}
DEBUG(dbgs() << "Processing common symbols...\n");
for (const auto &Sym : CommonSymbols) {
- StringRef Name;
- Check(Sym.getName(Name));
+ ErrorOr<StringRef> NameOrErr = Sym.getName();
+ Check(NameOrErr.getError());
+ StringRef Name = *NameOrErr;
// Skip common symbols already elsewhere.
if (GlobalSymbolTable.count(Name) ||
continue;
}
- uint32_t Align = 0;
- uint64_t Size = 0;
- Check(Sym.getAlignment(Align));
- Check(Sym.getSize(Size));
+ uint32_t Align = Sym.getAlignment();
+ uint64_t Size = Sym.getCommonSize();
CommonSize += Align + Size;
SymbolsToAllocate.push_back(Sym);
// Assign the address of each symbol
for (auto &Sym : SymbolsToAllocate) {
- uint32_t Align;
- uint64_t Size;
- StringRef Name;
- Check(Sym.getAlignment(Align));
- Check(Sym.getSize(Size));
- Check(Sym.getName(Name));
+ uint32_t Align = Sym.getAlignment();
+ uint64_t Size = Sym.getCommonSize();
+ ErrorOr<StringRef> NameOrErr = Sym.getName();
+ Check(NameOrErr.getError());
+ StringRef Name = *NameOrErr;
if (Align) {
// This symbol has an alignment requirement.
uint64_t AlignOffset = OffsetToAlignment((uint64_t)Addr, Align);
uint8_t *Addr;
const char *pData = nullptr;
+ // In either case, set the location of the unrelocated section in memory,
+ // since we still process relocations for it even if we're not applying them.
+ Check(Section.getContents(data));
+ // Virtual sections have no data in the object image, so leave pData = 0
+ if (!IsVirtual)
+ pData = data.data();
+
// Some sections, such as debug info, don't need to be loaded for execution.
// Leave those where they are.
if (IsRequired) {
- Check(Section.getContents(data));
Allocate = DataSize + PaddingSize + StubBufSize;
+ if (!Allocate)
+ Allocate = 1;
Addr = IsCode ? MemMgr.allocateCodeSection(Allocate, Alignment, SectionID,
Name)
: MemMgr.allocateDataSection(Allocate, Alignment, SectionID,
if (!Addr)
report_fatal_error("Unable to allocate section memory!");
- // Virtual sections have no data in the object image, so leave pData = 0
- if (!IsVirtual)
- pData = data.data();
-
// Zero-initialize or copy the data from the image
if (IsZeroInit || IsVirtual)
memset(Addr, 0, DataSize);
// and stubs for branches Thumb - ARM and ARM - Thumb.
writeBytesUnaligned(0xe51ff004, Addr, 4); // ldr pc,<label>
return Addr + 4;
- } else if (Arch == Triple::mipsel || Arch == Triple::mips) {
+ } else if (IsMipsO32ABI) {
// 0: 3c190000 lui t9,%hi(addr).
// 4: 27390000 addiu t9,t9,%lo(addr).
// 8: 03200008 jr t9.
report_fatal_error("Program used external function '" + Name +
"' which could not be resolved!");
- updateGOTEntries(Name, Addr);
- DEBUG(dbgs() << "Resolving relocations Name: " << Name << "\t"
- << format("0x%lx", Addr) << "\n");
- // This list may have been updated when we called getSymbolAddress, so
- // don't change this code to get the list earlier.
- RelocationList &Relocs = i->second;
- resolveRelocationList(Relocs, Addr);
+ // If Resolver returned UINT64_MAX, the client wants to handle this symbol
+ // manually and we shouldn't resolve its relocations.
+ if (Addr != UINT64_MAX) {
+ DEBUG(dbgs() << "Resolving relocations Name: " << Name << "\t"
+ << format("0x%lx", Addr) << "\n");
+ // This list may have been updated when we called getSymbolAddress, so
+ // don't change this code to get the list earlier.
+ RelocationList &Relocs = i->second;
+ resolveRelocationList(Relocs, Addr);
+ }
}
ExternalSymbolRelocations.erase(i);