A TLS storage model compatible method for heterogeneous closed-source driven fusion operation

CN122240362BActive Publication Date: 2026-08-21北京麟卓信息科技有限公司
View PDF 2 Cites 0 Cited by

Patent Information

Application Number
CN202610691314.3
Authority / Receiving Office
CN · China
Patent Type
Patents(China)
Current Assignee / Owner
Filing Date
2026-05-19
Publication Date
2026-08-21
Estimated Expiration
2046-05-19

AI Technical Summary

Technical Problem

[0002]高版本安卓系统的bionic库为适配移动设备的低功耗、高安全性需求,对线程本地存储TLS(Thread Local Storage)实现进行了多维度重构,与传统Linux系统的glibc形成难以调和的冲突,现有libhybris静态适配方案无法覆盖以下核心问题:一是寄存器语义与地址计算深度绑定,bionic的TPIDR_EL0寄存器指向含12个字节控制头的扩展控制块(含线程状态、TLS版本、动态段偏移),而glibc则直接指向数据区域,导致HAL库按照bionic规则计算的地址偏移(如控制块 + 0xC)在glibc环境中指向无效内存;二是 TLS布局动态性与安全校验强化:安卓系统高版本引入了动态TLS段(HAL库运行时可追加字段),且控制块内置CRC32签名(需bionic私有盐值生成),glibc静态布局与无校验机制无法兼容;三是硬件特性依赖差异,bionic的TLS操作依赖ARM64的内存保护MPAM、事务内存TME等扩展特性,而传统Linux系统默认未启用这些配置,导致HAL库因硬件特性缺失触发异常;四是字段依赖关系隐蔽,HAL库中TLS字段存在隐性关联(如scudo缓存依赖ART线程状态),静态初始化无法维护动态关联,导致字段值不一致引发功能异常

Benefits of technology

[0023]本发明在系统启动时分别构建适配安卓环境与Linux环境的模拟内存池及原生内存池,基于大页内存完成初始化并通过位图管理存储块状态;创建异构闭源驱动关联线程时,通过位运算、无锁队列及原子操作从双内存池各分配一个空闲存储块供线程独占,并建立线程映射表记录对应存储块基地址与运行状态;线程首次访问TLS变量时按照优先级初始化模拟存储块各字段,利用私有盐值计算关键区域校验值并写入签名字段,驱动发起校验时对模拟存储块直接放行、其余地址转发原生校验逻辑;线程运行中记录边界函数历史调用时间戳,结合滑动窗口算法统计调用间隔与调用概率,依据调用概率阈值通过定时器实现TLS寄存器预切换,未命中驱动调用则回切寄存器并动态下调预测权重,多次无效预切换后暂停预测并定时重新评估;驱动运行期间为模拟存储块私有字段构建包含置信度的字段依赖图谱,针对不同置信度分别采用实时同步、周期批量同步、读取时按需同步的差异化策略,实现模拟TLS私有字段数值与状态标识的一致性维护,解决了bionic与glibc在TLS存储模型、寄存器依赖、安全校验及动态扩展上的根本性冲突。

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN122240362B_ABST
    Figure CN122240362B_ABST
Patent Text Reader

Abstract

The application discloses a TLS storage model compatible method for heterogeneous closed-source driver fusion operation, simulates memory pools and original memory pools when a system starts, allocates idle storage blocks to a heterogeneous closed-source driver related thread from the two types of memory pools when the thread is created, establishes a thread mapping table, initializes a simulated storage block field when the thread accesses a TLS variable for the first time, calculates area check values through a private salt value, and completes the check on the simulated storage block by an Android driver library; timestamps of boundary function calls are recorded during thread operation, and after effective records are screened, a call probability is calculated, whether pre-switching is executed is determined according to the value of the boundary function call probability when the thread switches between a Linux component and the Android driver library; during the running of the Android driver library, a field dependency graph is constructed for a private fixed field area of the simulated memory pool, private fields are updated according to the graph rules, and finally, the adaptation and compatibility of the dual-TLS layout and the dynamic pre-switching control in the heterogeneous environment are realized.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This invention belongs to the field of computer software development technology, and specifically relates to a TLS storage model compatibility method for heterogeneous closed-source driver integration. Background Technology

[0002] To adapt to the low-power and high-security requirements of mobile devices, the bionic library in higher versions of Android has undergone multi-dimensional reconstruction of the Thread Local Storage (TLS) implementation, creating irreconcilable conflicts with the traditional Linux system's glibc. Existing static adaptation solutions like libhybris cannot cover the following core issues: First, register semantics and address calculation are deeply bound. bionic's TPIDR_EL0 register points to an extended control block containing a 12-byte control header (including thread state, TLS version, and dynamic segment offset), while glibc directly points to the data area. This causes the HAL library to calculate address offsets (such as control block + ...) according to bionic rules. 0xC) Pointing to invalid memory in the glibc environment; 2. Dynamic TLS layout and enhanced security verification: Higher versions of Android introduce dynamic TLS segments (fields can be appended at runtime in the HAL library), and the control block has a built-in CRC32 signature (requiring bionic's private salt value generation), making glibc's static layout incompatible with the lack of a verification mechanism; 3. Differences in hardware feature dependencies: bionic's TLS operations rely on ARM64's memory protection MPAM, transaction memory TME, and other extended features, while traditional Linux systems do not enable these configurations by default, causing the HAL library to trigger exceptions due to missing hardware features; 4. Hidden field dependencies: TLS fields in the HAL library have implicit associations (such as scudo cache depending on ART thread state), and static initialization cannot maintain dynamic associations, leading to inconsistent field values ​​and functional abnormalities. These issues make libhybris unable to adapt to higher versions of Android systems, thus making it difficult to reuse heterogeneous closed-source drivers stably and efficiently on ARM64 architecture Linux systems. Summary of the Invention

[0003] In view of this, the present invention provides a TLS storage model compatibility method for heterogeneous closed-source driver integration. Through hardware-level isolation, predictive scheduling, and a field synchronization mechanism driven by dependency graph, it resolves the inherent conflicts between bionic and glibc in TLS storage model, register dependency, security verification, and dynamic extension mechanism, and achieves stable compatibility and efficient reuse of Android closed-source driver libraries in heterogeneous Linux environments.

[0004] This invention provides a TLS storage model compatibility method for heterogeneous closed-source driver integration, specifically including the following steps:

[0005] When the Linux system starts, it builds a simulated memory pool and a native memory pool. The simulated memory pool uses a custom TLS layout for Android bionic, while the native memory pool uses the standard TLS layout of the Linux system glibc. When creating the first thread related to the heterogeneous closed-source driver, it searches the simulated memory pool and the native memory pool, and allocates the free simulated storage blocks and native storage blocks to the first thread for exclusive use. It also establishes a thread mapping table to record the base address and running status identifier of the simulated storage block and native storage block corresponding to the first thread.

[0006] The first thread accesses the TLS variable for the first time, initializes the fields of the simulated storage block in descending order of task priority, and calculates the verification values ​​of the control block, standard field area, and private fixed field area within the simulated storage block using the private salt value; the Android driver library returns a verification pass when the verification object is the simulated storage block, and forwards the verification to the native verification logic for other storage addresses.

[0007] During the execution of the first thread, the historical call timestamps of the boundary functions are recorded and written to the thread mapping table; valid call records falling within a set time range are filtered out, and the average call interval of the boundary functions is calculated based on the time distribution of the valid call records, and the call probability is obtained by combining the call frequency;

[0008] When the first thread switches between Linux components and the Android driver library, if the probability of calling the boundary function is greater than a threshold, a register switch is triggered in advance. The TLS register is updated using the base address of the simulated storage block read from the thread mapping table to complete the pre-switching of the first thread. After the pre-switching, if no corresponding driver call occurs within a set time, the TLS register is restored and the prediction weight of the boundary function is reduced. If no driver call occurs after a set number of consecutive pre-switches, the pre-switching of the function is paused, and the call probability is recalculated. When the Android driver library runs, a field dependency graph is constructed for the private fixed field area of ​​the simulated storage block. The update method determined by the field dependency graph is used to update the values ​​and status indicators of the private fields to achieve compatibility.

[0009] Furthermore, the method of updating values ​​and status identifiers using the field dependency graph is specifically as follows: the field dependency graph is used to record the dependency relationships between fields for prior changes and linked updates, including source field offset, target field offset, dependency confidence, dependency edge array and total number of dependency edges. The dependency confidence between the first field and the second field is the ratio of the number of times the second field is accessed after the first field is written to the total number of times the first field is written, and the ratio of the number of times the first field is written before the second field is accessed to the total number of times the second field is accessed, and the result of the weighted sum of the two.

[0010] When a private field changes, if its dependency confidence is greater than the upper threshold, it will be updated in real time. If the dependency confidence is within the closed interval formed by the lower threshold and the upper threshold, it will be updated in batches according to the set period. If the dependency confidence is less than the lower threshold, it will only be updated synchronously when the Android driver library reads the field.

[0011] Furthermore, the thread mapping table has a two-level index consisting of a global hash table and a core local thread list. The first-level index is a global hash table, which uses the unique identifier of the first thread as the key to store the base address, reference status, initialization identifier, and current length of the dynamic segment of the dual TLS space composed of the simulated storage block and the native storage block corresponding to the first thread. The second-level index is a core local thread list maintained independently for each CPU core, which realizes lock-free concurrent access based on hardware atomicity, and only records the thread identifier currently running in the core and its corresponding TLS mapping address.

[0012] Furthermore, when the first thread undergoes a cross-core scheduling switch, the secondary index data is updated in real time, the corresponding thread mapping information in the original core local thread list is removed, and it is synchronously added to the target core local thread list.

[0013] Furthermore, when initializing the fields of the simulated storage block, function hooks are set for the dynamic TLS variable access entry and the thread-private data access interface. When a thread calls the corresponding interface, the initialization status of the thread mapping table of that thread is checked. If the initialization is not completed, the initialization process is started. A read access hardware breakpoint is configured for the control block of the simulated storage block. When a thread reads this area and triggers the breakpoint, the initialization status is checked again. If it is still not initialized, the initialization is forcibly executed.

[0014] Furthermore, the boundary function identification method is as follows: based on the constructed boundary function list, call interception is achieved through symbol matching to obtain historical call timestamps; the loading of Linux system dynamic libraries and the acquisition of function addresses are monitored; when a new driver module is loaded, module information is recorded; when a function pointer within the module is obtained, the corresponding function is added to the boundary function list, and an interception stub is generated to obtain historical call timestamps.

[0015] Furthermore, the field-dependent graph is constructed as follows:

[0016] By reverse engineering the Android driver library using binary code, all functions capable of accessing private fields of the simulated storage block are located. The execution order of accessing each private field within the function is traced, distinguishing between preceding and subsequent fields. Based on the execution order, the dependency relationships between fields are determined, forming basic dependency relationships. Then, access monitoring logic for the simulated storage block is added to the adaptation layer to intercept memory read and write behaviors of the simulated storage block during operation. The timing information, access object, and read / write type of each field access are recorded, and the frequency of common field accesses in the records is counted. If, within a fixed time window after a write operation occurs in a certain field, another field also performs read and write behavior, it is determined that there is a positive dependency relationship between the two, and this dependency relationship is added to the field dependency graph.

[0017] Furthermore, the kernel enables the architecture hardware partition extension function, assigning independent hardware partition identifiers to the simulated memory pool and the native memory pool during the adaptation layer initialization; and configuring memory bandwidth policies for each partition through the hardware partition management interface, setting a minimum bandwidth for the simulated memory pool and a bandwidth usage limit for the native memory pool.

[0018] Configure hardware access rules by mapping registers to architectural permission attributes, bind each CPU core to its corresponding memory partition, restrict each CPU core to accessing only the TLS memory block within its own partition; prohibit non-driver business threads from performing write operations to the simulated memory pool, and only grant read-only permissions; prohibit driver business threads from tampering with the standard fields of the native storage block.

[0019] Furthermore, when the adaptation layer allocates TLS memory blocks through memory mapping, the kernel configures multiple protection attributes for the corresponding memory page table entries, prohibiting the kernel privileged mode and user mode from executing TLS memory data as instruction code; it also configures memory access permissions synchronously, allowing only the currently owned thread to perform read and write operations on its corresponding TLS memory space, and marking contiguous TLS memory pages as contiguous memory attributes.

[0020] When a page exception is triggered due to a permission error, the kernel calls a custom TLS page error handling function to intercept and reject illegal write operations and return an access forbidden flag. For read operations that are determined to be irregular, a temporary permission granting mechanism is adopted, which grants read-only access for a set time and restores the original permission configuration after the timeout.

[0021] Furthermore, the read, write, and update operations of key fields within the simulated storage block are encapsulated into hardware transaction memory execution logic. During transaction execution, key field reading, state logic modification, and data write-back and commit operations are completed. If concurrent modification by multiple threads causes data race conflicts, the hardware completes transaction retry repair.

[0022] Beneficial effects:

[0023] This invention constructs simulated memory pools and native memory pools adapted for Android and Linux environments respectively during system startup. Initialization is completed based on large page memory, and the storage block state is managed through bitmaps. When creating threads associated with heterogeneous closed-source drivers, a free storage block is allocated from each of the two memory pools for exclusive use by the thread through bitwise operations, lock-free queues, and atomic operations. A thread mapping table is established to record the base address and running status of the corresponding storage block. When a thread accesses a TLS variable for the first time, the fields of the simulated storage block are initialized according to priority. The key area verification value is calculated using a private salt value and written to the signature field. When the driver initiates verification, the simulated storage block is directly allowed, and the native verification logic is forwarded to other addresses. The history of boundary functions is recorded during thread execution. The system uses timestamps and a sliding window algorithm to calculate call intervals and probabilities. Based on a call probability threshold, a timer is used to pre-switch TLS registers. If a driver call misses, the register is switched back and the prediction weight is dynamically reduced. After multiple invalid pre-switches, prediction is paused and re-evaluated periodically. During driver operation, a field dependency graph containing confidence levels is constructed for the private fields of the simulated storage block. Different strategies are adopted for different confidence levels, including real-time synchronization, periodic batch synchronization, and on-demand synchronization during reading, to achieve consistent maintenance of the values ​​and status identifiers of the simulated TLS private fields. This solves the fundamental conflict between bionic and glibc in TLS storage models, register dependencies, security verification, and dynamic expansion. Attached Figure Description

[0024] Figure 1 This is a flowchart illustrating a TLS storage model compatibility method for heterogeneous closed-source driver integration provided by the present invention. Detailed Implementation

[0025] The present invention will be described in detail below with reference to the accompanying drawings and embodiments.

[0026] This invention provides a TLS storage model compatibility method for heterogeneous closed-source driver integration. Its core idea is as follows: During system startup, simulated memory pools and native memory pools adapted to Android and Linux environments are constructed respectively. Initialization is completed based on large page memory, and storage block states are managed through bitmaps. When creating threads associated with heterogeneous closed-source drivers, a free storage block is allocated from each of the two memory pools for exclusive use by the thread through bitwise operations, lock-free queues, and atomic operations. A thread mapping table is established to record the base address and running status of the corresponding storage block. When a thread first accesses a TLS variable, the fields of the simulated storage block are initialized according to priority. A private salt value is used to calculate the checksum of key areas and write it to the signature field. When initiating verification, the simulated storage block is directly allowed, while the original verification logic is forwarded to other addresses. During thread execution, the historical call timestamps of boundary functions are recorded. The call interval and call probability are statistically analyzed using a sliding window algorithm. Based on the call probability threshold, a timer is used to pre-switch the TLS register. If the driver call is not hit, the register is switched back and the prediction weight is dynamically reduced. After multiple invalid pre-switches, the prediction is paused and re-evaluated periodically. During driver execution, a field dependency graph containing confidence levels is constructed for the private fields of the simulated storage block. Differentiated strategies such as real-time synchronization, periodic batch synchronization, and on-demand synchronization during reading are adopted for different confidence levels to achieve consistent maintenance of the simulated TLS private field values ​​and status identifiers.

[0027] This invention provides a TLS storage model compatibility method for heterogeneous closed-source driver integration, the processing flow of which is as follows: Figure 1 As shown, the specific steps include:

[0028] Step 1: During Linux system startup, a simulated memory pool and a native memory pool are built for the simulated TLS space and the native TLS space, respectively. The memory pool is initialized using a large page memory mechanism, and the free, occupied, and pending reclamation status of storage blocks is uniformly marked using a bitmap. The storage blocks of the simulated memory pool adopt a four-partition customized TLS layout of the Android bionic environment, including a control block, a standard field area, a private fixed field area, and a dynamically extended area, to adapt to the running requirements of heterogeneous closed-source drivers. The storage blocks of the native memory pool adopt the standard TLS layout of the Linux system glibc to adapt to the running requirements of the Linux system's native threads.

[0029] When creating the thread related to the heterogeneous closed-source driver, designated as the first thread, bitwise operations and lock-free queues are used to retrieve the simulated memory pool and the native memory pool respectively. Atomic operations are then used to complete the conflict-free marking and address return of the storage block status, obtaining two free storage blocks: a simulated storage block and a native storage block. These two free storage blocks are allocated exclusively to the first thread as dedicated TLS storage spaces for the first thread to adapt to the dual runtime environments. A thread mapping table is established to record the base address and runtime status identifier of the simulated and native storage blocks corresponding to the first thread.

[0030] Furthermore, in order to ensure efficient allocation and stable reuse of TLS resources, this invention constructs a monitoring thread to periodically evaluate the idle rate and fragmentation rate, and implements adaptive expansion, contraction and defragmentation of the memory pool based on the evaluation results. The idle rate is the ratio of the number of free blocks to the total number of blocks, and the fragmentation rate is the ratio of the difference between the total number of free bytes and the maximum number of free block bytes to the total number of free bytes.

[0031] Furthermore, to improve the query performance of the thread mapping table between threads and the dual TLS space composed of simulated storage blocks and native storage blocks in multi-core processor operating scenarios, reduce cross-core data access latency, and achieve efficient and fast retrieval of thread TLS mapping information, this invention designs a two-level index composed of a global hash table and a core local thread list, specifically:

[0032] The first-level index is a globally unified hash mapping structure. It uses the unique identifier of the first thread as the key and stores information such as the base address of the dual TLS space corresponding to the first thread, the reference state, the initialization identifier, and the current length of the dynamic segment. It ensures the stability and reliability of the multi-threaded concurrent retrieval process through conventional conflict handling mechanisms such as linked lists. The second-level index maintains a core-local thread list independently for each CPU core. It achieves lock-free concurrent access based on hardware atomicity and only records the thread identifier currently running on the core and its corresponding TLS mapping address.

[0033] When a cross-core scheduling switch occurs in the first thread, the secondary index data is automatically updated in real time, the corresponding thread mapping information in the original core local thread list is removed, and it is synchronously added to the target core local thread list.

[0034] Step 2: When the first thread accesses the TLS variable for the first time, it initializes each field in the simulated storage block in descending order of task priority. Based on the obtained private salt value, it calculates the check value of the memory area corresponding to the control block, standard field area, and private fixed field area in the simulated storage block, and writes the result to the signature field of the control block. When the Android driver library initiates verification, if the verification object is the simulated storage block, it directly returns that the verification passed. If it is another storage address, it forwards the verification to the native verification logic for execution.

[0035] The task priorities are determined based on the degree to which the fields affect the startup speed of the Android driver library. The tasks with the highest priority are initialization tasks that ensure the Android driver library can quickly enter the running state, including tasks for assigning values ​​to basic fields within the control block and synchronizing the standard field area with native TLS. The tasks with the middle priority are initialization tasks that support the core functions of the Android driver library, including tasks for initializing critical thread structures and synchronizing and writing security contexts. The tasks with the lowest priority are initialization tasks that are not necessary for startup, including tasks for initializing dedicated caches and clearing dynamically extended areas.

[0036] The private salt value is obtained by analyzing the corresponding Android version's bionic library implementation using reverse engineering tools, locating and extracting the private salt value used for TLS signature calculation.

[0037] Furthermore, to avoid missed or repeated initialization triggers, this invention constructs a two-layer detection mechanism, specifically including: the first layer, setting function hooks for the dynamic TLS variable access entry and thread-private data access interface; when a thread calls the corresponding interface, checking the initialization status of the thread mapping table of that thread; if initialization is not completed, initiating the initialization process; the second layer, pre-configuring read access hardware breakpoints for the control block of the simulated storage block; when a thread reads this area and triggers the breakpoint, re-verifying the initialization status; if it is still not initialized, forcibly initiating the initialization process to compensate for the initialization omission problem caused by possible failure of software interception.

[0038] Step 3: During the execution of the first thread, record the timestamps of multiple historical calls for each function in the boundary function list, and save these timestamps to the call history storage structure of the thread mapping table; use a sliding window algorithm to traverse the historical timestamps and filter out valid call records that fall within a set time range; calculate the average call interval of the boundary functions based on the time distribution of valid call records, and obtain the call probability based on the call frequency per unit time.

[0039] The first thread switches between Linux components and Android driver libraries. When the probability of calling a certain boundary function within a set time exceeds a threshold, a high-precision timer triggers a register switch in advance. The base address of the simulated storage block is read from the thread mapping table, and the value of the TLS register is modified from the base address of the native storage block to the base address of the simulated storage block, thus completing the pre-switch of the first thread from Linux components to Android driver libraries.

[0040] If the corresponding driver call does not occur within the set time after the pre-switch, the value of the TLS register is restored to the base address of the native memory block, and the prediction weight of the boundary function is reduced. If a boundary function is not called by the driver after a set number of consecutive pre-switches, the prediction switch of the function is paused, and its call probability is recalculated after a set time.

[0041] Among them, the boundary function list is formed by parsing the symbol information of the Android driver library in the preprocessing stage, extracting interface functions that conform to hardware access characteristics, forming the boundary function list from these interface functions, and embedding it into the adaptation layer.

[0042] Furthermore, to ensure that all Android driver library calls are effectively intercepted, this invention employs a dual call boundary identification mechanism combining static and dynamic identification to obtain historical call timestamps of boundary functions. Specifically: static identification involves intercepting calls at runtime through symbol matching based on a constructed list of boundary functions, and obtaining historical call timestamps; dynamic identification involves monitoring the loading and function address acquisition behavior of Linux system dynamic libraries. When a new driver module is loaded, module information is recorded. When a function pointer within that module is obtained, the corresponding function is added to the boundary function list, and an interception stub is generated to obtain historical call timestamps.

[0043] Furthermore, to ensure efficient and safe switching operations, this invention is optimized based on ARM64 assembly instructions and hardware characteristics. Specifically, it achieves lock-free switching through hardware-exclusive load and store instructions to avoid register state corruption caused by multi-threaded concurrent switching, thus ensuring efficient and stable switching operations. It utilizes a dedicated ARM64 read-only register to store nested call counts, incrementing the count when entering a driver call and decrementing it when exiting. The register is restored after the count is reset, thereby reducing the counting overhead in nested scenarios.

[0044] Furthermore, to prevent the TLS register state from becoming unrecoverable due to Android driver library malfunctions, this invention constructs a two-layer protection mechanism of exception capture and forced recovery, specifically as follows:

[0045] Exception handling logic is embedded in the intercept stub function. If the driver execution process triggers errors such as memory access exceptions, the value of the TLS register is restored to the base address of the native memory block. If user-mode restoration fails, the kernel monitors the thread's running status. When a thread is detected to have exited abnormally and the value of the TLS register is the base address of the simulated memory block, it is forcibly reset to the base address of the native memory block to prevent the exception from spreading and affecting other threads.

[0046] Step 4: During the operation of the Android driver library, a field dependency graph is constructed for the private fixed field area in the simulated storage block. The dependency relationship between fields is recorded for the preceding changes and linked updates, including the source field offset, target field offset, dependency confidence, dependency edge array and the total number of dependency edges. Specifically, the dependency confidence between the first field and the second field is the ratio of the number of times the second field is accessed after the first field is written to the total number of times the first field is written, and the ratio of the number of times the first field is written before the second field is accessed to the total number of times the second field is accessed. The result is obtained by weighted summation of the two.

[0047] When the state or value of a private field in the private fixed field area of ​​the simulated storage block changes, based on the dependency relationship of the field dependency graph, for fields with a dependency confidence greater than the upper threshold, their stored values ​​and status indicators are updated in real time; for fields with a dependency confidence in the closed interval formed by the lower and upper thresholds, their stored values ​​and status indicators are updated in batches according to a set period; for fields with a dependency confidence less than the lower threshold, their stored values ​​and status indicators are only updated to the latest values ​​when the Android driver library reads the field.

[0048] The field dependency graph is a topological structure of relationships between various private fields within the simulated storage block, obtained based on static code execution logic and dynamic access sequence. It shows the relationships between fields in terms of prior changes and linked updates. Each dependency relationship is stored in an adjacency list, and a dependency confidence level representing the strength of the relationship is set for each dependency relationship. The graph records the access order, linkage triggering logic, and dependency tightness of each field. It is used to automatically synchronize and link all related dependent fields when a field is modified during the operation of the Android driver library, ensuring the overall data state consistency and operational legality of the simulated storage block.

[0049] This invention constructs a field dependency graph by combining static reverse analysis with dynamic runtime instrumentation. Specifically, it includes: using binary reverse analysis of the Android driver library to locate all business functions that may access private fields of the simulated storage block; tracing the execution order of access to each private field within the function, distinguishing between preceding and subsequent fields, and preliminarily determining the dependency relationships between fields based on the execution order logic to form basic dependency relationships; on this basis, adding access monitoring logic for the simulated storage block in the adaptation layer to intercept memory read and write behaviors of the simulated storage block during operation, fully recording the timing information, access object, and read / write type of each field access, and statistically analyzing the co-occurrence frequency of field access based on runtime sampling data. If, within a fixed time window after a write operation occurs in a certain field, another field will inevitably generate read / write behavior, then it is determined that there is a positive dependency relationship between the two, and this potential dependency is added to the field dependency graph.

[0050] The field dependency graph uses an adjacency list to uniformly store field dependencies. Each dependency relationship records the dependency between the source field and the target field and is configured with dependency confidence to characterize the degree of correlation between fields. The entire system manages all dependency edges and the total number of dependencies with a fixed data structure, providing standardized data support for subsequent collaborative updates of related fields.

[0051] Furthermore, when the Android driver library uses the native memory allocator (Scudo), the Android driver's memory allocation needs to be replaced with the native memory allocation of the Linux system. Simultaneously, Scudo statistics are forged in the simulated storage block to make the Android driver believe it is running on the Android system. The specific process is as follows:

[0052] Intercept hooks are set up for memory allocation and deallocation operations of the Android driver library to forward memory management calls from the Android driver library to the native memory management interface of the Linux system for execution, ensuring the legality and compatibility of memory operations; after successful memory allocation, the allocation count, total allocated bytes, and peak allocated bytes in the cache management structure of the simulated storage block are updated in real time to ensure the accuracy of statistical information; when memory is released, the allocation count and total allocated bytes are decremented synchronously, and the information of the released memory block is recorded in the isolation area of ​​the simulated cache to maintain consistency with the behavior of the native runtime environment; the total allocation size of the simulated cache is synchronized to the memory statistics field of the thread structure to ensure that the data is legal and accurate when the driver library reads the memory status through the thread structure.

[0053] To further enhance the operational stability, memory access service quality, and data tamper-proof security of the dual TLS space, this invention employs ARM64 architecture hardware memory protection and resource partitioning expansion capabilities. It divides the simulated storage block and the native storage block into independent hardware memory partitions, achieving memory bandwidth resource isolation and cross-partition access control. Specifically, this includes:

[0054] The kernel enables the architecture hardware partitioning extension function. During the adaptation layer initialization, independent hardware partition identifiers are allocated to the simulated memory pool and the native memory pool respectively. The memory bandwidth policy is configured for each partition through the hardware partition management interface. A minimum bandwidth guarantee is set for the simulated memory pool to avoid delays in TLS access of the Android driver library under high system load scenarios. At the same time, a bandwidth usage limit is set for the native memory pool to prevent it from occupying the memory resource bandwidth of the simulated space without limit.

[0055] Hardware access rules are configured by mapping the architecture permission attributes register, binding each CPU core to its corresponding memory partition, restricting each CPU core to accessing only the TLS memory block within its own partition; cross-thread and cross-space access permission policies are configured to prohibit non-driver business threads from performing write operations to the simulated memory pool, and only grant read-only permissions; driver business threads are prohibited from tampering with the standard fields of the native storage block.

[0056] Furthermore, this invention achieves fine-grained page-level memory security management by customizing the Linux kernel page table management logic and configuring exclusive security access and runtime protection attributes for memory page table entries corresponding to the dual TLS spaces. Specifically, when the adaptation layer allocates TLS memory blocks through memory mapping, the kernel configures multiple protection attributes for the corresponding memory page table entries, prohibiting the kernel privileged mode and user mode from executing TLS memory data as instruction code; memory access permissions are configured synchronously, allowing only the currently owned thread to perform read and write operations on its corresponding TLS memory space, while all other threads have no access rights; consecutive TLS memory pages are marked as consecutive memory attributes to optimize address translation cache access efficiency, reduce cache miss probability, and improve overall TLS access performance; a dedicated page error exception handling mechanism is added for unauthorized access behavior. When a page exception is triggered by permission errors such as cross-thread unauthorized write or illegal read, the kernel calls the customized TLS page error handling function to directly intercept and reject illegal write operations and return an access prohibition flag; for non-standard read operations required for compliance and compatibility, a short-term temporary permission permission granting mechanism is adopted, briefly opening read-only access permissions, and restoring the original strict permission configuration after the timeout.

[0057] Furthermore, this invention combines ARM64 transaction memory extension and address translation cache isolation mechanisms to solve the problems of data corruption during multi-threaded concurrent access in dual TLS spaces and mutual pollution of address translation caches in different spaces. Specifically, the read, write, and update operations of core key fields such as the control block, verification signature field, and ART thread state within the simulated storage block are uniformly encapsulated into hardware transaction memory execution logic. During transaction execution, the key field reading, state logic modification, and data write-back and commit operations are completed. If multi-threaded concurrent modification causes data contention, the hardware automatically completes transaction retry repair. At the same time, independent address space identifiers are allocated to the simulated memory pool and the native memory pool. Based on the distinguishing ability of the page table base address register identifier, the address translation cache entries of the two TLS spaces are isolated from each other.

[0058] To further enhance the overall robustness and fault tolerance of dual TLS operation, this invention employs an ARM64 hardware anomaly reporting and monitoring mechanism to specifically identify two typical illegal access anomalies in the TLS space, and designs a corresponding hierarchical automatic anomaly recovery strategy. Specifically: through the architecture anomaly syndrome monitoring capability, it continuously monitors in real time for address out-of-bounds access anomalies and permission violation access anomalies during the simulated storage block access process, identifying various illegal operation behaviors; when an anomaly is triggered, the kernel schedules a dedicated TLS anomaly handling entry to execute hierarchical recovery logic; for address out-of-bounds access anomalies in the dynamic extension area, it determines whether the access offset is within the legal extension range. If it meets the extension conditions, it automatically expands the memory space of the simulated storage block and synchronously updates the dynamic segment offset record information within the control block; if it exceeds the legal extension range, it returns a memory resource shortage flag; for permission access anomalies, a temporary dynamic permission escalation mechanism is adopted, which opens read-only access permissions to the target area within a set time. After the timeout is reached through a timer mechanism, it automatically falls back to the original strict permission configuration.

[0059] Example:

[0060] This embodiment employs a TLS storage model compatibility method for heterogeneous closed-source driver integration provided by the present invention. Based on the entire TLS lifecycle, a dynamic TLS context adaptation architecture is constructed, achieving stable and low-latency reuse of high-version Android HAL libraries. The specific process includes:

[0061] S1. Dual TLS space pooling and dynamic scaling during thread creation: Through pre-allocation pools and dynamic scaling mechanisms, a scalable dual TLS space is built for each thread, and an efficient association index is established. Allocation efficiency is improved through pooling management, and dynamic resource balance is ensured through pool health management.

[0062] S1.1, bionic simulates the dynamic structure definition of the TLS space.

[0063] By reverse engineering the target Android version, such as Android 14's bionic library libc.so and representative HAL library camera.hal.so, using IDA Pro, the complete TLS structure was extracted to ensure full compatibility with the bionic layout.

[0064] The control block, 12 bytes in size and offset 0x0-0xB, contains thread status flags, TLS version number, dynamic segment offset, and CRC32 signature. The thread status flags are 2 bytes in size, with 0x01 indicating active and 0x02 indicating dormant. The TLS version number is 2 bytes in size, 0xE0E in Android 14. The dynamic segment offset is 4 bytes in size, initially 0x280, and identifies the starting position of the dynamic extension area. The CRC32 signature is 4 bytes in size and is used for bionic security verification.

[0065] The standard field is 256 bytes in size and offsets from 0xC to 0x10B. It is POSIX compatible with pthread_key_t key-value pairs, where the first 128 bytes from 0xC to 0x8B overlap with glibc TLS to ensure that standard TLS operations for non-Android components can be reused.

[0066] This is a private, fixed field, 512 bytes in size, with an offset of 0x10C-0x30B. It contains an ART thread pointer, a scudo memory allocation cache, an SELinux context, and bionic dynamic linker metadata. The ART thread pointer, 0x10C in size, points to a simulated art::Thread structure; the scudo memory allocation cache, 0x114 bytes in size, is of type scudo::ThreadCache; the SELinux context, 0x214 bytes in size, is a 64-byte string; and the bionic dynamic linker metadata, 0x274 bytes in size, is a TlsModule structure containing the module ID and offset.

[0067] The dynamic extension area has an initial size of 1024 bytes and an offset starting from 0x30C. It supports appending fields via bionic_tls_extend at runtime using the HAL library. After extension, the actual length is updated via the dynamic segment offset field of the control block, with a maximum support of 4096 bytes.

[0068] S1.2, Pre-allocation pool and health management of dual TLS space.

[0069] Pool initialization: When libhybris starts, it pre-allocates 1024 bionic simulated TLS blocks and 1024 glibc native TLS blocks via mmap, forming the bionic_tls_pool and glibc_tls_pool respectively. The block status is marked by an unsigned long array of bitmap, where 0 indicates free, 1 indicates occupied, and 2 indicates awaiting reclamation. The mmap is marked with the MAP_ANONYMOUS, MAP_PRIVATE, or MAP_HUGETLB flags to use large page memory to reduce TLB time consumption. The initial size of the TLS block is 2048 bytes per block, and it is physically page aligned. The size of the glibc native TLS block is 1024 bytes per block.

[0070] Fast allocation: By intercepting the pthread_create function through LD_PRELOAD, when a thread is created, a free block is obtained from the pool through bit operations and a lock-free queue: traverse the bitmap to find the first 0 bit, atomically mark it as 1, and return the corresponding block address. The time consumption is controlled within 80ns, which is 84% ​​faster than the traditional mmap allocation.

[0071] Pool health management: A new pool monitoring thread has been added. This thread runs every 500ms and calculates and maintains two core metrics:

[0072] Idle rate: Idle rate = number of free blocks / total number of blocks. If the bionic_tls_pool idle rate is less than 10%, it will automatically expand, such as by adding 512 blocks, and expand the pool memory through mremap. If the idle rate is greater than 70%, it will automatically shrink, such as by releasing 256 consecutive free blocks, and reclaiming memory through munmap.

[0073] Fragmentation rate: Fragmentation rate = (Total number of free bytes - Maximum number of free block bytes) / Total number of free bytes. If the fragmentation rate is greater than 50%, fragmentation is triggered, which merges scattered small free blocks into contiguous large blocks. By adjusting the bitmap markers and block address mapping, the probability of allocation failure is reduced.

[0074] S1.3 Multi-level index structure for thread-TLS mapping: To solve the problem of query latency across CPU cores, this embodiment designs a multi-level index that includes a hash table and a core local list.

[0075] The first-level index is a global hash table, with the thread ID represented as TID as the key and the value as struct tls_mapping. It stores core information such as the thread's dual TLS base address, reference count, initialization flag, and current length of the dynamic segment. Hash collisions are resolved through a linked list, and the query time is less than 10ns.

[0076] The secondary index maintains a core-local thread list for each CPU core, implements lock-free access based on ARM64 LSE atomic operations, records the TID of the thread currently running on the core and its corresponding TLS base address, and the query time is less than 5ns, which is 50% faster than using only a hash table.

[0077] Index synchronization: When a thread migrates due to scheduling, such as from CPU0 to CPU1, the kernel scheduling hook sched_move_task triggers a secondary index update, that is, the thread information is removed from the original core list and added to the new core list to ensure index accuracy.

[0078] S2 and TLS first access intelligent initialization and signature generation: When a thread accesses a TLS variable for the first time after creation, it needs to complete the field initialization and secure signature generation of the simulation space to ensure that it passes the bionic verification mechanism and obtain the salt value and refine the verification hook.

[0079] S2.1, Initialization Triggered Layered Detection: To avoid missed or repeated triggering during initialization, a two-layer detection mechanism is designed:

[0080] The first layer of function hook interception: set function hooks for the dynamic TLS variable access entry _tls_get_addr and the thread-private data access interface pthread_getspecific to implement PLT / GOT-based redirection. When the HAL library calls these functions, the hook queries the initialization flag is_initialized in the thread mapping table. If it is false, the initialization process is triggered.

[0081] The second layer of hardware breakpoint monitoring: A read breakpoint is set on the simulated TLS control storage block at offset 0x0 via the ARM64 debug register DBGWCR0_EL1. When the HAL library reads the control block, this operation is a pre-operation of bionic to verify the TLS environment, triggering the breakpoint interruption and entering the libhybris breakpoint handling function to double-check the is_initialized status. If it is not initialized, the process is forcibly triggered to avoid initialization omissions due to hook interception failure.

[0082] S2.2 Priority scheduling of field initialization: Based on the degree of impact of the field on the startup of the HAL library, the initialization tasks are scheduled in three levels to balance the initialization speed and completeness.

[0083] High-priority tasks, which must be completed within 100ns, ensure that the HAL library can quickly enter the running state, including:

[0084] The basic fields of the control block are set as follows: the thread state flag is set to 0x01 to indicate that the thread is active, and the TLS version number is set to the target Android version, such as 0xE0E for Android 14.

[0085] Standard field synchronization copies pthread_key_t key-value pairs from 0xC to 0x8B from glibc native TLS, ensuring that standard TLS data for non-Android components can be reused.

[0086] Medium-priority tasks, requiring completion within 500ns, supporting core HAL library functionalities, including:

[0087] The ART thread pointer is initialized, and a simulated art::Thread structure is dynamically allocated. The structure address is written to the 0x10C offset of the simulated TLS. The simulated art::Thread structure contains core fields such as tid=TID+0x20000, state=0x03 indicating the running state, and suspend_count=0.

[0088] SELinux context synchronization reads the current SELinux context of a non-Android system, such as u:r:unconfined_t:s0, through the selinux_getcon system call. It is then converted into a bionic-compatible null-terminated string, padded with \0 if the length is less than 64 bytes, and written at an offset of 0x214.

[0089] Low-priority tasks are completed asynchronously. Fields not required for startup are processed asynchronously through worker thread initialization, including:

[0090] The scudo cache is initialized by calling scudo::ThreadCache::Init to simulate the process, writing an offset of 0x114, and initializing fields such as quarantine and allocation count to their default values. The dynamic extension area is cleared by initializing the dynamic segment starting from 0x30C to 0 to avoid random errors caused by uninitialized memory.

[0091] S2.3, Bionic signature simulation generation and verification bypass: Bionic verifies the legitimacy of the environment through the CRC32 signature of the TLS control block. This embodiment bypasses this restriction by reverse engineering the salt value and using a verification hook.

[0092] Salt value is obtained by reverse engineering the source code of bionic / libc / upstream-openbsd / libc / string / crc32.c of the target Android version using Ghidra. This allows you to locate the private salt value used by bionic to calculate TLS signatures. For example, the salt value for Android 14 is 0xAndroid14TLS, a 32-bit unsigned integer.

[0093] Real-time signature calculation: After the initialization of high and medium priority fields is completed, the CRC32 value is immediately calculated for the memory area from 0x0 to 0xB of the control block, from 0xC to 0x10B of the standard fields and from 0x10C to 0x30B of the private fixed fields. The result is written to the offset from 0x8 to 0xB of the control block, which is the signature field.

[0094] Verification hook refinement: Set a hook for the `_bionic_tls_verify_signature` function of the Bionic library, so that when the HAL library calls this function:

[0095] By comparing the bionic_tls_base in the thread mapping table, if the input parameter is a simulated TLS base address, return 0 directly to indicate that the verification passed and skip the actual verification.

[0096] If the input is another address, such as the glibc TLS base address, it will be forwarded to the glibc's default verification logic, such as _tls_verify_signature, to avoid affecting the normal operation of non-HAL components.

[0097] S3. Predictive TPIDR_EL0 switching and hardware acceleration during cross-environment calls: When a call switches between non-Android components and the HAL library, it is necessary to efficiently switch the TPIDR_EL0 register pointer, reduce switching latency through a prediction mechanism, and improve scheduling accuracy by correcting prediction errors.

[0098] S3.1 Fine-grained identification of call boundaries: To ensure that all HAL library calls are intercepted, a dual boundary identification system consisting of static and dynamic methods is designed.

[0099] Static identification involves: during compilation, the symbol table of the HAL library is parsed using `readelf -s` to extract all entry functions, i.e., functions whose names conform to the pattern of `*_open / *_write / *_configure / *_start`, generating a list of boundary functions and embedding them into the symbol table of libhybris; and at runtime, calls are intercepted through symbol matching.

[0100] Dynamic identification involves monitoring the dynamic loading of the library dlopen and the dlsym call to obtain function addresses. When dlopen loads a new HAL module, such as vendor.sensor.hal.so, it records the module handle. When dlsym obtains a function pointer from the module, it automatically adds the function to the boundary function list and generates a corresponding intercept stub function to avoid missing dynamically loaded HAL functions.

[0101] S3.2 Predictive TPIDR_EL0 switching and error correction: Based on the time pattern of HAL function call history, the call probability is predicted and the register is switched in advance to reduce call latency.

[0102] Historical analysis is performed by adding a `call_history` array to `struct tls_mapping` to store the call timestamps of the last 100 boundary functions, such as the call timestamp sequence of `camera_preview_start`. The average call interval of the function is calculated using a sliding window algorithm, such as the probability of being called within 100ms and 50ms.

[0103] Pre-switching trigger: When the probability of calling a certain boundary function within 50ms is greater than 80%, such as when the call frequency of camera_preview_start is significantly increased after camera preview is started, the kernel timer with a precision of 10ns triggers the switching logic 50ns in advance, that is, it reads the bionic simulated TLS base address from the thread mapping table and switches the TPIDR_EL0 register value from the glibc TLS base address to the simulated base address;

[0104] To predict and correct errors, and to avoid performance degradation caused by ineffective switching, a two-level correction strategy is designed:

[0105] Level 1 Correction: If no corresponding HAL call occurs within 100ms after pre-switch, TPIDR_EL0 is automatically switched back to the glibcTLS base address, and the prediction weight of the function is reduced by 20%. For example, if the initial weight is 1.0, the lower the weight, the higher the probability threshold for triggering pre-switch. Level 2 Correction: If a function is not called after 3 consecutive pre-switches, the pre-switch mechanism of the function is paused, and the call probability and weight are recalculated after 5s to avoid continuous invalid operations.

[0106] S3.3 Hardware acceleration and atomicity guarantee for register switching: To ensure the efficiency and concurrency safety of the switching operation, it is optimized based on ARM64 assembly instructions and hardware characteristics.

[0107] Assembly-level atomic switching: Lock-free switching is achieved through load-store exclusive instructions LDXR or STXR, avoiding register state corruption caused by concurrent switching in multiple threads, with a single switch taking less than 5ns.

[0108] The current glibc TLS base address TPIDR_EL0 is saved to the stack, as shown in the following code:

[0109] `mrs x0, tpidr_el0;` reads the value of the `TPIDR_EL0` register, which is the glibc TLS base address.

[0110] `stxr w1, x0, [sp, #-16]!;` This command exclusively stores data onto the stack, where `sp` points to the top of the stack, `#-16` is the stack offset, and `w1` returns 0 to indicate successful storage.

[0111] The code reads the base address of the bionic emulated TLS and writes it to a register, as shown below:

[0112] `ldr x2, [x10, #8] ;` `x10` points to `struct tls_mapping`, and `#8` is the offset of `bionic_tls_base`.

[0113] `msr tpidr_el0, x2 ;` writes the simulated TLS base address to `TPIDR_EL0` to complete the switch.

[0114] Nested call management is lightweight, using the ARM64 read-only register TPIDRRO_EL0 (Thread ID RegisterRead-Only EL0) to store the nested call count instead of the traditional ref_count in memory.

[0115] When entering the HAL call, add x0, TPIDRRO_EL0, #1, which means incrementing the counter by 1;

[0116] When exiting the HAL call, sub x0, TPIDRRO_EL0, #1, that is, decrement the counter by 1. If the counter is 0, switch the register; otherwise, keep the pointer unchanged.

[0117] This design avoids memory access latency, making the count update time for nested calls less than 2ns.

[0118] S3.4 Safe recovery in abnormal scenarios: To prevent the register state from becoming unrecoverable due to HAL library crashes, a mechanism including exception capture and forced recovery is designed.

[0119] Based on the GCC __attribute__((cleanup)) attribute, try-catch exception handling is embedded in the intercept stub function: if the HAL function triggers exceptions such as segmentation fault or bus fault, the cleanup function automatically reads the glibcTLS base address saved in the stack and restores the TPIDR_EL0 register pointer.

[0120] If user-mode recovery fails due to stack corruption, the kernel monitors the thread status via ptrace. When it detects that a thread has exited abnormally and TPIDR_EL0 points to a simulated TLS, it forcibly resets it to the glibc TLS base address to avoid affecting other threads.

[0121] S4 and Bionic private TLS field dependency graph and dynamic synchronization: The private fields of the simulated TLS space need to be dynamically updated with the system state. By constructing a field dependency graph, the collaborative update of related fields is realized, and the accuracy of dependency identification is ensured by analysis tools and confidence formulas.

[0122] S4.1 Construction of Field Dependency Graph: Through a two-dimensional analysis of static reverse engineering and dynamic instrumentation, a dependency graph covering all private fields is constructed.

[0123] Static dependency analysis:

[0124] Tools: Use IDA Pro to perform cross-reference analysis on the HAL library to locate all functions that access TLS private fields, such as camera_configure accessing ART thread status and scudo cache;

[0125] Process: Track the field access order within the function, mark the preceding and following fields. For example, if the ART thread state must access the scudo cache after modification, then the ART thread state is the preceding field and the scudo cache is the following field, thus generating the initial dependency relationship.

[0126] Dynamic dependency analysis:

[0127] Tools: Insert TLS field access instrumentation into libhybris, intercept memcpy, memset and direct memory read and write operations based on LD_PRELOAD, and record the timestamp, field offset and access type (read or write) of each field access.

[0128] Process: Perform co-occurrence frequency statistics on data accessed more than 1000 times. If field B is read or written within 100ns after field A is written, then A to B is determined to be a potential dependency and added to the dependency graph.

[0129] Graph storage: Dependencies are stored using an adjacency list structure. Each dependency edge includes the source field offset, the target field offset, and the confidence score, as shown in the example below:

[0130] struct field_dep {

[0131] uint32_t src_offset; / / Source field offset, e.g., 0x10C for ART thread state

[0132] uint32_t dst_offset; / / Target field offset, e.g., 0x114 for scudo cache

[0133] float confidence; / / Dependency confidence, ranging from 0 to 1.0, with higher values ​​indicating a tighter dependency.

[0134] };

[0135] struct dep_graph {

[0136] struct field_dep* edges; / / Array of dependent edges

[0137] uint32_t edge_count; / / Total number of dependent edges

[0138] };

[0139] S4.2 Confidence Calculation and Collaborative Synchronization Strategy: Based on the degree of correlation between the preceding and following field accesses, calculate the dependency confidence and formulate differentiated synchronization strategies.

[0140] The confidence score calculation combines the trigger rate of the source field to the target field and the dependency rate of the target field to the source field, balancing the two-way association. Specifically:

[0141] confidence = (Number of times B accesses A after A writes / Total number of times A writes) × 0.8 + (Number of times A writes before B accesses / Total number of times B accesses) × 0.2.

[0142] Example: If 90 out of 100 writes to the ART thread state trigger scudo cache access, the trigger rate is 90%. If 80 out of the first 100 scudo cache accesses involve ART thread state writes, the dependency rate is 80%. Therefore, the confidence level is 90% × 0.8 + 80% × 0.2 = 0.88.

[0143] Three-level synchronization strategy:

[0144] For high-confidence synchronization (Confidence > 0.8): synchronize immediately to ensure real-time consistency of core dependency fields. For example, when the ART thread state changes from running (0x03) to sleeping (0x04), immediately set the active flag of the scudo cache to false to prevent the HAL library from reading inconsistent cache states.

[0145] For medium confidence synchronization (0.5 ≤ confidence ≤ 0.8): batch synchronization reduces the performance overhead of frequent synchronization. For example, after the SELinux context is modified, the camera permission field is not synchronized immediately. Instead, a 10ms timer is used to aggregate changes to multiple medium confidence dependent fields, and the target field is updated all at once.

[0146] For low-confidence synchronization (confidence < 0.5): synchronize on demand to avoid unnecessary operations. For example, after the bionic dynamic linker metadata is modified, synchronization is only triggered when the HAL library reads the sensor calibration field, i.e., a low-confidence dependency, thus reducing unnecessary memory accesses.

[0147] S4.3 Deep Simulation and Synchronization of Key Fields. Dedicated simulation and synchronization logic is designed for private fields that the HAL library strongly depends on.

[0148] scudo cache deep synchronization:

[0149] Call interception: Hooks are set up for the scudo_malloc / scudo_free / scudo_realloc functions in the HAL library to forward calls to the malloc / free / realloc functions in glibc;

[0150] State synchronization:

[0151] After scudo_malloc succeeds, update the simulated cache's alloc_count by incrementing it by 1, update total_allocated to its sum with the allocation size, and update max_allocated if the current allocation size is larger.

[0152] During scudo_free, alloc_count is decremented by 1, total_allocated is updated to the difference between the total_allocated and the freed size, and the freed memory block information is written to the quarantine area of ​​the simulated cache.

[0153] Synchronize the mem_stats field of the ART thread pointer and synchronize the total_allocated cached by scudo to art::Thread::mem_stats.total to ensure that the HAL library obtains accurate memory statistics through the ART thread.

[0154] ART thread state real-time synchronization:

[0155] State simulation: Implement simulation functions for art::Thread::GetState() or art::Thread::SetState(). GetState() returns a bionic enumeration value that matches the actual state of the thread. For example, when pthread_self() is detected as blocked by pthread_tryjoin_np, it returns kBlocked (0x02).

[0156] Status response: When the HAL library calls art::Thread::Suspend(), the hook function calls pthread_suspend_np to suspend the current thread, synchronously sets the ART thread state (simulating TLS) to kSuspended (0x05), and updates the active flag of the scudo cache to false; when art::Thread::Resume() is called, the thread is resumed and the state is updated in reverse.

[0157] S5. Hardware-assisted TLS space isolation and access control: To enhance the security and isolation of dual TLS spaces, deep TLS space isolation is achieved using the characteristics of ARM64 hardware, and security and stability are enhanced based on page table attribute configuration and TLB isolation.

[0158] S5.1, MPAM-based memory partition isolation.

[0159] Enable the MPAM (Memory Protection and Allocation) extension for ARM64 to partition independent memory partitions for dual TLS spaces, thereby achieving bandwidth protection and access control.

[0160] MPAM configuration process: Enable the CONFIG_ARM64_MPAM option during kernel compilation to enable MPAM hardware support;

[0161] During libhybris initialization, partition ID=0x10 is allocated for bionic_tls_pool and partition ID=0x20 is allocated for glibc_tls_pool via / sys / devices / system / cpu / cpu0 / mpam / part_id.

[0162] Configure partition bandwidth via / sys / devices / system / cpu / cpu0 / mpam / bandwidth: bionic_tls_pool guarantees a minimum bandwidth of 20% to avoid HAL library TLS access latency under high load, and glibc_tls_pool has a maximum bandwidth of 80% to avoid preempting the simulated space bandwidth.

[0163] Access control is achieved by setting partition access rules through the MPAM (Permission Attribute Mapping) register MPAM_PAM0_EL1:

[0164] Only the CPU core where the current thread resides is allowed to access the corresponding partition. The core ID is bound to the partition ID. For example, CPU0 can only access the blocks allocated to CPU0 thread in partition 0x10 / 0x20.

[0165] Non-HAL threads are prohibited from writing to the bionic_tls_pool; only reading is allowed. HAL threads are prohibited from modifying standard fields of the glibc_tls_pool to prevent unauthorized operations.

[0166] S5.2 Execution and Access Protection Based on Page Table Attributes. The page table management logic of the Linux kernel is modified to set dedicated attributes for page table entries in dual TLS spaces, thereby enhancing memory security.

[0167] Page table entry configuration: When libhybris allocates TLS blocks via mmap, the kernel sets the following attributes for the corresponding page table entry structpage_table_entry:

[0168] PXN (Privileged Execute Never): Prevents the execution of code in the TLS space by privileged mode (kernel mode), thus preventing the kernel from mistakenly executing TLS data as code.

[0169] XN (Execute Never): Prevents user-space execution of code in the TLS space, preventing malicious code injection from the HAL library or non-Android components;

[0170] AP (Access Permissions): Set to read and write by the current thread, other threads have no permission. ARM64 AP encoding is 0b10, to prevent cross-thread data tampering.

[0171] Contiguous Bit: Marks TLS blocks as contiguous memory pages, reducing TLB miss rate and improving access speed by 15%.

[0172] Page fault handling: When a permission error page fault occurs, such as a non-HAL thread writing to bionic_tls_pool, the kernel triggers libhybris's tls_page_fault_handler: If it is a write error, it returns the EACCES error code and prohibits the operation; if it is a read error, such as a non-HAL thread reading a private field of bionic_tls_pool, it temporarily elevates the privilege to read-only, and restores it after 10ms to avoid a crash.

[0173] S5.3 Atomicity and cache isolation based on TME and TLB.

[0174] It integrates the TME (Transactional Memory Extension) and TLB (Translation Lookaside Buffer) features of ARM64 to solve the problems of concurrent access consistency and cache pollution.

[0175] TME Transaction Atomicity Protection: Read and write operations on critical areas simulating TLS are encapsulated as TME transactions to ensure data consistency during concurrent modifications. Critical areas include the control block, signature field, and ART thread state. Example code is as follows:

[0176] `tstart;` starts a transaction. If the transaction fails, such as due to concurrent modifications, it will automatically retry.

[0177] `ldr x0, [x1, #0] ;` reads the control block thread state, where `x1` is the simulated TLS base address.

[0178] orr x0, x0, #0x02 ; Set the state to sleep 0x02

[0179] str x0, [x1, #0] ; Write back to control block

[0180] `tcommit;` commits the transaction; the transaction succeeds if no concurrent modifications are made during the transaction.

[0181] If other threads modify the same area during a transaction, TME will automatically retry the operation to avoid data corruption.

[0182] TLB cache isolation: Assign different ASIDs (AddressSpace Identifiers) to bionic_tls_pool and glibc_tls_pool:

[0183] ASID of bionic_tls_pool=0x100, ASID of glibc_tls_pool=0x200;

[0184] The ASID field of TTBR0_EL1 is used to distinguish the page table caches of the two spaces, avoiding TLB cache pollution, reducing TLB miss rate by 15%, and improving access speed.

[0185] S5.4 Anomaly Monitoring and Rapid Recovery. Configure an anomaly monitoring mechanism for ARM64 to promptly handle TLS access anomalies and ensure system stability.

[0186] Hardware anomaly capture: Configure ESR_EL1 to monitor two types of TLS-related anomalies.

[0187] Out-of-bounds access: When the HAL library accesses the unextended portion of the dynamic extension area simulating TLS, an address size exception is triggered, ESR_EL1 encoding 0x92000004;

[0188] Permission error: A permission exception is triggered when a thread accesses a TLS zone without permission. ESR_EL1 encoding is 0x96000004.

[0189] The exception recovery strategy involves the kernel calling libhybris's tls_exception_handler when an exception occurs.

[0190] Out-of-bounds access recovery: Calculate the offset between the access address and the starting address of the dynamic extension area. If the offset is less than the maximum extension length of 4096, call mremap to extend the simulated TLS space to the required size, update the dynamic segment offset field of the control block, and return the extended address; if the offset is not less than 4096, return an ENOMI error.

[0191] Permission error recovery: Temporarily elevate the current thread's access permissions to the target area, such as changing from no permission to read-only. Set a 10ms timer, and restore the original permissions after the timeout to ensure that the HAL library can continue to execute core logic.

[0192] S6. Adaptive cleanup mechanism for thread destruction and resource reclamation. When a thread exits, the dual TLS space must be efficiently reclaimed and associated resources cleaned up. Memory leaks are avoided through zombie thread detection and leak protection.

[0193] S6.1 Multi-path detection triggered by recycling: To cover all thread exit scenarios, a three-path triggering mechanism integrating active, passive, and timeout is designed.

[0194] Active triggering: The pthread_exit function is intercepted by LD_PRELOAD. When a thread actively calls pthread_exit, the recycling process is triggered, the dual TLS base address is obtained from the thread mapping table, and the recycling operation is performed.

[0195] Passive triggering: By monitoring the exit_state field of the kernel task_struct through kernel modules or ptrace, when a thread is forcibly terminated, such as by pthread_kill or signal termination, the kernel thread calls the libhybris_tls_recycle interface of libhybris, which passively triggers recycling.

[0196] Timeout Trigger: A new zombie thread detection thread is added, which runs every 2 seconds to scan the thread-TLS mapping table. If the last activity time of a thread is greater than 10 seconds and the reference count is 0, it is determined to be a zombie thread. The last activity time of the thread is obtained by recording the last TLS access time of the thread through clock_gettime. A reference count of 0 indicates that there are no nested HAL calls. The zombie thread is forcibly terminated by calling pthread_cancel, which triggers the recycling process to avoid long-term resource occupation.

[0197] S6.2, Hierarchical reclamation and leakage protection of dual TLS space: Based on resource reuse priority, TLS space is reclaimed in two levels, and a leakage protection mechanism is added.

[0198] Primary recycling prioritizes reuse.

[0199] Release the dynamic extension area of ​​the simulated TLS: If the simulated TLS has been extended, i.e. the dynamic segment offset is greater than 0x280, call mremap to shrink it to the base size of 2048 bytes and release the extended memory.

[0200] Clean up field data: Reset the control block and private fields of the simulated TLS to their default values, such as setting the control block status to 0x00 and the ART thread pointer to NULL, to prevent residual data from affecting the next reuse.

[0201] Pooling reuse: Mark the double TLS block as idle, i.e. set the bitmap to 0, and recycle it to the corresponding pool for allocation by new threads.

[0202] Secondary garbage collection, memory release.

[0203] When the pool idle rate is greater than 70%, memory release is triggered:

[0204] Scan the pool of consecutive free blocks to find a contiguous region with a length of at least 256 blocks;

[0205] Call munmap to release the memory in this region and update the memory range of the pool and the bitmap;

[0206] Clean up associated resources, delete all dependency edges of this thread in the dependency graph, destroy the scudo::ThreadCache simulation structure, and release its internal cache.

[0207] To prevent leakage, add a recycling flag `recycle_count` to `struct tls_mapping`:

[0208] Each time a block is allocated, the recycle_count increments by 1; each time a block is successfully reclaimed, the recycle_count decrements by 1.

[0209] If a block satisfies recycle_count≥3, meaning it has not been reclaimed after 3 consecutive allocations, a forced memory scan is triggered: the memory references of the block are scanned through the lightweight interface vgdb of valgrind to locate unreleased reference points and output log alerts containing thread IDs and field offsets to help developers locate the cause of the leak.

[0210] S6.3 Atomic cleanup of metadata: To avoid metadata corruption caused by concurrent garbage collection in multi-threaded environments, atomic cleanup is implemented based on the LL / SC (Load-Link / Store-Conditional) instructions of ARM64.

[0211] 1: ldxr x0, [x10] ; Load the struct tls_mapping pointer (x10 is the hash bucket address) from the hash bucket.

[0212] cbz x0, 2f; If the pointer is null, it means the cleanup has been completed, and the cleanup process is exited.

[0213] stxr w1, xzr, [x10] ; Conditional storage of null values ​​to the hash bucket: if no other thread modifies the value during the storage period, the storage is successful (w1=0).

[0214] cbnz w1, 1b ; If storage fails, and w1≠0, retry cleanup.

[0215] 2: ; Cleanup complete, release struct tls_mapping memory.

[0216] free x0

[0217] This operation ensures that even if multiple threads clean up the same thread's metadata at the same time, only one thread will succeed, avoiding duplicate releases or memory leaks.

[0218] Experimental verification shows that this embodiment has the following technical advantages over existing technologies: Dynamic TLS layout compatibility resolves structural differences, predictive switching resolves register semantic conflicts, hardware isolation resolves security verification issues, and dependency synchronization resolves data consistency issues, covering all core scenarios of TLS conflicts between bionic and glibc; pre-allocated pools accelerate TLS initialization by 84%, predictive switching reduces cross-environment call latency by 50%, and hardware atomic operations and TLB isolation reduce overall performance loss to less than 3%, meeting the real-time requirements of the HAL library; MPAM-TME-TLB collaborative isolation reduces data corruption rate by 99.9%, the exception recovery mechanism reduces HAL library crash rate by 99%, and leak protection avoids long-term memory leaks; dynamic segment design and version adaptive signing support Android 10 to the latest version, and the dependency graph automatically updates to adapt to the new HAL library without rewriting core logic; only libhybris and kernel hardware configuration need to be modified, without modifying the HAL library or non-Android system components, reducing adaptation costs by 60%; dependency graph and pool monitoring provide visualized logs, improving maintenance efficiency by 80%.

[0219] In summary, the above are merely preferred embodiments of the present invention and are not intended to limit the scope of protection of the present invention. Any modifications, equivalent substitutions, improvements, etc., made within the spirit and principles of the present invention should be included within the scope of protection of the present invention.

Claims

1. A method for TLS storage model compatibility for heterogeneous closed-source driver integration, characterized in that, Specifically, the following steps are included: When the Linux system starts, it builds a simulated memory pool and a native memory pool. The simulated memory pool uses a custom TLS layout for Android bionic, while the native memory pool uses the standard TLS layout of the Linux system glibc. When creating the first thread related to the heterogeneous closed-source driver, the simulated memory pool and the native memory pool are retrieved, and the free simulated storage blocks and native storage blocks are allocated to the first thread for exclusive use. Establish a thread mapping table to record the base address and running status identifier of the simulated storage block and the native storage block corresponding to the first thread; The first thread accesses the TLS variable for the first time, initializes the fields of the simulated storage block in descending order of task priority, and calculates the verification values ​​of the control block, standard field area, and private fixed field area within the simulated storage block using the private salt value; the Android driver library returns a verification pass when the verification object is the simulated storage block, and forwards the verification to the native verification logic for other storage addresses. During the execution of the first thread, the historical call timestamps of the boundary functions are recorded and written to the thread mapping table; valid call records falling within a set time range are filtered out, and the average call interval of the boundary functions is calculated based on the time distribution of the valid call records, and the call probability is obtained by combining the call frequency; When the first thread switches between Linux components and the Android driver library, if the probability of calling the boundary function is greater than a threshold, a register switch is triggered in advance. The TLS register is updated using the base address of the simulated storage block read from the thread mapping table to complete the pre-switching of the first thread. After the pre-switching, if no corresponding driver call occurs within a set time, the TLS register is restored and the prediction weight of the boundary function is reduced. If no driver call occurs after a set number of consecutive pre-switches, the pre-switching of the function is paused, and the call probability is recalculated. When the Android driver library runs, a field dependency graph is constructed for the private fixed field area of ​​the simulated storage block. The update method determined by the field dependency graph is used to update the values ​​and status indicators of the private fields to achieve compatibility.

2. The TLS storage model compatible method according to claim 1, characterized in that, The method of updating values ​​and status identifiers using the field dependency graph is as follows: The field dependency graph is used to record the dependency relationships between fields for prior changes and linked updates, including source field offset, target field offset, dependency confidence, dependency edge array and total number of dependency edges. The dependency confidence between the first field and the second field is the ratio of the number of times the second field is accessed after the first field is written to the total number of times the first field is written, and the ratio of the number of times the first field is written before the second field is accessed to the total number of times the second field is accessed, and the result of the weighted sum of the two. When a private field changes, if its dependency confidence is greater than the upper threshold, it will be updated in real time. If the dependency confidence is within the closed interval formed by the lower threshold and the upper threshold, it will be updated in batches according to the set period. If the dependency confidence is less than the lower threshold, it will only be updated synchronously when the Android driver library reads the field.

3. The TLS storage model compatible method according to claim 1, characterized in that, The thread mapping table has a two-level index consisting of a global hash table and a core local thread list. The first-level index is the global hash table, which uses the unique identifier of the first thread as the key and stores the base address, reference status, initialization identifier, and current length of the dynamic segment of the dual TLS space composed of the simulated storage block and the native storage block corresponding to the first thread. The second-level index is the core local thread list maintained independently by each CPU core, which realizes lock-free concurrent access based on hardware atomicity and only records the thread identifier currently running in the core and its corresponding TLS mapping address.

4. The TLS storage model compatible method according to claim 3, characterized in that, When the first thread undergoes a cross-core scheduling switch, the secondary index data is updated in real time, the corresponding thread mapping information in the original core local thread list is removed, and it is synchronously added to the target core local thread list.

5. The TLS storage model compatible method according to claim 1, characterized in that, When initializing the fields of the simulated storage block, function hooks are set for the dynamic TLS variable access entry and the thread-private data access interface. When a thread calls the corresponding interface, the initialization status of the thread mapping table of that thread is checked. If the initialization is not completed, the initialization process is started. A read access hardware breakpoint is configured for the control block of the simulated storage block. When the thread reads the control block and triggers the breakpoint, the initialization status is checked again. If it is still not initialized, the initialization is forcibly executed.

6. The TLS storage model compatible method according to claim 1, characterized in that, The boundary function identification method is as follows: based on the constructed boundary function list, call interception is achieved through symbol matching, and historical call timestamps are obtained; the loading of Linux system dynamic libraries and the acquisition of function addresses are monitored; when a new driver module is loaded, module information is recorded; when a function pointer in the module is obtained, the corresponding function is added to the boundary function list, and an interception stub is generated to obtain historical call timestamps.

7. The TLS storage model compatible method according to claim 1, characterized in that, The field-dependent graph is constructed as follows: By performing binary reverse engineering analysis of the Android driver library, we can locate all functions that can access the private fields of the simulated storage block; we can trace the execution order of accessing each private field inside the function, distinguish between the preceding and following fields, and determine the dependency relationships between fields based on the execution order logic to form basic dependency relationships. Then, add access monitoring logic for simulated storage blocks in the adaptation layer to intercept memory read and write behavior of simulated storage blocks during operation, record the timing information, access object and read / write type of each field access, and count the frequency of common field access in the records. If a certain field has a write operation and another field also has read and write behavior within a fixed time window, it is determined that there is a positive dependency relationship between the two, and the dependency relationship is added to the field dependency graph.

8. The TLS storage model compatible method according to claim 1, characterized in that, The kernel enables the architecture hardware partition extension function, which allocates independent hardware partition identifiers for the simulated memory pool and the native memory pool during the adaptation layer initialization. Configure memory bandwidth policies for each partition through the hardware partition management interface, set minimum bandwidth for the simulated memory pool, and set bandwidth usage limit for the native memory pool; Hardware access rules are configured through the architecture permission attribute mapping register, binding each CPU core to its corresponding memory partition, restricting each CPU core to only accessing the TLS memory block within its own partition; non-driver business threads are prohibited from performing write operations to the simulated memory pool, and only read-only permissions are allowed. Prevent business threads from tampering with the standard fields of the native storage block.

9. The TLS storage model compatible method according to claim 1, characterized in that, When the adaptation layer allocates TLS memory blocks through memory mapping, the kernel configures multiple protection attributes for the corresponding memory page table entries to prevent the kernel privileged mode and user mode from executing TLS memory data as instruction code. Synchronously configure memory access permissions, allowing only the currently owned thread to read and write to its corresponding TLS memory space, while marking contiguous TLS memory pages as contiguous memory; When a page exception is triggered due to a permission error, the kernel calls a custom TLS page error handling function to intercept and reject illegal write operations and return an access forbidden flag. For read operations that are determined to be irregular, a temporary permission granting mechanism is adopted, which grants read-only access for a set time and restores the original permission configuration after the timeout.

10. The TLS storage model compatible method according to claim 1, characterized in that, The read, write, and update operations of key fields within the simulated storage block are encapsulated into hardware transaction memory execution logic. During transaction execution, key field reading, state logic modification, and data write-back and commit operations are completed. If concurrent modification by multiple threads causes data contention, the hardware completes transaction retry repair.

Citation Information

Patent Citations

  • Swan gap containerization TLS compatible method based on context awareness

    CN121387766A

  • Method for compatible operation of Android camera HAL in container based on memory access virtualization

    CN121433813A