1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 04:34:43 +04:00

Merge remote-tracking branch 'OFW/dev' into dev

This commit is contained in:
MX
2025-03-31 22:04:08 +03:00
13 changed files with 244 additions and 60 deletions

View File

@@ -37,11 +37,13 @@ void nfc_render_iso15693_3_brief(const Iso15693_3Data* data, FuriString* str) {
} }
void nfc_render_iso15693_3_system_info(const Iso15693_3Data* data, FuriString* str) { void nfc_render_iso15693_3_system_info(const Iso15693_3Data* data, FuriString* str) {
if(data->system_info.flags & ISO15693_3_SYSINFO_FLAG_MEMORY) { const uint16_t block_count = iso15693_3_get_block_count(data);
const uint8_t block_size = iso15693_3_get_block_size(data);
if((data->system_info.flags & ISO15693_3_SYSINFO_FLAG_MEMORY) &&
(block_count > 0 && block_size > 0)) {
furi_string_cat(str, "\e#Memory data\n\e*--------------------\n"); furi_string_cat(str, "\e#Memory data\n\e*--------------------\n");
const uint16_t block_count = iso15693_3_get_block_count(data);
const uint8_t block_size = iso15693_3_get_block_size(data);
const uint16_t display_block_count = const uint16_t display_block_count =
MIN(NFC_RENDER_ISO15693_3_MAX_BYTES / block_size, block_count); MIN(NFC_RENDER_ISO15693_3_MAX_BYTES / block_size, block_count);

View File

@@ -3,11 +3,11 @@ App(
name="USB Keyboard & Mouse", name="USB Keyboard & Mouse",
apptype=FlipperAppType.EXTERNAL, apptype=FlipperAppType.EXTERNAL,
entry_point="hid_usb_app", entry_point="hid_usb_app",
stack_size=1 * 1024 + 256, stack_size=2 * 1024,
sources=["*.c", "!transport_ble.c"], sources=["*.c", "!transport_ble.c"],
cdefines=["HID_TRANSPORT_USB"], cdefines=["HID_TRANSPORT_USB"],
fap_description="Use Flipper as a HID remote control over USB", fap_description="Use Flipper as a HID remote control over USB",
fap_version="1.0", fap_version="1.1",
fap_category="USB", fap_category="USB",
fap_icon="hid_usb_10px.png", fap_icon="hid_usb_10px.png",
fap_icon_assets="assets", fap_icon_assets="assets",
@@ -20,12 +20,12 @@ App(
name="Bluetooth Remote", name="Bluetooth Remote",
apptype=FlipperAppType.EXTERNAL, apptype=FlipperAppType.EXTERNAL,
entry_point="hid_ble_app", entry_point="hid_ble_app",
stack_size=1 * 1024 + 256, stack_size=2 * 1024,
sources=["*.c", "!transport_usb.c"], sources=["*.c", "!transport_usb.c"],
cdefines=["HID_TRANSPORT_BLE"], cdefines=["HID_TRANSPORT_BLE"],
fap_libs=["ble_profile"], fap_libs=["ble_profile"],
fap_description="Use Flipper as a HID remote control over Bluetooth", fap_description="Use Flipper as a HID remote control over Bluetooth",
fap_version="1.0", fap_version="1.1",
fap_category="Bluetooth", fap_category="Bluetooth",
fap_icon="hid_ble_10px.png", fap_icon="hid_ble_10px.png",
fap_icon_assets="assets", fap_icon_assets="assets",

View File

@@ -173,33 +173,35 @@ bool iso15693_3_load(Iso15693_3Data* data, FlipperFormat* ff, uint32_t version)
if(flipper_format_key_exist(ff, ISO15693_3_BLOCK_COUNT_KEY) && if(flipper_format_key_exist(ff, ISO15693_3_BLOCK_COUNT_KEY) &&
flipper_format_key_exist(ff, ISO15693_3_BLOCK_SIZE_KEY)) { flipper_format_key_exist(ff, ISO15693_3_BLOCK_SIZE_KEY)) {
data->system_info.flags |= ISO15693_3_SYSINFO_FLAG_MEMORY;
uint32_t block_count; uint32_t block_count;
if(!flipper_format_read_uint32(ff, ISO15693_3_BLOCK_COUNT_KEY, &block_count, 1)) break; if(!flipper_format_read_uint32(ff, ISO15693_3_BLOCK_COUNT_KEY, &block_count, 1)) break;
data->system_info.block_count = block_count; data->system_info.block_count = block_count;
data->system_info.flags |= ISO15693_3_SYSINFO_FLAG_MEMORY;
if(!flipper_format_read_hex( if(!flipper_format_read_hex(
ff, ISO15693_3_BLOCK_SIZE_KEY, &(data->system_info.block_size), 1)) ff, ISO15693_3_BLOCK_SIZE_KEY, &(data->system_info.block_size), 1))
break; break;
simple_array_init( if(data->system_info.block_count > 0 && data->system_info.block_size > 0) {
data->block_data, data->system_info.block_size * data->system_info.block_count); simple_array_init(
data->block_data,
if(!flipper_format_read_hex( data->system_info.block_size * data->system_info.block_count);
ff,
ISO15693_3_DATA_CONTENT_KEY,
simple_array_get_data(data->block_data),
simple_array_get_count(data->block_data)))
break;
if(flipper_format_key_exist(ff, ISO15693_3_SECURITY_STATUS_KEY)) {
simple_array_init(data->block_security, data->system_info.block_count); simple_array_init(data->block_security, data->system_info.block_count);
const bool security_loaded = has_lock_bits ? if(!flipper_format_read_hex(
iso15693_3_load_security(data, ff) : ff,
iso15693_3_load_security_legacy(data, ff); ISO15693_3_DATA_CONTENT_KEY,
if(!security_loaded) break; simple_array_get_data(data->block_data),
simple_array_get_count(data->block_data)))
break;
if(flipper_format_key_exist(ff, ISO15693_3_SECURITY_STATUS_KEY)) {
const bool security_loaded = has_lock_bits ?
iso15693_3_load_security(data, ff) :
iso15693_3_load_security_legacy(data, ff);
if(!security_loaded) break;
}
} }
} }
@@ -260,22 +262,24 @@ bool iso15693_3_save(const Iso15693_3Data* data, FlipperFormat* ff) {
ff, ISO15693_3_BLOCK_SIZE_KEY, &data->system_info.block_size, 1)) ff, ISO15693_3_BLOCK_SIZE_KEY, &data->system_info.block_size, 1))
break; break;
if(!flipper_format_write_hex( if(data->system_info.block_count > 0 && data->system_info.block_size > 0) {
ff, if(!flipper_format_write_hex(
ISO15693_3_DATA_CONTENT_KEY, ff,
simple_array_cget_data(data->block_data), ISO15693_3_DATA_CONTENT_KEY,
simple_array_get_count(data->block_data))) simple_array_cget_data(data->block_data),
break; simple_array_get_count(data->block_data)))
break;
if(!flipper_format_write_comment_cstr( if(!flipper_format_write_comment_cstr(
ff, "Block Security Status: 01 = locked, 00 = not locked")) ff, "Block Security Status: 01 = locked, 00 = not locked"))
break; break;
if(!flipper_format_write_hex( if(!flipper_format_write_hex(
ff, ff,
ISO15693_3_SECURITY_STATUS_KEY, ISO15693_3_SECURITY_STATUS_KEY,
simple_array_cget_data(data->block_security), simple_array_cget_data(data->block_security),
simple_array_get_count(data->block_security))) simple_array_get_count(data->block_security)))
break; break;
}
} }
saved = true; saved = true;
} while(false); } while(false);

View File

@@ -100,10 +100,12 @@ Iso15693_3Error iso15693_3_poller_activate(Iso15693_3Poller* instance, Iso15693_
break; break;
} }
if(system_info->block_count > 0) { if(system_info->block_count > 0 && system_info->block_size > 0) {
// Read blocks: Optional command
simple_array_init( simple_array_init(
data->block_data, system_info->block_count * system_info->block_size); data->block_data, system_info->block_count * system_info->block_size);
simple_array_init(data->block_security, system_info->block_count);
// Read blocks: Optional command
ret = iso15693_3_poller_read_blocks( ret = iso15693_3_poller_read_blocks(
instance, instance,
simple_array_get_data(data->block_data), simple_array_get_data(data->block_data),
@@ -115,8 +117,6 @@ Iso15693_3Error iso15693_3_poller_activate(Iso15693_3Poller* instance, Iso15693_
} }
// Get block security status: Optional command // Get block security status: Optional command
simple_array_init(data->block_security, system_info->block_count);
ret = iso15693_3_poller_get_blocks_security( ret = iso15693_3_poller_get_blocks_security(
instance, simple_array_get_data(data->block_security), system_info->block_count); instance, simple_array_get_data(data->block_security), system_info->block_count);
if(ret != Iso15693_3ErrorNone) { if(ret != Iso15693_3ErrorNone) {

View File

@@ -1,3 +1,4 @@
import os
import serial.tools.list_ports as list_ports import serial.tools.list_ports as list_ports
@@ -15,3 +16,8 @@ def resolve_port(logger, portname: str = "auto"):
logger.error("Failed to find connected Flipper") logger.error("Failed to find connected Flipper")
elif len(flippers) > 1: elif len(flippers) > 1:
logger.error("More than one Flipper is attached") logger.error("More than one Flipper is attached")
env_path = os.environ.get("FLIPPER_PATH")
if env_path:
if os.path.exists(env_path):
logger.info(f"Using FLIPPER_PATH from environment: {env_path}")
return env_path

View File

@@ -3,6 +3,8 @@
import time import time
from typing import Optional from typing import Optional
from serial.serialutil import SerialException
from flipper.app import App from flipper.app import App
from flipper.storage import FlipperStorage from flipper.storage import FlipperStorage
from flipper.utils.cdc import resolve_port from flipper.utils.cdc import resolve_port
@@ -32,11 +34,11 @@ class Main(App):
def _get_flipper(self, retry_count: Optional[int] = 1): def _get_flipper(self, retry_count: Optional[int] = 1):
port = None port = None
self.logger.info(f"Attempting to find flipper with {retry_count} attempts.")
for i in range(retry_count): for i in range(retry_count):
time.sleep(1) time.sleep(1)
self.logger.info(f"Attempting to find flipper #{i}.") self.logger.info(
f"Attempting to find flipper (Attempt {i + 1}/{retry_count})."
)
if port := resolve_port(self.logger, self.args.port): if port := resolve_port(self.logger, self.args.port):
self.logger.info(f"Found flipper at {port}") self.logger.info(f"Found flipper at {port}")
@@ -47,8 +49,16 @@ class Main(App):
return None return None
flipper = FlipperStorage(port) flipper = FlipperStorage(port)
flipper.start() for i in range(retry_count):
return flipper try:
flipper.start()
self.logger.info("Flipper successfully started.")
return flipper
except IOError as e:
self.logger.info(
f"Failed to start flipper (Attempt {i + 1}/{retry_count}): {e}"
)
time.sleep(1)
def power_off(self): def power_off(self):
if not (flipper := self._get_flipper(retry_count=10)): if not (flipper := self._get_flipper(retry_count=10)):

View File

@@ -4,6 +4,8 @@ import time
from datetime import datetime from datetime import datetime
from typing import Optional from typing import Optional
from serial.serialutil import SerialException
from flipper.app import App from flipper.app import App
from flipper.storage import FlipperStorage from flipper.storage import FlipperStorage
from flipper.utils.cdc import resolve_port from flipper.utils.cdc import resolve_port
@@ -34,23 +36,34 @@ class Main(App):
def _get_flipper(self, retry_count: Optional[int] = 1): def _get_flipper(self, retry_count: Optional[int] = 1):
port = None port = None
self.logger.info(f"Attempting to find flipper with {retry_count} attempts.")
for i in range(retry_count): for i in range(retry_count):
time.sleep(1) time.sleep(1)
self.logger.info(f"Attempt to find flipper #{i}.") self.logger.info(
f"Attempting to find flipper (Attempt {i + 1}/{retry_count})."
)
if port := resolve_port(self.logger, self.args.port): if port := resolve_port(self.logger, self.args.port):
self.logger.info(f"Found flipper at {port}") self.logger.info(f"Found flipper at {port}")
break break
if not port: if not port:
self.logger.info(f"Failed to find flipper {port}") self.logger.info(f"Failed to find flipper")
return None return None
flipper = FlipperStorage(port) flipper = FlipperStorage(port)
flipper.start() for i in range(retry_count):
return flipper try:
flipper.start()
self.logger.info("Flipper successfully started.")
return flipper
except IOError as e:
self.logger.info(
f"Failed to start flipper (Attempt {i + 1}/{retry_count}): {e}"
)
time.sleep(1)
self.logger.error("Flipper failed to start after all retries.")
return None
def await_flipper(self): def await_flipper(self):
if not (flipper := self._get_flipper(retry_count=self.args.timeout)): if not (flipper := self._get_flipper(retry_count=self.args.timeout)):

View File

@@ -31,6 +31,7 @@ ENV.AppendUnique(
"-Wundef", "-Wundef",
"-fdata-sections", "-fdata-sections",
"-ffunction-sections", "-ffunction-sections",
"-Wa,-gdwarf-sections",
"-fsingle-precision-constant", "-fsingle-precision-constant",
"-fno-math-errno", "-fno-math-errno",
# Generates .su files with stack usage information # Generates .su files with stack usage information

View File

@@ -1,5 +1,5 @@
entry,status,name,type,params entry,status,name,type,params
Version,+,82.2,, Version,+,83.0,,
Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli.h,,
1 entry status name type params
2 Version + 82.2 83.0
3 Header + applications/services/bt/bt_service/bt.h
4 Header + applications/services/bt/bt_service/bt_keys_storage.h
5 Header + applications/services/cli/cli.h

View File

@@ -1,5 +1,5 @@
entry,status,name,type,params entry,status,name,type,params
Version,+,82.2,, Version,+,83.0,,
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
1 entry status name type params
2 Version + 82.2 83.0
3 Header + applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h
4 Header + applications/services/bt/bt_service/bt.h
5 Header + applications/services/bt/bt_service/bt_keys_storage.h

View File

@@ -33,10 +33,56 @@ SECTIONS {
*(COMMON) *(COMMON)
} }
.ARM.attributes : { /* Default debug-related rules from ld */
*(.ARM.attributes)
*(.ARM.attributes.*) /* Stabs debugging sections. */
} .stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1. */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions. */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2. */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2. */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions. */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3. */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF 5. */
.debug_addr 0 : { *(.debug_addr) }
.debug_line_str 0 : { *(.debug_line_str) }
.debug_loclists 0 : { *(.debug_loclists) }
.debug_macro 0 : { *(.debug_macro) }
.debug_names 0 : { *(.debug_names) }
.debug_rnglists 0 : { *(.debug_rnglists) }
.debug_str_offsets 0 : { *(.debug_str_offsets) }
.debug_sup 0 : { *(.debug_sup) }
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
/DISCARD/ : { /DISCARD/ : {
*(.comment) *(.comment)

View File

@@ -131,4 +131,55 @@ SECTIONS {
MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM2A MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM2A
._sram2a_free : { . = ALIGN(4); __sram2a_free__ = .; } >RAM2A ._sram2a_free : { . = ALIGN(4); __sram2a_free__ = .; } >RAM2A
._sram2b_start : { . = ALIGN(4); __sram2b_start__ = .; } >RAM2B ._sram2b_start : { . = ALIGN(4); __sram2b_start__ = .; } >RAM2B
/* Default debug-related rules from ld */
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1. */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions. */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2. */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2. */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions. */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3. */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF 5. */
.debug_addr 0 : { *(.debug_addr) }
.debug_line_str 0 : { *(.debug_line_str) }
.debug_loclists 0 : { *(.debug_loclists) }
.debug_macro 0 : { *(.debug_macro) }
.debug_names 0 : { *(.debug_names) }
.debug_rnglists 0 : { *(.debug_rnglists) }
.debug_str_offsets 0 : { *(.debug_str_offsets) }
.debug_sup 0 : { *(.debug_sup) }
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
} }

View File

@@ -129,4 +129,55 @@ SECTIONS {
MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM2A MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM2A
._sram2a_free : { . = ALIGN(4); __sram2a_free__ = .; } >RAM2A ._sram2a_free : { . = ALIGN(4); __sram2a_free__ = .; } >RAM2A
._sram2b_start : { . = ALIGN(4); __sram2b_start__ = .; } >RAM2B ._sram2b_start : { . = ALIGN(4); __sram2b_start__ = .; } >RAM2B
/* Default debug-related rules from ld */
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1. */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions. */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2. */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2. */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions. */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3. */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF 5. */
.debug_addr 0 : { *(.debug_addr) }
.debug_line_str 0 : { *(.debug_line_str) }
.debug_loclists 0 : { *(.debug_loclists) }
.debug_macro 0 : { *(.debug_macro) }
.debug_names 0 : { *(.debug_names) }
.debug_rnglists 0 : { *(.debug_rnglists) }
.debug_str_offsets 0 : { *(.debug_str_offsets) }
.debug_sup 0 : { *(.debug_sup) }
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
} }