Skip to content

Commit 90e098e

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

File tree

4 files changed

+109
-69
lines changed

4 files changed

+109
-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: 28 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"
@@ -599,8 +604,8 @@ template <typename T> struct raw_type_mapping {
599604
// these types may be filled directly from byte representation
600605
SAFE_MAPPING(uint8_t);
601606
SAFE_MAPPING(char);
602-
SAFE_MAPPING(uint16_t);
603-
SAFE_MAPPING(uint32_t);
607+
SAFE_MAPPING(le_uint16_t);
608+
SAFE_MAPPING(le_uint32_t);
604609
SAFE_MAPPING(binary_info_core_t);
605610
SAFE_MAPPING(binary_info_id_and_int_t);
606611
SAFE_MAPPING(binary_info_id_and_string_t);
@@ -624,14 +629,14 @@ struct memory_access {
624629

625630
uint32_t read_int(uint32_t addr) {
626631
assert(!(addr & 3u));
627-
uint32_t rc;
632+
le_uint32_t rc;
628633
read(addr, (uint8_t *)&rc, 4);
629634
return rc;
630635
}
631636

632637
uint32_t read_short(uint32_t addr) {
633638
assert(!(addr & 1u));
634-
uint16_t rc;
639+
le_uint16_t rc;
635640
read(addr, (uint8_t *)&rc, 2);
636641
return rc;
637642
}
@@ -719,7 +724,7 @@ struct picoboot_memory_access : public memory_access {
719724
0x47184b00, // ldr r3, [pc, #0]; bx r3
720725
bootrom_func_lookup(*this, rom_table_code('M','C'))
721726
};
722-
write_vector(program_base, program);
727+
write_program(program_base, program);
723728
connection.exec(program_base);
724729
// 4k is copied into the start of RAM
725730
connection.read(SRAM_START + address, (uint8_t *) buffer, size);
@@ -759,6 +764,16 @@ struct picoboot_memory_access : public memory_access {
759764
assert(!v.empty());
760765
write(addr, (uint8_t *)v.data(), v.size() * sizeof(typename raw_type_mapping<T>::access_type));
761766
}
767+
void write_program(uint32_t addr, const vector<uint32_t> &program) {
768+
// Instructions generated by host code need to be converted into
769+
// le_uint32_t vectors first
770+
assert(!program.empty());
771+
vector<le_uint32_t> r;
772+
r.resize(program.size());
773+
for (unsigned i = 0; i < program.size(); i++)
774+
r[i] = program[i];
775+
write_vector(addr, r);
776+
}
762777
private:
763778
picoboot::connection& connection;
764779
};
@@ -881,7 +896,7 @@ static void __noreturn fail_write_error() {
881896
}
882897

883898
struct binary_info_header {
884-
vector<uint32_t> bi_addr;
899+
vector<le_uint32_t> bi_addr;
885900
range_map<uint32_t> reverse_copy_mapping;
886901
};
887902

@@ -891,7 +906,7 @@ bool find_binary_info(memory_access& access, binary_info_header &hdr) {
891906
fail(ERROR_FORMAT, "UF2 file does not contain a valid RP2 executable image");
892907
}
893908
if (base == FLASH_START) base += 0x100;
894-
vector<uint32_t> buffer = access.read_vector<uint32_t>(base, 64);
909+
vector<le_uint32_t> buffer = access.read_vector<le_uint32_t>(base, 64);
895910
for(uint i=0;i<64;i++) {
896911
if (buffer[i] == BINARY_INFO_MARKER_START) {
897912
if (i + 4 < 64 && buffer[i+4] == BINARY_INFO_MARKER_END) {
@@ -905,9 +920,9 @@ bool find_binary_info(memory_access& access, binary_info_header &hdr) {
905920
is_size_aligned(to, 4)) {
906921
access.read_into_vector(from, (to - from) / 4, hdr.bi_addr);
907922
uint32_t cpy_table = buffer[i+3];
908-
vector<uint32_t> mapping;
923+
vector<le_uint32_t> mapping;
909924
do {
910-
mapping = access.read_vector<uint32_t>(cpy_table, 3);
925+
mapping = access.read_vector<le_uint32_t>(cpy_table, 3);
911926
if (!mapping[0]) break;
912927
// from, to_start, to_end
913928
hdr.reverse_copy_mapping.insert(range(mapping[1], mapping[2]), mapping[0]);
@@ -1042,11 +1057,11 @@ struct bi_visitor_base {
10421057
}
10431058

10441059
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);
1060+
le_uint32_t bi_addr;
1061+
access.read_raw<le_uint32_t>(addr,bi_addr);
10471062
while (bi_addr) {
10481063
visit(access, addr);
1049-
access.read_raw<uint32_t>(addr,bi_addr);
1064+
access.read_raw<le_uint32_t>(addr,bi_addr);
10501065
}
10511066
}
10521067

@@ -1924,7 +1939,7 @@ void reboot_command::execute(device_map &devices) {
19241939
bootrom_func_lookup(raw_access, rom_table_code('U','B'))
19251940
};
19261941

1927-
raw_access.write_vector(program_base, program);
1942+
raw_access.write_program(program_base, program);
19281943
try {
19291944
con.exec(program_base);
19301945
} catch (picoboot::connection_error &e) {

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

0 commit comments

Comments
 (0)