mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-09 21:24:14 +00:00
add minimal support for aarch64 (#507)
Summary: Pull Request resolved: https://github.com/facebookexperimental/object-introspection/pull/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
This commit is contained in:
parent
8831269523
commit
b7b9ac1536
@ -16,6 +16,8 @@ endif()
|
|||||||
|
|
||||||
# Generate compile_commands.json to make it easier to work with clang based tools
|
# Generate compile_commands.json to make it easier to work with clang based tools
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
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)
|
option(ENABLE_IPO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)" OFF)
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@ target_link_libraries(drgn_utils
|
|||||||
add_library(symbol_service
|
add_library(symbol_service
|
||||||
Descs.cpp
|
Descs.cpp
|
||||||
SymbolService.cpp
|
SymbolService.cpp
|
||||||
|
arch/aarch64.cpp
|
||||||
|
arch/x86_64.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(symbol_service
|
target_link_libraries(symbol_service
|
||||||
drgn_utils
|
drgn_utils
|
||||||
|
10
oi/Descs.cpp
10
oi/Descs.cpp
@ -38,18 +38,16 @@ std::ostream& operator<<(std::ostream& os, const FuncDesc::Range& r) {
|
|||||||
* location?).
|
* location?).
|
||||||
*/
|
*/
|
||||||
std::optional<uintptr_t> FuncDesc::Arg::findAddress(
|
std::optional<uintptr_t> FuncDesc::Arg::findAddress(
|
||||||
struct user_regs_struct* regs, uintptr_t pc) const {
|
const user_regs_struct* regs, uintptr_t pc) const {
|
||||||
auto prevRip = std::exchange(regs->rip, pc);
|
user_regs_struct modifiedRegs = *regs;
|
||||||
BOOST_SCOPE_EXIT_ALL(&) {
|
oi::detail::arch::setProgramCounter(modifiedRegs, pc);
|
||||||
regs->rip = prevRip;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct drgn_object object {};
|
struct drgn_object object {};
|
||||||
BOOST_SCOPE_EXIT_ALL(&) {
|
BOOST_SCOPE_EXIT_ALL(&) {
|
||||||
drgn_object_deinit(&object);
|
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;
|
LOG(ERROR) << "Error while finding address of argument: " << err->message;
|
||||||
drgn_error_destroy(err);
|
drgn_error_destroy(err);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
10
oi/Descs.h
10
oi/Descs.h
@ -20,6 +20,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "oi/arch/Arch.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <drgn.h>
|
#include <drgn.h>
|
||||||
}
|
}
|
||||||
@ -103,7 +105,7 @@ struct FuncDesc {
|
|||||||
* can be found at the given pc (what about if we don't have this
|
* can be found at the given pc (what about if we don't have this
|
||||||
* location?).
|
* 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;
|
uintptr_t pc) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -114,16 +116,16 @@ struct FuncDesc {
|
|||||||
drgn_object_locator_deinit(&locator);
|
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;
|
uintptr_t pc) const final;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Retval final : virtual TargetObject {
|
struct Retval final : virtual TargetObject {
|
||||||
~Retval() final = default;
|
~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 {
|
uintptr_t /* pc */) const final {
|
||||||
return regs->rax;
|
return oi::detail::arch::getReturnValueAddress(*regs);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -88,8 +88,9 @@ static struct LLVMInitializer {
|
|||||||
llvm::InitializeNativeTargetAsmPrinter();
|
llvm::InitializeNativeTargetAsmPrinter();
|
||||||
llvm::InitializeNativeTargetDisassembler();
|
llvm::InitializeNativeTargetDisassembler();
|
||||||
|
|
||||||
|
std::string triple = llvm::sys::getProcessTriple();
|
||||||
disassemblerContext = LLVMCreateDisasm(
|
disassemblerContext = LLVMCreateDisasm(
|
||||||
"x86_64-pc-linux", nullptr, 0, nullptr, symbolLookupCallback);
|
triple.c_str(), nullptr, 0, nullptr, symbolLookupCallback);
|
||||||
if (!disassemblerContext) {
|
if (!disassemblerContext) {
|
||||||
throw std::runtime_error("Failed to initialize disassemblerContext");
|
throw std::runtime_error("Failed to initialize disassemblerContext");
|
||||||
}
|
}
|
||||||
|
29
oi/arch/Arch.h
Normal file
29
oi/arch/Arch.h
Normal file
@ -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
oi/arch/aarch64.cpp
Normal file
36
oi/arch/aarch64.cpp
Normal file
@ -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
oi/arch/x86_64.cpp
Normal file
36
oi/arch/x86_64.cpp
Normal file
@ -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.rax;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setProgramCounter(user_regs_struct& regs, uintptr_t pc) {
|
||||||
|
regs.rip = pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace oi::detail::arch
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user