Skip to content

Commit

Permalink
add minimal support for aarch64 (#507)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #507

OI is currently completely incompatible with anything except `x86_64`. Changing that generally is a big effort, but `oilgen` should work on other architectures. Begin adding some support for `aarch64` architecture.

This change sets up a file structure for architecture support. It pulls the 2 functions needed to make `Descs.{h,cpp}` architecture agnostic into architecture specific files for `x86_64` and `aarch64`. This enables `oilgen` (the binary) to build. At this stage `oilgen` is unable to generate working code for `aarch64`, but at least this is a step in the right direction.

Differential Revision: D61661524
  • Loading branch information
JakeHillion authored and facebook-github-bot committed Aug 22, 2024
1 parent 8831269 commit 39451c3
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 11 deletions.
2 changes: 2 additions & 0 deletions cmake/StandardProjectSettings.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ endif()

# Generate compile_commands.json to make it easier to work with clang based tools
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Include implicit directories in the compile commands file
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})

option(ENABLE_IPO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)" OFF)

Expand Down
2 changes: 2 additions & 0 deletions oi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ target_link_libraries(drgn_utils
add_library(symbol_service
Descs.cpp
SymbolService.cpp
arch/aarch64.cpp
arch/x86_64.cpp
)
target_link_libraries(symbol_service
drgn_utils
Expand Down
10 changes: 4 additions & 6 deletions oi/Descs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,16 @@ std::ostream& operator<<(std::ostream& os, const FuncDesc::Range& r) {
* location?).
*/
std::optional<uintptr_t> FuncDesc::Arg::findAddress(
struct user_regs_struct* regs, uintptr_t pc) const {
auto prevRip = std::exchange(regs->rip, pc);
BOOST_SCOPE_EXIT_ALL(&) {
regs->rip = prevRip;
};
const user_regs_struct* regs, uintptr_t pc) const {
user_regs_struct modifiedRegs = *regs;
oi::detail::arch::setProgramCounter(modifiedRegs, pc);

struct drgn_object object {};
BOOST_SCOPE_EXIT_ALL(&) {
drgn_object_deinit(&object);
};

if (auto* err = drgn_object_locate(&locator, regs, &object)) {
if (auto* err = drgn_object_locate(&locator, &modifiedRegs, &object)) {
LOG(ERROR) << "Error while finding address of argument: " << err->message;
drgn_error_destroy(err);
return std::nullopt;
Expand Down
10 changes: 6 additions & 4 deletions oi/Descs.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <string>
#include <vector>

#include "oi/arch/Arch.h"

extern "C" {
#include <drgn.h>
}
Expand Down Expand Up @@ -103,7 +105,7 @@ struct FuncDesc {
* can be found at the given pc (what about if we don't have this
* location?).
*/
virtual std::optional<uintptr_t> findAddress(struct user_regs_struct* regs,
virtual std::optional<uintptr_t> findAddress(const user_regs_struct* regs,
uintptr_t pc) const = 0;
};

Expand All @@ -114,16 +116,16 @@ struct FuncDesc {
drgn_object_locator_deinit(&locator);
}

std::optional<uintptr_t> findAddress(struct user_regs_struct* regs,
std::optional<uintptr_t> findAddress(const user_regs_struct* regs,
uintptr_t pc) const final;
};

struct Retval final : virtual TargetObject {
~Retval() final = default;

std::optional<uintptr_t> findAddress(struct user_regs_struct* regs,
std::optional<uintptr_t> findAddress(const user_regs_struct* regs,
uintptr_t /* pc */) const final {
return regs->rax;
return oi::detail::arch::getReturnValueAddress(*regs);
}
};
};
Expand Down
3 changes: 2 additions & 1 deletion oi/OICompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ static struct LLVMInitializer {
llvm::InitializeNativeTargetAsmPrinter();
llvm::InitializeNativeTargetDisassembler();

std::string triple = llvm::sys::getProcessTriple();
disassemblerContext = LLVMCreateDisasm(
"x86_64-pc-linux", nullptr, 0, nullptr, symbolLookupCallback);
triple.c_str(), nullptr, 0, nullptr, symbolLookupCallback);
if (!disassemblerContext) {
throw std::runtime_error("Failed to initialize disassemblerContext");
}
Expand Down
29 changes: 29 additions & 0 deletions oi/arch/Arch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* 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 <cstdint>
#include <optional>

struct user_regs_struct;

namespace oi::detail::arch {

void setProgramCounter(user_regs_struct& regs, uintptr_t pc);

std::optional<uintptr_t> getReturnValueAddress(const user_regs_struct&);

} // namespace oi::detail::arch
36 changes: 36 additions & 0 deletions oi/arch/aarch64.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* 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.
*/
#ifdef __aarch64__

extern "C" {
#include <sys/user.h>
}

#include "Arch.h"

namespace oi::detail::arch {

std::optional<uintptr_t> getReturnValueAddress(const user_regs_struct& regs) {
return regs.regs[0];
}

void setProgramCounter(user_regs_struct& regs, uintptr_t pc) {
regs.pc = pc;
}

} // namespace oi::detail::arch

#endif
36 changes: 36 additions & 0 deletions oi/arch/x86_64.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* 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.
*/
#ifdef __x86_64__

extern "C" {
#include <sys/user.h>
}

#include "Arch.h"

namespace oi::detail::arch {

std::optional<uintptr_t> getReturnValueAddress(const user_regs_struct& regs) {
return regs.rip;
}

void setProgramCounter(user_regs_struct& regs, uintptr_t pc) {
regs.rip = pc;
}

} // namespace oi::detail::arch

#endif

0 comments on commit 39451c3

Please sign in to comment.