Skip to content

Commit 241cc76

Browse files
committed
Swap endian-ness in tools on big endian host
1 parent 2520412 commit 241cc76

File tree

4 files changed

+106
-69
lines changed

4 files changed

+106
-69
lines changed

elf.h

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,44 +17,45 @@
1717

1818
#define PT_LOAD 0x00000001u
1919

20+
/* Note, only little endian ELFs handled */
2021
#pragma pack(push, 1)
2122
struct elf_header {
22-
uint32_t magic;
23+
le_uint32_t magic;
2324
uint8_t arch_class;
2425
uint8_t endianness;
2526
uint8_t version;
2627
uint8_t abi;
2728
uint8_t abi_version;
2829
uint8_t _pad[7];
29-
uint16_t type;
30-
uint16_t machine;
31-
uint32_t version2;
30+
le_uint16_t type;
31+
le_uint16_t machine;
32+
le_uint32_t version2;
3233
};
3334

3435
struct elf32_header {
3536
struct elf_header common;
36-
uint32_t entry;
37-
uint32_t ph_offset;
38-
uint32_t sh_offset;
39-
uint32_t flags;
40-
uint16_t eh_size;
41-
uint16_t ph_entry_size;
42-
uint16_t ph_num;
43-
uint16_t sh_entry_size;
44-
uint16_t sh_num;
45-
uint16_t sh_str_index;
37+
le_uint32_t entry;
38+
le_uint32_t ph_offset;
39+
le_uint32_t sh_offset;
40+
le_uint32_t flags;
41+
le_uint16_t eh_size;
42+
le_uint16_t ph_entry_size;
43+
le_uint16_t ph_num;
44+
le_uint16_t sh_entry_size;
45+
le_uint16_t sh_num;
46+
le_uint16_t sh_str_index;
4647
};
4748

4849
struct elf32_ph_entry {
49-
uint32_t type;
50-
uint32_t offset;
51-
uint32_t vaddr;
52-
uint32_t paddr;
53-
uint32_t filez;
54-
uint32_t memsz;
55-
uint32_t flags;
56-
uint32_t align;
50+
le_uint32_t type;
51+
le_uint32_t offset;
52+
le_uint32_t vaddr;
53+
le_uint32_t paddr;
54+
le_uint32_t filez;
55+
le_uint32_t memsz;
56+
le_uint32_t flags;
57+
le_uint32_t align;
5758
};
5859
#pragma pack(pop)
5960

60-
#endif
61+
#endif

main.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,16 @@
1919
#include <array>
2020
#include <cstring>
2121
#include <cstdarg>
22+
#include <cstdint>
2223
#include <algorithm>
2324
#include <iomanip>
2425
#include <numeric>
2526
#include <memory>
2627
#include <functional>
28+
#include "pico/platform.h"
29+
#define le_uint16_t stored_little_endian<uint16_t>
30+
#define le_uint32_t stored_little_endian<uint32_t>
31+
#define le_int32_t stored_little_endian<int32_t>
2732
#include "boot/uf2.h"
2833
#include "picoboot_connection_cxx.h"
2934
#include "pico/binary_info.h"
@@ -587,6 +592,12 @@ int parse(const int argc, char **argv) {
587592
return 0;
588593
}
589594

595+
// This is an le_uint32_t which can be initialized (but not put in a packed struct)
596+
class instruction_t : le_uint32_t {
597+
public:
598+
instruction_t(uint32_t i) { *this = i; }
599+
};
600+
590601
template <typename T> struct raw_type_mapping {
591602
};
592603

@@ -599,8 +610,9 @@ template <typename T> struct raw_type_mapping {
599610
// these types may be filled directly from byte representation
600611
SAFE_MAPPING(uint8_t);
601612
SAFE_MAPPING(char);
602-
SAFE_MAPPING(uint16_t);
603-
SAFE_MAPPING(uint32_t);
613+
SAFE_MAPPING(le_uint16_t);
614+
SAFE_MAPPING(le_uint32_t);
615+
SAFE_MAPPING(instruction_t);
604616
SAFE_MAPPING(binary_info_core_t);
605617
SAFE_MAPPING(binary_info_id_and_int_t);
606618
SAFE_MAPPING(binary_info_id_and_string_t);
@@ -624,14 +636,14 @@ struct memory_access {
624636

625637
uint32_t read_int(uint32_t addr) {
626638
assert(!(addr & 3u));
627-
uint32_t rc;
639+
le_uint32_t rc;
628640
read(addr, (uint8_t *)&rc, 4);
629641
return rc;
630642
}
631643

632644
uint32_t read_short(uint32_t addr) {
633645
assert(!(addr & 1u));
634-
uint16_t rc;
646+
le_uint16_t rc;
635647
read(addr, (uint8_t *)&rc, 2);
636648
return rc;
637649
}
@@ -713,7 +725,7 @@ struct picoboot_memory_access : public memory_access {
713725
// read by memcpy instead
714726
uint program_base = SRAM_START + 0x4000;
715727
// program is "return memcpy(SRAM_BASE, 0, 0x4000);"
716-
std::vector<uint32_t> program = {
728+
std::vector<instruction_t> program = {
717729
0x07482101, // movs r1, #1; lsls r0, r1, #29
718730
0x2100038a, // lsls r2, r1, #14; movs r1, #0
719731
0x47184b00, // ldr r3, [pc, #0]; bx r3
@@ -881,7 +893,7 @@ static void __noreturn fail_write_error() {
881893
}
882894

883895
struct binary_info_header {
884-
vector<uint32_t> bi_addr;
896+
vector<le_uint32_t> bi_addr;
885897
range_map<uint32_t> reverse_copy_mapping;
886898
};
887899

@@ -891,7 +903,7 @@ bool find_binary_info(memory_access& access, binary_info_header &hdr) {
891903
fail(ERROR_FORMAT, "UF2 file does not contain a valid RP2 executable image");
892904
}
893905
if (base == FLASH_START) base += 0x100;
894-
vector<uint32_t> buffer = access.read_vector<uint32_t>(base, 64);
906+
vector<le_uint32_t> buffer = access.read_vector<le_uint32_t>(base, 64);
895907
for(uint i=0;i<64;i++) {
896908
if (buffer[i] == BINARY_INFO_MARKER_START) {
897909
if (i + 4 < 64 && buffer[i+4] == BINARY_INFO_MARKER_END) {
@@ -905,9 +917,9 @@ bool find_binary_info(memory_access& access, binary_info_header &hdr) {
905917
is_size_aligned(to, 4)) {
906918
access.read_into_vector(from, (to - from) / 4, hdr.bi_addr);
907919
uint32_t cpy_table = buffer[i+3];
908-
vector<uint32_t> mapping;
920+
vector<le_uint32_t> mapping;
909921
do {
910-
mapping = access.read_vector<uint32_t>(cpy_table, 3);
922+
mapping = access.read_vector<le_uint32_t>(cpy_table, 3);
911923
if (!mapping[0]) break;
912924
// from, to_start, to_end
913925
hdr.reverse_copy_mapping.insert(range(mapping[1], mapping[2]), mapping[0]);
@@ -1042,11 +1054,11 @@ struct bi_visitor_base {
10421054
}
10431055

10441056
virtual void zero_terminated_bi_list(memory_access& access, const binary_info_core_t &bi_core, uint32_t addr) {
1045-
uint32_t bi_addr;
1046-
access.read_raw<uint32_t>(addr,bi_addr);
1057+
le_uint32_t bi_addr;
1058+
access.read_raw<le_uint32_t>(addr,bi_addr);
10471059
while (bi_addr) {
10481060
visit(access, addr);
1049-
access.read_raw<uint32_t>(addr,bi_addr);
1061+
access.read_raw<le_uint32_t>(addr,bi_addr);
10501062
}
10511063
}
10521064

@@ -1918,7 +1930,7 @@ void reboot_command::execute(device_map &devices) {
19181930
} else {
19191931
picoboot_memory_access raw_access(con);
19201932
uint program_base = SRAM_START;
1921-
std::vector<uint32_t> program = {
1933+
std::vector<instruction_t> program = {
19221934
0x20002100, // movs r0, #0; movs r1, #0
19231935
0x47104a00, // ldr r2, [pc, #0]; bx r2
19241936
bootrom_func_lookup(raw_access, rom_table_code('U','B'))

picoboot_connection/picoboot_connection.c

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77
#include <stdlib.h>
88
#include <string.h>
99
#include <stdbool.h>
10+
#include <stdint.h>
11+
12+
#define le_uint16_t le_uint16_t
13+
#define le_uint32_t le_uint32_t
14+
#define le_int32_t le_int32_t
15+
16+
typedef struct { uint8_t v[2]; } le_uint16_t;
17+
typedef struct { uint8_t v[4]; } le_uint32_t;
18+
typedef le_uint32_t le_int32_t;
1019

1120
#include "picoboot_connection.h"
1221

@@ -25,6 +34,16 @@ static bool verbose;
2534
#define PRODUCT_ID_PICOPROBE 0x0004u
2635
#define PRODUCT_ID_MICROPYTHON 0x0005u
2736

37+
static uint32_t le32_to_host(le_uint32_t le)
38+
{
39+
return le.v[0] | (le.v[1] << 8) | (le.v[2] << 16) | (le.v[3] << 24);
40+
}
41+
42+
static le_uint32_t host_to_le32(uint32_t host)
43+
{
44+
return (le_uint32_t){{ host, host>>8, host>>16, host>>24 }};
45+
}
46+
2847
uint32_t crc32_for_byte(uint32_t remainder) {
2948
const uint32_t POLYNOMIAL = 0x4C11DB7;
3049
remainder <<= 24u;
@@ -200,8 +219,8 @@ int picoboot_cmd(libusb_device_handle *usb_device, struct picoboot_cmd *cmd, uin
200219
int ret;
201220

202221
static int token = 1;
203-
cmd->dMagic = PICOBOOT_MAGIC;
204-
cmd->dToken = token++;
222+
cmd->dMagic = host_to_le32(PICOBOOT_MAGIC);
223+
cmd->dToken = host_to_le32(token++);
205224
ret = libusb_bulk_transfer(usb_device, out_ep, (uint8_t *) cmd, sizeof(struct picoboot_cmd), &sent, 3000);
206225

207226
if (ret != 0 || sent != sizeof(struct picoboot_cmd)) {
@@ -214,22 +233,22 @@ int picoboot_cmd(libusb_device_handle *usb_device, struct picoboot_cmd *cmd, uin
214233
timeout = one_time_bulk_timeout;
215234
one_time_bulk_timeout = 0;
216235
}
217-
if (cmd->dTransferLength != 0) {
218-
assert(buf_size >= cmd->dTransferLength);
236+
if (le32_to_host(cmd->dTransferLength) != 0) {
237+
assert(buf_size >= le32_to_host(cmd->dTransferLength));
219238
if (cmd->bCmdId & 0x80u) {
220-
if (verbose) output(" receive %d...\n", cmd->dTransferLength);
239+
if (verbose) output(" receive %d...\n", (int)le32_to_host(cmd->dTransferLength));
221240
int received = 0;
222-
ret = libusb_bulk_transfer(usb_device, in_ep, buffer, cmd->dTransferLength, &received, timeout);
223-
if (ret != 0 || received != (int) cmd->dTransferLength) {
224-
output(" ...failed to receive data %d %d/%d\n", ret, received, cmd->dTransferLength);
241+
ret = libusb_bulk_transfer(usb_device, in_ep, buffer, le32_to_host(cmd->dTransferLength), &received, timeout);
242+
if (ret != 0 || received != (int) le32_to_host(cmd->dTransferLength)) {
243+
output(" ...failed to receive data %d %d/%d\n", ret, received, (int)le32_to_host(cmd->dTransferLength));
225244
if (!ret) ret = 1;
226245
return ret;
227246
}
228247
} else {
229-
if (verbose) output(" send %d...\n", cmd->dTransferLength);
230-
ret = libusb_bulk_transfer(usb_device, out_ep, buffer, cmd->dTransferLength, &sent, timeout);
231-
if (ret != 0 || sent != (int) cmd->dTransferLength) {
232-
output(" ...failed to send data %d %d/%d\n", ret, sent, cmd->dTransferLength);
248+
if (verbose) output(" send %d...\n", (int)le32_to_host(cmd->dTransferLength));
249+
ret = libusb_bulk_transfer(usb_device, out_ep, buffer, le32_to_host(cmd->dTransferLength), &sent, timeout);
250+
if (ret != 0 || sent != (int) le32_to_host(cmd->dTransferLength)) {
251+
output(" ...failed to send data %d %d/%d\n", ret, sent, (int)le32_to_host(cmd->dTransferLength));
233252
if (!ret) ret = 1;
234253
picoboot_cmd_status_verbose(usb_device, NULL, true);
235254
return ret;
@@ -242,10 +261,10 @@ int picoboot_cmd(libusb_device_handle *usb_device, struct picoboot_cmd *cmd, uin
242261
uint8_t spoon[64];
243262
if (cmd->bCmdId & 0x80u) {
244263
if (verbose) output("zero length out\n");
245-
ret = libusb_bulk_transfer(usb_device, out_ep, spoon, 1, &received, cmd->dTransferLength == 0 ? timeout : 3000);
264+
ret = libusb_bulk_transfer(usb_device, out_ep, spoon, 1, &received, le32_to_host(cmd->dTransferLength) == 0 ? timeout : 3000);
246265
} else {
247266
if (verbose) output("zero length in\n");
248-
ret = libusb_bulk_transfer(usb_device, in_ep, spoon, 1, &received, cmd->dTransferLength == 0 ? timeout : 3000);
267+
ret = libusb_bulk_transfer(usb_device, in_ep, spoon, 1, &received, le32_to_host(cmd->dTransferLength) == 0 ? timeout : 3000);
249268
}
250269
return ret;
251270
}
@@ -256,7 +275,7 @@ int picoboot_exclusive_access(libusb_device_handle *usb_device, uint8_t exclusiv
256275
cmd.bCmdId = PC_EXCLUSIVE_ACCESS;
257276
cmd.exclusive_cmd.bExclusive = exclusive;
258277
cmd.bCmdSize = sizeof(struct picoboot_exclusive_cmd);
259-
cmd.dTransferLength = 0;
278+
cmd.dTransferLength = host_to_le32(0);
260279
return picoboot_cmd(usb_device, &cmd, NULL, 0);
261280
}
262281

@@ -265,7 +284,7 @@ int picoboot_exit_xip(libusb_device_handle *usb_device) {
265284
if (verbose) output("EXIT_XIP\n");
266285
cmd.bCmdId = PC_EXIT_XIP;
267286
cmd.bCmdSize = 0;
268-
cmd.dTransferLength = 0;
287+
cmd.dTransferLength = host_to_le32(0);
269288
return picoboot_cmd(usb_device, &cmd, NULL, 0);
270289
}
271290

@@ -274,7 +293,7 @@ int picoboot_enter_cmd_xip(libusb_device_handle *usb_device) {
274293
if (verbose) output("ENTER_CMD_XIP\n");
275294
cmd.bCmdId = PC_ENTER_CMD_XIP;
276295
cmd.bCmdSize = 0;
277-
cmd.dTransferLength = 0;
296+
cmd.dTransferLength = host_to_le32(0);
278297
return picoboot_cmd(usb_device, &cmd, NULL, 0);
279298
}
280299

@@ -283,10 +302,10 @@ int picoboot_reboot(libusb_device_handle *usb_device, uint32_t pc, uint32_t sp,
283302
if (verbose) output("REBOOT %08x %08x %u\n", (uint) pc, (uint) sp, (uint) delay_ms);
284303
cmd.bCmdId = PC_REBOOT;
285304
cmd.bCmdSize = sizeof(cmd.reboot_cmd);
286-
cmd.dTransferLength = 0;
287-
cmd.reboot_cmd.dPC = pc;
288-
cmd.reboot_cmd.dSP = sp;
289-
cmd.reboot_cmd.dDelayMS = delay_ms;
305+
cmd.dTransferLength = host_to_le32(0);
306+
cmd.reboot_cmd.dPC = host_to_le32(pc);
307+
cmd.reboot_cmd.dSP = host_to_le32(sp);
308+
cmd.reboot_cmd.dDelayMS = host_to_le32(delay_ms);
290309
return picoboot_cmd(usb_device, &cmd, NULL, 0);
291310
}
292311

@@ -297,8 +316,8 @@ int picoboot_exec(libusb_device_handle *usb_device, uint32_t addr) {
297316
if (verbose) output("EXEC %08x\n", (uint) addr);
298317
cmd.bCmdId = PC_EXEC;
299318
cmd.bCmdSize = sizeof(cmd.address_only_cmd);
300-
cmd.dTransferLength = 0;
301-
cmd.address_only_cmd.dAddr = addr;
319+
cmd.dTransferLength = host_to_le32(0);
320+
cmd.address_only_cmd.dAddr = host_to_le32(addr);
302321
return picoboot_cmd(usb_device, &cmd, NULL, 0);
303322
}
304323

@@ -307,9 +326,9 @@ int picoboot_flash_erase(libusb_device_handle *usb_device, uint32_t addr, uint32
307326
if (verbose) output("FLASH_ERASE %08x+%08x\n", (uint) addr, (uint) len);
308327
cmd.bCmdId = PC_FLASH_ERASE;
309328
cmd.bCmdSize = sizeof(cmd.range_cmd);
310-
cmd.range_cmd.dAddr = addr;
311-
cmd.range_cmd.dSize = len;
312-
cmd.dTransferLength = 0;
329+
cmd.range_cmd.dAddr = host_to_le32(addr);
330+
cmd.range_cmd.dSize = host_to_le32(len);
331+
cmd.dTransferLength = host_to_le32(0);
313332
return picoboot_cmd(usb_device, &cmd, NULL, 0);
314333
}
315334

@@ -318,8 +337,8 @@ int picoboot_vector(libusb_device_handle *usb_device, uint32_t addr) {
318337
if (verbose) output("VECTOR %08x\n", (uint) addr);
319338
cmd.bCmdId = PC_VECTORIZE_FLASH;
320339
cmd.bCmdSize = sizeof(cmd.address_only_cmd);
321-
cmd.range_cmd.dAddr = addr;
322-
cmd.dTransferLength = 0;
340+
cmd.range_cmd.dAddr = host_to_le32(addr);
341+
cmd.dTransferLength = host_to_le32(0);
323342
return picoboot_cmd(usb_device, &cmd, NULL, 0);
324343
}
325344

@@ -328,8 +347,8 @@ int picoboot_write(libusb_device_handle *usb_device, uint32_t addr, uint8_t *buf
328347
if (verbose) output("WRITE %08x+%08x\n", (uint) addr, (uint) len);
329348
cmd.bCmdId = PC_WRITE;
330349
cmd.bCmdSize = sizeof(cmd.range_cmd);
331-
cmd.range_cmd.dAddr = addr;
332-
cmd.range_cmd.dSize = cmd.dTransferLength = len;
350+
cmd.range_cmd.dAddr = host_to_le32(addr);
351+
cmd.range_cmd.dSize = cmd.dTransferLength = host_to_le32(len);
333352
return picoboot_cmd(usb_device, &cmd, buffer, len);
334353
}
335354

@@ -339,8 +358,8 @@ int picoboot_read(libusb_device_handle *usb_device, uint32_t addr, uint8_t *buff
339358
struct picoboot_cmd cmd;
340359
cmd.bCmdId = PC_READ;
341360
cmd.bCmdSize = sizeof(cmd.range_cmd);
342-
cmd.range_cmd.dAddr = addr;
343-
cmd.range_cmd.dSize = cmd.dTransferLength = len;
361+
cmd.range_cmd.dAddr = host_to_le32(addr);
362+
cmd.range_cmd.dSize = cmd.dTransferLength = host_to_le32(len);
344363
int ret = picoboot_cmd(usb_device, &cmd, buffer, len);
345364
if (!ret && len < 256 && verbose) {
346365
for (uint32_t i = 0; i < len; i += 32) {
@@ -422,4 +441,4 @@ int picoboot_peek(libusb_device_handle *usb_device, uint32_t addr, uint32_t *dat
422441
return ret;
423442
return picoboot_read(usb_device, PEEK_POKE_CODE_LOC + picoboot_peek_cmd_len, (uint8_t *) data, sizeof(uint32_t));
424443
}
425-
#endif
444+
#endif

picoboot_connection/picoboot_connection_cxx.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
#include <system_error>
99
#include <map>
1010
#include <algorithm>
11+
#include <cstdint>
12+
#include "pico/platform.h"
13+
#define le_uint16_t stored_little_endian<uint16_t>
14+
#define le_uint32_t stored_little_endian<uint32_t>
15+
#define le_int32_t stored_little_endian<int32_t>
1116
#include "picoboot_connection_cxx.h"
1217

1318
using picoboot::connection;

0 commit comments

Comments
 (0)