Skip to content

Commit 1c46c84

Browse files
committed
project Switch to c++23. Use std::print. Many other improvements
1 parent 63dff8b commit 1c46c84

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+5535
-3255
lines changed

CMakePresets.json

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"version": 2,
33
"cmakeMinimumRequired": {
44
"major": 3,
5-
"minor": 5,
5+
"minor": 10,
66
"patch": 0
77
},
88
"configurePresets": [
@@ -18,8 +18,9 @@
1818
"generator": "Ninja",
1919
"cacheVariables": {
2020
"CMAKE_BUILD_TYPE": "Debug",
21-
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
22-
"CMAKE_CXX_FLAGS_INIT": "$env{CXX_FLAGS}"
21+
"CMAKE_C_COMPILER": "clang",
22+
"CMAKE_CXX_COMPILER": "clang++",
23+
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
2324
},
2425
"inherits": ["base"]
2526
},
@@ -30,7 +31,9 @@
3031
"generator": "Ninja",
3132
"cacheVariables": {
3233
"CMAKE_BUILD_TYPE": "Release",
33-
"CMAKE_CXX_FLAGS_INIT": "$env{CXX_FLAGS} -O3 -Wno-unused-parameter -Wunused-variable"
34+
"CMAKE_C_COMPILER": "clang",
35+
"CMAKE_CXX_COMPILER": "clang++",
36+
"CMAKE_CXX_FLAGS_INIT": "-O3 -Wno-unused-parameter -Wunused-variable"
3437
},
3538
"inherits": ["base"]
3639
}

include/ADT/AddressResolver.h

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//
2+
// ADT/AddressResolver.h
3+
// © suhas pai
4+
//
5+
// Created by suhas pai on 12/16/24.
6+
//
7+
8+
#pragma once
9+
10+
#include <expected>
11+
#include <variant>
12+
13+
#include "ADT/MemoryMap.h"
14+
#include "Dyld3/ChainedFixups.h"
15+
16+
#include "MachO/BindInfo.h"
17+
#include "MachO/Header.h"
18+
#include "MachO/LoadCommands.h"
19+
#include "MachO/RebaseInfo.h"
20+
#include "MachO/SegmentList.h"
21+
22+
namespace ADT {
23+
struct AddressResolver {
24+
protected:
25+
MachO::BindActionList::UnorderedMap BindMap;
26+
MachO::RebaseActionList::UnorderedMap RebaseMap;
27+
28+
Dyld3::ChainedPointerKind ChainedFixupsKind;
29+
30+
explicit
31+
AddressResolver(
32+
MachO::BindActionList::UnorderedMap &&BindMap,
33+
MachO::RebaseActionList::UnorderedMap &&RebaseMap,
34+
Dyld3::ChainedPointerKind ChainedFixupsKind) noexcept
35+
: BindMap(std::move(BindMap)), RebaseMap(std::move(RebaseMap)),
36+
ChainedFixupsKind(ChainedFixupsKind) {}
37+
public:
38+
using BindParseError =
39+
std::pair<MachO::BindInfoKind, MachO::BindOpcodeParseResult>;
40+
41+
using RebaseParseError = MachO::RebaseOpcodeParseResult;
42+
using ParseErrorType = std::variant<BindParseError, RebaseParseError>;
43+
44+
static auto
45+
FromLoadCommands(MemoryMap Map,
46+
const MachO::Header &Header,
47+
const MachO::DyldInfoCommand *DyldInfo,
48+
const MachO::LinkeditDataCommand *ChainedFixups,
49+
const MachO::SegmentList &SegmentList) noexcept
50+
-> std::expected<AddressResolver, ParseErrorType>;
51+
52+
[[nodiscard]]
53+
auto resolveBind(uint64_t Address, uint64_t BaseAddress) const noexcept
54+
-> std::optional<const MachO::BindActionInfo *>;
55+
56+
struct ResolvedFixupResult {
57+
enum class Kind {
58+
Bind,
59+
Rebase
60+
};
61+
62+
Kind Kind;
63+
union {
64+
#pragma clang diagnostic push
65+
#pragma clang diagnostic ignored "-Wnested-anon-types"
66+
struct {
67+
uint64_t Ordinal = 0;
68+
uint64_t Addend = 0;
69+
} Bind;
70+
struct {
71+
uint64_t TargetRuntimeOffset = 0;
72+
} Rebase;
73+
#pragma clang diagnostic pop
74+
};
75+
76+
explicit ResolvedFixupResult(const enum Kind Kind) noexcept
77+
: Kind(Kind) {}
78+
79+
~ResolvedFixupResult() noexcept {}
80+
};
81+
82+
[[nodiscard]] auto
83+
resolveChainedFixup(uint64_t Value, uint64_t BaseAddress) const noexcept
84+
-> std::optional<ResolvedFixupResult>;
85+
86+
[[nodiscard]]
87+
auto resolve(uint64_t Address, uint64_t Value) const noexcept
88+
-> std::optional<uint64_t>;
89+
};
90+
}

include/ADT/DeVirtualizer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ namespace ADT {
2222
bool IgnoreSectionBounds = false) const noexcept
2323
-> std::optional<ADT::MemoryMap> = 0;
2424

25+
[[nodiscard]] virtual auto getBaseAddress() const noexcept
26+
-> uint64_t = 0;
27+
2528
template <typename T>
2629
[[nodiscard]] inline auto
2730
getDataAtAddress(const uint64_t Address,

include/ADT/FlagsIterator.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,36 +40,36 @@ namespace ADT {
4040
auto operator<=>(const FlagsIterator<T> &Rhs) const noexcept = default;
4141

4242
constexpr auto operator++() noexcept -> decltype(*this) {
43-
BitIndex++;
44-
if (BitIndex < bit_sizeof(T)) {
45-
BitIndex = Value.getFirstSet(BitIndex);
43+
if (this->BitIndex < bit_sizeof(T) - 1) {
44+
this->BitIndex++;
45+
this->BitIndex = this->Value.getFirstSet(this->BitIndex);
4646
} else {
47-
BitIndex = bit_sizeof(T);
47+
this->BitIndex = bit_sizeof(T);
4848
}
4949

5050
return *this;
5151
}
5252

5353
constexpr auto operator++(int) noexcept {
54-
return operator++();
54+
return this->operator++();
5555
}
5656

5757
[[nodiscard]] constexpr auto operator*() const noexcept {
58-
return BitIndex;
58+
return this->BitIndex;
5959
}
6060

6161
[[nodiscard]] constexpr auto mask() const noexcept {
62-
return T(1) << BitIndex;
62+
return T(1) << this->BitIndex;
6363
}
6464

6565
[[nodiscard]] constexpr
6666
auto operator==([[maybe_unused]] const EndValue &End) const noexcept {
67-
return BitIndex == bit_sizeof(T);
67+
return this->BitIndex == bit_sizeof(T);
6868
}
6969

7070
[[nodiscard]] constexpr
7171
auto operator!=([[maybe_unused]] const EndValue &End) const noexcept {
72-
return !operator==(End);
72+
return !this->operator==(End);
7373
}
7474
};
7575
}

include/ADT/MemoryMap.h

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,13 @@ namespace ADT {
2828
explicit MemoryMap(void *const Base, const uint64_t Size) noexcept
2929
: Base(Base), Size(Size) {}
3030

31+
template <typename T>
32+
constexpr explicit MemoryMap(const std::span<T> Span) noexcept
33+
: Base(Span.begin()),
34+
Size(Utils::MulAndCheckOverflow(Span.size(), sizeof(T)).value()) {}
35+
3136
[[nodiscard]] constexpr auto size() const noexcept {
32-
return Size;
37+
return this->Size;
3338
}
3439

3540
[[nodiscard]] constexpr auto empty() const noexcept {
@@ -99,29 +104,53 @@ namespace ADT {
99104
return reinterpret_cast<T *>(AdjBase);
100105
}
101106

102-
template <typename T = uint8_t, bool Verify = true>
103-
[[nodiscard]] inline auto
104-
getFromRange(const Range &Range,
105-
T **const EndOut = nullptr) const noexcept -> T *
107+
template <typename T = uint8_t,
108+
bool Verify = true,
109+
uint64_t Size = sizeof(T)>
110+
111+
[[nodiscard]] inline
112+
auto get(const Range &Range, const uint64_t Count = 1) const noexcept
113+
-> T *
106114
{
107115
if constexpr (Verify) {
108-
if (!this->range().contains(Range)) {
116+
const auto FullRangeOpt = Range.multiply(Count);
117+
if (!FullRangeOpt.has_value()) {
118+
return nullptr;
119+
}
120+
121+
const auto FullRange = FullRangeOpt.value();
122+
if (!this->range().contains(FullRange)) {
109123
return nullptr;
110124
}
111125
}
112126

113127
const auto AdjBase =
114-
reinterpret_cast<uint64_t>(Base) + Range.front();
128+
reinterpret_cast<uint8_t *>(Base) + Range.front();
115129

116-
if (EndOut != nullptr) {
117-
*EndOut = reinterpret_cast<T *>(AdjBase + Range.size());
130+
return reinterpret_cast<T *>(AdjBase);
131+
}
132+
133+
template <typename T = uint8_t, bool Verify = true>
134+
[[nodiscard]]
135+
inline auto getRange(const Range &Range) const noexcept
136+
-> std::optional<std::span<T>>
137+
{
138+
if constexpr (Verify) {
139+
if (!this->range().contains(Range)) {
140+
return std::nullopt;
141+
}
118142
}
119143

120-
return reinterpret_cast<T *>(AdjBase);
144+
const auto AdjBase =
145+
reinterpret_cast<uint64_t>(Base) + Range.front();
146+
147+
return std::span(reinterpret_cast<T *>(AdjBase),
148+
Range.size() / sizeof(T));
121149
}
122150

123-
template <typename T, uint64_t Size = sizeof(T), bool Verify = true>
124-
[[nodiscard]] constexpr auto list() const noexcept
151+
template <typename T = uint8_t, uint64_t Size = sizeof(T),
152+
bool Verify = true>
153+
[[nodiscard]] constexpr auto span() const noexcept
125154
-> std::optional<std::span<T>>
126155
{
127156
const auto Base = this->base<T, Verify>();

include/ADT/Range.h

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,28 @@ namespace ADT {
3030
return Range(Begin, Size);
3131
}
3232

33+
[[nodiscard]] constexpr static auto CreateMax() noexcept {
34+
return Range::FromSize(0, std::numeric_limits<uint64_t>::max());
35+
}
36+
37+
[[nodiscard]] constexpr static auto
38+
FromSizeAndCount(const uint64_t Begin,
39+
const uint64_t Size,
40+
const uint64_t Count) noexcept
41+
-> std::optional<ADT::Range>
42+
{
43+
auto TotalSize = Utils::MulAndCheckOverflow(Size, Count);
44+
if (TotalSize.has_value()) {
45+
return Range::FromSize(Begin, TotalSize.value());
46+
}
47+
48+
return std::nullopt;
49+
}
50+
3351
[[nodiscard]] constexpr static
3452
auto FromEnd(const uint64_t Begin, const uint64_t End) noexcept {
3553
assert(Begin <= End);
36-
return Range(Begin, (End - Begin));
54+
return Range::FromSize(Begin, (End - Begin));
3755
}
3856

3957
[[nodiscard]] constexpr auto front() const noexcept {
@@ -44,6 +62,29 @@ namespace ADT {
4462
return this->Size;
4563
}
4664

65+
[[nodiscard]]
66+
constexpr auto adding(const uint64_t Base) const noexcept
67+
-> std::optional<Range>
68+
{
69+
auto NewBegin = uint64_t();
70+
if (!Utils::AddAndCheckOverflow(this->front(), Base, NewBegin)) {
71+
return std::nullopt;
72+
}
73+
74+
return Range::FromSize(NewBegin, this->size());
75+
}
76+
77+
[[nodiscard]]
78+
constexpr auto subtracting(const uint64_t Base) const noexcept
79+
-> std::optional<Range>
80+
{
81+
if (Base > this->front()) {
82+
return std::nullopt;
83+
}
84+
85+
return Range::FromSize(this->front() - Base, this->size());
86+
}
87+
4788
[[nodiscard]] constexpr auto end() const noexcept {
4889
return Utils::AddAndCheckOverflow(this->front(), this->size());
4990
}
@@ -144,7 +185,7 @@ namespace ADT {
144185
indexForLoc(const uint64_t Loc,
145186
uint64_t *const MaxSizeOut = nullptr) const noexcept
146187
{
147-
assert(hasLoc(Loc));
188+
assert(this->hasLoc(Loc));
148189

149190
const auto Index = Loc - this->front();
150191
if (MaxSizeOut != nullptr) {
@@ -234,6 +275,18 @@ namespace ADT {
234275
return Range::FromSize(0, Index);
235276
}
236277

278+
[[nodiscard]]
279+
constexpr auto multiply(const uint64_t Count) const noexcept
280+
-> std::optional<Range>
281+
{
282+
auto NewSize = uint64_t();
283+
if (Utils::MulAddAndCheckOverflow(this->size(), Count, NewSize)) {
284+
return std::nullopt;
285+
}
286+
287+
return Range::FromSize(this->front(), NewSize);
288+
}
289+
237290
[[nodiscard]]
238291
constexpr auto operator==(const Range &Range) const noexcept {
239292
return this->front() == Range.front() &&

include/ADT/Tree.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ namespace ADT {
567567
{
568568
const auto RootDepthLevel = uint64_t(1);
569569
if (NodePrinterFunc(OutFile, 0, RootDepthLevel, *this)) {
570-
fputc('\n', OutFile);
570+
std::print(OutFile, "\n");
571571
}
572572

573573
auto Iter = TreeDFSIterator<const TreeNode>(this);
@@ -580,7 +580,7 @@ namespace ADT {
580580

581581
for (auto I = RootDepthLevel; I != End; I++) {
582582
if (Iter.getParentAtIndex(I)->nextSibling() != nullptr) {
583-
fputs("", OutFile);
583+
std::print(OutFile, "");
584584
WrittenOut += Utils::PadSpaces(OutFile, TabLength) + 1;
585585
} else {
586586
WrittenOut += Utils::PadSpaces(OutFile, TabLength + 1);
@@ -589,9 +589,9 @@ namespace ADT {
589589

590590
WrittenOut += 1;
591591
if (Iter->nextSibling() != nullptr) {
592-
fputs("", OutFile);
592+
std::print(OutFile, "");
593593
} else {
594-
fputs("", OutFile);
594+
std::print(OutFile, "");
595595
}
596596

597597
// Add 1 for the ├ or └ character, and 1 for the space after the
@@ -600,11 +600,11 @@ namespace ADT {
600600
WrittenOut += static_cast<int>(TabLength) + 2;
601601
Utils::PrintMultTimes(OutFile, "", TabLength);
602602

603-
fputc(' ', OutFile);
603+
std::print(OutFile, " ");
604604
WrittenOut += 1;
605605

606606
NodePrinterFunc(OutFile, WrittenOut, DepthLevel, Info);
607-
fputc('\n', OutFile);
607+
std::print(OutFile, "\n");
608608
}
609609

610610
return *this;

0 commit comments

Comments
 (0)