RetroLinker
Linker for several 8-bit, 16-bit and 32-bit formats
Loading...
Searching...
No Matches
common.h
1#ifndef COMMON_H
2#define COMMON_H
3
4#include <cassert>
5#include <cstdint>
6#include <cstddef>
7#include <chrono>
8#include <map>
9#include <memory>
10#include <iostream>
11#include <string>
12
13typedef uint64_t offset_t;
14typedef int64_t relative_offset_t;
15typedef size_t number_t;
16
17enum EndianType
18{
19 UndefinedEndian,
20 LittleEndian,
21 BigEndian,
22 PDP11Endian, /* little endian within a 16-bit word, big endian between words */
23 AntiPDP11Endian,
24};
25
26static constexpr EndianType ByteSwapped(EndianType endian_type)
27{
28 switch(endian_type)
29 {
30 case UndefinedEndian:
31 return UndefinedEndian;
32 case LittleEndian:
33 return BigEndian;
34 case BigEndian:
35 return LittleEndian;
36 case PDP11Endian:
37 return AntiPDP11Endian;
38 case AntiPDP11Endian:
39 return PDP11Endian;
40 }
41 assert(false);
42}
43
44extern EndianType DefaultEndianType;
45
49size_t GetOffset(EndianType endiantype, size_t bytes, size_t index);
50
54offset_t AlignTo(offset_t value, offset_t align);
55
59uint16_t Swap16(uint16_t value);
60
64uint16_t FromLittleEndian16(uint16_t value);
65
69uint16_t FromBigEndian16(uint16_t value);
70
74uint32_t Swap32(uint32_t value);
75
79uint32_t Swap32words(uint32_t value);
80
84uint32_t FromLittleEndian32(uint32_t value);
85
89uint32_t FromBigEndian32(uint32_t value);
90
94uint32_t FromPDP11Endian32(uint32_t value);
95
99uint64_t Swap64(uint64_t value);
100
104uint64_t Swap64words(uint64_t value);
105
109uint64_t FromLittleEndian64(uint64_t value);
110
111uint64_t FromBigEndian64(uint64_t value);
112
113uint64_t FromPDP11Endian64(uint64_t value);
114
118uint64_t ReadUnsigned(size_t bytes, size_t maximum, uint8_t const * data, EndianType endiantype);
119
123int64_t SignExtend(size_t bytes, int64_t value);
124
128int64_t ReadSigned(size_t bytes, size_t maximum, uint8_t const * data, EndianType endiantype);
129
133void WriteWord(size_t bytes, size_t maximum, uint8_t * data, uint64_t value, EndianType endiantype);
134
135bool LookupOption(std::map<std::string, std::string>& options, std::string key, std::string& value);
136
138{
139 inline bool operator()(const std::string& first, const std::string& second) const
140 {
141 return std::ranges::equal(first.begin(), first.end(), second.begin(), second.end(),
142 [](char c1, char c2) -> bool { return std::tolower(static_cast<unsigned char>(c1)) == std::tolower(static_cast<unsigned char>(c2)); });
143 }
144};
145
147{
148 inline bool operator()(const std::string& first, const std::string& second) const
149 {
150 return std::lexicographical_compare(first.begin(), first.end(), second.begin(), second.end(),
151 [](char c1, char c2) -> bool { return std::tolower(static_cast<unsigned char>(c1)) < std::tolower(static_cast<unsigned char>(c2)); });
152 }
153};
154
160bool starts_with(std::string str, std::string start);
161
167bool ends_with(std::string str, std::string end);
168
170enum class Month : unsigned
171{
172 January = 1,
173 February = 2,
174 March = 3,
175 April = 4,
176 May = 5,
177 June = 6,
178 July = 7,
179 August = 8,
180 September = 9,
181 October = 10,
182 November = 11,
183 December = 12,
184};
185
187template <unsigned _Year, Month _Month = Month::January, unsigned _Day = 1>
189{
190 static constexpr unsigned Year = _Year;
191 static constexpr ::Month Month = _Month;
192 static constexpr unsigned Day = _Day;
193
194 static constexpr std::chrono::sys_days to_days()
195 {
196 return std::chrono::year(Year) / std::chrono::month(unsigned(Month)) / std::chrono::day(Day);
197 }
198};
199
208template <typename Epoch, typename Rep = int32_t, typename Period = std::ratio<1>>
210{
211 using rep = Rep;
212 using period = Period;
213 using duration = std::chrono::duration<rep, period>;
214 using time_point = std::chrono::time_point<VendorClock>;
215 static constexpr bool is_steady = false;
216
217 static constexpr rep to_ticks(duration dur)
218 {
219 return dur.count();
220 }
221
222 static constexpr rep to_ticks(time_point tp)
223 {
224 return to_ticks(tp.time_since_epoch());
225 }
226
227 static constexpr duration to_duration(Rep ticks)
228 {
229 return duration(ticks);
230 }
231
232 static constexpr time_point to_time_point(duration dur)
233 {
234 return time_point(dur);
235 }
236
237 static constexpr time_point to_time_point(Rep ticks)
238 {
239 return time_point(duration(ticks));
240 }
241
242 static constexpr time_point to_time_point(std::chrono::time_point<std::chrono::system_clock> tp)
243 {
244 return time_point(std::chrono::duration_cast<duration>(tp - Epoch::to_time_point()));
245 }
246
247 static constexpr time_point to_time_point(std::chrono::sys_days days, std::chrono::nanoseconds ns)
248 {
249 return time_point(std::chrono::duration_cast<duration>(days - Epoch::to_days()) + std::chrono::duration_cast<duration>(ns));
250 }
251
252 template <typename FromClock>
253 static time_point convert(std::chrono::time_point<FromClock> from)
254 {
255 return to_time_point(FromClock::to_days(from), FromClock::to_nanoseconds(from));
256 }
257
258 static constexpr std::chrono::sys_days to_days(time_point tp)
259 {
260 return Epoch::to_days() + std::chrono::duration_cast<std::chrono::days>(tp.time_since_epoch());
261 }
262
263 static constexpr std::chrono::nanoseconds to_nanoseconds(time_point tp)
264 {
265 const auto dur = tp.time_since_epoch();
266 return dur - std::chrono::duration_cast<std::chrono::days>(dur);
267 }
268
269 static std::string to_iso_time(time_point tp)
270 {
271 return std::format("{:%Y-%m-%d} {:%H:%M:%S}", to_days(tp), to_nanoseconds(tp));
272 }
273
274 static time_point now() noexcept
275 {
276 return to_time_point(std::chrono::system_clock::now());
277 }
278};
279
282
284template <typename Clock>
285 using Timestamp = std::chrono::time_point<Clock>;
286
287namespace Linker
288{
290 {
291 public:
292 std::string message;
293 Exception(std::string message) : message(message)
294 {
295 }
296 };
297
298 /* TODO: implement these properly */
299 extern std::ostream Debug;
300 extern std::ostream Warning;
301 extern std::ostream Error;
302
303 [[noreturn]] void FatalError(std::string message);
304
305 class Section;
306 class Location;
307 typedef std::map<std::shared_ptr<Section>, Location> Displacement;
308}
309
310#endif /* COMMON_H */
Definition common.h:290
Represents a single offset within a section, or an absolute location in memory if the section is null...
Definition location.h:17
A section of data as read from an object file.
Definition section.h:28
Definition common.h:138
Definition common.h:147
Provides a type for compile-time constants representing Gregorian dates.
Definition common.h:189
A static class that encodes a specific timestamp format.
Definition common.h:210