Skip to content

Commit

Permalink
[EraVM] MC C-API: make a copy of the input buffer.
Browse files Browse the repository at this point in the history
This ensures that the new buffer is null-terminated,
which is required for the current AsmParser implementation.
  • Loading branch information
PavelKopyl authored and akiramenai committed Aug 31, 2024
1 parent d5f4601 commit 256a724
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 4 deletions.
8 changes: 4 additions & 4 deletions llvm/lib/MC/MCC/AssemblerC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ LLVMBool LLVMAssembleEraVM(LLVMTargetMachineRef T, LLVMMemoryBufferRef InBuffer,
MemoryBuffer *InMemBuf = unwrap(InBuffer);
// Create a copy of the input buffer because SourceMgr will take
// ownership of the memory buffer.
// The buffer we pass to AsmParser doesn't need to be null-terminated.
std::unique_ptr<MemoryBuffer> BufferPtr =
MemoryBuffer::getMemBuffer(InMemBuf->getMemBufferRef(),
/*RequiresNullTerminator=*/false);
// The buffer we pass to AsmParser needs to be null-terminated, which is
// ensured by the getMemBufferCopy implementation.
std::unique_ptr<MemoryBuffer> BufferPtr = MemoryBuffer::getMemBufferCopy(
InMemBuf->getBuffer(), InMemBuf->getBufferIdentifier());

llvm::SmallString<0> ErrorMsgBuffer;
llvm::raw_svector_ostream ErrorMsgOS(ErrorMsgBuffer);
Expand Down
28 changes: 28 additions & 0 deletions llvm/unittests/MC/EraVM/AssemblerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,34 @@ TEST_F(AssemblerCTest, AsmParserError) {
LLVMDisposeMemoryBuffer(AsmMemBuffer);
}

// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions)
TEST_F(AssemblerCTest, NoBufferNullTerminator) {
StringRef Asm = " \
.text \n\
get_glob: \n\
add r1, r1, r1 \n\
ret";

// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, hicpp-avoid-c-arrays)
auto Buffer = std::make_unique<char[]>(Asm.size());
std::memcpy(Buffer.get(), Asm.data(), Asm.size());
StringRef StrBuffer(Buffer.get(), Asm.size());
std::unique_ptr<MemoryBuffer> MemBuffer =
MemoryBuffer::getMemBuffer(StrBuffer, "",
/*RequiresNullTerminator=*/false);

LLVMMemoryBufferRef AsmMemBuffer = llvm::wrap(MemBuffer.get());
LLVMMemoryBufferRef ObjMemBuffer = nullptr;
char *ErrMsg = nullptr;
// Return code 'true' denotes an error.
if (LLVMAssembleEraVM(TM, AsmMemBuffer, &ObjMemBuffer, &ErrMsg)) {
FAIL() << "Failed to assembly:" << ErrMsg;
LLVMDisposeMessage(ErrMsg);
return;
}
LLVMDisposeMemoryBuffer(ObjMemBuffer);
}

// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions)
TEST_F(AssemblerCTest, ToManyInstructionsError) {
std::string Asm = ".text";
Expand Down

0 comments on commit 256a724

Please sign in to comment.