Skip to content

Commit

Permalink
[NFC] Decouple the dependency on both X86 and ARM target builds
Browse files Browse the repository at this point in the history
to allow for single target build (either X86 or ARM) of llvm-mctoll
  • Loading branch information
bharadwajy committed Dec 9, 2018
1 parent 116e832 commit f4b690b
Show file tree
Hide file tree
Showing 14 changed files with 426 additions and 195 deletions.
25 changes: 13 additions & 12 deletions ARM/ARMMachineInstructionRaiser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "ARMMachineInstructionRaiser.h"
#include "ARMEliminatePrologEpilog.h"
#include "ARMFunctionPrototype.h"
#include "ARMModuleRaiser.h"
#include "MachineFunctionRaiser.h"

using namespace llvm;

Expand All @@ -35,7 +37,6 @@ bool ARMMachineInstructionRaiser::raiseMachineFunction() {

bool ARMMachineInstructionRaiser::raise() {
raiseMachineFunction();

return true;
}

Expand Down Expand Up @@ -71,15 +72,15 @@ FunctionType *ARMMachineInstructionRaiser::getRaisedFunctionPrototype() {
return raisedFunction->getFunctionType();
}

#ifdef __cplusplus
extern "C" {
#endif
MachineInstructionRaiser *
InitializeARMMachineInstructionRaiser(MachineFunction &machFunc, Module &m,
const ModuleRaiser *mr,
MCInstRaiser *mcir) {
return new ARMMachineInstructionRaiser(machFunc, mr, mcir);
}
#ifdef __cplusplus
// Create a new MachineFunctionRaiser object and add it to the list of
// MachineFunction raiser objects of this module.
MachineFunctionRaiser *ARMModuleRaiser::CreateAndAddMachineFunctionRaiser(
Function *f, const ModuleRaiser *mr, uint64_t start, uint64_t end) {
MachineFunctionRaiser *mfRaiser = new MachineFunctionRaiser(
*M, mr->getMachineModuleInfo()->getOrCreateMachineFunction(*f), mr, start,
end);
mfRaiser->setMachineInstrRaiser(new ARMMachineInstructionRaiser(
mfRaiser->getMachineFunction(), mr, mfRaiser->getMCInstRaiser()));
mfRaiserVector.push_back(mfRaiser);
return mfRaiser;
}
#endif
85 changes: 85 additions & 0 deletions ARM/ARMModuleRaiser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//===- ARMModuleRaiser.h - Binary raiser utility llvm-mctoll --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of ARMModuleRaiser class for use by
// llvm-mctoll.
//
//===----------------------------------------------------------------------===//

#include "ARMModuleRaiser.h"
#include "llvm/Object/ELFObjectFile.h"

using namespace llvm;

namespace RaiserContext {
extern SmallVector<ModuleRaiser *, 4> ModuleRaiserRegistry;
}

bool ARMModuleRaiser::collectDynamicRelocations() {
if (!Obj->isELF()) {
return false;
}

const ELF32LEObjectFile *Elf32LEObjFile = dyn_cast<ELF32LEObjectFile>(Obj);
if (!Elf32LEObjFile) {
return false;
}

std::vector<SectionRef> DynRelSec = Obj->dynamic_relocation_sections();

for (const SectionRef &Section : DynRelSec) {
for (const RelocationRef &Reloc : Section.relocations()) {
DynRelocs.push_back(Reloc);
}
}

// Get relocations of .got.plt section from .rela.plt if it exists. I do not
// see an API in ObjectFile class to get at these.

// Find .got.plt and .rel.plt sections Note: A lot of verification and double
// checking done in the following code.
const ELFFile<ELF32LE> *ElfFile = Elf32LEObjFile->getELFFile();
// Find .rel.plt
SectionRef DotGotDotPltSec, DotRelaDotPltSec;
for (const SectionRef Section : Obj->sections()) {
StringRef SecName;
Section.getName(SecName);
if (SecName.equals(".rel.plt")) {
DotRelaDotPltSec = Section;
} else if (SecName.equals(".got")) {
DotGotDotPltSec = Section;
}
}

if (DotRelaDotPltSec.getObject() != nullptr) {
// Do some additional sanity checks
assert((DotGotDotPltSec.getObject() != nullptr) &&
"Failed to find .got section");
auto DotRelaDotPltShdr = ElfFile->getSection(DotRelaDotPltSec.getIndex());
assert(DotRelaDotPltShdr && "Failed to find .rel.plt section");
for (const RelocationRef &Reloc : DotRelaDotPltSec.relocations()) {
DynRelocs.push_back(Reloc);
}
}
return true;
}

#ifdef __cplusplus
extern "C" {
#endif

void InitializeARMModuleRaiser() {
ModuleRaiser *m = new ARMModuleRaiser();
RaiserContext::ModuleRaiserRegistry.push_back(m);
return;
}

#ifdef __cplusplus
}
#endif
34 changes: 34 additions & 0 deletions ARM/ARMModuleRaiser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//===- ARMModuleRaiser.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of ARMModuleRaiser class for use by
// llvm-mctoll.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TOOLS_LLVM_MCTOLL_ARM_ARMMODULERAISER_H
#define LLVM_TOOLS_LLVM_MCTOLL_ARM_ARMMODULERAISER_H

#include "ModuleRaiser.h"

using namespace llvm;

class ARMModuleRaiser : public ModuleRaiser {
public:
ARMModuleRaiser() : ModuleRaiser() { Arch = Triple::arm; }

// Create a new MachineFunctionRaiser object and add it to the list of
// MachineFunction raiser objects of this module.
MachineFunctionRaiser *
CreateAndAddMachineFunctionRaiser(Function *f, const ModuleRaiser *mr,
uint64_t start, uint64_t end);
bool collectDynamicRelocations();
};

#endif // LLVM_TOOLS_LLVM_MCTOLL_ARM_ARMMODULERAISER_H
1 change: 1 addition & 0 deletions ARM/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ if(NOT LLVM_MCTOLL_BUILT_STANDALONE)
endif()

add_llvm_library(ARMRaiser
ARMModuleRaiser.cpp
ARMFunctionPrototype.cpp
ARMEliminatePrologEpilog.cpp
ARMMachineInstructionRaiser.cpp
Expand Down
14 changes: 14 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
if(NOT (LLVM_TARGETS_TO_BUILD MATCHES "X86" OR LLVM_TARGETS_TO_BUILD MATCHES "ARM"))
return()
endif()

set(LLVM_MCTOLL_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(LLVM_MCTOLL_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})

Expand All @@ -9,17 +13,27 @@ llvm_map_components_to_libnames(llvm_libs
)

set(LLVM_MCTOLL_LIB_DEPS ${llvm_libs})
set(LLVM_MCTOLL_SUPPORTED_ARCHS "")

if(LLVM_TARGETS_TO_BUILD MATCHES "X86")
set(LLVM_MCTOLL_SUPPORTED_ARCHS
"${LLVM_MCTOLL_SUPPORTED_ARCHS}MODULE_RAISER(X86)\n")
add_subdirectory(X86)
list(APPEND LLVM_MCTOLL_LIB_DEPS X86Raiser)
endif()

if(LLVM_TARGETS_TO_BUILD MATCHES "ARM")
set(LLVM_MCTOLL_SUPPORTED_ARCHS
"${LLVM_MCTOLL_SUPPORTED_ARCHS}MODULE_RAISER(ARM)\n")
add_subdirectory(ARM)
list(APPEND LLVM_MCTOLL_LIB_DEPS ARMRaiser)
endif()

configure_file(
${LLVM_MCTOLL_SOURCE_DIR}/Raisers.def.in
${LLVM_INCLUDE_DIR}/Raisers.def
)

add_subdirectory(test)

add_llvm_tool(llvm-mctoll
Expand Down
124 changes: 15 additions & 109 deletions MachineFunctionRaiser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,60 +13,15 @@
//===----------------------------------------------------------------------===//

#include "MachineFunctionRaiser.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Target/TargetMachine.h"

#ifdef __cplusplus
extern "C" {
#endif

// ARM Raiser passes
MachineInstructionRaiser *
InitializeARMMachineInstructionRaiser(MachineFunction &machFunc, Module &m,
const ModuleRaiser *mr,
MCInstRaiser *mcir);

// X86 Raiser passes
MachineInstructionRaiser *
InitializeX86MachineInstructionRaiser(MachineFunction &machFunc, Module &m,
const ModuleRaiser *mr,
MCInstRaiser *mcir);
#ifdef __cplusplus
}
#endif

void MachineFunctionRaiser::init(uint64_t start, uint64_t end) {
mcInstRaiser = new MCInstRaiser(start, end);
machineInstRaiser = nullptr;
auto arch = MR->getTargetMachine()->getTargetTriple().getArch();

// Double check supported architecture.
if (!MR->isSupportedArch()) {
outs() << arch << "Unsupported architecture\n";
return;
}

switch (arch) {
case Triple::x86_64:
machineInstRaiser =
InitializeX86MachineInstructionRaiser(MF, module, MR, mcInstRaiser);
break;
case Triple::arm:
machineInstRaiser =
InitializeARMMachineInstructionRaiser(MF, module, MR, mcInstRaiser);
break;
// Add default case to pacify the compiler warnings.
default:
outs() << "\n" << arch << " not yet supported for raising\n";
}
}

bool MachineFunctionRaiser::runRaiserPasses() {
bool success = false;
// Do not run raise binaries of an unsupported architecture.
if (!MR->isSupportedArch())
return false;

// Raise MCInst to MachineInstr and Build CFG
if (machineInstRaiser != nullptr) {
// Raise MachineInstr to Instruction
Expand Down Expand Up @@ -95,16 +50,6 @@ void MachineFunctionRaiser::cleanupRaisedFunction() {
* reference MachineFunctionRaiser class that has a forward declaration in
* ModuleRaiser.h.
*/
// Create a new MachineFunctionRaiser object and add it to the list of
// MachineFunction raiser objects of this module.
MachineFunctionRaiser *ModuleRaiser::CreateAndAddMachineFunctionRaiser(
Function *f, const ModuleRaiser *mr, uint64_t start, uint64_t end) {
MachineFunctionRaiser *mfRaiser = new MachineFunctionRaiser(
M, mr->getMachineModuleInfo()->getOrCreateMachineFunction(*f), mr, start,
end);
mfRaiserVector.push_back(mfRaiser);
return mfRaiser;
}

Function *ModuleRaiser::getFunctionAt(uint64_t Index) const {
int64_t TextSecAddr = getTextSectionAddress();
Expand Down Expand Up @@ -234,60 +179,6 @@ bool ModuleRaiser::collectTextSectionRelocs(const SectionRef &TextSec) {
return true;
}

bool ModuleRaiser::collectDynamicRelocations() {

if (!Obj->isELF()) {
return false;
}

const ELF64LEObjectFile *Elf64LEObjFile = dyn_cast<ELF64LEObjectFile>(Obj);
if (!Elf64LEObjFile) {
return false;
}

std::vector<SectionRef> DynRelSec = Obj->dynamic_relocation_sections();

for (const SectionRef &Section : DynRelSec) {
for (const RelocationRef &Reloc : Section.relocations()) {
DynRelocs.push_back(Reloc);
}
}

// Get relocations of .got.plt section from .rela.plt if it exists. I do not
// see an API in ObjectFile class to get at these.

// Find .got.plt and .rela.plt sections Note: A lot of verification and double
// checking done in the following code.
const ELFFile<ELF64LE> *ElfFile = Elf64LEObjFile->getELFFile();
// Find .rela.plt
SectionRef DotGotDotPltSec, DotRelaDotPltSec;
for (const SectionRef Section : Obj->sections()) {
StringRef SecName;
Section.getName(SecName);
if (SecName.equals(".rela.plt")) {
DotRelaDotPltSec = Section;
} else if (SecName.equals(".got.plt")) {
DotGotDotPltSec = Section;
}
}
if (DotRelaDotPltSec.getObject() != nullptr) {
// If the binary has .got.plt section, read the dynamic relocations.
if (DotGotDotPltSec.getObject() != nullptr) {
auto DotRelaDotPltShdr = ElfFile->getSection(DotRelaDotPltSec.getIndex());
// Perform some sanity checks
assert(DotRelaDotPltShdr && "Failed to find .rela.plt section");
assert((DotRelaDotPltShdr.get()->sh_info == DotGotDotPltSec.getIndex()) &&
".rela.plt does not refer .got.plt section");
assert((DotRelaDotPltShdr.get()->sh_type == ELF::SHT_RELA) &&
"Unexpected type of section .rela.plt");
for (const RelocationRef &Reloc : DotRelaDotPltSec.relocations()) {
DynRelocs.push_back(Reloc);
}
}
}
return true;
}

// Return text section address; or -1 if text section is not found
int64_t ModuleRaiser::getTextSectionAddress() const {
if (!Obj->isELF()) {
Expand Down Expand Up @@ -318,3 +209,18 @@ void ModuleRaiser::addRODataValueAt(Value *v, uint64_t offset) const {
GlobalRODataValues.emplace(offset, v);
return;
}

#ifdef __cplusplus
extern "C" {
#endif

#define MODULE_RAISER(TargetName) void Initialize##TargetName##ModuleRaiser();
#include "Raisers.def"
#ifdef __cplusplus
}
#endif

void ModuleRaiser::InitializeAllModuleRaisers() {
#define MODULE_RAISER(TargetName) Initialize##TargetName##ModuleRaiser();
#include "Raisers.def"
}
3 changes: 3 additions & 0 deletions MachineFunctionRaiser.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class MachineFunctionRaiser {
MachineInstructionRaiser *getMachineInstrRaiser() {
return machineInstRaiser;
}
void setMachineInstrRaiser(MachineInstructionRaiser *r) {
machineInstRaiser = r;
}
Function *getRaisedFunction() {
return machineInstRaiser->getRaisedFunction();
}
Expand Down
Loading

0 comments on commit f4b690b

Please sign in to comment.