Skip to content
Merged
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
34 changes: 20 additions & 14 deletions amd/comgr/src/comgr-hotswap-b0a0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,22 @@ static void runScratchVerification(WritableMemoryBuffer &OutBuf,
<< "scratch conflicts\n";
}

static std::unique_ptr<WritableMemoryBuffer>
copyOutputBuffer(const void *Data, size_t Size, StringRef CopyKind) {
std::unique_ptr<WritableMemoryBuffer> Result =
WritableMemoryBuffer::getNewUninitMemBuffer(Size);
if (!Result) {
log() << "hotswap: error: retargetCodeObject: "
<< "getNewUninitMemBuffer(" << Size
<< ") failed (out of memory) for the " << CopyKind
<< " output copy.\n";
return nullptr;
}

std::memcpy(Result->getBufferStart(), Data, Size);
return Result;
}

// -- retargetCodeObject -------------------------------------------------------

amd_comgr_status_t retargetCodeObject(const void *ElfData, size_t ElfSize,
Expand All @@ -535,14 +551,9 @@ amd_comgr_status_t retargetCodeObject(const void *ElfData, size_t ElfSize,

if (!Options.RunB0A0Patches && !Options.RunEntryTrampolines) {
std::unique_ptr<WritableMemoryBuffer> Result =
WritableMemoryBuffer::getNewUninitMemBuffer(ElfSize);
if (!Result) {
log() << "hotswap: error: retargetCodeObject: "
<< "getNewUninitMemBuffer(" << ElfSize
<< ") failed (out of memory) for the no-op output copy.\n";
copyOutputBuffer(ElfData, ElfSize, "no-op");
if (!Result)
return AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES;
}
std::memcpy(Result->getBufferStart(), ElfData, ElfSize);
Out = std::move(Result);
return AMD_COMGR_STATUS_SUCCESS;
}
Expand Down Expand Up @@ -638,14 +649,9 @@ amd_comgr_status_t retargetCodeObject(const void *ElfData, size_t ElfSize,
EntryFixups))
return AMD_COMGR_STATUS_ERROR;
} else {
Result = WritableMemoryBuffer::getNewUninitMemBuffer(ElfSize);
if (!Result) {
log() << "hotswap: error: retargetCodeObject: "
<< "getNewUninitMemBuffer(" << ElfSize
<< ") failed (out of memory) for the patched output copy.\n";
Result = copyOutputBuffer(Buf.data(), ElfSize, "patched");
if (!Result)
return AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES;
}
std::memcpy(Result->getBufferStart(), Buf.data(), ElfSize);
}

if (!ScratchPatches.empty())
Expand Down
51 changes: 20 additions & 31 deletions amd/comgr/src/comgr-hotswap-elf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/MsgPackDocument.h"
#include "llvm/Support/CheckedArithmetic.h"

#include <algorithm>
#include <limits>
Expand All @@ -42,16 +41,6 @@ enum class MetadataSgprUpdateStatus {
Error,
};

static std::optional<uint64_t> checkedAdd(uint64_t LHS, uint64_t RHS,
StringRef Context) {
std::optional<uint64_t> Result = checkedAddUnsigned(LHS, RHS);
if (Result)
return Result;

log() << "hotswap: error: " << Context << " overflows uint64_t.\n";
return std::nullopt;
}

static std::optional<size_t>
checkedAlignToSize(size_t Value, uint64_t Alignment, StringRef Context) {
if (Alignment <= 1)
Expand All @@ -61,7 +50,7 @@ checkedAlignToSize(size_t Value, uint64_t Alignment, StringRef Context) {
if (Remainder == 0)
return Value;
std::optional<uint64_t> Aligned =
checkedAdd(Value64, Alignment - Remainder, Context);
checkedAddUint64(Value64, Alignment - Remainder, Context);
if (!Aligned)
return std::nullopt;
if (*Aligned > static_cast<uint64_t>(std::numeric_limits<size_t>::max())) {
Expand All @@ -84,8 +73,8 @@ static std::optional<uint64_t> checkedSectionFileOffset(const ELFT::Shdr &Sec,
}

uint64_t Delta = VAddr - Sec.sh_addr;
std::optional<uint64_t> FileOffset =
checkedAdd(Sec.sh_offset, Delta, (Twine(Context) + " file offset").str());
std::optional<uint64_t> FileOffset = checkedAddUint64(
Sec.sh_offset, Delta, (Twine(Context) + " file offset").str());
if (!FileOffset)
return std::nullopt;

Expand Down Expand Up @@ -837,7 +826,7 @@ static bool adjustSectionHeaders(uint8_t *Elf, size_t ElfSize,
return true;

std::optional<uint64_t> TextEnd =
checkedAdd(TextOffset, TextSize, "section header .text end");
checkedAddUint64(TextOffset, TextSize, "section header .text end");
if (!TextEnd)
return false;
uint64_t Shoff;
Expand All @@ -851,7 +840,7 @@ static bool adjustSectionHeaders(uint8_t *Elf, size_t ElfSize,

if (Shoff >= *TextEnd) {
std::optional<uint64_t> NewShoff =
checkedAdd(Shoff, TrampTotal, "section header table offset");
checkedAddUint64(Shoff, TrampTotal, "section header table offset");
if (!NewShoff)
return false;
uint64_t NewShoffValue = *NewShoff;
Expand All @@ -863,7 +852,7 @@ static bool adjustSectionHeaders(uint8_t *Elf, size_t ElfSize,
for (uint16_t I = 0; I < Shnum; ++I) {
uint64_t ShTableDelta = static_cast<uint64_t>(I) * Shentsize;
std::optional<uint64_t> ShPos =
checkedAdd(Shoff, ShTableDelta, "section header entry offset");
checkedAddUint64(Shoff, ShTableDelta, "section header entry offset");
if (!ShPos)
return false;
if (*ShPos > ElfSize || sizeof(Shdr) > ElfSize - *ShPos)
Expand All @@ -874,15 +863,15 @@ static bool adjustSectionHeaders(uint8_t *Elf, size_t ElfSize,

if (ShOffset == TextOffset) {
std::optional<uint64_t> NewTextSize =
checkedAdd(TextSize, TrampTotal, ".text section size");
checkedAddUint64(TextSize, TrampTotal, ".text section size");
if (!NewTextSize)
return false;
uint64_t NewTextSizeValue = *NewTextSize;
std::memcpy(Sh + offsetof(Shdr, sh_size), &NewTextSizeValue,
sizeof(NewTextSizeValue));
} else if (ShOffset > TextOffset) {
std::optional<uint64_t> NewOffset =
checkedAdd(ShOffset, TrampTotal, "post-.text section offset");
checkedAddUint64(ShOffset, TrampTotal, "post-.text section offset");
if (!NewOffset)
return false;
uint64_t NewOffsetValue = *NewOffset;
Expand All @@ -894,7 +883,7 @@ static bool adjustSectionHeaders(uint8_t *Elf, size_t ElfSize,
uint64_t ShAddr;
std::memcpy(&ShAddr, Sh + offsetof(Shdr, sh_addr), sizeof(ShAddr));
std::optional<uint64_t> NewAddr =
checkedAdd(ShAddr, TrampTotal, "post-.text section address");
checkedAddUint64(ShAddr, TrampTotal, "post-.text section address");
if (!NewAddr)
return false;
ShAddr = *NewAddr;
Expand All @@ -912,7 +901,7 @@ static bool adjustProgramHeaders(uint8_t *Elf, size_t ElfSize,
return true;

std::optional<uint64_t> TextEnd =
checkedAdd(TextOffset, TextSize, "program header .text end");
checkedAddUint64(TextOffset, TextSize, "program header .text end");
if (!TextEnd)
return false;
uint64_t Phoff;
Expand All @@ -927,7 +916,7 @@ static bool adjustProgramHeaders(uint8_t *Elf, size_t ElfSize,
for (uint16_t I = 0; I < Phnum; ++I) {
uint64_t PhTableDelta = static_cast<uint64_t>(I) * Phentsize;
std::optional<uint64_t> PhPos =
checkedAdd(Phoff, PhTableDelta, "program header entry offset");
checkedAddUint64(Phoff, PhTableDelta, "program header entry offset");
if (!PhPos)
return false;
if (*PhPos > ElfSize || sizeof(Phdr) > ElfSize - *PhPos)
Expand All @@ -941,14 +930,14 @@ static bool adjustProgramHeaders(uint8_t *Elf, size_t ElfSize,
std::memcpy(&PMemsz, Ph + offsetof(Phdr, p_memsz), sizeof(PMemsz));

std::optional<uint64_t> PEnd =
checkedAdd(POffset, PFilesz, "program header file end");
checkedAddUint64(POffset, PFilesz, "program header file end");
if (!PEnd)
return false;
if (POffset <= TextOffset && *PEnd >= *TextEnd) {
std::optional<uint64_t> NewPFilesz =
checkedAdd(PFilesz, TrampTotal, "program header file size");
checkedAddUint64(PFilesz, TrampTotal, "program header file size");
std::optional<uint64_t> NewPMemsz =
checkedAdd(PMemsz, TrampTotal, "program header memory size");
checkedAddUint64(PMemsz, TrampTotal, "program header memory size");
if (!NewPFilesz || !NewPMemsz)
return false;
PFilesz = *NewPFilesz;
Expand All @@ -957,23 +946,23 @@ static bool adjustProgramHeaders(uint8_t *Elf, size_t ElfSize,
std::memcpy(Ph + offsetof(Phdr, p_memsz), &PMemsz, sizeof(PMemsz));
} else if (POffset > TextOffset) {
std::optional<uint64_t> NewPOffset =
checkedAdd(POffset, TrampTotal, "post-.text program offset");
checkedAddUint64(POffset, TrampTotal, "post-.text program offset");
if (!NewPOffset)
return false;
POffset = *NewPOffset;
std::memcpy(Ph + offsetof(Phdr, p_offset), &POffset, sizeof(POffset));
uint64_t PVaddr;
std::memcpy(&PVaddr, Ph + offsetof(Phdr, p_vaddr), sizeof(PVaddr));
std::optional<uint64_t> NewPVaddr =
checkedAdd(PVaddr, TrampTotal, "post-.text program vaddr");
checkedAddUint64(PVaddr, TrampTotal, "post-.text program vaddr");
if (!NewPVaddr)
return false;
PVaddr = *NewPVaddr;
std::memcpy(Ph + offsetof(Phdr, p_vaddr), &PVaddr, sizeof(PVaddr));
uint64_t PPaddr;
std::memcpy(&PPaddr, Ph + offsetof(Phdr, p_paddr), sizeof(PPaddr));
std::optional<uint64_t> NewPPaddr =
checkedAdd(PPaddr, TrampTotal, "post-.text program paddr");
checkedAddUint64(PPaddr, TrampTotal, "post-.text program paddr");
if (!NewPPaddr)
return false;
PPaddr = *NewPPaddr;
Expand Down Expand Up @@ -1050,7 +1039,7 @@ static bool adjustSymbolValues(uint8_t *Elf, size_t ElfSize,

uint64_t SymOffset = SymBytes - File.base();
std::optional<uint64_t> Value =
checkedAdd(Sym.st_value, TrampTotal, "post-.text symbol value");
checkedAddUint64(Sym.st_value, TrampTotal, "post-.text symbol value");
if (!Value)
return false;
uint64_t Value64 = *Value;
Expand Down Expand Up @@ -1091,8 +1080,8 @@ ElfView::growWithTrampolines(ArrayRef<Trampoline> Trampolines,
return nullptr;
}

std::optional<uint64_t> TextEnd =
checkedAdd(textOffset(), textSize(), "growWithTrampolines .text end");
std::optional<uint64_t> TextEnd = checkedAddUint64(
textOffset(), textSize(), "growWithTrampolines .text end");
if (!TextEnd || *TextEnd > InputSize) {
log() << "hotswap: error: growWithTrampolines: .text range exceeds input "
<< "ELF size.\n";
Expand Down
Loading
Loading