1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2203d8a4aSSong Shan Gong #include <unistd.h> 3203d8a4aSSong Shan Gong #include <stdio.h> 4203d8a4aSSong Shan Gong #include <string.h> 5*20f2be1dSJiri Olsa #include <internal/lib.h> // page_size 6203d8a4aSSong Shan Gong #include "machine.h" 7203d8a4aSSong Shan Gong #include "api/fs/fs.h" 86738028dSThomas Richter #include "debug.h" 9b9c0a649SThomas Richter #include "symbol.h" 10203d8a4aSSong Shan Gong 1112a6d294SThomas Richter int arch__fix_module_text_start(u64 *start, u64 *size, const char *name) 12203d8a4aSSong Shan Gong { 136738028dSThomas Richter u64 m_start = *start; 14203d8a4aSSong Shan Gong char path[PATH_MAX]; 15203d8a4aSSong Shan Gong 16203d8a4aSSong Shan Gong snprintf(path, PATH_MAX, "module/%.*s/sections/.text", 17203d8a4aSSong Shan Gong (int)strlen(name) - 2, name + 1); 186738028dSThomas Richter if (sysfs__read_ull(path, (unsigned long long *)start) < 0) { 196738028dSThomas Richter pr_debug2("Using module %s start:%#lx\n", path, m_start); 206738028dSThomas Richter *start = m_start; 2112a6d294SThomas Richter } else { 2212a6d294SThomas Richter /* Successful read of the modules segment text start address. 2312a6d294SThomas Richter * Calculate difference between module start address 2412a6d294SThomas Richter * in memory and module text segment start address. 2512a6d294SThomas Richter * For example module load address is 0x3ff8011b000 2612a6d294SThomas Richter * (from /proc/modules) and module text segment start 2712a6d294SThomas Richter * address is 0x3ff8011b870 (from file above). 2812a6d294SThomas Richter * 2912a6d294SThomas Richter * Adjust the module size and subtract the GOT table 3012a6d294SThomas Richter * size located at the beginning of the module. 3112a6d294SThomas Richter */ 3212a6d294SThomas Richter *size -= (*start - m_start); 336738028dSThomas Richter } 34203d8a4aSSong Shan Gong 35203d8a4aSSong Shan Gong return 0; 36203d8a4aSSong Shan Gong } 37b9c0a649SThomas Richter 38b9c0a649SThomas Richter /* On s390 kernel text segment start is located at very low memory addresses, 39b9c0a649SThomas Richter * for example 0x10000. Modules are located at very high memory addresses, 40b9c0a649SThomas Richter * for example 0x3ff xxxx xxxx. The gap between end of kernel text segment 41b9c0a649SThomas Richter * and beginning of first module's text segment is very big. 42b9c0a649SThomas Richter * Therefore do not fill this gap and do not assign it to the kernel dso map. 43b9c0a649SThomas Richter */ 44b9c0a649SThomas Richter void arch__symbols__fixup_end(struct symbol *p, struct symbol *c) 45b9c0a649SThomas Richter { 46b9c0a649SThomas Richter if (strchr(p->name, '[') == NULL && strchr(c->name, '[')) 47b9c0a649SThomas Richter /* Last kernel symbol mapped to end of page */ 48b9c0a649SThomas Richter p->end = roundup(p->end, page_size); 49b9c0a649SThomas Richter else 50b9c0a649SThomas Richter p->end = c->start; 51b9c0a649SThomas Richter pr_debug4("%s sym:%s end:%#lx\n", __func__, p->name, p->end); 52b9c0a649SThomas Richter } 53