18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <unistd.h> 38c2ecf20Sopenharmony_ci#include <stdio.h> 48c2ecf20Sopenharmony_ci#include <string.h> 58c2ecf20Sopenharmony_ci#include <internal/lib.h> // page_size 68c2ecf20Sopenharmony_ci#include "machine.h" 78c2ecf20Sopenharmony_ci#include "api/fs/fs.h" 88c2ecf20Sopenharmony_ci#include "debug.h" 98c2ecf20Sopenharmony_ci#include "symbol.h" 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ciint arch__fix_module_text_start(u64 *start, u64 *size, const char *name) 128c2ecf20Sopenharmony_ci{ 138c2ecf20Sopenharmony_ci u64 m_start = *start; 148c2ecf20Sopenharmony_ci char path[PATH_MAX]; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci snprintf(path, PATH_MAX, "module/%.*s/sections/.text", 178c2ecf20Sopenharmony_ci (int)strlen(name) - 2, name + 1); 188c2ecf20Sopenharmony_ci if (sysfs__read_ull(path, (unsigned long long *)start) < 0) { 198c2ecf20Sopenharmony_ci pr_debug2("Using module %s start:%#lx\n", path, m_start); 208c2ecf20Sopenharmony_ci *start = m_start; 218c2ecf20Sopenharmony_ci } else { 228c2ecf20Sopenharmony_ci /* Successful read of the modules segment text start address. 238c2ecf20Sopenharmony_ci * Calculate difference between module start address 248c2ecf20Sopenharmony_ci * in memory and module text segment start address. 258c2ecf20Sopenharmony_ci * For example module load address is 0x3ff8011b000 268c2ecf20Sopenharmony_ci * (from /proc/modules) and module text segment start 278c2ecf20Sopenharmony_ci * address is 0x3ff8011b870 (from file above). 288c2ecf20Sopenharmony_ci * 298c2ecf20Sopenharmony_ci * Adjust the module size and subtract the GOT table 308c2ecf20Sopenharmony_ci * size located at the beginning of the module. 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_ci *size -= (*start - m_start); 338c2ecf20Sopenharmony_ci } 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci return 0; 368c2ecf20Sopenharmony_ci} 37