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