Skip to content

Commit

Permalink
Merge remote-tracking branch 'OFW/dev' into dev [ci skip]
Browse files Browse the repository at this point in the history
  • Loading branch information
xMasterX committed Jun 17, 2024
2 parents 9abe245 + d8ef099 commit 990d80e
Show file tree
Hide file tree
Showing 20 changed files with 353 additions and 149 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ static void nfc_scene_read_and_saved_menu_on_enter_mf_ultralight(NfcApp* instanc
} else if(
data->type == MfUltralightTypeNTAG213 || data->type == MfUltralightTypeNTAG215 ||
data->type == MfUltralightTypeNTAG216 || data->type == MfUltralightTypeUL11 ||
data->type == MfUltralightTypeUL21) {
data->type == MfUltralightTypeUL21 || data->type == MfUltralightTypeOrigin) {
submenu_add_item(
submenu,
"Write",
Expand Down
9 changes: 3 additions & 6 deletions applications/main/nfc/nfc_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,13 +464,10 @@ static bool nfc_is_hal_ready(void) {
// No connection to the chip, show an error screen
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
DialogMessage* message = dialog_message_alloc();
dialog_message_set_header(message, "Error: NFC Chip Failed", 64, 0, AlignCenter, AlignTop);
dialog_message_set_text(
message,
"Error!\nNFC chip failed to start\n\n\nSend a photo of this to:\nsupport@flipperzero.one",
0,
0,
AlignLeft,
AlignTop);
message, "Send error photo via\nsupport.flipper.net", 0, 63, AlignLeft, AlignBottom);
//dialog_message_set_icon(message, &I_err_09, 128 - 25, 64 - 25);
dialog_message_show(dialogs, message);
dialog_message_free(message);
furi_record_close(RECORD_DIALOGS);
Expand Down
232 changes: 178 additions & 54 deletions applications/services/loader/loader.c

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions applications/services/loader/loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const
/**
* @brief Start application detached with GUI error message
* @param[in] instance loader instance
* @param[in] name application name
* @param[in] name application name or id
* @param[in] args application arguments
*/
void loader_start_detached_with_gui_error(Loader* loader, const char* name, const char* args);

/**
/**
* @brief Lock application start
* @param[in] instance loader instance
* @return true on success
Expand Down
12 changes: 12 additions & 0 deletions applications/services/loader/loader_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,20 @@ typedef struct {
FuriString* error_message;
} LoaderMessageStartByName;

typedef enum {
LoaderStatusErrorUnknown,
LoaderStatusErrorInvalidFile,
LoaderStatusErrorInvalidManifest,
LoaderStatusErrorMissingImports,
LoaderStatusErrorHWMismatch,
LoaderStatusErrorOutdatedApp,
LoaderStatusErrorOutOfMemory,
LoaderStatusErrorOutdatedFirmware,
} LoaderStatusError;

typedef struct {
LoaderStatus value;
LoaderStatusError error;
} LoaderMessageLoaderStatusResult;

typedef struct {
Expand Down
Binary file added assets/icons/Loader/err_01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icons/Loader/err_02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icons/Loader/err_03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icons/Loader/err_04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icons/Loader/err_05.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
137 changes: 102 additions & 35 deletions lib/flipper_application/elf/elf_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,16 +435,13 @@ static bool elf_relocate(ELFFile* elf, ELFSection* s) {
/************************************ Internal FAP interfaces *************************************/
/**************************************************************************************************/
typedef enum {
SectionTypeERROR = 0,
SectionTypeUnused = 1 << 0,
SectionTypeData = 1 << 1,
SectionTypeRelData = 1 << 2,
SectionTypeSymTab = 1 << 3,
SectionTypeStrTab = 1 << 4,
SectionTypeDebugLink = 1 << 5,
SectionTypeFastRelData = 1 << 6,

SectionTypeValid = SectionTypeSymTab | SectionTypeStrTab,
} SectionType;

static bool elf_load_debug_link(ELFFile* elf, Elf32_Shdr* section_header) {
Expand All @@ -460,37 +457,62 @@ static bool str_prefix(const char* str, const char* prefix) {
return strncmp(prefix, str, strlen(prefix)) == 0;
}

static bool elf_load_section_data(ELFFile* elf, ELFSection* section, Elf32_Shdr* section_header) {
typedef enum {
ELFLoadSectionResultSuccess,
ELFLoadSectionResultNoMemory,
ELFLoadSectionResultError,
} ELFLoadSectionResult;

typedef struct {
SectionType type;
ELFLoadSectionResult result;
} SectionTypeInfo;

static ELFLoadSectionResult
elf_load_section_data(ELFFile* elf, ELFSection* section, Elf32_Shdr* section_header) {
if(section_header->sh_size == 0) {
FURI_LOG_D(TAG, "No data for section");
return true;
return ELFLoadSectionResultSuccess;
}

size_t safe_size = section_header->sh_size + 1024;

furi_kernel_lock();

if(memmgr_heap_get_max_free_block() < safe_size) {
furi_kernel_unlock();
FURI_LOG_E(TAG, "Not enough memory to load section data");
return ELFLoadSectionResultNoMemory;
}

section->data = aligned_malloc(section_header->sh_size, section_header->sh_addralign);
section->size = section_header->sh_size;

furi_kernel_unlock();

if(section_header->sh_type == SHT_NOBITS) {
// BSS section, no data to load
return true;
return ELFLoadSectionResultSuccess;
}

if((!storage_file_seek(elf->fd, section_header->sh_offset, true)) ||
(storage_file_read(elf->fd, section->data, section_header->sh_size) !=
section_header->sh_size)) {
FURI_LOG_E(TAG, " seek/read fail");
return false;
return ELFLoadSectionResultError;
}

FURI_LOG_D(TAG, "0x%p", section->data);
return true;
return ELFLoadSectionResultSuccess;
}

static SectionType elf_preload_section(
static SectionTypeInfo elf_preload_section(
ELFFile* elf,
size_t section_idx,
Elf32_Shdr* section_header,
FuriString* name_string) {
const char* name = furi_string_get_cstr(name_string);
SectionTypeInfo info;

#ifdef ELF_DEBUG_LOG
// log section name, type and flags
Expand Down Expand Up @@ -527,7 +549,10 @@ static SectionType elf_preload_section(
if(str_prefix(name, ".ARM.") || str_prefix(name, ".rel.ARM.") ||
str_prefix(name, ".fast.rel.ARM.")) {
FURI_LOG_D(TAG, "Ignoring ARM section");
return SectionTypeUnused;

info.type = SectionTypeUnused;
info.result = ELFLoadSectionResultSuccess;
return info;
}

// Load allocable section
Expand All @@ -546,26 +571,32 @@ static SectionType elf_preload_section(
elf->fini_array = section_p;
}

if(!elf_load_section_data(elf, section_p, section_header)) {
info.type = SectionTypeData;
info.result = elf_load_section_data(elf, section_p, section_header);

if(info.result != ELFLoadSectionResultSuccess) {
FURI_LOG_E(TAG, "Error loading section '%s'", name);
return SectionTypeERROR;
} else {
return SectionTypeData;
}

return info;
}

// Load link info section
if(section_header->sh_flags & SHF_INFO_LINK) {
info.type = SectionTypeRelData;

if(str_prefix(name, ".rel")) {
name = name + strlen(".rel");
ELFSection* section_p = elf_file_get_or_put_section(elf, name);
section_p->rel_count = section_header->sh_size / sizeof(Elf32_Rel);
section_p->rel_offset = section_header->sh_offset;
return SectionTypeRelData;
info.result = ELFLoadSectionResultSuccess;
} else {
FURI_LOG_E(TAG, "Unknown link info section '%s'", name);
return SectionTypeERROR;
info.result = ELFLoadSectionResultError;
}

return info;
}

// Load fast rel section
Expand All @@ -574,41 +605,56 @@ static SectionType elf_preload_section(
ELFSection* section_p = elf_file_get_or_put_section(elf, name);
section_p->fast_rel = malloc(sizeof(ELFSection));

if(!elf_load_section_data(elf, section_p->fast_rel, section_header)) {
info.type = SectionTypeFastRelData;
info.result = elf_load_section_data(elf, section_p->fast_rel, section_header);

if(info.result != ELFLoadSectionResultSuccess) {
FURI_LOG_E(TAG, "Error loading section '%s'", name);
return SectionTypeERROR;
} else {
FURI_LOG_D(TAG, "Loaded fast rel section for '%s'", name);
}

FURI_LOG_D(TAG, "Loaded fast rel section for '%s'", name);
return SectionTypeFastRelData;
return info;
}

// Load symbol table
if(strcmp(name, ".symtab") == 0) {
FURI_LOG_D(TAG, "Found .symtab section");
elf->symbol_table = section_header->sh_offset;
elf->symbol_count = section_header->sh_size / sizeof(Elf32_Sym);
return SectionTypeSymTab;

info.type = SectionTypeSymTab;
info.result = ELFLoadSectionResultSuccess;
return info;
}

// Load string table
if(strcmp(name, ".strtab") == 0) {
FURI_LOG_D(TAG, "Found .strtab section");
elf->symbol_table_strings = section_header->sh_offset;
return SectionTypeStrTab;

info.type = SectionTypeStrTab;
info.result = ELFLoadSectionResultSuccess;
return info;
}

// Load debug link section
if(strcmp(name, ".gnu_debuglink") == 0) {
FURI_LOG_D(TAG, "Found .gnu_debuglink section");
info.type = SectionTypeDebugLink;

if(elf_load_debug_link(elf, section_header)) {
return SectionTypeDebugLink;
info.result = ELFLoadSectionResultSuccess;
return info;
} else {
return SectionTypeERROR;
info.result = ELFLoadSectionResultError;
return info;
}
}

return SectionTypeUnused;
info.type = SectionTypeUnused;
info.result = ELFLoadSectionResultSuccess;
return info;
}

static Elf32_Addr elf_address_of_by_hash(ELFFile* elf, uint32_t hash) {
Expand Down Expand Up @@ -836,35 +882,57 @@ bool elf_file_open(ELFFile* elf, const char* path) {
return true;
}

bool elf_file_load_section_table(ELFFile* elf) {
SectionType loaded_sections = SectionTypeERROR;
ElfLoadSectionTableResult elf_file_load_section_table(ELFFile* elf) {
SectionType loaded_sections = 0;
FuriString* name = furi_string_alloc();
ElfLoadSectionTableResult result = ElfLoadSectionTableResultSuccess;

FURI_LOG_D(TAG, "Scan ELF indexs...");
// TODO FL-3526: why we start from 1?

for(size_t section_idx = 1; section_idx < elf->sections_count; section_idx++) {
Elf32_Shdr section_header;

furi_string_reset(name);
if(!elf_read_section(elf, section_idx, &section_header, name)) {
loaded_sections = SectionTypeERROR;
loaded_sections = 0;
break;
}

FURI_LOG_D(
TAG, "Preloading data for section #%d %s", section_idx, furi_string_get_cstr(name));
SectionType section_type = elf_preload_section(elf, section_idx, &section_header, name);
loaded_sections |= section_type;
SectionTypeInfo section_type_info =
elf_preload_section(elf, section_idx, &section_header, name);
loaded_sections |= section_type_info.type;

if(section_type_info.result != ELFLoadSectionResultSuccess) {
if(section_type_info.result == ELFLoadSectionResultNoMemory) {
FURI_LOG_E(TAG, "Not enough memory");
result = ElfLoadSectionTableResultNoMemory;
} else if(section_type_info.result == ELFLoadSectionResultError) {
FURI_LOG_E(TAG, "Error loading section");
result = ElfLoadSectionTableResultError;
}

if(section_type == SectionTypeERROR) {
loaded_sections = SectionTypeERROR;
loaded_sections = 0;
break;
}
}

furi_string_free(name);

return IS_FLAGS_SET(loaded_sections, SectionTypeValid);
if(result != ElfLoadSectionTableResultSuccess) {
return result;
} else {
bool sections_valid =
IS_FLAGS_SET(loaded_sections, SectionTypeSymTab | SectionTypeStrTab) |
IS_FLAGS_SET(loaded_sections, SectionTypeFastRelData);
if(sections_valid) {
return ElfLoadSectionTableResultSuccess;
} else {
FURI_LOG_E(TAG, "No valid sections found");
return ElfLoadSectionTableResultError;
}
}
}

ElfProcessSectionResult elf_process_section(
Expand All @@ -877,7 +945,6 @@ ElfProcessSectionResult elf_process_section(
Elf32_Shdr section_header;

// find section
// TODO FL-3526: why we start from 1?
for(size_t section_idx = 1; section_idx < elf->sections_count; section_idx++) {
furi_string_reset(section_name);
if(!elf_read_section(elf, section_idx, &section_header, section_name)) {
Expand Down
11 changes: 8 additions & 3 deletions lib/flipper_application/elf/elf_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ typedef struct {
typedef enum {
ELFFileLoadStatusSuccess = 0,
ELFFileLoadStatusUnspecifiedError,
ELFFileLoadStatusNoFreeMemory,
ELFFileLoadStatusMissingImports,
} ELFFileLoadStatus;

Expand All @@ -43,6 +42,12 @@ typedef enum {
ElfProcessSectionResultSuccess,
} ElfProcessSectionResult;

typedef enum {
ElfLoadSectionTableResultError,
ElfLoadSectionTableResultNoMemory,
ElfLoadSectionTableResultSuccess,
} ElfLoadSectionTableResult;

typedef bool(ElfProcessSection)(File* file, size_t offset, size_t size, void* context);

/**
Expand Down Expand Up @@ -70,9 +75,9 @@ bool elf_file_open(ELFFile* elf_file, const char* path);
/**
* @brief Load ELF file section table (load stage #1)
* @param elf_file
* @return bool
* @return ElfLoadSectionTableResult
*/
bool elf_file_load_section_table(ELFFile* elf_file);
ElfLoadSectionTableResult elf_file_load_section_table(ELFFile* elf_file);

/**
* @brief Load and relocate ELF file sections (load stage #2)
Expand Down
Loading

0 comments on commit 990d80e

Please sign in to comment.