@@ -627,7 +627,7 @@ static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map,
627
627
* kernel range is broken in several maps, named [kernel].N, as we don't have
628
628
* the original ELF section names vmlinux have.
629
629
*/
630
- static int dso__split_kallsyms (struct dso * dso , struct map * map ,
630
+ static int dso__split_kallsyms (struct dso * dso , struct map * map , u64 delta ,
631
631
symbol_filter_t filter )
632
632
{
633
633
struct map_groups * kmaps = map__kmap (map )-> kmaps ;
@@ -692,6 +692,12 @@ static int dso__split_kallsyms(struct dso *dso, struct map *map,
692
692
char dso_name [PATH_MAX ];
693
693
struct dso * ndso ;
694
694
695
+ if (delta ) {
696
+ /* Kernel was relocated at boot time */
697
+ pos -> start -= delta ;
698
+ pos -> end -= delta ;
699
+ }
700
+
695
701
if (count == 0 ) {
696
702
curr_map = map ;
697
703
goto filter_symbol ;
@@ -721,6 +727,10 @@ static int dso__split_kallsyms(struct dso *dso, struct map *map,
721
727
curr_map -> map_ip = curr_map -> unmap_ip = identity__map_ip ;
722
728
map_groups__insert (kmaps , curr_map );
723
729
++ kernel_range ;
730
+ } else if (delta ) {
731
+ /* Kernel was relocated at boot time */
732
+ pos -> start -= delta ;
733
+ pos -> end -= delta ;
724
734
}
725
735
filter_symbol :
726
736
if (filter && filter (curr_map , pos )) {
@@ -1130,15 +1140,41 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
1130
1140
return - EINVAL ;
1131
1141
}
1132
1142
1143
+ /*
1144
+ * If the kernel is relocated at boot time, kallsyms won't match. Compute the
1145
+ * delta based on the relocation reference symbol.
1146
+ */
1147
+ static int kallsyms__delta (struct map * map , const char * filename , u64 * delta )
1148
+ {
1149
+ struct kmap * kmap = map__kmap (map );
1150
+ u64 addr ;
1151
+
1152
+ if (!kmap -> ref_reloc_sym || !kmap -> ref_reloc_sym -> name )
1153
+ return 0 ;
1154
+
1155
+ addr = kallsyms__get_function_start (filename ,
1156
+ kmap -> ref_reloc_sym -> name );
1157
+ if (!addr )
1158
+ return -1 ;
1159
+
1160
+ * delta = addr - kmap -> ref_reloc_sym -> addr ;
1161
+ return 0 ;
1162
+ }
1163
+
1133
1164
int dso__load_kallsyms (struct dso * dso , const char * filename ,
1134
1165
struct map * map , symbol_filter_t filter )
1135
1166
{
1167
+ u64 delta = 0 ;
1168
+
1136
1169
if (symbol__restricted_filename (filename , "/proc/kallsyms" ))
1137
1170
return -1 ;
1138
1171
1139
1172
if (dso__load_all_kallsyms (dso , filename , map ) < 0 )
1140
1173
return -1 ;
1141
1174
1175
+ if (kallsyms__delta (map , filename , & delta ))
1176
+ return -1 ;
1177
+
1142
1178
symbols__fixup_duplicate (& dso -> symbols [map -> type ]);
1143
1179
symbols__fixup_end (& dso -> symbols [map -> type ]);
1144
1180
@@ -1150,7 +1186,7 @@ int dso__load_kallsyms(struct dso *dso, const char *filename,
1150
1186
if (!dso__load_kcore (dso , map , filename ))
1151
1187
return dso__split_kallsyms_for_kcore (dso , map , filter );
1152
1188
else
1153
- return dso__split_kallsyms (dso , map , filter );
1189
+ return dso__split_kallsyms (dso , map , delta , filter );
1154
1190
}
1155
1191
1156
1192
static int dso__load_perf_map (struct dso * dso , struct map * map ,
0 commit comments