Skip to content

Commit b7b9ac1

Browse files
JakeHillionfacebook-github-bot
authored andcommitted
add minimal support for aarch64 (#507)
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
1 parent 8831269 commit b7b9ac1

File tree

8 files changed

+117
-11
lines changed

8 files changed

+117
-11
lines changed

cmake/StandardProjectSettings.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ endif()
1616

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

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

oi/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ target_link_libraries(drgn_utils
1212
add_library(symbol_service
1313
Descs.cpp
1414
SymbolService.cpp
15+
arch/aarch64.cpp
16+
arch/x86_64.cpp
1517
)
1618
target_link_libraries(symbol_service
1719
drgn_utils

oi/Descs.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,16 @@ std::ostream& operator<<(std::ostream& os, const FuncDesc::Range& r) {
3838
* location?).
3939
*/
4040
std::optional<uintptr_t> FuncDesc::Arg::findAddress(
41-
struct user_regs_struct* regs, uintptr_t pc) const {
42-
auto prevRip = std::exchange(regs->rip, pc);
43-
BOOST_SCOPE_EXIT_ALL(&) {
44-
regs->rip = prevRip;
45-
};
41+
const user_regs_struct* regs, uintptr_t pc) const {
42+
user_regs_struct modifiedRegs = *regs;
43+
oi::detail::arch::setProgramCounter(modifiedRegs, pc);
4644

4745
struct drgn_object object {};
4846
BOOST_SCOPE_EXIT_ALL(&) {
4947
drgn_object_deinit(&object);
5048
};
5149

52-
if (auto* err = drgn_object_locate(&locator, regs, &object)) {
50+
if (auto* err = drgn_object_locate(&locator, &modifiedRegs, &object)) {
5351
LOG(ERROR) << "Error while finding address of argument: " << err->message;
5452
drgn_error_destroy(err);
5553
return std::nullopt;

oi/Descs.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include <string>
2121
#include <vector>
2222

23+
#include "oi/arch/Arch.h"
24+
2325
extern "C" {
2426
#include <drgn.h>
2527
}
@@ -103,7 +105,7 @@ struct FuncDesc {
103105
* can be found at the given pc (what about if we don't have this
104106
* location?).
105107
*/
106-
virtual std::optional<uintptr_t> findAddress(struct user_regs_struct* regs,
108+
virtual std::optional<uintptr_t> findAddress(const user_regs_struct* regs,
107109
uintptr_t pc) const = 0;
108110
};
109111

@@ -114,16 +116,16 @@ struct FuncDesc {
114116
drgn_object_locator_deinit(&locator);
115117
}
116118

117-
std::optional<uintptr_t> findAddress(struct user_regs_struct* regs,
119+
std::optional<uintptr_t> findAddress(const user_regs_struct* regs,
118120
uintptr_t pc) const final;
119121
};
120122

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

124-
std::optional<uintptr_t> findAddress(struct user_regs_struct* regs,
126+
std::optional<uintptr_t> findAddress(const user_regs_struct* regs,
125127
uintptr_t /* pc */) const final {
126-
return regs->rax;
128+
return oi::detail::arch::getReturnValueAddress(*regs);
127129
}
128130
};
129131
};

oi/OICompiler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,9 @@ static struct LLVMInitializer {
8888
llvm::InitializeNativeTargetAsmPrinter();
8989
llvm::InitializeNativeTargetDisassembler();
9090

91+
std::string triple = llvm::sys::getProcessTriple();
9192
disassemblerContext = LLVMCreateDisasm(
92-
"x86_64-pc-linux", nullptr, 0, nullptr, symbolLookupCallback);
93+
triple.c_str(), nullptr, 0, nullptr, symbolLookupCallback);
9394
if (!disassemblerContext) {
9495
throw std::runtime_error("Failed to initialize disassemblerContext");
9596
}

oi/arch/Arch.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#pragma once
17+
18+
#include <cstdint>
19+
#include <optional>
20+
21+
struct user_regs_struct;
22+
23+
namespace oi::detail::arch {
24+
25+
void setProgramCounter(user_regs_struct& regs, uintptr_t pc);
26+
27+
std::optional<uintptr_t> getReturnValueAddress(const user_regs_struct&);
28+
29+
} // namespace oi::detail::arch

oi/arch/aarch64.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#ifdef __aarch64__
17+
18+
extern "C" {
19+
#include <sys/user.h>
20+
}
21+
22+
#include "Arch.h"
23+
24+
namespace oi::detail::arch {
25+
26+
std::optional<uintptr_t> getReturnValueAddress(const user_regs_struct& regs) {
27+
return regs.regs[0];
28+
}
29+
30+
void setProgramCounter(user_regs_struct& regs, uintptr_t pc) {
31+
regs.pc = pc;
32+
}
33+
34+
} // namespace oi::detail::arch
35+
36+
#endif

oi/arch/x86_64.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#ifdef __x86_64__
17+
18+
extern "C" {
19+
#include <sys/user.h>
20+
}
21+
22+
#include "Arch.h"
23+
24+
namespace oi::detail::arch {
25+
26+
std::optional<uintptr_t> getReturnValueAddress(const user_regs_struct& regs) {
27+
return regs.rax;
28+
}
29+
30+
void setProgramCounter(user_regs_struct& regs, uintptr_t pc) {
31+
regs.rip = pc;
32+
}
33+
34+
} // namespace oi::detail::arch
35+
36+
#endif

0 commit comments

Comments
 (0)