Simplify BuildPointerToOffset to index at byte granularity rather

than using underlying element size
This commit is contained in:
Alex Cameron
2022-06-21 10:15:45 +10:00
parent 05df435aa3
commit 080969e0b0
4 changed files with 9 additions and 108 deletions
-28
View File
@@ -1,28 +0,0 @@
/*
* Copyright (c) 2022 Trail of Bits, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "remill/BC/Version.h"
namespace remill {
// TODO(alex): Just remove this function entirely
inline static llvm::Type *PointerElementType(llvm::PointerType *type) {
// assert(type->isOpaque());
return nullptr;
}
} // namespace remill
-1
View File
@@ -21,7 +21,6 @@
#include "Decode.h"
#include "remill/Arch/Instruction.h"
#include "remill/Arch/Name.h"
#include "remill/BC/Compat/PointerType.h"
#include "remill/BC/ABI.h"
#include "remill/BC/Util.h"
#include "remill/OS/OS.h"
-1
View File
@@ -22,7 +22,6 @@
#include "remill/Arch/Instruction.h"
#include "remill/Arch/Name.h"
#include "remill/BC/ABI.h"
#include "remill/BC/Compat/PointerType.h"
#include "remill/BC/Util.h"
#include "remill/OS/OS.h"
+9 -78
View File
@@ -53,7 +53,6 @@
#include "remill/BC/Compat/DebugInfo.h"
#include "remill/BC/Compat/GlobalValue.h"
#include "remill/BC/Compat/IRReader.h"
#include "remill/BC/Compat/PointerType.h"
#include "remill/BC/Compat/ToolOutputFile.h"
#include "remill/BC/Compat/VectorType.h"
#include "remill/BC/Compat/Verifier.h"
@@ -2390,30 +2389,18 @@ BuildIndexes(const llvm::DataLayout &dl, llvm::Type *type, size_t offset,
// and to give access to a module for data layouts.
llvm::Value *BuildPointerToOffset(llvm::IRBuilder<> &ir, llvm::Value *ptr,
size_t dest_elem_offset,
llvm::Type *dest_ptr_type_) {
const auto block = ir.GetInsertBlock();
llvm::Module *module = nullptr;
if (block) {
module = block->getModule();
} else if (auto gv = llvm::dyn_cast<llvm::GlobalValue>(ptr); gv) {
module = gv->getParent();
llvm::Type *dest_ptr_type) {
// TODO(pag): Improve the API to take a `DataLayout`, perhaps.
} else {
LOG(FATAL) << "Unable to get the current module.";
}
auto &context = ptr->getContext();
const auto i32_type = llvm::Type::getInt32Ty(context);
const auto &dl = module->getDataLayout();
llvm::SmallVector<llvm::Value *, 16> indexes;
auto ptr_type = llvm::dyn_cast<llvm::PointerType>(ptr->getType());
CHECK_NOTNULL(ptr_type);
const auto dest_elem_ptr_type =
llvm::dyn_cast<llvm::PointerType>(dest_ptr_type_);
llvm::dyn_cast<llvm::PointerType>(dest_ptr_type);
CHECK_NOTNULL(dest_elem_ptr_type);
auto ptr_addr_space = ptr_type->getAddressSpace();
const auto dest_ptr_addr_space = dest_elem_ptr_type->getAddressSpace();
@@ -2433,73 +2420,17 @@ llvm::Value *BuildPointerToOffset(llvm::IRBuilder<> &ir, llvm::Value *ptr,
}
}
// NOTE(alex): Same here
const auto dest_elem_type = PointerElementType(dest_elem_ptr_type);
const auto ptr_elem_type = PointerElementType(ptr_type);
const auto ptr_elem_size = dl.getTypeAllocSize(ptr_elem_type);
const auto base_index = dest_elem_offset / ptr_elem_size;
const auto i8_type = llvm::Type::getInt8Ty(context);
indexes.push_back(llvm::ConstantInt::get(i32_type, base_index, false));
dest_elem_offset = dest_elem_offset % ptr_elem_size;
auto [reached_disp, indexed_type] =
BuildIndexes(dl, ptr_elem_type, 0, dest_elem_offset, indexes);
if (reached_disp) {
if (dest_elem_offset) {
indexes.push_back(
llvm::ConstantInt::get(i32_type, dest_elem_offset, false));
if (constant_ptr) {
if (base_index) {
constant_ptr = llvm::ConstantExpr::getGetElementPtr(
ptr_elem_type, constant_ptr, indexes);
} else {
constant_ptr = llvm::ConstantExpr::getGetElementPtr(
ptr_elem_type, constant_ptr, indexes, true,
(base_index * ptr_elem_size) + reached_disp);
}
constant_ptr =
llvm::ConstantExpr::getGetElementPtr(i8_type, constant_ptr, indexes);
ptr = constant_ptr;
} else {
if (base_index) {
ptr = ir.CreateGEP(ptr_elem_type, ptr, indexes);
} else {
ptr = ir.CreateInBoundsGEP(ptr_elem_type, ptr, indexes);
}
}
}
if (const auto diff = dest_elem_offset - reached_disp; diff) {
DCHECK_LE(diff, dest_elem_offset);
const auto i8_type = llvm::Type::getInt8Ty(context);
const auto i8_ptr_type =
llvm::PointerType::getInt8PtrTy(context, ptr_addr_space);
const auto dest_elem_size = dl.getTypeAllocSize(dest_elem_type);
if (diff % dest_elem_size) {
if (constant_ptr) {
constant_ptr =
llvm::ConstantExpr::getBitCast(constant_ptr, i8_ptr_type);
constant_ptr = llvm::ConstantExpr::getGetElementPtr(
i8_type, constant_ptr, llvm::ConstantInt::get(i32_type, diff));
return llvm::ConstantExpr::getBitCast(constant_ptr, dest_elem_ptr_type);
} else {
ptr = ir.CreateBitCast(ptr, i8_ptr_type);
ptr = ir.CreateGEP(i8_type, ptr,
llvm::ConstantInt::get(i32_type, diff, false));
return ir.CreateBitCast(ptr, dest_elem_ptr_type);
}
} else {
if (constant_ptr) {
constant_ptr =
llvm::ConstantExpr::getBitCast(constant_ptr, dest_elem_ptr_type);
return llvm::ConstantExpr::getGetElementPtr(
dest_elem_type, constant_ptr,
llvm::ConstantInt::get(i32_type, diff / dest_elem_size));
} else {
ptr = ir.CreateBitCast(ptr, dest_elem_ptr_type);
return ir.CreateGEP(
dest_elem_type, ptr,
llvm::ConstantInt::get(i32_type, diff / dest_elem_size, false));
}
ptr = ir.CreateGEP(i8_type, ptr, indexes);
}
}