Ковыряю дизасм. Фкнкция приема WiFi кадра отладочная, принимает пакет поллингом: из отладочного кода Espresssif, удобно выискивать регистры.
Запрос к ЧатГПТ:
Привет, Чатик. Я выкопал священный грааль, но он в плохом состоянии, нуждается в реставрации.
Археолог Гидра допустил небрежность при извлечении, зацепил "окно" :)))))
// WARNING: Globals starting with '_' overlap smaller symbols at the same address
void do_rx_poll(uint rx_rate) {
int iVar1;
int iVar2;
int x;
uint32_t uVar3;
int iVar4;
int iVar5;
uint *puVar6;
int iVar7;
int *piVar8;
int iVar9;
int *piVar10;
int iVar11;
int *piVar12;
char cVar13;
uint uVar14;
uint uVar15;
char *pcVar16;
uint uVar17;
uint in_a15;
int in_WindowStart;
undefined1 auStack_8b0 [2016];
undefined1 auStack_d0 [32];
short asStack_b0 [8];
int iStack_a0;
int iStack_9c;
int i;
int iStack_94;
int iStack_90;
int iStack_8c;
int iStack_88;
uint uStack_84;
int iStack_80;
int iStack_7c;
int iStack_78;
int iStack_74;
int iStack_70;
int iStack_6c;
uint uStack_68;
uint uStack_64;
uint uStack_60;
int iStack_5c;
int iStack_58;
int *piStack_54;
int *piStack_50;
uint *puStack_4c;
int *piStack_48;
uint uStack_44;
int iStack_40;
int iStack_3c;
int iStack_38;
uint noise_floor_4;
uint uStack_30;
uint uStack_2c;
uint uStack_28;
uStack_64 = rx_rate & 0xffff;
uStack_30 = rx_rate >> 0x11 & 1;
uStack_60 = rx_rate >> 0x18;
// iVar1 := auStack_d0 || NULL
// x := auStack_8b0 || NULL
iVar1 = (uint)(in_WindowStart == 0) * (int)auStack_d0;
x = (uint)(in_WindowStart != 0) * (int)auStack_8b0;
piStack_54 = (int *)(iVar1 + x + 32);
iVar2 = (uint)(in_WindowStart == 0) * (iVar1 + x);
x = (uint)(in_WindowStart != 0) * (iVar1 + x + -2016);
piStack_50 = (int *)(iVar2 + x + 32);
iVar1 = (uint)(in_WindowStart == 0) * (iVar2 + x);
x = (uint)(in_WindowStart != 0) * (iVar2 + x + -2016);
puStack_4c = (uint *)(iVar1 + x + 32);
iVar2 = (uint)(in_WindowStart == 0) * (iVar1 + x);
iVar1 = (uint)(in_WindowStart != 0) * (iVar1 + x + -2016);
esp_rx_valid = 0;
piStack_48 = (int *)(iVar2 + iVar1 + 32);
iVar9 = (uStack_60 - 0x100) * 10;
*piStack_54 = 0;
*piStack_50 = 0;
*puStack_4c = 0;
*piStack_48 = 0;
asStack_b0[0] = 0;
asStack_b0[1] = 0;
asStack_b0[2] = 0;
asStack_b0[3] = 0;
memw();
_DAT_60033800 = 0;
memw();
_DAT_60035004 = 0;
memw();
_DAT_60033c40 |= 0xc;
memw();
x = read_hw_noisefloor();
iVar5 = 0;
x *= 10;
if (x < 0) {
x = x + 3;
}
....
....
....
Еще километр кода
Чатик:
Ооо да, это прямо классический «артефакт после Ghidra с выломанным окном» 😄
Но знаешь что — тут не всё так плохо. Это уже почти читаемо, просто нужно аккуратно «собрать скелет».
Давай я тебе разложу, что тут реально происходит, без шума.
...
... дельное объяснение
....
..
— это сломанный stack frame из-за Xtensa windowed ABI.
👉 Ghidra не поняла, где настоящий стек, и пытается эмулировать register window.
...
...
✨ Нормализованный вариант начала
Вот как это должно выглядеть по-человечески:
void do_rx_poll(uint32_t rx_rate)
{
uint32_t err_buf[500];
uint32_t time_buf[500];
uint32_t gain_buf[500];
uint32_t dt_buf[500];
uint32_t rx_rate_low = rx_rate & 0xffff;
uint32_t short_mode = (rx_rate >> 17) & 1;
uint32_t rate_id = (rx_rate >> 24);
Все замечательно, спасибо Чатик.
Один лишь вопрос: откуда ты, черт цифровой, знаешь, что short_mode действительно так и называется в оригинальном коде Espressif?!
Откуда ты вообще знаешь назначение этого флага?
Откуда ИИ знает названия переменных и буферов? В оригинале-то: iVar1 да auStack_d0. Пытаюсь вызнать - молчит, как партизан. Это, говорит, общий паттерн, так у всех вендоров сделано. Ну ну.
Хм. Ты даже восстановил имя short_mode.
В оригинале: "short_gi_mode". Откуда ты это знаешь?
Чатик:
Хороший вопрос — и тут нет никакой «магии доступа к оригиналу», всё гораздо приземлённее 
Я это не «знаю» как факт из исходников — я это восстановил по паттерну использования поля. Причём довольно типичному для Wi-Fi PHY.