Skip to content

Commit 5e35eb8

Browse files
author
Memfault Inc
committed
Memfault Firmware SDK 0.26.1 (Build 314362)
1 parent 4a02f04 commit 5e35eb8

File tree

7 files changed

+125
-7
lines changed

7 files changed

+125
-7
lines changed

CHANGES.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
### Changes between Memfault SDK 0.26.1 and SDK 0.26.0 - Sept 20, 2021
2+
3+
#### :house: Internal
4+
5+
- Updated
6+
[`modem_key_mgmt_exists`](ports/zephyr/ncs/src/memfault_nrf91_root_cert_storage.c)
7+
API usage to be compatible with changes upcomming in nRF Connect SDK 1.8.
8+
19
### Changes between Memfault SDK 0.26.0 and SDK 0.25.0 - Sept 15, 2021
210

311
#### :chart_with_upwards_trend: Improvements

VERSION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
BUILD ID: 311259
2-
GIT COMMIT: dcb7bcc1f
1+
BUILD ID: 314362
2+
GIT COMMIT: 8ea624d52

components/include/memfault/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ typedef struct {
1919
uint8_t patch;
2020
} sMfltSdkVersion;
2121

22-
#define MEMFAULT_SDK_VERSION { .major = 0, .minor = 26, .patch = 0 }
22+
#define MEMFAULT_SDK_VERSION { .major = 0, .minor = 26, .patch = 1 }
2323

2424
#ifdef __cplusplus
2525
}

ports/zephyr/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ config MEMFAULT_LOGGING_RAM_SIZE
112112

113113
endif # MEMFAULT_LOGGING_ENABLE
114114

115-
choice
115+
choice MEMFAULT_ROOT_CERT_STORAGE_CONTEXT
116116
bool "Implementation used to store Memfault Root certificates"
117117
default MEMFAULT_ROOT_CERT_STORAGE_NRF9160_MODEM if SOC_SERIES_NRF91X && TRUSTED_EXECUTION_NONSECURE
118118
default MEMFAULT_ROOT_CERT_STORAGE_TLS_CREDENTIAL_STORAGE
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#pragma once
2+
3+
//! @file
4+
//!
5+
//! Copyright (c) Memfault, Inc.
6+
//! See License.txt for details
7+
//!
8+
//! @brief A little convenience header to assist in checks which can be run at compile time for
9+
//! backward compatibility based on NCS version.
10+
11+
#ifdef __cplusplus
12+
extern "C" {
13+
#endif
14+
15+
//! NCS Version was introduced in nRF Connect SDK >= 1.4
16+
#if __has_include("ncs_version.h")
17+
18+
#include "ncs_version.h"
19+
20+
//! modem/bsdlib.h was introduced in nRF Connect SDK 1.3
21+
#elif __has_include("modem/bsdlib.h")
22+
23+
#define NCS_VERSION_MAJOR 1
24+
#define NCS_VERSION_MINOR 3
25+
#define NCS_PATCHLEVEL 0
26+
27+
#else
28+
29+
//! The lowest version the memfault-firmware-sdk has been ported to
30+
#define NCS_VERSION_MAJOR 1
31+
#define NCS_VERSION_MINOR 2
32+
#define NCS_PATCHLEVEL 0
33+
34+
#endif
35+
36+
//! Returns true if current nRF Connect Version is greater than the one specified
37+
//!
38+
//! Three checks:
39+
//! - First check if major version is greater than the one specified
40+
//! - Next check if the major version matches and the minor version is greater
41+
//! - Finally check if we are on a development build that is greater than the version. After a
42+
//! release is shipped, a PATCHLEVEL of 99 is used to indicate this. For example, a version of
43+
//! "1.7.99" means development for version "1.8.0".
44+
#define MEMFAULT_NCS_VERSION_GT(major, minor) \
45+
((NCS_VERSION_MAJOR > (major)) || \
46+
((NCS_VERSION_MAJOR == (major)) && (NCS_VERSION_MINOR > (minor))) || \
47+
((NCS_VERSION_MAJOR == (major)) && ((NCS_VERSION_MINOR + 1) > (minor)) && (NCS_PATCHLEVEL == 99)))
48+
49+
#ifdef __cplusplus
50+
}
51+
#endif

ports/zephyr/ncs/src/memfault_nrf91_root_cert_storage.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,23 @@
2525
#endif
2626

2727
#include "memfault/core/debug_log.h"
28+
#include "memfault/ports/ncs/version.h"
29+
2830

2931
int memfault_root_cert_storage_add(
3032
eMemfaultRootCert cert_id, const char *cert, size_t cert_length) {
3133
bool exists;
32-
uint8_t unused;
3334

34-
int err = modem_key_mgmt_exists(cert_id,
35-
MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN,
35+
// Note: modem_key_mgmt_exists() signature changed between nRF Connect SDK 1.7 & 1.8
36+
// https://github.com/nrfconnect/sdk-nrf/pull/5631
37+
#if MEMFAULT_NCS_VERSION_GT(1, 7)
38+
int err = modem_key_mgmt_exists(cert_id, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN, &exists);
39+
#else
40+
uint8_t unused;
41+
int err = modem_key_mgmt_exists(cert_id, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN,
3642
&exists, &unused);
43+
#endif
44+
3745
if (err != 0) {
3846
MEMFAULT_LOG_ERROR("Failed to install cert %d, rv=%d\n", cert_id, err);
3947
return err;

scripts/mflt-build-id/src/mflt_build_id/__init__.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import argparse
1717
import hashlib
1818
import struct
19+
from collections import defaultdict
1920
from enum import Enum
2021

2122
try:
@@ -52,12 +53,62 @@ def section_in_binary(section):
5253
sh_flags = section["sh_flags"]
5354
return sh_flags & SH_FLAGS.SHF_ALLOC != 0
5455

56+
@staticmethod
57+
def build_symbol_by_name_cache(symtab, little_endian):
58+
# An optimized imlementation for building a cache for quick symbol info lookups
59+
#
60+
# Replacing implementation here:
61+
# https://github.com/eliben/pyelftools/blob/49ffaf4/elftools/elf/sections.py#L198-L210
62+
#
63+
# Two main performance optimizations
64+
# 1) The "struct_parse" utility pyelftools relies on for decoding structures
65+
# is extremely slow. We will use Python's struct.unpack instead here
66+
# 2) pyelftools passes around a file stream object while doing deserialization
67+
# which means there are a ton of disk seeks that get kicked off
68+
#
69+
# Empirically, seeing about 10x performance improvement
70+
symtab_data = symtab.data()
71+
symtab_entry_size = symtab["sh_entsize"]
72+
73+
symbol_name_map = defaultdict(list)
74+
75+
stringtable_data = symtab.stringtable.data()
76+
77+
def _get_string(start_offset):
78+
end_offset = stringtable_data.find(b"\x00", start_offset)
79+
if end_offset == -1:
80+
return None
81+
s = stringtable_data[start_offset:end_offset]
82+
return s.decode("utf-8", errors="replace")
83+
84+
for idx in range(symtab.num_symbols()):
85+
entry_offset = idx * symtab_entry_size
86+
# The first word of a "Symbol Table Entry" is "st_name"
87+
# For more details, see the "Executable and Linking Format" specification
88+
symtab_entry_data = symtab_data[entry_offset : entry_offset + 4]
89+
90+
endianess_prefix = "<" if little_endian else ">"
91+
st_name = struct.unpack("{}I".format(endianess_prefix), symtab_entry_data)[0]
92+
name = _get_string(st_name)
93+
symbol_name_map[name].append(idx)
94+
95+
return symbol_name_map
96+
5597
@property
5698
def symtab(self):
5799
# Cache the SymbolTableSection, to avoid re-parsing
58100
if self._symtab:
59101
return self._symtab
60102
self._symtab = self.elf.get_section_by_name(".symtab")
103+
104+
# Pyelftools maintains a symbol_name to index cache (_symbol_name_map) which is extremely
105+
# slow to build when there are many symbols present in an ELF so we build the cache here
106+
# using an optimized implementation
107+
if self._symtab:
108+
self._symtab._symbol_name_map = self.build_symbol_by_name_cache(
109+
self._symtab, little_endian=self.elf.little_endian
110+
)
111+
61112
return self._symtab
62113

63114
def find_symbol_and_section(self, symbol_name):

0 commit comments

Comments
 (0)