Skip to content

Commit 9334235

Browse files
Initial release for socket-based remote hosts on Linux
0 parents  commit 9334235

21 files changed

+1865
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.cache
2+
.vscode
3+
build*

CMakeLists.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
cmake_minimum_required(VERSION 3.13)
2+
project(ez-clang-linux)
3+
4+
add_executable(ez-clang-linux-socket
5+
main.cpp
6+
src/abi.cpp
7+
src/assert.cpp
8+
src/protocol.cpp
9+
src/raspi32.cpp
10+
src/response.cpp
11+
src/serialize.cpp
12+
src/symbols.cpp
13+
)
14+
15+
target_include_directories(ez-clang-linux-socket PRIVATE include)
16+
target_link_libraries(ez-clang-linux-socket PRIVATE dl)
17+
target_link_options(ez-clang-linux-socket PRIVATE -rdynamic)
18+
19+
set(EZ_RESTART_PORT 10819)
20+
set(EZ_RESTART_BINARY ez-clang-linux-socket)
21+
configure_file(ez-clang-linux.service.in ez-clang-linux-socket.service @ONLY)

LICENSE

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
## Build
2+
3+
```
4+
> sudo apt update
5+
> sudo apt install -y cmake ninja-build build-essential
6+
> mkdir build
7+
> cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=On .
8+
-- The C compiler identification is GNU 10.2.1
9+
-- The CXX compiler identification is GNU 10.2.1
10+
-- Detecting C compiler ABI info
11+
-- Detecting C compiler ABI info - done
12+
-- Check for working C compiler: /usr/bin/cc - skipped
13+
-- Detecting C compile features
14+
-- Detecting C compile features - done
15+
-- Detecting CXX compiler ABI info
16+
-- Detecting CXX compiler ABI info - done
17+
-- Check for working CXX compiler: /usr/bin/c++ - skipped
18+
-- Detecting CXX compile features
19+
-- Detecting CXX compile features - done
20+
-- Configuring done
21+
-- Generating done
22+
-- Build files have been written to: /home/ez/Develop/ez-clang-linux/build
23+
> ninja -C build
24+
> ./build/ez-clang-linux-socket 10819
25+
Listening on port 10819
26+
```
27+
28+
## Setup Systemd service for auto restart
29+
30+
```
31+
> sudo cp build/ez-clang-linux-socket.service /etc/systemd/user/.
32+
> sudo systemctl daemon-reload
33+
> systemctl --user start ez-clang-linux-socket
34+
> systemctl --user status ez-clang-linux-socket
35+
● ez-clang-linux-socket.service - Permanent ez-clang-linux remote host service
36+
Loaded: loaded (/etc/systemd/system/ez-clang-linux-socket.service; disabled; vendor preset: enabled)
37+
Active: activating (start) since Thu 2023-01-26 15:22:14 CET; 3s ago
38+
Cntrl PID: 18118 (ez-clang-linux-)
39+
Tasks: 1 (limit: 1596)
40+
CPU: 24ms
41+
CGroup: /system.slice/ez-clang-linux-socket.service
42+
└─18118 /home/ez/Develop/ez-clang-linux/build/ez-clang-linux-socket 10819
43+
44+
Jan 26 15:22:14 raspberrypi systemd[1]: Starting Permanent ez-clang-linux remote host service...
45+
> systemctl enable --user ez-clang-linux-socket
46+
Created symlink /home/ez/.config/systemd/user/multi-user.target.wants/ez-clang-linux-socket.service → /etc/xdg/systemd/user/ez-clang-linux-socket.service.
47+
```
48+
49+
## Dump Systemd service log
50+
51+
```
52+
> journalctl --user -u ez-clang-linux-socket.service --follow
53+
Jan 30 10:39:42 raspberrypi systemd[1]: Starting Permanent ez-clang-linux remote host service...
54+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: Listening on port 10819
55+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: Connected
56+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: Send ->
57+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: 6a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
58+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: Send ->
59+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: 05 00 00 00 00 00 00 00 30 2e 30 2e 35 00 80 39 01 00 00 00 00 00 80 00 00 00 00 00 00 01 00 00 00 00 00 00 00 15 00 00 00 00 00 00 00 5f 5f 65 7a 5f 63 6c 61 6e 67 5f 72 70 63 5f 6c 6f 6f 6b 75 70 94 26 01 00 00 00 00 00
60+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: Receive <-
61+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: 20 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
62+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: Send ->
63+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: 21 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
64+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: Send ->
65+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: 00
66+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: Receive <-
67+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: 20 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
68+
Jan 30 10:40:36 raspberrypi ez-clang-linux-socket[4827]: Exiting
69+
Jan 30 10:40:36 raspberrypi systemd[1]: ez-clang-linux-socket.service: Succeeded.
70+
Jan 30 10:40:36 raspberrypi systemd[1]: Started Permanent ez-clang-linux remote host service.
71+
Jan 30 10:40:36 raspberrypi systemd[1]: ez-clang-linux-socket.service: Scheduled restart job, restart counter is at 2.
72+
Jan 30 10:40:36 raspberrypi systemd[1]: Stopped Permanent ez-clang-linux remote host service.
73+
Jan 30 10:40:36 raspberrypi systemd[1]: Starting Permanent ez-clang-linux remote host service...
74+
Jan 30 10:40:37 raspberrypi ez-clang-linux-socket[4926]: Listening on port 10819
75+
```

ez-clang-linux.service.in

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[Unit]
2+
Description=Permanent ez-clang-linux remote host service
3+
After=network-online.target
4+
StartLimitBurst=10
5+
StartLimitIntervalSec=1
6+
7+
[Service]
8+
Type=simple
9+
ExecStart=@CMAKE_BINARY_DIR@/@EZ_RESTART_BINARY@ @EZ_RESTART_PORT@
10+
Restart=always
11+
12+
[Install]
13+
WantedBy=multi-user.target

include/ez/abi.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#ifndef EZ_ABI_H
2+
#define EZ_ABI_H
3+
4+
#ifdef __cplusplus
5+
#include <cstddef>
6+
#include <cstdint>
7+
#else
8+
#include <stddef.h>
9+
#include <stdint.h>
10+
#endif
11+
12+
#ifdef __cplusplus
13+
extern "C" {
14+
#endif
15+
16+
#define EZ_CLANG_RPC_ENDPOINT(Name) char *Name(const char *Data, size_t Size)
17+
18+
// RPC endpoints:
19+
EZ_CLANG_RPC_ENDPOINT(__ez_clang_rpc_lookup);
20+
EZ_CLANG_RPC_ENDPOINT(__ez_clang_rpc_commit);
21+
EZ_CLANG_RPC_ENDPOINT(__ez_clang_rpc_execute);
22+
EZ_CLANG_RPC_ENDPOINT(__ez_clang_rpc_mem_read_cstring);
23+
24+
#undef EZ_CLANG_RPC_ENDPOINT
25+
26+
char *__ez_clang_inline_heap_acquire(size_t Bytes);
27+
void __ez_clang_report_string(const char *Data, size_t Size);
28+
void __ez_clang_report_value(uint32_t SeqID, const char *Blob, size_t Size);
29+
30+
#ifdef __cplusplus
31+
} // extern "C"
32+
#endif
33+
34+
#endif // EZ_ABI_H

include/ez/assert.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#ifndef EZ_ASSERT_H
2+
#define EZ_ASSERT_H
3+
4+
#include "support.h"
5+
6+
#include <cstdint>
7+
#include <csetjmp>
8+
9+
#if defined(assert)
10+
static_assert(false, "Internal assert() clashes with existing definition");
11+
#endif
12+
13+
#if !defined(NDEBUG) // && defined(DEBUG)
14+
15+
void assert(bool Premise, const char *Description);
16+
EZ_NORETURN void fail(const char *Description);
17+
18+
#else
19+
# define assert(Premise, Description)
20+
# define fail(Description)
21+
#endif
22+
23+
extern jmp_buf GlobalAssertionFailureReturnPoint;
24+
extern char *GlobalAssertionFailureBuffer;
25+
extern uint32_t GlobalAssertionFailureBufferSize;
26+
27+
#endif // EZ_ASSERT_H

include/ez/device.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef EZ_DEVICE_H
2+
#define EZ_DEVICE_H
3+
4+
#include <cstddef>
5+
#include <cstdint>
6+
#include <string>
7+
8+
void device_notifyBoot();
9+
void device_notifyReady();
10+
void device_notifyTick();
11+
void device_notifyShutdown();
12+
13+
void device_setupSendReceive();
14+
void device_sendBytes(const char *Buffer, size_t Size);
15+
bool device_receiveBytes(char Buffer[], uint32_t Count);
16+
17+
void device_flushReceiveBuffer();
18+
19+
// Ad-hoc device interface extensions for Linux/sockets support
20+
char *device_allocCodeBuffer(size_t Size);
21+
void device_listenOnPort(std::string PortStr);
22+
23+
#endif // EZ_DEVICE_H

include/ez/protocol.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#ifndef EZ_PROTOCOL_H
2+
#define EZ_PROTOCOL_H
3+
4+
#include "ez/abi.h"
5+
#include "ez/serialize.h"
6+
#include "ez/symbols.h"
7+
8+
#include <cstddef>
9+
#include <cstdint>
10+
11+
typedef char* RPCEndpoint(const char *Data, size_t Size);
12+
13+
enum EPCOpCode : uint32_t {
14+
Setup,
15+
Hangup,
16+
Result,
17+
Call,
18+
ReportValue,
19+
ReportString,
20+
LastOpC = ReportString
21+
};
22+
23+
struct SetupInfo {
24+
const char *Version;
25+
char *CodeBuffer;
26+
uint32_t CodeBufferSize;
27+
uint32_t NumSymbols;
28+
const Symbol *Symbols;
29+
};
30+
31+
struct HeaderInfo {
32+
uint32_t SeqID;
33+
uint32_t OpCode;
34+
uint32_t PayloadBytes;
35+
RPCEndpoint *Handler;
36+
};
37+
38+
bool receiveMessage(char Buffer[], uint32_t BufferSize, HeaderInfo &Msg);
39+
40+
void sendMessage(EPCOpCode OpC, uint32_t SeqID, const char Payload[],
41+
uint32_t NumArgBytes);
42+
43+
void sendSetupMessage(char Buffer[], SetupInfo Info);
44+
45+
void sendHangupMessage(uint8_t ErrCode);
46+
47+
#endif // EZ_PROTOCOL_H

include/ez/response.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef EZ_RESPONSE_H
2+
#define EZ_RESPONSE_H
3+
4+
#include <cstddef>
5+
#include <cstdint>
6+
7+
extern char *GlobalResponseBuffer;
8+
extern size_t GlobalResponseCapacity;
9+
extern const char *GlobalResponseBufferEnd;
10+
11+
char *responseAcquire(uint32_t ExpectedBytes);
12+
char *responseFinalize(char *ResponseEnd);
13+
const char *responseSetBuffer(char *InputEnd, size_t Capacity);
14+
void responseClearBuffer();
15+
16+
const char *responseGetBuffer();
17+
const char *responseGetLimit();
18+
19+
char *error(const char *Fmt, ...);
20+
char *errorEx(char *Buffer, uint32_t Size, const char *Fmt, ...);
21+
22+
const char *errorGetBuffer(uint32_t &Size);
23+
char *errorFinalize(uint32_t Length);
24+
25+
uint32_t formatlnBytesHex(char Buffer[], const char *Bytes,
26+
size_t BytesRemaining, size_t LineMax = 0);
27+
28+
#endif // EZ_RESPONSE_H

0 commit comments

Comments
 (0)